Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 92693
b: refs/heads/master
c: c67ec53
h: refs/heads/master
i:
  92691: 5688a40
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Apr 24, 2008
1 parent 348cd27 commit de6a6d7
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 76 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 82ac4f876505615ba9dc6a73cd9a584bad8fe23f
refs/heads/master: c67ec53f8f4e90ebd482789e2f6d121f41a0bd90
81 changes: 34 additions & 47 deletions trunk/drivers/media/video/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,19 +436,25 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);

/* Board Hauppauge WinTV HVR 900 analog */
struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
{ -1, -1, 6},
{EM28XX_R08_GPIO, 0x2d, 10},
{EM28XX_R08_GPIO, 0x3d, 5},
{ -1, -1, -1},
{EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
{0x05, 0xff, 0x10, 10},
{ -1, -1, -1, -1},
};

/* Board Hauppauge WinTV HVR 900 digital */
struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
{ -1, -1, 6},
{EM28XX_R08_GPIO, 0x2e, 6},
{EM28XX_R08_GPIO, 0x3e, 6},
{EM2880_R04_GPO, 0x04, 10},
{EM2880_R04_GPO, 0x0c, 10},
{ -1, -1, -1},
{EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x04, 0x0f, 10},
{EM2880_R04_GPO, 0x0c, 0x0f, 10},
{ -1, -1, -1, -1},
};

/* Board Hauppauge WinTV HVR 900 tuner_callback */
struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};

/*
Expand All @@ -469,7 +475,6 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
{
int rc = 0;
struct em28xx *dev = ptr;
struct em28xx_reg_seq *gpio;

if (dev->tuner_type != TUNER_XC2028)
return 0;
Expand All @@ -478,32 +483,10 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
return 0;

if (dev->mode == EM28XX_ANALOG_MODE)
gpio = dev->analog_gpio;
rc = em28xx_gpio_set(dev, dev->tun_analog_gpio);
else
gpio = dev->digital_gpio;
rc = em28xx_gpio_set(dev, dev->tun_digital_gpio);

/* djh - Not sure if these are still required */
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);
else
dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
msleep(6);

if (!gpio)
return rc;

/* 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;
}
EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
Expand All @@ -527,6 +510,10 @@ void em28xx_pre_card_setup(struct em28xx *dev)
{
int rc;

rc = em28xx_read_reg(dev, EM2880_R04_GPO);
if (rc >= 0)
dev->reg_gpo = rc;

dev->wait_after_write = 5;
rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
if (rc > 0) {
Expand All @@ -547,24 +534,24 @@ void em28xx_pre_card_setup(struct em28xx *dev)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
case EM2880_BOARD_TERRATEC_HYBRID_XS:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\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;
/* Sets GPO/GPIO sequences for this device */
dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback;
dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;

break;
}

em28xx_gpio_set(dev, dev->tun_analog_gpio);
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);

/* Unlock device */
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
}

void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
Expand Down
90 changes: 83 additions & 7 deletions trunk/drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
unsigned char *bufs;

if (dev->state & DEV_DISCONNECTED)
return(-ENODEV);
return -ENODEV;

if (len < 1)
return -EINVAL;

bufs = kmalloc(len, GFP_KERNEL);

Expand Down Expand Up @@ -162,7 +165,23 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,

int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
{
return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
int rc;

rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);

/* Stores GPO/GPIO values at the cache, if changed
Only write values should be stored, since input on a GPIO
register will return the input bits.
Not sure what happens on reading GPO register.
*/
if (rc >= 0) {
if (reg == EM2880_R04_GPO)
dev->reg_gpo = buf[0];
else if (reg == EM28XX_R08_GPIO)
dev->reg_gpio = buf[0];
}

return rc;
}

/*
Expand All @@ -176,12 +195,19 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
int oldval;
u8 newval;

oldval = em28xx_read_reg(dev, reg);
/* Uses cache for gpo/gpio registers */
if (reg == EM2880_R04_GPO)
oldval = dev->reg_gpo;
else if (reg == EM28XX_R08_GPIO)
oldval = dev->reg_gpio;
else
oldval = em28xx_read_reg(dev, reg);

if (oldval < 0)
return oldval;

newval = (((u8) oldval) & ~bitmask) | (val & bitmask);

return em28xx_write_regs(dev, reg, &newval, 1);
}

Expand Down Expand Up @@ -472,6 +498,57 @@ int em28xx_set_alternate(struct em28xx *dev)
return 0;
}

int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
{
int rc = 0;

if (!gpio)
return rc;

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);
else
dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
msleep(6);

/* Send GPIO reset sequences specified at board entry */
while (gpio->sleep >= 0) {
if (gpio->reg >= 0) {
rc = em28xx_write_reg_bits(dev,
gpio->reg,
gpio->val,
gpio->mask);
if (rc < 0)
return rc;
}
if (gpio->sleep > 0)
msleep(gpio->sleep);

gpio++;
}
return rc;
}

int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode)
{
if (dev->mode == set_mode)
return 0;

if (set_mode == EM28XX_MODE_UNDEFINED) {
dev->mode = set_mode;
return 0;
}

dev->mode = set_mode;

if (dev->mode == EM28XX_DIGITAL_MODE)
return em28xx_gpio_set(dev, dev->digital_gpio);
else
return em28xx_gpio_set(dev, dev->analog_gpio);
}
EXPORT_SYMBOL_GPL(em28xx_set_mode);

/* ------------------------------------------------------------------
URB control
------------------------------------------------------------------*/
Expand Down Expand Up @@ -548,8 +625,7 @@ EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
*/
int em28xx_init_isoc(struct em28xx *dev, int max_packets,
int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct em28xx *dev, struct urb *urb),
int cap_type)
int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
{
struct em28xx_dmaqueue *dma_q = &dev->vidq;
int i;
Expand Down Expand Up @@ -612,7 +688,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
should also be using 'desc.bInterval'
*/
pipe = usb_rcvisocpipe(dev->udev,
cap_type == EM28XX_ANALOG_CAPTURE ? 0x82 : 0x84);
dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84);

usb_fill_int_urb(urb, dev->udev, pipe,
dev->isoc_ctl.transfer_buffer[i], sb_size,
Expand All @@ -632,7 +708,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,

init_waitqueue_head(&dma_q->wq);

em28xx_capture_start(dev, cap_type);
em28xx_capture_start(dev, 1);

/* submit urbs and enables IRQ */
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
Expand Down
20 changes: 11 additions & 9 deletions trunk/drivers/media/video/em28xx/em28xx-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,27 @@ static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb)

static int start_streaming(struct em28xx_dvb *dvb)
{
int rc;
struct em28xx *dev = dvb->adapter.priv;

usb_set_interface(dev->udev, 0, 1);
dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
if (rc < 0)
return rc;

return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS,
EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE,
dvb_isoc_copy, EM28XX_DIGITAL_CAPTURE);
dvb_isoc_copy);
}

static int stop_streaming(struct em28xx_dvb *dvb)
{
struct em28xx *dev = dvb->adapter.priv;

em28xx_uninit_isoc(dev);

em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);

return 0;
}

Expand Down Expand Up @@ -368,13 +374,10 @@ static int dvb_init(struct em28xx *dev)
}
dev->dvb = dvb;

em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
/* Enable lgdt330x */
dev->mode = EM28XX_DIGITAL_MODE;
em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0);

dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
&dev->i2c_adap);
Expand All @@ -384,9 +387,6 @@ static int dvb_init(struct em28xx *dev)
}
break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
/* Enable zl10353 */
dev->mode = EM28XX_DIGITAL_MODE;
em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0);
dvb->frontend = dvb_attach(zl10353_attach,
&em28xx_zl10353_with_xc3028,
&dev->i2c_adap);
Expand Down Expand Up @@ -415,10 +415,12 @@ static int dvb_init(struct em28xx *dev)
if (result < 0)
goto out_free;

em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
return 0;

out_free:
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
kfree(dvb);
dev->dvb = NULL;
return result;
Expand Down
12 changes: 10 additions & 2 deletions trunk/drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
if (urb_init) {
rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
EM28XX_NUM_BUFS, dev->max_pkt_size,
em28xx_isoc_copy, EM28XX_ANALOG_CAPTURE);
em28xx_isoc_copy);
if (rc < 0)
goto fail;
}
Expand Down Expand Up @@ -1534,8 +1534,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
em28xx_videodbg("open minor=%d type=%s users=%d\n",
minor, v4l2_type_names[fh_type], dev->users);

fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);

fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
if (!fh) {
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
return -ENOMEM;
Expand All @@ -1552,9 +1552,15 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
dev->hscale = 0;
dev->vscale = 0;

em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
em28xx_set_alternate(dev);
em28xx_resolution_set(dev);

/* Needed, since GPIO might have disabled power of
some i2c device
*/
em28xx_config_i2c(dev);

}
if (fh->radio) {
em28xx_videodbg("video_open: setting radio device\n");
Expand All @@ -1568,6 +1574,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
sizeof(struct em28xx_buffer), fh);

mutex_unlock(&dev->lock);

return errCode;
}

Expand Down Expand Up @@ -1647,6 +1654,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)

/* do this before setting alternate! */
em28xx_uninit_isoc(dev);
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);

/* set alternate 0 */
dev->alt = 0;
Expand Down
Loading

0 comments on commit de6a6d7

Please sign in to comment.