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