41 #include <linux/module.h>
42 #include <linux/kernel.h>
45 #include <linux/slab.h>
59 static int ivtvfb_card_id = -1;
60 static int ivtvfb_debug = 0;
61 static bool osd_laced;
78 "Only use framebuffer of the specified ivtv card (0-31)\n"
79 "\t\t\tdefault -1: initialize all available framebuffers");
82 "Debug level (bitmask). Default: errors only\n"
83 "\t\t\t(debug = 3 gives full debugging)");
96 "Bits per pixel - 8, 16, 32\n"
100 "Vertical start position\n"
101 "\t\t\tdefault 0 (Centered)");
104 "Horizontal start position\n"
105 "\t\t\tdefault 0 (Centered)");
109 "\t\t\tdefault 480 (PAL)\n"
110 "\t\t\t 400 (NTSC)");
114 "\t\t\tdefault 640");
116 MODULE_AUTHOR(
"Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
121 #define IVTVFB_DBGFLG_WARN (1 << 0)
122 #define IVTVFB_DBGFLG_INFO (1 << 1)
124 #define IVTVFB_DEBUG(x, type, fmt, args...) \
126 if ((x) & ivtvfb_debug) \
127 printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
129 #define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
130 #define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
133 #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
134 #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
135 #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
139 #define IVTV_OSD_MAX_WIDTH 720
140 #define IVTV_OSD_MAX_HEIGHT 576
142 #define IVTV_OSD_BPP_8 0x00
143 #define IVTV_OSD_BPP_16_444 0x03
144 #define IVTV_OSD_BPP_16_555 0x02
145 #define IVTV_OSD_BPP_16_565 0x01
146 #define IVTV_OSD_BPP_32 0x04
160 unsigned long fb_start_aligned_physaddr;
162 unsigned long fb_end_aligned_physaddr;
203 static int ivtvfb_get_framebuffer(
struct ivtv *itv,
u32 *fbbase,
216 static int ivtvfb_get_osd_coords(
struct ivtv *itv,
227 osd->
lines = data[2];
248 static int ivtvfb_set_display_window(
struct ivtv *itv,
struct v4l2_rect *ivtv_window)
250 int osd_height_limit = itv->
is_out_50hz ? 576 : 480;
257 if (ivtv_window->
top + ivtv_window->
height > osd_height_limit) {
258 IVTVFB_DEBUG_WARN(
"ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
260 ivtv_window->
top = osd_height_limit - ivtv_window->
height;
264 IVTVFB_DEBUG_WARN(
"ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
284 static int ivtvfb_prep_dec_dma_to_device(
struct ivtv *itv,
285 unsigned long ivtv_dest_addr,
void __user *userbuf,
293 if (
ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
296 "Error with get_user_pages: %d bytes, %d pages returned\n",
297 size_in_bytes, itv->
udma.page_count);
304 size_in_bytes, itv->
udma.page_count);
314 got_sig = signal_pending(
current);
333 static int ivtvfb_prep_frame(
struct ivtv *itv,
int cmd,
void __user *
source,
334 unsigned long dest_offset,
int count)
347 IVTVFB_WARN(
"ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
353 if ((
unsigned long)source & 3)
354 IVTVFB_WARN(
"ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
355 (
unsigned long)source);
358 IVTVFB_WARN(
"ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
361 IVTVFB_WARN(
"ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
366 (
unsigned long)source);
368 IVTVFB_DEBUG_WARN(
"access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
369 dest_offset, (
unsigned long)source,
378 return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
382 size_t count, loff_t *ppos)
384 unsigned long p = *ppos;
390 unsigned long dma_offset =
392 unsigned long dma_size;
401 total_size = info->
fix.smem_len;
406 if (count > total_size) {
411 if (count + p > total_size) {
414 count = total_size -
p;
419 if (info->
fbops->fb_sync)
420 info->
fbops->fb_sync(info);
425 ((
unsigned long)buf & 3) == ((
unsigned long)dst & 3)) {
427 if ((
unsigned long)dst & 3) {
428 lead = 4 - ((
unsigned long)dst & 3);
435 if ((count - lead) & 3)
436 tail = (count - lead) & 3;
438 dma_size = count - lead -
tail;
439 dma_err = ivtvfb_prep_dec_dma_to_device(itv,
440 p + lead + dma_offset, (
void __user *)buf, dma_size);
455 return (err) ? err :
count;
458 static int ivtvfb_ioctl(
struct fb_info *info,
unsigned int cmd,
unsigned long arg)
481 vblank.vcount =
trace;
483 if (
copy_to_user((
void __user *)arg, &vblank,
sizeof(vblank)))
502 return ivtvfb_prep_frame(itv, cmd,
args.source,
args.dest_offset,
args.count);
538 switch (var->
green.length) {
558 if (osd_mode != -1) {
579 ivtvfb_get_osd_coords(itv, &ivtv_osd);
586 ivtvfb_set_osd_coords(itv, &ivtv_osd);
601 ivtvfb_set_display_window(itv, &ivtv_window);
604 itv->
yuv_info.osd_full_w = ivtv_osd.pixel_stride;
605 itv->
yuv_info.osd_full_h = ivtv_osd.lines;
608 itv->
yuv_info.yuv_forced_update = 1;
634 strlcpy(fix->
id,
"cx23415 TV out",
sizeof(fix->
id));
653 int osd_height_limit;
654 u32 pixclock, hlimit, vlimit;
663 osd_height_limit = 576;
669 osd_height_limit = 480;
675 var->
red.offset = 16;
677 var->
green.offset = 8;
678 var->
green.length = 8;
679 var->
blue.offset = 0;
680 var->
blue.length = 8;
684 switch (var->
green.length) {
688 var->
green.offset = 4;
689 var->
green.length = 4;
690 var->
blue.offset = 0;
691 var->
blue.length = 4;
696 var->
red.offset = 10;
698 var->
green.offset = 5;
699 var->
green.length = 5;
700 var->
blue.offset = 0;
701 var->
blue.length = 5;
706 var->
red.offset = 11;
708 var->
green.offset = 5;
709 var->
green.length = 6;
710 var->
blue.offset = 0;
711 var->
blue.length = 5;
831 return _ivtvfb_check_var(var, itv);
843 osd_pan_index = var->
yoffset * info->
fix.line_length
844 + var->
xoffset * info->
var.bits_per_pixel / 8;
851 itv->
yuv_info.yuv_forced_update = 1;
853 itv->
osd_info->pan_cur = osd_pan_index;
857 static int ivtvfb_set_par(
struct fb_info *info)
864 rc = ivtvfb_set_var(itv, &info->
var);
865 ivtvfb_pan_display(&info->
var, info);
866 ivtvfb_get_fix(itv, &info->
fix);
871 static int ivtvfb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
878 if (regno >= info->
cmap.len)
881 color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
882 if (info->
var.bits_per_pixel <= 8) {
892 if (info->
var.bits_per_pixel == 16) {
893 switch (info->
var.green.length) {
895 color = ((red & 0xf000) >> 4) |
896 ((green & 0xf000) >> 8) |
897 ((blue & 0xf000) >> 12);
900 color = ((red & 0xf800) >> 1) |
901 ((green & 0xf800) >> 6) |
902 ((blue & 0xf800) >> 11);
905 color = (red & 0xf800 ) |
906 ((green & 0xfc00) >> 5) |
907 ((blue & 0xf800) >> 11);
911 palette[regno] =
color;
917 static int ivtvfb_blank(
int blank_mode,
struct fb_info *info)
922 switch (blank_mode) {
938 itv->
osd_info->blank_cur = blank_mode;
942 static struct fb_ops ivtvfb_ops = {
944 .fb_write = ivtvfb_write,
945 .fb_check_var = ivtvfb_check_var,
946 .fb_set_par = ivtvfb_set_par,
947 .fb_setcolreg = ivtvfb_setcolreg,
952 .fb_ioctl = ivtvfb_ioctl,
953 .fb_pan_display = ivtvfb_pan_display,
954 .fb_blank = ivtvfb_blank,
958 static void ivtvfb_restore(
struct ivtv *itv)
965 for (i = 0; i < 256; i++) {
976 static int ivtvfb_init_vidmode(
struct ivtv *itv)
984 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
997 else if (osd_depth == 16)
1000 start_window.width = osd_xres ? osd_xres : 640;
1003 if (osd_left && osd_left + start_window.width > 721) {
1004 IVTVFB_ERR(
"Invalid osd_left - assuming default\n");
1011 start_window.left = osd_left >= 0 ?
1021 if (osd_yres > max_height)
1024 start_window.height = osd_yres ?
1028 if (osd_upper + start_window.height > max_height + 1) {
1029 IVTVFB_ERR(
"Invalid osd_upper - assuming default\n");
1036 start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1090 IVTVFB_ERR(
"abort, unable to alloc pseudo palette\n");
1099 static int ivtvfb_init_io(
struct ivtv *itv)
1126 IVTVFB_ERR(
"abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1131 IVTVFB_INFO(
"Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1138 int size_shift = 31;
1144 oi->fb_start_aligned_physaddr = oi->
video_pbase & ~((1 << size_shift) - 1);
1146 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1147 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1148 if (
mtrr_add(oi->fb_start_aligned_physaddr,
1149 oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
1152 oi->fb_start_aligned_physaddr = 0;
1153 oi->fb_end_aligned_physaddr = 0;
1165 static void ivtvfb_release_buffers (
struct ivtv *itv)
1178 if (oi->fb_end_aligned_physaddr) {
1179 mtrr_del(-1, oi->fb_start_aligned_physaddr,
1180 oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
1190 static int ivtvfb_init_card(
struct ivtv *itv)
1195 IVTVFB_ERR(
"Card %d already initialised\n", ivtvfb_card_id);
1202 IVTVFB_ERR(
"Failed to allocate memory for osd_info\n");
1207 rc = ivtvfb_init_io(itv);
1209 ivtvfb_release_buffers(itv);
1214 if ((rc = ivtvfb_init_vidmode(itv))) {
1215 ivtvfb_release_buffers(itv);
1221 ivtvfb_release_buffers(itv);
1228 ivtvfb_set_par(&itv->
osd_info->ivtvfb_info);
1252 if (ivtvfb_init_card(itv) == 0) {
1261 static int ivtvfb_callback_cleanup(
struct device *dev,
void *p)
1269 IVTVFB_WARN(
"Framebuffer %d is in use, cannot unload\n",
1276 ivtvfb_release_buffers(itv);
1282 static int __init ivtvfb_init(
void)
1289 printk(
KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1304 static void ivtvfb_cleanup(
void)