Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285723
b: refs/heads/master
c: 8ab3362
h: refs/heads/master
i:
  285721: 9f6d98c
  285719: a15c331
v: v3
  • Loading branch information
Holger Nelson authored and Mauro Carvalho Chehab committed Jan 6, 2012
1 parent 9606ce4 commit 9c874cd
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 137 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: 4d28d3d9978b84326a4608c25bda484973bba0a6
refs/heads/master: 8ab3362665a699bd54fc489ff7fb6372678b94c1
2 changes: 1 addition & 1 deletion trunk/drivers/media/video/em28xx/em28xx-audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)

urb->dev = dev->udev;
urb->context = dev;
urb->pipe = usb_rcvisocpipe(dev->udev, 0x83);
urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = dev->adev.transfer_buffer[i];
urb->interval = 1;
Expand Down
148 changes: 72 additions & 76 deletions trunk/drivers/media/video/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -3111,12 +3111,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
static int em28xx_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
const struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev;
struct em28xx *dev = NULL;
int retval;
bool is_audio_only = false, has_audio = false;
int i, nr, isoc_pipe;
bool has_audio = false, has_video = false, has_dvb = false;
int i, nr;
const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
char *speed;
char descr[255] = "";
Expand Down Expand Up @@ -3148,54 +3147,65 @@ static int em28xx_usb_probe(struct usb_interface *interface,
goto err;
}

/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
em28xx_err(DRIVER_NAME ": out of memory!\n");
retval = -ENOMEM;
goto err;
}

/* compute alternate max packet sizes */
dev->alt_max_pkt_size = kmalloc(sizeof(dev->alt_max_pkt_size[0]) *
interface->num_altsetting, GFP_KERNEL);
if (dev->alt_max_pkt_size == NULL) {
em28xx_errdev("out of memory!\n");
kfree(dev);
retval = -ENOMEM;
goto err;
}

/* Get endpoints */
for (i = 0; i < interface->num_altsetting; i++) {
int ep;

for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
struct usb_host_endpoint *e;
e = &interface->altsetting[i].endpoint[ep];

if (e->desc.bEndpointAddress == 0x83)
has_audio = true;
const struct usb_endpoint_descriptor *e;
int sizedescr, size;

e = &interface->altsetting[i].endpoint[ep].desc;

sizedescr = le16_to_cpu(e->wMaxPacketSize);
size = sizedescr & 0x7ff;

if (udev->speed == USB_SPEED_HIGH)
size = size * hb_mult(sizedescr);

if (usb_endpoint_xfer_isoc(e) &&
usb_endpoint_dir_in(e)) {
switch (e->bEndpointAddress) {
case EM28XX_EP_AUDIO:
has_audio = true;
break;
case EM28XX_EP_ANALOG:
has_video = true;
dev->alt_max_pkt_size[i] = size;
break;
case EM28XX_EP_DIGITAL:
has_dvb = true;
if (size > dev->dvb_max_pkt_size) {
dev->dvb_max_pkt_size = size;
dev->dvb_alt = i;
}
break;
}
}
}
}

endpoint = &interface->cur_altsetting->endpoint[0].desc;

/* check if the device has the iso in endpoint at the correct place */
if (usb_endpoint_xfer_isoc(endpoint)
&&
(interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
/* It's a newer em2874/em2875 device */
isoc_pipe = 0;
} else {
int check_interface = 1;
isoc_pipe = 1;
endpoint = &interface->cur_altsetting->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint))
check_interface = 0;

if (usb_endpoint_dir_out(endpoint))
check_interface = 0;

if (!check_interface) {
if (has_audio) {
is_audio_only = true;
} else {
em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
"interface %i, class %i found.\n",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
ifnum,
interface->altsetting[0].desc.bInterfaceClass);
em28xx_err(DRIVER_NAME " This is an anciliary "
"interface not used by the driver\n");

retval = -ENODEV;
goto err;
}
}
if (!(has_audio || has_video || has_dvb)) {
retval = -ENODEV;
goto err_free;
}

switch (udev->speed) {
Expand All @@ -3221,6 +3231,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
strlcat(descr, " ", sizeof(descr));
strlcat(descr, udev->product, sizeof(descr));
}

if (*descr)
strlcat(descr, " ", sizeof(descr));

Expand All @@ -3237,6 +3248,14 @@ static int em28xx_usb_probe(struct usb_interface *interface,
printk(KERN_INFO DRIVER_NAME
": Audio Vendor Class interface %i found\n",
ifnum);
if (has_video)
printk(KERN_INFO DRIVER_NAME
": Video interface %i found\n",
ifnum);
if (has_dvb)
printk(KERN_INFO DRIVER_NAME
": DVB interface %i found\n",
ifnum);

/*
* Make sure we have 480 Mbps of bandwidth, otherwise things like
Expand All @@ -3248,22 +3267,14 @@ static int em28xx_usb_probe(struct usb_interface *interface,
printk(DRIVER_NAME ": Device must be connected to a high-speed"
" USB 2.0 port.\n");
retval = -ENODEV;
goto err;
}

/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
em28xx_err(DRIVER_NAME ": out of memory!\n");
retval = -ENOMEM;
goto err;
goto err_free;
}

snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr);
dev->devno = nr;
dev->model = id->driver_info;
dev->alt = -1;
dev->is_audio_only = is_audio_only;
dev->is_audio_only = has_audio && !(has_video || has_dvb);
dev->has_alsa_audio = has_audio;
dev->audio_ifnum = ifnum;

Expand All @@ -3276,26 +3287,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
}
}

/* compute alternate max packet sizes */
dev->num_alt = interface->num_altsetting;
dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);

if (dev->alt_max_pkt_size == NULL) {
em28xx_errdev("out of memory!\n");
kfree(dev);
retval = -ENOMEM;
goto err;
}

for (i = 0; i < dev->num_alt ; i++) {
u16 tmp = le16_to_cpu(interface->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
unsigned int size = tmp & 0x7ff;

if (udev->speed == USB_SPEED_HIGH)
size = size * hb_mult(tmp);

dev->alt_max_pkt_size[i] = size;
}

if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
dev->model = card[nr];
Expand All @@ -3308,10 +3300,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
mutex_lock(&dev->lock);
retval = em28xx_init_dev(&dev, udev, interface, nr);
if (retval) {
mutex_unlock(&dev->lock);
kfree(dev->alt_max_pkt_size);
kfree(dev);
goto err;
goto unlock_and_free;
}

request_modules(dev);
Expand All @@ -3330,6 +3319,13 @@ static int em28xx_usb_probe(struct usb_interface *interface,

return 0;

unlock_and_free:
mutex_unlock(&dev->lock);

err_free:
kfree(dev->alt_max_pkt_size);
kfree(dev);

err:
clear_bit(nr, &em28xx_devused);

Expand Down
59 changes: 2 additions & 57 deletions trunk/drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
should also be using 'desc.bInterval'
*/
pipe = usb_rcvisocpipe(dev->udev,
dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84);
dev->mode == EM28XX_ANALOG_MODE ?
EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL);

usb_fill_int_urb(urb, dev->udev, pipe,
dev->isoc_ctl.transfer_buffer[i], sb_size,
Expand Down Expand Up @@ -1108,62 +1109,6 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
}
EXPORT_SYMBOL_GPL(em28xx_init_isoc);

/* Determine the packet size for the DVB stream for the given device
(underlying value programmed into the eeprom) */
int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
{
unsigned int chip_cfg2;
unsigned int packet_size;

switch (dev->chip_id) {
case CHIP_ID_EM2710:
case CHIP_ID_EM2750:
case CHIP_ID_EM2800:
case CHIP_ID_EM2820:
case CHIP_ID_EM2840:
case CHIP_ID_EM2860:
/* No DVB support */
return -EINVAL;
case CHIP_ID_EM2870:
case CHIP_ID_EM2883:
/* TS max packet size stored in bits 1-0 of R01 */
chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
packet_size = 188;
break;
case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
packet_size = 376;
break;
case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
packet_size = 564;
break;
case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
packet_size = 752;
break;
}
break;
case CHIP_ID_EM2874:
/*
* FIXME: for now assumes 564 like it was before, but the
* em2874 code should be added to return the proper value
*/
packet_size = 564;
break;
case CHIP_ID_EM2884:
case CHIP_ID_EM28174:
default:
/*
* FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
* but not enough for 44 Mbit DVB-C.
*/
packet_size = 752;
}

return packet_size;
}
EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);

/*
* em28xx_wake_i2c()
* configure i2c attached devices
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/media/video/em28xx/em28xx-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb)
struct em28xx *dev = dvb->adapter.priv;
int max_dvb_packet_size;

usb_set_interface(dev->udev, 0, 1);
usb_set_interface(dev->udev, 0, dev->dvb_alt);
rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
if (rc < 0)
return rc;

max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
max_dvb_packet_size = dev->dvb_max_pkt_size;
if (max_dvb_packet_size < 0)
return max_dvb_packet_size;
dprintk(1, "Using %d buffers each with %d bytes\n",
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
#define EM_GPO_2 (1 << 2)
#define EM_GPO_3 (1 << 3)

/* em28xx endpoints */
#define EM28XX_EP_ANALOG 0x82
#define EM28XX_EP_AUDIO 0x83
#define EM28XX_EP_DIGITAL 0x84

/* em2800 registers */
#define EM2800_R08_AUDIOSRC 0x08

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@ struct em28xx {
int max_pkt_size; /* max packet size of isoc transaction */
int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
int dvb_alt; /* alternate for DVB */
unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
transfer */
Expand Down

0 comments on commit 9c874cd

Please sign in to comment.