.. | .. |
---|
13 | 13 | * 1. add 2lane support. |
---|
14 | 14 | * 2. add some debug info. |
---|
15 | 15 | * 3. adjust gc8034_g_mbus_config function. |
---|
| 16 | + * V0.0X01.0X07 support get channel info |
---|
| 17 | + * V0.0X01.0X08 |
---|
| 18 | + * 1. default support 2lane full 30fps. |
---|
| 19 | + * 2. default support rk otp spec. |
---|
| 20 | + * V0.0X01.0X09 adjust supply sequence to suit spec |
---|
16 | 21 | */ |
---|
17 | | - |
---|
| 22 | +//#define DEBUG |
---|
18 | 23 | #include <linux/clk.h> |
---|
19 | 24 | #include <linux/device.h> |
---|
20 | 25 | #include <linux/delay.h> |
---|
.. | .. |
---|
39 | 44 | #include <media/v4l2-subdev.h> |
---|
40 | 45 | #include <linux/pinctrl/consumer.h> |
---|
41 | 46 | #include <linux/slab.h> |
---|
| 47 | +#include <linux/of_graph.h> |
---|
| 48 | +#include "otp_eeprom.h" |
---|
42 | 49 | |
---|
43 | | -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06) |
---|
| 50 | +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x09) |
---|
44 | 51 | |
---|
45 | 52 | #ifndef V4L2_CID_DIGITAL_GAIN |
---|
46 | 53 | #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN |
---|
.. | .. |
---|
49 | 56 | #define GC8034_LANES 4 |
---|
50 | 57 | #define GC8034_BITS_PER_SAMPLE 10 |
---|
51 | 58 | #define GC8034_MIPI_FREQ_336MHZ 336000000U |
---|
| 59 | +#define GC8034_MIPI_FREQ_634MHZ 634000000U |
---|
52 | 60 | |
---|
53 | 61 | /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ |
---|
54 | 62 | #define GC8034_PIXEL_RATE 288000000 |
---|
.. | .. |
---|
92 | 100 | #define GC8034_NAME "gc8034" |
---|
93 | 101 | #define GC8034_MEDIA_BUS_FMT MEDIA_BUS_FMT_SRGGB10_1X10 |
---|
94 | 102 | |
---|
| 103 | +/* use RK_OTP or old mode */ |
---|
| 104 | +#define RK_OTP |
---|
| 105 | +/* choose 2lane support full 30fps or 15fps */ |
---|
| 106 | +#define GC8034_2LANE_30FPS |
---|
| 107 | + |
---|
95 | 108 | static const char * const gc8034_supply_names[] = { |
---|
96 | | - "avdd", /* Analog power */ |
---|
97 | 109 | "dovdd", /* Digital I/O power */ |
---|
98 | 110 | "dvdd", /* Digital core power */ |
---|
| 111 | + "avdd", /* Analog power */ |
---|
99 | 112 | }; |
---|
100 | 113 | |
---|
101 | | -static const struct regval *gc8034_global_regs; |
---|
102 | 114 | #define GC8034_NUM_SUPPLIES ARRAY_SIZE(gc8034_supply_names) |
---|
103 | 115 | |
---|
| 116 | +#ifndef RK_OTP |
---|
104 | 117 | struct gc8034_dd { |
---|
105 | 118 | u16 x; |
---|
106 | 119 | u16 y; |
---|
.. | .. |
---|
145 | 158 | {0xd0, "CK8401"}, |
---|
146 | 159 | {0x00, "Unknown"} |
---|
147 | 160 | }; |
---|
| 161 | +#endif |
---|
148 | 162 | |
---|
149 | 163 | struct regval { |
---|
150 | 164 | u8 addr; |
---|
.. | .. |
---|
158 | 172 | u32 hts_def; |
---|
159 | 173 | u32 vts_def; |
---|
160 | 174 | u32 exp_def; |
---|
| 175 | + u32 mipi_freq_idx; |
---|
| 176 | + const struct regval *global_reg_list; |
---|
161 | 177 | const struct regval *reg_list; |
---|
| 178 | + u32 vc[PAD_MAX]; |
---|
162 | 179 | }; |
---|
163 | 180 | |
---|
164 | 181 | struct gc8034 { |
---|
.. | .. |
---|
192 | 209 | const char *module_name; |
---|
193 | 210 | const char *len_name; |
---|
194 | 211 | u32 Dgain_ratio; |
---|
| 212 | +#ifdef RK_OTP |
---|
| 213 | + struct otp_info *otp; |
---|
| 214 | +#else |
---|
195 | 215 | struct gc8034_otp_info *otp; |
---|
| 216 | +#endif |
---|
196 | 217 | struct rkmodule_inf module_inf; |
---|
197 | 218 | struct rkmodule_awb_cfg awb_cfg; |
---|
198 | 219 | }; |
---|
.. | .. |
---|
244 | 265 | * Xclk 24Mhz |
---|
245 | 266 | */ |
---|
246 | 267 | static const struct regval gc8034_global_regs_2lane[] = { |
---|
| 268 | +#ifdef GC8034_2LANE_30FPS |
---|
| 269 | + /* SYS */ |
---|
| 270 | + {0xf2, 0x00}, |
---|
| 271 | + {0xf4, 0x90}, |
---|
| 272 | + {0xf5, 0x3d}, |
---|
| 273 | + {0xf6, 0x44}, |
---|
| 274 | + {0xf8, 0x63}, |
---|
| 275 | + {0xfa, 0x42}, |
---|
| 276 | + {0xf9, 0x00}, |
---|
| 277 | + {0xf7, 0x95}, |
---|
| 278 | + {0xfc, 0x00}, |
---|
| 279 | + {0xfc, 0x00}, |
---|
| 280 | + {0xfc, 0xea}, |
---|
| 281 | + {0xfe, 0x03}, |
---|
| 282 | + {0x03, 0x9a}, |
---|
| 283 | + {0xfc, 0xee}, |
---|
| 284 | + {0xfe, 0x00}, |
---|
| 285 | + {0x88, 0x03}, |
---|
| 286 | + |
---|
| 287 | + /*Cisctl&Analog*/ |
---|
| 288 | + {0xfe, 0x00}, |
---|
| 289 | + {0x03, 0x08}, |
---|
| 290 | + {0x04, 0xc6}, |
---|
| 291 | + {0x05, 0x02}, |
---|
| 292 | + {0x06, 0x16}, |
---|
| 293 | + {0x07, 0x00}, |
---|
| 294 | + {0x08, 0x10}, |
---|
| 295 | + {0x0a, 0x3a}, //row start |
---|
| 296 | + {0x0b, 0x00}, |
---|
| 297 | + {0x0c, 0x04}, //col start |
---|
| 298 | + {0x0d, 0x09}, |
---|
| 299 | + {0x0e, 0xa0}, //win_height 2464 |
---|
| 300 | + {0x0f, 0x0c}, |
---|
| 301 | + {0x10, 0xd4}, //win_width 3284 |
---|
| 302 | + {0x17, GC8034_MIRROR}, |
---|
| 303 | + {0x18, 0x02}, |
---|
| 304 | + {0x19, 0x17}, |
---|
| 305 | + {0x1e, 0x50}, |
---|
| 306 | + {0x1f, 0x80}, |
---|
| 307 | + {0x21, 0x4c}, |
---|
| 308 | + {0x25, 0x00}, |
---|
| 309 | + {0x28, 0x4a}, |
---|
| 310 | + {0x2d, 0x89}, |
---|
| 311 | + {0xca, 0x02}, |
---|
| 312 | + {0xcb, 0x00}, |
---|
| 313 | + {0xcc, 0x39}, |
---|
| 314 | + {0xce, 0xd0}, |
---|
| 315 | + {0xcf, 0x93}, |
---|
| 316 | + {0xd0, 0x1b}, |
---|
| 317 | + {0xd1, 0xaa}, |
---|
| 318 | + {0xd2, 0xcb}, |
---|
| 319 | + {0xd8, 0x40}, |
---|
| 320 | + {0xd9, 0xff}, |
---|
| 321 | + {0xda, 0x0e}, |
---|
| 322 | + {0xdb, 0xb0}, |
---|
| 323 | + {0xdc, 0x0e}, |
---|
| 324 | + {0xde, 0x08}, |
---|
| 325 | + {0xe4, 0xc6}, |
---|
| 326 | + {0xe5, 0x08}, |
---|
| 327 | + {0xe6, 0x10}, |
---|
| 328 | + {0xed, 0x2a}, |
---|
| 329 | + {0xfe, 0x02}, |
---|
| 330 | + {0x59, 0x02}, |
---|
| 331 | + {0x5a, 0x04}, |
---|
| 332 | + {0x5b, 0x08}, |
---|
| 333 | + {0x5c, 0x20}, |
---|
| 334 | + {0xfe, 0x00}, |
---|
| 335 | + {0x1a, 0x09}, |
---|
| 336 | + {0x1d, 0x13}, |
---|
| 337 | + {0xfe, 0x10}, |
---|
| 338 | + {0xfe, 0x00}, |
---|
| 339 | + {0xfe, 0x10}, |
---|
| 340 | + {0xfe, 0x00}, |
---|
| 341 | + |
---|
| 342 | + /* Gamma */ |
---|
| 343 | + {0xfe, 0x00}, |
---|
| 344 | + {0x20, 0x54}, |
---|
| 345 | + {0x33, 0x82}, |
---|
| 346 | + {0xfe, 0x01}, |
---|
| 347 | + {0xdf, 0x06}, |
---|
| 348 | + {0xe7, 0x18}, |
---|
| 349 | + {0xe8, 0x20}, |
---|
| 350 | + {0xe9, 0x16}, |
---|
| 351 | + {0xea, 0x17}, |
---|
| 352 | + {0xeb, 0x50}, |
---|
| 353 | + {0xec, 0x6c}, |
---|
| 354 | + {0xed, 0x9b}, |
---|
| 355 | + {0xee, 0xd8}, |
---|
| 356 | + |
---|
| 357 | + /*ISP*/ |
---|
| 358 | + {0xfe, 0x00}, |
---|
| 359 | + {0x80, 0x13}, |
---|
| 360 | + {0x84, 0x01}, |
---|
| 361 | + {0x89, 0x03}, |
---|
| 362 | + {0x8d, 0x03}, |
---|
| 363 | + {0x8f, 0x14}, |
---|
| 364 | + {0xad, 0x00}, |
---|
| 365 | + {0x66, 0x0c}, |
---|
| 366 | + {0xbc, 0x09}, |
---|
| 367 | + {0xc2, 0x7f}, |
---|
| 368 | + {0xc3, 0xff}, |
---|
| 369 | + |
---|
| 370 | + /*Crop window*/ |
---|
| 371 | + {0x90, 0x01}, |
---|
| 372 | + {0x92, FULL_STARTY}, |
---|
| 373 | + {0x94, FULL_STARTX}, |
---|
| 374 | + {0x95, 0x09}, |
---|
| 375 | + {0x96, 0x90}, |
---|
| 376 | + {0x97, 0x0c}, |
---|
| 377 | + {0x98, 0xc0}, |
---|
| 378 | + |
---|
| 379 | + /*Gain*/ |
---|
| 380 | + {0xb0, 0x90}, |
---|
| 381 | + {0xb1, 0x01}, |
---|
| 382 | + {0xb2, 0x00}, |
---|
| 383 | + {0xb6, 0x00}, |
---|
| 384 | + |
---|
| 385 | + /*BLK*/ |
---|
| 386 | + {0xfe, 0x00}, |
---|
| 387 | + {0x40, 0x22}, |
---|
| 388 | + {0x41, 0x20}, |
---|
| 389 | + {0x42, 0x02}, |
---|
| 390 | + {0x43, 0x08}, |
---|
| 391 | + {0x4e, 0x0f}, |
---|
| 392 | + {0x4f, 0xf0}, |
---|
| 393 | + {0x58, 0x80}, |
---|
| 394 | + {0x59, 0x80}, |
---|
| 395 | + {0x5a, 0x80}, |
---|
| 396 | + {0x5b, 0x80}, |
---|
| 397 | + {0x5c, 0x00}, |
---|
| 398 | + {0x5d, 0x00}, |
---|
| 399 | + {0x5e, 0x00}, |
---|
| 400 | + {0x5f, 0x00}, |
---|
| 401 | + {0x6b, 0x01}, |
---|
| 402 | + {0x6c, 0x00}, |
---|
| 403 | + {0x6d, 0x0c}, |
---|
| 404 | + |
---|
| 405 | + /*WB offset*/ |
---|
| 406 | + {0xfe, 0x01}, |
---|
| 407 | + {0xbf, 0x40}, |
---|
| 408 | + |
---|
| 409 | + /*Dark Sun*/ |
---|
| 410 | + {0xfe, 0x01}, |
---|
| 411 | + {0x68, 0x77}, |
---|
| 412 | + |
---|
| 413 | + /*DPC*/ |
---|
| 414 | + {0xfe, 0x01}, |
---|
| 415 | + {0x60, 0x00}, |
---|
| 416 | + {0x61, 0x10}, |
---|
| 417 | + {0x62, 0x60}, |
---|
| 418 | + {0x63, 0x30}, |
---|
| 419 | + {0x64, 0x00}, |
---|
| 420 | + |
---|
| 421 | + /* LSC */ |
---|
| 422 | + {0xfe, 0x01}, |
---|
| 423 | + {0xa8, 0x60}, |
---|
| 424 | + {0xa2, 0xd1}, |
---|
| 425 | + {0xc8, 0x57}, |
---|
| 426 | + {0xa1, 0xb8}, |
---|
| 427 | + {0xa3, 0x91}, |
---|
| 428 | + {0xc0, 0x50}, |
---|
| 429 | + {0xd0, 0x05}, |
---|
| 430 | + {0xd1, 0xb2}, |
---|
| 431 | + {0xd2, 0x1f}, |
---|
| 432 | + {0xd3, 0x00}, |
---|
| 433 | + {0xd4, 0x00}, |
---|
| 434 | + {0xd5, 0x00}, |
---|
| 435 | + {0xd6, 0x00}, |
---|
| 436 | + {0xd7, 0x00}, |
---|
| 437 | + {0xd8, 0x00}, |
---|
| 438 | + {0xd9, 0x00}, |
---|
| 439 | + {0xa4, 0x10}, |
---|
| 440 | + {0xa5, 0x20}, |
---|
| 441 | + {0xa6, 0x60}, |
---|
| 442 | + {0xa7, 0x80}, |
---|
| 443 | + {0xab, 0x18}, |
---|
| 444 | + {0xc7, 0xc0}, |
---|
| 445 | + |
---|
| 446 | + /*ABB*/ |
---|
| 447 | + {0xfe, 0x01}, |
---|
| 448 | + {0x20, 0x02}, |
---|
| 449 | + {0x21, 0x02}, |
---|
| 450 | + {0x23, 0x42}, |
---|
| 451 | + |
---|
| 452 | + /*MIPI*/ |
---|
| 453 | + {0xfe, 0x03}, |
---|
| 454 | + {0x01, 0x07}, |
---|
| 455 | + {0x02, 0x04}, |
---|
| 456 | + {0x04, 0x80}, |
---|
| 457 | + {0x11, 0x2b}, |
---|
| 458 | + {0x12, 0xf0}, //lwc 3264*5/4 |
---|
| 459 | + {0x13, 0x0f}, |
---|
| 460 | + {0x15, 0x10}, //LP |
---|
| 461 | + {0x16, 0x29}, |
---|
| 462 | + {0x17, 0xff}, |
---|
| 463 | + {0x18, 0x01}, |
---|
| 464 | + {0x19, 0xaa}, |
---|
| 465 | + {0x1a, 0x02}, |
---|
| 466 | + {0x21, 0x0c}, |
---|
| 467 | + {0x22, 0x0e}, |
---|
| 468 | + {0x23, 0x45}, |
---|
| 469 | + {0x24, 0x01}, |
---|
| 470 | + {0x25, 0x1c}, |
---|
| 471 | + {0x26, 0x0b}, |
---|
| 472 | + {0x29, 0x0e}, |
---|
| 473 | + {0x2a, 0x1d}, |
---|
| 474 | + {0x2b, 0x0b}, |
---|
| 475 | + {0xfe, 0x00}, |
---|
| 476 | + //{0x3f, 0x91}, |
---|
| 477 | + {0x3f, 0x00}, |
---|
| 478 | +#else |
---|
247 | 479 | /*SYS*/ |
---|
248 | 480 | {0xf2, 0x00}, |
---|
249 | 481 | {0xf4, 0x80}, |
---|
.. | .. |
---|
433 | 665 | {0xfe, 0x00}, |
---|
434 | 666 | //{0x3f, 0x91}, |
---|
435 | 667 | {0x3f, 0x00}, |
---|
436 | | - |
---|
| 668 | +#endif |
---|
437 | 669 | {REG_NULL, 0x00}, |
---|
438 | 670 | }; |
---|
439 | 671 | |
---|
| 672 | +#ifndef GC8034_2LANE_30FPS |
---|
440 | 673 | /* |
---|
441 | 674 | * Xclk 24Mhz |
---|
442 | 675 | * max_framerate 30fps |
---|
.. | .. |
---|
507 | 740 | |
---|
508 | 741 | {REG_NULL, 0x00}, |
---|
509 | 742 | }; |
---|
| 743 | +#endif |
---|
510 | 744 | |
---|
511 | 745 | /* |
---|
512 | 746 | * Xclk 24Mhz |
---|
.. | .. |
---|
514 | 748 | * mipi_datarate per lane 672Mbps |
---|
515 | 749 | */ |
---|
516 | 750 | static const struct regval gc8034_3264x2448_regs_2lane[] = { |
---|
| 751 | +#ifdef GC8034_2LANE_30FPS |
---|
| 752 | + /* SYS */ |
---|
| 753 | + {0xf2, 0x00}, |
---|
| 754 | + {0xf4, 0x90}, |
---|
| 755 | + {0xf5, 0x3d}, |
---|
| 756 | + {0xf6, 0x44}, |
---|
| 757 | + {0xf8, 0x63}, |
---|
| 758 | + {0xfa, 0x42}, |
---|
| 759 | + {0xf9, 0x00}, |
---|
| 760 | + {0xf7, 0x95}, |
---|
| 761 | + {0xfc, 0x00}, |
---|
| 762 | + {0xfc, 0x00}, |
---|
| 763 | + {0xfc, 0xea}, |
---|
| 764 | + {0xfe, 0x03}, |
---|
| 765 | + {0x03, 0x9a}, |
---|
| 766 | + {0xfc, 0xee}, |
---|
| 767 | + {0xfe, 0x00}, |
---|
| 768 | + {0x3f, 0x00}, |
---|
| 769 | + {0xfe, 0x10}, |
---|
| 770 | + {0xfe, 0x00}, |
---|
| 771 | + {0xfe, 0x10}, |
---|
| 772 | + {0xfe, 0x00}, |
---|
| 773 | + |
---|
| 774 | + /* ISP */ |
---|
| 775 | + {0xfe, 0x00}, |
---|
| 776 | + {0x80, 0x13}, |
---|
| 777 | + {0xad, 0x00}, |
---|
| 778 | + {0x66, 0x0c}, |
---|
| 779 | + {0xbc, 0x06}, |
---|
| 780 | + |
---|
| 781 | + /* Crop window */ |
---|
| 782 | + {0x90, 0x01}, |
---|
| 783 | + {0x92, FULL_STARTY}, |
---|
| 784 | + {0x94, FULL_STARTX}, |
---|
| 785 | + {0x95, 0x09}, |
---|
| 786 | + {0x96, 0x90}, |
---|
| 787 | + {0x97, 0x0c}, |
---|
| 788 | + {0x98, 0xc0}, |
---|
| 789 | + |
---|
| 790 | + /* MIPI */ |
---|
| 791 | + {0xfe, 0x03}, |
---|
| 792 | + {0x01, 0x07}, |
---|
| 793 | + {0x02, 0x04}, |
---|
| 794 | + {0x04, 0x80}, |
---|
| 795 | + {0x11, 0x2b}, |
---|
| 796 | + {0x12, 0xf0}, //lwc 3264*5/4 |
---|
| 797 | + {0x13, 0x0f}, |
---|
| 798 | + {0x15, 0x10}, //LP |
---|
| 799 | + {0x16, 0x29}, |
---|
| 800 | + {0x17, 0xff}, |
---|
| 801 | + {0x18, 0x01}, |
---|
| 802 | + {0x19, 0xaa}, |
---|
| 803 | + {0x1a, 0x02}, |
---|
| 804 | + {0x21, 0x0c}, |
---|
| 805 | + {0x22, 0x0c}, |
---|
| 806 | + {0x23, 0x56}, |
---|
| 807 | + {0x24, 0x00}, |
---|
| 808 | + {0x25, 0x1c}, |
---|
| 809 | + {0x26, 0x0b}, |
---|
| 810 | + {0x29, 0x0e}, |
---|
| 811 | + {0x2a, 0x1d}, |
---|
| 812 | + {0x2b, 0x0b}, |
---|
| 813 | + {0xfe, 0x00}, |
---|
| 814 | + //{0x3f, 0x91}, |
---|
| 815 | + {0x3f, 0x00}, |
---|
| 816 | +#else |
---|
517 | 817 | /*SYS*/ |
---|
518 | 818 | {0xf2, 0x00}, |
---|
519 | 819 | {0xf4, 0x80}, |
---|
.. | .. |
---|
570 | 870 | {0xfe, 0x00}, |
---|
571 | 871 | //{0x3f, 0x91}, |
---|
572 | 872 | {0x3f, 0x00}, |
---|
| 873 | +#endif |
---|
573 | 874 | {REG_NULL, 0x00}, |
---|
574 | 875 | }; |
---|
575 | 876 | |
---|
.. | .. |
---|
843 | 1144 | }; |
---|
844 | 1145 | |
---|
845 | 1146 | static const struct gc8034_mode supported_modes_2lane[] = { |
---|
| 1147 | +#ifdef GC8034_2LANE_30FPS |
---|
| 1148 | + { |
---|
| 1149 | + .width = 3264, |
---|
| 1150 | + .height = 2448, |
---|
| 1151 | + .max_fps = { |
---|
| 1152 | + .numerator = 10000, |
---|
| 1153 | + .denominator = 300000, |
---|
| 1154 | + }, |
---|
| 1155 | + .exp_def = 0x0900, |
---|
| 1156 | + .hts_def = 0x0858 * 2, |
---|
| 1157 | + .vts_def = 0x09c0, |
---|
| 1158 | + .mipi_freq_idx = 1, |
---|
| 1159 | + .global_reg_list = gc8034_global_regs_2lane, |
---|
| 1160 | + .reg_list = gc8034_3264x2448_regs_2lane, |
---|
| 1161 | + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, |
---|
| 1162 | + }, |
---|
| 1163 | +#else |
---|
846 | 1164 | { |
---|
847 | 1165 | .width = 3264, |
---|
848 | 1166 | .height = 2448, |
---|
.. | .. |
---|
853 | 1171 | .exp_def = 0x09a0, |
---|
854 | 1172 | .hts_def = 0x0858 * 2, |
---|
855 | 1173 | .vts_def = 0x09c4, |
---|
| 1174 | + .mipi_freq_idx = 0, |
---|
| 1175 | + .global_reg_list = gc8034_global_regs_2lane, |
---|
856 | 1176 | .reg_list = gc8034_3264x2448_regs_2lane, |
---|
| 1177 | + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, |
---|
857 | 1178 | }, |
---|
858 | 1179 | { |
---|
859 | 1180 | .width = 1632, |
---|
.. | .. |
---|
865 | 1186 | .exp_def = 0x09a0, |
---|
866 | 1187 | .hts_def = 0x0858 * 2, |
---|
867 | 1188 | .vts_def = 0x09c4, |
---|
| 1189 | + .mipi_freq_idx = 0, |
---|
| 1190 | + .global_reg_list = gc8034_global_regs_2lane, |
---|
868 | 1191 | .reg_list = gc8034_1632x1224_regs_2lane, |
---|
| 1192 | + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, |
---|
869 | 1193 | }, |
---|
| 1194 | +#endif |
---|
870 | 1195 | }; |
---|
871 | 1196 | |
---|
872 | 1197 | static const struct gc8034_mode supported_modes_4lane[] = { |
---|
.. | .. |
---|
880 | 1205 | .exp_def = 0x08c6, |
---|
881 | 1206 | .hts_def = 0x10b0, |
---|
882 | 1207 | .vts_def = 0x09c0, |
---|
| 1208 | + .mipi_freq_idx = 0, |
---|
| 1209 | + .global_reg_list = gc8034_global_regs_4lane, |
---|
883 | 1210 | .reg_list = gc8034_3264x2448_regs_4lane, |
---|
| 1211 | + .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0, |
---|
884 | 1212 | }, |
---|
885 | 1213 | }; |
---|
886 | 1214 | |
---|
.. | .. |
---|
888 | 1216 | |
---|
889 | 1217 | static const s64 link_freq_menu_items[] = { |
---|
890 | 1218 | GC8034_MIPI_FREQ_336MHZ, |
---|
| 1219 | + GC8034_MIPI_FREQ_634MHZ |
---|
891 | 1220 | }; |
---|
892 | 1221 | |
---|
893 | 1222 | /* Write registers up to 4 at a time */ |
---|
.. | .. |
---|
1017 | 1346 | __v4l2_ctrl_modify_range(gc8034->vblank, vblank_def, |
---|
1018 | 1347 | GC8034_VTS_MAX - mode->height, |
---|
1019 | 1348 | 1, vblank_def); |
---|
1020 | | - __v4l2_ctrl_s_ctrl(gc8034->link_freq, |
---|
1021 | | - link_freq_menu_items[0]); |
---|
| 1349 | + __v4l2_ctrl_s_ctrl(gc8034->vblank, vblank_def); |
---|
| 1350 | + __v4l2_ctrl_s_ctrl(gc8034->link_freq, mode->mipi_freq_idx); |
---|
1022 | 1351 | } |
---|
1023 | 1352 | |
---|
1024 | 1353 | mutex_unlock(&gc8034->mutex); |
---|
.. | .. |
---|
1089 | 1418 | struct gc8034 *gc8034 = to_gc8034(sd); |
---|
1090 | 1419 | const struct gc8034_mode *mode = gc8034->cur_mode; |
---|
1091 | 1420 | |
---|
1092 | | - mutex_lock(&gc8034->mutex); |
---|
1093 | 1421 | fi->interval = mode->max_fps; |
---|
1094 | | - mutex_unlock(&gc8034->mutex); |
---|
1095 | 1422 | |
---|
1096 | 1423 | return 0; |
---|
1097 | 1424 | } |
---|
1098 | 1425 | |
---|
| 1426 | +#ifdef RK_OTP |
---|
| 1427 | +static void gc8034_get_otp(struct otp_info *otp, |
---|
| 1428 | + struct rkmodule_inf *inf) |
---|
| 1429 | +{ |
---|
| 1430 | + u32 i, j; |
---|
| 1431 | + u32 w, h; |
---|
| 1432 | + |
---|
| 1433 | + /* awb */ |
---|
| 1434 | + if (otp->awb_data.flag) { |
---|
| 1435 | + inf->awb.flag = 1; |
---|
| 1436 | + inf->awb.r_value = otp->awb_data.r_ratio; |
---|
| 1437 | + inf->awb.b_value = otp->awb_data.b_ratio; |
---|
| 1438 | + inf->awb.gr_value = otp->awb_data.g_ratio; |
---|
| 1439 | + inf->awb.gb_value = 0x0; |
---|
| 1440 | + |
---|
| 1441 | + inf->awb.golden_r_value = otp->awb_data.r_golden; |
---|
| 1442 | + inf->awb.golden_b_value = otp->awb_data.b_golden; |
---|
| 1443 | + inf->awb.golden_gr_value = otp->awb_data.g_golden; |
---|
| 1444 | + inf->awb.golden_gb_value = 0x0; |
---|
| 1445 | + } |
---|
| 1446 | + |
---|
| 1447 | + /* lsc */ |
---|
| 1448 | + if (otp->lsc_data.flag) { |
---|
| 1449 | + inf->lsc.flag = 1; |
---|
| 1450 | + inf->lsc.width = otp->basic_data.size.width; |
---|
| 1451 | + inf->lsc.height = otp->basic_data.size.height; |
---|
| 1452 | + inf->lsc.table_size = otp->lsc_data.table_size; |
---|
| 1453 | + |
---|
| 1454 | + for (i = 0; i < 289; i++) { |
---|
| 1455 | + inf->lsc.lsc_r[i] = (otp->lsc_data.data[i * 2] << 8) | |
---|
| 1456 | + otp->lsc_data.data[i * 2 + 1]; |
---|
| 1457 | + inf->lsc.lsc_gr[i] = (otp->lsc_data.data[i * 2 + 578] << 8) | |
---|
| 1458 | + otp->lsc_data.data[i * 2 + 579]; |
---|
| 1459 | + inf->lsc.lsc_gb[i] = (otp->lsc_data.data[i * 2 + 1156] << 8) | |
---|
| 1460 | + otp->lsc_data.data[i * 2 + 1157]; |
---|
| 1461 | + inf->lsc.lsc_b[i] = (otp->lsc_data.data[i * 2 + 1734] << 8) | |
---|
| 1462 | + otp->lsc_data.data[i * 2 + 1735]; |
---|
| 1463 | + } |
---|
| 1464 | + } |
---|
| 1465 | + |
---|
| 1466 | + /* pdaf */ |
---|
| 1467 | + if (otp->pdaf_data.flag) { |
---|
| 1468 | + inf->pdaf.flag = 1; |
---|
| 1469 | + inf->pdaf.gainmap_width = otp->pdaf_data.gainmap_width; |
---|
| 1470 | + inf->pdaf.gainmap_height = otp->pdaf_data.gainmap_height; |
---|
| 1471 | + inf->pdaf.pd_offset = otp->pdaf_data.pd_offset; |
---|
| 1472 | + inf->pdaf.dcc_mode = otp->pdaf_data.dcc_mode; |
---|
| 1473 | + inf->pdaf.dcc_dir = otp->pdaf_data.dcc_dir; |
---|
| 1474 | + inf->pdaf.dccmap_width = otp->pdaf_data.dccmap_width; |
---|
| 1475 | + inf->pdaf.dccmap_height = otp->pdaf_data.dccmap_height; |
---|
| 1476 | + w = otp->pdaf_data.gainmap_width; |
---|
| 1477 | + h = otp->pdaf_data.gainmap_height; |
---|
| 1478 | + for (i = 0; i < h; i++) { |
---|
| 1479 | + for (j = 0; j < w; j++) { |
---|
| 1480 | + inf->pdaf.gainmap[i * w + j] = |
---|
| 1481 | + (otp->pdaf_data.gainmap[(i * w + j) * 2] << 8) | |
---|
| 1482 | + otp->pdaf_data.gainmap[(i * w + j) * 2 + 1]; |
---|
| 1483 | + } |
---|
| 1484 | + } |
---|
| 1485 | + w = otp->pdaf_data.dccmap_width; |
---|
| 1486 | + h = otp->pdaf_data.dccmap_height; |
---|
| 1487 | + for (i = 0; i < h; i++) { |
---|
| 1488 | + for (j = 0; j < w; j++) { |
---|
| 1489 | + inf->pdaf.dccmap[i * w + j] = |
---|
| 1490 | + (otp->pdaf_data.dccmap[(i * w + j) * 2] << 8) | |
---|
| 1491 | + otp->pdaf_data.dccmap[(i * w + j) * 2 + 1]; |
---|
| 1492 | + } |
---|
| 1493 | + } |
---|
| 1494 | + } |
---|
| 1495 | + |
---|
| 1496 | + /* af */ |
---|
| 1497 | + if (otp->af_data.flag) { |
---|
| 1498 | + inf->af.flag = 1; |
---|
| 1499 | + inf->af.dir_cnt = 1; |
---|
| 1500 | + inf->af.af_otp[0].vcm_start = otp->af_data.af_inf; |
---|
| 1501 | + inf->af.af_otp[0].vcm_end = otp->af_data.af_macro; |
---|
| 1502 | + inf->af.af_otp[0].vcm_dir = 0; |
---|
| 1503 | + } |
---|
| 1504 | + |
---|
| 1505 | +} |
---|
| 1506 | +#else |
---|
1099 | 1507 | #define DD_WIDTH 3284 |
---|
1100 | 1508 | #define DD_HEIGHT 2464 |
---|
1101 | 1509 | |
---|
.. | .. |
---|
1605 | 2013 | inf->af.af_otp[0].vcm_dir = otp->vcm_dir; |
---|
1606 | 2014 | } |
---|
1607 | 2015 | } |
---|
| 2016 | +#endif |
---|
1608 | 2017 | |
---|
1609 | 2018 | static void gc8034_get_module_inf(struct gc8034 *gc8034, |
---|
1610 | 2019 | struct rkmodule_inf *inf) |
---|
1611 | 2020 | { |
---|
| 2021 | +#ifdef RK_OTP |
---|
| 2022 | + struct otp_info *otp = gc8034->otp; |
---|
| 2023 | +#else |
---|
1612 | 2024 | struct gc8034_otp_info *otp = gc8034->otp; |
---|
| 2025 | +#endif |
---|
1613 | 2026 | |
---|
1614 | 2027 | strlcpy(inf->base.sensor, |
---|
1615 | 2028 | GC8034_NAME, |
---|
.. | .. |
---|
1632 | 2045 | mutex_unlock(&gc8034->mutex); |
---|
1633 | 2046 | } |
---|
1634 | 2047 | |
---|
| 2048 | +static int gc8034_get_channel_info(struct gc8034 *gc8034, struct rkmodule_channel_info *ch_info) |
---|
| 2049 | +{ |
---|
| 2050 | + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) |
---|
| 2051 | + return -EINVAL; |
---|
| 2052 | + ch_info->vc = gc8034->cur_mode->vc[ch_info->index]; |
---|
| 2053 | + ch_info->width = gc8034->cur_mode->width; |
---|
| 2054 | + ch_info->height = gc8034->cur_mode->height; |
---|
| 2055 | + ch_info->bus_fmt = GC8034_MEDIA_BUS_FMT; |
---|
| 2056 | + return 0; |
---|
| 2057 | +} |
---|
| 2058 | + |
---|
1635 | 2059 | static long gc8034_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
---|
1636 | 2060 | { |
---|
1637 | 2061 | struct gc8034 *gc8034 = to_gc8034(sd); |
---|
1638 | 2062 | long ret = 0; |
---|
1639 | 2063 | u32 stream = 0; |
---|
| 2064 | + struct rkmodule_channel_info *ch_info; |
---|
1640 | 2065 | |
---|
1641 | 2066 | switch (cmd) { |
---|
1642 | 2067 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1671 | 2096 | GC8034_MODE_SW_STANDBY); |
---|
1672 | 2097 | } |
---|
1673 | 2098 | break; |
---|
| 2099 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 2100 | + ch_info = (struct rkmodule_channel_info *)arg; |
---|
| 2101 | + ret = gc8034_get_channel_info(gc8034, ch_info); |
---|
| 2102 | + break; |
---|
1674 | 2103 | default: |
---|
1675 | 2104 | ret = -ENOTTY; |
---|
1676 | 2105 | break; |
---|
.. | .. |
---|
1688 | 2117 | struct rkmodule_awb_cfg *cfg; |
---|
1689 | 2118 | long ret = 0; |
---|
1690 | 2119 | u32 stream = 0; |
---|
| 2120 | + struct rkmodule_channel_info *ch_info; |
---|
1691 | 2121 | |
---|
1692 | 2122 | switch (cmd) { |
---|
1693 | 2123 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1698 | 2128 | } |
---|
1699 | 2129 | |
---|
1700 | 2130 | ret = gc8034_ioctl(sd, cmd, inf); |
---|
1701 | | - if (!ret) |
---|
| 2131 | + if (!ret) { |
---|
1702 | 2132 | ret = copy_to_user(up, inf, sizeof(*inf)); |
---|
| 2133 | + if (ret) |
---|
| 2134 | + ret = -EFAULT; |
---|
| 2135 | + } |
---|
1703 | 2136 | kfree(inf); |
---|
1704 | 2137 | break; |
---|
1705 | 2138 | case RKMODULE_AWB_CFG: |
---|
.. | .. |
---|
1712 | 2145 | ret = copy_from_user(cfg, up, sizeof(*cfg)); |
---|
1713 | 2146 | if (!ret) |
---|
1714 | 2147 | ret = gc8034_ioctl(sd, cmd, cfg); |
---|
| 2148 | + else |
---|
| 2149 | + ret = -EFAULT; |
---|
1715 | 2150 | kfree(cfg); |
---|
1716 | 2151 | break; |
---|
1717 | 2152 | case RKMODULE_SET_QUICK_STREAM: |
---|
1718 | 2153 | ret = copy_from_user(&stream, up, sizeof(u32)); |
---|
1719 | 2154 | if (!ret) |
---|
1720 | 2155 | ret = gc8034_ioctl(sd, cmd, &stream); |
---|
| 2156 | + else |
---|
| 2157 | + ret = -EFAULT; |
---|
| 2158 | + break; |
---|
| 2159 | + case RKMODULE_GET_CHANNEL_INFO: |
---|
| 2160 | + ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); |
---|
| 2161 | + if (!ch_info) { |
---|
| 2162 | + ret = -ENOMEM; |
---|
| 2163 | + return ret; |
---|
| 2164 | + } |
---|
| 2165 | + |
---|
| 2166 | + ret = gc8034_ioctl(sd, cmd, ch_info); |
---|
| 2167 | + if (!ret) { |
---|
| 2168 | + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); |
---|
| 2169 | + if (ret) |
---|
| 2170 | + ret = -EFAULT; |
---|
| 2171 | + } |
---|
| 2172 | + kfree(ch_info); |
---|
1721 | 2173 | break; |
---|
1722 | 2174 | default: |
---|
1723 | 2175 | ret = -ENOTTY; |
---|
.. | .. |
---|
1728 | 2180 | } |
---|
1729 | 2181 | #endif |
---|
1730 | 2182 | |
---|
| 2183 | +#ifndef RK_OTP |
---|
1731 | 2184 | /*--------------------------------------------------------------------------*/ |
---|
1732 | 2185 | static int gc8034_apply_otp(struct gc8034 *gc8034) |
---|
1733 | 2186 | { |
---|
.. | .. |
---|
1908 | 2361 | } |
---|
1909 | 2362 | return 0; |
---|
1910 | 2363 | } |
---|
| 2364 | +#endif |
---|
1911 | 2365 | |
---|
1912 | 2366 | static int __gc8034_start_stream(struct gc8034 *gc8034) |
---|
1913 | 2367 | { |
---|
1914 | 2368 | int ret; |
---|
1915 | | - |
---|
| 2369 | +#ifndef RK_OTP |
---|
1916 | 2370 | if (gc8034->otp) { |
---|
1917 | 2371 | ret = gc8034_otp_enable(gc8034); |
---|
1918 | 2372 | gc8034_check_prsel(gc8034); |
---|
.. | .. |
---|
1922 | 2376 | if (ret) |
---|
1923 | 2377 | return ret; |
---|
1924 | 2378 | } |
---|
| 2379 | +#endif |
---|
1925 | 2380 | ret = gc8034_write_array(gc8034->client, gc8034->cur_mode->reg_list); |
---|
1926 | 2381 | if (ret) |
---|
1927 | 2382 | return ret; |
---|
.. | .. |
---|
2006 | 2461 | { |
---|
2007 | 2462 | struct gc8034 *gc8034 = to_gc8034(sd); |
---|
2008 | 2463 | struct i2c_client *client = gc8034->client; |
---|
| 2464 | + const struct gc8034_mode *mode = gc8034->cur_mode; |
---|
2009 | 2465 | int ret = 0; |
---|
2010 | 2466 | |
---|
2011 | 2467 | dev_info(&client->dev, "%s(%d) on(%d)\n", __func__, __LINE__, on); |
---|
.. | .. |
---|
2022 | 2478 | goto unlock_and_return; |
---|
2023 | 2479 | } |
---|
2024 | 2480 | |
---|
2025 | | - ret = gc8034_write_array(gc8034->client, gc8034_global_regs); |
---|
| 2481 | + ret = gc8034_write_array(gc8034->client, mode->global_reg_list); |
---|
2026 | 2482 | if (ret) { |
---|
2027 | 2483 | v4l2_err(sd, "could not set init registers\n"); |
---|
2028 | 2484 | pm_runtime_put_noidle(&client->dev); |
---|
.. | .. |
---|
2047 | 2503 | return DIV_ROUND_UP(cycles, GC8034_XVCLK_FREQ / 1000 / 1000); |
---|
2048 | 2504 | } |
---|
2049 | 2505 | |
---|
| 2506 | +static int gc8034_enable_regulators(struct gc8034 *gc8034, |
---|
| 2507 | + struct regulator_bulk_data *consumers) |
---|
| 2508 | +{ |
---|
| 2509 | + int i, j; |
---|
| 2510 | + int ret = 0; |
---|
| 2511 | + struct device *dev = &gc8034->client->dev; |
---|
| 2512 | + int num_consumers = GC8034_NUM_SUPPLIES; |
---|
| 2513 | + |
---|
| 2514 | + for (i = 0; i < num_consumers; i++) { |
---|
| 2515 | + |
---|
| 2516 | + ret = regulator_enable(consumers[i].consumer); |
---|
| 2517 | + if (ret < 0) { |
---|
| 2518 | + dev_err(dev, "Failed to enable regulator: %s\n", |
---|
| 2519 | + consumers[i].supply); |
---|
| 2520 | + goto err; |
---|
| 2521 | + } |
---|
| 2522 | + } |
---|
| 2523 | + return 0; |
---|
| 2524 | +err: |
---|
| 2525 | + for (j = 0; j < i; j++) |
---|
| 2526 | + regulator_disable(consumers[j].consumer); |
---|
| 2527 | + |
---|
| 2528 | + return ret; |
---|
| 2529 | +} |
---|
| 2530 | + |
---|
2050 | 2531 | static int __gc8034_power_on(struct gc8034 *gc8034) |
---|
2051 | 2532 | { |
---|
2052 | 2533 | int ret; |
---|
.. | .. |
---|
2069 | 2550 | dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); |
---|
2070 | 2551 | if (clk_get_rate(gc8034->xvclk) != GC8034_XVCLK_FREQ) |
---|
2071 | 2552 | dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); |
---|
2072 | | - ret = clk_prepare_enable(gc8034->xvclk); |
---|
2073 | | - if (ret < 0) { |
---|
2074 | | - dev_err(dev, "Failed to enable xvclk\n"); |
---|
2075 | | - return ret; |
---|
2076 | | - } |
---|
| 2553 | + |
---|
2077 | 2554 | if (!IS_ERR(gc8034->reset_gpio)) |
---|
2078 | 2555 | gpiod_set_value_cansleep(gc8034->reset_gpio, 1); |
---|
2079 | 2556 | |
---|
2080 | | - ret = regulator_bulk_enable(GC8034_NUM_SUPPLIES, gc8034->supplies); |
---|
| 2557 | + ret = gc8034_enable_regulators(gc8034, gc8034->supplies); |
---|
2081 | 2558 | if (ret < 0) { |
---|
2082 | 2559 | dev_err(dev, "Failed to enable regulators\n"); |
---|
2083 | 2560 | goto disable_clk; |
---|
2084 | 2561 | } |
---|
2085 | 2562 | |
---|
| 2563 | + usleep_range(100, 200); |
---|
| 2564 | + ret = clk_prepare_enable(gc8034->xvclk); |
---|
| 2565 | + if (ret < 0) { |
---|
| 2566 | + dev_err(dev, "Failed to enable xvclk\n"); |
---|
| 2567 | + return ret; |
---|
| 2568 | + } |
---|
| 2569 | + |
---|
2086 | 2570 | usleep_range(1000, 1100); |
---|
| 2571 | + if (!IS_ERR(gc8034->pwdn_gpio)) |
---|
| 2572 | + gpiod_set_value_cansleep(gc8034->pwdn_gpio, 0); |
---|
| 2573 | + |
---|
| 2574 | + usleep_range(500, 1000); |
---|
2087 | 2575 | if (!IS_ERR(gc8034->reset_gpio)) |
---|
2088 | 2576 | gpiod_set_value_cansleep(gc8034->reset_gpio, 0); |
---|
2089 | 2577 | |
---|
2090 | | - usleep_range(500, 1000); |
---|
2091 | | - if (!IS_ERR(gc8034->pwdn_gpio)) |
---|
2092 | | - gpiod_set_value_cansleep(gc8034->pwdn_gpio, 0); |
---|
| 2578 | + usleep_range(6000, 7000); |
---|
2093 | 2579 | |
---|
2094 | 2580 | /* 8192 cycles prior to first SCCB transaction */ |
---|
2095 | 2581 | delay_us = gc8034_cal_delay(8192); |
---|
.. | .. |
---|
2109 | 2595 | |
---|
2110 | 2596 | if (!IS_ERR(gc8034->pwdn_gpio)) |
---|
2111 | 2597 | gpiod_set_value_cansleep(gc8034->pwdn_gpio, 1); |
---|
2112 | | - clk_disable_unprepare(gc8034->xvclk); |
---|
| 2598 | + |
---|
2113 | 2599 | if (!IS_ERR(gc8034->reset_gpio)) |
---|
2114 | 2600 | gpiod_set_value_cansleep(gc8034->reset_gpio, 1); |
---|
| 2601 | + |
---|
| 2602 | + clk_disable_unprepare(gc8034->xvclk); |
---|
2115 | 2603 | if (!IS_ERR_OR_NULL(gc8034->pins_sleep)) { |
---|
2116 | 2604 | ret = pinctrl_select_state(gc8034->pinctrl, |
---|
2117 | 2605 | gc8034->pins_sleep); |
---|
.. | .. |
---|
2124 | 2612 | regulator_bulk_disable(GC8034_NUM_SUPPLIES, gc8034->supplies); |
---|
2125 | 2613 | } |
---|
2126 | 2614 | |
---|
2127 | | -static int gc8034_runtime_resume(struct device *dev) |
---|
| 2615 | +static int __maybe_unused gc8034_runtime_resume(struct device *dev) |
---|
2128 | 2616 | { |
---|
2129 | 2617 | struct i2c_client *client = to_i2c_client(dev); |
---|
2130 | 2618 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
.. | .. |
---|
2133 | 2621 | return __gc8034_power_on(gc8034); |
---|
2134 | 2622 | } |
---|
2135 | 2623 | |
---|
2136 | | -static int gc8034_runtime_suspend(struct device *dev) |
---|
| 2624 | +static int __maybe_unused gc8034_runtime_suspend(struct device *dev) |
---|
2137 | 2625 | { |
---|
2138 | 2626 | struct i2c_client *client = to_i2c_client(dev); |
---|
2139 | 2627 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
.. | .. |
---|
2175 | 2663 | if (fie->index >= gc8034->cfg_num) |
---|
2176 | 2664 | return -EINVAL; |
---|
2177 | 2665 | |
---|
2178 | | - if (fie->code != GC8034_MEDIA_BUS_FMT) |
---|
2179 | | - return -EINVAL; |
---|
2180 | | - |
---|
| 2666 | + fie->code = GC8034_MEDIA_BUS_FMT; |
---|
2181 | 2667 | fie->width = supported_modes[fie->index].width; |
---|
2182 | 2668 | fie->height = supported_modes[fie->index].height; |
---|
2183 | 2669 | fie->interval = supported_modes[fie->index].max_fps; |
---|
2184 | 2670 | return 0; |
---|
2185 | 2671 | } |
---|
2186 | 2672 | |
---|
2187 | | -static int gc8034_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 2673 | +static int gc8034_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
---|
2188 | 2674 | struct v4l2_mbus_config *config) |
---|
2189 | 2675 | { |
---|
2190 | 2676 | struct gc8034 *sensor = to_gc8034(sd); |
---|
.. | .. |
---|
2193 | 2679 | dev_info(dev, "%s(%d) enter!\n", __func__, __LINE__); |
---|
2194 | 2680 | |
---|
2195 | 2681 | if (2 == sensor->lane_num) { |
---|
2196 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 2682 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
2197 | 2683 | config->flags = V4L2_MBUS_CSI2_2_LANE | |
---|
2198 | 2684 | V4L2_MBUS_CSI2_CHANNEL_0 | |
---|
2199 | 2685 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
2200 | 2686 | } else if (4 == sensor->lane_num) { |
---|
2201 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 2687 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
2202 | 2688 | config->flags = V4L2_MBUS_CSI2_4_LANE | |
---|
2203 | 2689 | V4L2_MBUS_CSI2_CHANNEL_0 | |
---|
2204 | 2690 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
.. | .. |
---|
2231 | 2717 | static const struct v4l2_subdev_video_ops gc8034_video_ops = { |
---|
2232 | 2718 | .s_stream = gc8034_s_stream, |
---|
2233 | 2719 | .g_frame_interval = gc8034_g_frame_interval, |
---|
2234 | | - .g_mbus_config = gc8034_g_mbus_config, |
---|
2235 | 2720 | }; |
---|
2236 | 2721 | |
---|
2237 | 2722 | static const struct v4l2_subdev_pad_ops gc8034_pad_ops = { |
---|
.. | .. |
---|
2240 | 2725 | .enum_frame_interval = gc8034_enum_frame_interval, |
---|
2241 | 2726 | .get_fmt = gc8034_get_fmt, |
---|
2242 | 2727 | .set_fmt = gc8034_set_fmt, |
---|
| 2728 | + .get_mbus_config = gc8034_g_mbus_config, |
---|
2243 | 2729 | }; |
---|
2244 | 2730 | |
---|
2245 | 2731 | static const struct v4l2_subdev_ops gc8034_subdev_ops = { |
---|
.. | .. |
---|
2388 | 2874 | switch (ctrl->id) { |
---|
2389 | 2875 | case V4L2_CID_EXPOSURE: |
---|
2390 | 2876 | /* 4 least significant bits of expsoure are fractional part */ |
---|
2391 | | - dev_info(&client->dev, "set exposure value 0x%x\n", ctrl->val); |
---|
| 2877 | + dev_dbg(&client->dev, "set exposure value 0x%x\n", ctrl->val); |
---|
2392 | 2878 | ret = gc8034_set_exposure_reg(gc8034, ctrl->val); |
---|
2393 | 2879 | break; |
---|
2394 | 2880 | case V4L2_CID_ANALOGUE_GAIN: |
---|
2395 | | - dev_info(&client->dev, "set analog gain value 0x%x\n", ctrl->val); |
---|
| 2881 | + dev_dbg(&client->dev, "set analog gain value 0x%x\n", ctrl->val); |
---|
2396 | 2882 | ret = gc8034_set_gain_reg(gc8034, ctrl->val); |
---|
2397 | 2883 | break; |
---|
2398 | 2884 | case V4L2_CID_VBLANK: |
---|
2399 | | - dev_info(&client->dev, "set vb value 0x%x\n", ctrl->val); |
---|
| 2885 | + dev_dbg(&client->dev, "set vb value 0x%x\n", ctrl->val); |
---|
2400 | 2886 | /* VB = VTS - 2448 -36, according android8.1 driver */ |
---|
2401 | 2887 | temp = ctrl->val + gc8034->cur_mode->height - 2448 - 36; |
---|
2402 | 2888 | ret = gc8034_write_reg(gc8034->client, |
---|
.. | .. |
---|
2440 | 2926 | handler->lock = &gc8034->mutex; |
---|
2441 | 2927 | |
---|
2442 | 2928 | gc8034->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, |
---|
2443 | | - V4L2_CID_LINK_FREQ, 0, 0, |
---|
| 2929 | + V4L2_CID_LINK_FREQ, |
---|
| 2930 | + ARRAY_SIZE(link_freq_menu_items) - 1, 0, |
---|
2444 | 2931 | link_freq_menu_items); |
---|
| 2932 | + v4l2_ctrl_s_ctrl(gc8034->link_freq, mode->mipi_freq_idx); |
---|
2445 | 2933 | |
---|
2446 | 2934 | v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, |
---|
2447 | 2935 | 0, gc8034->pixel_rate, 1, gc8034->pixel_rate); |
---|
.. | .. |
---|
2542 | 3030 | gc8034->cur_mode = &supported_modes_4lane[0]; |
---|
2543 | 3031 | supported_modes = supported_modes_4lane; |
---|
2544 | 3032 | gc8034->cfg_num = ARRAY_SIZE(supported_modes_4lane); |
---|
2545 | | - gc8034_global_regs = gc8034_global_regs_4lane; |
---|
2546 | 3033 | /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ |
---|
2547 | 3034 | fps = DIV_ROUND_CLOSEST(gc8034->cur_mode->max_fps.denominator, |
---|
2548 | 3035 | gc8034->cur_mode->max_fps.numerator); |
---|
.. | .. |
---|
2555 | 3042 | gc8034->cur_mode = &supported_modes_2lane[0]; |
---|
2556 | 3043 | supported_modes = supported_modes_2lane; |
---|
2557 | 3044 | gc8034->cfg_num = ARRAY_SIZE(supported_modes_2lane); |
---|
2558 | | - gc8034_global_regs = gc8034_global_regs_2lane; |
---|
2559 | 3045 | /*pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ |
---|
2560 | 3046 | fps = DIV_ROUND_CLOSEST(gc8034->cur_mode->max_fps.denominator, |
---|
2561 | 3047 | gc8034->cur_mode->max_fps.numerator); |
---|
.. | .. |
---|
2580 | 3066 | struct v4l2_subdev *sd; |
---|
2581 | 3067 | char facing[2]; |
---|
2582 | 3068 | int ret; |
---|
| 3069 | + struct device_node *eeprom_ctrl_node; |
---|
| 3070 | + struct i2c_client *eeprom_ctrl_client; |
---|
| 3071 | + struct v4l2_subdev *eeprom_ctrl; |
---|
| 3072 | + struct otp_info *otp_ptr; |
---|
2583 | 3073 | |
---|
2584 | 3074 | dev_info(dev, "driver version: %02x.%02x.%02x", |
---|
2585 | 3075 | DRIVER_VERSION >> 16, |
---|
.. | .. |
---|
2661 | 3151 | ret = gc8034_check_sensor_id(gc8034, client); |
---|
2662 | 3152 | if (ret) |
---|
2663 | 3153 | goto err_power_off; |
---|
2664 | | - |
---|
| 3154 | +#ifdef RK_OTP |
---|
| 3155 | + eeprom_ctrl_node = of_parse_phandle(node, "eeprom-ctrl", 0); |
---|
| 3156 | + if (eeprom_ctrl_node) { |
---|
| 3157 | + eeprom_ctrl_client = |
---|
| 3158 | + of_find_i2c_device_by_node(eeprom_ctrl_node); |
---|
| 3159 | + of_node_put(eeprom_ctrl_node); |
---|
| 3160 | + if (IS_ERR_OR_NULL(eeprom_ctrl_client)) { |
---|
| 3161 | + dev_err(dev, "can not get node\n"); |
---|
| 3162 | + goto continue_probe; |
---|
| 3163 | + } |
---|
| 3164 | + eeprom_ctrl = i2c_get_clientdata(eeprom_ctrl_client); |
---|
| 3165 | + if (IS_ERR_OR_NULL(eeprom_ctrl)) { |
---|
| 3166 | + dev_err(dev, "can not get eeprom i2c client\n"); |
---|
| 3167 | + } else { |
---|
| 3168 | + otp_ptr = devm_kzalloc(dev, sizeof(*otp_ptr), GFP_KERNEL); |
---|
| 3169 | + if (!otp_ptr) |
---|
| 3170 | + return -ENOMEM; |
---|
| 3171 | + ret = v4l2_subdev_call(eeprom_ctrl, |
---|
| 3172 | + core, ioctl, 0, otp_ptr); |
---|
| 3173 | + if (!ret) { |
---|
| 3174 | + gc8034->otp = otp_ptr; |
---|
| 3175 | + } else { |
---|
| 3176 | + gc8034->otp = NULL; |
---|
| 3177 | + devm_kfree(dev, otp_ptr); |
---|
| 3178 | + dev_warn(dev, "can not get otp info, skip!\n"); |
---|
| 3179 | + } |
---|
| 3180 | + } |
---|
| 3181 | + } |
---|
| 3182 | +continue_probe: |
---|
| 3183 | +#else |
---|
2665 | 3184 | gc8034_otp_enable(gc8034); |
---|
2666 | 3185 | gc8034_otp_read(gc8034); |
---|
2667 | 3186 | gc8034_otp_disable(gc8034); |
---|
| 3187 | +#endif |
---|
2668 | 3188 | |
---|
2669 | 3189 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API |
---|
2670 | 3190 | sd->internal_ops = &gc8034_internal_ops; |
---|