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