Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: drivers/media/video/samsung/tv20/s5p_stda_video_layer.c

Issue 2036011: V4L/DVB : Add S5PV210 TV out driver support (Closed) Base URL: swsolcc@12.23.106.100:kernel-samsung.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* linux/drivers/media/video/samsung/tv20/s5p_stda_video_layer.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - Video Layer ftn. file for Samsung TVOut driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/stddef.h>
16 #include <linux/delay.h>
17 #include <linux/ioctl.h>
18 #include <linux/clk.h>
19
20 #include <linux/io.h>
21 #include <linux/uaccess.h>
22
23 #include "s5p_tv.h"
24
25 #ifdef CONFIG_TVOUT_DBG
26 #define S5P_VLAYER_DEBUG 1
27 #endif
28
29 #ifdef S5P_VLAYER_DEBUG
30 #define VLAYERPRINTK(fmt, args...) \
31 printk(KERN_INFO "\t[VLAYER] %s: " fmt, __func__ , ## args)
32 #else
33 #define VLAYERPRINTK(fmt, args...)
34 #endif
35
36 #define INTERLACED 0
37 #define PROGRESSIVE 1
38
39 u8 check_input_mode(enum s5p_vp_src_color color)
40 {
41 u8 ret = PROGRESSIVE;
42
43 /* check i_mode */
44 if (color == VPROC_SRC_COLOR_NV12IW ||
45 color == VPROC_SRC_COLOR_TILE_NV12IW)
46 ret = INTERLACED; /* interlaced */
47 else
48 ret = PROGRESSIVE; /* progressive */
49
50 return ret;
51 }
52
53 u8 check_output_mode(enum s5p_tv_disp_mode display,
54 enum s5p_tv_o_mode out)
55 {
56 u8 ret = PROGRESSIVE;
57
58 switch (out) {
59 case TVOUT_OUTPUT_COMPOSITE:
60 case TVOUT_OUTPUT_SVIDEO:
61 case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
62 ret = INTERLACED;
63 break;
64 case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
65 case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
66 case TVOUT_OUTPUT_HDMI_RGB:
67 case TVOUT_OUTPUT_HDMI:
68 case TVOUT_OUTPUT_DVI:
69 if (display == TVOUT_1080I_60 ||
70 display == TVOUT_1080I_59 ||
71 display == TVOUT_1080I_50)
72
73 ret = INTERLACED;
74 else
75 ret = PROGRESSIVE;
76 break;
77 default:
78 break;
79 }
80
81 return ret;
82
83 }
84
85 static bool tv_vlayer_wait_previous_update(void)
86 {
87 tv_vp_get_update_status();
88 return false;
89 }
90
91 static void tv_vlayer_calc_inner_values(void)
92 {
93 struct s5p_tv_status *st = &s5ptv_status;
94 struct s5p_vl_param *video = &(s5ptv_status.vl_basic_param);
95 u8 o_mode, i_mode;
96
97 u32 t_y_addr = video->top_y_address;
98 u32 t_c_addr = video->top_c_address;
99 u32 img_w = video->img_width;
100 u32 s_ox = video->src_offset_x;
101 u32 s_oy = video->src_offset_y;
102 u32 d_ox = video->dest_offset_x;
103 u32 d_oy = video->dest_offset_y;
104 u32 s_w = video->src_width;
105 u32 s_h = video->src_height;
106 u32 d_w = video->dest_width;
107 u32 d_h = video->dest_height;
108
109 i_mode = check_input_mode(st->src_color);
110 o_mode = check_output_mode(st->tvout_param.disp_mode,
111 st->tvout_param.out_mode);
112
113 st->vl_top_y_address = t_y_addr;
114 st->vl_top_c_address = t_c_addr;
115
116 if (st->src_color == VPROC_SRC_COLOR_NV12IW) {
117 st->vl_bottom_y_address = t_y_addr + img_w;
118 st->vl_bottom_c_address = t_c_addr + img_w;
119 } else if (st->src_color == VPROC_SRC_COLOR_TILE_NV12IW) {
120 st->vl_bottom_y_address = t_y_addr + 0x40;
121 st->vl_bottom_c_address = t_c_addr + 0x40;
122 }
123
124 st->vl_src_offset_x = s_ox;
125 st->vl_src_offset_y = s_oy;
126 st->vl_src_width = s_w;
127 st->vl_src_height = s_h;
128 st->vl_dest_offset_x = d_ox;
129 st->vl_dest_offset_y = d_oy;
130 st->vl_dest_width = d_w;
131 st->vl_dest_height = d_h;
132
133
134 if (o_mode == INTERLACED) {
135 st->vl_src_height = s_h / 2;
136 st->vl_src_offset_y = s_oy / 2;
137 st->vl_dest_height = d_h / 2;
138 st->vl_dest_offset_y = d_oy / 2;
139 } else {
140 if (i_mode == INTERLACED) {
141 st->vl_src_height = s_h / 2;
142 st->vl_src_offset_y = s_oy / 2;
143 }
144 }
145 }
146
147 bool tv_vlayer_start(void)
148 {
149 int i;
150
151 enum s5p_tv_vp_err verr;
152 enum s5p_tv_vmx_err merr;
153 struct s5p_video_img_address temp_addr;
154 struct s5p_img_size img_size;
155
156 struct s5p_vl_param param
157 = s5ptv_status.vl_basic_param;
158
159 u8 contrast = s5ptv_status.vl_contrast;
160
161 u32 ty_addr = s5ptv_status.vl_top_y_address;
162 u32 tc_addr = s5ptv_status.vl_top_c_address;
163 u32 by_addr = s5ptv_status.vl_bottom_y_address;
164 u32 bc_addr = s5ptv_status.vl_bottom_c_address;
165 u32 endian = param.src_img_endian;
166 u32 i_w = param.src_width;
167 u32 i_h = param.src_height;
168 u32 s_ox = s5ptv_status.vl_src_offset_x;
169 u32 s_xf = s5ptv_status.vl_src_x_fact_step;
170 u32 s_oy = s5ptv_status.vl_src_offset_y;
171 u32 s_w = s5ptv_status.vl_src_width;
172 u32 s_h = s5ptv_status.vl_src_height;
173 u32 d_ox = s5ptv_status.vl_dest_offset_x;
174 u32 d_oy = s5ptv_status.vl_dest_offset_y;
175 u32 d_w = s5ptv_status.vl_dest_width;
176 u32 d_h = s5ptv_status.vl_dest_height;
177 u32 noise = s5ptv_status.vl_sharpness.th_noise;
178 u32 saturation = s5ptv_status.vl_saturation;
179 u32 alpha = param.alpha;
180 u32 priority = param.priority;
181 u32 br_offset = s5ptv_status.vl_bright_offset;
182
183 bool ipc = s5ptv_status.vl2d_ipc;
184 bool l_skip = s5ptv_status.vl_op_mode.line_skip;
185 bool bypass = s5ptv_status.vl_bypass_post_process;
186 bool po_def = s5ptv_status.vl_poly_filter_default;
187 bool bright = s5ptv_status.us_vl_brightness;
188 bool w_blend = param.win_blending;
189 bool csc_en = s5ptv_status.vl_csc_control.csc_en;
190 bool s_off_en = s5ptv_status.vl_csc_control.sub_y_offset_en;
191 bool csc_coef_def = s5ptv_status.vl_csc_coef_default;
192
193 enum s5p_vp_field f_id = s5ptv_status.field_id;
194 enum s5p_vp_mem_mode m_mode = s5ptv_status.vl_op_mode.mem_mode;
195 enum s5p_vp_chroma_expansion cro_ex
196 = s5ptv_status.vl_op_mode.chroma_exp;
197 enum s5p_vp_filed_id_toggle f_id_tog
198 = s5ptv_status.vl_op_mode.toggle_id;
199 enum s5p_vp_pxl_rate p_rate = s5ptv_status.vl_rate;
200 enum s5p_vp_sharpness_control sharp
201 = s5ptv_status.vl_sharpness.sharpness;
202 enum s5p_vp_csc_type csc_type = s5ptv_status.vl_csc_type;
203
204 tv_vp_sw_reset();
205 tv_vp_init_field_id(f_id);
206 tv_vp_init_op_mode(l_skip, m_mode, cro_ex, f_id_tog);
207 tv_vp_init_pixel_rate_control(p_rate);
208
209 temp_addr.y_address = param.top_y_address;
210 temp_addr.c_address = param.top_c_address;
211 img_size.img_width = param.src_width;
212 img_size.img_height = param.src_height;
213
214 tv_vlayer_set_top_address((unsigned long)&temp_addr);
215 tv_vlayer_set_img_size((unsigned long)&img_size);
216 tv_vlayer_set_src_size((unsigned long)&img_size);
217
218 if (po_def)
219 verr = tv_vp_init_layer_def_poly_filter_coef(ty_addr,
220 tc_addr, by_addr, bc_addr, endian,
221 i_w, i_h, s_ox, s_xf, s_oy, s_w, s_h,
222 d_ox, d_oy, d_w, d_h, ipc);
223 else
224 verr = tv_vp_init_layer(ty_addr, tc_addr, by_addr,
225 bc_addr, endian, i_w, i_h, s_ox, s_xf,
226 s_oy, s_w, s_h, d_ox, d_oy, d_w, d_h, ipc);
227
228 if (verr != VPROC_NO_ERROR)
229 return false;
230
231 tv_vp_init_bypass_post_process(bypass);
232 tv_vp_init_sharpness(noise, sharp);
233 tv_vp_init_saturation(saturation);
234 tv_vp_init_brightness(bright);
235 tv_vp_init_contrast(contrast);
236
237 for (i = VProc_LINE_EQ_0; i <= VProc_LINE_EQ_7; i++) {
238 if (s5ptv_status.vl_bc_control[i].eq_num == i)
239 verr = tv_vp_init_brightness_contrast_control(
240 s5ptv_status.vl_bc_control[i].eq_num,
241 s5ptv_status.vl_bc_control[i].intc,
242 s5ptv_status.vl_bc_control[i].slope);
243
244 if (verr != VPROC_NO_ERROR)
245 return false;
246 }
247
248 tv_vp_init_brightness_offset(br_offset);
249
250 tv_vp_init_csc_control(s_off_en, csc_en);
251
252 if (csc_en && csc_coef_def) {
253 verr = tv_vp_init_csc_coef_default(csc_type);
254
255 if (verr != VPROC_NO_ERROR)
256 return false;
257 }
258
259 verr = tv_vp_start();
260
261 if (verr != VPROC_NO_ERROR)
262 return false;
263
264 merr = tv_vm_init_layer(s5ptv_status.tvout_param.disp_mode,
265 VM_VIDEO_LAYER, true,
266 w_blend, alpha, priority,
267 VM_DIRECT_RGB565, false, false, false,
268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
269 if (merr != VPROC_NO_ERROR)
270 return false;
271
272 tv_vm_start();
273
274 s5ptv_status.vp_layer_enable = true;
275
276 return true;
277 }
278
279 bool tv_vlayer_stop(void)
280 {
281 enum s5p_tv_vp_err verr;
282
283 tv_vm_set_layer_show(VM_VIDEO_LAYER, false);
284
285 if (tv_vlayer_wait_previous_update())
286 return false;
287
288 verr = tv_vp_stop();
289
290 if (verr != VPROC_NO_ERROR)
291 return false;
292
293 s5ptv_status.vp_layer_enable = false;
294
295 return true;
296 }
297
298
299 bool tv_vlayer_set_priority(unsigned long buf_in)
300 {
301 enum s5p_tv_vmx_err merr;
302 u32 pri;
303
304 s5ptv_status.vl_basic_param.priority = (unsigned int)(buf_in);
305
306 pri = s5ptv_status.vl_basic_param.priority;
307
308 merr = tv_vm_set_layer_priority(VM_VIDEO_LAYER, pri);
309
310 if (merr != VMIXER_NO_ERROR)
311 return false;
312
313 return true;
314 }
315
316 bool tv_vlayer_set_blending(unsigned long buf_in)
317 {
318 enum s5p_tv_vmx_err merr;
319 bool blend;
320
321 s5ptv_status.vl_basic_param.win_blending = (bool)(buf_in);
322 blend = s5ptv_status.vl_basic_param.win_blending;
323
324 merr = tv_vm_set_win_blend(VM_VIDEO_LAYER, blend);
325
326 if (merr != VMIXER_NO_ERROR)
327 return false;
328
329 return true;
330 }
331
332 bool tv_vlayer_set_alpha(unsigned long buf_in)
333 {
334 enum s5p_tv_vmx_err merr;
335 u32 alpha;
336
337 s5ptv_status.vl_basic_param.alpha = (unsigned int)(buf_in);
338 alpha = s5ptv_status.vl_basic_param.alpha;
339
340 merr = tv_vm_set_layer_alpha(VM_VIDEO_LAYER, alpha);
341
342 if (merr != VMIXER_NO_ERROR)
343 return false;
344
345 return true;
346 }
347
348 bool tv_vlayer_set_field_id(unsigned long buf_in)
349 {
350 enum s5p_tv_vp_err verr;
351
352 s5ptv_status.field_id = (enum s5p_vp_field)(buf_in);
353
354 if (tv_vlayer_wait_previous_update())
355 return false;
356
357 tv_vp_set_field_id(s5ptv_status.field_id);
358
359 verr = tv_vp_update();
360
361 if (verr != VPROC_NO_ERROR)
362 return false;
363
364 return true;
365 }
366
367 bool tv_vlayer_set_top_address(unsigned long buf_in)
368 {
369 u32 t_y_addr = 0;
370 u32 t_c_addr = 0;
371 u32 b_y_addr = 0;
372 u32 b_c_addr = 0;
373
374 struct s5p_video_img_address *addr =
375 (struct s5p_video_img_address *)buf_in;
376 enum s5p_tv_vp_err verr;
377
378 s5ptv_status.vl_basic_param.top_y_address = addr->y_address;
379 s5ptv_status.vl_basic_param.top_c_address = addr->c_address;
380
381 tv_vlayer_calc_inner_values();
382
383 t_y_addr = s5ptv_status.vl_top_y_address;
384 t_c_addr = s5ptv_status.vl_top_c_address;
385 b_y_addr = s5ptv_status.vl_bottom_y_address;
386 b_c_addr = s5ptv_status.vl_bottom_c_address;
387
388 if (tv_vlayer_wait_previous_update())
389 return false;
390
391 verr = tv_vp_set_top_field_address(t_y_addr, t_c_addr);
392
393 if (verr != VPROC_NO_ERROR)
394 return false;
395
396 if (check_input_mode(s5ptv_status.src_color) == INTERLACED) {
397 tv_vp_set_field_id(s5ptv_status.field_id);
398 verr = tv_vp_set_bottom_field_address(b_y_addr, b_c_addr);
399
400 if (verr != VPROC_NO_ERROR)
401 return false;
402 }
403
404 verr = tv_vp_update();
405
406 if (verr != VPROC_NO_ERROR)
407 return false;
408
409 return true;
410 }
411
412 bool tv_vlayer_set_bottom_address(unsigned long buf_in)
413 {
414 u32 t_y_addr = 0;
415 u32 t_c_addr = 0;
416 u32 b_y_addr = 0;
417 u32 b_c_addr = 0;
418
419 u32 img_width = s5ptv_status.vl_basic_param.img_width;
420
421 struct s5p_video_img_address *addr =
422 (struct s5p_video_img_address *)buf_in;
423 enum s5p_tv_vp_err verr;
424 enum s5p_vp_src_color s_color = s5ptv_status.src_color;
425
426 if (s_color == VPROC_SRC_COLOR_NV12IW) {
427 s5ptv_status.vl_basic_param.top_y_address =
428 addr->y_address - img_width;
429 s5ptv_status.vl_basic_param.top_c_address =
430 addr->c_address - img_width;
431 }
432
433 tv_vlayer_calc_inner_values();
434
435 t_y_addr = s5ptv_status.vl_top_y_address;
436 t_c_addr = s5ptv_status.vl_top_c_address;
437 b_y_addr = s5ptv_status.vl_bottom_y_address;
438 b_c_addr = s5ptv_status.vl_bottom_c_address;
439
440 if (tv_vlayer_wait_previous_update())
441 return false;
442
443 verr = tv_vp_set_bottom_field_address(b_y_addr, b_c_addr);
444
445 if (verr != VPROC_NO_ERROR)
446 return false;
447
448 if (s5ptv_status.src_color == VPROC_SRC_COLOR_NV12IW) {
449 verr = tv_vp_set_top_field_address(t_y_addr, t_c_addr);
450
451 if (verr != VPROC_NO_ERROR)
452 return false;
453 }
454
455 verr = tv_vp_update();
456
457 if (verr != VPROC_NO_ERROR)
458 return false;
459
460 return true;
461 }
462
463 bool tv_vlayer_set_img_size(unsigned long buf_in)
464 {
465 struct s5p_img_size *size = (struct s5p_img_size *)buf_in;
466 enum s5p_tv_vp_err verr;
467
468 s5ptv_status.vl_basic_param.img_width = size->img_width;
469 s5ptv_status.vl_basic_param.img_height = size->img_height;
470
471 if (tv_vlayer_wait_previous_update())
472 return false;
473
474 verr = tv_vp_set_img_size(size->img_width, size->img_height);
475
476 if (verr != VPROC_NO_ERROR)
477 return false;
478
479 verr = tv_vp_update();
480
481 if (verr != VPROC_NO_ERROR)
482 return false;
483
484 VLAYERPRINTK("()\n\r");
485
486 return true;
487 }
488
489 bool tv_vlayer_set_src_position(unsigned long buf_in)
490 {
491 struct s5p_img_offset *offset = (struct s5p_img_offset *)buf_in;
492 enum s5p_tv_vp_err verr;
493
494 s5ptv_status.vl_basic_param.src_offset_x = offset->offset_x;
495 s5ptv_status.vl_basic_param.src_offset_y = offset->offset_y;
496 tv_vlayer_calc_inner_values();
497
498 if (tv_vlayer_wait_previous_update())
499 return false;
500
501 tv_vp_set_src_position(s5ptv_status.vl_src_offset_x,
502 s5ptv_status.vl_src_x_fact_step,
503 s5ptv_status.vl_src_offset_y);
504
505 verr = tv_vp_update();
506
507 if (verr != VPROC_NO_ERROR)
508 return false;
509
510 return true;
511 }
512
513 bool tv_vlayer_set_dest_position(unsigned long buf_in)
514 {
515 u32 d_ox = 0;
516 u32 d_oy = 0;
517 struct s5p_img_offset *offset = (struct s5p_img_offset *)buf_in;
518 enum s5p_tv_vp_err verr;
519
520 s5ptv_status.vl_basic_param.dest_offset_x = offset->offset_x;
521 s5ptv_status.vl_basic_param.dest_offset_y = offset->offset_y;
522 tv_vlayer_calc_inner_values();
523
524 d_ox = s5ptv_status.vl_dest_offset_x;
525 d_oy = s5ptv_status.vl_dest_offset_y;
526
527 if (tv_vlayer_wait_previous_update())
528 return false;
529
530 tv_vp_set_dest_position(d_ox, d_oy);
531
532 verr = tv_vp_update();
533
534 if (verr != VPROC_NO_ERROR)
535 return false;
536
537 return true;
538 }
539
540 bool tv_vlayer_set_src_size(unsigned long buf_in)
541 {
542 u32 s_w = 0;
543 u32 s_h = 0;
544 u32 d_w = 0;
545 u32 d_h = 0;
546 bool ipc = false;
547
548 struct s5p_img_size *size = (struct s5p_img_size *)buf_in;
549 enum s5p_tv_vp_err verr;
550
551 s5ptv_status.vl_basic_param.src_width = size->img_width;
552 s5ptv_status.vl_basic_param.src_height = size->img_height;
553 tv_vlayer_calc_inner_values();
554
555 s_w = s5ptv_status.vl_src_width;
556 s_h = s5ptv_status.vl_src_height;
557 d_w = s5ptv_status.vl_dest_width;
558 d_h = s5ptv_status.vl_dest_height;
559 ipc = s5ptv_status.vl2d_ipc;
560
561 if (tv_vlayer_wait_previous_update())
562 return false;
563
564 tv_vp_set_src_dest_size(s_w, s_h, d_w, d_h, ipc);
565
566 verr = tv_vp_update();
567
568 if (verr != VPROC_NO_ERROR)
569 return false;
570
571 return true;
572 }
573
574 bool tv_vlayer_set_dest_size(unsigned long buf_in)
575 {
576 u32 s_w = 0;
577 u32 s_h = 0;
578 u32 d_w = 0;
579 u32 d_h = 0;
580 bool ipc = false;
581
582 struct s5p_img_size *size = (struct s5p_img_size *)buf_in;
583 enum s5p_tv_vp_err verr;
584
585 s5ptv_status.vl_basic_param.dest_width = size->img_width;
586 s5ptv_status.vl_basic_param.dest_height = size->img_height;
587 tv_vlayer_calc_inner_values();
588
589 s_w = s5ptv_status.vl_src_width;
590 s_h = s5ptv_status.vl_src_height;
591 d_w = s5ptv_status.vl_dest_width;
592 d_h = s5ptv_status.vl_dest_height;
593 ipc = s5ptv_status.vl2d_ipc;
594
595 if (tv_vlayer_wait_previous_update())
596 return false;
597
598 tv_vp_set_src_dest_size(s_w, s_h, d_w, d_h, ipc);
599
600 verr = tv_vp_update();
601
602 if (verr != VPROC_NO_ERROR)
603 return false;
604
605 return true;
606 }
607
608 bool tv_vlayer_set_brightness(unsigned long buf_in)
609 {
610 enum s5p_tv_vp_err verr;
611
612 s5ptv_status.us_vl_brightness = (unsigned short)buf_in;
613
614 if (tv_vlayer_wait_previous_update())
615 return false;
616
617 tv_vp_set_brightness(s5ptv_status.us_vl_brightness);
618
619
620 verr = tv_vp_update();
621
622 if (verr != VPROC_NO_ERROR)
623 return false;
624
625 return true;
626 }
627
628 bool tv_vlayer_set_contrast(unsigned long buf_in)
629 {
630 enum s5p_tv_vp_err verr;
631
632 s5ptv_status.vl_contrast = (unsigned char)buf_in;
633
634 if (tv_vlayer_wait_previous_update())
635 return false;
636
637 tv_vp_set_contrast(s5ptv_status.vl_contrast);
638
639 verr = tv_vp_update();
640
641 if (verr != VPROC_NO_ERROR)
642 return false;
643
644 return true;
645 }
646
647 void tv_vlayer_get_priority(unsigned long buf_out)
648 {
649 unsigned int *id = (unsigned int *)buf_out;
650
651 *id = s5ptv_status.vl_basic_param.priority;
652 }
653
654 bool tv_vlayer_set_brightness_contrast_control(unsigned long buf_in)
655 {
656 u32 intc;
657 u32 slope;
658
659 enum s5p_vp_line_eq eq_num;
660 enum s5p_tv_vp_err verr;
661 struct s5p_vl_bright_contrast_ctrl *ctrl =
662 (struct s5p_vl_bright_contrast_ctrl *)buf_in;
663
664 if (ctrl->eq_num > VProc_LINE_EQ_7 ||
665 ctrl->eq_num < VProc_LINE_EQ_0) {
666 VLAYERPRINTK("(ERR) : invalid eq_num(%d)\n\r", ctrl->eq_num);
667 return false;
668 }
669
670 memcpy((void *)&(s5ptv_status.vl_bc_control[ctrl->eq_num]),
671 (const void *)ctrl, sizeof(struct s5p_vl_csc_ctrl));
672
673 eq_num = s5ptv_status.vl_bc_control[ctrl->eq_num].eq_num;
674 intc = s5ptv_status.vl_bc_control[ctrl->eq_num].intc;
675 slope = s5ptv_status.vl_bc_control[ctrl->eq_num].slope;
676
677 if (tv_vlayer_wait_previous_update())
678 return false;
679
680 verr = tv_vp_set_brightness_contrast_control(eq_num, intc, slope);
681
682 if (verr != VPROC_NO_ERROR)
683 return false;
684
685 verr = tv_vp_update();
686
687 if (verr != VPROC_NO_ERROR)
688 return false;
689
690 return true;
691 }
692
693 bool tv_vlayer_set_poly_filter_coef(unsigned long buf_in)
694 {
695 struct s5p_video_poly_filter_coef *coef =
696 (struct s5p_video_poly_filter_coef *)buf_in;
697 enum s5p_tv_vp_err verr;
698
699 if (coef->poly_coeff < VPROC_POLY8_Y0_LL ||
700 (coef->poly_coeff > VPROC_POLY8_Y3_HH &&
701 coef->poly_coeff < VPROC_POLY4_Y0_LL) ||
702 coef->poly_coeff > VPROC_POLY4_C1_HH) {
703 VLAYERPRINTK("(ERR) : invalid poly_coeff(%d)\n\r",
704 coef->poly_coeff);
705 return false;
706 }
707
708 if (tv_vlayer_wait_previous_update())
709 return false;
710
711 verr = tv_vp_init_poly_filter_coef(coef->poly_coeff,
712 coef->ch0, coef->ch1,
713 coef->ch2, coef->ch3);
714
715 if (verr != VPROC_NO_ERROR)
716 return false;
717
718 verr = tv_vp_update();
719
720 if (verr != VPROC_NO_ERROR)
721 return false;
722
723 s5ptv_status.vl_poly_filter_default = false;
724
725 return true;
726 }
727
728 bool tv_vlayer_set_csc_coef(unsigned long buf_in)
729 {
730 struct s5p_video_csc_coef *coef = (struct s5p_video_csc_coef *)buf_in;
731 enum s5p_tv_vp_err verr;
732
733 if (coef->csc_coeff < VPROC_CSC_Y2Y_COEF ||
734 coef->csc_coeff > VPROC_CSC_CR2CR_COEF) {
735 VLAYERPRINTK("(ERR) : invalid csc_coeff(%d)\n\r",
736 coef->csc_coeff);
737 return false;
738 }
739
740 if (tv_vlayer_wait_previous_update())
741 return false;
742
743 verr = tv_vp_init_csc_coef(coef->csc_coeff, coef->coeff);
744
745 if (verr != VPROC_NO_ERROR)
746 return false;
747
748 verr = tv_vp_update();
749
750 if (verr != VPROC_NO_ERROR)
751 return false;
752
753 s5ptv_status.vl_csc_coef_default = false;
754
755 return true;
756 }
757
758 bool tv_vlayer_init_param(unsigned long buf_in)
759 {
760 struct s5p_tv_status *st = &s5ptv_status;
761
762 bool i_mode, o_mode; /* 0 for interlaced, 1 for progressive */
763
764 switch (st->tvout_param.disp_mode) {
765
766 case TVOUT_480P_60_16_9:
767 case TVOUT_480P_60_4_3:
768 case TVOUT_576P_50_16_9:
769 case TVOUT_576P_50_4_3:
770 case TVOUT_480P_59:
771 st->vl_csc_type = VPROC_CSC_SD_HD;
772 break;
773
774 case TVOUT_1080I_50:
775 case TVOUT_1080I_60:
776 case TVOUT_1080P_50:
777 case TVOUT_1080P_30:
778 case TVOUT_1080P_60:
779 case TVOUT_720P_59:
780 case TVOUT_1080I_59:
781 case TVOUT_1080P_59:
782 case TVOUT_720P_50:
783 case TVOUT_720P_60:
784 st->vl_csc_type = VPROC_CSC_HD_SD;
785 break;
786
787 default:
788 break;
789 }
790
791 st->vl_csc_control.csc_en = false;
792
793
794 i_mode = check_input_mode(st->src_color);
795 o_mode = check_output_mode(st->tvout_param.disp_mode,
796 st->tvout_param.out_mode);
797
798 /* check o_mode */
799 if (i_mode == INTERLACED) {
800 /* i to i : line skip 1, ipc 0, auto toggle 0 */
801 if (o_mode == INTERLACED) {
802 st->vl_op_mode.line_skip = true;
803 st->vl2d_ipc = false;
804 st->vl_op_mode.toggle_id = false;
805 } else {
806 /* i to p : line skip 1, ipc 1, auto toggle 0 */
807 st->vl_op_mode.line_skip = true;
808 st->vl2d_ipc = true;
809 st->vl_op_mode.toggle_id = false;
810 }
811 } else {
812 /* p to i : line skip 1, ipc 0, auto toggle 0 */
813 if (o_mode == INTERLACED) {
814 st->vl_op_mode.line_skip = true;
815 st->vl2d_ipc = false;
816 st->vl_op_mode.toggle_id = false;
817 } else {
818 /* p to p : line skip 0, ipc 0, auto toggle 0 */
819 st->vl_op_mode.line_skip = false;
820 st->vl2d_ipc = false;
821 st->vl_op_mode.toggle_id = false;
822 }
823 }
824
825 st->vl_op_mode.mem_mode = ((st->src_color == VPROC_SRC_COLOR_NV12) ||
826 st->src_color == VPROC_SRC_COLOR_NV12IW) ?
827 VPROC_LINEAR_MODE : VPROC_2D_TILE_MODE;
828
829 st->vl_op_mode.chroma_exp = 0; /* use only top y addr */
830
831 tv_vlayer_calc_inner_values();
832
833 if (st->vl_mode) {
834 VLAYERPRINTK("(ERR) : Default values are already updated\n\r");
835 return true;
836 }
837
838 /* Initialize Video Layer Parameters to Default Values */
839 st->vl_src_x_fact_step = 0;
840 st->field_id = VPROC_TOP_FIELD;
841 st->vl_rate = VPROC_PIXEL_PER_RATE_1_1;
842 st->vl_poly_filter_default = true;
843 st->vl_bypass_post_process = false;
844 st->vl_saturation = 0x80;
845 st->vl_sharpness.th_noise = 0;
846 st->vl_sharpness.sharpness = VPROC_SHARPNESS_NO;
847 st->us_vl_brightness = 0x00;
848 st->vl_contrast = 0x80;
849 st->vl_bright_offset = 0x00;
850 st->vl_csc_control.sub_y_offset_en = false;
851 st->vl_csc_coef_default = true;
852 st->vl_bc_control[0].eq_num = VProc_LINE_EQ_7 + 1;
853 st->vl_bc_control[1].eq_num = VProc_LINE_EQ_7 + 1;
854 st->vl_bc_control[2].eq_num = VProc_LINE_EQ_7 + 1;
855 st->vl_bc_control[3].eq_num = VProc_LINE_EQ_7 + 1;
856 st->vl_bc_control[4].eq_num = VProc_LINE_EQ_7 + 1;
857 st->vl_bc_control[5].eq_num = VProc_LINE_EQ_7 + 1;
858 st->vl_bc_control[6].eq_num = VProc_LINE_EQ_7 + 1;
859 st->vl_bc_control[7].eq_num = VProc_LINE_EQ_7 + 1;
860 st->vl_mode = true;
861
862 return true;
863 }
864
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/s5p_stda_tvout_if.c ('k') | drivers/media/video/samsung/tv20/s5p_tv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698