Commit dd60bf43 authored by Brad Love's avatar Brad Love Committed by Mauro Carvalho Chehab
Browse files

media: pvrusb2: Add Hauppauge HVR1955/1975 devices



Includes support to identify and use two Hauppauge device.
- LGDT3306a ATSC/QAM demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

HVR-1975 dual-frontend:
- LGDT3306a ATSC/QAM demod
- si2168 DVB-C/T/T2 demod
- si2177 tuner
- cx25840 decoder for analog tv/composite/s-video/audio

Signed-off-by: default avatarBrad Love <brad@nextdimension.cc>
Reviewed-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 6f6be371
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ config VIDEO_PVRUSB2_DVB
	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
	select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
	select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
+25 −0
Original line number Diff line number Diff line
@@ -111,10 +111,35 @@ static const struct routing_scheme routing_defav400 = {
	.cnt = ARRAY_SIZE(routing_schemeav400),
};

static const struct routing_scheme_item routing_scheme160xxx[] = {
	[PVR2_CVAL_INPUT_TV] = {
		.vid = CX25840_COMPOSITE7,
		.aud = CX25840_AUDIO8,
	},
	[PVR2_CVAL_INPUT_RADIO] = {
		.vid = CX25840_COMPOSITE4,
		.aud = CX25840_AUDIO6,
	},
	[PVR2_CVAL_INPUT_COMPOSITE] = {
		.vid = CX25840_COMPOSITE3,
		.aud = CX25840_AUDIO_SERIAL,
	},
	[PVR2_CVAL_INPUT_SVIDEO] = {
		.vid = CX25840_SVIDEO1,
		.aud = CX25840_AUDIO_SERIAL,
	},
};

static const struct routing_scheme routing_def160xxx = {
	.def = routing_scheme160xxx,
	.cnt = ARRAY_SIZE(routing_scheme160xxx),
};

static const struct routing_scheme *routing_schemes[] = {
	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
	[PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
};

void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
+166 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ pvr2_device_desc structures.
#include "tda18271.h"
#include "tda8290.h"
#include "tuner-simple.h"
#include "si2157.h"
#include "lgdt3306a.h"
#include "si2168.h"
#endif


@@ -525,7 +528,166 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
#endif
};

/*------------------------------------------------------------------------*/
/*    Hauppauge PVR-USB2 Model 160000 / 160111 -- HVR-1955 / HVR-1975     */

#ifdef CONFIG_VIDEO_PVRUSB2_DVB
static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap);
static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap);
static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap);
static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap);

static const struct pvr2_dvb_props pvr2_160000_dvb_props = {
	.frontend_attach = pvr2_dual_fe_attach,
	.tuner_attach    = pvr2_si2157_attach,
};

static const struct pvr2_dvb_props pvr2_160111_dvb_props = {
	.frontend_attach = pvr2_lgdt3306a_attach,
	.tuner_attach    = pvr2_si2157_attach,
};

static int pvr2_si2157_attach(struct pvr2_dvb_adapter *adap)
{
	struct si2157_config si2157_config = {};

	si2157_config.inversion = 1;
	si2157_config.fe = adap->fe[0];

	adap->i2c_client_tuner = dvb_module_probe("si2157", "si2177",
						  &adap->channel.hdw->i2c_adap,
						  0x60, &si2157_config);

	if (!adap->i2c_client_tuner)
		return -ENODEV;

	return 0;
}

static int pvr2_si2168_attach(struct pvr2_dvb_adapter *adap)
{
	struct si2168_config si2168_config = {};
	struct i2c_adapter *adapter;

	pr_debug("%s()\n", __func__);

	si2168_config.fe = &adap->fe[1];
	si2168_config.i2c_adapter = &adapter;
	si2168_config.ts_mode = SI2168_TS_PARALLEL; /*2, 1-serial, 2-parallel.*/
	si2168_config.ts_clock_gapped = 1; /*0-disabled, 1-enabled.*/
	si2168_config.ts_clock_inv = 0; /*0-not-invert, 1-invert*/
	si2168_config.spectral_inversion = 1; /*0-not-invert, 1-invert*/

	adap->i2c_client_demod[1] = dvb_module_probe("si2168", NULL,
						     &adap->channel.hdw->i2c_adap,
						     0x64, &si2168_config);

	if (!adap->i2c_client_demod[1])
		return -ENODEV;

	return 0;
}

static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
{
	struct lgdt3306a_config lgdt3306a_config;
	struct i2c_adapter *adapter;

	pr_debug("%s()\n", __func__);

	lgdt3306a_config.fe = &adap->fe[0];
	lgdt3306a_config.i2c_adapter = &adapter;
	lgdt3306a_config.deny_i2c_rptr = 1;
	lgdt3306a_config.spectral_inversion = 1;
	lgdt3306a_config.qam_if_khz = 4000;
	lgdt3306a_config.vsb_if_khz = 3250;
	lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
	lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
	lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
	lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */

	adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
						     &adap->channel.hdw->i2c_adap,
						     0x59, &lgdt3306a_config);

	if (!adap->i2c_client_demod[0])
		return -ENODEV;

	return 0;
}

static int pvr2_dual_fe_attach(struct pvr2_dvb_adapter *adap)
{
	pr_debug("%s()\n", __func__);

	if (pvr2_lgdt3306a_attach(adap) != 0)
		return -ENODEV;

	if (pvr2_si2168_attach(adap) != 0) {
		dvb_module_release(adap->i2c_client_demod[0]);
		return -ENODEV;
	}

	return 0;
}
#endif

#define PVR2_FIRMWARE_160xxx "v4l-pvrusb2-160xxx-01.fw"
static const char *pvr2_fw1_names_160xxx[] = {
		PVR2_FIRMWARE_160xxx,
};

static const struct pvr2_device_client_desc pvr2_cli_160xxx[] = {
	{ .module_id = PVR2_CLIENT_ID_CX25840 },
};

static const struct pvr2_device_desc pvr2_device_160000 = {
		.description = "WinTV HVR-1975 Model 160000",
		.shortname = "160000",
		.client_table.lst = pvr2_cli_160xxx,
		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
		.default_tuner_type = TUNER_ABSENT,
		.flag_has_cx25840 = 1,
		.flag_has_hauppauge_rom = 1,
		.flag_has_analogtuner = 1,
		.flag_has_composite = 1,
		.flag_has_svideo = 1,
		.flag_fx2_16kb = 1,
		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
		.default_std_mask = V4L2_STD_NTSC_M,
		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
		.dvb_props = &pvr2_160000_dvb_props,
#endif
};

static const struct pvr2_device_desc pvr2_device_160111 = {
		.description = "WinTV HVR-1955 Model 160111",
		.shortname = "160111",
		.client_table.lst = pvr2_cli_160xxx,
		.client_table.cnt = ARRAY_SIZE(pvr2_cli_160xxx),
		.fx2_firmware.lst = pvr2_fw1_names_160xxx,
		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_160xxx),
		.default_tuner_type = TUNER_ABSENT,
		.flag_has_cx25840 = 1,
		.flag_has_hauppauge_rom = 1,
		.flag_has_analogtuner = 1,
		.flag_has_composite = 1,
		.flag_has_svideo = 1,
		.flag_fx2_16kb = 1,
		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
		.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
		.default_std_mask = V4L2_STD_NTSC_M,
		.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
		.ir_scheme = PVR2_IR_SCHEME_ZILOG,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
		.dvb_props = &pvr2_160111_dvb_props,
#endif
};

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

@@ -552,6 +714,10 @@ struct usb_device_id pvr2_device_table[] = {
	  .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
	{ USB_DEVICE(0x0ccd, 0x0039),
	  .driver_info = (kernel_ulong_t)&pvr2_device_av400},
	{ USB_DEVICE(0x2040, 0x7502),
	  .driver_info = (kernel_ulong_t)&pvr2_device_160111},
	{ USB_DEVICE(0x2040, 0x7510),
	  .driver_info = (kernel_ulong_t)&pvr2_device_160000},
	{ }
};

+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct pvr2_string_table {
#define PVR2_ROUTING_SCHEME_GOTVIEW 1
#define PVR2_ROUTING_SCHEME_ONAIR 2
#define PVR2_ROUTING_SCHEME_AV400 3
#define PVR2_ROUTING_SCHEME_HAUP160XXX 4

#define PVR2_DIGITAL_SCHEME_NONE 0
#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@

#define FX2CMD_FWPOST1          0x52u

/* These 2 only exist on Model 160xxx */
#define FX2CMD_HCW_DEMOD_RESET_PIN 0xd4u
#define FX2CMD_HCW_MAKO_SLEEP_PIN  0xd5u

#define FX2CMD_POWER_OFF        0xdcu
#define FX2CMD_POWER_ON         0xdeu

Loading