[media] ivtvfb: use display information in info not in var for panning
[pandora-kernel.git] / drivers / media / video / ivtv / ivtvfb.c
1 /*
2     On Screen Display cx23415 Framebuffer driver
3
4     This module presents the cx23415 OSD (onscreen display) framebuffer memory
5     as a standard Linux /dev/fb style framebuffer device. The framebuffer has
6     support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
7     mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
8     local alpha. The colorspace is selectable between rgb & yuv.
9     Depending on the TV standard configured in the ivtv module at load time,
10     the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
11     Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
12     or 59.94 (NTSC)
13
14     Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
15
16     Derived from drivers/video/vesafb.c
17     Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
18
19     2.6 kernel port:
20     Copyright (C) 2004 Matthias Badaire
21
22     Copyright (C) 2004  Chris Kennedy <c@groovy.org>
23
24     Copyright (C) 2006  Ian Armstrong <ian@iarmst.demon.co.uk>
25
26     This program is free software; you can redistribute it and/or modify
27     it under the terms of the GNU General Public License as published by
28     the Free Software Foundation; either version 2 of the License, or
29     (at your option) any later version.
30
31     This program is distributed in the hope that it will be useful,
32     but WITHOUT ANY WARRANTY; without even the implied warranty of
33     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34     GNU General Public License for more details.
35
36     You should have received a copy of the GNU General Public License
37     along with this program; if not, write to the Free Software
38     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
39  */
40
41 #include <linux/module.h>
42 #include <linux/kernel.h>
43 #include <linux/fb.h>
44 #include <linux/ivtvfb.h>
45 #include <linux/slab.h>
46
47 #ifdef CONFIG_MTRR
48 #include <asm/mtrr.h>
49 #endif
50
51 #include "ivtv-driver.h"
52 #include "ivtv-cards.h"
53 #include "ivtv-i2c.h"
54 #include "ivtv-udma.h"
55 #include "ivtv-mailbox.h"
56 #include "ivtv-firmware.h"
57
58 /* card parameters */
59 static int ivtvfb_card_id = -1;
60 static int ivtvfb_debug = 0;
61 static int osd_laced;
62 static int osd_depth;
63 static int osd_upper;
64 static int osd_left;
65 static int osd_yres;
66 static int osd_xres;
67
68 module_param(ivtvfb_card_id, int, 0444);
69 module_param_named(debug,ivtvfb_debug, int, 0644);
70 module_param(osd_laced, bool, 0444);
71 module_param(osd_depth, int, 0444);
72 module_param(osd_upper, int, 0444);
73 module_param(osd_left, int, 0444);
74 module_param(osd_yres, int, 0444);
75 module_param(osd_xres, int, 0444);
76
77 MODULE_PARM_DESC(ivtvfb_card_id,
78                  "Only use framebuffer of the specified ivtv card (0-31)\n"
79                  "\t\t\tdefault -1: initialize all available framebuffers");
80
81 MODULE_PARM_DESC(debug,
82                  "Debug level (bitmask). Default: errors only\n"
83                  "\t\t\t(debug = 3 gives full debugging)");
84
85 /* Why upper, left, xres, yres, depth, laced ? To match terminology used
86    by fbset.
87    Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
88
89 MODULE_PARM_DESC(osd_laced,
90                  "Interlaced mode\n"
91                  "\t\t\t0=off\n"
92                  "\t\t\t1=on\n"
93                  "\t\t\tdefault off");
94
95 MODULE_PARM_DESC(osd_depth,
96                  "Bits per pixel - 8, 16, 32\n"
97                  "\t\t\tdefault 8");
98
99 MODULE_PARM_DESC(osd_upper,
100                  "Vertical start position\n"
101                  "\t\t\tdefault 0 (Centered)");
102
103 MODULE_PARM_DESC(osd_left,
104                  "Horizontal start position\n"
105                  "\t\t\tdefault 0 (Centered)");
106
107 MODULE_PARM_DESC(osd_yres,
108                  "Display height\n"
109                  "\t\t\tdefault 480 (PAL)\n"
110                  "\t\t\t        400 (NTSC)");
111
112 MODULE_PARM_DESC(osd_xres,
113                  "Display width\n"
114                  "\t\t\tdefault 640");
115
116 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
117 MODULE_LICENSE("GPL");
118
119 /* --------------------------------------------------------------------- */
120
121 #define IVTVFB_DBGFLG_WARN  (1 << 0)
122 #define IVTVFB_DBGFLG_INFO  (1 << 1)
123
124 #define IVTVFB_DEBUG(x, type, fmt, args...) \
125         do { \
126                 if ((x) & ivtvfb_debug) \
127                         printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
128         } while (0)
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)
131
132 /* Standard kernel messages */
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)
136
137 /* --------------------------------------------------------------------- */
138
139 #define IVTV_OSD_MAX_WIDTH  720
140 #define IVTV_OSD_MAX_HEIGHT 576
141
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
147
148 struct osd_info {
149         /* Physical base address */
150         unsigned long video_pbase;
151         /* Relative base address (relative to start of decoder memory) */
152         u32 video_rbase;
153         /* Mapped base address */
154         volatile char __iomem *video_vbase;
155         /* Buffer size */
156         u32 video_buffer_size;
157
158 #ifdef CONFIG_MTRR
159         /* video_base rounded down as required by hardware MTRRs */
160         unsigned long fb_start_aligned_physaddr;
161         /* video_base rounded up as required by hardware MTRRs */
162         unsigned long fb_end_aligned_physaddr;
163 #endif
164
165         /* Store the buffer offset */
166         int set_osd_coords_x;
167         int set_osd_coords_y;
168
169         /* Current dimensions (NOT VISIBLE SIZE!) */
170         int display_width;
171         int display_height;
172         int display_byte_stride;
173
174         /* Current bits per pixel */
175         int bits_per_pixel;
176         int bytes_per_pixel;
177
178         /* Frame buffer stuff */
179         struct fb_info ivtvfb_info;
180         struct fb_var_screeninfo ivtvfb_defined;
181         struct fb_fix_screeninfo ivtvfb_fix;
182
183         /* Used for a warm start */
184         struct fb_var_screeninfo fbvar_cur;
185         int blank_cur;
186         u32 palette_cur[256];
187         u32 pan_cur;
188 };
189
190 struct ivtv_osd_coords {
191         unsigned long offset;
192         unsigned long max_offset;
193         int pixel_stride;
194         int lines;
195         int x;
196         int y;
197 };
198
199 /* --------------------------------------------------------------------- */
200
201 /* ivtv API calls for framebuffer related support */
202
203 static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
204                                        u32 *fblength)
205 {
206         u32 data[CX2341X_MBOX_MAX_DATA];
207         int rc;
208
209         ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
210         rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
211         *fbbase = data[0];
212         *fblength = data[1];
213         return rc;
214 }
215
216 static int ivtvfb_get_osd_coords(struct ivtv *itv,
217                                       struct ivtv_osd_coords *osd)
218 {
219         struct osd_info *oi = itv->osd_info;
220         u32 data[CX2341X_MBOX_MAX_DATA];
221
222         ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
223
224         osd->offset = data[0] - oi->video_rbase;
225         osd->max_offset = oi->display_width * oi->display_height * 4;
226         osd->pixel_stride = data[1];
227         osd->lines = data[2];
228         osd->x = data[3];
229         osd->y = data[4];
230         return 0;
231 }
232
233 static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
234 {
235         struct osd_info *oi = itv->osd_info;
236
237         oi->display_width = osd->pixel_stride;
238         oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
239         oi->set_osd_coords_x += osd->x;
240         oi->set_osd_coords_y = osd->y;
241
242         return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
243                         osd->offset + oi->video_rbase,
244                         osd->pixel_stride,
245                         osd->lines, osd->x, osd->y);
246 }
247
248 static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
249 {
250         int osd_height_limit = itv->is_50hz ? 576 : 480;
251
252         /* Only fail if resolution too high, otherwise fudge the start coords. */
253         if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
254                 return -EINVAL;
255
256         /* Ensure we don't exceed display limits */
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",
259                         ivtv_window->top, ivtv_window->height);
260                 ivtv_window->top = osd_height_limit - ivtv_window->height;
261         }
262
263         if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
264                 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
265                         ivtv_window->left, ivtv_window->width);
266                 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
267         }
268
269         /* Set the OSD origin */
270         write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
271
272         /* How much to display */
273         write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
274
275         /* Pass this info back the yuv handler */
276         itv->yuv_info.osd_vis_w = ivtv_window->width;
277         itv->yuv_info.osd_vis_h = ivtv_window->height;
278         itv->yuv_info.osd_x_offset = ivtv_window->left;
279         itv->yuv_info.osd_y_offset = ivtv_window->top;
280
281         return 0;
282 }
283
284 static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
285                                   unsigned long ivtv_dest_addr, void __user *userbuf,
286                                   int size_in_bytes)
287 {
288         DEFINE_WAIT(wait);
289         int got_sig = 0;
290
291         mutex_lock(&itv->udma.lock);
292         /* Map User DMA */
293         if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
294                 mutex_unlock(&itv->udma.lock);
295                 IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, "
296                                "Error with get_user_pages: %d bytes, %d pages returned\n",
297                                size_in_bytes, itv->udma.page_count);
298
299                 /* get_user_pages must have failed completely */
300                 return -EIO;
301         }
302
303         IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
304                        size_in_bytes, itv->udma.page_count);
305
306         ivtv_udma_prepare(itv);
307         prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
308         /* if no UDMA is pending and no UDMA is in progress, then the DMA
309            is finished */
310         while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
311                test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
312                 /* don't interrupt if the DMA is in progress but break off
313                    a still pending DMA. */
314                 got_sig = signal_pending(current);
315                 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
316                         break;
317                 got_sig = 0;
318                 schedule();
319         }
320         finish_wait(&itv->dma_waitq, &wait);
321
322         /* Unmap Last DMA Xfer */
323         ivtv_udma_unmap(itv);
324         mutex_unlock(&itv->udma.lock);
325         if (got_sig) {
326                 IVTV_DEBUG_INFO("User stopped OSD\n");
327                 return -EINTR;
328         }
329
330         return 0;
331 }
332
333 static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
334                               unsigned long dest_offset, int count)
335 {
336         DEFINE_WAIT(wait);
337         struct osd_info *oi = itv->osd_info;
338
339         /* Nothing to do */
340         if (count == 0) {
341                 IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
342                 return -EINVAL;
343         }
344
345         /* Check Total FB Size */
346         if ((dest_offset + count) > oi->video_buffer_size) {
347                 IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
348                         dest_offset + count, oi->video_buffer_size);
349                 return -E2BIG;
350         }
351
352         /* Not fatal, but will have undesirable results */
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);
356
357         if (dest_offset & 3)
358                 IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
359
360         if (count & 3)
361                 IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
362
363         /* Check Source */
364         if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
365                 IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
366                         (unsigned long)source);
367
368                 IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
369                         dest_offset, (unsigned long)source,
370                         count);
371                 return -EINVAL;
372         }
373
374         /* OSD Address to send DMA to */
375         dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
376
377         /* Fill Buffers */
378         return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
379 }
380
381 static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
382                                                 size_t count, loff_t *ppos)
383 {
384         unsigned long p = *ppos;
385         void *dst;
386         int err = 0;
387         int dma_err;
388         unsigned long total_size;
389         struct ivtv *itv = (struct ivtv *) info->par;
390         unsigned long dma_offset =
391                         IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
392         unsigned long dma_size;
393         u16 lead = 0, tail = 0;
394
395         if (info->state != FBINFO_STATE_RUNNING)
396                 return -EPERM;
397
398         total_size = info->screen_size;
399
400         if (total_size == 0)
401                 total_size = info->fix.smem_len;
402
403         if (p > total_size)
404                 return -EFBIG;
405
406         if (count > total_size) {
407                 err = -EFBIG;
408                 count = total_size;
409         }
410
411         if (count + p > total_size) {
412                 if (!err)
413                         err = -ENOSPC;
414                 count = total_size - p;
415         }
416
417         dst = (void __force *) (info->screen_base + p);
418
419         if (info->fbops->fb_sync)
420                 info->fbops->fb_sync(info);
421
422         /* If transfer size > threshold and both src/dst
423         addresses are aligned, use DMA */
424         if (count >= 4096 &&
425             ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
426                 /* Odd address = can't DMA. Align */
427                 if ((unsigned long)dst & 3) {
428                         lead = 4 - ((unsigned long)dst & 3);
429                         if (copy_from_user(dst, buf, lead))
430                                 return -EFAULT;
431                         buf += lead;
432                         dst += lead;
433                 }
434                 /* DMA resolution is 32 bits */
435                 if ((count - lead) & 3)
436                         tail = (count - lead) & 3;
437                 /* DMA the data */
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);
441                 if (dma_err)
442                         return dma_err;
443                 dst += dma_size;
444                 buf += dma_size;
445                 /* Copy any leftover data */
446                 if (tail && copy_from_user(dst, buf, tail))
447                         return -EFAULT;
448         } else if (copy_from_user(dst, buf, count)) {
449                 return -EFAULT;
450         }
451
452         if  (!err)
453                 *ppos += count;
454
455         return (err) ? err : count;
456 }
457
458 static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
459 {
460         DEFINE_WAIT(wait);
461         struct ivtv *itv = (struct ivtv *)info->par;
462         int rc = 0;
463
464         switch (cmd) {
465                 case FBIOGET_VBLANK: {
466                         struct fb_vblank vblank;
467                         u32 trace;
468
469                         memset(&vblank, 0, sizeof(struct fb_vblank));
470
471                         vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
472                                         FB_VBLANK_HAVE_VSYNC;
473                         trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
474                         if (itv->is_50hz && trace > 312)
475                                 trace -= 312;
476                         else if (itv->is_60hz && trace > 262)
477                                 trace -= 262;
478                         if (trace == 1)
479                                 vblank.flags |= FB_VBLANK_VSYNCING;
480                         vblank.count = itv->last_vsync_field;
481                         vblank.vcount = trace;
482                         vblank.hcount = 0;
483                         if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
484                                 return -EFAULT;
485                         return 0;
486                 }
487
488                 case FBIO_WAITFORVSYNC:
489                         prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
490                         if (!schedule_timeout(msecs_to_jiffies(50)))
491                                 rc = -ETIMEDOUT;
492                         finish_wait(&itv->vsync_waitq, &wait);
493                         return rc;
494
495                 case IVTVFB_IOC_DMA_FRAME: {
496                         struct ivtvfb_dma_frame args;
497
498                         IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
499                         if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
500                                 return -EFAULT;
501
502                         return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
503                 }
504
505                 default:
506                         IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
507                         return -EINVAL;
508         }
509         return 0;
510 }
511
512 /* Framebuffer device handling */
513
514 static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
515 {
516         struct osd_info *oi = itv->osd_info;
517         struct ivtv_osd_coords ivtv_osd;
518         struct v4l2_rect ivtv_window;
519         int osd_mode = -1;
520
521         IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
522
523         /* Select color space */
524         if (var->nonstd) /* YUV */
525                 write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
526         else /* RGB  */
527                 write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
528
529         /* Set the color mode */
530         switch (var->bits_per_pixel) {
531                 case 8:
532                         osd_mode = IVTV_OSD_BPP_8;
533                         break;
534                 case 32:
535                         osd_mode = IVTV_OSD_BPP_32;
536                         break;
537                 case 16:
538                         switch (var->green.length) {
539                         case 4:
540                                 osd_mode = IVTV_OSD_BPP_16_444;
541                                 break;
542                         case 5:
543                                 osd_mode = IVTV_OSD_BPP_16_555;
544                                 break;
545                         case 6:
546                                 osd_mode = IVTV_OSD_BPP_16_565;
547                                 break;
548                         default:
549                                 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
550                         }
551                         break;
552                 default:
553                         IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
554         }
555
556         /* Set video mode. Although rare, the display can become scrambled even
557            if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
558         if (osd_mode != -1) {
559                 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
560                 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
561         }
562
563         oi->bits_per_pixel = var->bits_per_pixel;
564         oi->bytes_per_pixel = var->bits_per_pixel / 8;
565
566         /* Set the flicker filter */
567         switch (var->vmode & FB_VMODE_MASK) {
568                 case FB_VMODE_NONINTERLACED: /* Filter on */
569                         ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
570                         break;
571                 case FB_VMODE_INTERLACED: /* Filter off */
572                         ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
573                         break;
574                 default:
575                         IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
576         }
577
578         /* Read the current osd info */
579         ivtvfb_get_osd_coords(itv, &ivtv_osd);
580
581         /* Now set the OSD to the size we want */
582         ivtv_osd.pixel_stride = var->xres_virtual;
583         ivtv_osd.lines = var->yres_virtual;
584         ivtv_osd.x = 0;
585         ivtv_osd.y = 0;
586         ivtvfb_set_osd_coords(itv, &ivtv_osd);
587
588         /* Can't seem to find the right API combo for this.
589            Use another function which does what we need through direct register access. */
590         ivtv_window.width = var->xres;
591         ivtv_window.height = var->yres;
592
593         /* Minimum margin cannot be 0, as X won't allow such a mode */
594         if (!var->upper_margin)
595                 var->upper_margin++;
596         if (!var->left_margin)
597                 var->left_margin++;
598         ivtv_window.top = var->upper_margin - 1;
599         ivtv_window.left = var->left_margin - 1;
600
601         ivtvfb_set_display_window(itv, &ivtv_window);
602
603         /* Pass screen size back to yuv handler */
604         itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
605         itv->yuv_info.osd_full_h = ivtv_osd.lines;
606
607         /* Force update of yuv registers */
608         itv->yuv_info.yuv_forced_update = 1;
609
610         /* Keep a copy of these settings */
611         memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
612
613         IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
614                       var->xres, var->yres,
615                       var->xres_virtual, var->yres_virtual,
616                       var->bits_per_pixel);
617
618         IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
619                       var->left_margin, var->upper_margin);
620
621         IVTVFB_DEBUG_INFO("Display filter: %s\n",
622                         (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
623         IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
624
625         return 0;
626 }
627
628 static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
629 {
630         struct osd_info *oi = itv->osd_info;
631
632         IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
633         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
634         strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
635         fix->smem_start = oi->video_pbase;
636         fix->smem_len = oi->video_buffer_size;
637         fix->type = FB_TYPE_PACKED_PIXELS;
638         fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
639         fix->xpanstep = 1;
640         fix->ypanstep = 1;
641         fix->ywrapstep = 0;
642         fix->line_length = oi->display_byte_stride;
643         fix->accel = FB_ACCEL_NONE;
644         return 0;
645 }
646
647 /* Check the requested display mode, returning -EINVAL if we can't
648    handle it. */
649
650 static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
651 {
652         struct osd_info *oi = itv->osd_info;
653         int osd_height_limit;
654         u32 pixclock, hlimit, vlimit;
655
656         IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
657
658         /* Set base references for mode calcs. */
659         if (itv->is_50hz) {
660                 pixclock = 84316;
661                 hlimit = 776;
662                 vlimit = 591;
663                 osd_height_limit = 576;
664         }
665         else {
666                 pixclock = 83926;
667                 hlimit = 776;
668                 vlimit = 495;
669                 osd_height_limit = 480;
670         }
671
672         if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
673                 var->transp.offset = 24;
674                 var->transp.length = 8;
675                 var->red.offset = 16;
676                 var->red.length = 8;
677                 var->green.offset = 8;
678                 var->green.length = 8;
679                 var->blue.offset = 0;
680                 var->blue.length = 8;
681         }
682         else if (var->bits_per_pixel == 16) {
683                 /* To find out the true mode, check green length */
684                 switch (var->green.length) {
685                         case 4:
686                                 var->red.offset = 8;
687                                 var->red.length = 4;
688                                 var->green.offset = 4;
689                                 var->green.length = 4;
690                                 var->blue.offset = 0;
691                                 var->blue.length = 4;
692                                 var->transp.offset = 12;
693                                 var->transp.length = 1;
694                                 break;
695                         case 5:
696                                 var->red.offset = 10;
697                                 var->red.length = 5;
698                                 var->green.offset = 5;
699                                 var->green.length = 5;
700                                 var->blue.offset = 0;
701                                 var->blue.length = 5;
702                                 var->transp.offset = 15;
703                                 var->transp.length = 1;
704                                 break;
705                         default:
706                                 var->red.offset = 11;
707                                 var->red.length = 5;
708                                 var->green.offset = 5;
709                                 var->green.length = 6;
710                                 var->blue.offset = 0;
711                                 var->blue.length = 5;
712                                 var->transp.offset = 0;
713                                 var->transp.length = 0;
714                                 break;
715                 }
716         }
717         else {
718                 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
719                 return -EINVAL;
720         }
721
722         /* Check the resolution */
723         if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
724                 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
725                                 var->xres, var->yres);
726                 return -EINVAL;
727         }
728
729         /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
730         if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
731             var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
732             var->xres_virtual < var->xres ||
733             var->yres_virtual < var->yres) {
734                 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
735                         var->xres_virtual, var->yres_virtual);
736                 return -EINVAL;
737         }
738
739         /* Some extra checks if in 8 bit mode */
740         if (var->bits_per_pixel == 8) {
741                 /* Width must be a multiple of 4 */
742                 if (var->xres & 3) {
743                         IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
744                         return -EINVAL;
745                 }
746                 if (var->xres_virtual & 3) {
747                         IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
748                         return -EINVAL;
749                 }
750         }
751         else if (var->bits_per_pixel == 16) {
752                 /* Width must be a multiple of 2 */
753                 if (var->xres & 1) {
754                         IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
755                         return -EINVAL;
756                 }
757                 if (var->xres_virtual & 1) {
758                         IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
759                         return -EINVAL;
760                 }
761         }
762
763         /* Now check the offsets */
764         if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
765                 IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
766                         var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
767                 return -EINVAL;
768         }
769
770         /* Check pixel format */
771         if (var->nonstd > 1) {
772                 IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
773                 return -EINVAL;
774         }
775
776         /* Check video mode */
777         if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
778                 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
779                 IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
780                 return -EINVAL;
781         }
782
783         /* Check the left & upper margins
784            If the margins are too large, just center the screen
785            (enforcing margins causes too many problems) */
786
787         if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) {
788                 var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
789         }
790         if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) {
791                 var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
792         }
793
794         /* Maintain overall 'size' for a constant refresh rate */
795         var->right_margin = hlimit - var->left_margin - var->xres;
796         var->lower_margin = vlimit - var->upper_margin - var->yres;
797
798         /* Fixed sync times */
799         var->hsync_len = 24;
800         var->vsync_len = 2;
801
802         /* Non-interlaced / interlaced mode is used to switch the OSD filter
803            on or off. Adjust the clock timings to maintain a constant
804            vertical refresh rate. */
805         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
806                 var->pixclock = pixclock / 2;
807         else
808                 var->pixclock = pixclock;
809
810         itv->osd_rect.width = var->xres;
811         itv->osd_rect.height = var->yres;
812
813         IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
814                       var->xres, var->yres,
815                       var->xres_virtual, var->yres_virtual,
816                       var->bits_per_pixel);
817
818         IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
819                       var->left_margin, var->upper_margin);
820
821         IVTVFB_DEBUG_INFO("Display filter: %s\n",
822                         (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
823         IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
824         return 0;
825 }
826
827 static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
828 {
829         struct ivtv *itv = (struct ivtv *) info->par;
830         IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
831         return _ivtvfb_check_var(var, itv);
832 }
833
834 static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
835 {
836         u32 osd_pan_index;
837         struct ivtv *itv = (struct ivtv *) info->par;
838
839         osd_pan_index = var->yoffset * info->fix.line_length
840                       + var->xoffset * info->var.bits_per_pixel / 8;
841         write_reg(osd_pan_index, 0x02A0C);
842
843         /* Pass this info back the yuv handler */
844         itv->yuv_info.osd_x_pan = var->xoffset;
845         itv->yuv_info.osd_y_pan = var->yoffset;
846         /* Force update of yuv registers */
847         itv->yuv_info.yuv_forced_update = 1;
848         /* Remember this value */
849         itv->osd_info->pan_cur = osd_pan_index;
850         return 0;
851 }
852
853 static int ivtvfb_set_par(struct fb_info *info)
854 {
855         int rc = 0;
856         struct ivtv *itv = (struct ivtv *) info->par;
857
858         IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
859
860         rc = ivtvfb_set_var(itv, &info->var);
861         ivtvfb_pan_display(&info->var, info);
862         ivtvfb_get_fix(itv, &info->fix);
863         ivtv_firmware_check(itv, "ivtvfb_set_par");
864         return rc;
865 }
866
867 static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
868                                 unsigned blue, unsigned transp,
869                                 struct fb_info *info)
870 {
871         u32 color, *palette;
872         struct ivtv *itv = (struct ivtv *)info->par;
873
874         if (regno >= info->cmap.len)
875                 return -EINVAL;
876
877         color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
878         if (info->var.bits_per_pixel <= 8) {
879                 write_reg(regno, 0x02a30);
880                 write_reg(color, 0x02a34);
881                 itv->osd_info->palette_cur[regno] = color;
882                 return 0;
883         }
884         if (regno >= 16)
885                 return -EINVAL;
886
887         palette = info->pseudo_palette;
888         if (info->var.bits_per_pixel == 16) {
889                 switch (info->var.green.length) {
890                         case 4:
891                                 color = ((red & 0xf000) >> 4) |
892                                         ((green & 0xf000) >> 8) |
893                                         ((blue & 0xf000) >> 12);
894                                 break;
895                         case 5:
896                                 color = ((red & 0xf800) >> 1) |
897                                         ((green & 0xf800) >> 6) |
898                                         ((blue & 0xf800) >> 11);
899                                 break;
900                         case 6:
901                                 color = (red & 0xf800 ) |
902                                         ((green & 0xfc00) >> 5) |
903                                         ((blue & 0xf800) >> 11);
904                                 break;
905                 }
906         }
907         palette[regno] = color;
908         return 0;
909 }
910
911 /* We don't really support blanking. All this does is enable or
912    disable the OSD. */
913 static int ivtvfb_blank(int blank_mode, struct fb_info *info)
914 {
915         struct ivtv *itv = (struct ivtv *)info->par;
916
917         IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
918         switch (blank_mode) {
919         case FB_BLANK_UNBLANK:
920                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
921                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
922                 break;
923         case FB_BLANK_NORMAL:
924         case FB_BLANK_HSYNC_SUSPEND:
925         case FB_BLANK_VSYNC_SUSPEND:
926                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
927                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
928                 break;
929         case FB_BLANK_POWERDOWN:
930                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
931                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
932                 break;
933         }
934         itv->osd_info->blank_cur = blank_mode;
935         return 0;
936 }
937
938 static struct fb_ops ivtvfb_ops = {
939         .owner = THIS_MODULE,
940         .fb_write       = ivtvfb_write,
941         .fb_check_var   = ivtvfb_check_var,
942         .fb_set_par     = ivtvfb_set_par,
943         .fb_setcolreg   = ivtvfb_setcolreg,
944         .fb_fillrect    = cfb_fillrect,
945         .fb_copyarea    = cfb_copyarea,
946         .fb_imageblit   = cfb_imageblit,
947         .fb_cursor      = NULL,
948         .fb_ioctl       = ivtvfb_ioctl,
949         .fb_pan_display = ivtvfb_pan_display,
950         .fb_blank       = ivtvfb_blank,
951 };
952
953 /* Restore hardware after firmware restart */
954 static void ivtvfb_restore(struct ivtv *itv)
955 {
956         struct osd_info *oi = itv->osd_info;
957         int i;
958
959         ivtvfb_set_var(itv, &oi->fbvar_cur);
960         ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
961         for (i = 0; i < 256; i++) {
962                 write_reg(i, 0x02a30);
963                 write_reg(oi->palette_cur[i], 0x02a34);
964         }
965         write_reg(oi->pan_cur, 0x02a0c);
966 }
967
968 /* Initialization */
969
970
971 /* Setup our initial video mode */
972 static int ivtvfb_init_vidmode(struct ivtv *itv)
973 {
974         struct osd_info *oi = itv->osd_info;
975         struct v4l2_rect start_window;
976         int max_height;
977
978         /* Color mode */
979
980         if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
981                 osd_depth = 8;
982         oi->bits_per_pixel = osd_depth;
983         oi->bytes_per_pixel = oi->bits_per_pixel / 8;
984
985         /* Horizontal size & position */
986
987         if (osd_xres > 720)
988                 osd_xres = 720;
989
990         /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
991         if (osd_depth == 8)
992                 osd_xres &= ~3;
993         else if (osd_depth == 16)
994                 osd_xres &= ~1;
995
996         start_window.width = osd_xres ? osd_xres : 640;
997
998         /* Check horizontal start (osd_left). */
999         if (osd_left && osd_left + start_window.width > 721) {
1000                 IVTVFB_ERR("Invalid osd_left - assuming default\n");
1001                 osd_left = 0;
1002         }
1003
1004         /* Hardware coords start at 0, user coords start at 1. */
1005         osd_left--;
1006
1007         start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
1008
1009         oi->display_byte_stride =
1010                         start_window.width * oi->bytes_per_pixel;
1011
1012         /* Vertical size & position */
1013
1014         max_height = itv->is_50hz ? 576 : 480;
1015
1016         if (osd_yres > max_height)
1017                 osd_yres = max_height;
1018
1019         start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
1020
1021         /* Check vertical start (osd_upper). */
1022         if (osd_upper + start_window.height > max_height + 1) {
1023                 IVTVFB_ERR("Invalid osd_upper - assuming default\n");
1024                 osd_upper = 0;
1025         }
1026
1027         /* Hardware coords start at 0, user coords start at 1. */
1028         osd_upper--;
1029
1030         start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1031
1032         oi->display_width = start_window.width;
1033         oi->display_height = start_window.height;
1034
1035         /* Generate a valid fb_var_screeninfo */
1036
1037         oi->ivtvfb_defined.xres = oi->display_width;
1038         oi->ivtvfb_defined.yres = oi->display_height;
1039         oi->ivtvfb_defined.xres_virtual = oi->display_width;
1040         oi->ivtvfb_defined.yres_virtual = oi->display_height;
1041         oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
1042         oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
1043         oi->ivtvfb_defined.left_margin = start_window.left + 1;
1044         oi->ivtvfb_defined.upper_margin = start_window.top + 1;
1045         oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
1046         oi->ivtvfb_defined.nonstd = 0;
1047
1048         /* We've filled in the most data, let the usual mode check
1049            routine fill in the rest. */
1050         _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
1051
1052         /* Generate valid fb_fix_screeninfo */
1053
1054         ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1055
1056         /* Generate valid fb_info */
1057
1058         oi->ivtvfb_info.node = -1;
1059         oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1060         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1061         oi->ivtvfb_info.par = itv;
1062         oi->ivtvfb_info.var = oi->ivtvfb_defined;
1063         oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1064         oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1065         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1066
1067         /* Supply some monitor specs. Bogus values will do for now */
1068         oi->ivtvfb_info.monspecs.hfmin = 8000;
1069         oi->ivtvfb_info.monspecs.hfmax = 70000;
1070         oi->ivtvfb_info.monspecs.vfmin = 10;
1071         oi->ivtvfb_info.monspecs.vfmax = 100;
1072
1073         /* Allocate color map */
1074         if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1075                 IVTVFB_ERR("abort, unable to alloc cmap\n");
1076                 return -ENOMEM;
1077         }
1078
1079         /* Allocate the pseudo palette */
1080         oi->ivtvfb_info.pseudo_palette =
1081                 kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
1082
1083         if (!oi->ivtvfb_info.pseudo_palette) {
1084                 IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
1085                 return -ENOMEM;
1086         }
1087
1088         return 0;
1089 }
1090
1091 /* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
1092
1093 static int ivtvfb_init_io(struct ivtv *itv)
1094 {
1095         struct osd_info *oi = itv->osd_info;
1096
1097         mutex_lock(&itv->serialize_lock);
1098         if (ivtv_init_on_first_open(itv)) {
1099                 mutex_unlock(&itv->serialize_lock);
1100                 IVTVFB_ERR("Failed to initialize ivtv\n");
1101                 return -ENXIO;
1102         }
1103         mutex_unlock(&itv->serialize_lock);
1104
1105         if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1106                                         &oi->video_buffer_size) < 0) {
1107                 IVTVFB_ERR("Firmware failed to respond\n");
1108                 return -EIO;
1109         }
1110
1111         /* The osd buffer size depends on the number of video buffers allocated
1112            on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1113            size to prevent any overlap. */
1114         oi->video_buffer_size = 1704960;
1115
1116         oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1117         oi->video_vbase = itv->dec_mem + oi->video_rbase;
1118
1119         if (!oi->video_vbase) {
1120                 IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1121                      oi->video_buffer_size, oi->video_pbase);
1122                 return -EIO;
1123         }
1124
1125         IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1126                         oi->video_pbase, oi->video_vbase,
1127                         oi->video_buffer_size / 1024);
1128
1129 #ifdef CONFIG_MTRR
1130         {
1131                 /* Find the largest power of two that maps the whole buffer */
1132                 int size_shift = 31;
1133
1134                 while (!(oi->video_buffer_size & (1 << size_shift))) {
1135                         size_shift--;
1136                 }
1137                 size_shift++;
1138                 oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1139                 oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1140                 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1141                 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1142                 if (mtrr_add(oi->fb_start_aligned_physaddr,
1143                         oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
1144                              MTRR_TYPE_WRCOMB, 1) < 0) {
1145                         IVTVFB_INFO("disabled mttr\n");
1146                         oi->fb_start_aligned_physaddr = 0;
1147                         oi->fb_end_aligned_physaddr = 0;
1148                 }
1149         }
1150 #endif
1151
1152         /* Blank the entire osd. */
1153         memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1154
1155         return 0;
1156 }
1157
1158 /* Release any memory we've grabbed & remove mtrr entry */
1159 static void ivtvfb_release_buffers (struct ivtv *itv)
1160 {
1161         struct osd_info *oi = itv->osd_info;
1162
1163         /* Release cmap */
1164         if (oi->ivtvfb_info.cmap.len)
1165                 fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1166
1167         /* Release pseudo palette */
1168         if (oi->ivtvfb_info.pseudo_palette)
1169                 kfree(oi->ivtvfb_info.pseudo_palette);
1170
1171 #ifdef CONFIG_MTRR
1172         if (oi->fb_end_aligned_physaddr) {
1173                 mtrr_del(-1, oi->fb_start_aligned_physaddr,
1174                         oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
1175         }
1176 #endif
1177
1178         kfree(oi);
1179         itv->osd_info = NULL;
1180 }
1181
1182 /* Initialize the specified card */
1183
1184 static int ivtvfb_init_card(struct ivtv *itv)
1185 {
1186         int rc;
1187
1188         if (itv->osd_info) {
1189                 IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1190                 return -EBUSY;
1191         }
1192
1193         itv->osd_info = kzalloc(sizeof(struct osd_info),
1194                                         GFP_ATOMIC|__GFP_NOWARN);
1195         if (itv->osd_info == NULL) {
1196                 IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1197                 return -ENOMEM;
1198         }
1199
1200         /* Find & setup the OSD buffer */
1201         rc = ivtvfb_init_io(itv);
1202         if (rc) {
1203                 ivtvfb_release_buffers(itv);
1204                 return rc;
1205         }
1206
1207         /* Set the startup video mode information */
1208         if ((rc = ivtvfb_init_vidmode(itv))) {
1209                 ivtvfb_release_buffers(itv);
1210                 return rc;
1211         }
1212
1213         /* Register the framebuffer */
1214         if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1215                 ivtvfb_release_buffers(itv);
1216                 return -EINVAL;
1217         }
1218
1219         itv->osd_video_pbase = itv->osd_info->video_pbase;
1220
1221         /* Set the card to the requested mode */
1222         ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1223
1224         /* Set color 0 to black */
1225         write_reg(0, 0x02a30);
1226         write_reg(0, 0x02a34);
1227
1228         /* Enable the osd */
1229         ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1230
1231         /* Enable restart */
1232         itv->ivtvfb_restore = ivtvfb_restore;
1233
1234         /* Allocate DMA */
1235         ivtv_udma_alloc(itv);
1236         return 0;
1237
1238 }
1239
1240 static int __init ivtvfb_callback_init(struct device *dev, void *p)
1241 {
1242         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1243         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1244
1245         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1246                 if (ivtvfb_init_card(itv) == 0) {
1247                         IVTVFB_INFO("Framebuffer registered on %s\n",
1248                                         itv->v4l2_dev.name);
1249                         (*(int *)p)++;
1250                 }
1251         }
1252         return 0;
1253 }
1254
1255 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1256 {
1257         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1258         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1259         struct osd_info *oi = itv->osd_info;
1260
1261         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1262                 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1263                         IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1264                                        itv->instance);
1265                         return 0;
1266                 }
1267                 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1268                 itv->ivtvfb_restore = NULL;
1269                 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1270                 ivtvfb_release_buffers(itv);
1271                 itv->osd_video_pbase = 0;
1272         }
1273         return 0;
1274 }
1275
1276 static int __init ivtvfb_init(void)
1277 {
1278         struct device_driver *drv;
1279         int registered = 0;
1280         int err;
1281
1282         if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1283                 printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1284                      IVTV_MAX_CARDS - 1);
1285                 return -EINVAL;
1286         }
1287
1288         drv = driver_find("ivtv", &pci_bus_type);
1289         err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1290         put_driver(drv);
1291         if (!registered) {
1292                 printk(KERN_ERR "ivtvfb:  no cards found\n");
1293                 return -ENODEV;
1294         }
1295         return 0;
1296 }
1297
1298 static void ivtvfb_cleanup(void)
1299 {
1300         struct device_driver *drv;
1301         int err;
1302
1303         printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
1304
1305         drv = driver_find("ivtv", &pci_bus_type);
1306         err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1307         put_driver(drv);
1308 }
1309
1310 module_init(ivtvfb_init);
1311 module_exit(ivtvfb_cleanup);