Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[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                         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_50hz && trace > 312)
475                                 trace -= 312;
476                         else if (itv->is_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_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_50hz ? 577 : 481)) {
791                 var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
792         }
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         osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8;
840         write_reg(osd_pan_index, 0x02A0C);
841
842         /* Pass this info back the yuv handler */
843         itv->yuv_info.osd_x_pan = var->xoffset;
844         itv->yuv_info.osd_y_pan = var->yoffset;
845         /* Force update of yuv registers */
846         itv->yuv_info.yuv_forced_update = 1;
847         /* Remember this value */
848         itv->osd_info->pan_cur = osd_pan_index;
849         return 0;
850 }
851
852 static int ivtvfb_set_par(struct fb_info *info)
853 {
854         int rc = 0;
855         struct ivtv *itv = (struct ivtv *) info->par;
856
857         IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
858
859         rc = ivtvfb_set_var(itv, &info->var);
860         ivtvfb_pan_display(&info->var, info);
861         ivtvfb_get_fix(itv, &info->fix);
862         ivtv_firmware_check(itv, "ivtvfb_set_par");
863         return rc;
864 }
865
866 static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
867                                 unsigned blue, unsigned transp,
868                                 struct fb_info *info)
869 {
870         u32 color, *palette;
871         struct ivtv *itv = (struct ivtv *)info->par;
872
873         if (regno >= info->cmap.len)
874                 return -EINVAL;
875
876         color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
877         if (info->var.bits_per_pixel <= 8) {
878                 write_reg(regno, 0x02a30);
879                 write_reg(color, 0x02a34);
880                 itv->osd_info->palette_cur[regno] = color;
881                 return 0;
882         }
883         if (regno >= 16)
884                 return -EINVAL;
885
886         palette = info->pseudo_palette;
887         if (info->var.bits_per_pixel == 16) {
888                 switch (info->var.green.length) {
889                         case 4:
890                                 color = ((red & 0xf000) >> 4) |
891                                         ((green & 0xf000) >> 8) |
892                                         ((blue & 0xf000) >> 12);
893                                 break;
894                         case 5:
895                                 color = ((red & 0xf800) >> 1) |
896                                         ((green & 0xf800) >> 6) |
897                                         ((blue & 0xf800) >> 11);
898                                 break;
899                         case 6:
900                                 color = (red & 0xf800 ) |
901                                         ((green & 0xfc00) >> 5) |
902                                         ((blue & 0xf800) >> 11);
903                                 break;
904                 }
905         }
906         palette[regno] = color;
907         return 0;
908 }
909
910 /* We don't really support blanking. All this does is enable or
911    disable the OSD. */
912 static int ivtvfb_blank(int blank_mode, struct fb_info *info)
913 {
914         struct ivtv *itv = (struct ivtv *)info->par;
915
916         IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
917         switch (blank_mode) {
918         case FB_BLANK_UNBLANK:
919                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
920                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
921                 break;
922         case FB_BLANK_NORMAL:
923         case FB_BLANK_HSYNC_SUSPEND:
924         case FB_BLANK_VSYNC_SUSPEND:
925                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
926                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
927                 break;
928         case FB_BLANK_POWERDOWN:
929                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
930                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
931                 break;
932         }
933         itv->osd_info->blank_cur = blank_mode;
934         return 0;
935 }
936
937 static struct fb_ops ivtvfb_ops = {
938         .owner = THIS_MODULE,
939         .fb_write       = ivtvfb_write,
940         .fb_check_var   = ivtvfb_check_var,
941         .fb_set_par     = ivtvfb_set_par,
942         .fb_setcolreg   = ivtvfb_setcolreg,
943         .fb_fillrect    = cfb_fillrect,
944         .fb_copyarea    = cfb_copyarea,
945         .fb_imageblit   = cfb_imageblit,
946         .fb_cursor      = NULL,
947         .fb_ioctl       = ivtvfb_ioctl,
948         .fb_pan_display = ivtvfb_pan_display,
949         .fb_blank       = ivtvfb_blank,
950 };
951
952 /* Restore hardware after firmware restart */
953 static void ivtvfb_restore(struct ivtv *itv)
954 {
955         struct osd_info *oi = itv->osd_info;
956         int i;
957
958         ivtvfb_set_var(itv, &oi->fbvar_cur);
959         ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
960         for (i = 0; i < 256; i++) {
961                 write_reg(i, 0x02a30);
962                 write_reg(oi->palette_cur[i], 0x02a34);
963         }
964         write_reg(oi->pan_cur, 0x02a0c);
965 }
966
967 /* Initialization */
968
969
970 /* Setup our initial video mode */
971 static int ivtvfb_init_vidmode(struct ivtv *itv)
972 {
973         struct osd_info *oi = itv->osd_info;
974         struct v4l2_rect start_window;
975         int max_height;
976
977         /* Color mode */
978
979         if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
980                 osd_depth = 8;
981         oi->bits_per_pixel = osd_depth;
982         oi->bytes_per_pixel = oi->bits_per_pixel / 8;
983
984         /* Horizontal size & position */
985
986         if (osd_xres > 720)
987                 osd_xres = 720;
988
989         /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
990         if (osd_depth == 8)
991                 osd_xres &= ~3;
992         else if (osd_depth == 16)
993                 osd_xres &= ~1;
994
995         start_window.width = osd_xres ? osd_xres : 640;
996
997         /* Check horizontal start (osd_left). */
998         if (osd_left && osd_left + start_window.width > 721) {
999                 IVTVFB_ERR("Invalid osd_left - assuming default\n");
1000                 osd_left = 0;
1001         }
1002
1003         /* Hardware coords start at 0, user coords start at 1. */
1004         osd_left--;
1005
1006         start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
1007
1008         oi->display_byte_stride =
1009                         start_window.width * oi->bytes_per_pixel;
1010
1011         /* Vertical size & position */
1012
1013         max_height = itv->is_50hz ? 576 : 480;
1014
1015         if (osd_yres > max_height)
1016                 osd_yres = max_height;
1017
1018         start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
1019
1020         /* Check vertical start (osd_upper). */
1021         if (osd_upper + start_window.height > max_height + 1) {
1022                 IVTVFB_ERR("Invalid osd_upper - assuming default\n");
1023                 osd_upper = 0;
1024         }
1025
1026         /* Hardware coords start at 0, user coords start at 1. */
1027         osd_upper--;
1028
1029         start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1030
1031         oi->display_width = start_window.width;
1032         oi->display_height = start_window.height;
1033
1034         /* Generate a valid fb_var_screeninfo */
1035
1036         oi->ivtvfb_defined.xres = oi->display_width;
1037         oi->ivtvfb_defined.yres = oi->display_height;
1038         oi->ivtvfb_defined.xres_virtual = oi->display_width;
1039         oi->ivtvfb_defined.yres_virtual = oi->display_height;
1040         oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
1041         oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
1042         oi->ivtvfb_defined.left_margin = start_window.left + 1;
1043         oi->ivtvfb_defined.upper_margin = start_window.top + 1;
1044         oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
1045         oi->ivtvfb_defined.nonstd = 0;
1046
1047         /* We've filled in the most data, let the usual mode check
1048            routine fill in the rest. */
1049         _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
1050
1051         /* Generate valid fb_fix_screeninfo */
1052
1053         ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1054
1055         /* Generate valid fb_info */
1056
1057         oi->ivtvfb_info.node = -1;
1058         oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1059         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1060         oi->ivtvfb_info.par = itv;
1061         oi->ivtvfb_info.var = oi->ivtvfb_defined;
1062         oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1063         oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1064         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1065
1066         /* Supply some monitor specs. Bogus values will do for now */
1067         oi->ivtvfb_info.monspecs.hfmin = 8000;
1068         oi->ivtvfb_info.monspecs.hfmax = 70000;
1069         oi->ivtvfb_info.monspecs.vfmin = 10;
1070         oi->ivtvfb_info.monspecs.vfmax = 100;
1071
1072         /* Allocate color map */
1073         if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1074                 IVTVFB_ERR("abort, unable to alloc cmap\n");
1075                 return -ENOMEM;
1076         }
1077
1078         /* Allocate the pseudo palette */
1079         oi->ivtvfb_info.pseudo_palette =
1080                 kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
1081
1082         if (!oi->ivtvfb_info.pseudo_palette) {
1083                 IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
1084                 return -ENOMEM;
1085         }
1086
1087         return 0;
1088 }
1089
1090 /* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
1091
1092 static int ivtvfb_init_io(struct ivtv *itv)
1093 {
1094         struct osd_info *oi = itv->osd_info;
1095
1096         mutex_lock(&itv->serialize_lock);
1097         if (ivtv_init_on_first_open(itv)) {
1098                 mutex_unlock(&itv->serialize_lock);
1099                 IVTVFB_ERR("Failed to initialize ivtv\n");
1100                 return -ENXIO;
1101         }
1102         mutex_unlock(&itv->serialize_lock);
1103
1104         if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1105                                         &oi->video_buffer_size) < 0) {
1106                 IVTVFB_ERR("Firmware failed to respond\n");
1107                 return -EIO;
1108         }
1109
1110         /* The osd buffer size depends on the number of video buffers allocated
1111            on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1112            size to prevent any overlap. */
1113         oi->video_buffer_size = 1704960;
1114
1115         oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1116         oi->video_vbase = itv->dec_mem + oi->video_rbase;
1117
1118         if (!oi->video_vbase) {
1119                 IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1120                      oi->video_buffer_size, oi->video_pbase);
1121                 return -EIO;
1122         }
1123
1124         IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1125                         oi->video_pbase, oi->video_vbase,
1126                         oi->video_buffer_size / 1024);
1127
1128 #ifdef CONFIG_MTRR
1129         {
1130                 /* Find the largest power of two that maps the whole buffer */
1131                 int size_shift = 31;
1132
1133                 while (!(oi->video_buffer_size & (1 << size_shift))) {
1134                         size_shift--;
1135                 }
1136                 size_shift++;
1137                 oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1138                 oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1139                 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1140                 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1141                 if (mtrr_add(oi->fb_start_aligned_physaddr,
1142                         oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
1143                              MTRR_TYPE_WRCOMB, 1) < 0) {
1144                         IVTVFB_INFO("disabled mttr\n");
1145                         oi->fb_start_aligned_physaddr = 0;
1146                         oi->fb_end_aligned_physaddr = 0;
1147                 }
1148         }
1149 #endif
1150
1151         /* Blank the entire osd. */
1152         memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1153
1154         return 0;
1155 }
1156
1157 /* Release any memory we've grabbed & remove mtrr entry */
1158 static void ivtvfb_release_buffers (struct ivtv *itv)
1159 {
1160         struct osd_info *oi = itv->osd_info;
1161
1162         /* Release cmap */
1163         if (oi->ivtvfb_info.cmap.len)
1164                 fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1165
1166         /* Release pseudo palette */
1167         if (oi->ivtvfb_info.pseudo_palette)
1168                 kfree(oi->ivtvfb_info.pseudo_palette);
1169
1170 #ifdef CONFIG_MTRR
1171         if (oi->fb_end_aligned_physaddr) {
1172                 mtrr_del(-1, oi->fb_start_aligned_physaddr,
1173                         oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
1174         }
1175 #endif
1176
1177         kfree(oi);
1178         itv->osd_info = NULL;
1179 }
1180
1181 /* Initialize the specified card */
1182
1183 static int ivtvfb_init_card(struct ivtv *itv)
1184 {
1185         int rc;
1186
1187         if (itv->osd_info) {
1188                 IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1189                 return -EBUSY;
1190         }
1191
1192         itv->osd_info = kzalloc(sizeof(struct osd_info),
1193                                         GFP_ATOMIC|__GFP_NOWARN);
1194         if (itv->osd_info == NULL) {
1195                 IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1196                 return -ENOMEM;
1197         }
1198
1199         /* Find & setup the OSD buffer */
1200         rc = ivtvfb_init_io(itv);
1201         if (rc) {
1202                 ivtvfb_release_buffers(itv);
1203                 return rc;
1204         }
1205
1206         /* Set the startup video mode information */
1207         if ((rc = ivtvfb_init_vidmode(itv))) {
1208                 ivtvfb_release_buffers(itv);
1209                 return rc;
1210         }
1211
1212         /* Register the framebuffer */
1213         if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1214                 ivtvfb_release_buffers(itv);
1215                 return -EINVAL;
1216         }
1217
1218         itv->osd_video_pbase = itv->osd_info->video_pbase;
1219
1220         /* Set the card to the requested mode */
1221         ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1222
1223         /* Set color 0 to black */
1224         write_reg(0, 0x02a30);
1225         write_reg(0, 0x02a34);
1226
1227         /* Enable the osd */
1228         ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1229
1230         /* Enable restart */
1231         itv->ivtvfb_restore = ivtvfb_restore;
1232
1233         /* Allocate DMA */
1234         ivtv_udma_alloc(itv);
1235         return 0;
1236
1237 }
1238
1239 static int __init ivtvfb_callback_init(struct device *dev, void *p)
1240 {
1241         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1242         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1243
1244         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1245                 if (ivtvfb_init_card(itv) == 0) {
1246                         IVTVFB_INFO("Framebuffer registered on %s\n",
1247                                         itv->v4l2_dev.name);
1248                         (*(int *)p)++;
1249                 }
1250         }
1251         return 0;
1252 }
1253
1254 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1255 {
1256         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1257         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1258         struct osd_info *oi = itv->osd_info;
1259
1260         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1261                 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1262                         IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1263                                        itv->instance);
1264                         return 0;
1265                 }
1266                 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1267                 itv->ivtvfb_restore = NULL;
1268                 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1269                 ivtvfb_release_buffers(itv);
1270                 itv->osd_video_pbase = 0;
1271         }
1272         return 0;
1273 }
1274
1275 static int __init ivtvfb_init(void)
1276 {
1277         struct device_driver *drv;
1278         int registered = 0;
1279         int err;
1280
1281         if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1282                 printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1283                      IVTV_MAX_CARDS - 1);
1284                 return -EINVAL;
1285         }
1286
1287         drv = driver_find("ivtv", &pci_bus_type);
1288         err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1289         put_driver(drv);
1290         if (!registered) {
1291                 printk(KERN_ERR "ivtvfb:  no cards found\n");
1292                 return -ENODEV;
1293         }
1294         return 0;
1295 }
1296
1297 static void ivtvfb_cleanup(void)
1298 {
1299         struct device_driver *drv;
1300         int err;
1301
1302         printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
1303
1304         drv = driver_find("ivtv", &pci_bus_type);
1305         err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1306         put_driver(drv);
1307 }
1308
1309 module_init(ivtvfb_init);
1310 module_exit(ivtvfb_cleanup);