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