/*
On Screen Display cx23415 Framebuffer driver
This module presents the cx23415 OSD (onscreen display) framebuffer memory
as a standard Linux /dev/fb style framebuffer device. The framebuffer has
support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
local alpha. The colorspace is selectable between rgb & yuv.
Depending on the TV standard configured in the ivtv module at load time,
the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
or 59.94 (NTSC)
Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
Derived from drivers/video/vesafb.c
Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
2.6 kernel port:
Copyright (C) 2004 Matthias Badaire
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
Copyright (C) 2006 Ian Armstrong <ian@iarmst.demon.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fb.h>
#include <linux/ivtvfb.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "ivtv-driver.h"
#include "ivtv-udma.h"
#include "ivtv-mailbox.h"
/* card parameters */
static int ivtvfb_card_id = -1;
static int ivtvfb_debug = 0;
static int osd_laced;
static int osd_depth;
static int osd_upper;
static int osd_left;
static int osd_yres;
static int osd_xres;
module_param(ivtvfb_card_id, int, 0444);
module_param_named(debug,ivtvfb_debug, int, 0644);
module_param(osd_laced, bool, 0444);
module_param(osd_depth, int, 0444);
module_param(osd_upper, int, 0444);
module_param(osd_left, int, 0444);
module_param(osd_yres, int, 0444);
module_param(osd_xres, int, 0444);
MODULE_PARM_DESC(ivtvfb_card_id,
"Only use framebuffer of the specified ivtv card (0-31)\n"
"\t\t\tdefault -1: initialize all available framebuffers");
MODULE_PARM_DESC(debug,
"Debug level (bitmask). Default: errors only\n"
"\t\t\t(debug = 3 gives full debugging)");
/* Why upper, left, xres, yres, depth, laced ? To match terminology used
by fbset.
Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
MODULE_PARM_DESC(osd_laced,
"Interlaced mode\n"
"\t\t\t0=off\n"
"\t\t\t1=on\n"
"\t\t\tdefault off");
MODULE_PARM_DESC(osd_depth,
"Bits per pixel - 8, 16, 32\n"
"\t\t\tdefault 8");
MODULE_PARM_DESC(osd_upper,
"Vertical start position\n"
"\t\t\tdefault 0 (Centered)");
MODULE_PARM_DESC(osd_left,
"Horizontal start position\n"
"\t\t\tdefault 0 (Centered)");
MODULE_PARM_DESC(osd_yres,
"Display height\n"
"\t\t\tdefault 480 (PAL)\n"
"\t\t\t 400 (NTSC)");
MODULE_PARM_DESC(osd_xres,
"Display width\n"
"\t\t\tdefault 640");
MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
MODULE_LICENSE("GPL");
/* --------------------------------------------------------------------- */
#define IVTVFB_DBGFLG_WARN (1 << 0)
#define IVTVFB_DBGFLG_INFO (1 << 1)
#define IVTVFB_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & ivtvfb_debug) \
printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->num , ## args); \
} while (0)
#define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
#define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
/* Standard kernel messages */
#define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->num , ## args)
#define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->num , ## args)
#define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->num , ## args)
/* --------------------------------------------------------------------- */
#define IVTV_OSD_MAX_WIDTH 720
#define IVTV_OSD_MAX_HEIGHT 576
#define IVTV_OSD_BPP_8 0x00
#define IVTV_OSD_BPP_16_444 0x03
#define IVTV_OSD_BPP_16_555 0x02
#define IVTV_OSD_BPP_16_565 0x01
#define IVTV_OSD_BPP_32 0x04
struct osd_info {
/* Physical base address */
unsigned long video_pbase;
/* Relative base address (relative to start of decoder memory) */
u32 video_rbase;
/* Mapped base address */