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

Side by Side Diff: drivers/media/video/samsung/tv20/s5p_tv_v4l2.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_tv_v4l2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - Video4Linux API 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/string.h>
17 #include <linux/version.h>
18
19 #include <media/v4l2-common.h>
20 #include <media/v4l2-ioctl.h>
21
22 #include <linux/io.h>
23 #include <linux/uaccess.h>
24
25 #include "s5p_tv.h"
26
27 #ifdef CONFIG_TVOUT_DBG
28 #define S5P_V4L2_DEBUG 1
29 #endif
30
31 #ifdef S5P_V4L2_DEBUG
32 #define V4L2PRINTK(fmt, args...) \
33 printk(KERN_INFO "[V4L2_IF] %s: " fmt, __func__ , ## args)
34 #else
35 #define V4L2PRINTK(fmt, args...)
36 #endif
37
38 u8 hdcp_protocol_status;
39 /* 0 - hdcp stopped, 1 - hdcp started, 2 - hdcp reset */
40
41 #define CVBS_S_VIDEO (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP|\
42 V4L2_STD_PAL|V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|\
43 V4L2_STD_PAL_60|V4L2_STD_NTSC_443)
44
45 struct v4l2_output s5p_tv_outputs[] = {
46 {
47 .index = 0,
48 .name = "Analog COMPOSITE",
49 .type = V4L2_OUTPUT_TYPE_COMPOSITE,
50 .audioset = 0,
51 .modulator = 0,
52 .std = CVBS_S_VIDEO,
53 }, {
54 .index = 1,
55 .name = "Analog SVIDEO",
56 .type = V4L2_OUTPUT_TYPE_SVIDEO,
57 .audioset = 0,
58 .modulator = 0,
59 .std = CVBS_S_VIDEO,
60 }, {
61 .index = 2,
62 .name = "Analog COMPONENT_YPBPR_I",
63 .type = V4L2_OUTPUT_TYPE_YPBPR_INERLACED,
64 .audioset = 0,
65 .modulator = 0,
66 .std = V4L2_STD_ALL,
67 }, {
68 .index = 3,
69 .name = "Analog COMPONENT_YPBPR_P",
70 .type = V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE,
71 .audioset = 0,
72 .modulator = 0,
73 .std = V4L2_STD_ALL,
74 }, {
75 .index = 4,
76 .name = "Analog COMPONENT_RGB_P",
77 .type = V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE,
78 .audioset = 0,
79 .modulator = 0,
80 .std = V4L2_STD_ALL,
81 }, {
82 .index = 5,
83 .name = "Digital HDMI(YCbCr)",
84 .type = V4L2_OUTPUT_TYPE_HDMI,
85 .audioset = 2,
86 .modulator = 0,
87 .std =
88 V4L2_STD_480P_60_16_9 | V4L2_STD_480P_60_16_9 |
89 V4L2_STD_720P_60 | V4L2_STD_720P_50
90 | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 |
91 V4L2_STD_1080I_60 | V4L2_STD_1080I_50 |
92 V4L2_STD_480P_59 | V4L2_STD_720P_59 |
93 V4L2_STD_1080I_59 | V4L2_STD_1080P_59 |
94 V4L2_STD_1080P_30,
95 }, {
96 .index = 6,
97 .name = "Digital HDMI(RGB)",
98 .type = V4L2_OUTPUT_TYPE_HDMI_RGB,
99 .audioset = 2,
100 .modulator = 0,
101 .std = V4L2_STD_480P_60_16_9 |
102 V4L2_STD_480P_60_16_9 |
103 V4L2_STD_720P_60 | V4L2_STD_720P_50
104 | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 |
105 V4L2_STD_1080I_60 | V4L2_STD_1080I_50 |
106 V4L2_STD_480P_59 | V4L2_STD_720P_59 |
107 V4L2_STD_1080I_59 | V4L2_STD_1080P_59 |
108 V4L2_STD_1080P_30,
109 }, {
110 .index = 7,
111 .name = "Digital DVI",
112 .type = V4L2_OUTPUT_TYPE_DVI,
113 .audioset = 2,
114 .modulator = 0,
115 .std =
116 V4L2_STD_480P_60_16_9 | V4L2_STD_480P_60_16_9 |
117 V4L2_STD_720P_60 | V4L2_STD_720P_50
118 | V4L2_STD_1080P_60 | V4L2_STD_1080P_50 |
119 V4L2_STD_1080I_60 | V4L2_STD_1080I_50 |
120 V4L2_STD_480P_59 | V4L2_STD_720P_59 |
121 V4L2_STD_1080I_59 | V4L2_STD_1080P_59 |
122 V4L2_STD_1080P_30,
123 }
124
125 };
126
127 const struct v4l2_fmtdesc s5p_tv_o_fmt_desc[] = {
128 {
129 .index = 0,
130 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
131 .description = "YUV420, NV12 (Video Processor)",
132 .pixelformat = V4L2_PIX_FMT_NV12,
133 .flags = FORMAT_FLAGS_CrCb,
134 }
135 };
136
137 const struct v4l2_fmtdesc s5p_tv_o_overlay_fmt_desc[] = {
138 {
139 .index = 0,
140 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
141 .description = "16bpp RGB, le - RGB[565]",
142 .pixelformat = V4L2_PIX_FMT_RGB565,
143 .flags = FORMAT_FLAGS_PACKED,
144 }, {
145 .index = 1,
146 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
147 .description = "16bpp RGB, le - ARGB[1555]",
148 .pixelformat = V4L2_PIX_FMT_RGB555,
149 .flags = FORMAT_FLAGS_PACKED,
150 }, {
151 .index = 2,
152 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
153 .description = "16bpp RGB, le - ARGB[4444]",
154 .pixelformat = V4L2_PIX_FMT_RGB444,
155 .flags = FORMAT_FLAGS_PACKED,
156 }, {
157 .index = 3,
158 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
159 .description = "32bpp RGB, le - ARGB[8888]",
160 .pixelformat = V4L2_PIX_FMT_RGB32,
161 .flags = FORMAT_FLAGS_PACKED,
162 }
163 };
164
165 const struct v4l2_standard s5p_tv_standards[] = {
166 {
167 .index = 0,
168 .id = V4L2_STD_NTSC_M,
169 .name = "NTSC_M",
170 }, {
171
172 .index = 1,
173 .id = V4L2_STD_PAL_BDGHI,
174 .name = "PAL_BDGHI",
175 }, {
176 .index = 2,
177 .id = V4L2_STD_PAL_M,
178 .name = "PAL_M",
179 }, {
180 .index = 3,
181 .id = V4L2_STD_PAL_N,
182 .name = "PAL_N",
183 }, {
184 .index = 4,
185 .id = V4L2_STD_PAL_Nc,
186 .name = "PAL_Nc",
187 }, {
188 .index = 5,
189 .id = V4L2_STD_PAL_60,
190 .name = "PAL_60",
191 }, {
192 .index = 6,
193 .id = V4L2_STD_NTSC_443,
194 .name = "NTSC_443",
195 }, {
196 .index = 7,
197 .id = V4L2_STD_480P_60_16_9,
198 .name = "480P_60_16_9",
199 }, {
200 .index = 8,
201 .id = V4L2_STD_480P_60_4_3,
202 .name = "480P_60_4_3",
203 }, {
204 .index = 9,
205 .id = V4L2_STD_576P_50_16_9,
206 .name = "576P_50_16_9",
207 }, {
208 .index = 10,
209 .id = V4L2_STD_576P_50_4_3,
210 .name = "576P_50_4_3",
211 }, {
212 .index = 11,
213 .id = V4L2_STD_720P_60,
214 .name = "720P_60",
215 }, {
216 .index = 12,
217 .id = V4L2_STD_720P_50,
218 .name = "720P_50",
219 },
220 {
221 .index = 13,
222 .id = V4L2_STD_1080P_60,
223 .name = "1080P_60",
224 }, {
225 .index = 14,
226 .id = V4L2_STD_1080P_50,
227 .name = "1080P_50",
228 }, {
229 .index = 15,
230 .id = V4L2_STD_1080I_60,
231 .name = "1080I_60",
232 }, {
233 .index = 16,
234 .id = V4L2_STD_1080I_50,
235 .name = "1080I_50",
236 }, {
237 .index = 17,
238 .id = V4L2_STD_480P_59,
239 .name = "480P_59",
240 }, {
241 .index = 18,
242 .id = V4L2_STD_720P_59,
243 .name = "720P_59",
244 }, {
245 .index = 19,
246 .id = V4L2_STD_1080I_59,
247 .name = "1080I_59",
248 }, {
249 .index = 20,
250 .id = V4L2_STD_1080P_59,
251 .name = "1080I_50",
252 }, {
253 .index = 21,
254 .id = V4L2_STD_1080P_30,
255 .name = "1080I_30",
256 }
257 };
258
259 /* TODO: set default format for v, vo0/1 */
260
261 const struct v4l2_format s5p_tv_format[] = {
262 {
263 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
264 }, {
265 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
266 }, {
267 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY,
268 },
269 };
270
271 #define S5P_TVOUT_MAX_STANDARDS ARRAY_SIZE(s5p_tv_standards)
272 #define S5P_TVOUT_MAX_O_TYPES ARRAY_SIZE(s5p_tv_outputs)
273 #define S5P_TVOUT_MAX_O_FMT ARRAY_SIZE(s5p_tv_format)
274 #define S5P_TVOUT_MAX_O_FMT_DESC ARRAY_SIZE(s5p_tv_o_fmt_desc)
275 #define S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC \
276 ARRAY_SIZE(s5p_tv_o_overlay_fmt_desc)
277
278
279 void s5p_tv_v4l2_init_param(void)
280 {
281 s5ptv_status.v4l2.output =
282 (struct v4l2_output *)&s5p_tv_outputs[0];
283 s5ptv_status.v4l2.std =
284 (struct v4l2_standard *)&s5p_tv_standards[0];
285 s5ptv_status.v4l2.fmt_v =
286 (struct v4l2_format *)&s5p_tv_o_fmt_desc[0];
287 s5ptv_status.v4l2.fmt_vo_0 =
288 (struct v4l2_format *)&s5p_tv_format[1];
289 s5ptv_status.v4l2.fmt_vo_1 =
290 (struct v4l2_format *)&s5p_tv_format[2];
291 s5ptv_status.hdmi_audio_type = HDMI_AUDIO_PCM;
292 }
293
294 /* VIDIOC_QUERYCAP handler */
295 static int s5p_tv_v4l2_querycap(
296 struct file *file, void *fh, struct v4l2_capability *cap)
297 {
298 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
299 u32 index;
300
301 if (layer == NULL) {
302 index = 0;
303 strcpy(cap->driver, "S3C TV Vid drv");
304 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT;
305 } else {
306 index = layer->index + 1;
307 strcpy(cap->driver, "S3C TV Grp drv");
308 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
309 }
310
311 strlcpy(cap->card,
312 s5ptv_status.video_dev[index]->name, sizeof(cap->card));
313
314 sprintf(cap->bus_info, "ARM AHB BUS");
315 cap->version = KERNEL_VERSION(2, 6, 29);
316
317 return 0;
318 }
319
320
321 /* VIDIOC_ENUM_FMT handlers */
322 static int s5p_tv_v4l2_enum_fmt_vid_out(
323 struct file *file, void *fh, struct v4l2_fmtdesc *f)
324 {
325 int index = f->index;
326
327 V4L2PRINTK("(%d)++\n", f->index);
328
329 if (index >= S5P_TVOUT_MAX_O_FMT_DESC) {
330 V4L2PRINTK("exceeded S5P_TVOUT_MAX_O_FMT_DESC\n");
331 return -EINVAL;
332 }
333
334 memcpy(f, &s5p_tv_o_fmt_desc[index],
335 sizeof(struct v4l2_fmtdesc));
336
337 V4L2PRINTK("()--\n");
338 return 0;
339
340 }
341
342 static int s5p_tv_v4l2_enum_fmt_vid_out_overlay(
343 struct file *file, void *fh, struct v4l2_fmtdesc *f)
344 {
345 int index = f->index;
346
347 V4L2PRINTK("(%d)++\n", f->index);
348
349 if (index >= S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC) {
350 V4L2PRINTK("exceeded S5P_TVOUT_MAX_O_OVERLAY_FMT_DESC\n");
351 return -EINVAL;
352 }
353
354 memcpy(f, &s5p_tv_o_overlay_fmt_desc[index],
355 sizeof(struct v4l2_fmtdesc));
356
357 V4L2PRINTK("()--\n");
358
359 return 0;
360 }
361
362
363 /* VIDIOC_G_FMT handlers */
364 static int s5p_tv_v4l2_g_fmt_vid_out(
365 struct file *file, void *fh, struct v4l2_format *f)
366 {
367
368 struct v4l2_format *vid_out_fmt = f;
369
370 V4L2PRINTK("(0x%08x)++\n", f->type);
371
372 switch (vid_out_fmt->type) {
373
374 case V4L2_BUF_TYPE_VIDEO_OUTPUT: {
375
376 struct v4l2_pix_format_s5p_tvout vparam;
377 memset(&vparam, 0, sizeof(struct v4l2_pix_format_s5p_tvout));
378
379 vparam.base_y =
380 (void *)s5ptv_status.vl_basic_param.top_y_address;
381 vparam.base_c =
382 (void *)s5ptv_status.vl_basic_param.top_c_address;
383 vparam.pix_fmt.pixelformat =
384 s5ptv_status.src_color; /* VPROC_SRC_COLOR_NV12 */
385 vparam.pix_fmt.width =
386 s5ptv_status.vl_basic_param.src_width;
387 vparam.pix_fmt.height =
388 s5ptv_status.vl_basic_param.src_height;
389 V4L2PRINTK(
390 "[type0x%08x]:addr_y:[0x%08x],addr_c[0x%08x],w[%d],h[%d]\n",
391 f->type,
392 s5ptv_status.vl_basic_param.top_y_address,
393 s5ptv_status.vl_basic_param.top_c_address,
394 s5ptv_status.vl_basic_param.src_width,
395 s5ptv_status.vl_basic_param.src_height);
396 memcpy(vid_out_fmt->fmt.raw_data, &vparam,
397 sizeof(struct v4l2_pix_format_s5p_tvout));
398 break;
399 }
400
401 default:
402 break;
403 }
404
405 return 0;
406 }
407
408 static int s5p_tv_v4l2_g_fmt_vid_out_overlay(
409 struct file *file, void *fh, struct v4l2_format *f)
410 {
411
412 struct v4l2_format *vid_out_fmt = f;
413
414 V4L2PRINTK("(0x%08x)++\n", f->type);
415
416 switch (vid_out_fmt->type) {
417
418 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
419
420 struct v4l2_window_s5p_tvout vparam;
421 memset(&vparam, 0, sizeof(struct v4l2_window_s5p_tvout));
422
423 if (s5ptv_status.vl_basic_param.win_blending) {
424 vparam.flags = V4L2_FBUF_FLAG_CHROMAKEY;
425 vparam.capability = V4L2_FBUF_CAP_CHROMAKEY;
426 }
427
428 if (s5ptv_status.vl_basic_param.alpha) {
429 vparam.flags = V4L2_FBUF_FLAG_LOCAL_ALPHA;
430 vparam.capability = V4L2_FBUF_CAP_LOCAL_ALPHA;
431 }
432
433 vparam.priority =
434 s5ptv_status.vl_basic_param.priority;
435
436 vparam.win.w.left =
437 s5ptv_status.vl_basic_param.src_offset_x;
438 vparam.win.w.top =
439 s5ptv_status.vl_basic_param.src_offset_y;
440 vparam.win.w.width =
441 s5ptv_status.vl_basic_param.src_width;
442 vparam.win.w.height =
443 s5ptv_status.vl_basic_param.src_height;
444 V4L2PRINTK(
445 "[type 0x%08x] : left:[%d],top[%d],width[%d],height[%d]\n",
446 f->type,
447 s5ptv_status.vl_basic_param.src_offset_x,
448 s5ptv_status.vl_basic_param.src_offset_y,
449 s5ptv_status.vl_basic_param.src_width,
450 s5ptv_status.vl_basic_param.src_height);
451 memcpy(vid_out_fmt->fmt.raw_data,
452 &vparam, sizeof(struct v4l2_window_s5p_tvout));
453 break;
454 }
455
456 default:
457 break;
458 }
459
460 V4L2PRINTK("()--\n");
461
462 return 0;
463 }
464
465 /* VIDIOC_S_FMT handlers */
466 static int s5p_tv_v4l2_s_fmt_vid_out(
467 struct file *file, void *fh, struct v4l2_format *f)
468 {
469
470 struct v4l2_format *vid_out_fmt = f;
471
472 V4L2PRINTK("(0x%08x)++\n", f->type);
473
474 switch (vid_out_fmt->type) {
475
476 case V4L2_BUF_TYPE_VIDEO_OUTPUT: {
477
478 struct v4l2_pix_format_s5p_tvout vparam;
479 memcpy(&vparam, vid_out_fmt->fmt.raw_data,
480 sizeof(struct v4l2_pix_format_s5p_tvout));
481
482 s5ptv_status.vl_basic_param.src_width =
483 vparam.pix_fmt.width;
484 s5ptv_status.vl_basic_param.src_height =
485 vparam.pix_fmt.height;
486 s5ptv_status.src_color = vparam.pix_fmt.pixelformat;
487
488 s5ptv_status.vl_basic_param.top_y_address =
489 (unsigned int)vparam.base_y;
490 s5ptv_status.vl_basic_param.top_c_address =
491 (unsigned int)vparam.base_c;
492
493 /* check progressive or not */
494 if (vparam.pix_fmt.field == V4L2_FIELD_NONE) {
495
496 /* progressive */
497
498 switch (vparam.pix_fmt.pixelformat) {
499
500 case V4L2_PIX_FMT_NV12:
501 /* linear */
502 s5ptv_status.src_color =
503 VPROC_SRC_COLOR_NV12;
504 break;
505 case V4L2_PIX_FMT_NV12T:
506 /* tiled */
507 s5ptv_status.src_color =
508 VPROC_SRC_COLOR_TILE_NV12;
509 break;
510 default:
511 V4L2PRINTK("src img format not supported\n");
512 break;
513 }
514
515 s5ptv_status.field_id = VPROC_TOP_FIELD;
516
517 if (s5ptv_status.vp_layer_enable) {
518 struct s5p_video_img_address temp_addr;
519 struct s5p_img_size img_size;
520
521 temp_addr.y_address =
522 (unsigned int)vparam.base_y;
523 temp_addr.c_address =
524 (unsigned int)vparam.base_c;
525 img_size.img_width =
526 (unsigned int)vparam.pix_fmt.width;
527 img_size.img_height =
528 (unsigned int)vparam.pix_fmt.height;
529
530 tv_vlayer_set_top_address(
531 (unsigned long)&temp_addr);
532 tv_vlayer_set_img_size(
533 (unsigned long)&img_size);
534 tv_vlayer_set_src_size(
535 (unsigned long)&img_size);
536
537 }
538 } else if (vparam.pix_fmt.field == V4L2_FIELD_INTERLACED_TB) {
539
540 /* interlaced */
541
542 switch (vparam.pix_fmt.pixelformat) {
543
544 case V4L2_PIX_FMT_NV12:
545 /* linear */
546 s5ptv_status.src_color = VPROC_SRC_COLOR_NV12IW;
547 break;
548 case V4L2_PIX_FMT_NV12T:
549 /* tiled */
550 s5ptv_status.src_color =
551 VPROC_SRC_COLOR_TILE_NV12IW;
552 break;
553 default:
554 V4L2PRINTK("src img format not supported\n");
555 break;
556 }
557
558 if (vparam.pix_fmt.priv == V4L2_FIELD_BOTTOM)
559 s5ptv_status.field_id = VPROC_BOTTOM_FIELD;
560 else
561 s5ptv_status.field_id = VPROC_TOP_FIELD;
562
563 if (s5ptv_status.vp_layer_enable) {
564 struct s5p_video_img_address temp_addr;
565 struct s5p_img_size img_size;
566
567 temp_addr.y_address =
568 (unsigned int)vparam.base_y;
569 temp_addr.c_address =
570 (unsigned int)vparam.base_c;
571 img_size.img_width =
572 (unsigned int)vparam.pix_fmt.width;
573 img_size.img_height =
574 (unsigned int)vparam.pix_fmt.height;
575
576 tv_vlayer_set_top_address(
577 (unsigned long)&temp_addr);
578 tv_vlayer_set_img_size(
579 (unsigned long)&img_size);
580 tv_vlayer_set_src_size(
581 (unsigned long)&img_size);
582
583 }
584
585 } else {
586 V4L2PRINTK("this field id not supported\n");
587 }
588 break;
589 }
590
591 default:
592 break;
593 }
594
595 V4L2PRINTK(
596 "[type 0x%08x] : addr_y:[0x%08x],addr_c[0x%08x],width[%d],height[%d]\n",
597 f->type,
598 s5ptv_status.vl_basic_param.top_y_address,
599 s5ptv_status.vl_basic_param.top_c_address,
600 s5ptv_status.vl_basic_param.src_width,
601 s5ptv_status.vl_basic_param.src_height);
602 V4L2PRINTK("()--\n");
603
604 return 0;
605 }
606
607
608 static int s5p_tv_v4l2_s_fmt_vid_out_overlay(
609 struct file *file, void *fh, struct v4l2_format *f)
610 {
611
612 struct v4l2_format *vid_out_fmt = f;
613
614 V4L2PRINTK("(0x%08x)++\n", f->type);
615
616 switch (vid_out_fmt->type) {
617
618 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
619
620 struct v4l2_window_s5p_tvout vparam;
621 memcpy(&vparam, vid_out_fmt->fmt.raw_data,
622 sizeof(struct v4l2_window_s5p_tvout));
623
624 s5ptv_status.vl_basic_param.win_blending =
625 (vparam.flags & V4L2_FBUF_FLAG_CHROMAKEY) ? 1 : 0;
626 s5ptv_status.vl_basic_param.alpha =
627 (vparam.flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) ? 1 : 0;
628 s5ptv_status.vl_basic_param.priority =
629 vparam.priority;
630 s5ptv_status.vl_basic_param.src_offset_x =
631 vparam.win.w.left;
632 s5ptv_status.vl_basic_param.src_offset_y =
633 vparam.win.w.top;
634 s5ptv_status.vl_basic_param.src_width = vparam.win.w.width;
635 s5ptv_status.vl_basic_param.src_height = vparam.win.w.height;
636 V4L2PRINTK(
637 "[type 0x%08x] : left: [%d],top [%d],width[%d],height[%d]\n",
638 f->type,
639 s5ptv_status.vl_basic_param.src_offset_x,
640 s5ptv_status.vl_basic_param.src_offset_y,
641 s5ptv_status.vl_basic_param.src_width,
642 s5ptv_status.vl_basic_param.src_height);
643
644 if (s5ptv_status.vp_layer_enable) {
645 struct s5p_img_offset img_offset;
646 struct s5p_img_size img_size;
647
648 img_offset.offset_x = vparam.win.w.left;
649 img_offset.offset_y = vparam.win.w.top;
650 img_size.img_width = vparam.win.w.width;
651 img_size.img_height = vparam.win.w.height;
652 tv_vlayer_set_blending(
653 s5ptv_status.vl_basic_param.win_blending);
654 tv_vlayer_set_alpha(
655 s5ptv_status.vl_basic_param.alpha);
656 tv_vlayer_set_priority(vparam.priority);
657 tv_vlayer_set_src_position(
658 (unsigned long)&img_offset);
659 tv_vlayer_set_src_size((unsigned long)&img_size);
660 }
661
662 break;
663 }
664
665 default:
666 break;
667 }
668
669 V4L2PRINTK("()--\n");
670
671 return 0;
672 }
673
674 /* start overlay * */
675 static int s5p_tv_v4l2_overlay(struct file *file, void *fh, unsigned int i)
676 {
677 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
678 int start = i;
679 V4L2PRINTK("(0x%08x)++\n", i);
680
681 if (start)
682 tv_grp_start(layer->index);
683 else
684 tv_grp_stop(layer->index);
685
686 return 0;
687 }
688
689 static int s5p_tv_v4l2_g_fbuf(
690 struct file *file, void *fh, struct v4l2_framebuffer *a)
691 {
692
693 struct v4l2_framebuffer *fbuf = a;
694 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
695
696 fbuf->base = (void *)s5ptv_overlay[layer->index].base_addr;
697 fbuf->fmt.pixelformat = s5ptv_overlay[layer->index].fb.fmt.pixelformat;
698
699 return 0;
700 }
701
702 static int s5p_tv_v4l2_s_fbuf(
703 struct file *file, void *fh, struct v4l2_framebuffer *a)
704 {
705
706 struct v4l2_framebuffer *fbuf = a;
707 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
708
709 s5ptv_overlay[layer->index].base_addr = (unsigned int)fbuf->base;
710
711 switch (fbuf->fmt.pixelformat) {
712
713 case V4L2_PIX_FMT_RGB565:
714 s5ptv_overlay[layer->index].fb.fmt.pixelformat =
715 VM_DIRECT_RGB565;
716 break;
717
718 case V4L2_PIX_FMT_RGB555:
719 s5ptv_overlay[layer->index].fb.fmt.pixelformat =
720 VM_DIRECT_RGB1555;
721 break;
722
723 case V4L2_PIX_FMT_RGB444:
724 s5ptv_overlay[layer->index].fb.fmt.pixelformat =
725 VM_DIRECT_RGB4444;
726 break;
727
728 case V4L2_PIX_FMT_RGB32:
729 s5ptv_overlay[layer->index].fb.fmt.pixelformat =
730 VM_DIRECT_RGB8888;
731 break;
732
733 default:
734 break;
735 }
736
737 return 0;
738 }
739
740 /* Stream on/off */
741 static int s5p_tv_v4l2_streamon(
742 struct file *file, void *fh, enum v4l2_buf_type i)
743 {
744 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
745
746 V4L2PRINTK("(0x%08x)++\n", i);
747
748 switch (i) {
749
750 /* Vlayer */
751 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
752 tv_vlayer_init_param(0);
753 tv_vlayer_start();
754 s5ptv_status.vp_layer_enable = true;
755 break;
756
757 /* GRP0/1 */
758 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
759 tv_grp_start(layer->index);
760 break;
761
762 default:
763 break;
764 }
765
766 V4L2PRINTK("()--\n");
767
768 return 0;
769 }
770
771 static int s5p_tv_v4l2_streamoff(
772 struct file *file, void *fh, enum v4l2_buf_type i)
773 {
774 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
775
776 V4L2PRINTK("(0x%08x)++\n", i);
777
778 switch (i) {
779
780 /* Vlayer */
781 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
782 tv_vlayer_stop();
783 break;
784
785 /* GRP0/1 */
786 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
787 tv_grp_stop(layer->index);
788 break;
789
790 default:
791 break;
792 }
793
794 V4L2PRINTK("()--\n");
795
796 return 0;
797 }
798
799 /* Standard handling ENUMSTD is handled by videodev.c */
800 static int s5p_tv_v4l2_g_std(struct file *file, void *fh, v4l2_std_id *norm)
801 {
802 V4L2PRINTK("()++\n");
803
804 *norm = s5ptv_status.v4l2.std->id;
805
806 V4L2PRINTK("(%d)++\n", (int)(*norm));
807
808 return 0;
809 }
810
811 static int s5p_tv_v4l2_s_std(struct file *file, void *fh, v4l2_std_id *norm)
812 {
813 unsigned int i = 0;
814 v4l2_std_id std_id = *norm;
815
816 V4L2PRINTK("(0x%08Lx)++\n", std_id);
817
818 s5ptv_status.v4l2.std = NULL;
819
820 do {
821 if (s5p_tv_standards[i].id == std_id) {
822 s5ptv_status.v4l2.std =
823 (struct v4l2_standard *)&s5p_tv_standards[i];
824 break;
825 }
826
827 i++;
828 } while (i < S5P_TVOUT_MAX_STANDARDS);
829
830 if (i >= S5P_TVOUT_MAX_STANDARDS || s5ptv_status.v4l2.std == NULL) {
831 V4L2PRINTK(
832 "(ERR) There is no tv-out standards : index = 0x%08Lx\n",
833 std_id);
834 return -EINVAL;
835 }
836
837 switch (std_id) {
838
839 case V4L2_STD_NTSC_M:
840 s5ptv_status.tvout_param.disp_mode = TVOUT_NTSC_M;
841 break;
842
843 case V4L2_STD_PAL_BDGHI:
844 s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_BDGHI;
845 break;
846
847 case V4L2_STD_PAL_M:
848 s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_M;
849 break;
850
851 case V4L2_STD_PAL_N:
852 s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_N;
853 break;
854
855 case V4L2_STD_PAL_Nc:
856 s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_NC;
857 break;
858
859 case V4L2_STD_PAL_60:
860 s5ptv_status.tvout_param.disp_mode = TVOUT_PAL_60;
861 break;
862
863 case V4L2_STD_NTSC_443:
864 s5ptv_status.tvout_param.disp_mode = TVOUT_NTSC_443;
865 break;
866
867 case V4L2_STD_480P_60_16_9:
868 s5ptv_status.tvout_param.disp_mode = TVOUT_480P_60_16_9;
869 break;
870
871 case V4L2_STD_480P_60_4_3:
872 s5ptv_status.tvout_param.disp_mode = TVOUT_480P_60_4_3;
873 break;
874
875 case V4L2_STD_480P_59:
876 s5ptv_status.tvout_param.disp_mode = TVOUT_480P_59;
877 break;
878
879 case V4L2_STD_576P_50_16_9:
880 s5ptv_status.tvout_param.disp_mode = TVOUT_576P_50_16_9;
881 break;
882
883 case V4L2_STD_576P_50_4_3:
884 s5ptv_status.tvout_param.disp_mode = TVOUT_576P_50_4_3;
885 break;
886
887 case V4L2_STD_720P_60:
888 s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60;
889 break;
890
891 case V4L2_STD_720P_59:
892 s5ptv_status.tvout_param.disp_mode = TVOUT_720P_59;
893 break;
894
895 case V4L2_STD_720P_50:
896 s5ptv_status.tvout_param.disp_mode = TVOUT_720P_50;
897 break;
898
899 case V4L2_STD_1080I_60:
900 s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_60;
901 break;
902
903 case V4L2_STD_1080I_59:
904 s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_59;
905 break;
906
907 case V4L2_STD_1080I_50:
908 s5ptv_status.tvout_param.disp_mode = TVOUT_1080I_50;
909 break;
910
911 case V4L2_STD_1080P_30:
912 s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_30;
913 break;
914
915 case V4L2_STD_1080P_60:
916 s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_60;
917 break;
918
919 case V4L2_STD_1080P_59:
920 s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_59;
921 break;
922
923 case V4L2_STD_1080P_50:
924 s5ptv_status.tvout_param.disp_mode = TVOUT_1080P_50;
925 break;
926 default:
927 V4L2PRINTK(
928 "(ERR) not supported standard id : index = 0x%08Lx\n",
929 std_id);
930 return -EINVAL;
931 }
932
933 V4L2PRINTK("()--\n");
934
935 return 0;
936 }
937
938 /* Output handling */
939 static int s5p_tv_v4l2_enum_output(struct file *file,
940 void *fh, struct v4l2_output *a)
941 {
942 unsigned int index = a->index;
943 V4L2PRINTK("(%d)++\n", a->index);
944
945 if (index >= S5P_TVOUT_MAX_O_TYPES) {
946 V4L2PRINTK("exceeded supported output!!\n");
947 return -EINVAL;
948 }
949
950 memcpy(a, &s5p_tv_outputs[index], sizeof(struct v4l2_output));
951
952 V4L2PRINTK("()--\n");
953
954 return 0;
955 }
956
957 static int s5p_tv_v4l2_g_output(struct file *file, void *fh, unsigned int *i)
958 {
959 V4L2PRINTK("(%d)++\n", *i);
960
961 *i = s5ptv_status.v4l2.output->index;
962
963 V4L2PRINTK("()--\n");
964 return 0;
965 }
966
967 static int s5p_tv_v4l2_s_output(struct file *file, void *fh, unsigned int i)
968 {
969 V4L2PRINTK("(%d)++\n", i);
970
971 if (i >= S5P_TVOUT_MAX_O_TYPES)
972 return -EINVAL;
973
974 s5ptv_status.v4l2.output = &s5p_tv_outputs[i];
975
976 switch (s5ptv_status.v4l2.output->type) {
977
978 case V4L2_OUTPUT_TYPE_COMPOSITE:
979 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_COMPOSITE;
980 break;
981
982 case V4L2_OUTPUT_TYPE_SVIDEO:
983 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_SVIDEO;
984 break;
985
986 case V4L2_OUTPUT_TYPE_YPBPR_INERLACED:
987 s5ptv_status.tvout_param.out_mode =
988 TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED;
989 break;
990
991 case V4L2_OUTPUT_TYPE_YPBPR_PROGRESSIVE:
992 s5ptv_status.tvout_param.out_mode =
993 TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE;
994 break;
995
996 case V4L2_OUTPUT_TYPE_RGB_PROGRESSIVE:
997 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_COMPOSITE;
998 break;
999
1000 case V4L2_OUTPUT_TYPE_HDMI:
1001 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_HDMI;
1002 break;
1003
1004 case V4L2_OUTPUT_TYPE_HDMI_RGB:
1005 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_HDMI_RGB;
1006 break;
1007
1008 case V4L2_OUTPUT_TYPE_DVI:
1009 s5ptv_status.tvout_param.out_mode = TVOUT_OUTPUT_DVI;
1010 break;
1011
1012 default:
1013 break;
1014 }
1015
1016 tv_if_set_disp();
1017
1018 V4L2PRINTK("()--\n");
1019
1020 return 0;
1021 };
1022
1023 /* Crop ioctls */
1024
1025 /*
1026 * Video Format Name Pixel aspect ratio Description
1027 * STD(4:3) Anamorphic(16:9)
1028 * 640x480 4:3 Used on YouTube
1029 * 720x576 576i 5:4 64:45 Used on D1/DV PAL
1030 * 704x576 576p 12:11 16:11 Used on EDTV PAL
1031 * 720x480 480i 8:9 32:27 Used on DV NTSC
1032 * 720x486 480i 8:9 32:27 Used on D1 NTSC (ITU-R 601)
1033 * 704x480 480p 10:11 40:33 Used on EDTV NTSC
1034 */
1035
1036 static int s5p_tv_v4l2_cropcap(struct file *file, void *fh,
1037 struct v4l2_cropcap *a)
1038 {
1039
1040 struct v4l2_cropcap *cropcap = a;
1041
1042 switch (cropcap->type) {
1043
1044 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1045 break;
1046
1047 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1048 break;
1049
1050 default:
1051 return -1;
1052 }
1053
1054 switch (s5ptv_status.tvout_param.disp_mode) {
1055
1056 case TVOUT_NTSC_M:
1057 case TVOUT_NTSC_443:
1058 case TVOUT_480P_60_16_9:
1059 case TVOUT_480P_60_4_3:
1060 case TVOUT_480P_59:
1061 cropcap->bounds.top = 0;
1062 cropcap->bounds.left = 0;
1063 cropcap->bounds.width = 720;
1064 cropcap->bounds.height = 480;
1065
1066 cropcap->defrect.top = 0;
1067 cropcap->defrect.left = 0;
1068 cropcap->defrect.width = 720;
1069 cropcap->defrect.height = 480;
1070 break;
1071
1072 case TVOUT_PAL_M:
1073 case TVOUT_PAL_BDGHI:
1074 case TVOUT_PAL_N:
1075 case TVOUT_PAL_NC:
1076 case TVOUT_PAL_60:
1077 case TVOUT_576P_50_16_9:
1078 case TVOUT_576P_50_4_3:
1079 cropcap->bounds.top = 0;
1080 cropcap->bounds.left = 0;
1081 cropcap->bounds.width = 720;
1082 cropcap->bounds.height = 576;
1083
1084 cropcap->defrect.top = 0;
1085 cropcap->defrect.left = 0;
1086 cropcap->defrect.width = 720;
1087 cropcap->defrect.height = 576;
1088 break;
1089
1090 case TVOUT_720P_60:
1091 case TVOUT_720P_59:
1092 case TVOUT_720P_50:
1093 cropcap->bounds.top = 0;
1094 cropcap->bounds.left = 0;
1095 cropcap->bounds.width = 1280;
1096 cropcap->bounds.height = 720;
1097
1098 cropcap->defrect.top = 0;
1099 cropcap->defrect.left = 0;
1100 cropcap->defrect.width = 1280;
1101 cropcap->defrect.height = 720;
1102 break;
1103
1104 case TVOUT_1080I_60:
1105 case TVOUT_1080I_59:
1106 case TVOUT_1080I_50:
1107 case TVOUT_1080P_60:
1108 case TVOUT_1080P_59:
1109 case TVOUT_1080P_50:
1110 case TVOUT_1080P_30:
1111 cropcap->bounds.top = 0;
1112 cropcap->bounds.left = 0;
1113 cropcap->bounds.width = 1920;
1114 cropcap->bounds.height = 1080;
1115
1116 cropcap->defrect.top = 0;
1117 cropcap->defrect.left = 0;
1118 cropcap->defrect.width = 1920;
1119 cropcap->defrect.height = 1080;
1120 break;
1121
1122 default:
1123 return -1;
1124
1125 }
1126
1127 V4L2PRINTK("[input type 0x%08x] : left: \
1128 [%d], top [%d], width[%d], height[%d]\n",
1129 s5ptv_status.tvout_param.disp_mode,
1130 cropcap->bounds.top ,
1131 cropcap->bounds.left ,
1132 cropcap->bounds.width,
1133 cropcap->bounds.height);
1134
1135 return 0;
1136 }
1137
1138 static int s5p_tv_v4l2_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
1139 {
1140
1141 struct v4l2_crop *crop = a;
1142 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
1143
1144 switch (crop->type) {
1145
1146 /* Vlayer */
1147 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1148 crop->c.left = s5ptv_status.vl_basic_param.dest_offset_x;
1149 crop->c.top = s5ptv_status.vl_basic_param.dest_offset_y;
1150 crop->c.width = s5ptv_status.vl_basic_param.dest_width;
1151 crop->c.height = s5ptv_status.vl_basic_param.dest_height;
1152 break;
1153
1154 /* GRP0/1 */
1155 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1156 crop->c.left = s5ptv_overlay[layer->index].dst_rect.left;
1157 crop->c.top = s5ptv_overlay[layer->index].dst_rect.top;
1158 crop->c.width = s5ptv_overlay[layer->index].dst_rect.width;
1159 crop->c.height = s5ptv_overlay[layer->index].dst_rect.height;
1160 break;
1161
1162 default:
1163 break;
1164 }
1165
1166 return 0;
1167 }
1168
1169 static int s5p_tv_v4l2_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
1170 {
1171
1172 struct v4l2_crop *crop = a;
1173 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
1174
1175 switch (crop->type) {
1176
1177 /* Vlayer - scaling!! */
1178 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1179
1180 s5ptv_status.vl_basic_param.dest_offset_x = crop->c.left;
1181 s5ptv_status.vl_basic_param.dest_offset_y = crop->c.top;
1182 s5ptv_status.vl_basic_param.dest_width = crop->c.width;
1183 s5ptv_status.vl_basic_param.dest_height = crop->c.height;
1184
1185 if (s5ptv_status.vp_layer_enable) {
1186 struct s5p_img_size img_size;
1187 struct s5p_img_offset img_offset;
1188 img_size.img_width = crop->c.width;
1189 img_size.img_height = crop->c.height;
1190 img_offset.offset_x = crop->c.left;
1191 img_offset.offset_y = crop->c.top;
1192
1193 tv_vlayer_set_dest_size((unsigned long)&img_size);
1194 tv_vlayer_set_dest_position(
1195 (unsigned long)&img_offset);
1196 }
1197 break;
1198
1199 /* GRP0/1 */
1200 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1201 s5ptv_overlay[layer->index].dst_rect.left = crop->c.left;
1202 s5ptv_overlay[layer->index].dst_rect.top = crop->c.top;
1203 s5ptv_overlay[layer->index].dst_rect.width
1204 = crop->c.width;
1205 s5ptv_overlay[layer->index].dst_rect.height
1206 = crop->c.height;
1207 break;
1208
1209 default:
1210 break;
1211 }
1212
1213 return 0;
1214 }
1215
1216 /* Stream type-dependent parameter ioctls */
1217 static int s5p_tv_v4l2_g_parm_v(struct file *file, void *fh,
1218 struct v4l2_streamparm *a)
1219 {
1220
1221 struct v4l2_streamparm *param = a;
1222
1223 struct v4l2_window_s5p_tvout vparam;
1224
1225 if (s5ptv_status.vl_basic_param.win_blending) {
1226 vparam.flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1227 vparam.capability = V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1228 }
1229
1230 vparam.win.global_alpha = s5ptv_status.vl_basic_param.alpha;
1231
1232 vparam.priority = s5ptv_status.vl_basic_param.priority;
1233 vparam.win.w.left = s5ptv_status.vl_basic_param.src_offset_x;
1234 vparam.win.w.top = s5ptv_status.vl_basic_param.src_offset_y;
1235 vparam.win.w.width = s5ptv_status.vl_basic_param.src_width;
1236 vparam.win.w.height = s5ptv_status.vl_basic_param.src_height;
1237
1238 memcpy(param->parm.raw_data, &vparam,
1239 sizeof(struct v4l2_window_s5p_tvout));
1240
1241 return 0;
1242 }
1243
1244 static int s5p_tv_v4l2_s_parm_v(struct file *file, void *fh,
1245 struct v4l2_streamparm *a)
1246 {
1247
1248 struct v4l2_streamparm *param = a;
1249
1250 struct v4l2_window_s5p_tvout vparam;
1251
1252 memcpy(&vparam, param->parm.raw_data,
1253 sizeof(struct v4l2_window_s5p_tvout));
1254
1255 s5ptv_status.vl_basic_param.win_blending =
1256 (vparam.flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0;
1257 s5ptv_status.vl_basic_param.alpha = vparam.win.global_alpha;
1258 s5ptv_status.vl_basic_param.priority = vparam.priority;
1259 s5ptv_status.vl_basic_param.src_offset_x = vparam.win.w.left;
1260 s5ptv_status.vl_basic_param.src_offset_y = vparam.win.w.top;
1261 s5ptv_status.vl_basic_param.src_width = vparam.win.w.width;
1262 s5ptv_status.vl_basic_param.src_height = vparam.win.w.height;
1263
1264 V4L2PRINTK("[type 0x%08x] : left: [%d], top [%d], \
1265 width[%d], height[%d]\n",
1266 a->type,
1267 s5ptv_status.vl_basic_param.src_offset_x,
1268 s5ptv_status.vl_basic_param.src_offset_y,
1269 s5ptv_status.vl_basic_param.src_width,
1270 s5ptv_status.vl_basic_param.src_height);
1271
1272 if (s5ptv_status.vp_layer_enable) {
1273 struct s5p_img_offset img_offset;
1274 struct s5p_img_size img_size;
1275
1276 img_offset.offset_x = vparam.win.w.left;
1277 img_offset.offset_y = vparam.win.w.top;
1278 img_size.img_width = vparam.win.w.width;
1279 img_size.img_height = vparam.win.w.height;
1280 tv_vlayer_set_blending(
1281 s5ptv_status.vl_basic_param.win_blending);
1282 tv_vlayer_set_alpha(s5ptv_status.vl_basic_param.alpha);
1283 tv_vlayer_set_priority(vparam.priority);
1284 tv_vlayer_set_src_position((unsigned long)&img_offset);
1285 tv_vlayer_set_src_size((unsigned long)&img_size);
1286 }
1287
1288 return 0;
1289 }
1290
1291 static int s5p_tv_v4l2_g_parm_vo(struct file *file, void *fh,
1292 struct v4l2_streamparm *a)
1293 {
1294
1295 struct v4l2_streamparm *param = a;
1296
1297 struct v4l2_window_s5p_tvout vparam;
1298 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
1299
1300 memset(&vparam, 0, sizeof(struct v4l2_window_s5p_tvout));
1301
1302 V4L2PRINTK("entered\n");
1303
1304 if (s5ptv_overlay[layer->index].win_blending) {
1305 vparam.flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1306 vparam.capability = V4L2_FBUF_CAP_GLOBAL_ALPHA;
1307 }
1308
1309 if (s5ptv_overlay[layer->index].blank_change) {
1310 vparam.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1311 vparam.capability |= V4L2_FBUF_CAP_CHROMAKEY;
1312 }
1313
1314 if (s5ptv_overlay[layer->index].pixel_blending) {
1315 vparam.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1316 vparam.capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
1317 }
1318
1319 if (s5ptv_overlay[layer->index].pre_mul) {
1320 vparam.flags |= V4L2_FBUF_FLAG_PRE_MULTIPLY;
1321 vparam.capability |= V4L2_FBUF_CAP_PRE_MULTIPLY;
1322 }
1323
1324 vparam.priority = s5ptv_overlay[layer->index].priority;
1325
1326 vparam.win.chromakey =
1327 s5ptv_overlay[layer->index].blank_color;
1328 vparam.win.w.left = s5ptv_overlay[layer->index].dst_rect.left;
1329 vparam.win.w.top = s5ptv_overlay[layer->index].dst_rect.top;
1330 vparam.win.w.left = s5ptv_overlay[layer->index].win.w.left;
1331 vparam.win.w.top = s5ptv_overlay[layer->index].win.w.top;
1332 vparam.win.w.width = s5ptv_overlay[layer->index].win.w.width;
1333 vparam.win.w.height = s5ptv_overlay[layer->index].win.w.height;
1334 vparam.win.global_alpha =
1335 s5ptv_overlay[layer->index].win.global_alpha;
1336 vparam.win.w.width =
1337 s5ptv_overlay[layer->index].fb.fmt.bytesperline;
1338
1339 memcpy(param->parm.raw_data, &vparam,
1340 sizeof(struct v4l2_window_s5p_tvout));
1341
1342 return 0;
1343
1344 }
1345
1346
1347 static int s5p_tv_v4l2_s_parm_vo(struct file *file, void *fh,
1348 struct v4l2_streamparm *a)
1349 {
1350
1351 struct v4l2_streamparm *param = a;
1352
1353 struct v4l2_window_s5p_tvout vparam;
1354
1355 struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;
1356 memcpy(&vparam, param->parm.raw_data,
1357 sizeof(struct v4l2_window_s5p_tvout));
1358
1359 s5ptv_overlay[layer->index].win_blending =
1360 (vparam.flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0;
1361 s5ptv_overlay[layer->index].blank_change =
1362 (vparam.flags & V4L2_FBUF_FLAG_CHROMAKEY) ? 1 : 0;
1363 s5ptv_overlay[layer->index].pixel_blending =
1364 (vparam.flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) ? 1 : 0;
1365 s5ptv_overlay[layer->index].pre_mul =
1366 (vparam.flags & V4L2_FBUF_FLAG_PRE_MULTIPLY) ? 1 : 0;
1367 s5ptv_overlay[layer->index].priority = vparam.priority;
1368 s5ptv_overlay[layer->index].blank_color =
1369 vparam.win.chromakey;
1370 s5ptv_overlay[layer->index].dst_rect.left = vparam.win.w.left;
1371 s5ptv_overlay[layer->index].dst_rect.top = vparam.win.w.top;
1372 s5ptv_overlay[layer->index].win.w.left = vparam.win.w.left;
1373 s5ptv_overlay[layer->index].win.w.top = vparam.win.w.top;
1374 s5ptv_overlay[layer->index].win.w.width = vparam.win.w.width;
1375 s5ptv_overlay[layer->index].win.w.height = vparam.win.w.height;
1376 s5ptv_overlay[layer->index].win.global_alpha =
1377 vparam.win.global_alpha;
1378
1379 s5ptv_overlay[layer->index].fb.fmt.bytesperline = vparam.win.w.width;
1380
1381 return 0;
1382 }
1383
1384 #define VIDIOC_HDCP_ENABLE _IOWR('V', 100, unsigned int)
1385 #define VIDIOC_HDCP_STATUS _IOR('V', 101, unsigned int)
1386 #define VIDIOC_HDCP_PROT_STATUS _IOR('V', 102, unsigned int)
1387
1388 long s5p_tv_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1389 {
1390 switch (cmd) {
1391
1392 case VIDIOC_HDCP_ENABLE:
1393 s5ptv_status.hdcp_en = (unsigned int) arg;
1394 V4L2PRINTK("HDCP status is %s\n",
1395 s5ptv_status.hdcp_en ? "enabled" : "disabled");
1396 return 0;
1397
1398 case VIDIOC_HDCP_STATUS: {
1399
1400 unsigned int *status = (unsigned int *)&arg;
1401
1402 *status = 1;
1403
1404 V4L2PRINTK("HPD status is %s\n",
1405 s5ptv_status.hpd_status ? "plugged" : "unplugged");
1406 return 0;
1407 }
1408
1409 case VIDIOC_HDCP_PROT_STATUS: {
1410
1411 unsigned int *prot = (unsigned int *)&arg;
1412
1413 *prot = 1;
1414
1415 V4L2PRINTK("hdcp prot status is %d\n",
1416 hdcp_protocol_status);
1417 return 0;
1418 }
1419
1420 case VIDIOC_ENUMSTD: {
1421
1422 struct v4l2_standard *p = (struct v4l2_standard *)arg;
1423
1424 if (p->index >= S5P_TVOUT_MAX_STANDARDS) {
1425 V4L2PRINTK("exceeded S5P_TVOUT_MAX_STANDARDS\n");
1426 return -EINVAL;
1427 }
1428
1429 memcpy(p, &s5p_tv_standards[p->index],
1430 sizeof(struct v4l2_standard));
1431 return 0;
1432 }
1433
1434 default:
1435 break;
1436 }
1437
1438 return video_ioctl2(file, cmd, arg);
1439 }
1440
1441 long s5p_tv_vid_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1442 {
1443 struct video_device *vfd = video_devdata(file);
1444 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
1445
1446 switch (cmd) {
1447
1448 case VIDIOC_S_FMT: {
1449 struct v4l2_format *f = (struct v4l2_format *)arg;
1450 void *fh = file->private_data;
1451 long ret = -EINVAL;
1452
1453 if (ops->vidioc_s_fmt_vid_out)
1454 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
1455 return ret;
1456 }
1457
1458 default:
1459 break;
1460 }
1461
1462 return video_ioctl2(file, cmd, arg);
1463 }
1464
1465
1466 long s5p_tv_v_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1467 {
1468 struct video_device *vfd = video_devdata(file);
1469 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
1470
1471 switch (cmd) {
1472
1473 case VIDIOC_S_FMT: {
1474 struct v4l2_format *f = (struct v4l2_format *)arg;
1475 void *fh = file->private_data;
1476 long ret = -EINVAL;
1477
1478 if (ops->vidioc_s_fmt_vid_out)
1479 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
1480 return ret;
1481 }
1482
1483 case VIDIOC_HDCP_ENABLE:
1484 s5ptv_status.hdcp_en = (unsigned int) arg;
1485 V4L2PRINTK("HDCP status is %s\n",
1486 s5ptv_status.hdcp_en ? "enabled" : "disabled");
1487 return 0;
1488
1489 case VIDIOC_HDCP_STATUS: {
1490
1491 unsigned int *status = (unsigned int *)&arg;
1492
1493 *status = 1;
1494
1495 V4L2PRINTK("HPD status is %s\n",
1496 s5ptv_status.hpd_status ? "plugged" : "unplugged");
1497 return 0;
1498 }
1499
1500 case VIDIOC_HDCP_PROT_STATUS: {
1501
1502 unsigned int *prot = (unsigned int *)&arg;
1503
1504 *prot = 1;
1505
1506 V4L2PRINTK("hdcp prot status is %d\n",
1507 hdcp_protocol_status);
1508 return 0;
1509 }
1510
1511 case VIDIOC_ENUMSTD: {
1512
1513 struct v4l2_standard *p = (struct v4l2_standard *)arg;
1514
1515 if (p->index >= S5P_TVOUT_MAX_STANDARDS) {
1516 V4L2PRINTK("exceeded S5P_TVOUT_MAX_STANDARDS\n");
1517 return -EINVAL;
1518 }
1519
1520 memcpy(p, &s5p_tv_standards[p->index],
1521 sizeof(struct v4l2_standard));
1522
1523 return 0;
1524 }
1525
1526 default:
1527 break;
1528 }
1529
1530 return video_ioctl2(file, cmd, arg);
1531 }
1532
1533 long s5p_tv_vo_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1534 {
1535 void *fh = file->private_data;
1536
1537 switch (cmd) {
1538
1539 case VIDIOC_ENUM_FMT: {
1540
1541 struct v4l2_fmtdesc *f = (struct v4l2_fmtdesc *)arg;
1542 enum v4l2_buf_type type;
1543 unsigned int index;
1544
1545 index = f->index;
1546 type = f->type;
1547
1548 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
1549 memset(f, 0, sizeof(*f));
1550 f->index = index;
1551 f->type = type;
1552
1553 return s5p_tv_v4l2_enum_fmt_vid_out_overlay(
1554 file, fh, f);
1555 }
1556
1557 break;
1558 }
1559
1560 case VIDIOC_G_FMT: {
1561
1562 struct v4l2_format *f = (struct v4l2_format *)arg;
1563
1564 return s5p_tv_v4l2_g_fmt_vid_out_overlay(file, fh, f);
1565 }
1566
1567 break;
1568
1569 default:
1570 break;
1571 }
1572
1573 /*
1574 * in 2.6.28 version Mauro Carvalho Chehab added for removing inode
1575 * but 2.6.29 is not applied. what is it?
1576 */
1577 return video_ioctl2(file, cmd, arg);
1578 }
1579
1580 const struct v4l2_ioctl_ops s5p_tv_v4l2_ops = {
1581 .vidioc_querycap = s5p_tv_v4l2_querycap,
1582 .vidioc_g_std = s5p_tv_v4l2_g_std,
1583 .vidioc_s_std = s5p_tv_v4l2_s_std,
1584 .vidioc_enum_output = s5p_tv_v4l2_enum_output,
1585 .vidioc_g_output = s5p_tv_v4l2_g_output,
1586 .vidioc_s_output = s5p_tv_v4l2_s_output,
1587 };
1588
1589 const struct v4l2_ioctl_ops s5p_tv_v4l2_vid_ops = {
1590 .vidioc_querycap = s5p_tv_v4l2_querycap,
1591 .vidioc_enum_fmt_vid_out = s5p_tv_v4l2_enum_fmt_vid_out,
1592 .vidioc_g_fmt_vid_out = s5p_tv_v4l2_g_fmt_vid_out,
1593 .vidioc_s_fmt_vid_out = s5p_tv_v4l2_s_fmt_vid_out,
1594 .vidioc_streamon = s5p_tv_v4l2_streamon,
1595 .vidioc_streamoff = s5p_tv_v4l2_streamoff,
1596 .vidioc_cropcap = s5p_tv_v4l2_cropcap,
1597 .vidioc_g_crop = s5p_tv_v4l2_g_crop,
1598 .vidioc_s_crop = s5p_tv_v4l2_s_crop,
1599 .vidioc_g_parm = s5p_tv_v4l2_g_parm_v,
1600 .vidioc_s_parm = s5p_tv_v4l2_s_parm_v,
1601 };
1602
1603 const struct v4l2_ioctl_ops s5p_tv_v4l2_v_ops = {
1604 .vidioc_querycap = s5p_tv_v4l2_querycap,
1605 .vidioc_enum_fmt_vid_out = s5p_tv_v4l2_enum_fmt_vid_out,
1606 .vidioc_g_fmt_vid_out = s5p_tv_v4l2_g_fmt_vid_out,
1607 .vidioc_s_fmt_vid_out = s5p_tv_v4l2_s_fmt_vid_out,
1608 .vidioc_streamon = s5p_tv_v4l2_streamon,
1609 .vidioc_streamoff = s5p_tv_v4l2_streamoff,
1610 .vidioc_g_std = s5p_tv_v4l2_g_std,
1611 .vidioc_s_std = s5p_tv_v4l2_s_std,
1612 .vidioc_enum_output = s5p_tv_v4l2_enum_output,
1613 .vidioc_g_output = s5p_tv_v4l2_g_output,
1614 .vidioc_s_output = s5p_tv_v4l2_s_output,
1615 .vidioc_cropcap = s5p_tv_v4l2_cropcap,
1616 .vidioc_g_crop = s5p_tv_v4l2_g_crop,
1617 .vidioc_s_crop = s5p_tv_v4l2_s_crop,
1618 .vidioc_g_parm = s5p_tv_v4l2_g_parm_v,
1619 .vidioc_s_parm = s5p_tv_v4l2_s_parm_v,
1620 };
1621
1622 const struct v4l2_ioctl_ops s5p_tv_v4l2_vo_ops = {
1623 .vidioc_querycap = s5p_tv_v4l2_querycap,
1624 .vidioc_g_fmt_vid_out_overlay = s5p_tv_v4l2_g_fmt_vid_out_overlay,
1625 .vidioc_s_fmt_vid_out_overlay = s5p_tv_v4l2_s_fmt_vid_out_overlay,
1626 .vidioc_overlay = s5p_tv_v4l2_overlay,
1627 .vidioc_g_fbuf = s5p_tv_v4l2_g_fbuf,
1628 .vidioc_s_fbuf = s5p_tv_v4l2_s_fbuf,
1629 .vidioc_streamon = s5p_tv_v4l2_streamon,
1630 .vidioc_streamoff = s5p_tv_v4l2_streamoff,
1631 .vidioc_cropcap = s5p_tv_v4l2_cropcap,
1632 .vidioc_g_crop = s5p_tv_v4l2_g_crop,
1633 .vidioc_s_crop = s5p_tv_v4l2_s_crop,
1634 .vidioc_g_parm = s5p_tv_v4l2_g_parm_vo,
1635 .vidioc_s_parm = s5p_tv_v4l2_s_parm_vo,
1636 };
1637
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/s5p_tv_base.c ('k') | drivers/media/video/samsung/tv20/sdout_s5pv210.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698