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

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
...@@ -171,26 +171,6 @@ struct em28xx_board em28xx_boards[] = { ...@@ -171,26 +171,6 @@ struct em28xx_board em28xx_boards[] = {
.vmux = TVP5150_SVIDEO, .vmux = TVP5150_SVIDEO,
.amux = 1, .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] = { [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
.name = "Hauppauge WinTV HVR 950", .name = "Hauppauge WinTV HVR 950",
...@@ -214,32 +194,6 @@ struct em28xx_board em28xx_boards[] = { ...@@ -214,32 +194,6 @@ struct em28xx_board em28xx_boards[] = {
.vmux = TVP5150_SVIDEO, .vmux = TVP5150_SVIDEO,
.amux = 1, .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] = { [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
.name = "Terratec Hybrid XS", .name = "Terratec Hybrid XS",
...@@ -476,7 +430,28 @@ struct usb_device_id em28xx_id_table [] = { ...@@ -476,7 +430,28 @@ struct usb_device_id em28xx_id_table [] = {
}; };
MODULE_DEVICE_TABLE(usb, 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 [] = { static struct em28xx_hash_table em28xx_eeprom_hash [] = {
/* P/N: SA 60002070465 Tuner: TVF7533-MF */ /* P/N: SA 60002070465 Tuner: TVF7533-MF */
{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
...@@ -490,9 +465,9 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { ...@@ -490,9 +465,9 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
int em28xx_tuner_callback(void *ptr, int command, int arg) int em28xx_tuner_callback(void *ptr, int command, int arg)
{ {
int rc = 0, i; int rc = 0;
struct em28xx *dev = ptr; struct em28xx *dev = ptr;
struct gpio_ctl *gpio_ctl; struct em28xx_reg_seq *gpio;
if (dev->tuner_type != TUNER_XC2028) if (dev->tuner_type != TUNER_XC2028)
return 0; return 0;
...@@ -501,44 +476,31 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) ...@@ -501,44 +476,31 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
return 0; return 0;
if (dev->mode == EM28XX_ANALOG_MODE) if (dev->mode == EM28XX_ANALOG_MODE)
gpio_ctl = dev->analog_gpio; gpio = dev->analog_gpio;
else else
gpio_ctl = dev->digital_gpio; gpio = dev->digital_gpio;
/* djh - Not sure if these are still required */ /* djh - Not sure if these are still required */
if (dev->mode == EM28XX_ANALOG_MODE) {
dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); 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); dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
msleep(6); else
} else {
dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
msleep(6); 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) { if (!gpio)
gpio_ctl++; return rc;
continue;
}
dev->em28xx_write_regs(dev,
gpio_ctl->reg,
&gpio_ctl->rst, 1);
if (gpio_ctl->t2)
msleep(gpio_ctl->t2);
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; return rc;
} }
...@@ -554,8 +516,6 @@ static void em28xx_set_model(struct em28xx *dev) ...@@ -554,8 +516,6 @@ static void em28xx_set_model(struct em28xx *dev)
dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; 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->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
dev->has_dvb = em28xx_boards[dev->model].has_dvb; 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, /* Since em28xx_pre_card_setup() requires a proper dev->model,
...@@ -573,13 +533,22 @@ void em28xx_pre_card_setup(struct em28xx *dev) ...@@ -573,13 +533,22 @@ void em28xx_pre_card_setup(struct em28xx *dev)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
em28xx_write_regs(dev, XCLK_REG, "\x27", 1); em28xx_write_regs(dev, XCLK_REG, "\x27", 1);
em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 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 */ break;
if (dev->tuner_type == TUNER_XC2028) { }
dev->mode = EM28XX_ANALOG_MODE;
em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0);
};
} }
void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
......
...@@ -331,22 +331,17 @@ int em28xx_capture_start(struct em28xx *dev, int start) ...@@ -331,22 +331,17 @@ int em28xx_capture_start(struct em28xx *dev, int start)
if (!start) { if (!start) {
/* disable video capture */ /* disable video capture */
rc = em28xx_write_regs(dev, VINENABLE_REG, "\x27", 1); rc = em28xx_write_regs(dev, VINENABLE_REG, "\x27", 1);
if (rc < 0)
return rc; return rc;
} }
/* enable video capture */ /* enable video capture */
rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
if (rc < 0)
return rc;
if (dev->mode == EM28XX_ANALOG_MODE) if (dev->mode == EM28XX_ANALOG_MODE)
rc = em28xx_write_regs(dev, VINENABLE_REG,"\x67", 1); rc = em28xx_write_regs(dev, VINENABLE_REG,"\x67", 1);
else else
rc = em28xx_write_regs(dev, VINENABLE_REG,"\x37", 1); rc = em28xx_write_regs(dev, VINENABLE_REG,"\x37", 1);
if (rc < 0)
return rc;
msleep (6); msleep (6);
return rc; return rc;
......
...@@ -414,6 +414,7 @@ static int dvb_init(struct em28xx *dev) ...@@ -414,6 +414,7 @@ static int dvb_init(struct em28xx *dev)
goto out_free; goto out_free;
} }
printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
return 0; return 0;
out_free: out_free:
......
...@@ -225,19 +225,10 @@ enum em28xx_decoder { ...@@ -225,19 +225,10 @@ enum em28xx_decoder {
EM28XX_SAA7114 EM28XX_SAA7114
}; };
#define MAX_GPIO 2 struct em28xx_reg_seq {
struct gpio_ctl { int reg;
/* Register to be set */
unsigned char reg;
/* Initial/final value */
unsigned char val; unsigned char val;
/* reset value - if set, it will do: int sleep;
val1 - val2 - val1
*/
unsigned char rst;
/* Sleep times
*/
unsigned int t1, t2, t3;
}; };
struct em28xx_board { struct em28xx_board {
...@@ -255,9 +246,6 @@ struct em28xx_board { ...@@ -255,9 +246,6 @@ struct em28xx_board {
unsigned int max_range_640_480:1; unsigned int max_range_640_480:1;
unsigned int has_dvb:1; unsigned int has_dvb:1;
struct gpio_ctl analog_gpio[MAX_GPIO];
struct gpio_ctl digital_gpio[MAX_GPIO];
enum em28xx_decoder decoder; enum em28xx_decoder decoder;
struct em28xx_input input[MAX_EM28XX_INPUT]; struct em28xx_input input[MAX_EM28XX_INPUT];
...@@ -343,8 +331,8 @@ struct em28xx { ...@@ -343,8 +331,8 @@ struct em28xx {
unsigned int max_range_640_480:1; unsigned int max_range_640_480:1;
unsigned int has_dvb:1; unsigned int has_dvb:1;
struct gpio_ctl *analog_gpio; /* GPIO sequences for tuner callback */
struct gpio_ctl *digital_gpio; struct em28xx_reg_seq *analog_gpio, *digital_gpio;
int video_inputs; /* number of video inputs */ int video_inputs; /* number of video inputs */
struct list_head devlist; struct list_head devlist;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment