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 */
59static int ivtvfb_card_id = -1;
60static int ivtvfb_debug = 0;
61static bool osd_laced;
62static int osd_depth;
63static int osd_upper;
64static int osd_left;
65static int osd_yres;
66static int osd_xres;
67
68module_param(ivtvfb_card_id, int, 0444);
69module_param_named(debug,ivtvfb_debug, int, 0644);
70module_param(osd_laced, bool, 0444);
71module_param(osd_depth, int, 0444);
72module_param(osd_upper, int, 0444);
73module_param(osd_left, int, 0444);
74module_param(osd_yres, int, 0444);
75module_param(osd_xres, int, 0444);
76
77MODULE_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
81MODULE_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
89MODULE_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
95MODULE_PARM_DESC(osd_depth,
96		 "Bits per pixel - 8, 16, 32\n"
97		 "\t\t\tdefault 8");
98
99MODULE_PARM_DESC(osd_upper,
100		 "Vertical start position\n"
101		 "\t\t\tdefault 0 (Centered)");
102
103MODULE_PARM_DESC(osd_left,
104		 "Horizontal start position\n"
105		 "\t\t\tdefault 0 (Centered)");
106
107MODULE_PARM_DESC(osd_yres,
108		 "Display height\n"
109		 "\t\t\tdefault 480 (PAL)\n"
110		 "\t\t\t        400 (NTSC)");
111
112MODULE_PARM_DESC(osd_xres,
113		 "Display width\n"
114		 "\t\t\tdefault 640");
115
116MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
117MODULE_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
148struct 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
190struct 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
203static 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
216static 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
233static 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
248static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
249{
250	int osd_height_limit = itv->is_out_50hz ? 576 : 480;
251
252	/* Only fail if resolution too high, otherwise fudge the start coords. */
253	if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
254		return -EINVAL;
255
256	/* Ensure we don't exceed display limits */
257	if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
258		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
259			ivtv_window->top, ivtv_window->height);
260		ivtv_window->top = osd_height_limit - ivtv_window->height;
261	}
262
263	if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
264		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
265			ivtv_window->left, ivtv_window->width);
266		ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
267	}
268
269	/* Set the OSD origin */
270	write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
271
272	/* How much to display */
273	write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
274
275	/* Pass this info back the yuv handler */
276	itv->yuv_info.osd_vis_w = ivtv_window->width;
277	itv->yuv_info.osd_vis_h = ivtv_window->height;
278	itv->yuv_info.osd_x_offset = ivtv_window->left;
279	itv->yuv_info.osd_y_offset = ivtv_window->top;
280
281	return 0;
282}
283
284static 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
333static 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
381static 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
458static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
459{
460	DEFINE_WAIT(wait);
461	struct ivtv *itv = (struct ivtv *)info->par;
462	int rc = 0;
463
464	switch (cmd) {
465		case FBIOGET_VBLANK: {
466			struct fb_vblank vblank;
467			u32 trace;
468
469			memset(&vblank, 0, sizeof(struct fb_vblank));
470
471			vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
472					FB_VBLANK_HAVE_VSYNC;
473			trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
474			if (itv->is_out_50hz && trace > 312)
475				trace -= 312;
476			else if (itv->is_out_60hz && trace > 262)
477				trace -= 262;
478			if (trace == 1)
479				vblank.flags |= FB_VBLANK_VSYNCING;
480			vblank.count = itv->last_vsync_field;
481			vblank.vcount = trace;
482			vblank.hcount = 0;
483			if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
484				return -EFAULT;
485			return 0;
486		}
487
488		case FBIO_WAITFORVSYNC:
489			prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
490			if (!schedule_timeout(msecs_to_jiffies(50)))
491				rc = -ETIMEDOUT;
492			finish_wait(&itv->vsync_waitq, &wait);
493			return rc;
494
495		case IVTVFB_IOC_DMA_FRAME: {
496			struct ivtvfb_dma_frame args;
497
498			IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
499			if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
500				return -EFAULT;
501
502			return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
503		}
504
505		default:
506			IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
507			return -EINVAL;
508	}
509	return 0;
510}
511
512/* Framebuffer device handling */
513
514static 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
628static 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
650static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
651{
652	struct osd_info *oi = itv->osd_info;
653	int osd_height_limit;
654	u32 pixclock, hlimit, vlimit;
655
656	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
657
658	/* Set base references for mode calcs. */
659	if (itv->is_out_50hz) {
660		pixclock = 84316;
661		hlimit = 776;
662		vlimit = 591;
663		osd_height_limit = 576;
664	}
665	else {
666		pixclock = 83926;
667		hlimit = 776;
668		vlimit = 495;
669		osd_height_limit = 480;
670	}
671
672	if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
673		var->transp.offset = 24;
674		var->transp.length = 8;
675		var->red.offset = 16;
676		var->red.length = 8;
677		var->green.offset = 8;
678		var->green.length = 8;
679		var->blue.offset = 0;
680		var->blue.length = 8;
681	}
682	else if (var->bits_per_pixel == 16) {
683		/* To find out the true mode, check green length */
684		switch (var->green.length) {
685			case 4:
686				var->red.offset = 8;
687				var->red.length = 4;
688				var->green.offset = 4;
689				var->green.length = 4;
690				var->blue.offset = 0;
691				var->blue.length = 4;
692				var->transp.offset = 12;
693				var->transp.length = 1;
694				break;
695			case 5:
696				var->red.offset = 10;
697				var->red.length = 5;
698				var->green.offset = 5;
699				var->green.length = 5;
700				var->blue.offset = 0;
701				var->blue.length = 5;
702				var->transp.offset = 15;
703				var->transp.length = 1;
704				break;
705			default:
706				var->red.offset = 11;
707				var->red.length = 5;
708				var->green.offset = 5;
709				var->green.length = 6;
710				var->blue.offset = 0;
711				var->blue.length = 5;
712				var->transp.offset = 0;
713				var->transp.length = 0;
714				break;
715		}
716	}
717	else {
718		IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
719		return -EINVAL;
720	}
721
722	/* Check the resolution */
723	if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
724		IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
725				var->xres, var->yres);
726		return -EINVAL;
727	}
728
729	/* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
730	if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
731	    var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
732	    var->xres_virtual < var->xres ||
733	    var->yres_virtual < var->yres) {
734		IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
735			var->xres_virtual, var->yres_virtual);
736		return -EINVAL;
737	}
738
739	/* Some extra checks if in 8 bit mode */
740	if (var->bits_per_pixel == 8) {
741		/* Width must be a multiple of 4 */
742		if (var->xres & 3) {
743			IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
744			return -EINVAL;
745		}
746		if (var->xres_virtual & 3) {
747			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
748			return -EINVAL;
749		}
750	}
751	else if (var->bits_per_pixel == 16) {
752		/* Width must be a multiple of 2 */
753		if (var->xres & 1) {
754			IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
755			return -EINVAL;
756		}
757		if (var->xres_virtual & 1) {
758			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
759			return -EINVAL;
760		}
761	}
762
763	/* Now check the offsets */
764	if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
765		IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
766			var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
767		return -EINVAL;
768	}
769
770	/* Check pixel format */
771	if (var->nonstd > 1) {
772		IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
773		return -EINVAL;
774	}
775
776	/* Check video mode */
777	if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
778		((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
779		IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
780		return -EINVAL;
781	}
782
783	/* Check the left & upper margins
784	   If the margins are too large, just center the screen
785	   (enforcing margins causes too many problems) */
786
787	if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
788		var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
789
790	if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
791		var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
792			var->yres) / 2);
793
794	/* Maintain overall 'size' for a constant refresh rate */
795	var->right_margin = hlimit - var->left_margin - var->xres;
796	var->lower_margin = vlimit - var->upper_margin - var->yres;
797
798	/* Fixed sync times */
799	var->hsync_len = 24;
800	var->vsync_len = 2;
801
802	/* Non-interlaced / interlaced mode is used to switch the OSD filter
803	   on or off. Adjust the clock timings to maintain a constant
804	   vertical refresh rate. */
805	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
806		var->pixclock = pixclock / 2;
807	else
808		var->pixclock = pixclock;
809
810	itv->osd_rect.width = var->xres;
811	itv->osd_rect.height = var->yres;
812
813	IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
814		      var->xres, var->yres,
815		      var->xres_virtual, var->yres_virtual,
816		      var->bits_per_pixel);
817
818	IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
819		      var->left_margin, var->upper_margin);
820
821	IVTVFB_DEBUG_INFO("Display filter: %s\n",
822			(var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
823	IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
824	return 0;
825}
826
827static 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
834static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
835{
836	u32 osd_pan_index;
837	struct ivtv *itv = (struct ivtv *) info->par;
838
839	if (var->yoffset + info->var.yres > info->var.yres_virtual ||
840	    var->xoffset + info->var.xres > info->var.xres_virtual)
841		return -EINVAL;
842
843	osd_pan_index = var->yoffset * info->fix.line_length
844		      + var->xoffset * info->var.bits_per_pixel / 8;
845	write_reg(osd_pan_index, 0x02A0C);
846
847	/* Pass this info back the yuv handler */
848	itv->yuv_info.osd_x_pan = var->xoffset;
849	itv->yuv_info.osd_y_pan = var->yoffset;
850	/* Force update of yuv registers */
851	itv->yuv_info.yuv_forced_update = 1;
852	/* Remember this value */
853	itv->osd_info->pan_cur = osd_pan_index;
854	return 0;
855}
856
857static int ivtvfb_set_par(struct fb_info *info)
858{
859	int rc = 0;
860	struct ivtv *itv = (struct ivtv *) info->par;
861
862	IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
863
864	rc = ivtvfb_set_var(itv, &info->var);
865	ivtvfb_pan_display(&info->var, info);
866	ivtvfb_get_fix(itv, &info->fix);
867	ivtv_firmware_check(itv, "ivtvfb_set_par");
868	return rc;
869}
870
871static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
872				unsigned blue, unsigned transp,
873				struct fb_info *info)
874{
875	u32 color, *palette;
876	struct ivtv *itv = (struct ivtv *)info->par;
877
878	if (regno >= info->cmap.len)
879		return -EINVAL;
880
881	color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
882	if (info->var.bits_per_pixel <= 8) {
883		write_reg(regno, 0x02a30);
884		write_reg(color, 0x02a34);
885		itv->osd_info->palette_cur[regno] = color;
886		return 0;
887	}
888	if (regno >= 16)
889		return -EINVAL;
890
891	palette = info->pseudo_palette;
892	if (info->var.bits_per_pixel == 16) {
893		switch (info->var.green.length) {
894			case 4:
895				color = ((red & 0xf000) >> 4) |
896					((green & 0xf000) >> 8) |
897					((blue & 0xf000) >> 12);
898				break;
899			case 5:
900				color = ((red & 0xf800) >> 1) |
901					((green & 0xf800) >> 6) |
902					((blue & 0xf800) >> 11);
903				break;
904			case 6:
905				color = (red & 0xf800 ) |
906					((green & 0xfc00) >> 5) |
907					((blue & 0xf800) >> 11);
908				break;
909		}
910	}
911	palette[regno] = color;
912	return 0;
913}
914
915/* We don't really support blanking. All this does is enable or
916   disable the OSD. */
917static int ivtvfb_blank(int blank_mode, struct fb_info *info)
918{
919	struct ivtv *itv = (struct ivtv *)info->par;
920
921	IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
922	switch (blank_mode) {
923	case FB_BLANK_UNBLANK:
924		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
925		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
926		break;
927	case FB_BLANK_NORMAL:
928	case FB_BLANK_HSYNC_SUSPEND:
929	case FB_BLANK_VSYNC_SUSPEND:
930		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
931		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
932		break;
933	case FB_BLANK_POWERDOWN:
934		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
935		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
936		break;
937	}
938	itv->osd_info->blank_cur = blank_mode;
939	return 0;
940}
941
942static struct fb_ops ivtvfb_ops = {
943	.owner = THIS_MODULE,
944	.fb_write       = ivtvfb_write,
945	.fb_check_var   = ivtvfb_check_var,
946	.fb_set_par     = ivtvfb_set_par,
947	.fb_setcolreg   = ivtvfb_setcolreg,
948	.fb_fillrect    = cfb_fillrect,
949	.fb_copyarea    = cfb_copyarea,
950	.fb_imageblit   = cfb_imageblit,
951	.fb_cursor      = NULL,
952	.fb_ioctl       = ivtvfb_ioctl,
953	.fb_pan_display = ivtvfb_pan_display,
954	.fb_blank       = ivtvfb_blank,
955};
956
957/* Restore hardware after firmware restart */
958static void ivtvfb_restore(struct ivtv *itv)
959{
960	struct osd_info *oi = itv->osd_info;
961	int i;
962
963	ivtvfb_set_var(itv, &oi->fbvar_cur);
964	ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
965	for (i = 0; i < 256; i++) {
966		write_reg(i, 0x02a30);
967		write_reg(oi->palette_cur[i], 0x02a34);
968	}
969	write_reg(oi->pan_cur, 0x02a0c);
970}
971
972/* Initialization */
973
974
975/* Setup our initial video mode */
976static int ivtvfb_init_vidmode(struct ivtv *itv)
977{
978	struct osd_info *oi = itv->osd_info;
979	struct v4l2_rect start_window;
980	int max_height;
981
982	/* Color mode */
983
984	if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
985		osd_depth = 8;
986	oi->bits_per_pixel = osd_depth;
987	oi->bytes_per_pixel = oi->bits_per_pixel / 8;
988
989	/* Horizontal size & position */
990
991	if (osd_xres > 720)
992		osd_xres = 720;
993
994	/* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
995	if (osd_depth == 8)
996		osd_xres &= ~3;
997	else if (osd_depth == 16)
998		osd_xres &= ~1;
999
1000	start_window.width = osd_xres ? osd_xres : 640;
1001
1002	/* Check horizontal start (osd_left). */
1003	if (osd_left && osd_left + start_window.width > 721) {
1004		IVTVFB_ERR("Invalid osd_left - assuming default\n");
1005		osd_left = 0;
1006	}
1007
1008	/* Hardware coords start at 0, user coords start at 1. */
1009	osd_left--;
1010
1011	start_window.left = osd_left >= 0 ?
1012		 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
1013
1014	oi->display_byte_stride =
1015			start_window.width * oi->bytes_per_pixel;
1016
1017	/* Vertical size & position */
1018
1019	max_height = itv->is_out_50hz ? 576 : 480;
1020
1021	if (osd_yres > max_height)
1022		osd_yres = max_height;
1023
1024	start_window.height = osd_yres ?
1025		osd_yres : itv->is_out_50hz ? 480 : 400;
1026
1027	/* Check vertical start (osd_upper). */
1028	if (osd_upper + start_window.height > max_height + 1) {
1029		IVTVFB_ERR("Invalid osd_upper - assuming default\n");
1030		osd_upper = 0;
1031	}
1032
1033	/* Hardware coords start at 0, user coords start at 1. */
1034	osd_upper--;
1035
1036	start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1037
1038	oi->display_width = start_window.width;
1039	oi->display_height = start_window.height;
1040
1041	/* Generate a valid fb_var_screeninfo */
1042
1043	oi->ivtvfb_defined.xres = oi->display_width;
1044	oi->ivtvfb_defined.yres = oi->display_height;
1045	oi->ivtvfb_defined.xres_virtual = oi->display_width;
1046	oi->ivtvfb_defined.yres_virtual = oi->display_height;
1047	oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
1048	oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
1049	oi->ivtvfb_defined.left_margin = start_window.left + 1;
1050	oi->ivtvfb_defined.upper_margin = start_window.top + 1;
1051	oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
1052	oi->ivtvfb_defined.nonstd = 0;
1053
1054	/* We've filled in the most data, let the usual mode check
1055	   routine fill in the rest. */
1056	_ivtvfb_check_var(&oi->ivtvfb_defined, itv);
1057
1058	/* Generate valid fb_fix_screeninfo */
1059
1060	ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1061
1062	/* Generate valid fb_info */
1063
1064	oi->ivtvfb_info.node = -1;
1065	oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1066	oi->ivtvfb_info.fbops = &ivtvfb_ops;
1067	oi->ivtvfb_info.par = itv;
1068	oi->ivtvfb_info.var = oi->ivtvfb_defined;
1069	oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1070	oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1071	oi->ivtvfb_info.fbops = &ivtvfb_ops;
1072
1073	/* Supply some monitor specs. Bogus values will do for now */
1074	oi->ivtvfb_info.monspecs.hfmin = 8000;
1075	oi->ivtvfb_info.monspecs.hfmax = 70000;
1076	oi->ivtvfb_info.monspecs.vfmin = 10;
1077	oi->ivtvfb_info.monspecs.vfmax = 100;
1078
1079	/* Allocate color map */
1080	if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1081		IVTVFB_ERR("abort, unable to alloc cmap\n");
1082		return -ENOMEM;
1083	}
1084
1085	/* Allocate the pseudo palette */
1086	oi->ivtvfb_info.pseudo_palette =
1087		kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
1088
1089	if (!oi->ivtvfb_info.pseudo_palette) {
1090		IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
1091		return -ENOMEM;
1092	}
1093
1094	return 0;
1095}
1096
1097/* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
1098
1099static int ivtvfb_init_io(struct ivtv *itv)
1100{
1101	struct osd_info *oi = itv->osd_info;
1102
1103	mutex_lock(&itv->serialize_lock);
1104	if (ivtv_init_on_first_open(itv)) {
1105		mutex_unlock(&itv->serialize_lock);
1106		IVTVFB_ERR("Failed to initialize ivtv\n");
1107		return -ENXIO;
1108	}
1109	mutex_unlock(&itv->serialize_lock);
1110
1111	if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1112					&oi->video_buffer_size) < 0) {
1113		IVTVFB_ERR("Firmware failed to respond\n");
1114		return -EIO;
1115	}
1116
1117	/* The osd buffer size depends on the number of video buffers allocated
1118	   on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1119	   size to prevent any overlap. */
1120	oi->video_buffer_size = 1704960;
1121
1122	oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1123	oi->video_vbase = itv->dec_mem + oi->video_rbase;
1124
1125	if (!oi->video_vbase) {
1126		IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1127		     oi->video_buffer_size, oi->video_pbase);
1128		return -EIO;
1129	}
1130
1131	IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1132			oi->video_pbase, oi->video_vbase,
1133			oi->video_buffer_size / 1024);
1134
1135#ifdef CONFIG_MTRR
1136	{
1137		/* Find the largest power of two that maps the whole buffer */
1138		int size_shift = 31;
1139
1140		while (!(oi->video_buffer_size & (1 << size_shift))) {
1141			size_shift--;
1142		}
1143		size_shift++;
1144		oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1145		oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1146		oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1147		oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1148		if (mtrr_add(oi->fb_start_aligned_physaddr,
1149			oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
1150			     MTRR_TYPE_WRCOMB, 1) < 0) {
1151			IVTVFB_INFO("disabled mttr\n");
1152			oi->fb_start_aligned_physaddr = 0;
1153			oi->fb_end_aligned_physaddr = 0;
1154		}
1155	}
1156#endif
1157
1158	/* Blank the entire osd. */
1159	memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1160
1161	return 0;
1162}
1163
1164/* Release any memory we've grabbed & remove mtrr entry */
1165static void ivtvfb_release_buffers (struct ivtv *itv)
1166{
1167	struct osd_info *oi = itv->osd_info;
1168
1169	/* Release cmap */
1170	if (oi->ivtvfb_info.cmap.len)
1171		fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1172
1173	/* Release pseudo palette */
1174	if (oi->ivtvfb_info.pseudo_palette)
1175		kfree(oi->ivtvfb_info.pseudo_palette);
1176
1177#ifdef CONFIG_MTRR
1178	if (oi->fb_end_aligned_physaddr) {
1179		mtrr_del(-1, oi->fb_start_aligned_physaddr,
1180			oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
1181	}
1182#endif
1183
1184	kfree(oi);
1185	itv->osd_info = NULL;
1186}
1187
1188/* Initialize the specified card */
1189
1190static int ivtvfb_init_card(struct ivtv *itv)
1191{
1192	int rc;
1193
1194	if (itv->osd_info) {
1195		IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1196		return -EBUSY;
1197	}
1198
1199	itv->osd_info = kzalloc(sizeof(struct osd_info),
1200					GFP_ATOMIC|__GFP_NOWARN);
1201	if (itv->osd_info == NULL) {
1202		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1203		return -ENOMEM;
1204	}
1205
1206	/* Find & setup the OSD buffer */
1207	rc = ivtvfb_init_io(itv);
1208	if (rc) {
1209		ivtvfb_release_buffers(itv);
1210		return rc;
1211	}
1212
1213	/* Set the startup video mode information */
1214	if ((rc = ivtvfb_init_vidmode(itv))) {
1215		ivtvfb_release_buffers(itv);
1216		return rc;
1217	}
1218
1219	/* Register the framebuffer */
1220	if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1221		ivtvfb_release_buffers(itv);
1222		return -EINVAL;
1223	}
1224
1225	itv->osd_video_pbase = itv->osd_info->video_pbase;
1226
1227	/* Set the card to the requested mode */
1228	ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1229
1230	/* Set color 0 to black */
1231	write_reg(0, 0x02a30);
1232	write_reg(0, 0x02a34);
1233
1234	/* Enable the osd */
1235	ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1236
1237	/* Enable restart */
1238	itv->ivtvfb_restore = ivtvfb_restore;
1239
1240	/* Allocate DMA */
1241	ivtv_udma_alloc(itv);
1242	return 0;
1243
1244}
1245
1246static int __init ivtvfb_callback_init(struct device *dev, void *p)
1247{
1248	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1249	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1250
1251	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1252		if (ivtvfb_init_card(itv) == 0) {
1253			IVTVFB_INFO("Framebuffer registered on %s\n",
1254					itv->v4l2_dev.name);
1255			(*(int *)p)++;
1256		}
1257	}
1258	return 0;
1259}
1260
1261static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1262{
1263	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1264	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1265	struct osd_info *oi = itv->osd_info;
1266
1267	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1268		if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1269			IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1270				       itv->instance);
1271			return 0;
1272		}
1273		IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1274		itv->ivtvfb_restore = NULL;
1275		ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1276		ivtvfb_release_buffers(itv);
1277		itv->osd_video_pbase = 0;
1278	}
1279	return 0;
1280}
1281
1282static int __init ivtvfb_init(void)
1283{
1284	struct device_driver *drv;
1285	int registered = 0;
1286	int err;
1287
1288	if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1289		printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1290		     IVTV_MAX_CARDS - 1);
1291		return -EINVAL;
1292	}
1293
1294	drv = driver_find("ivtv", &pci_bus_type);
1295	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1296	if (!registered) {
1297		printk(KERN_ERR "ivtvfb:  no cards found\n");
1298		return -ENODEV;
1299	}
1300	return 0;
1301}
1302
1303static void ivtvfb_cleanup(void)
1304{
1305	struct device_driver *drv;
1306	int err;
1307
1308	printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
1309
1310	drv = driver_find("ivtv", &pci_bus_type);
1311	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1312}
1313
1314module_init(ivtvfb_init);
1315module_exit(ivtvfb_cleanup);
1316