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