1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * nvp6188 driver
4 *
5 * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
6 *
7 * V0.0X01.0X00 first version.
8 * V0.0X01.0X01 version.
9 * 1. add get virtual channel fmt ioctl
10 * 2. add get virtual channel hotplug status ioctl
11 * 3. add virtual channel hotplug status event report to vicap
12 * 4. fixup variables are reused when multiple devices use the same driver
13 * V0.0X02.0X00 version.
14 * 1. update init registers setting
15 * 2. nvp6188 do not stream after writing registers setting
16 * 3. support detect fmt change when hotplug ahd camera
17 * 4. support 1600x1300 ahd camera input
18 */
19
20 //#define DEBUG
21 #include <linux/clk.h>
22 #include <linux/device.h>
23 #include <linux/delay.h>
24 #include <linux/gpio/consumer.h>
25 #include <linux/i2c.h>
26 #include <linux/module.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/sysfs.h>
30 #include <linux/slab.h>
31 #include <linux/version.h>
32 #include <linux/rk-camera-module.h>
33 #include <media/media-entity.h>
34 #include <media/v4l2-async.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-subdev.h>
37 #include <linux/pinctrl/consumer.h>
38 #include <linux/rk-preisp.h>
39 #include <linux/sched.h>
40 #include <linux/kthread.h>
41 #include <sound/core.h>
42 #include <sound/pcm.h>
43 #include <sound/pcm_params.h>
44 #include <sound/soc.h>
45 #include <sound/tlv.h>
46 #include <linux/platform_device.h>
47 #include <linux/input.h>
48 #include "nvp6188.h"
49
50 #define DRIVER_VERSION KERNEL_VERSION(0, 0x02, 0x0)
51
52 #ifndef V4L2_CID_DIGITAL_GAIN
53 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
54 #endif
55
56 #define NVP6188_XVCLK_FREQ 27000000
57 #define NVP6188_LINK_FREQ_1458M (1458000000UL >> 1)
58 #define NVP6188_LINK_FREQ_756M (756000000UL >> 1)
59
60 #define NVP6188_LANES 4
61 #define NVP6188_BITS_PER_SAMPLE 8
62
63 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
64
65 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
66 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
67
68 #define NVP6188_NAME "nvp6188"
69
70 #define _MIPI_PORT0_
71 //#define _MIPI_PORT1_
72
73 #define POWER_ALWAY_ON 1
74
75 #ifdef _MIPI_PORT0_
76 #define _MAR_BANK_ 0x20
77 #define _MTX_BANK_ 0x23
78 #else
79 #define _MAR_BANK_ 0x30
80 #define _MTX_BANK_ 0x33
81 #endif
82
83 #define NVP_RESO_960H_NSTC_VALUE 0x00
84 #define NVP_RESO_960H_PAL_VALUE 0x10
85 #define NVP_RESO_720P_NSTC_VALUE 0x20
86 #define NVP_RESO_720P_PAL_VALUE 0x21
87 #define NVP_RESO_1080P_NSTC_VALUE 0x30
88 #define NVP_RESO_1080P_PAL_VALUE 0x31
89 #define NVP_RESO_960P_NSTC_VALUE 0xa0
90 #define NVP_RESO_960P_PAL_VALUE 0xa1
91 #define NVP_RESO_1300P_NSTC_VALUE 0x3A
92 #define NVP_RESO_1300P_PAL_VALUE 0x3B
93
94 enum nvp6188_support_reso {
95 NVP_RESO_UNKOWN = 0,
96 NVP_RESO_960H_PAL,
97 NVP_RESO_720P_PAL,
98 NVP_RESO_960P_PAL,
99 NVP_RESO_1080P_PAL,
100 NVP_RESO_1300P_PAL,
101 NVP_RESO_960H_NSTC,
102 NVP_RESO_720P_NSTC,
103 NVP_RESO_960P_NSTC,
104 NVP_RESO_1080P_NSTC,
105 NVP_RESO_1300P_NSTC,
106 };
107
108 /* Audio output port formats */
109 enum nvp6188_audfmts {
110 AUDFMT_DISABLED = 0,
111 AUDFMT_I2S,
112 AUDFMT_DSP,
113 AUDFMT_SSP,
114 };
115
116 struct regval {
117 u8 addr;
118 u8 val;
119 };
120
121 struct nvp6188_mode {
122 u32 bus_fmt;
123 u32 width;
124 u32 height;
125 struct v4l2_fract max_fps;
126 u32 mipi_freq_idx;
127 u32 bpp;
128 const struct regval *global_reg_list;
129 const struct regval *reg_list;
130 u32 hdr_mode;
131 u32 vc[PAD_MAX];
132 u32 channel_reso[PAD_MAX];
133 u32 unkown_reso_count[PAD_MAX];
134 };
135
136 struct nvp6188_audio {
137 enum nvp6188_audfmts audfmt;
138 int mclk_fs;
139 };
140
141 struct nvp6188 {
142 struct i2c_client *client;
143 struct clk *xvclk;
144 struct gpio_desc *reset_gpio;
145 struct gpio_desc *power_gpio;
146 struct gpio_desc *vi_gpio;
147 struct pinctrl *pinctrl;
148 struct pinctrl_state *pins_default;
149 struct pinctrl_state *pins_sleep;
150 struct v4l2_subdev subdev;
151 struct media_pad pad;
152 struct v4l2_ctrl_handler ctrl_handler;
153 struct v4l2_ctrl *pixel_rate;
154 struct v4l2_ctrl *link_freq;
155 struct mutex mutex;
156 bool power_on;
157 struct nvp6188_mode cur_mode;
158 u32 module_index;
159 u32 cfg_num;
160 const char *module_facing;
161 const char *module_name;
162 const char *len_name;
163 struct nvp6188_audio *audio_in;
164 struct nvp6188_audio *audio_out;
165 int streaming;
166 struct task_struct *detect_thread;
167 struct input_dev* input_dev;
168 unsigned char detect_status;
169 unsigned char last_detect_status;
170 u8 is_reset;
171 bool disable_dump_register;
172 };
173
174 #define to_nvp6188(sd) container_of(sd, struct nvp6188, subdev)
175
176 static int nvp6188_audio_init(struct nvp6188 *nvp6188);
177 static int __nvp6188_start_stream(struct nvp6188 *nvp6188);
178 static int __nvp6188_stop_stream(struct nvp6188 *nvp6188);
179
180 // detect_status: bit 0~3 means channels plugin status : 1 no exist 0: exist
show_hotplug_status(struct device * dev,struct device_attribute * attr,char * buf)181 static ssize_t show_hotplug_status(struct device *dev,
182 struct device_attribute *attr,
183 char *buf)
184 {
185 struct i2c_client *client = to_i2c_client(dev);
186 struct v4l2_subdev *sd = i2c_get_clientdata(client);
187 struct nvp6188 *nvp6188 = to_nvp6188(sd);
188
189 return sprintf(buf, "%d\n", nvp6188->detect_status);
190 }
191
nvp6188_debug_func(struct device * dev,struct device_attribute * attr,char * buf)192 static ssize_t nvp6188_debug_func(struct device *dev,
193 struct device_attribute *attr,
194 char *buf)
195 {
196 struct i2c_client *client = to_i2c_client(dev);
197 struct v4l2_subdev *sd = i2c_get_clientdata(client);
198 struct nvp6188 *nvp6188 = to_nvp6188(sd);
199
200 nvp6188->disable_dump_register = (nvp6188->disable_dump_register) ? false : true;
201 return sprintf(buf, "switch disable_dump_register(%d)\n", nvp6188->disable_dump_register);
202 }
203
204 static DEVICE_ATTR(hotplug_status, S_IRUSR, show_hotplug_status, NULL);
205 static DEVICE_ATTR(nvp6188_debug, S_IRUSR, nvp6188_debug_func, NULL);
206 static struct attribute *dev_attrs[] = {
207 &dev_attr_hotplug_status.attr,
208 &dev_attr_nvp6188_debug.attr,
209 NULL,
210 };
211
212 static struct attribute_group dev_attr_grp = {
213 .attrs = dev_attrs,
214 };
215
216 static __maybe_unused const struct regval common_setting_756M_regs[] = {
217 {0xff, 0x00},
218 {0x80, 0x0f},
219 {0x00, 0x10},
220 {0x01, 0x10},
221 {0x02, 0x10},
222 {0x03, 0x10},
223 {0x22, 0x0b},
224 {0x23, 0x41},
225 {0x26, 0x0b},
226 {0x27, 0x41},
227 {0x2a, 0x0b},
228 {0x2b, 0x41},
229 {0x2e, 0x0b},
230 {0x2f, 0x41},
231
232 {0xff, 0x01},
233 {0x98, 0x30},
234 {0xed, 0x00},
235
236 {0xff, 0x05 + 0},
237 {0x00, 0xd0},
238 {0x01, 0x22},
239 {0x47, 0xee},
240 {0x50, 0xc6},
241 {0x57, 0x00},
242 {0x58, 0x77},
243 {0x5b, 0x41},
244 {0x5c, 0x78},
245 {0xB8, 0xB8},
246
247 {0xff, 0x05 + 1},
248 {0x00, 0xd0},
249 {0x01, 0x22},
250 {0x47, 0xee},
251 {0x50, 0xc6},
252 {0x57, 0x00},
253 {0x58, 0x77},
254 {0x5b, 0x41},
255 {0x5c, 0x78},
256 {0xB8, 0xB8},
257
258 {0xff, 0x05 + 2},
259 {0x00, 0xd0},
260 {0x01, 0x22},
261 {0x47, 0xee},
262 {0x50, 0xc6},
263 {0x57, 0x00},
264 {0x58, 0x77},
265 {0x5b, 0x41},
266 {0x5c, 0x78},
267 {0xB8, 0xB8},
268
269 {0xff, 0x05 + 3},
270 {0x00, 0xd0},
271 {0x01, 0x22},
272 {0x47, 0xee},
273 {0x50, 0xc6},
274 {0x57, 0x00},
275 {0x58, 0x77},
276 {0x5b, 0x41},
277 {0x5c, 0x78},
278 {0xB8, 0xB8},
279
280 {0xff, 0x09},
281 {0x50, 0x30},
282 {0x51, 0x6f},
283 {0x52, 0x67},
284 {0x53, 0x48},
285 {0x54, 0x30},
286 {0x55, 0x6f},
287 {0x56, 0x67},
288 {0x57, 0x48},
289 {0x58, 0x30},
290 {0x59, 0x6f},
291 {0x5a, 0x67},
292 {0x5b, 0x48},
293 {0x5c, 0x30},
294 {0x5d, 0x6f},
295 {0x5e, 0x67},
296 {0x5f, 0x48},
297
298 {0xff, 0x0a},
299 {0x25, 0x10},
300 {0x27, 0x1e},
301 {0x30, 0xac},
302 {0x31, 0x78},
303 {0x32, 0x17},
304 {0x33, 0xc1},
305 {0x34, 0x40},
306 {0x35, 0x00},
307 {0x36, 0xc3},
308 {0x37, 0x0a},
309 {0x38, 0x00},
310 {0x39, 0x02},
311 {0x3a, 0x00},
312 {0x3b, 0xb2},
313 {0xa5, 0x10},
314 {0xa7, 0x1e},
315 {0xb0, 0xac},
316 {0xb1, 0x78},
317 {0xb2, 0x17},
318 {0xb3, 0xc1},
319 {0xb4, 0x40},
320 {0xb5, 0x00},
321 {0xb6, 0xc3},
322 {0xb7, 0x0a},
323 {0xb8, 0x00},
324 {0xb9, 0x02},
325 {0xba, 0x00},
326 {0xbb, 0xb2},
327 {0xff, 0x0b},
328 {0x25, 0x10},
329 {0x27, 0x1e},
330 {0x30, 0xac},
331 {0x31, 0x78},
332 {0x32, 0x17},
333 {0x33, 0xc1},
334 {0x34, 0x40},
335 {0x35, 0x00},
336 {0x36, 0xc3},
337 {0x37, 0x0a},
338 {0x38, 0x00},
339 {0x39, 0x02},
340 {0x3a, 0x00},
341 {0x3b, 0xb2},
342 {0xa5, 0x10},
343 {0xa7, 0x1e},
344 {0xb0, 0xac},
345 {0xb1, 0x78},
346 {0xb2, 0x17},
347 {0xb3, 0xc1},
348 {0xb4, 0x40},
349 {0xb5, 0x00},
350 {0xb6, 0xc3},
351 {0xb7, 0x0a},
352 {0xb8, 0x00},
353 {0xb9, 0x02},
354 {0xba, 0x00},
355 {0xbb, 0xb2},
356
357 {0xff, 0x13},
358 {0x05, 0xa0},
359 {0x31, 0xff},
360 {0x07, 0x47},
361 {0x12, 0x04},
362 {0x1e, 0x1f},
363 {0x1f, 0x27},
364 {0x2e, 0x10},
365 {0x2f, 0xc8},
366 {0x31, 0xff},
367 {0x32, 0x00},
368 {0x33, 0x00},
369 {0x72, 0x05},
370 {0x7a, 0xf0},
371 {0xff, _MAR_BANK_},
372 {0x10, 0xff},
373 {0x11, 0xff},
374
375 {0x30, 0x0f},
376 {0x32, 0x92},
377 {0x34, 0xcd},
378 {0x36, 0x04},
379 {0x38, 0x58},
380
381 {0x3c, 0x01},
382 {0x3d, 0x11},
383 {0x3e, 0x11},
384 {0x45, 0x60},
385 {0x46, 0x49},
386
387 {0xff, _MTX_BANK_},
388 {0xe9, 0x03},
389 {0x03, 0x02},
390 {0x01, 0xe0},
391 {0x00, 0x7d},
392 {0x01, 0xe0},
393 {0x02, 0xa0},
394 {0x20, 0x1e},
395 {0x20, 0x1f},
396
397 {0x04, 0x38},
398 {0x45, 0xc4},
399 {0x46, 0x01},
400 {0x47, 0x1b},
401 {0x48, 0x08},
402 {0x65, 0xc4},
403 {0x66, 0x01},
404 {0x67, 0x1b},
405 {0x68, 0x08},
406 {0x85, 0xc4},
407 {0x86, 0x01},
408 {0x87, 0x1b},
409 {0x88, 0x08},
410 {0xa5, 0xc4},
411 {0xa6, 0x01},
412 {0xa7, 0x1b},
413 {0xa8, 0x08},
414 {0xc5, 0xc4},
415 {0xc6, 0x01},
416 {0xc7, 0x1b},
417 {0xc8, 0x08},
418 {0xeb, 0x8d},
419
420 {0xff, _MAR_BANK_},
421 {0x00, 0xff},
422 {0x40, 0x01},
423 {0x40, 0x00},
424 {0xff, 0x01},
425 {0x97, 0x00},
426 {0x97, 0x0f},
427
428 {0xff, 0x00}, //test pattern
429 {0x78, 0xba},
430 {0x79, 0xac},
431 {0xff, 0x05},
432 {0x2c, 0x08},
433 {0x6a, 0x80},
434 {0xff, 0x06},
435 {0x2c, 0x08},
436 {0x6a, 0x80},
437 {0xff, 0x07},
438 {0x2c, 0x08},
439 {0x6a, 0x80},
440 {0xff, 0x08},
441 {0x2c, 0x08},
442 {0x6a, 0x80},
443 };
444
445 static __maybe_unused const struct regval common_setting_1458M_regs[] = {
446 {0xff, 0x01},
447 {0x80, 0x40},
448 {0x98, 0x30},
449 {0x7a, 0x00},
450 {0xff, _MTX_BANK_},
451 {0xe9, 0x03},
452 {0x03, 0x02},
453 {0x04, 0x6c},
454 {0x08, 0x4f},
455 {0x01, 0xe4},
456 {0x00, 0x7d},
457 {0x01, 0xe0},
458 {0x20, 0x1e},
459 {0x20, 0x1f},
460 {0xeb, 0x8d},
461 {0x45, 0xcd},
462 {0x46, 0x42},
463 {0x47, 0x36},
464 {0x48, 0x0f},
465 {0x65, 0xcd},
466 {0x66, 0x42},
467 {0x67, 0x0e},
468 {0x68, 0x0f},
469 {0x85, 0xcd},
470 {0x86, 0x42},
471 {0x87, 0x0e},
472 {0x88, 0x0f},
473 {0xa5, 0xcd},
474 {0xa6, 0x42},
475 {0xa7, 0x0e},
476 {0xa8, 0x0f},
477 {0xc5, 0xcd},
478 {0xc6, 0x42},
479 {0xc7, 0x0e},
480 {0xc8, 0x0f},
481
482 {0xff, 0x05 + 0},
483 {0x01, 0x62},
484 {0x05, 0x04},
485 {0x08, 0x55},
486 {0x1b, 0x08},
487 {0x25, 0xdc},
488 {0x28, 0x80},
489 {0x2f, 0x00},
490 {0x30, 0xe0},
491 {0x31, 0x43},
492 {0x32, 0xa2},
493 {0x57, 0x00},
494 {0x58, 0x77},
495 {0x5b, 0x41},
496 {0x5c, 0x78},
497 {0x5f, 0x00},
498 {0x7b, 0x11},
499 {0x7c, 0x01},
500 {0x7d, 0x80},
501 {0x80, 0x00},
502 {0x90, 0x01},
503 {0xa9, 0x00},
504 {0xb5, 0x00},
505 {0xb9, 0x72},
506 {0xd1, 0x00},
507 {0xd5, 0x80},
508
509 {0xff, 0x05 + 1},
510 {0x01, 0x62},
511 {0x05, 0x04},
512 {0x08, 0x55},
513 {0x1b, 0x08},
514 {0x25, 0xdc},
515 {0x28, 0x80},
516 {0x2f, 0x00},
517 {0x30, 0xe0},
518 {0x31, 0x43},
519 {0x32, 0xa2},
520 {0x57, 0x00},
521 {0x58, 0x77},
522 {0x5b, 0x41},
523 {0x5c, 0x78},
524 {0x5f, 0x00},
525 {0x7b, 0x11},
526 {0x7c, 0x01},
527 {0x7d, 0x80},
528 {0x80, 0x00},
529 {0x90, 0x01},
530 {0xa9, 0x00},
531 {0xb5, 0x00},
532 {0xb9, 0x72},
533 {0xd1, 0x00},
534 {0xd5, 0x80},
535
536 {0xff, 0x05 + 2},
537 {0x01, 0x62},
538 {0x05, 0x04},
539 {0x08, 0x55},
540 {0x1b, 0x08},
541 {0x25, 0xdc},
542 {0x28, 0x80},
543 {0x2f, 0x00},
544 {0x30, 0xe0},
545 {0x31, 0x43},
546 {0x32, 0xa2},
547 {0x57, 0x00},
548 {0x58, 0x77},
549 {0x5b, 0x41},
550 {0x5c, 0x78},
551 {0x5f, 0x00},
552 {0x7b, 0x11},
553 {0x7c, 0x01},
554 {0x7d, 0x80},
555 {0x80, 0x00},
556 {0x90, 0x01},
557 {0xa9, 0x00},
558 {0xb5, 0x00},
559 {0xb9, 0x72},
560 {0xd1, 0x00},
561 {0xd5, 0x80},
562
563 {0xff, 0x05 + 3},
564 {0x01, 0x62},
565 {0x05, 0x04},
566 {0x08, 0x55},
567 {0x1b, 0x08},
568 {0x25, 0xdc},
569 {0x28, 0x80},
570 {0x2f, 0x00},
571 {0x30, 0xe0},
572 {0x31, 0x43},
573 {0x32, 0xa2},
574 {0x57, 0x00},
575 {0x58, 0x77},
576 {0x5b, 0x41},
577 {0x5c, 0x78},
578 {0x5f, 0x00},
579 {0x7b, 0x11},
580 {0x7c, 0x01},
581 {0x7d, 0x80},
582 {0x80, 0x00},
583 {0x90, 0x01},
584 {0xa9, 0x00},
585 {0xb5, 0x00},
586 {0xb9, 0x72},
587 {0xd1, 0x00},
588 {0xd5, 0x80},
589
590 {0xff, 0x09},
591 {0x50, 0x30},
592 {0x51, 0x6f},
593 {0x52, 0x67},
594 {0x53, 0x48},
595 {0x54, 0x30},
596 {0x55, 0x6f},
597 {0x56, 0x67},
598 {0x57, 0x48},
599 {0x58, 0x30},
600 {0x59, 0x6f},
601 {0x5a, 0x67},
602 {0x5b, 0x48},
603 {0x5c, 0x30},
604 {0x5d, 0x6f},
605 {0x5e, 0x67},
606 {0x5f, 0x48},
607 {0x96, 0x03},
608 {0xb6, 0x03},
609 {0xd6, 0x03},
610 {0xf6, 0x03},
611
612 {0xff, 0x0a},
613 {0x25, 0x10},
614 {0x27, 0x1e},
615 {0x30, 0xac},
616 {0x31, 0x78},
617 {0x32, 0x17},
618 {0x33, 0xc1},
619 {0x34, 0x40},
620 {0x35, 0x00},
621 {0x36, 0xc3},
622 {0x37, 0x0a},
623 {0x38, 0x00},
624 {0x39, 0x02},
625 {0x3a, 0x00},
626 {0x3b, 0xb2},
627 {0xa5, 0x10},
628 {0xa7, 0x1e},
629 {0xb0, 0xac},
630 {0xb1, 0x78},
631 {0xb2, 0x17},
632 {0xb3, 0xc1},
633 {0xb4, 0x40},
634 {0xb5, 0x00},
635 {0xb6, 0xc3},
636 {0xb7, 0x0a},
637 {0xb8, 0x00},
638 {0xb9, 0x02},
639 {0xba, 0x00},
640 {0xbb, 0xb2},
641 {0xff, 0x0b},
642 {0x25, 0x10},
643 {0x27, 0x1e},
644 {0x30, 0xac},
645 {0x31, 0x78},
646 {0x32, 0x17},
647 {0x33, 0xc1},
648 {0x34, 0x40},
649 {0x35, 0x00},
650 {0x36, 0xc3},
651 {0x37, 0x0a},
652 {0x38, 0x00},
653 {0x39, 0x02},
654 {0x3a, 0x00},
655 {0x3b, 0xb2},
656 {0xa5, 0x10},
657 {0xa7, 0x1e},
658 {0xb0, 0xac},
659 {0xb1, 0x78},
660 {0xb2, 0x17},
661 {0xb3, 0xc1},
662 {0xb4, 0x40},
663 {0xb5, 0x00},
664 {0xb6, 0xc3},
665 {0xb7, 0x0a},
666 {0xb8, 0x00},
667 {0xb9, 0x02},
668 {0xba, 0x00},
669 {0xbb, 0xb2},
670
671 {0xff, 0x00},
672 {0x00, 0x10},
673 {0x01, 0x10},
674 {0x02, 0x10},
675 {0x03, 0x10},
676 {0x22, 0x0b},
677 {0x23, 0x41},
678 {0x26, 0x0b},
679 {0x27, 0x41},
680 {0x2a, 0x0b},
681 {0x2b, 0x41},
682 {0x2e, 0x0b},
683 {0x2f, 0x41},
684
685 {0xff, 0x13},
686 {0x05, 0xa0},
687 {0x07, 0x47},
688 {0x12, 0x04},
689 {0x1e, 0x1f},
690 {0x1f, 0x27},
691 {0x2e, 0x10},
692 {0x2f, 0xc8},
693 {0x30, 0x00},
694 {0x31, 0xff},
695 {0x32, 0x00},
696 {0x33, 0x00},
697 {0x3a, 0xff},
698 {0x3b, 0xff},
699 {0x3c, 0xff},
700 {0x3d, 0xff},
701 {0x3e, 0xff},
702 {0x3f, 0x0f},
703 {0x70, 0x00},
704 {0x72, 0x05},
705 {0x7A, 0xf0},
706 {0x74, 0x00},
707 {0x76, 0x00},
708 {0x78, 0x00},
709 {0x75, 0xff},
710 {0x77, 0xff},
711 {0x79, 0xff},
712 {0x01, 0x0c},
713 {0x73, 0x23},
714 {0xff, _MAR_BANK_},
715 {0x40, 0x01},
716 {0x10, 0xff},
717 {0x11, 0xff},
718 {0x46, 0x49},
719 {0x45, 0x60},
720 {0x30, 0x0f},
721 {0x32, 0xff},
722 {0x34, 0xcd},
723 {0x36, 0x04},
724 {0x38, 0xff},
725 {0x07, 0x00},
726 {0x2a, 0x0a},
727 {0x3d, 0x11},
728 {0x3e, 0x11},
729 {0x3c, 0x01},
730 {0x1a, 0x92},
731 {0x1b, 0x00},
732 {0x1c, 0x00},
733 {0x05, 0x00},
734 {0x06, 0x00},
735 {0x0d, 0x01},
736 {0x00, 0x00},//mipi not enabled first
737 {0x40, 0x00},
738
739 {0xff, 0x01},
740 //{ 0x82, 0x12 },
741 {0x80, 0x61},
742 {0x80, 0x60},
743 {0xa0, 0x20},
744 {0xa1, 0x20},
745 {0xa2, 0x20},
746 {0xa3, 0x20},
747 {0xed, 0x00},
748
749 {0xff, 0x00},
750 {0x80, 0x0f},
751 {0x81, 0x02},
752 {0x82, 0x02},
753 {0x83, 0x02},
754 {0x84, 0x02},
755 {0x64, 0x01},
756 {0x65, 0x01},
757 {0x66, 0x01},
758 {0x67, 0x01},
759 {0x5c, 0x80},
760 {0x5d, 0x80},
761 {0x5e, 0x80},
762 {0x5f, 0x80},
763 {0xff, 0x01},
764 {0x84, 0x02},
765 {0x85, 0x02},
766 {0x86, 0x02},
767 {0x87, 0x02},
768 {0x8c, 0x40},
769 {0x8d, 0x40},
770 {0x8e, 0x40},
771 {0x8f, 0x40},
772 {0xff, 0x20},
773 {0x01, 0x00},
774 {0x12, 0xc0},
775 {0x13, 0x03},
776 {0x14, 0xc0},
777 {0x15, 0x03},
778 {0x16, 0xc0},
779 {0x17, 0x03},
780 {0x18, 0xc0},
781 {0x19, 0x03},
782 {0xff, 0x01},
783 {0x97, 0xf0},
784 {0x97, 0x0f},
785
786 {0xff, 0x00}, //test pattern
787 {0x78, 0x88},
788 {0x79, 0x88},
789 {0xff, 0x05},
790 {0x2c, 0x08},
791 {0x6a, 0x00},
792 {0xff, 0x06},
793 {0x2c, 0x08},
794 {0x6a, 0x00},
795 {0xff, 0x07},
796 {0x2c, 0x08},
797 {0x6a, 0x00},
798 {0xff, 0x08},
799 {0x2c, 0x08},
800 {0x6a, 0x00},
801 };
802
803 static struct nvp6188_mode supported_modes[] = {
804 {
805 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
806 .width = 1920,
807 .height = 1080,
808 .max_fps = {
809 .numerator = 10000,
810 .denominator = 250000,
811 },
812 .global_reg_list = common_setting_1458M_regs,
813 .mipi_freq_idx = 0,
814 .bpp = 8,
815 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
816 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
817 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
818 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
819 },
820 {
821 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
822 .width = 1280,
823 .height = 720,
824 .max_fps = {
825 .numerator = 10000,
826 .denominator = 250000,
827 },
828 .global_reg_list = common_setting_1458M_regs,
829 .mipi_freq_idx = 0,
830 .bpp = 8,
831 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
832 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
833 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
834 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
835 },
836 {
837 .bus_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
838 .width = 960,
839 .height = 480,
840 .max_fps = {
841 .numerator = 10000,
842 .denominator = 250000,
843 },
844 .global_reg_list = common_setting_1458M_regs,
845 .mipi_freq_idx = 0,
846 .bpp = 8,
847 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
848 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,
849 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_2,
850 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_3,
851 },
852 };
853
854 static const s64 link_freq_items[] = {
855 NVP6188_LINK_FREQ_1458M,
856 NVP6188_LINK_FREQ_756M,
857 };
858
859 /* sensor register write */
nvp6188_write_reg(struct i2c_client * client,u8 reg,u8 val)860 static int nvp6188_write_reg(struct i2c_client *client, u8 reg, u8 val)
861 {
862 struct i2c_msg msg;
863 u8 buf[2];
864 int ret;
865
866 buf[0] = reg & 0xFF;
867 buf[1] = val;
868
869 msg.addr = client->addr;
870 msg.flags = client->flags;
871 msg.buf = buf;
872 msg.len = sizeof(buf);
873
874 ret = i2c_transfer(client->adapter, &msg, 1);
875 if (ret >= 0) {
876 usleep_range(300, 400);
877 return 0;
878 }
879
880 dev_err(&client->dev,
881 "nvp6188 write reg(0x%x val:0x%x) failed !\n", reg, val);
882
883 return ret;
884 }
885
nvp6188_write_array(struct i2c_client * client,const struct regval * regs,int size)886 static int nvp6188_write_array(struct i2c_client *client,
887 const struct regval *regs, int size)
888 {
889 int i, ret = 0;
890
891 i = 0;
892 while (i < size) {
893 ret = nvp6188_write_reg(client, regs[i].addr, regs[i].val);
894 if (ret) {
895 dev_err(&client->dev, "%s failed !\n", __func__);
896 break;
897 }
898 i++;
899 }
900
901 return ret;
902 }
903
904 /* sensor register read */
nvp6188_read_reg(struct i2c_client * client,u8 reg,u8 * val)905 static int nvp6188_read_reg(struct i2c_client *client, u8 reg, u8 *val)
906 {
907 struct i2c_msg msg[2];
908 u8 buf[1];
909 int ret;
910
911 buf[0] = reg & 0xFF;
912
913 msg[0].addr = client->addr;
914 msg[0].flags = client->flags;
915 msg[0].buf = buf;
916 msg[0].len = sizeof(buf);
917
918 msg[1].addr = client->addr;
919 msg[1].flags = client->flags | I2C_M_RD;
920 msg[1].buf = buf;
921 msg[1].len = 1;
922
923 ret = i2c_transfer(client->adapter, msg, 2);
924 if (ret >= 0) {
925 *val = buf[0];
926 return 0;
927 }
928
929 dev_err(&client->dev, "nvp6188 read reg(0x%x) failed !\n", reg);
930
931 return ret;
932 }
933
nv6188_read_htotal(struct nvp6188 * nvp6188,unsigned char ch)934 static int nv6188_read_htotal(struct nvp6188 *nvp6188, unsigned char ch)
935 {
936 int ch_htotal = 0;
937 unsigned char val_5xf2 = 0, val_5xf3 = 0;
938 struct i2c_client *client = nvp6188->client;
939
940 nvp6188_write_reg(client, 0xff, 0x05 + ch);
941 nvp6188_read_reg(client, 0xf2, &val_5xf2);
942 nvp6188_read_reg(client, 0xf3, &val_5xf3);
943 ch_htotal = ((val_5xf3 << 8) | val_5xf2);
944
945 return ch_htotal;
946 }
947
nv6188_read_vfc(struct nvp6188 * nvp6188,unsigned char ch)948 static unsigned char nv6188_read_vfc(struct nvp6188 *nvp6188, unsigned char ch)
949 {
950 unsigned char ch_vfc = 0xff;
951 struct i2c_client *client = nvp6188->client;
952
953 nvp6188_write_reg(client, 0xff, 0x05 + ch);
954 nvp6188_read_reg(client, 0xf0, &ch_vfc);
955
956 return ch_vfc;
957 }
958
nvp6188_auto_detect_hotplug(struct nvp6188 * nvp6188)959 static __maybe_unused int nvp6188_auto_detect_hotplug(struct nvp6188 *nvp6188)
960 {
961 int ret = 0;
962 struct i2c_client *client = nvp6188->client;
963 nvp6188_write_reg(client, 0xff, 0x00);
964 nvp6188_read_reg(client, 0xa8, &nvp6188->detect_status);
965 //nvp6188->detect_status = ~nvp6188->detect_status;
966 return ret;
967 }
968
nvp6188_get_reso_dist(const struct nvp6188_mode * mode,struct v4l2_mbus_framefmt * framefmt)969 static int nvp6188_get_reso_dist(const struct nvp6188_mode *mode,
970 struct v4l2_mbus_framefmt *framefmt)
971 {
972 return abs(mode->width - framefmt->width) +
973 abs(mode->height - framefmt->height);
974 }
975
976 static struct nvp6188_mode *
nvp6188_find_best_fit(struct nvp6188 * nvp6188,struct v4l2_subdev_format * fmt)977 nvp6188_find_best_fit(struct nvp6188 *nvp6188,
978 struct v4l2_subdev_format *fmt)
979 {
980 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
981 int dist;
982 int cur_best_fit = 0;
983 int cur_best_fit_dist = -1;
984 unsigned int i;
985
986 for (i = 0; i < nvp6188->cfg_num; i++) {
987 dist = nvp6188_get_reso_dist(&supported_modes[i], framefmt);
988 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
989 supported_modes[i].bus_fmt == framefmt->code) {
990 cur_best_fit_dist = dist;
991 cur_best_fit = i;
992 }
993 }
994
995 return &supported_modes[cur_best_fit];
996 }
997
nvp6188_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)998 static int nvp6188_set_fmt(struct v4l2_subdev *sd,
999 struct v4l2_subdev_pad_config *cfg,
1000 struct v4l2_subdev_format *fmt)
1001 {
1002 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1003 struct nvp6188_mode *mode;
1004 u64 pixel_rate = 0;
1005
1006 mutex_lock(&nvp6188->mutex);
1007
1008 mode = nvp6188_find_best_fit(nvp6188, fmt);
1009 memcpy(&nvp6188->cur_mode, mode, sizeof(struct nvp6188_mode));
1010
1011 fmt->format.code = mode->bus_fmt;
1012 fmt->format.width = mode->width;
1013 fmt->format.height = mode->height;
1014 fmt->format.field = V4L2_FIELD_NONE;
1015 fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
1016
1017 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1018 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1019 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
1020 #else
1021 mutex_unlock(&nvp6188->mutex);
1022 return -ENOTTY;
1023 #endif
1024 } else {
1025 __v4l2_ctrl_s_ctrl(nvp6188->link_freq, mode->mipi_freq_idx);
1026 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * NVP6188_LANES;
1027 __v4l2_ctrl_s_ctrl_int64(nvp6188->pixel_rate, pixel_rate);
1028 dev_info(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
1029 dev_info(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
1030 }
1031
1032 mutex_unlock(&nvp6188->mutex);
1033 return 0;
1034 }
1035
nvp6188_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1036 static int nvp6188_get_fmt(struct v4l2_subdev *sd,
1037 struct v4l2_subdev_pad_config *cfg,
1038 struct v4l2_subdev_format *fmt)
1039 {
1040 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1041 struct i2c_client *client = nvp6188->client;
1042
1043 const struct nvp6188_mode *mode = &nvp6188->cur_mode;
1044
1045 mutex_lock(&nvp6188->mutex);
1046 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1047 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1048 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1049 #else
1050 mutex_unlock(&nvp6188->mutex);
1051 return -ENOTTY;
1052 #endif
1053 } else {
1054 fmt->format.width = mode->width;
1055 fmt->format.height = mode->height;
1056 fmt->format.code = mode->bus_fmt;
1057 fmt->format.field = V4L2_FIELD_NONE;
1058 if (fmt->pad < PAD_MAX && fmt->pad > PAD0)
1059 fmt->reserved[0] = mode->vc[fmt->pad];
1060 else
1061 fmt->reserved[0] = mode->vc[PAD0];
1062 }
1063 mutex_unlock(&nvp6188->mutex);
1064
1065 dev_dbg(&client->dev, "%s: %x %dx%d vc %x\n",
1066 __func__, fmt->format.code,
1067 fmt->format.width, fmt->format.height, fmt->pad);
1068
1069 return 0;
1070 }
1071
nvp6188_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)1072 static int nvp6188_enum_mbus_code(struct v4l2_subdev *sd,
1073 struct v4l2_subdev_pad_config *cfg,
1074 struct v4l2_subdev_mbus_code_enum *code)
1075 {
1076 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1077
1078 if (code->index != 0)
1079 return -EINVAL;
1080 code->code = nvp6188->cur_mode.bus_fmt;
1081
1082 return 0;
1083 }
1084
nvp6188_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)1085 static int nvp6188_enum_frame_interval(struct v4l2_subdev *sd,
1086 struct v4l2_subdev_pad_config *cfg,
1087 struct v4l2_subdev_frame_interval_enum *fie)
1088 {
1089 if (fie->index >= ARRAY_SIZE(supported_modes))
1090 return -EINVAL;
1091
1092 fie->code = supported_modes[fie->index].bus_fmt;
1093 fie->width = supported_modes[fie->index].width;
1094 fie->height = supported_modes[fie->index].height;
1095 fie->interval = supported_modes[fie->index].max_fps;
1096
1097 return 0;
1098 }
1099
nvp6188_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)1100 static int nvp6188_enum_frame_sizes(struct v4l2_subdev *sd,
1101 struct v4l2_subdev_pad_config *cfg,
1102 struct v4l2_subdev_frame_size_enum *fse)
1103 {
1104 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1105 struct i2c_client *client = nvp6188->client;
1106
1107 dev_dbg(&client->dev, "%s:\n", __func__);
1108
1109 if (fse->index >= nvp6188->cfg_num)
1110 return -EINVAL;
1111
1112 if (fse->code != supported_modes[fse->index].bus_fmt)
1113 return -EINVAL;
1114
1115 fse->min_width = supported_modes[fse->index].width;
1116 fse->max_width = supported_modes[fse->index].width;
1117 fse->max_height = supported_modes[fse->index].height;
1118 fse->min_height = supported_modes[fse->index].height;
1119 return 0;
1120 }
1121
nvp6188_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * cfg)1122 static int nvp6188_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
1123 struct v4l2_mbus_config *cfg)
1124 {
1125 cfg->type = V4L2_MBUS_CSI2_DPHY;
1126 cfg->flags = V4L2_MBUS_CSI2_4_LANE |
1127 V4L2_MBUS_CSI2_CHANNELS;
1128
1129 return 0;
1130 }
1131
nvp6188_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)1132 static int nvp6188_g_frame_interval(struct v4l2_subdev *sd,
1133 struct v4l2_subdev_frame_interval *fi)
1134 {
1135 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1136 const struct nvp6188_mode *mode = &nvp6188->cur_mode;
1137
1138 mutex_lock(&nvp6188->mutex);
1139 fi->interval = mode->max_fps;
1140 mutex_unlock(&nvp6188->mutex);
1141
1142 return 0;
1143 }
1144
nvp6188_get_module_inf(struct nvp6188 * nvp6188,struct rkmodule_inf * inf)1145 static void nvp6188_get_module_inf(struct nvp6188 *nvp6188,
1146 struct rkmodule_inf *inf)
1147 {
1148 memset(inf, 0, sizeof(*inf));
1149 strscpy(inf->base.sensor, NVP6188_NAME, sizeof(inf->base.sensor));
1150 strscpy(inf->base.module, nvp6188->module_name,
1151 sizeof(inf->base.module));
1152 strscpy(inf->base.lens, nvp6188->len_name, sizeof(inf->base.lens));
1153 }
1154
nvp6188_get_vc_fmt_inf(struct nvp6188 * nvp6188,struct rkmodule_vc_fmt_info * inf)1155 static void nvp6188_get_vc_fmt_inf(struct nvp6188 *nvp6188,
1156 struct rkmodule_vc_fmt_info *inf)
1157 {
1158 int ch = 0;
1159 static u32 last_channel_reso[PAD_MAX] = {NVP_RESO_UNKOWN};
1160 memset(inf, 0, sizeof(*inf));
1161
1162 for (ch = 0; ch < PAD_MAX; ch++) {
1163 //Maintain last resolution modify by cairufan
1164 if (nvp6188->cur_mode.channel_reso[ch] != NVP_RESO_UNKOWN)
1165 last_channel_reso[ch] = nvp6188->cur_mode.channel_reso[ch];
1166
1167 switch (last_channel_reso[ch]) {
1168 case NVP_RESO_960H_NSTC:
1169 inf->width[ch] = 960;
1170 inf->height[ch] = 576;
1171 inf->fps[ch] = 30;
1172 break;
1173 case NVP_RESO_960H_PAL:
1174 inf->width[ch] = 960;
1175 inf->height[ch] = 576;
1176 inf->fps[ch] = 25;
1177 break;
1178 case NVP_RESO_960P_PAL:
1179 inf->width[ch] = 1280;
1180 inf->height[ch] = 960;
1181 inf->fps[ch] = 25;
1182 break;
1183 case NVP_RESO_960P_NSTC:
1184 inf->width[ch] = 1280;
1185 inf->height[ch] = 960;
1186 inf->fps[ch] = 30;
1187 break;
1188 case NVP_RESO_720P_PAL:
1189 inf->width[ch] = 1280;
1190 inf->height[ch] = 720;
1191 inf->fps[ch] = 25;
1192 break;
1193 case NVP_RESO_720P_NSTC:
1194 inf->width[ch] = 1280;
1195 inf->height[ch] = 720;
1196 inf->fps[ch] = 30;
1197 break;
1198 case NVP_RESO_1080P_PAL:
1199 inf->width[ch] = 1920;
1200 inf->height[ch] = 1080;
1201 inf->fps[ch] = 25;
1202 break;
1203 case NVP_RESO_1300P_NSTC:
1204 inf->width[ch] = 1600;
1205 inf->height[ch] = 1300;
1206 inf->fps[ch] = 30;
1207 break;
1208 case NVP_RESO_1300P_PAL:
1209 inf->width[ch] = 1600;
1210 inf->height[ch] = 1300;
1211 inf->fps[ch] = 25;
1212 break;
1213 case NVP_RESO_1080P_NSTC:
1214 default:
1215 inf->width[ch] = 1920;
1216 inf->height[ch] = 1080;
1217 inf->fps[ch] = 30;
1218 break;
1219 }
1220 }
1221 }
1222
nvp6188_get_vc_hotplug_inf(struct nvp6188 * nvp6188,struct rkmodule_vc_hotplug_info * inf)1223 static void nvp6188_get_vc_hotplug_inf(struct nvp6188 *nvp6188,
1224 struct rkmodule_vc_hotplug_info *inf)
1225 {
1226 memset(inf, 0, sizeof(*inf));
1227 //nvp6188_auto_detect_hotplug(nvp6188);
1228 inf->detect_status = nvp6188->detect_status;
1229 }
1230
nvp6188_get_vicap_rst_inf(struct nvp6188 * nvp6188,struct rkmodule_vicap_reset_info * rst_info)1231 static void nvp6188_get_vicap_rst_inf(struct nvp6188 *nvp6188,
1232 struct rkmodule_vicap_reset_info *rst_info)
1233 {
1234 rst_info->is_reset = nvp6188->is_reset;
1235 rst_info->src = RKCIF_RESET_SRC_ERR_HOTPLUG;
1236 }
1237
nvp6188_set_vicap_rst_inf(struct nvp6188 * nvp6188,struct rkmodule_vicap_reset_info rst_info)1238 static void nvp6188_set_vicap_rst_inf(struct nvp6188 *nvp6188,
1239 struct rkmodule_vicap_reset_info rst_info)
1240 {
1241 nvp6188->is_reset = rst_info.is_reset;
1242 }
1243
nvp6188_set_streaming(struct nvp6188 * nvp6188,int on)1244 static void nvp6188_set_streaming(struct nvp6188 *nvp6188, int on)
1245 {
1246 struct i2c_client *client = nvp6188->client;
1247
1248 dev_info(&client->dev, "%s: on: %d\n", __func__, on);
1249 if (!on)
1250 usleep_range(40 * 1000, 50 * 1000);
1251 }
1252
nvp6188_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)1253 static long nvp6188_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1254 {
1255 struct nvp6188 *nvp6188 = to_nvp6188(sd);
1256 long ret = 0;
1257 u32 stream = 0;
1258
1259 switch (cmd) {
1260 case RKMODULE_GET_MODULE_INFO:
1261 nvp6188_get_module_inf(nvp6188, (struct rkmodule_inf *)arg);
1262 break;
1263 case RKMODULE_GET_VC_FMT_INFO:
1264 nvp6188_get_vc_fmt_inf(nvp6188, (struct rkmodule_vc_fmt_info *)arg);
1265 break;
1266 case RKMODULE_GET_VC_HOTPLUG_INFO:
1267 nvp6188_get_vc_hotplug_inf(nvp6188, (struct rkmodule_vc_hotplug_info *)arg);
1268 break;
1269 case RKMODULE_GET_VICAP_RST_INFO:
1270 nvp6188_get_vicap_rst_inf(nvp6188, (struct rkmodule_vicap_reset_info *)arg);
1271 break;
1272 case RKMODULE_SET_VICAP_RST_INFO:
1273 nvp6188_set_vicap_rst_inf(nvp6188, *(struct rkmodule_vicap_reset_info *)arg);
1274 break;
1275 case RKMODULE_GET_START_STREAM_SEQ:
1276 *(int *)arg = RKMODULE_START_STREAM_FRONT;
1277 break;
1278 case RKMODULE_SET_QUICK_STREAM:
1279 stream = *((u32 *)arg);
1280 nvp6188_set_streaming(nvp6188, !!stream);
1281 break;
1282 default:
1283 ret = -ENOTTY;
1284 break;
1285 }
1286
1287 return ret;
1288 }
1289
1290 #ifdef CONFIG_COMPAT
nvp6188_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)1291 static long nvp6188_compat_ioctl32(struct v4l2_subdev *sd,
1292 unsigned int cmd, unsigned long arg)
1293 {
1294 void __user *up = compat_ptr(arg);
1295 struct rkmodule_inf *inf;
1296 struct rkmodule_awb_cfg *cfg;
1297 struct rkmodule_vc_fmt_info *vc_fmt_inf;
1298 struct rkmodule_vc_hotplug_info *vc_hp_inf;
1299 struct rkmodule_vicap_reset_info *vicap_rst_inf;
1300 int *seq;
1301 long ret = 0;
1302
1303 switch (cmd) {
1304 case RKMODULE_GET_MODULE_INFO:
1305 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
1306 if (!inf) {
1307 ret = -ENOMEM;
1308 return ret;
1309 }
1310
1311 ret = nvp6188_ioctl(sd, cmd, inf);
1312 if (!ret) {
1313 ret = copy_to_user(up, inf, sizeof(*inf));
1314 if (ret)
1315 ret = -EFAULT;
1316 }
1317 kfree(inf);
1318 break;
1319 case RKMODULE_AWB_CFG:
1320 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1321 if (!cfg) {
1322 ret = -ENOMEM;
1323 return ret;
1324 }
1325
1326 ret = copy_from_user(cfg, up, sizeof(*cfg));
1327 if (!ret)
1328 ret = nvp6188_ioctl(sd, cmd, cfg);
1329 else
1330 ret = -EFAULT;
1331 kfree(cfg);
1332 break;
1333 case RKMODULE_GET_VC_FMT_INFO:
1334 vc_fmt_inf = kzalloc(sizeof(*vc_fmt_inf), GFP_KERNEL);
1335 if (!vc_fmt_inf) {
1336 ret = -ENOMEM;
1337 return ret;
1338 }
1339
1340 ret = nvp6188_ioctl(sd, cmd, vc_fmt_inf);
1341 if (!ret) {
1342 ret = copy_to_user(up, vc_fmt_inf, sizeof(*vc_fmt_inf));
1343 if (ret)
1344 ret = -EFAULT;
1345 }
1346 kfree(vc_fmt_inf);
1347 break;
1348 case RKMODULE_GET_VC_HOTPLUG_INFO:
1349 vc_hp_inf = kzalloc(sizeof(*vc_hp_inf), GFP_KERNEL);
1350 if (!vc_hp_inf) {
1351 ret = -ENOMEM;
1352 return ret;
1353 }
1354
1355 ret = nvp6188_ioctl(sd, cmd, vc_hp_inf);
1356 if (!ret) {
1357 ret = copy_to_user(up, vc_hp_inf, sizeof(*vc_hp_inf));
1358 if (ret)
1359 ret = -EFAULT;
1360 }
1361 kfree(vc_hp_inf);
1362 break;
1363 case RKMODULE_GET_VICAP_RST_INFO:
1364 vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
1365 if (!vicap_rst_inf) {
1366 ret = -ENOMEM;
1367 return ret;
1368 }
1369
1370 ret = nvp6188_ioctl(sd, cmd, vicap_rst_inf);
1371 if (!ret) {
1372 ret = copy_to_user(up, vicap_rst_inf, sizeof(*vicap_rst_inf));
1373 if (ret)
1374 ret = -EFAULT;
1375 }
1376 kfree(vicap_rst_inf);
1377 break;
1378 case RKMODULE_SET_VICAP_RST_INFO:
1379 vicap_rst_inf = kzalloc(sizeof(*vicap_rst_inf), GFP_KERNEL);
1380 if (!vicap_rst_inf) {
1381 ret = -ENOMEM;
1382 return ret;
1383 }
1384
1385 ret = copy_from_user(vicap_rst_inf, up, sizeof(*vicap_rst_inf));
1386 if (!ret)
1387 ret = nvp6188_ioctl(sd, cmd, vicap_rst_inf);
1388 else
1389 ret = -EFAULT;
1390 kfree(vicap_rst_inf);
1391 break;
1392 case RKMODULE_GET_START_STREAM_SEQ:
1393 seq = kzalloc(sizeof(*seq), GFP_KERNEL);
1394 if (!seq) {
1395 ret = -ENOMEM;
1396 return ret;
1397 }
1398
1399 ret = nvp6188_ioctl(sd, cmd, seq);
1400 if (!ret) {
1401 ret = copy_to_user(up, seq, sizeof(*seq));
1402 if (ret)
1403 ret = -EFAULT;
1404 }
1405 kfree(seq);
1406 break;
1407 default:
1408 ret = -ENOIOCTLCMD;
1409 break;
1410 }
1411
1412 return ret;
1413 }
1414 #endif
1415
1416 /*
1417 * 1280x960p
1418 * dev:0x60 / 0x62 / 0x64 / 0x66
1419 * ch : 0 ~ 3
1420 * ntpal: 1:25p, 0:30p
1421 */
nv6188_set_chn_960p(struct nvp6188 * nvp6188,u8 ch,u8 ntpal)1422 static __maybe_unused void nv6188_set_chn_960p(struct nvp6188 *nvp6188, u8 ch,
1423 u8 ntpal)
1424
1425 {
1426 unsigned char val_0x54 = 0, val_20x01 = 0;
1427 struct i2c_client *client = nvp6188->client;
1428
1429 dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
1430
1431 nvp6188_write_reg(client, 0xff, 0x00);
1432 nvp6188_write_reg(client, 0x00 + ch, 0x10);
1433 nvp6188_write_reg(client, 0x08 + ch, 0x00);
1434 nvp6188_write_reg(client, 0x18 + ch, 0x0f);
1435 nvp6188_write_reg(client, 0x30 + ch, 0x12);
1436 nvp6188_write_reg(client, 0x34 + ch, 0x00);
1437 nvp6188_read_reg(client, 0x54, &val_0x54);
1438 val_0x54 &= ~(0x10 << ch);
1439 nvp6188_write_reg(client, 0x54, val_0x54);
1440 nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x40 : 0x48);
1441 nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x80 : 0x80);
1442 nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x28 : 0x28);
1443 nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x07 : 0x06);
1444 nvp6188_write_reg(client, 0x85 + ch, 0x0b);
1445 nvp6188_write_reg(client, 0x89 + ch, 0x00);
1446 nvp6188_write_reg(client, 0x8e + ch, 0x00);
1447 nvp6188_write_reg(client, 0xa0 + ch, 0x05);
1448 nvp6188_write_reg(client, 0xff, 0x01);
1449 nvp6188_write_reg(client, 0x84 + ch, 0x02);
1450 nvp6188_write_reg(client, 0x88 + ch, 0x00);
1451 nvp6188_write_reg(client, 0x8c + ch, 0x40);
1452 nvp6188_write_reg(client, 0xa0 + ch, 0x20);
1453 nvp6188_write_reg(client, 0xff, 0x05 + ch);
1454 nvp6188_write_reg(client, 0x00, 0xd0);
1455 nvp6188_write_reg(client, 0x01, 0x22);
1456 nvp6188_write_reg(client, 0x05, 0x04);
1457 nvp6188_write_reg(client, 0x08, 0x55);
1458 nvp6188_write_reg(client, 0x25, 0xdc);
1459 nvp6188_write_reg(client, 0x28, 0x80);
1460 nvp6188_write_reg(client, 0x2f, 0x00);
1461 nvp6188_write_reg(client, 0x30, 0xe0);
1462 nvp6188_write_reg(client, 0x31, 0x43);
1463 nvp6188_write_reg(client, 0x32, 0xa2);
1464 nvp6188_write_reg(client, 0x47, 0xee);
1465 nvp6188_write_reg(client, 0x50, 0xc6);
1466 nvp6188_write_reg(client, 0x57, 0x00);
1467 nvp6188_write_reg(client, 0x58, 0x77);
1468 nvp6188_write_reg(client, 0x5b, 0x41);
1469 nvp6188_write_reg(client, 0x5c, 0x78);
1470 nvp6188_write_reg(client, 0x5f, 0x00);
1471 nvp6188_write_reg(client, 0x62, 0x00);
1472 nvp6188_write_reg(client, 0x6C, 0x00);
1473 nvp6188_write_reg(client, 0x6d, 0x00);
1474 nvp6188_write_reg(client, 0x6e, 0x00);
1475 nvp6188_write_reg(client, 0x6f, 0x00);
1476 nvp6188_write_reg(client, 0x7b, 0x11);
1477 nvp6188_write_reg(client, 0x7c, 0x01);
1478 nvp6188_write_reg(client, 0x7d, 0x80);
1479 nvp6188_write_reg(client, 0x80, 0x00);
1480 nvp6188_write_reg(client, 0x90, 0x01);
1481 nvp6188_write_reg(client, 0xa9, 0x00);
1482 nvp6188_write_reg(client, 0xb5, 0x40);
1483 nvp6188_write_reg(client, 0xb8, 0x39);
1484 nvp6188_write_reg(client, 0xb9, 0x72);
1485 nvp6188_write_reg(client, 0xd1, 0x00);
1486 nvp6188_write_reg(client, 0xd5, 0x80);
1487 nvp6188_write_reg(client, 0xff, 0x09);
1488 nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
1489 nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
1490 nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
1491 nvp6188_write_reg(client, 0xff, 0x11);
1492 nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
1493 nvp6188_write_reg(client, 0xff, _MAR_BANK_);
1494 nvp6188_read_reg(client, 0x01, &val_20x01);
1495 val_20x01 &= (~(0x03 << (ch * 2)));
1496 //val_20x01 |=(0x01<<(ch*2));
1497 nvp6188_write_reg(client, 0x01, val_20x01);
1498 nvp6188_write_reg(client, 0x12 + (ch * 2), 0x80);
1499 nvp6188_write_reg(client, 0x13 + (ch * 2), 0x02);
1500 }
1501
1502 //each channel setting
1503 /*
1504 * 960x480i
1505 * ch : 0 ~ 3
1506 * ntpal: 1:25p, 0:30p
1507 */
nv6188_set_chn_960h(struct nvp6188 * nvp6188,u8 ch,u8 ntpal)1508 static __maybe_unused void nv6188_set_chn_960h(struct nvp6188 *nvp6188, u8 ch,
1509 u8 ntpal)
1510 {
1511 unsigned char val_0x54 = 0, val_20x01 = 0;
1512 struct i2c_client *client = nvp6188->client;
1513
1514 dev_err(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
1515 nvp6188_write_reg(client, 0xff, 0x00);
1516 nvp6188_write_reg(client, 0x00 + ch, 0x10);
1517 nvp6188_write_reg(client, 0x08 + ch, ntpal ? 0xdd : 0xa0);
1518 nvp6188_write_reg(client, 0x18 + ch, 0x08);
1519 nvp6188_write_reg(client, 0x22 + ch * 4, 0x0b);
1520 nvp6188_write_reg(client, 0x23 + ch * 4, 0x41);
1521 nvp6188_write_reg(client, 0x30 + ch, 0x12);
1522 nvp6188_write_reg(client, 0x34 + ch, 0x01);
1523 nvp6188_read_reg(client, 0x54, &val_0x54);
1524 if (ntpal)
1525 val_0x54 &= ~(0x10 << ch);
1526 else
1527 val_0x54 |= (0x10 << ch);
1528 nvp6188_write_reg(client, 0x54, val_0x54);
1529 nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x80 : 0x90);
1530 nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0xbe : 0xbc);
1531 nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0xa0 : 0x81);
1532 nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0xf0 : 0xe0);
1533 nvp6188_write_reg(client, 0x85 + ch, 0x00);
1534 nvp6188_write_reg(client, 0x89 + ch, 0x00);
1535 nvp6188_write_reg(client, 0x8e + ch, 0x00);
1536 nvp6188_write_reg(client, 0xa0 + ch, 0x05);
1537 nvp6188_write_reg(client, 0xff, 0x01);
1538 nvp6188_write_reg(client, 0x84 + ch, 0x02);
1539 nvp6188_write_reg(client, 0x88 + ch, 0x00);
1540 nvp6188_write_reg(client, 0x8c + ch, 0x40);
1541 nvp6188_write_reg(client, 0xa0 + ch, 0x20);
1542 nvp6188_write_reg(client, 0xed, 0x00);
1543 nvp6188_write_reg(client, 0xff, 0x05 + ch);
1544 nvp6188_write_reg(client, 0x00, 0xd0);
1545 nvp6188_write_reg(client, 0x01, 0x22);
1546 nvp6188_write_reg(client, 0x05, 0x00);
1547 nvp6188_write_reg(client, 0x08, 0x55);
1548 nvp6188_write_reg(client, 0x25, 0xdc);
1549 nvp6188_write_reg(client, 0x28, 0x80);
1550 nvp6188_write_reg(client, 0x2f, 0x00);
1551 nvp6188_write_reg(client, 0x30, 0xe0);
1552 nvp6188_write_reg(client, 0x31, 0x43);
1553 nvp6188_write_reg(client, 0x32, 0xa2);
1554 nvp6188_write_reg(client, 0x47, 0x04);
1555 nvp6188_write_reg(client, 0x50, 0x84);
1556 nvp6188_write_reg(client, 0x57, 0x00);
1557 nvp6188_write_reg(client, 0x58, 0x77);
1558 nvp6188_write_reg(client, 0x5b, 0x43);
1559 nvp6188_write_reg(client, 0x5c, 0x78);
1560 nvp6188_write_reg(client, 0x5f, 0x00);
1561 nvp6188_write_reg(client, 0x62, 0x20);
1562 nvp6188_write_reg(client, 0x7b, 0x00);
1563 nvp6188_write_reg(client, 0x7c, 0x01);
1564 nvp6188_write_reg(client, 0x7d, 0x80);
1565 nvp6188_write_reg(client, 0x80, 0x00);
1566 nvp6188_write_reg(client, 0x90, 0x01);
1567 nvp6188_write_reg(client, 0xa9, 0x00);
1568 nvp6188_write_reg(client, 0xb5, 0x00);
1569 nvp6188_write_reg(client, 0xb8, 0xb9);
1570 nvp6188_write_reg(client, 0xb9, 0x72);
1571 nvp6188_write_reg(client, 0xd1, 0x00);
1572 nvp6188_write_reg(client, 0xd5, 0x80);
1573 nvp6188_write_reg(client, 0xff, 0x09);
1574 nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x10);
1575 nvp6188_write_reg(client, 0x98 + (ch * 0x20), ntpal ? 0xc0 : 0xe0);
1576 nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
1577 nvp6188_write_reg(client, 0xff, 0x11);
1578 nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
1579 nvp6188_write_reg(client, 0xff, _MAR_BANK_);
1580 nvp6188_read_reg(client, 0x01, &val_20x01);
1581 val_20x01 &= (~(0x03 << (ch * 2)));
1582 val_20x01 |= (0x02 << (ch * 2));
1583 nvp6188_write_reg(client, 0x01, val_20x01);
1584 nvp6188_write_reg(client, 0x12 + (ch * 2), 0xe0);
1585 nvp6188_write_reg(client, 0x13 + (ch * 2), 0x01);
1586 }
1587
1588 //each channel setting
1589 /*
1590 * 1280x720p
1591 * ch : 0 ~ 3
1592 * ntpal: 1:25p, 0:30p
1593 */
nv6188_set_chn_720p(struct nvp6188 * nvp6188,u8 ch,u8 ntpal)1594 static __maybe_unused void nv6188_set_chn_720p(struct nvp6188 *nvp6188, u8 ch,
1595 u8 ntpal)
1596 {
1597 unsigned char val_0x54 = 0, val_20x01 = 0;
1598 struct i2c_client *client = nvp6188->client;
1599
1600 dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
1601 nvp6188_write_reg(client, 0xff, 0x00);
1602 nvp6188_write_reg(client, 0x00 + ch, 0x00);
1603 nvp6188_write_reg(client, 0x08 + ch, 0x00);
1604 nvp6188_write_reg(client, 0x18 + ch, 0x10);
1605 nvp6188_write_reg(client, 0x30 + ch, 0x12);
1606 nvp6188_write_reg(client, 0x34 + ch, 0x00);
1607 nvp6188_read_reg(client, 0x54, &val_0x54);
1608 val_0x54 &= ~(0x10 << ch);
1609 nvp6188_write_reg(client, 0x54, val_0x54);
1610 nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x80 : 0x80);
1611 nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x00 : 0x00);
1612 nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x01 : 0x01);
1613 nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x0d : 0x0c);
1614 nvp6188_write_reg(client, 0x85 + ch, 0x00);
1615 nvp6188_write_reg(client, 0x89 + ch, 0x00);
1616 nvp6188_write_reg(client, 0x8e + ch, 0x00);
1617 nvp6188_write_reg(client, 0xa0 + ch, 0x05);
1618 nvp6188_write_reg(client, 0xff, 0x01);
1619 nvp6188_write_reg(client, 0x84 + ch, 0x02);
1620 nvp6188_write_reg(client, 0x88 + ch, 0x00);
1621 nvp6188_write_reg(client, 0x8c + ch, 0x40);
1622 nvp6188_write_reg(client, 0xa0 + ch, 0x20);
1623 nvp6188_write_reg(client, 0xff, 0x05 + ch);
1624 nvp6188_write_reg(client, 0x00, 0xf0);
1625 nvp6188_write_reg(client, 0x01, 0x22);
1626 nvp6188_write_reg(client, 0x05, 0x04);
1627 nvp6188_write_reg(client, 0x08, 0x55);
1628 nvp6188_write_reg(client, 0x25, 0xdc);
1629 nvp6188_write_reg(client, 0x28, 0x80);
1630 nvp6188_write_reg(client, 0x2f, 0x00);
1631 nvp6188_write_reg(client, 0x30, 0xe0);
1632 nvp6188_write_reg(client, 0x31, 0x43);
1633 nvp6188_write_reg(client, 0x32, 0xa2);
1634 nvp6188_write_reg(client, 0x47, 0x04);
1635 nvp6188_write_reg(client, 0x50, 0x84);
1636 nvp6188_write_reg(client, 0x57, 0x00);
1637 nvp6188_write_reg(client, 0x58, 0x77);
1638 nvp6188_write_reg(client, 0x5b, 0x41);
1639 nvp6188_write_reg(client, 0x5c, 0x78);
1640 nvp6188_write_reg(client, 0x5f, 0x00);
1641 nvp6188_write_reg(client, 0x62, 0x00);
1642 nvp6188_write_reg(client, 0x7b, 0x11);
1643 nvp6188_write_reg(client, 0x7c, 0x01);
1644 nvp6188_write_reg(client, 0x7d, 0x80);
1645 nvp6188_write_reg(client, 0x80, 0x00);
1646 nvp6188_write_reg(client, 0x90, 0x01);
1647 nvp6188_write_reg(client, 0xa9, 0x00);
1648 nvp6188_write_reg(client, 0xb5, 0x00);
1649 nvp6188_write_reg(client, 0xb8, 0xb9);
1650 nvp6188_write_reg(client, 0xb9, 0x72);
1651 nvp6188_write_reg(client, 0xd1, 0x00);
1652 nvp6188_write_reg(client, 0xd5, 0x80);
1653 nvp6188_write_reg(client, 0xff, 0x09);
1654 nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
1655 nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
1656 nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
1657 nvp6188_write_reg(client, 0xff, 0x11);
1658 nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
1659 nvp6188_write_reg(client, 0xff, _MAR_BANK_);
1660 nvp6188_read_reg(client, 0x01, &val_20x01);
1661 val_20x01 &= (~(0x03 << (ch * 2)));
1662 val_20x01 |= (0x01 << (ch * 2));
1663 nvp6188_write_reg(client, 0x01, val_20x01);
1664 nvp6188_write_reg(client, 0x12 + (ch * 2), 0x80);
1665 nvp6188_write_reg(client, 0x13 + (ch * 2), 0x02);
1666 }
1667
1668 //each channel setting
1669 /*
1670 * 1920x1080p
1671 * ch : 0 ~ 3
1672 * ntpal: 1:25p, 0:30p
1673 */
nv6188_set_chn_1080p(struct nvp6188 * nvp6188,u8 ch,u8 ntpal)1674 static __maybe_unused void nv6188_set_chn_1080p(struct nvp6188 *nvp6188, u8 ch,
1675 u8 ntpal)
1676 {
1677 unsigned char val_0x54 = 0, val_20x01 = 0;
1678 struct i2c_client *client = nvp6188->client;
1679
1680 dev_info(&client->dev, "%s ch %d ntpal %d", __func__, ch, ntpal);
1681 nvp6188_write_reg(client, 0xff, 0x00);
1682 nvp6188_write_reg(client, 0x00 + ch, 0x10);
1683 nvp6188_write_reg(client, 0x08 + ch, 0x00);
1684 nvp6188_write_reg(client, 0x18 + ch, 0x10);
1685 nvp6188_write_reg(client, 0x30 + ch, 0x12);
1686 nvp6188_write_reg(client, 0x34 + ch, 0x00);
1687 nvp6188_read_reg(client, 0x54, &val_0x54);
1688 val_0x54 &= ~(0x10 << ch);
1689 nvp6188_write_reg(client, 0x54, val_0x54);
1690 nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x80 : 0x80);
1691 nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x00 : 0x00);
1692 nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x01 : 0x01);
1693 nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x03 : 0x02);
1694 nvp6188_write_reg(client, 0x85 + ch, 0x00);
1695 nvp6188_write_reg(client, 0x89 + ch, 0x10);
1696 nvp6188_write_reg(client, 0x8e + ch, 0x00);
1697 nvp6188_write_reg(client, 0xa0 + ch, 0x05);
1698 nvp6188_write_reg(client, 0xff, 0x01);
1699 nvp6188_write_reg(client, 0x84 + ch, 0x02);
1700 nvp6188_write_reg(client, 0x88 + ch, 0x00);
1701 nvp6188_write_reg(client, 0x8c + ch, 0x40);
1702 nvp6188_write_reg(client, 0xa0 + ch, 0x20);
1703 nvp6188_write_reg(client, 0xff, 0x05 + ch);
1704 nvp6188_write_reg(client, 0x00, 0xd0);
1705 nvp6188_write_reg(client, 0x01, 0x22);
1706 nvp6188_write_reg(client, 0x05, 0x04);
1707 nvp6188_write_reg(client, 0x08, 0x55);
1708 nvp6188_write_reg(client, 0x25, 0xdc);
1709 nvp6188_write_reg(client, 0x28, 0x80);
1710 nvp6188_write_reg(client, 0x2f, 0x00);
1711 nvp6188_write_reg(client, 0x30, 0xe0);
1712 nvp6188_write_reg(client, 0x31, 0x41);
1713 nvp6188_write_reg(client, 0x32, 0xa2);
1714 nvp6188_write_reg(client, 0x47, 0xee);
1715 nvp6188_write_reg(client, 0x50, 0xc6);
1716 nvp6188_write_reg(client, 0x57, 0x00);
1717 nvp6188_write_reg(client, 0x58, 0x77);
1718 nvp6188_write_reg(client, 0x5b, 0x41);
1719 nvp6188_write_reg(client, 0x5c, 0x7C);
1720 nvp6188_write_reg(client, 0x5f, 0x00);
1721 nvp6188_write_reg(client, 0x62, 0x20);
1722 nvp6188_write_reg(client, 0x7b, 0x11);
1723 nvp6188_write_reg(client, 0x7c, 0x01);
1724 nvp6188_write_reg(client, 0x7d, 0x80);
1725 nvp6188_write_reg(client, 0x80, 0x00);
1726 nvp6188_write_reg(client, 0x90, 0x01);
1727 nvp6188_write_reg(client, 0xa9, 0x00);
1728 nvp6188_write_reg(client, 0xb5, 0x40);
1729 nvp6188_write_reg(client, 0xb8, 0x39);
1730 nvp6188_write_reg(client, 0xb9, 0x72);
1731 nvp6188_write_reg(client, 0xd1, 0x00);
1732 nvp6188_write_reg(client, 0xd5, 0x80);
1733 nvp6188_write_reg(client, 0xff, 0x09);
1734 nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
1735 nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
1736 nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
1737 nvp6188_write_reg(client, 0xff, 0x11);
1738 nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
1739 nvp6188_write_reg(client, 0xff, _MAR_BANK_);
1740 nvp6188_read_reg(client, 0x01, &val_20x01);
1741 val_20x01 &= (~(0x03 << (ch * 2)));
1742 nvp6188_write_reg(client, 0x01, val_20x01);
1743 nvp6188_write_reg(client, 0x12 + (ch * 2), 0xc0);
1744 nvp6188_write_reg(client, 0x13 + (ch * 2), 0x03);
1745 }
1746
1747 //each channel setting
1748 /*
1749 * 1600x1300p
1750 * dev:0x60 / 0x62 / 0x64 / 0x66
1751 * ch : 0 ~ 3
1752 * ntpal: 1:25p, 0:30p
1753 * detection: 5xf3<<8 | 5xf2 = 0x0708(30p) =0x0870(25p)
1754 */
nv6188_set_chn_1300p(struct nvp6188 * nvp6188,unsigned char ch,unsigned char ntpal)1755 static void nv6188_set_chn_1300p(struct nvp6188 *nvp6188, unsigned char ch, unsigned char ntpal)
1756 {
1757 unsigned char val_0x54 = 0, val_20x01 = 0;
1758 struct i2c_client *client = nvp6188->client;
1759
1760 dev_info(&client->dev, "%s ch %d ntpal %d", __func__, ch, ntpal);
1761
1762 nvp6188_write_reg(client, 0xff, 0x00);
1763 nvp6188_write_reg(client, 0x00 + ch, 0x10);
1764 nvp6188_write_reg(client, 0x08 + ch, 0x00);
1765 nvp6188_write_reg(client, 0x18 + ch, 0x10);
1766 nvp6188_write_reg(client, 0x30 + ch, 0x12);
1767 nvp6188_write_reg(client, 0x34 + ch, 0x00);
1768 nvp6188_read_reg(client, 0x54, &val_0x54);
1769 val_0x54 &= ~(0x10 << ch);
1770 nvp6188_write_reg(client, 0x54, val_0x54);
1771 nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x80 : 0x80);
1772 nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x80 : 0x80);
1773 nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x00 : 0x01);
1774 nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x03 : 0x02);
1775 nvp6188_write_reg(client, 0x85 + ch, 0x00);
1776 nvp6188_write_reg(client, 0x89 + ch, 0x10);
1777 nvp6188_write_reg(client, 0x8e + ch, 0x00);
1778 nvp6188_write_reg(client, 0xa0 + ch, 0x05);
1779 nvp6188_write_reg(client, 0xff, 0x01);
1780 nvp6188_write_reg(client, 0x84 + ch, 0x02);
1781 nvp6188_write_reg(client, 0x88 + ch, 0x00);
1782 nvp6188_write_reg(client, 0x8c + ch, 0x40);
1783 nvp6188_write_reg(client, 0xa0 + ch, 0x20);
1784 nvp6188_write_reg(client, 0xff, 0x05 + ch);
1785 nvp6188_write_reg(client, 0x00, 0xd0);
1786 nvp6188_write_reg(client, 0x01, 0x22);
1787 nvp6188_write_reg(client, 0x05, 0x04);
1788 nvp6188_write_reg(client, 0x08, 0x55);
1789 nvp6188_write_reg(client, 0x25, 0xdc);
1790 nvp6188_write_reg(client, 0x28, 0x80);
1791 nvp6188_write_reg(client, 0x2f, 0x00);
1792 nvp6188_write_reg(client, 0x30, 0xe0);
1793 nvp6188_write_reg(client, 0x31, 0x41);
1794 nvp6188_write_reg(client, 0x32, 0xa2);
1795 nvp6188_write_reg(client, 0x47, 0xee);
1796 nvp6188_write_reg(client, 0x50, 0xc6);
1797 nvp6188_write_reg(client, 0x57, 0x00);
1798 nvp6188_write_reg(client, 0x58, 0x77);
1799 nvp6188_write_reg(client, 0x5b, 0x41);
1800 nvp6188_write_reg(client, 0x5c, 0x78);
1801 nvp6188_write_reg(client, 0x5f, 0x00);
1802 nvp6188_write_reg(client, 0x62, 0x00);
1803 nvp6188_write_reg(client, 0x6C, 0x00);
1804 nvp6188_write_reg(client, 0x6d, 0x00);
1805 nvp6188_write_reg(client, 0x6e, 0x00);
1806 nvp6188_write_reg(client, 0x6f, 0x00);
1807 nvp6188_write_reg(client, 0x7b, 0x11);
1808 nvp6188_write_reg(client, 0x7c, 0x01);
1809 nvp6188_write_reg(client, 0x7d, 0x80);
1810 nvp6188_write_reg(client, 0x80, 0x00);
1811 nvp6188_write_reg(client, 0x90, 0x01);
1812 nvp6188_write_reg(client, 0xa9, 0x00);
1813 nvp6188_write_reg(client, 0xb5, 0x00);
1814 nvp6188_write_reg(client, 0xb8, 0xb9);
1815 nvp6188_write_reg(client, 0xb9, 0x72);
1816 nvp6188_write_reg(client, 0xd1, 0x00);
1817 nvp6188_write_reg(client, 0xd5, 0x80);
1818 nvp6188_write_reg(client, 0xff, 0x09);
1819 nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
1820 nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
1821 nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
1822 nvp6188_write_reg(client, 0xff, 0x11); //additional settings for 1300p
1823 nvp6188_write_reg(client, 0x01 + (ch * 0x20), ntpal ? 0x01 : 0x00);
1824 nvp6188_write_reg(client, 0x02 + (ch * 0x20), ntpal ? 0xb2 : 0x50);
1825 nvp6188_write_reg(client, 0x03 + (ch * 0x20), 0x06);
1826 nvp6188_write_reg(client, 0x04 + (ch * 0x20), 0x40);
1827 nvp6188_write_reg(client, 0x05 + (ch * 0x20), ntpal ? 0x08 : 0x07);
1828 nvp6188_write_reg(client, 0x06 + (ch * 0x20), ntpal ? 0x70 : 0x08);
1829 nvp6188_write_reg(client, 0x07 + (ch * 0x20), 0x00);
1830 nvp6188_write_reg(client, 0x08 + (ch * 0x20), 0x00);
1831 nvp6188_write_reg(client, 0x0a + (ch * 0x20), 0x05);
1832 nvp6188_write_reg(client, 0x0b + (ch * 0x20), 0x14);
1833 nvp6188_write_reg(client, 0x0c + (ch * 0x20), 0x05);
1834 nvp6188_write_reg(client, 0x0d + (ch * 0x20), 0x5f);
1835 nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x03);
1836 nvp6188_write_reg(client, 0xff, 0x20);
1837 nvp6188_read_reg(client, 0x01, &val_20x01);
1838 val_20x01 &= (~(0x03 << (ch * 2)));
1839 nvp6188_write_reg(client, 0x01, val_20x01);
1840 nvp6188_write_reg(client, 0x12 + (ch * 2), 0x20);
1841 nvp6188_write_reg(client, 0x13 + (ch * 2), 0x03);
1842 }
1843
nvp6188_manual_mode(struct nvp6188 * nvp6188,u8 ch,u32 fmt)1844 static __maybe_unused void nvp6188_manual_mode(struct nvp6188 *nvp6188, u8 ch, u32 fmt)
1845 {
1846 unsigned char val_13x70 = 0, val_13x71 = 0;
1847 struct i2c_client *client = nvp6188->client;
1848
1849 if (fmt != NVP_RESO_UNKOWN) {
1850 nvp6188_write_reg(client, 0xFF, 0x13);
1851 nvp6188_read_reg(client, 0x70, &val_13x70);
1852 val_13x70 |= (0x01 << ch);
1853 nvp6188_write_reg(client, 0x70, val_13x70);
1854 nvp6188_read_reg(client, 0x71, &val_13x71);
1855 val_13x71 |= (0x01 << ch);
1856 nvp6188_write_reg(client, 0x71, val_13x71);
1857 }
1858 switch (fmt) {
1859 case NVP_RESO_960H_PAL:
1860 nv6188_set_chn_960h(nvp6188, ch, 1);
1861 break;
1862 case NVP_RESO_960P_PAL:
1863 nv6188_set_chn_960p(nvp6188, ch, 1);
1864 break;
1865 case NVP_RESO_720P_PAL:
1866 nv6188_set_chn_720p(nvp6188, ch, 1);
1867 break;
1868 case NVP_RESO_1080P_PAL:
1869 nv6188_set_chn_1080p(nvp6188, ch, 1);
1870 break;
1871 case NVP_RESO_1300P_PAL:
1872 nv6188_set_chn_1300p(nvp6188, ch, 1);
1873 break;
1874 case NVP_RESO_960H_NSTC:
1875 nv6188_set_chn_960h(nvp6188, ch, 0);
1876 break;
1877 case NVP_RESO_960P_NSTC:
1878 nv6188_set_chn_960p(nvp6188, ch, 0);
1879 break;
1880 case NVP_RESO_720P_NSTC:
1881 nv6188_set_chn_720p(nvp6188, ch, 0);
1882 break;
1883 case NVP_RESO_1080P_NSTC:
1884 nv6188_set_chn_1080p(nvp6188, ch, 0);
1885 break;
1886 case NVP_RESO_1300P_NSTC:
1887 nv6188_set_chn_1300p(nvp6188, ch, 0);
1888 break;
1889 default:
1890 nv6188_set_chn_1080p(nvp6188, ch, 0);
1891
1892 dev_err(&client->dev, "channel %d not detect\n", ch);
1893 nvp6188_write_reg(client, 0xFF, 0x13);
1894 nvp6188_read_reg(client, 0x70, &val_13x70);
1895 val_13x70 &= ~(0x01 << ch);
1896 nvp6188_write_reg(client, 0x70, val_13x70);
1897 nvp6188_write_reg(client, 0xFF, 0x05 + ch);
1898 nvp6188_write_reg(client, 0x58, 0x77);
1899 nvp6188_write_reg(client, 0xb8, 0xb8);
1900 break;
1901 }
1902
1903 // clear unknown count status
1904 nvp6188->cur_mode.unkown_reso_count[ch] = 0;
1905 }
1906
nvp6188_auto_detect_fmt(struct nvp6188 * nvp6188)1907 static __maybe_unused void nvp6188_auto_detect_fmt(struct nvp6188 *nvp6188)
1908 {
1909 u8 ch = 0;
1910 u32 reso = 0;
1911 unsigned char ch_vfc = 0xff, val_13x70 = 0xf0;
1912 int ch_htotal = 0;
1913 struct i2c_client *client = nvp6188->client;
1914
1915 for (ch = 0; ch < PAD_MAX; ch++) {
1916 ch_vfc = nv6188_read_vfc(nvp6188, ch);
1917 if (ch_vfc == 0xFF) {
1918 ch_htotal = nv6188_read_htotal(nvp6188, ch);
1919 if (ch_htotal == 0x0708)
1920 ch_vfc = NVP_RESO_1300P_NSTC_VALUE;
1921 else if (ch_htotal == 0x0870)
1922 ch_vfc = NVP_RESO_1300P_PAL_VALUE;
1923 }
1924 switch (ch_vfc) {
1925 case NVP_RESO_960H_NSTC_VALUE:
1926 dev_dbg(&client->dev, "channel %d det 960h nstc", ch);
1927 reso = NVP_RESO_960H_NSTC;
1928 break;
1929 case NVP_RESO_960H_PAL_VALUE:
1930 dev_dbg(&client->dev, "channel %d det 960h pal", ch);
1931 reso = NVP_RESO_960H_PAL;
1932 break;
1933 case NVP_RESO_720P_NSTC_VALUE:
1934 dev_dbg(&client->dev, "channel %d det 720p nstc", ch);
1935 reso = NVP_RESO_720P_NSTC;
1936 break;
1937 case NVP_RESO_720P_PAL_VALUE:
1938 dev_dbg(&client->dev, "channel %d det 720p pal", ch);
1939 reso = NVP_RESO_720P_PAL;
1940 break;
1941 case NVP_RESO_1080P_NSTC_VALUE:
1942 dev_dbg(&client->dev, "channel %d det 1080p nstc", ch);
1943 reso = NVP_RESO_1080P_NSTC;
1944 break;
1945 case NVP_RESO_1080P_PAL_VALUE:
1946 dev_dbg(&client->dev, "channel %d det 1080p pal", ch);
1947 reso = NVP_RESO_1080P_PAL;
1948 break;
1949 case NVP_RESO_960P_NSTC_VALUE:
1950 dev_dbg(&client->dev, "channel %d det 960p nstc", ch);
1951 reso = NVP_RESO_960P_NSTC;
1952 break;
1953 case NVP_RESO_960P_PAL_VALUE:
1954 dev_dbg(&client->dev, "channel %d det 960p pal", ch);
1955 reso = NVP_RESO_960P_PAL;
1956 break;
1957 case NVP_RESO_1300P_NSTC_VALUE:
1958 dev_dbg(&client->dev, "channel %d det 1300p nstc", ch);
1959 reso = NVP_RESO_1300P_NSTC;
1960 break;
1961 case NVP_RESO_1300P_PAL_VALUE:
1962 dev_dbg(&client->dev, "channel %d det 1300p pal", ch);
1963 reso = NVP_RESO_1300P_PAL;
1964 break;
1965 default:
1966 dev_dbg(&client->dev, "channel %d not detect\n", ch);
1967 reso = NVP_RESO_UNKOWN;
1968 break;
1969 }
1970
1971 if (reso != nvp6188->cur_mode.channel_reso[ch]) {
1972 if (nvp6188->cur_mode.channel_reso[ch] != NVP_RESO_UNKOWN &&
1973 reso == NVP_RESO_UNKOWN &&
1974 (nvp6188->detect_status & (0x01 << ch)) == 0) {
1975 dev_info(&client->dev, "channel(%d) fmt(%d) -> invalid(0x%x)",
1976 ch, nvp6188->cur_mode.channel_reso[ch], ch_vfc);
1977 if (nvp6188->cur_mode.unkown_reso_count[ch] < 5) {
1978 nvp6188_write_reg(client, 0xFF, 0x13);
1979 nvp6188_read_reg(client, 0x70, &val_13x70);
1980 val_13x70 &= ~(0x01 << ch);
1981 nvp6188_write_reg(client, 0x70, val_13x70);
1982 nvp6188->cur_mode.unkown_reso_count[ch]++;
1983 continue;
1984 }
1985 }
1986 dev_info(&client->dev, "channel(%d) fmt(%d) -> cur(%d)",
1987 ch, nvp6188->cur_mode.channel_reso[ch], reso);
1988 nvp6188_manual_mode(nvp6188, ch, reso);
1989 nvp6188->cur_mode.channel_reso[ch] = reso;
1990 }
1991 }
1992 }
1993
nvp6188_init_default_fmt(struct nvp6188 * nvp6188,u32 fmt)1994 static __maybe_unused void nvp6188_init_default_fmt(struct nvp6188 *nvp6188, u32 fmt)
1995 {
1996 u8 ch = 0;
1997
1998 for (ch = 0; ch < PAD_MAX; ch++) {
1999 nvp6188_manual_mode(nvp6188, ch, fmt);
2000 nvp6188->cur_mode.channel_reso[ch] = fmt;
2001 }
2002 }
2003
detect_thread_function(void * data)2004 static int detect_thread_function(void *data)
2005 {
2006 struct nvp6188 *nvp6188 = (struct nvp6188 *) data;
2007 struct i2c_client *client = nvp6188->client;
2008 int need_reset_wait = -1;
2009 nvp6188->disable_dump_register = true;
2010 if (nvp6188->power_on) {
2011 nvp6188_auto_detect_hotplug(nvp6188);
2012 nvp6188->last_detect_status = nvp6188->detect_status;
2013 nvp6188->is_reset = 0;
2014 }
2015 while (!kthread_should_stop()) {
2016 if (nvp6188->disable_dump_register && nvp6188->power_on) {
2017 mutex_lock(&nvp6188->mutex);
2018 nvp6188_auto_detect_hotplug(nvp6188);
2019 nvp6188_auto_detect_fmt(nvp6188);
2020
2021 mutex_unlock(&nvp6188->mutex);
2022 if (nvp6188->last_detect_status != nvp6188->detect_status) {
2023 dev_info(&client->dev, "last_detect_status(0x%x) -> detect_status(0x%x)",
2024 nvp6188->last_detect_status, nvp6188->detect_status);
2025 nvp6188->last_detect_status = nvp6188->detect_status;
2026 input_event(nvp6188->input_dev, EV_MSC, MSC_RAW, nvp6188->detect_status);
2027 input_sync(nvp6188->input_dev);
2028 need_reset_wait = 5;
2029 }
2030 if (need_reset_wait > 0) {
2031 need_reset_wait--;
2032 } else if (need_reset_wait == 0) {
2033 need_reset_wait = -1;
2034 nvp6188->is_reset = 1;
2035 dev_info(&client->dev, "trigger reset time up\n");
2036 }
2037 }
2038 set_current_state(TASK_INTERRUPTIBLE);
2039 schedule_timeout(msecs_to_jiffies(200));
2040 }
2041 return 0;
2042 }
2043
detect_thread_start(struct nvp6188 * nvp6188)2044 static int __maybe_unused detect_thread_start(struct nvp6188 *nvp6188)
2045 {
2046 int ret = 0;
2047 struct i2c_client *client = nvp6188->client;
2048 nvp6188->detect_thread = kthread_create(detect_thread_function,
2049 nvp6188, "nvp6188_kthread");
2050
2051 if (IS_ERR(nvp6188->detect_thread)) {
2052 dev_err(&client->dev, "kthread_create nvp6188_kthread failed\n");
2053 ret = PTR_ERR(nvp6188->detect_thread);
2054 nvp6188->detect_thread = NULL;
2055 return ret;
2056 }
2057 wake_up_process(nvp6188->detect_thread);
2058 return ret;
2059 }
2060
detect_thread_stop(struct nvp6188 * nvp6188)2061 static int __maybe_unused detect_thread_stop(struct nvp6188 *nvp6188)
2062 {
2063 if (nvp6188->detect_thread)
2064 kthread_stop(nvp6188->detect_thread);
2065 nvp6188->detect_thread = NULL;
2066
2067 return 0;
2068 }
2069
nvp6188_reg_check(struct nvp6188 * nvp6188)2070 static int __maybe_unused nvp6188_reg_check(struct nvp6188 *nvp6188)
2071 {
2072 unsigned char val_20x52 = 0, val_20x53 = 0;
2073 int check_value1 = 0, check_value2 = 0, check_cnt = 10;
2074 struct i2c_client *client = nvp6188->client;
2075
2076 nvp6188_write_reg(client, 0xff, 0x20);
2077 nvp6188_write_reg(client, 0x00, 0xff); // open mipi
2078 usleep_range(100 * 1000, 100 * 1000);
2079 //nvp6188_write_reg(client, 0x40, 0x01);
2080 //nvp6188_write_reg(client, 0x40, 0x00);
2081 while (check_cnt--) {
2082 nvp6188_write_reg(client, 0xff, 0x20);
2083 nvp6188_read_reg(client, 0x52, &val_20x52);
2084 nvp6188_read_reg(client, 0x53, &val_20x53);
2085 check_value1 = (val_20x52 << 8) | val_20x53;
2086 usleep_range(80 * 1000, 100 * 1000);
2087 nvp6188_write_reg(client, 0xff, 0x20);
2088 nvp6188_read_reg(client, 0x52, &val_20x52);
2089 nvp6188_read_reg(client, 0x53, &val_20x53);
2090 check_value2 = (val_20x52 << 8) | val_20x53;
2091 if (check_value2 <= 2 || check_value1 == check_value2) {
2092 dev_err(&client->dev, "attention!!! check cnt = %d\n", check_cnt);
2093 nvp6188_write_reg(client, 0xff, 0x01);
2094 nvp6188_write_reg(client, 0x97, 0xf0);
2095 usleep_range(40 * 1000, 50 * 1000);
2096 nvp6188_write_reg(client, 0x97, 0x0f);
2097 } else {
2098 dev_err(&client->dev, "check_value1=%x, check_value2=%x,check cnt = %d\n",
2099 check_value1, check_value2, check_cnt);
2100 break;
2101 }
2102 }
2103 return check_cnt;
2104 }
2105
nvp6188_auto_det_set(struct nvp6188 * nvp6188)2106 static int nvp6188_auto_det_set(struct nvp6188 *nvp6188)
2107 {
2108 struct i2c_client *client = nvp6188->client;
2109
2110 dev_info(&client->dev, "[%s::%d]\n", __func__, __LINE__);
2111
2112 nvp6188_write_reg(client, 0xff, 0x13);
2113 nvp6188_write_reg(client, 0x30, 0x7f);
2114 nvp6188_write_reg(client, 0x70, 0xf0);
2115 nvp6188_write_reg(client, 0xff, 0x00);
2116 nvp6188_write_reg(client, 0x00, 0x18);
2117 nvp6188_write_reg(client, 0x01, 0x18);
2118 nvp6188_write_reg(client, 0x02, 0x18);
2119 nvp6188_write_reg(client, 0x03, 0x18);
2120 usleep_range(30 * 1000, 40 * 1000);
2121 nvp6188_write_reg(client, 0x00, 0x10);
2122 nvp6188_write_reg(client, 0x01, 0x10);
2123 nvp6188_write_reg(client, 0x02, 0x10);
2124 nvp6188_write_reg(client, 0x03, 0x10);
2125
2126 return 0;
2127 }
2128
nvp6188_video_init(struct nvp6188 * nvp6188)2129 static int nvp6188_video_init(struct nvp6188 *nvp6188)
2130 {
2131 int ret;
2132 int array_size = 0;
2133 struct i2c_client *client = nvp6188->client;
2134
2135 if (nvp6188->cur_mode.global_reg_list == common_setting_1458M_regs) {
2136 array_size = ARRAY_SIZE(common_setting_1458M_regs);
2137 } else if (nvp6188->cur_mode.global_reg_list == common_setting_756M_regs) {
2138 array_size = ARRAY_SIZE(common_setting_756M_regs);
2139 } else {
2140 return -1;
2141 }
2142
2143 ret = nvp6188_write_array(nvp6188->client,
2144 nvp6188->cur_mode.global_reg_list, array_size);
2145 if (ret) {
2146 dev_err(&client->dev, "__nvp6188_start_stream global_reg_list faild");
2147 return ret;
2148 }
2149
2150 nvp6188_init_default_fmt(nvp6188, NVP_RESO_UNKOWN);
2151 nvp6188_auto_det_set(nvp6188);
2152 usleep_range(150*1000, 150*1000);
2153 nvp6188_auto_detect_fmt(nvp6188);
2154
2155 return 0;
2156 }
2157
__nvp6188_start_stream(struct nvp6188 * nvp6188)2158 static int __nvp6188_start_stream(struct nvp6188 *nvp6188)
2159 {
2160 struct i2c_client *client = nvp6188->client;
2161
2162 if (nvp6188->detect_thread) {
2163 nvp6188_write_reg(client, 0xff, 0x20);
2164 nvp6188_write_reg(client, 0x00, 0xff);
2165 return 0;
2166 }
2167
2168 nvp6188_audio_init(nvp6188);
2169 nvp6188_reg_check(nvp6188);
2170 detect_thread_start(nvp6188);
2171 return 0;
2172 }
2173
__nvp6188_stop_stream(struct nvp6188 * nvp6188)2174 static int __nvp6188_stop_stream(struct nvp6188 *nvp6188)
2175 {
2176 struct i2c_client *client = nvp6188->client;
2177
2178 nvp6188_write_reg(client, 0xff, 0x20);
2179 nvp6188_write_reg(client, 0x00, 0x00);
2180 nvp6188_write_reg(client, 0x40, 0x01);
2181 nvp6188_write_reg(client, 0x40, 0x00);
2182 //detect_thread_stop(nvp6188);
2183 usleep_range(100 * 1000, 150 * 1000);
2184
2185 return 0;
2186 }
2187
nvp6188_stream(struct v4l2_subdev * sd,int on)2188 static int nvp6188_stream(struct v4l2_subdev *sd, int on)
2189 {
2190 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2191 struct i2c_client *client = nvp6188->client;
2192
2193 dev_info(&client->dev, "s_stream: %d. %dx%d\n", on,
2194 nvp6188->cur_mode.width,
2195 nvp6188->cur_mode.height);
2196
2197 mutex_lock(&nvp6188->mutex);
2198 on = !!on;
2199 if (nvp6188->streaming == on)
2200 goto unlock;
2201
2202 if (on) {
2203 __nvp6188_start_stream(nvp6188);
2204 } else {
2205 __nvp6188_stop_stream(nvp6188);
2206 }
2207
2208 nvp6188->streaming = on;
2209
2210 unlock:
2211 mutex_unlock(&nvp6188->mutex);
2212
2213 return 0;
2214 }
2215
nvp6188_power(struct v4l2_subdev * sd,int on)2216 static int nvp6188_power(struct v4l2_subdev *sd, int on)
2217 {
2218 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2219 struct i2c_client *client = nvp6188->client;
2220 int ret = 0;
2221
2222 mutex_lock(&nvp6188->mutex);
2223
2224 /* If the power state is not modified - no work to do. */
2225 if (nvp6188->power_on == !!on)
2226 goto exit;
2227
2228 if (on) {
2229 ret = pm_runtime_get_sync(&client->dev);
2230 if (ret < 0) {
2231 pm_runtime_put_noidle(&client->dev);
2232 goto exit;
2233 }
2234 nvp6188->power_on = true;
2235 } else {
2236 pm_runtime_put(&client->dev);
2237 nvp6188->power_on = false;
2238 }
2239
2240 exit:
2241 mutex_unlock(&nvp6188->mutex);
2242
2243 return ret;
2244 }
2245
__nvp6188_power_on(struct nvp6188 * nvp6188)2246 static int __nvp6188_power_on(struct nvp6188 *nvp6188)
2247 {
2248 int ret;
2249 struct device *dev = &nvp6188->client->dev;
2250
2251 if (!IS_ERR_OR_NULL(nvp6188->pins_default)) {
2252 ret = pinctrl_select_state(nvp6188->pinctrl,
2253 nvp6188->pins_default);
2254 if (ret < 0)
2255 dev_err(dev, "could not set pins. ret=%d\n", ret);
2256 }
2257
2258 #if POWER_ALWAY_ON
2259 #else
2260 if (!IS_ERR(nvp6188->power_gpio)) {
2261 gpiod_set_value_cansleep(nvp6188->power_gpio, 1);
2262 usleep_range(25 * 1000, 30 * 1000);
2263 }
2264 #endif
2265
2266 usleep_range(1500, 2000);
2267
2268 ret = clk_set_rate(nvp6188->xvclk, NVP6188_XVCLK_FREQ);
2269 if (ret < 0)
2270 dev_warn(dev, "Failed to set xvclk rate\n");
2271 if (clk_get_rate(nvp6188->xvclk) != NVP6188_XVCLK_FREQ)
2272 dev_warn(dev, "xvclk mismatched\n");
2273 ret = clk_prepare_enable(nvp6188->xvclk);
2274 if (ret < 0) {
2275 dev_err(dev, "Failed to enable xvclk\n");
2276 goto err_clk;
2277 }
2278
2279 if (!IS_ERR(nvp6188->reset_gpio)) {
2280 gpiod_set_value_cansleep(nvp6188->reset_gpio, 1);
2281 usleep_range(10 * 1000, 20 * 1000);
2282 gpiod_set_value_cansleep(nvp6188->reset_gpio, 0);
2283 usleep_range(10 * 1000, 20 * 1000);
2284 gpiod_set_value_cansleep(nvp6188->reset_gpio, 1);
2285 usleep_range(100 * 1000, 110 * 1000);
2286
2287 //Resolve audio register reset caused by reset_gpio
2288 nvp6188_audio_init(nvp6188);
2289 }
2290
2291 usleep_range(10 * 1000, 20 * 1000);
2292
2293 return 0;
2294
2295 err_clk:
2296 if (!IS_ERR(nvp6188->reset_gpio))
2297 gpiod_set_value_cansleep(nvp6188->reset_gpio, 1);
2298
2299 if (!IS_ERR_OR_NULL(nvp6188->pins_sleep))
2300 pinctrl_select_state(nvp6188->pinctrl, nvp6188->pins_sleep);
2301
2302 return ret;
2303 }
2304
__nvp6188_power_off(struct nvp6188 * nvp6188)2305 static void __nvp6188_power_off(struct nvp6188 *nvp6188)
2306 {
2307 int ret;
2308 struct device *dev = &nvp6188->client->dev;
2309
2310 if (!IS_ERR(nvp6188->reset_gpio))
2311 gpiod_set_value_cansleep(nvp6188->reset_gpio, 1);
2312 clk_disable_unprepare(nvp6188->xvclk);
2313
2314 if (!IS_ERR_OR_NULL(nvp6188->pins_sleep)) {
2315 ret = pinctrl_select_state(nvp6188->pinctrl,
2316 nvp6188->pins_sleep);
2317 if (ret < 0)
2318 dev_dbg(dev, "could not set pins\n");
2319 }
2320
2321 #if POWER_ALWAY_ON
2322 #else
2323 if (!IS_ERR(nvp6188->power_gpio))
2324 gpiod_set_value_cansleep(nvp6188->power_gpio, 0);
2325 #endif
2326 }
2327
nvp6188_initialize_controls(struct nvp6188 * nvp6188)2328 static int nvp6188_initialize_controls(struct nvp6188 *nvp6188)
2329 {
2330 const struct nvp6188_mode *mode;
2331 struct v4l2_ctrl_handler *handler;
2332 u64 pixel_rate;
2333 int ret;
2334
2335 handler = &nvp6188->ctrl_handler;
2336 mode = &nvp6188->cur_mode;
2337 ret = v4l2_ctrl_handler_init(handler, 2);
2338 if (ret)
2339 return ret;
2340 handler->lock = &nvp6188->mutex;
2341
2342 nvp6188->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
2343 V4L2_CID_LINK_FREQ,
2344 ARRAY_SIZE(link_freq_items) - 1, 0,
2345 link_freq_items);
2346 __v4l2_ctrl_s_ctrl(nvp6188->link_freq, mode->mipi_freq_idx);
2347
2348 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
2349 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * NVP6188_LANES;
2350 nvp6188->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2351 V4L2_CID_PIXEL_RATE, 0, pixel_rate, 1, pixel_rate);
2352 if (handler->error) {
2353 ret = handler->error;
2354 dev_err(&nvp6188->client->dev,
2355 "Failed to init controls(%d)\n", ret);
2356 goto err_free_handler;
2357 }
2358
2359 dev_dbg(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
2360 dev_dbg(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
2361 dev_dbg(&nvp6188->client->dev, "link_freq %lld\n", link_freq_items[mode->mipi_freq_idx]);
2362
2363 nvp6188->subdev.ctrl_handler = handler;
2364
2365 return 0;
2366
2367 err_free_handler:
2368 v4l2_ctrl_handler_free(handler);
2369
2370 return ret;
2371 }
2372
nvp6188_runtime_resume(struct device * dev)2373 static int __maybe_unused nvp6188_runtime_resume(struct device *dev)
2374 {
2375 struct i2c_client *client = to_i2c_client(dev);
2376 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2377 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2378
2379 return __nvp6188_power_on(nvp6188);
2380 }
2381
nvp6188_runtime_suspend(struct device * dev)2382 static int __maybe_unused nvp6188_runtime_suspend(struct device *dev)
2383 {
2384 struct i2c_client *client = to_i2c_client(dev);
2385 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2386 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2387
2388 __nvp6188_power_off(nvp6188);
2389
2390 return 0;
2391 }
2392
2393 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
nvp6188_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2394 static int nvp6188_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2395 {
2396 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2397 struct v4l2_mbus_framefmt *try_fmt =
2398 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2399 const struct nvp6188_mode *def_mode = &supported_modes[0];
2400
2401 dev_dbg(&nvp6188->client->dev, "%s\n", __func__);
2402
2403 mutex_lock(&nvp6188->mutex);
2404 /* Initialize try_fmt */
2405 try_fmt->width = def_mode->width;
2406 try_fmt->height = def_mode->height;
2407 try_fmt->code = def_mode->bus_fmt;
2408 try_fmt->field = V4L2_FIELD_NONE;
2409
2410 mutex_unlock(&nvp6188->mutex);
2411 /* No crop or compose */
2412
2413 return 0;
2414 }
2415 #endif
2416
2417 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2418 static const struct v4l2_subdev_internal_ops nvp6188_internal_ops = {
2419 .open = nvp6188_open,
2420 };
2421 #endif
2422
2423 static const struct v4l2_subdev_video_ops nvp6188_video_ops = {
2424 .s_stream = nvp6188_stream,
2425 .g_frame_interval = nvp6188_g_frame_interval,
2426 };
2427
2428 static const struct v4l2_subdev_pad_ops nvp6188_subdev_pad_ops = {
2429 .enum_mbus_code = nvp6188_enum_mbus_code,
2430 .enum_frame_size = nvp6188_enum_frame_sizes,
2431 .enum_frame_interval = nvp6188_enum_frame_interval,
2432 .get_fmt = nvp6188_get_fmt,
2433 .set_fmt = nvp6188_set_fmt,
2434 .get_mbus_config = nvp6188_g_mbus_config,
2435 };
2436
2437 static const struct v4l2_subdev_core_ops nvp6188_core_ops = {
2438 .s_power = nvp6188_power,
2439 .ioctl = nvp6188_ioctl,
2440 #ifdef CONFIG_COMPAT
2441 .compat_ioctl32 = nvp6188_compat_ioctl32,
2442 #endif
2443 };
2444
2445 static const struct v4l2_subdev_ops nvp6188_subdev_ops = {
2446 .core = &nvp6188_core_ops,
2447 .video = &nvp6188_video_ops,
2448 .pad = &nvp6188_subdev_pad_ops,
2449 };
2450
2451 /* -----------------------------------------------------------------------------
2452 * Audio Codec
2453 */
nvp6188_codec_read(struct snd_soc_component * component,unsigned int reg)2454 static unsigned int nvp6188_codec_read(struct snd_soc_component *component,
2455 unsigned int reg)
2456 {
2457 struct v4l2_subdev *sd = snd_soc_component_get_drvdata(component);
2458 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2459 struct i2c_client *client = nvp6188->client;
2460 int ret;
2461 u8 val;
2462
2463 mutex_lock(&nvp6188->mutex);
2464 ret = nvp6188_read_reg(client, reg, &val);
2465 if (ret < 0) {
2466 dev_err(&client->dev, "%s failed: (%d)\n", __func__, ret);
2467 mutex_unlock(&nvp6188->mutex);
2468 return ret;
2469 }
2470
2471 mutex_unlock(&nvp6188->mutex);
2472 return val;
2473 }
2474
nvp6188_codec_write(struct snd_soc_component * component,unsigned int reg,unsigned int val)2475 static int nvp6188_codec_write(struct snd_soc_component *component,
2476 unsigned int reg, unsigned int val)
2477 {
2478 struct v4l2_subdev *sd = snd_soc_component_get_drvdata(component);
2479 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2480 struct i2c_client *client = nvp6188->client;
2481 int ret;
2482
2483 mutex_lock(&nvp6188->mutex);
2484 ret = nvp6188_write_reg(client, reg, val);
2485 if (ret < 0) {
2486 dev_err(&client->dev, "%s failed: (%d)\n", __func__, ret);
2487 mutex_unlock(&nvp6188->mutex);
2488 return ret;
2489 }
2490
2491 mutex_unlock(&nvp6188->mutex);
2492 return 0;
2493 }
2494
nvp6188_pcm_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)2495 static int nvp6188_pcm_startup(struct snd_pcm_substream *substream,
2496 struct snd_soc_dai *dai)
2497 {
2498 return 0;
2499 }
2500
nvp6188_pcm_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)2501 static void nvp6188_pcm_shutdown(struct snd_pcm_substream *substream,
2502 struct snd_soc_dai *dai)
2503 {
2504 }
2505
nvp6188_pcm_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)2506 static int nvp6188_pcm_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2507 {
2508 struct v4l2_subdev *sd = snd_soc_dai_get_drvdata(dai);
2509 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2510 struct i2c_client *client = nvp6188->client;
2511 u8 val_rm = 0, val_pb = 0;
2512 int ret = 0;
2513
2514 mutex_lock(&nvp6188->mutex);
2515 nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
2516 nvp6188_read_reg(client, 0x07, &val_rm);
2517 nvp6188_read_reg(client, 0x13, &val_pb);
2518 /* set master/slave audio interface */
2519 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2520 case SND_SOC_DAIFMT_CBM_CFM: /* MASTER MODE */
2521 val_rm |= 0x80;
2522 val_pb |= 0x80;
2523 break;
2524 case SND_SOC_DAIFMT_CBS_CFS: /* SLAVE MODE */
2525 val_rm &= (~0x80);
2526 val_pb &= (~0x80);
2527 break;
2528 default:
2529 ret = -EINVAL;
2530 goto unlock;
2531 }
2532
2533 /* interface format */
2534 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2535 case SND_SOC_DAIFMT_I2S: /* I2S MODE */
2536 val_rm &= (~0x01);
2537 val_pb &= (~0x01);
2538 break;
2539 case SND_SOC_DAIFMT_DSP_A: /* DSP MODE */
2540 val_rm |= 0x01;
2541 val_pb |= 0x01;
2542 break;
2543 case SND_SOC_DAIFMT_DSP_B: /* SSP MODE */
2544 val_rm |= 0x03;
2545 val_pb |= 0x03;
2546 break;
2547 default:
2548 ret = -EINVAL;
2549 goto unlock;
2550 }
2551
2552 /* clock inversion */
2553 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2554 case SND_SOC_DAIFMT_NB_NF: /* Inverted Clock */
2555 val_rm &= (~0x40);
2556 val_pb &= (~0x40);
2557 break;
2558 case SND_SOC_DAIFMT_IB_NF: /* Non-inverted Clock */
2559 val_rm |= 0x40;
2560 val_pb |= 0x40;
2561 break;
2562 default:
2563 ret = -EINVAL;
2564 goto unlock;
2565 }
2566
2567 nvp6188_write_reg(client, 0x07, val_rm);
2568 nvp6188_write_reg(client, 0x13, val_pb);
2569
2570 unlock:
2571 mutex_unlock(&nvp6188->mutex);
2572
2573 return ret;
2574 }
2575
nvp6188_pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)2576 static int nvp6188_pcm_hw_params(struct snd_pcm_substream *substream,
2577 struct snd_pcm_hw_params *params,
2578 struct snd_soc_dai *dai)
2579 {
2580 struct v4l2_subdev *sd = snd_soc_dai_get_drvdata(dai);
2581 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2582 struct i2c_client *client = nvp6188->client;
2583 u8 val = 0;
2584 int ret = 0;
2585
2586 mutex_lock(&nvp6188->mutex);
2587 nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
2588
2589 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
2590 /* Configure formats for Playback */
2591 nvp6188_read_reg(client, 0x13, &val);
2592 switch (params_format(params)) {
2593 case SNDRV_PCM_FORMAT_S8:
2594 val |= 0x04;
2595 break;
2596 case SNDRV_PCM_FORMAT_S16_LE:
2597 val &= (~0x04);
2598 break;
2599 default:
2600 ret = -EINVAL;
2601 goto unlock;
2602 }
2603
2604 switch (params_rate(params)) {
2605 case 8000:
2606 val &= (~0x08);
2607 break;
2608 case 16000:
2609 val |= 0x08;
2610 break;
2611 case 32000:
2612 /* TODO */
2613 break;
2614 default:
2615 ret = -EINVAL;
2616 goto unlock;
2617 }
2618
2619 if (nvp6188->audio_out) {
2620 switch (nvp6188->audio_out->mclk_fs) {
2621 case 256:
2622 val = ((val & (~0x30)) | 0x00);
2623 break;
2624 case 384:
2625 val = ((val & (~0x30)) | 0x10);
2626 break;
2627 case 320:
2628 val = ((val & (~0x30)) | 0x20);
2629 break;
2630 default:
2631 dev_err(&client->dev, "Invalid audio_out mclk_fs: %d\n",
2632 nvp6188->audio_out->mclk_fs);
2633 ret = -EINVAL;
2634 goto unlock;
2635 }
2636 }
2637
2638 nvp6188_write_reg(client, 0x13, val);
2639 } else {
2640 /* Configure formats for Capture */
2641 nvp6188_read_reg(client, 0x07, &val);
2642 switch (params_format(params)) {
2643 case SNDRV_PCM_FORMAT_S8:
2644 val |= 0x04;
2645 break;
2646 case SNDRV_PCM_FORMAT_S16_LE:
2647 val &= (~0x04);
2648 break;
2649 default:
2650 ret = -EINVAL;
2651 goto unlock;
2652 }
2653
2654 switch (params_rate(params)) {
2655 case 8000:
2656 val &= (~0x08);
2657 break;
2658 case 16000:
2659 val |= 0x08;
2660 break;
2661 case 32000:
2662 /* TODO */
2663 break;
2664 default:
2665 ret = -EINVAL;
2666 goto unlock;
2667 }
2668
2669 if (nvp6188->audio_in) {
2670 switch (nvp6188->audio_in->mclk_fs) {
2671 case 256:
2672 val = ((val & (~0x30)) | 0x00);
2673 break;
2674 case 384:
2675 val = ((val & (~0x30)) | 0x10);
2676 break;
2677 case 320:
2678 val = ((val & (~0x30)) | 0x20);
2679 break;
2680 default:
2681 dev_err(&client->dev, "Invalid audio_in mclk_fs: %d\n",
2682 nvp6188->audio_in->mclk_fs);
2683 ret = -EINVAL;
2684 goto unlock;
2685 }
2686 }
2687 nvp6188_write_reg(client, 0x07, val);
2688
2689 nvp6188_read_reg(client, 0x08, &val);
2690 switch (params_channels(params)) {
2691 case 2:
2692 val = (val & (~0x03));
2693 break;
2694 case 4:
2695 val = (val & (~0x03)) | 0x01;
2696 break;
2697 default:
2698 dev_err(&client->dev, "Not supported channels: %d\n",
2699 params_channels(params));
2700 ret = -EINVAL;
2701 goto unlock;
2702 }
2703 nvp6188_write_reg(client, 0x08, val);
2704 }
2705
2706 unlock:
2707 mutex_unlock(&nvp6188->mutex);
2708
2709 return ret;
2710 }
2711
nvp6188_pcm_mute(struct snd_soc_dai * dai,int mute,int stream)2712 static int nvp6188_pcm_mute(struct snd_soc_dai *dai, int mute, int stream)
2713 {
2714 return 0;
2715 }
2716
2717 static const struct snd_soc_dai_ops nvp6188_dai_ops = {
2718 .startup = nvp6188_pcm_startup,
2719 .shutdown = nvp6188_pcm_shutdown,
2720 .set_fmt = nvp6188_pcm_set_dai_fmt,
2721 .hw_params = nvp6188_pcm_hw_params,
2722 .mute_stream = nvp6188_pcm_mute,
2723 };
2724
2725 static struct snd_soc_dai_driver nvp6188_audio_dai = {
2726 .name = "nvp6188",
2727 .playback = {
2728 .stream_name = "Playback",
2729 .channels_min = 1,
2730 .channels_max = 16,
2731 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
2732 SNDRV_PCM_RATE_32000,
2733 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE),
2734 },
2735 .capture = {
2736 .stream_name = "Capture",
2737 .channels_min = 1,
2738 .channels_max = 16,
2739 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
2740 SNDRV_PCM_RATE_32000,
2741 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE),
2742 },
2743 .ops = &nvp6188_dai_ops,
2744 };
2745
nvp6188_codec_probe(struct snd_soc_component * component)2746 static int nvp6188_codec_probe(struct snd_soc_component *component)
2747 {
2748 return 0;
2749 }
2750
nvp6188_codec_remove(struct snd_soc_component * component)2751 static void nvp6188_codec_remove(struct snd_soc_component *component)
2752 {
2753 }
2754
2755 /*
2756 * Control Functions
2757 */
2758
2759 /* nvp6188 tlv kcontrol calls */
nvp6188_codec_tlv_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2760 static int nvp6188_codec_tlv_get(struct snd_kcontrol *kcontrol,
2761 struct snd_ctl_elem_value *ucontrol)
2762 {
2763 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2764 struct v4l2_subdev *sd = snd_soc_component_get_drvdata(component);
2765 struct nvp6188 *nvp6188 = to_nvp6188(sd);
2766 struct i2c_client *client = nvp6188->client;
2767
2768 mutex_lock(&nvp6188->mutex);
2769 nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
2770 mutex_unlock(&nvp6188->mutex);
2771 return snd_soc_get_volsw(kcontrol, ucontrol);
2772 }
2773
nvp6188_codec_tlv_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2774 static int nvp6188_codec_tlv_put(struct snd_kcontrol *kcontrol,
2775 struct snd_ctl_elem_value *ucontrol)
2776 {
2777 return snd_soc_put_volsw(kcontrol, ucontrol);
2778 }
2779
2780 static const DECLARE_TLV_DB_SCALE(nvp6188_codec_aiao_gains_tlv, 0, 125, 1875);
2781
2782 /*
2783 * KControls
2784 */
2785 static const struct snd_kcontrol_new nvp6188_codec_controls[] = {
2786 /* AIGAINs and MIGAIN */
2787 SOC_SINGLE_EXT_TLV("AIGain_01", 0x01,
2788 0,
2789 0x0f,
2790 0,
2791 nvp6188_codec_tlv_get,
2792 nvp6188_codec_tlv_put,
2793 nvp6188_codec_aiao_gains_tlv),
2794 SOC_SINGLE_EXT_TLV("AIGain_02", 0x02,
2795 0,
2796 0x0f,
2797 0,
2798 nvp6188_codec_tlv_get,
2799 nvp6188_codec_tlv_put,
2800 nvp6188_codec_aiao_gains_tlv),
2801 SOC_SINGLE_EXT_TLV("AIGain_03", 0x03,
2802 0,
2803 0x0f,
2804 0,
2805 nvp6188_codec_tlv_get,
2806 nvp6188_codec_tlv_put,
2807 nvp6188_codec_aiao_gains_tlv),
2808 SOC_SINGLE_EXT_TLV("AIGain_04", 0x04,
2809 0,
2810 0x0f,
2811 0,
2812 nvp6188_codec_tlv_get,
2813 nvp6188_codec_tlv_put,
2814 nvp6188_codec_aiao_gains_tlv),
2815 SOC_SINGLE_EXT_TLV("MIGain", 0x05,
2816 0,
2817 0x0f,
2818 0,
2819 nvp6188_codec_tlv_get,
2820 nvp6188_codec_tlv_put,
2821 nvp6188_codec_aiao_gains_tlv),
2822
2823 /* AOGAIN */
2824 SOC_SINGLE_EXT_TLV("AOGain", 0x22,
2825 0,
2826 0x0f,
2827 0,
2828 nvp6188_codec_tlv_get,
2829 nvp6188_codec_tlv_put,
2830 nvp6188_codec_aiao_gains_tlv),
2831 };
2832
2833 static struct snd_soc_component_driver nvp6188_codec_driver = {
2834 .probe = nvp6188_codec_probe,
2835 .remove = nvp6188_codec_remove,
2836 .read = nvp6188_codec_read,
2837 .write = nvp6188_codec_write,
2838 .controls = nvp6188_codec_controls,
2839 .num_controls = ARRAY_SIZE(nvp6188_codec_controls),
2840 .idle_bias_on = 1,
2841 .use_pmdown_time = 1,
2842 .endianness = 1,
2843 .non_legacy_dai_naming = 1,
2844 };
2845
check_chip_id(struct i2c_client * client)2846 static int check_chip_id(struct i2c_client *client){
2847 struct device *dev = &client->dev;
2848 unsigned char chip_id = 0, chip_revid = 0;
2849 nvp6188_write_reg(client, 0xFF, 0x00);
2850 nvp6188_read_reg(client, 0xF4, &chip_id);
2851
2852 nvp6188_write_reg(client, 0xFF, 0x00);
2853 nvp6188_read_reg(client, 0xF5, &chip_revid);
2854 dev_err(dev, "chip_id : 0x%2x chip_revid : 0x%2x \n", chip_id, chip_revid);
2855 if (chip_id != 0xd0 && chip_id != 0xd3) {
2856 return -1;
2857 }
2858 return 0;
2859 }
2860
nvp6188_audio_init(struct nvp6188 * nvp6188)2861 static int nvp6188_audio_init(struct nvp6188 *nvp6188)
2862 {
2863 struct i2c_client *client = nvp6188->client;
2864
2865 if (!nvp6188->audio_in && !nvp6188->audio_out)
2866 return 0;
2867
2868 /* Switch to bank1 for audio */
2869 nvp6188_write_reg(client, 0xff, 0x01);
2870 nvp6188_write_reg(client, 0x94, 0x00);
2871
2872 /* Single chip operation */
2873 nvp6188_write_reg(client, 0x06, 0x03);
2874
2875 /* MSB/u-law/linear PCM/Speaker data/4ch */
2876 nvp6188_write_reg(client, 0x08, 0x01);
2877
2878 /* Channels mapping */
2879 nvp6188_write_reg(client, 0x0a, 0x20);
2880 nvp6188_write_reg(client, 0x0b, 0x98);
2881 nvp6188_write_reg(client, 0x0f, 0x31);
2882
2883 /* AOGAIN 1.0 */
2884 nvp6188_write_reg(client, 0x22, 0x08);
2885 /* First stage playback audio*/
2886 nvp6188_write_reg(client, 0x23, 0x10);
2887
2888 /* Slave */
2889 nvp6188_write_reg(client, 0x39, 0x82);
2890
2891 nvp6188_write_reg(client, 0x01, 0x09);
2892 nvp6188_write_reg(client, 0x02, 0x09);
2893 nvp6188_write_reg(client, 0x03, 0x09);
2894 nvp6188_write_reg(client, 0x04, 0x09);
2895 nvp6188_write_reg(client, 0x05, 0x09);
2896
2897 nvp6188_write_reg(client, 0x31, 0x0a);
2898 nvp6188_write_reg(client, 0x47, 0x01);
2899 nvp6188_write_reg(client, 0x49, 0x88);
2900 nvp6188_write_reg(client, 0x44, 0x00);
2901
2902 nvp6188_write_reg(client, 0x32, 0x00);
2903 /* Filter on / 16K Mode */
2904 nvp6188_write_reg(client, 0x00, 0x02);
2905 nvp6188_write_reg(client, 0x46, 0x10);
2906 nvp6188_write_reg(client, 0x48, 0xD0);
2907 nvp6188_write_reg(client, 0x94, 0x40);
2908
2909 nvp6188_write_reg(client, 0x38, 0x18);
2910 msleep(30);
2911 nvp6188_write_reg(client, 0x38, 0x08);
2912
2913 //SLAVE MODE I2S MODE Inverted Clock
2914 nvp6188_write_reg(client, 0xff, 0x01);
2915 nvp6188_write_reg(client, 0x07, 0x08);
2916 nvp6188_write_reg(client, 0x13, 0x08);
2917
2918 return 0;
2919 }
2920
nvp6188_probe(struct i2c_client * client,const struct i2c_device_id * id)2921 static int nvp6188_probe(struct i2c_client *client,
2922 const struct i2c_device_id *id)
2923 {
2924 struct device *dev = &client->dev;
2925 struct device_node *node = dev->of_node;
2926 struct nvp6188 *nvp6188;
2927 struct v4l2_subdev *sd;
2928 const char *str;
2929 __maybe_unused char facing[2];
2930 u32 v;
2931 int ret;
2932
2933 dev_info(dev, "driver version: %02x.%02x.%02x",
2934 DRIVER_VERSION >> 16,
2935 (DRIVER_VERSION & 0xff00) >> 8,
2936 DRIVER_VERSION & 0x00ff);
2937
2938 nvp6188 = devm_kzalloc(dev, sizeof(*nvp6188), GFP_KERNEL);
2939 if (!nvp6188)
2940 return -ENOMEM;
2941
2942 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
2943 &nvp6188->module_index);
2944 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
2945 &nvp6188->module_facing);
2946 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
2947 &nvp6188->module_name);
2948 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
2949 &nvp6188->len_name);
2950 if (ret) {
2951 dev_err(dev, "could not get %s!\n", RKMODULE_CAMERA_LENS_NAME);
2952 return -EINVAL;
2953 }
2954
2955 nvp6188->client = client;
2956 nvp6188->cfg_num = ARRAY_SIZE(supported_modes);
2957 memcpy(&nvp6188->cur_mode, &supported_modes[0], sizeof(struct nvp6188_mode));
2958
2959 nvp6188->xvclk = devm_clk_get(dev, "xvclk");
2960 if (IS_ERR(nvp6188->xvclk)) {
2961 dev_err(dev, "Failed to get xvclk\n");
2962 return -EINVAL;
2963 }
2964
2965 nvp6188->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
2966 if (IS_ERR(nvp6188->reset_gpio))
2967 dev_warn(dev, "Failed to get reset-gpios\n");
2968
2969 nvp6188->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
2970 if (IS_ERR(nvp6188->power_gpio))
2971 dev_warn(dev, "Failed to get power-gpios\n");
2972
2973 nvp6188->vi_gpio = devm_gpiod_get(dev, "vi", GPIOD_OUT_HIGH);
2974 if (IS_ERR(nvp6188->vi_gpio))
2975 dev_warn(dev, "Failed to get vi-gpios\n");
2976
2977 nvp6188->pinctrl = devm_pinctrl_get(dev);
2978 if (!IS_ERR(nvp6188->pinctrl)) {
2979 nvp6188->pins_default =
2980 pinctrl_lookup_state(nvp6188->pinctrl,
2981 OF_CAMERA_PINCTRL_STATE_DEFAULT);
2982 if (IS_ERR(nvp6188->pins_default))
2983 dev_info(dev, "could not get default pinstate\n");
2984
2985 nvp6188->pins_sleep =
2986 pinctrl_lookup_state(nvp6188->pinctrl,
2987 OF_CAMERA_PINCTRL_STATE_SLEEP);
2988 if (IS_ERR(nvp6188->pins_sleep))
2989 dev_info(dev, "could not get sleep pinstate\n");
2990 } else {
2991 dev_info(dev, "no pinctrl\n");
2992 }
2993
2994 mutex_init(&nvp6188->mutex);
2995
2996 sd = &nvp6188->subdev;
2997 v4l2_i2c_subdev_init(sd, client, &nvp6188_subdev_ops);
2998 ret = nvp6188_initialize_controls(nvp6188);
2999 if (ret) {
3000 dev_err(dev, "Failed to initialize controls nvp6188\n");
3001 goto err_destroy_mutex;
3002 }
3003
3004 ret = __nvp6188_power_on(nvp6188);
3005 if (ret) {
3006 dev_err(dev, "Failed to power on nvp6188\n");
3007 goto err_free_handler;
3008 }
3009
3010 ret = check_chip_id(client);
3011 if (ret) {
3012 dev_err(dev, "Failed to check senosr id\n");
3013 goto err_free_handler;
3014 }
3015
3016 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
3017 sd->internal_ops = &nvp6188_internal_ops;
3018 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
3019 #endif
3020
3021 #if defined(CONFIG_MEDIA_CONTROLLER)
3022 nvp6188->pad.flags = MEDIA_PAD_FL_SOURCE;
3023 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
3024 ret = media_entity_pads_init(&sd->entity, 1, &nvp6188->pad);
3025 if (ret < 0)
3026 goto err_power_off;
3027 #endif
3028
3029 memset(facing, 0, sizeof(facing));
3030 if (strcmp(nvp6188->module_facing, "back") == 0)
3031 facing[0] = 'b';
3032 else
3033 facing[0] = 'f';
3034
3035 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
3036 nvp6188->module_index, facing,
3037 NVP6188_NAME, dev_name(sd->dev));
3038
3039 ret = v4l2_async_register_subdev_sensor_common(sd);
3040 if (ret) {
3041 dev_err(dev, "v4l2 async register subdev failed\n");
3042 goto err_clean_entity;
3043 }
3044
3045 /* Parse audio parts */
3046 nvp6188->audio_in = NULL;
3047 if (!of_property_read_string(node, "rockchip,audio-in-format", &str)) {
3048 struct nvp6188_audio *audio_stream;
3049
3050 nvp6188->audio_in = devm_kzalloc(dev, sizeof(struct nvp6188_audio), GFP_KERNEL);
3051 if (!nvp6188->audio_in) {
3052 dev_err(dev, "alloc audio_in failed\n");
3053 return -ENOMEM;
3054 }
3055 audio_stream = nvp6188->audio_in;
3056
3057 if (strcmp(str, "i2s") == 0)
3058 audio_stream->audfmt = AUDFMT_I2S;
3059 else if (strcmp(str, "dsp") == 0)
3060 audio_stream->audfmt = AUDFMT_DSP;
3061 else if (strcmp(str, "ssp") == 0)
3062 audio_stream->audfmt = AUDFMT_SSP;
3063 else {
3064 dev_err(dev, "rockchip,audio-in-format invalid\n");
3065 return -EINVAL;
3066 }
3067
3068 if (!of_property_read_u32(node, "rockchip,audio-in-mclk-fs", &v)) {
3069 switch (v) {
3070 case 256:
3071 case 384:
3072 case 320:
3073 break;
3074 default:
3075 dev_err(dev,
3076 "rockchip,audio-in-mclk-fs invalid\n");
3077 return -EINVAL;
3078 }
3079 audio_stream->mclk_fs = v;
3080 }
3081 }
3082
3083 nvp6188->audio_out = NULL;
3084 if (!of_property_read_string(node, "rockchip,audio-out-format", &str)) {
3085 struct nvp6188_audio *audio_stream;
3086
3087 nvp6188->audio_out = devm_kzalloc(dev, sizeof(struct nvp6188_audio), GFP_KERNEL);
3088 if (!nvp6188->audio_out) {
3089 dev_err(dev, "alloc audio_out failed\n");
3090 return -ENOMEM;
3091 }
3092 audio_stream = nvp6188->audio_out;
3093
3094 if (strcmp(str, "i2s") == 0)
3095 audio_stream->audfmt = AUDFMT_I2S;
3096 else if (strcmp(str, "dsp") == 0)
3097 audio_stream->audfmt = AUDFMT_DSP;
3098 else if (strcmp(str, "ssp") == 0)
3099 audio_stream->audfmt = AUDFMT_SSP;
3100 else {
3101 dev_err(dev, "rockchip,audio-out-format invalid\n");
3102 return -EINVAL;
3103 }
3104
3105 if (!of_property_read_u32(node, "rockchip,audio-out-mclk-fs", &v)) {
3106 switch (v) {
3107 case 256:
3108 case 384:
3109 case 320:
3110 break;
3111 default:
3112 dev_err(dev,
3113 "rockchip,audio-out-mclk-fs invalid\n");
3114 return -EINVAL;
3115 }
3116 audio_stream->mclk_fs = v;
3117 }
3118 }
3119
3120 /* Register audio DAIs */
3121 if (nvp6188->audio_in || nvp6188->audio_out) {
3122 ret = devm_snd_soc_register_component(dev,
3123 &nvp6188_codec_driver,
3124 &nvp6188_audio_dai, 1);
3125 if (ret) {
3126 dev_err(dev, "register audio codec failed\n");
3127 return -EINVAL;
3128 }
3129
3130 dev_info(dev, "registered audio codec\n");
3131 nvp6188_audio_init(nvp6188);
3132 }
3133
3134 if (sysfs_create_group(&dev->kobj, &dev_attr_grp))
3135 return -ENODEV;
3136
3137 nvp6188->input_dev = devm_input_allocate_device(dev);
3138 if (nvp6188->input_dev == NULL) {
3139 dev_err(dev, "failed to allocate nvp6188 input device\n");
3140 return -ENOMEM;
3141 }
3142 nvp6188->input_dev->name = "nvp6188_input_event";
3143 set_bit(EV_MSC, nvp6188->input_dev->evbit);
3144 set_bit(MSC_RAW, nvp6188->input_dev->mscbit);
3145
3146 ret = input_register_device(nvp6188->input_dev);
3147 if (ret) {
3148 pr_err("%s: failed to register nvp6188 input device\n", __func__);
3149 return ret;
3150 }
3151
3152 pm_runtime_set_active(dev);
3153 pm_runtime_enable(dev);
3154 pm_runtime_idle(dev);
3155
3156 nvp6188_video_init(nvp6188);
3157
3158 return 0;
3159
3160 err_clean_entity:
3161 #if defined(CONFIG_MEDIA_CONTROLLER)
3162 media_entity_cleanup(&sd->entity);
3163 #endif
3164 err_power_off:
3165 __nvp6188_power_off(nvp6188);
3166 err_free_handler:
3167 v4l2_ctrl_handler_free(&nvp6188->ctrl_handler);
3168 err_destroy_mutex:
3169 mutex_destroy(&nvp6188->mutex);
3170
3171 return ret;
3172 }
3173
nvp6188_remove(struct i2c_client * client)3174 static int nvp6188_remove(struct i2c_client *client)
3175 {
3176 struct v4l2_subdev *sd = i2c_get_clientdata(client);
3177 struct nvp6188 *nvp6188 = to_nvp6188(sd);
3178
3179 v4l2_async_unregister_subdev(sd);
3180 #if defined(CONFIG_MEDIA_CONTROLLER)
3181 media_entity_cleanup(&sd->entity);
3182 #endif
3183 v4l2_ctrl_handler_free(&nvp6188->ctrl_handler);
3184 mutex_destroy(&nvp6188->mutex);
3185
3186 pm_runtime_disable(&client->dev);
3187 if (!pm_runtime_status_suspended(&client->dev))
3188 __nvp6188_power_off(nvp6188);
3189 pm_runtime_set_suspended(&client->dev);
3190
3191 return 0;
3192 }
3193
3194 static const struct dev_pm_ops __maybe_unused nvp6188_pm_ops = {
3195 SET_RUNTIME_PM_OPS(nvp6188_runtime_suspend,
3196 nvp6188_runtime_resume, NULL)
3197 };
3198
3199 #if IS_ENABLED(CONFIG_OF)
3200 static const struct of_device_id nvp6188_of_match[] = {
3201 { .compatible = "nvp6188" },
3202 {},
3203 };
3204 MODULE_DEVICE_TABLE(of, nvp6188_of_match);
3205 #endif
3206
3207 static const struct i2c_device_id nvp6188_match_id[] = {
3208 { "nvp6188", 0 },
3209 { },
3210 };
3211
3212 static struct i2c_driver nvp6188_i2c_driver = {
3213 .driver = {
3214 .name = NVP6188_NAME,
3215 //.pm = &nvp6188_pm_ops,
3216 .of_match_table = of_match_ptr(nvp6188_of_match),
3217 },
3218 .probe = &nvp6188_probe,
3219 .remove = &nvp6188_remove,
3220 .id_table = nvp6188_match_id,
3221 };
3222
nvp6188_sensor_mod_init(void)3223 int nvp6188_sensor_mod_init(void)
3224 {
3225 return i2c_add_driver(&nvp6188_i2c_driver);
3226 }
3227
3228 #ifndef CONFIG_VIDEO_REVERSE_IMAGE
3229 device_initcall_sync(nvp6188_sensor_mod_init);
3230 #endif
3231
sensor_mod_exit(void)3232 static void __exit sensor_mod_exit(void)
3233 {
3234 i2c_del_driver(&nvp6188_i2c_driver);
3235 }
3236
3237 module_exit(sensor_mod_exit);
3238
3239 MODULE_AUTHOR("Vicent Chi <vicent.chi@rock-chips.com>");
3240 MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
3241 MODULE_DESCRIPTION("nvp6188 sensor driver");
3242 MODULE_LICENSE("GPL v2");
3243