linux/drivers/staging/media/av7110/av7110.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
 * - initialization and demux stuff
 *
 * Copyright (C) 1999-2002 Ralph  Metzler
 *                       & Marcus Metzler for convergence integrated media GmbH
 *
 * originally based on code by:
 * Copyright (C) 1998,1999 Christian Theiss <[email protected]>
 *
 * the project's page is at https://linuxtv.org
 */

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
#include <linux/i2c.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>

#include <linux/dvb/frontend.h>

#include <media/dvb_frontend.h>

#include "ttpci-eeprom.h"
#include "av7110.h"
#include "av7110_hw.h"
#include "av7110_av.h"
#include "av7110_ca.h"
#include "av7110_ipack.h"

#include "bsbe1.h"
#include "lnbp21.h"
#include "bsru6.h"

#define TS_WIDTH
#define TS_HEIGHT
#define TS_BUFLEN
#define TS_MAX_PACKETS

int av7110_debug;

static int vidmode =;
static int pids_off;
static int adac =;
static int hw_sections;
static int rgb_on;
static int volume =;
static int budgetpatch;
static int wss_cfg_4_3 =;
static int wss_cfg_16_9 =;
static int tv_standard;
static int full_ts;

module_param_named(debug, av7110_debug, int, 0644);
MODULE_PARM_DESC();
module_param(vidmode, int, 0444);
MODULE_PARM_DESC();
module_param(pids_off, int, 0444);
MODULE_PARM_DESC();
module_param(adac, int, 0444);
MODULE_PARM_DESC();
module_param(hw_sections, int, 0444);
MODULE_PARM_DESC();
module_param(rgb_on, int, 0444);
MODULE_PARM_DESC();
module_param(volume, int, 0444);
MODULE_PARM_DESC();
module_param(budgetpatch, int, 0444);
MODULE_PARM_DESC();
module_param(full_ts, int, 0444);
MODULE_PARM_DESC();
module_param(wss_cfg_4_3, int, 0444);
MODULE_PARM_DESC();
module_param(wss_cfg_16_9, int, 0444);
MODULE_PARM_DESC();
module_param(tv_standard, int, 0444);
MODULE_PARM_DESC();

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

static void restart_feeds(struct av7110 *av7110);
static int budget_start_feed(struct dvb_demux_feed *feed);
static int budget_stop_feed(struct dvb_demux_feed *feed);

static int av7110_num;

#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func)

static void init_av7110_av(struct av7110 *av7110)
{}

static void recover_arm(struct av7110 *av7110)
{}

static void av7110_arm_sync(struct av7110 *av7110)
{}

static int arm_thread(void *data)
{}

/****************************************************************************
 * IRQ handling
 ****************************************************************************/

static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
				u8 *buffer2, size_t buffer2_len,
				struct dvb_demux_filter *dvbdmxfilter,
				struct av7110 *av7110)
{}

//#define DEBUG_TIMING
static inline void print_time(char *s)
{}

#define DEBI_READ
#define DEBI_WRITE
static inline void start_debi_dma(struct av7110 *av7110, int dir,
				  unsigned long addr, unsigned int len)
{}

static void debiirq(struct tasklet_struct *t)
{}

/* irq from av7110 firmware writing the mailbox register in the DPRAM */
static void gpioirq(struct tasklet_struct *t)
{}

#ifdef CONFIG_DVB_AV7110_OSD
static int dvb_osd_ioctl(struct file *file,
			 unsigned int cmd, void *parg)
{}

static const struct file_operations dvb_osd_fops =;

static struct dvb_device dvbdev_osd =;
#endif /* CONFIG_DVB_AV7110_OSD */

static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
			  u16 subpid, u16 pcrpid)
{}

int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
	       u16 subpid, u16 pcrpid)
{}

/******************************************************************************
 * hardware filter functions
 ******************************************************************************/

static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{}

static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{}

static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{}

static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{}

static int av7110_start_feed(struct dvb_demux_feed *feed)
{}

static int av7110_stop_feed(struct dvb_demux_feed *feed)
{}

static void restart_feeds(struct av7110 *av7110)
{}

static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
		       u64 *stc, unsigned int *base)
{}

/******************************************************************************
 * SEC device file operations
 ******************************************************************************/

static int av7110_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
{}

static int av7110_diseqc_send_master_cmd(struct dvb_frontend *fe,
					 struct dvb_diseqc_master_cmd *cmd)
{}

static int av7110_diseqc_send_burst(struct dvb_frontend *fe,
				    enum fe_sec_mini_cmd minicmd)
{}

/* simplified code from budget-core.c */
static int stop_ts_capture(struct av7110 *budget)
{}

static int start_ts_capture(struct av7110 *budget)
{}

static int budget_start_feed(struct dvb_demux_feed *feed)
{}

static int budget_stop_feed(struct dvb_demux_feed *feed)
{}

static void vpeirq(struct tasklet_struct *t)
{}

static int av7110_register(struct av7110 *av7110)
{}

static void dvb_unregister(struct av7110 *av7110)
{}

/****************************************************************************
 * I2C client commands
 ****************************************************************************/

int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
{}

u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
{}

/****************************************************************************
 * INITIALIZATION
 ****************************************************************************/

static int check_firmware(struct av7110 *av7110)
{}

static void put_firmware(struct av7110 *av7110)
{}

static int get_firmware(struct av7110 *av7110)
{}

static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
{}

static struct ves1x93_config alps_bsrv2_config =;

static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
{}

static struct ves1820_config alps_tdbe2_config =;

static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
{}

static struct tda8083_config grundig_29504_451_config =;

static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe)
{}

static struct ves1820_config philips_cd1516_config =;

static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe)
{}

static int alps_tdlb7_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
{}

static const struct sp8870_config alps_tdlb7_config =;

static u8 nexusca_stv0297_inittab[] =;

static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
{}

static struct stv0297_config nexusca_stv0297_config =;

static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
{}

static struct l64781_config grundig_29504_401_config =;

static int av7110_fe_lock_fix(struct av7110 *av7110, enum fe_status status)
{}

static int av7110_fe_set_frontend(struct dvb_frontend *fe)
{}

static int av7110_fe_init(struct dvb_frontend *fe)
{}

static int av7110_fe_read_status(struct dvb_frontend *fe,
				 enum fe_status *status)
{}

static int av7110_fe_diseqc_reset_overload(struct dvb_frontend *fe)
{}

static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend *fe,
					    struct dvb_diseqc_master_cmd *cmd)
{}

static int av7110_fe_diseqc_send_burst(struct dvb_frontend *fe,
				       enum fe_sec_mini_cmd minicmd)
{}

static int av7110_fe_set_tone(struct dvb_frontend *fe,
			      enum fe_sec_tone_mode tone)
{}

static int av7110_fe_set_voltage(struct dvb_frontend *fe,
				 enum fe_sec_voltage voltage)
{}

static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend *fe, unsigned long cmd)
{}

static void dvb_s_recover(struct av7110 *av7110)
{}

static u8 read_pwm(struct av7110 *av7110)
{}

static int frontend_init(struct av7110 *av7110)
{}

/* Budgetpatch note:
 * Original hardware design by Roberto Deza:
 * There is a DVB_Wiki at
 * https://linuxtv.org
 *
 * New software triggering design by Emard that works on
 * original Roberto Deza's hardware:
 *
 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
 * HS is an internal event of 7146, accessible with RPS
 * and temporarily raised high every n lines
 * (n in defined in the RPS_THRESH1 counter threshold)
 * I think HS is raised high on the beginning of the n-th line
 * and remains high until this n-th line that triggered
 * it is completely received. When the reception of n-th line
 * ends, HS is lowered.
 *
 * To transmit data over DMA, 7146 needs changing state at
 * port B VSYNC pin. Any changing of port B VSYNC will
 * cause some DMA data transfer, with more or less packets loss.
 * It depends on the phase and frequency of VSYNC and
 * the way of 7146 is instructed to trigger on port B (defined
 * in DD1_INIT register, 3rd nibble from the right valid
 * numbers are 0-7, see datasheet)
 *
 * The correct triggering can minimize packet loss,
 * dvbtraffic should give this stable bandwidths:
 *   22k transponder = 33814 kbit/s
 * 27.5k transponder = 38045 kbit/s
 * by experiment it is found that the best results
 * (stable bandwidths and almost no packet loss)
 * are obtained using DD1_INIT triggering number 2
 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
 * and a VSYNC phase that occurs in the middle of DMA transfer
 * (about byte 188*512=96256 in the DMA window).
 *
 * Phase of HS is still not clear to me how to control,
 * It just happens to be so. It can be seen if one enables
 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
 * time RPS_INTERRUPT is called, the Event Counter 1 will
 * increment. That's how the 7146 is programmed to do event
 * counting in this budget-patch.c
 * I *think* HPS setting has something to do with the phase
 * of HS but I can't be 100% sure in that.
 *
 * hardware debug note: a working budget card (including budget patch)
 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
 * and that means 3*25=75 Hz of interrupt frequency, as seen by
 * watch cat /proc/interrupts
 *
 * If this frequency is 3x lower (and data received in the DMA
 * buffer don't start with 0x47, but in the middle of packets,
 * whose lengths appear to be like 188 292 188 104 etc.
 * this means VSYNC line is not connected in the hardware.
 * (check soldering pcb and pins)
 * The same behaviour of missing VSYNC can be duplicated on budget
 * cards, by setting DD1_INIT trigger mode 7 in 3rd nibble.
 */
static int av7110_attach(struct saa7146_dev *dev,
			 struct saa7146_pci_extension_data *pci_ext)
{}

static int av7110_detach(struct saa7146_dev *saa)
{}

static void av7110_irq(struct saa7146_dev *dev, u32 *isr)
{}

static struct saa7146_extension av7110_extension_driver;

#define MAKE_AV7110_INFO(x_var, x_name)

MAKE_AV7110_INFO(tts_1_X_fsc, "Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(ttt_1_X,    "Technotrend/Hauppauge WinTV DVB-T rev1.X");
MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
MAKE_AV7110_INFO(tts_2_3,    "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");

static const struct pci_device_id pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, pci_tbl);

static struct saa7146_extension av7110_extension_driver =;

static int __init av7110_init(void)
{}

static void __exit av7110_exit(void)
{}

module_init();
module_exit(av7110_exit);

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