linux/drivers/media/usb/em28xx/em28xx-dvb.c

// SPDX-License-Identifier: GPL-2.0
//
// DVB device driver for em28xx
//
// (c) 2008-2011 Mauro Carvalho Chehab <[email protected]>
//
// (c) 2008 Devin Heitmueller <[email protected]>
//	- Fixes for the driver to properly work with HVR-950
//	- Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
//	- Fixes for the driver to properly work with AMD ATI TV Wonder HD 600
//
// (c) 2008 Aidan Thornton <[email protected]>
//
// (c) 2012 Frank Schäfer <[email protected]>
//
// Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by:
//	(c) 2004, 2005 Chris Pascoe <[email protected]>
//	(c) 2004 Gerd Knorr <[email protected]> [SuSE Labs]

#include "em28xx.h"

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/usb.h>

#include <media/v4l2-common.h>
#include <media/dvb_demux.h>
#include <media/dvb_net.h>
#include <media/dmxdev.h>
#include <media/tuner.h>
#include "tuner-simple.h"
#include <linux/gpio.h>

#include "lgdt330x.h"
#include "lgdt3305.h"
#include "lgdt3306a.h"
#include "zl10353.h"
#include "s5h1409.h"
#include "mt2060.h"
#include "mt352.h"
#include "mt352_priv.h" /* FIXME */
#include "tda1002x.h"
#include "drx39xyj/drx39xxj.h"
#include "tda18271.h"
#include "s921.h"
#include "drxd.h"
#include "cxd2820r.h"
#include "tda18271c2dd.h"
#include "drxk.h"
#include "tda10071.h"
#include "tda18212.h"
#include "a8293.h"
#include "qt1010.h"
#include "mb86a20s.h"
#include "m88ds3103.h"
#include "ts2020.h"
#include "si2168.h"
#include "si2157.h"
#include "tc90522.h"
#include "qm1d1c0042.h"
#include "mxl692.h"

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

static unsigned int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC();

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

#define dprintk(level, fmt, arg...)

struct em28xx_dvb {};

static inline void print_err_status(struct em28xx *dev,
				    int packet, int status)
{}

static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb)
{}

static int em28xx_start_streaming(struct em28xx_dvb *dvb)
{}

static int em28xx_stop_streaming(struct em28xx_dvb *dvb)
{}

static int em28xx_start_feed(struct dvb_demux_feed *feed)
{}

static int em28xx_stop_feed(struct dvb_demux_feed *feed)
{}

/* ------------------------------------------------------------------ */
static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
{}

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

static struct lgdt330x_config em2880_lgdt3303_dev =;

static struct lgdt3305_config em2870_lgdt3304_dev =;

static struct lgdt3305_config em2874_lgdt3305_dev =;

static struct lgdt3305_config em2874_lgdt3305_nogate_dev =;

static struct s921_config sharp_isdbt =;

static struct zl10353_config em28xx_zl10353_with_xc3028 =;

static struct s5h1409_config em28xx_s5h1409_with_xc3028 =;

static struct tda18271_std_map kworld_a340_std_map =;

static struct tda18271_config kworld_a340_config =;

static struct tda18271_config kworld_ub435q_v2_config =;

static struct tda18212_config kworld_ub435q_v3_config =;

static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate =;

static struct drxd_config em28xx_drxd =;

static struct drxk_config terratec_h5_drxk =;

static struct drxk_config hauppauge_930c_drxk =;

static struct drxk_config terratec_htc_stick_drxk =;

static struct drxk_config maxmedia_ub425_tc_drxk =;

static struct drxk_config pctv_520e_drxk =;

static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
{}

static void hauppauge_hvr930c_init(struct em28xx *dev)
{}

static void terratec_h5_init(struct em28xx *dev)
{
	int i;
	static const struct em28xx_reg_seq terratec_h5_init[] = {
		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
		{	-1,			-1,	-1,	-1},
	};
	static const struct em28xx_reg_seq terratec_h5_end[] = {
		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
		{	-1,			-1,	-1,	-1},
	};
	static const struct {
		unsigned char r[4];
		int len;
	} regs[] = {
		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
		{{ 0x01, 0x02 }, 2},
		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
		{{ 0x01, 0x00, 0x03, 0xa0 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0x73, 0xaf }, 4},
		{{ 0x04, 0x00 }, 2},
		{{ 0x00, 0x04 }, 2},
		{{ 0x00, 0x04, 0x00, 0x0a }, 4},
		{{ 0x04, 0x14 }, 2},
		{{ 0x04, 0x14, 0x00, 0x00 }, 4},
	};

	em28xx_gpio_set(dev, terratec_h5_init);
	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
	usleep_range(10000, 11000);
	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45);
	usleep_range(10000, 11000);

	dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1;

	for (i = 0; i < ARRAY_SIZE(regs); i++)
		i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
				regs[i].r, regs[i].len);
	em28xx_gpio_set(dev, terratec_h5_end);
};

static void terratec_htc_stick_init(struct em28xx *dev)
{
	int i;

	/*
	 * GPIO configuration:
	 * 0xff: unknown (does not affect DVB-T).
	 * 0xf6: DRX-K (demodulator).
	 * 0xe6: unknown (does not affect DVB-T).
	 * 0xb6: unknown (does not affect DVB-T).
	 */
	static const struct em28xx_reg_seq terratec_htc_stick_init[] = {
		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	50},
		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
		{	-1,			-1,	-1,	-1},
	};
	static const struct em28xx_reg_seq terratec_htc_stick_end[] = {
		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
		{	-1,			-1,	-1,	-1},
	};

	/*
	 * Init the analog decoder (not yet supported), but
	 * it's probably still a good idea.
	 */
	static const struct {
		unsigned char r[4];
		int len;
	} regs[] = {
		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
		{{ 0x01, 0x02 }, 2},
		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
	};

	em28xx_gpio_set(dev, terratec_htc_stick_init);

	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
	usleep_range(10000, 11000);
	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
	usleep_range(10000, 11000);

	dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1;

	for (i = 0; i < ARRAY_SIZE(regs); i++)
		i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
				regs[i].r, regs[i].len);

	em28xx_gpio_set(dev, terratec_htc_stick_end);
};

static void terratec_htc_usb_xs_init(struct em28xx *dev)
{
	int i;

	static const struct em28xx_reg_seq terratec_htc_usb_xs_init[] = {
		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	50},
		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
		{	-1,			-1,	-1,	-1},
	};
	static const struct em28xx_reg_seq terratec_htc_usb_xs_end[] = {
		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	100},
		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
		{	-1,			-1,	-1,	-1},
	};

	/*
	 * Init the analog decoder (not yet supported), but
	 * it's probably still a good idea.
	 */
	static const struct {
		unsigned char r[4];
		int len;
	} regs[] = {
		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
		{{ 0x01, 0x02 }, 2},
		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
		{{ 0x01, 0x00, 0x03, 0xa0 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0x73, 0xaf }, 4},
		{{ 0x04, 0x00 }, 2},
		{{ 0x00, 0x04 }, 2},
		{{ 0x00, 0x04, 0x00, 0x0a }, 4},
		{{ 0x04, 0x14 }, 2},
		{{ 0x04, 0x14, 0x00, 0x00 }, 4},
	};

	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);

	em28xx_gpio_set(dev, terratec_htc_usb_xs_init);

	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
	usleep_range(10000, 11000);
	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
	usleep_range(10000, 11000);

	dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1;

	for (i = 0; i < ARRAY_SIZE(regs); i++)
		i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
				regs[i].r, regs[i].len);

	em28xx_gpio_set(dev, terratec_htc_usb_xs_end);
};

static void pctv_520e_init(struct em28xx *dev)
{
	/*
	 * Init AVF4910B analog decoder. Looks like I2C traffic to
	 * digital demodulator and tuner are routed via AVF4910B.
	 */
	int i;
	static const struct {
		unsigned char r[4];
		int len;
	} regs[] = {
		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
		{{ 0x01, 0x02 }, 2},
		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
		{{ 0x01, 0x00, 0x03, 0xa0 }, 4},
		{{ 0x01, 0x00 }, 2},
		{{ 0x01, 0x00, 0x73, 0xaf }, 4},
	};

	dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; /* 0x41 */

	for (i = 0; i < ARRAY_SIZE(regs); i++)
		i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
				regs[i].r, regs[i].len);
};

static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe)
{}

static int em28xx_pctv_292e_set_lna(struct dvb_frontend *fe)
{}

static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe)
{}

static void px_bcud_init(struct em28xx *dev)
{
	int i;
	static const struct {
		unsigned char r[4];
		int len;
	} regs1[] = {
		{{ 0x0e, 0x77 }, 2},
		{{ 0x0f, 0x77 }, 2},
		{{ 0x03, 0x90 }, 2},
	}, regs2[] = {
		{{ 0x07, 0x01 }, 2},
		{{ 0x08, 0x10 }, 2},
		{{ 0x13, 0x00 }, 2},
		{{ 0x17, 0x00 }, 2},
		{{ 0x03, 0x01 }, 2},
		{{ 0x10, 0xb1 }, 2},
		{{ 0x11, 0x40 }, 2},
		{{ 0x85, 0x7a }, 2},
		{{ 0x87, 0x04 }, 2},
	};
	static const struct em28xx_reg_seq gpio[] = {
		{EM28XX_R06_I2C_CLK,		0x40,	0xff,	300},
		{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	60},
		{EM28XX_R15_RGAIN,		0x20,	0xff,	0},
		{EM28XX_R16_GGAIN,		0x20,	0xff,	0},
		{EM28XX_R17_BGAIN,		0x20,	0xff,	0},
		{EM28XX_R18_ROFFSET,		0x00,	0xff,	0},
		{EM28XX_R19_GOFFSET,		0x00,	0xff,	0},
		{EM28XX_R1A_BOFFSET,		0x00,	0xff,	0},
		{EM28XX_R23_UOFFSET,		0x00,	0xff,	0},
		{EM28XX_R24_VOFFSET,		0x00,	0xff,	0},
		{EM28XX_R26_COMPR,		0x00,	0xff,	0},
		{0x13,				0x08,	0xff,	0},
		{EM28XX_R12_VINENABLE,		0x27,	0xff,	0},
		{EM28XX_R0C_USBSUSP,		0x10,	0xff,	0},
		{EM28XX_R27_OUTFMT,		0x00,	0xff,	0},
		{EM28XX_R10_VINMODE,		0x00,	0xff,	0},
		{EM28XX_R11_VINCTRL,		0x11,	0xff,	0},
		{EM2874_R50_IR_CONFIG,		0x01,	0xff,	0},
		{EM2874_R5F_TS_ENABLE,		0x80,	0xff,	0},
		{EM28XX_R06_I2C_CLK,		0x46,	0xff,	0},
	};
	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x46);
	/* sleeping ISDB-T */
	dev->dvb->i2c_client_demod->addr = 0x14;
	for (i = 0; i < ARRAY_SIZE(regs1); i++)
		i2c_master_send(dev->dvb->i2c_client_demod,
				regs1[i].r, regs1[i].len);
	/* sleeping ISDB-S */
	dev->dvb->i2c_client_demod->addr = 0x15;
	for (i = 0; i < ARRAY_SIZE(regs2); i++)
		i2c_master_send(dev->dvb->i2c_client_demod, regs2[i].r,
				regs2[i].len);
	for (i = 0; i < ARRAY_SIZE(gpio); i++) {
		em28xx_write_reg_bits(dev, gpio[i].reg, gpio[i].val,
				      gpio[i].mask);
		if (gpio[i].sleep > 0)
			msleep(gpio[i].sleep);
	}
};

static struct mt352_config terratec_xs_mt352_cfg =;

static struct tda10023_config em28xx_tda10023_config =;

static struct cxd2820r_config em28xx_cxd2820r_config =;

static struct tda18271_config em28xx_cxd2820r_tda18271_config =;

static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev =;

static struct mt2060_config em28xx_mt2060_config =;

static struct qt1010_config em28xx_qt1010_config =;

static const struct mb86a20s_config c3tech_duo_mb86a20s_config =;

static struct tda18271_std_map mb86a20s_tda18271_config =;

static struct tda18271_config c3tech_duo_tda18271_config =;

static struct tda18271_std_map drx_j_std_map =;

static struct tda18271_config pinnacle_80e_dvb_config =;

static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config =;

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

static noinline_for_stack int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
{}

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

static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module,
			       struct em28xx *dev, struct device *device)
{}

static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
{}

static int em28174_dvb_init_pctv_460e(struct em28xx *dev)
{}

static int em28178_dvb_init_pctv_461e(struct em28xx *dev)
{}

static int em28178_dvb_init_pctv_461e_v2(struct em28xx *dev)
{}

static int em28178_dvb_init_pctv_292e(struct em28xx *dev)
{}

static int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev)
{}

static int em28178_dvb_init_plex_px_bcud(struct em28xx *dev)
{}

static int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev)
{}

static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev)
{}

static int em2874_dvb_init_hauppauge_usb_quadhd(struct em28xx *dev)
{}

static int em28xx_dvb_init(struct em28xx *dev)
{}

static inline void prevent_sleep(struct dvb_frontend_ops *ops)
{}

static int em28xx_dvb_fini(struct em28xx *dev)
{}

static int em28xx_dvb_suspend(struct em28xx *dev)
{}

static int em28xx_dvb_resume(struct em28xx *dev)
{}

static struct em28xx_ops dvb_ops =;

static int __init em28xx_dvb_register(void)
{}

static void __exit em28xx_dvb_unregister(void)
{}

module_init();
module_exit(em28xx_dvb_unregister);