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