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