linux/drivers/media/pci/bt8xx/bttv-driver.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*

    bttv - Bt848 frame grabber driver

    Copyright (C) 1996,97,98 Ralph  Metzler <[email protected]>
			   & Marcus Metzler <[email protected]>
    (c) 1999-2002 Gerd Knorr <[email protected]>

    some v4l2 code lines are taken from Justin's bttv2 driver which is
    (c) 2000 Justin Schoeman <[email protected]>

    V4L1 removal from:
    (c) 2005-2006 Nickolay V. Shmyrev <[email protected]>

    Fixes to be fully V4L2 compliant by
    (c) 2006 Mauro Carvalho Chehab <[email protected]>

    Cropping and overscan support
    Copyright (C) 2005, 2006 Michael H. Schimek <[email protected]>
    Sponsored by OPQ Systems AB

*/

#define pr_fmt(fmt)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
#include "bttvp.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include <media/i2c/tvaudio.h>
#include <media/drv-intf/msp3400.h>

#include <linux/dma-mapping.h>

#include <asm/io.h>
#include <asm/byteorder.h>

#include <media/i2c/saa6588.h>

#define BTTV_VERSION

unsigned int bttv_num;			/* number of Bt848s in use */
struct bttv *bttvs[BTTV_MAX];

unsigned int bttv_debug;
unsigned int bttv_verbose =;
unsigned int bttv_gpio;

/* config variables */
#ifdef __BIG_ENDIAN
static unsigned int bigendian=1;
#else
static unsigned int bigendian;
#endif
static unsigned int radio[BTTV_MAX];
static unsigned int irq_debug;
static unsigned int gbuffers =;
static unsigned int gbufsize =;
static unsigned int reset_crop =;

static int video_nr[BTTV_MAX] =;
static int radio_nr[BTTV_MAX] =;
static int vbi_nr[BTTV_MAX] =;
static int debug_latency;
static int disable_ir;

static unsigned int fdsr;

/* options */
static unsigned int combfilter;
static unsigned int lumafilter;
static unsigned int automute    =;
static unsigned int chroma_agc;
static unsigned int agc_crush   =;
static unsigned int whitecrush_upper =;
static unsigned int whitecrush_lower =;
static unsigned int vcr_hack;
static unsigned int irq_iswitch;
static unsigned int uv_ratio    =;
static unsigned int full_luma_range;
static unsigned int coring;

/* API features (turn on/off stuff for testing) */
static unsigned int v4l2        =;

/* insmod args */
module_param(bttv_verbose,      int, 0644);
module_param(bttv_gpio,         int, 0644);
module_param(bttv_debug,        int, 0644);
module_param(irq_debug,         int, 0644);
module_param(debug_latency,     int, 0644);
module_param(disable_ir,        int, 0444);

module_param(fdsr,              int, 0444);
module_param(gbuffers,          int, 0444);
module_param(gbufsize,          int, 0444);
module_param(reset_crop,        int, 0444);

module_param(v4l2,              int, 0644);
module_param(bigendian,         int, 0644);
module_param(irq_iswitch,       int, 0644);
module_param(combfilter,        int, 0444);
module_param(lumafilter,        int, 0444);
module_param(automute,          int, 0444);
module_param(chroma_agc,        int, 0444);
module_param(agc_crush,         int, 0444);
module_param(whitecrush_upper,  int, 0444);
module_param(whitecrush_lower,  int, 0444);
module_param(vcr_hack,          int, 0444);
module_param(uv_ratio,          int, 0444);
module_param(full_luma_range,   int, 0444);
module_param(coring,            int, 0444);

module_param_array();
module_param_array();
module_param_array();
module_param_array();

MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_VERSION();

#define V4L2_CID_PRIVATE_COMBFILTER
#define V4L2_CID_PRIVATE_AUTOMUTE
#define V4L2_CID_PRIVATE_LUMAFILTER
#define V4L2_CID_PRIVATE_AGC_CRUSH
#define V4L2_CID_PRIVATE_VCR_HACK
#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER
#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER
#define V4L2_CID_PRIVATE_UV_RATIO
#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE
#define V4L2_CID_PRIVATE_CORING

/* ----------------------------------------------------------------------- */
/* sysfs                                                                   */

static ssize_t card_show(struct device *cd,
			 struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(card);

/* ----------------------------------------------------------------------- */
/* dvb auto-load setup                                                     */
#if defined(CONFIG_MODULES) && defined(MODULE)
static void request_module_async(struct work_struct *work)
{
	request_module("dvb-bt8xx");
}

static void request_modules(struct bttv *dev)
{
	INIT_WORK(&dev->request_module_wk, request_module_async);
	schedule_work(&dev->request_module_wk);
}

static void flush_request_modules(struct bttv *dev)
{
	flush_work(&dev->request_module_wk);
}
#else
#define request_modules(dev)
#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */


/* ----------------------------------------------------------------------- */
/* static data                                                             */

/* special timing tables from conexant... */
static u8 SRAM_Table[][60] =;

/* minhdelayx1	first video pixel we can capture on a line and
   hdelayx1	start of active video, both relative to rising edge of
		/HRESET pulse (0H) in 1 / fCLKx1.
   swidth	width of active video and
   totalwidth	total line width, both in 1 / fCLKx1.
   sqwidth	total line width in square pixels.
   vdelay	start of active video in 2 * field lines relative to
		trailing edge of /VRESET pulse (VDELAY register).
   sheight	height of active video in 2 * field lines.
   extraheight	Added to sheight for cropcap.bounds.height only
   videostart0	ITU-R frame line number of the line corresponding
		to vdelay in the first field. */
#define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth,	 \
		vdelay, sheight, extraheight, videostart0)

const struct bttv_tvnorm bttv_tvnorms[] =;
static const unsigned int BTTV_TVNORMS =;

/* ----------------------------------------------------------------------- */
/* bttv format list
   packed pixel formats must come first */
static const struct bttv_format formats[] =;
static const unsigned int FORMATS =;

/* ----------------------------------------------------------------------- */
/* resource management                                                     */

/*
   RESOURCE_    allocated by                freed by

   VIDEO_READ   bttv_read 1)                bttv_read 2)

   VIDEO_STREAM VIDIOC_STREAMON             VIDIOC_STREAMOFF
		 VIDIOC_QBUF 1)              bttv_release
		 VIDIOCMCAPTURE 1)

   VBI		 VIDIOC_STREAMON             VIDIOC_STREAMOFF
		 VIDIOC_QBUF 1)              bttv_release
		 bttv_read, bttv_poll 1) 3)

   1) The resource must be allocated when we enter buffer prepare functions
      and remain allocated while buffers are in the DMA queue.
   2) This is a single frame read.
   3) This is a continuous read, implies VIDIOC_STREAMON.

   Note this driver permits video input and standard changes regardless if
   resources are allocated.
*/

#define VBI_RESOURCES
#define VIDEO_RESOURCES

int check_alloc_btres_lock(struct bttv *btv, int bit)
{}

static
int check_btres(struct bttv *btv, int bit)
{}

static
int locked_btres(struct bttv *btv, int bit)
{}

/* Call with btv->lock down. */
static void
disclaim_vbi_lines(struct bttv *btv)
{}

/* Call with btv->lock down. */
static void
disclaim_video_lines(struct bttv *btv)
{}

void free_btres_lock(struct bttv *btv, int bits)
{}

/* ----------------------------------------------------------------------- */
/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC          */

/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
   PLL_X = Reference pre-divider (0=1, 1=2)
   PLL_C = Post divider (0=6, 1=4)
   PLL_I = Integer input
   PLL_F = Fractional input

   F_input = 28.636363 MHz:
   PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
*/

static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
{}

static void set_pll(struct bttv *btv)
{}

/* used to switch between the bt848's analog/digital video capture modes */
static void bt848A_set_timing(struct bttv *btv)
{}

/* ----------------------------------------------------------------------- */

static void bt848_bright(struct bttv *btv, int bright)
{}

static void bt848_hue(struct bttv *btv, int hue)
{}

static void bt848_contrast(struct bttv *btv, int cont)
{}

static void bt848_sat(struct bttv *btv, int color)
{}

/* ----------------------------------------------------------------------- */

static int
video_mux(struct bttv *btv, unsigned int input)
{}

static char *audio_modes[] =;

static void
audio_mux_gpio(struct bttv *btv, int input, int mute)
{}

static int
audio_mute(struct bttv *btv, int mute)
{}

static int
audio_input(struct bttv *btv, int input)
{}

static void
bttv_crop_calc_limits(struct bttv_crop *c)
{}

static void
bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
{}

/* Call with btv->lock down. */
static int
set_tvnorm(struct bttv *btv, unsigned int norm)
{}

/* Call with btv->lock down. */
static void
set_input(struct bttv *btv, unsigned int input, unsigned int norm)
{}

void init_irqreg(struct bttv *btv)
{}

static void init_bt848(struct bttv *btv)
{}

static void bttv_reinit_bt848(struct bttv *btv)
{}

static int bttv_s_ctrl(struct v4l2_ctrl *c)
{}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops bttv_ctrl_ops =;

static struct v4l2_ctrl_config bttv_ctrl_combfilter =;

static struct v4l2_ctrl_config bttv_ctrl_automute =;

static struct v4l2_ctrl_config bttv_ctrl_lumafilter =;

static struct v4l2_ctrl_config bttv_ctrl_agc_crush =;

static struct v4l2_ctrl_config bttv_ctrl_vcr_hack =;

static struct v4l2_ctrl_config bttv_ctrl_whitecrush_lower =;

static struct v4l2_ctrl_config bttv_ctrl_whitecrush_upper =;

static struct v4l2_ctrl_config bttv_ctrl_uv_ratio =;

static struct v4l2_ctrl_config bttv_ctrl_full_luma =;

static struct v4l2_ctrl_config bttv_ctrl_coring =;


/* ----------------------------------------------------------------------- */

void bttv_gpio_tracking(struct bttv *btv, char *comment)
{}

static const struct bttv_format*
format_by_fourcc(int fourcc)
{}

/* ----------------------------------------------------------------------- */
/* video4linux (1) interface                                               */

static int queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
		       unsigned int *num_planes, unsigned int sizes[],
		       struct device *alloc_devs[])
{}

static void buf_queue(struct vb2_buffer *vb)
{}

static int buf_prepare(struct vb2_buffer *vb)
{}

static void buf_cleanup(struct vb2_buffer *vb)
{}

static int start_streaming(struct vb2_queue *q, unsigned int count)
{}

static void stop_streaming(struct vb2_queue *q)
{}

static const struct vb2_ops bttv_video_qops =;

static void radio_enable(struct bttv *btv)
{}

static int bttv_s_std(struct file *file, void *priv, v4l2_std_id id)
{}

static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id)
{}

static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id)
{}

static int bttv_enum_input(struct file *file, void *priv,
					struct v4l2_input *i)
{}

static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
{}

static int bttv_s_input(struct file *file, void *priv, unsigned int i)
{}

static int bttv_s_tuner(struct file *file, void *priv,
					const struct v4l2_tuner *t)
{}

static int bttv_g_frequency(struct file *file, void *priv,
					struct v4l2_frequency *f)
{}

static void bttv_set_frequency(struct bttv *btv, const struct v4l2_frequency *f)
{}

static int bttv_s_frequency(struct file *file, void *priv,
					const struct v4l2_frequency *f)
{}

static int bttv_log_status(struct file *file, void *f)
{}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int bttv_g_register(struct file *file, void *f,
					struct v4l2_dbg_register *reg)
{}

static int bttv_s_register(struct file *file, void *f,
					const struct v4l2_dbg_register *reg)
{}
#endif

/* Given cropping boundaries b and the scaled width and height of a
   single field or frame, which must not exceed hardware limits, this
   function adjusts the cropping parameters c. */
static void
bttv_crop_adjust	(struct bttv_crop *             c,
			 const struct v4l2_rect *	b,
			 __s32                          width,
			 __s32                          height,
			 enum v4l2_field                field)
{}

/* Returns an error if scaling to a frame or single field with the given
   width and height is not possible with the current cropping parameters
   and width aligned according to width_mask. If adjust_size is TRUE the
   function may adjust the width and/or height instead, rounding width
   to (width + width_bias) & width_mask. If adjust_crop is TRUE it may
   also adjust the current cropping parameters to get closer to the
   desired image size. */
static int
limit_scaled_size_lock(struct bttv *btv, __s32 *width, __s32 *height,
		       enum v4l2_field field, unsigned int width_mask,
		       unsigned int width_bias, int adjust_size,
		       int adjust_crop)
{}

static int bttv_switch_type(struct bttv *btv, enum v4l2_buf_type type)
{}

static void
pix_format_set_size     (struct v4l2_pix_format *       f,
			 const struct bttv_format *     fmt,
			 unsigned int                   width,
			 unsigned int                   height)
{}

static int bttv_g_fmt_vid_cap(struct file *file, void *priv,
					struct v4l2_format *f)
{}

static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt,
					unsigned int *width_mask,
					unsigned int *width_bias)
{}

static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
						struct v4l2_format *f)
{}

static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
			      struct v4l2_format *f)
{}

static int bttv_querycap(struct file *file, void  *priv,
				struct v4l2_capability *cap)
{}

static int bttv_enum_fmt_vid_cap(struct file *file, void  *priv,
				 struct v4l2_fmtdesc *f)
{}

static int bttv_g_parm(struct file *file, void *f,
				struct v4l2_streamparm *parm)
{}

static int bttv_g_tuner(struct file *file, void *priv,
				struct v4l2_tuner *t)
{}

static int bttv_g_pixelaspect(struct file *file, void *priv,
			      int type, struct v4l2_fract *f)
{}

static int bttv_g_selection(struct file *file, void *f, struct v4l2_selection *sel)
{}

static int bttv_s_selection(struct file *file, void *f, struct v4l2_selection *sel)
{}

static const struct v4l2_file_operations bttv_fops =;

static const struct v4l2_ioctl_ops bttv_ioctl_ops =;

static struct video_device bttv_video_template =;

/* ----------------------------------------------------------------------- */
/* radio interface                                                         */

static int radio_open(struct file *file)
{}

static int radio_release(struct file *file)
{}

static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
{}

static int radio_s_tuner(struct file *file, void *priv,
					const struct v4l2_tuner *t)
{}

static int radio_s_hw_freq_seek(struct file *file, void *priv,
					const struct v4l2_hw_freq_seek *a)
{}

static int radio_enum_freq_bands(struct file *file, void *priv,
					 struct v4l2_frequency_band *band)
{}

static ssize_t radio_read(struct file *file, char __user *data,
			 size_t count, loff_t *ppos)
{}

static __poll_t radio_poll(struct file *file, poll_table *wait)
{}

static const struct v4l2_file_operations radio_fops =;

static const struct v4l2_ioctl_ops radio_ioctl_ops =;

static struct video_device radio_template =;

/* ----------------------------------------------------------------------- */
/* some debug code                                                         */

static int bttv_risc_decode(u32 risc)
{}

static void bttv_risc_disasm(struct bttv *btv,
			     struct btcx_riscmem *risc)
{}

static void bttv_print_riscaddr(struct bttv *btv)
{}

/* ----------------------------------------------------------------------- */
/* irq handler                                                             */

static char *irq_name[] =;

static void bttv_print_irqbits(u32 print, u32 mark)
{}

static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
{}

static int
bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
{}

static void
bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
		      struct bttv_buffer_set *curr, unsigned int state)
{}

static void
bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
				unsigned int state)
{}

static void bttv_irq_timeout(struct timer_list *t)
{}

static void
bttv_irq_wakeup_top(struct bttv *btv)
{}

static inline int is_active(struct btcx_riscmem *risc, u32 rc)
{}

static void
bttv_irq_switch_video(struct bttv *btv)
{}

static void
bttv_irq_switch_vbi(struct bttv *btv)
{}

static irqreturn_t bttv_irq(int irq, void *dev_id)
{}


/* ----------------------------------------------------------------------- */
/* initialization                                                          */

static int vdev_init(struct bttv *btv, struct video_device *vfd,
		     const struct video_device *template,
		     const char *type_name)
{}

static void bttv_unregister_video(struct bttv *btv)
{}

/* register video4linux devices */
static int bttv_register_video(struct bttv *btv)
{}


/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
/* response on cards with no firmware is not enabled by OF */
static void pci_set_command(struct pci_dev *dev)
{}

static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
{}

static void bttv_remove(struct pci_dev *pci_dev)
{}

static int __maybe_unused bttv_suspend(struct device *dev)
{}

static int __maybe_unused bttv_resume(struct device *dev)
{}

static const struct pci_device_id bttv_pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);

static SIMPLE_DEV_PM_OPS(bttv_pm_ops,
			 bttv_suspend,
			 bttv_resume);

static struct pci_driver bttv_pci_driver =;

static int __init bttv_init_module(void)
{}

static void __exit bttv_cleanup_module(void)
{}

module_init();
module_exit(bttv_cleanup_module);