Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 102a0b08 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (7604): em28xx-dvb: Fix analog mode



The analog entries are wrong. Fix it.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 3421b778
Loading
Loading
Loading
Loading
+59 −90
Original line number Diff line number Diff line
@@ -171,26 +171,6 @@ struct em28xx_board em28xx_boards[] = {
			.vmux     = TVP5150_SVIDEO,
			.amux     = 1,
		} },
		.analog_gpio = {
			{		/* xc3028 reset seq */
				.reg = 0x08,
				.val = 0x2d,
				.rst = 0x3d,
				.t1 = 5,
				.t2 = 10,
				.t3 = 5,
			},
		},
		.digital_gpio = {
			{		/* xc3028 reset seq */
				.reg = 0x08,
				.val = 0x2e,
				.rst = 0x3e,
				.t1 = 6,
				.t2 = 6,
				.t3 = 6,
			}
		},
	},
	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
		.name           = "Hauppauge WinTV HVR 950",
@@ -214,32 +194,6 @@ struct em28xx_board em28xx_boards[] = {
			.vmux     = TVP5150_SVIDEO,
			.amux     = 1,
		} },
		.analog_gpio = {
			{		/* xc3028 reset seq */
				.reg = 0x08,
				.val = 0x2d,
				.rst = 0x3d,
				.t1 = 5,
				.t2 = 10,
				.t3 = 5,
			},
		},
		.digital_gpio = {
			{		/* xc3028 reset seq */
				.reg = 0x08,
				.val = 0x2e,
				.rst = 0x3e,
				.t1 = 6,
				.t2 = 6,
				.t3 = 6,
			}, {		/* demod reset seq */
				.reg = 0x04,
				.val = 0x04,
				.rst = 0x0c,
				.t2 = 10,
				.t3 = 10,
			}
		},
	},
	[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
		.name         = "Terratec Hybrid XS",
@@ -476,7 +430,28 @@ struct usb_device_id em28xx_id_table [] = {
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);

/* EEPROM hash table for devices with generic USB IDs */
/*
 *  Reset sequences for analog/digital modes
 */

/* Board Hauppauge WinTV HVR 900 analog */
struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
	{  -1,   -1,   6},
	{0x08, 0x2d,  10},
	{0x08, 0x3d,   5},
	{ -1,    -1,  -1},
};
/* Board Hauppauge WinTV HVR 900 digital */
struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
	{  -1,   -1,   6},
	{0x08, 0x2e,   6},
	{0x08, 0x3e,   6},
	{ -1,    -1,  -1},
};

/*
 * EEPROM hash table for devices with generic USB IDs
 */
static struct em28xx_hash_table em28xx_eeprom_hash [] = {
	/* P/N: SA 60002070465 Tuner: TVF7533-MF */
	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
@@ -490,9 +465,9 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {

int em28xx_tuner_callback(void *ptr, int command, int arg)
{
	int rc = 0, i;
	int rc = 0;
	struct em28xx *dev = ptr;
	struct gpio_ctl *gpio_ctl;
	struct em28xx_reg_seq *gpio;

	if (dev->tuner_type != TUNER_XC2028)
		return 0;
@@ -501,44 +476,31 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
		return 0;

	if (dev->mode == EM28XX_ANALOG_MODE)
		gpio_ctl = dev->analog_gpio;
		gpio = dev->analog_gpio;
	else
		gpio_ctl = dev->digital_gpio;
		gpio = dev->digital_gpio;

	/* djh - Not sure if these are still required */
	if (dev->mode == EM28XX_ANALOG_MODE) {
	dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
	if (dev->mode == EM28XX_ANALOG_MODE)
		dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
	  msleep(6);
	} else {
	  dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
	else
		dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
	msleep(6);
	}

	/* Send GPIO reset sequences specified at board entry */
	for (i = 0; i < MAX_GPIO; i++) {
		if (!gpio_ctl->val)
			break;

		dev->em28xx_write_regs(dev,
				       gpio_ctl->reg,
				       &gpio_ctl->val, 1);
		if (gpio_ctl->t1)
			msleep(gpio_ctl->t1);

		if (!gpio_ctl->rst) {
			gpio_ctl++;
			continue;
		}

		dev->em28xx_write_regs(dev,
				       gpio_ctl->reg,
				       &gpio_ctl->rst, 1);
		if (gpio_ctl->t2)
			msleep(gpio_ctl->t2);
	if (!gpio)
		return rc;

		gpio_ctl++;
	/* Send GPIO reset sequences specified at board entry */
	while (gpio->sleep >= 0) {
		if (gpio->reg >= 0)
			rc = dev->em28xx_write_regs(dev,
						    gpio->reg,
						    &gpio->val, 1);
		if (gpio->sleep > 0)
			msleep(gpio->sleep);

		gpio++;
	}
	return rc;
}
@@ -554,8 +516,6 @@ static void em28xx_set_model(struct em28xx *dev)
	dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
	dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
	dev->has_dvb = em28xx_boards[dev->model].has_dvb;
	dev->analog_gpio = em28xx_boards[dev->model].analog_gpio;
	dev->digital_gpio = em28xx_boards[dev->model].digital_gpio;
}

/* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -573,13 +533,22 @@ void em28xx_pre_card_setup(struct em28xx *dev)
	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
		em28xx_write_regs(dev, XCLK_REG, "\x27", 1);
		em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1);
	}
		em28xx_write_regs(dev, 0x08, "\xff", 1);
		em28xx_write_regs(dev, 0x04, "\x00", 1);
		msleep(100);
		em28xx_write_regs(dev, 0x04, "\x08", 1);
		msleep(100);
		em28xx_write_regs(dev, 0x08, "\xff", 1);
		msleep(50);
		em28xx_write_regs(dev, 0x08, "\x2d", 1);
		msleep(50);
		em28xx_write_regs(dev, 0x08, "\x3d", 1);

		dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
		dev->digital_gpio = hauppauge_wintv_hvr_900_digital;

	/* Put xc2028 tuners and demods into a sane state */
	if (dev->tuner_type == TUNER_XC2028) {
		dev->mode = EM28XX_ANALOG_MODE;
		em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0);
	};
		break;
	}
}

void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
+2 −7
Original line number Diff line number Diff line
@@ -331,22 +331,17 @@ int em28xx_capture_start(struct em28xx *dev, int start)
	if (!start) {
		/* disable video capture */
		rc = em28xx_write_regs(dev, VINENABLE_REG, "\x27", 1);
		if (rc < 0)
		return rc;
	}

	/* enable video capture */
	rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
	if (rc < 0)
		return rc;

	if (dev->mode == EM28XX_ANALOG_MODE)
		rc = em28xx_write_regs(dev, VINENABLE_REG,"\x67", 1);
	else
		rc = em28xx_write_regs(dev, VINENABLE_REG,"\x37", 1);

	if (rc < 0)
		return rc;

	msleep (6);

	return rc;
+1 −0
Original line number Diff line number Diff line
@@ -414,6 +414,7 @@ static int dvb_init(struct em28xx *dev)
		goto out_free;
	}

	printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
	return 0;

out_free:
+5 −17
Original line number Diff line number Diff line
@@ -225,19 +225,10 @@ enum em28xx_decoder {
	EM28XX_SAA7114
};

#define MAX_GPIO 2
struct gpio_ctl {
		/* Register to be set */
	unsigned char reg;
		/* Initial/final value */
struct em28xx_reg_seq {
	int reg;
	unsigned char val;
		/* reset value - if set, it will do:
		   val1 - val2 - val1
		 */
	unsigned char rst;
		/* Sleep times
		 */
	unsigned int  t1, t2, t3;
	int sleep;
};

struct em28xx_board {
@@ -255,9 +246,6 @@ struct em28xx_board {
	unsigned int max_range_640_480:1;
	unsigned int has_dvb:1;

	struct gpio_ctl analog_gpio[MAX_GPIO];
	struct gpio_ctl digital_gpio[MAX_GPIO];

	enum em28xx_decoder decoder;

	struct em28xx_input       input[MAX_EM28XX_INPUT];
@@ -343,8 +331,8 @@ struct em28xx {
	unsigned int max_range_640_480:1;
	unsigned int has_dvb:1;

	struct gpio_ctl *analog_gpio;
	struct gpio_ctl *digital_gpio;
	/* GPIO sequences for tuner callback */
	struct em28xx_reg_seq *analog_gpio, *digital_gpio;

	int video_inputs;	/* number of video inputs */
	struct list_head	devlist;