aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHolger Nelson <hnelson@hnelson.de>2011-12-28 16:55:41 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-06 08:37:07 -0500
commit8ab3362665a699bd54fc489ff7fb6372678b94c1 (patch)
tree05baa99a41717f5abdd9f690488d22ffe63c0833 /drivers
parent4d28d3d9978b84326a4608c25bda484973bba0a6 (diff)
[media] em28xx: Reworked probe code to get rid of some hacks
Reworked device probing to get rid of hacks to guess the maximum size of dvb iso transfer packets. The new code also selects the first alternate config which supports the largest possible iso transfers for dvb. [mchehab@redhat.com: Fix a few checkpatch.pl CodingStyle compliants] Signed-off-by: Holger Nelson <hnelson@hnelson.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c148
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c59
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c4
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h5
-rw-r--r--drivers/media/video/em28xx/em28xx.h2
6 files changed, 84 insertions, 136 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index cff0768afbf5..e2a7b77c39c7 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -193,7 +193,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
193 193
194 urb->dev = dev->udev; 194 urb->dev = dev->udev;
195 urb->context = dev; 195 urb->context = dev;
196 urb->pipe = usb_rcvisocpipe(dev->udev, 0x83); 196 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
197 urb->transfer_flags = URB_ISO_ASAP; 197 urb->transfer_flags = URB_ISO_ASAP;
198 urb->transfer_buffer = dev->adev.transfer_buffer[i]; 198 urb->transfer_buffer = dev->adev.transfer_buffer[i];
199 urb->interval = 1; 199 urb->interval = 1;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index b95e66146501..0adaf8402a85 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -3111,12 +3111,11 @@ unregister_dev:
3111static int em28xx_usb_probe(struct usb_interface *interface, 3111static int em28xx_usb_probe(struct usb_interface *interface,
3112 const struct usb_device_id *id) 3112 const struct usb_device_id *id)
3113{ 3113{
3114 const struct usb_endpoint_descriptor *endpoint;
3115 struct usb_device *udev; 3114 struct usb_device *udev;
3116 struct em28xx *dev = NULL; 3115 struct em28xx *dev = NULL;
3117 int retval; 3116 int retval;
3118 bool is_audio_only = false, has_audio = false; 3117 bool has_audio = false, has_video = false, has_dvb = false;
3119 int i, nr, isoc_pipe; 3118 int i, nr;
3120 const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; 3119 const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
3121 char *speed; 3120 char *speed;
3122 char descr[255] = ""; 3121 char descr[255] = "";
@@ -3148,54 +3147,65 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3148 goto err; 3147 goto err;
3149 } 3148 }
3150 3149
3150 /* allocate memory for our device state and initialize it */
3151 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
3152 if (dev == NULL) {
3153 em28xx_err(DRIVER_NAME ": out of memory!\n");
3154 retval = -ENOMEM;
3155 goto err;
3156 }
3157
3158 /* compute alternate max packet sizes */
3159 dev->alt_max_pkt_size = kmalloc(sizeof(dev->alt_max_pkt_size[0]) *
3160 interface->num_altsetting, GFP_KERNEL);
3161 if (dev->alt_max_pkt_size == NULL) {
3162 em28xx_errdev("out of memory!\n");
3163 kfree(dev);
3164 retval = -ENOMEM;
3165 goto err;
3166 }
3167
3151 /* Get endpoints */ 3168 /* Get endpoints */
3152 for (i = 0; i < interface->num_altsetting; i++) { 3169 for (i = 0; i < interface->num_altsetting; i++) {
3153 int ep; 3170 int ep;
3154 3171
3155 for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { 3172 for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
3156 struct usb_host_endpoint *e; 3173 const struct usb_endpoint_descriptor *e;
3157 e = &interface->altsetting[i].endpoint[ep]; 3174 int sizedescr, size;
3158 3175
3159 if (e->desc.bEndpointAddress == 0x83) 3176 e = &interface->altsetting[i].endpoint[ep].desc;
3160 has_audio = true; 3177
3178 sizedescr = le16_to_cpu(e->wMaxPacketSize);
3179 size = sizedescr & 0x7ff;
3180
3181 if (udev->speed == USB_SPEED_HIGH)
3182 size = size * hb_mult(sizedescr);
3183
3184 if (usb_endpoint_xfer_isoc(e) &&
3185 usb_endpoint_dir_in(e)) {
3186 switch (e->bEndpointAddress) {
3187 case EM28XX_EP_AUDIO:
3188 has_audio = true;
3189 break;
3190 case EM28XX_EP_ANALOG:
3191 has_video = true;
3192 dev->alt_max_pkt_size[i] = size;
3193 break;
3194 case EM28XX_EP_DIGITAL:
3195 has_dvb = true;
3196 if (size > dev->dvb_max_pkt_size) {
3197 dev->dvb_max_pkt_size = size;
3198 dev->dvb_alt = i;
3199 }
3200 break;
3201 }
3202 }
3161 } 3203 }
3162 } 3204 }
3163 3205
3164 endpoint = &interface->cur_altsetting->endpoint[0].desc; 3206 if (!(has_audio || has_video || has_dvb)) {
3165 3207 retval = -ENODEV;
3166 /* check if the device has the iso in endpoint at the correct place */ 3208 goto err_free;
3167 if (usb_endpoint_xfer_isoc(endpoint)
3168 &&
3169 (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) {
3170 /* It's a newer em2874/em2875 device */
3171 isoc_pipe = 0;
3172 } else {
3173 int check_interface = 1;
3174 isoc_pipe = 1;
3175 endpoint = &interface->cur_altsetting->endpoint[1].desc;
3176 if (!usb_endpoint_xfer_isoc(endpoint))
3177 check_interface = 0;
3178
3179 if (usb_endpoint_dir_out(endpoint))
3180 check_interface = 0;
3181
3182 if (!check_interface) {
3183 if (has_audio) {
3184 is_audio_only = true;
3185 } else {
3186 em28xx_err(DRIVER_NAME " video device (%04x:%04x): "
3187 "interface %i, class %i found.\n",
3188 le16_to_cpu(udev->descriptor.idVendor),
3189 le16_to_cpu(udev->descriptor.idProduct),
3190 ifnum,
3191 interface->altsetting[0].desc.bInterfaceClass);
3192 em28xx_err(DRIVER_NAME " This is an anciliary "
3193 "interface not used by the driver\n");
3194
3195 retval = -ENODEV;
3196 goto err;
3197 }
3198 }
3199 } 3209 }
3200 3210
3201 switch (udev->speed) { 3211 switch (udev->speed) {
@@ -3221,6 +3231,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3221 strlcat(descr, " ", sizeof(descr)); 3231 strlcat(descr, " ", sizeof(descr));
3222 strlcat(descr, udev->product, sizeof(descr)); 3232 strlcat(descr, udev->product, sizeof(descr));
3223 } 3233 }
3234
3224 if (*descr) 3235 if (*descr)
3225 strlcat(descr, " ", sizeof(descr)); 3236 strlcat(descr, " ", sizeof(descr));
3226 3237
@@ -3237,6 +3248,14 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3237 printk(KERN_INFO DRIVER_NAME 3248 printk(KERN_INFO DRIVER_NAME
3238 ": Audio Vendor Class interface %i found\n", 3249 ": Audio Vendor Class interface %i found\n",
3239 ifnum); 3250 ifnum);
3251 if (has_video)
3252 printk(KERN_INFO DRIVER_NAME
3253 ": Video interface %i found\n",
3254 ifnum);
3255 if (has_dvb)
3256 printk(KERN_INFO DRIVER_NAME
3257 ": DVB interface %i found\n",
3258 ifnum);
3240 3259
3241 /* 3260 /*
3242 * Make sure we have 480 Mbps of bandwidth, otherwise things like 3261 * Make sure we have 480 Mbps of bandwidth, otherwise things like
@@ -3248,22 +3267,14 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3248 printk(DRIVER_NAME ": Device must be connected to a high-speed" 3267 printk(DRIVER_NAME ": Device must be connected to a high-speed"
3249 " USB 2.0 port.\n"); 3268 " USB 2.0 port.\n");
3250 retval = -ENODEV; 3269 retval = -ENODEV;
3251 goto err; 3270 goto err_free;
3252 }
3253
3254 /* allocate memory for our device state and initialize it */
3255 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
3256 if (dev == NULL) {
3257 em28xx_err(DRIVER_NAME ": out of memory!\n");
3258 retval = -ENOMEM;
3259 goto err;
3260 } 3271 }
3261 3272
3262 snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr); 3273 snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr);
3263 dev->devno = nr; 3274 dev->devno = nr;
3264 dev->model = id->driver_info; 3275 dev->model = id->driver_info;
3265 dev->alt = -1; 3276 dev->alt = -1;
3266 dev->is_audio_only = is_audio_only; 3277 dev->is_audio_only = has_audio && !(has_video || has_dvb);
3267 dev->has_alsa_audio = has_audio; 3278 dev->has_alsa_audio = has_audio;
3268 dev->audio_ifnum = ifnum; 3279 dev->audio_ifnum = ifnum;
3269 3280
@@ -3276,26 +3287,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3276 } 3287 }
3277 } 3288 }
3278 3289
3279 /* compute alternate max packet sizes */
3280 dev->num_alt = interface->num_altsetting; 3290 dev->num_alt = interface->num_altsetting;
3281 dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL);
3282
3283 if (dev->alt_max_pkt_size == NULL) {
3284 em28xx_errdev("out of memory!\n");
3285 kfree(dev);
3286 retval = -ENOMEM;
3287 goto err;
3288 }
3289
3290 for (i = 0; i < dev->num_alt ; i++) {
3291 u16 tmp = le16_to_cpu(interface->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
3292 unsigned int size = tmp & 0x7ff;
3293
3294 if (udev->speed == USB_SPEED_HIGH)
3295 size = size * hb_mult(tmp);
3296
3297 dev->alt_max_pkt_size[i] = size;
3298 }
3299 3291
3300 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) 3292 if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
3301 dev->model = card[nr]; 3293 dev->model = card[nr];
@@ -3308,10 +3300,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3308 mutex_lock(&dev->lock); 3300 mutex_lock(&dev->lock);
3309 retval = em28xx_init_dev(&dev, udev, interface, nr); 3301 retval = em28xx_init_dev(&dev, udev, interface, nr);
3310 if (retval) { 3302 if (retval) {
3311 mutex_unlock(&dev->lock); 3303 goto unlock_and_free;
3312 kfree(dev->alt_max_pkt_size);
3313 kfree(dev);
3314 goto err;
3315 } 3304 }
3316 3305
3317 request_modules(dev); 3306 request_modules(dev);
@@ -3330,6 +3319,13 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3330 3319
3331 return 0; 3320 return 0;
3332 3321
3322unlock_and_free:
3323 mutex_unlock(&dev->lock);
3324
3325err_free:
3326 kfree(dev->alt_max_pkt_size);
3327 kfree(dev);
3328
3333err: 3329err:
3334 clear_bit(nr, &em28xx_devused); 3330 clear_bit(nr, &em28xx_devused);
3335 3331
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 2982a061cbae..0aacc96f9a23 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1070,7 +1070,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1070 should also be using 'desc.bInterval' 1070 should also be using 'desc.bInterval'
1071 */ 1071 */
1072 pipe = usb_rcvisocpipe(dev->udev, 1072 pipe = usb_rcvisocpipe(dev->udev,
1073 dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84); 1073 dev->mode == EM28XX_ANALOG_MODE ?
1074 EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL);
1074 1075
1075 usb_fill_int_urb(urb, dev->udev, pipe, 1076 usb_fill_int_urb(urb, dev->udev, pipe,
1076 dev->isoc_ctl.transfer_buffer[i], sb_size, 1077 dev->isoc_ctl.transfer_buffer[i], sb_size,
@@ -1108,62 +1109,6 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1108} 1109}
1109EXPORT_SYMBOL_GPL(em28xx_init_isoc); 1110EXPORT_SYMBOL_GPL(em28xx_init_isoc);
1110 1111
1111/* Determine the packet size for the DVB stream for the given device
1112 (underlying value programmed into the eeprom) */
1113int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
1114{
1115 unsigned int chip_cfg2;
1116 unsigned int packet_size;
1117
1118 switch (dev->chip_id) {
1119 case CHIP_ID_EM2710:
1120 case CHIP_ID_EM2750:
1121 case CHIP_ID_EM2800:
1122 case CHIP_ID_EM2820:
1123 case CHIP_ID_EM2840:
1124 case CHIP_ID_EM2860:
1125 /* No DVB support */
1126 return -EINVAL;
1127 case CHIP_ID_EM2870:
1128 case CHIP_ID_EM2883:
1129 /* TS max packet size stored in bits 1-0 of R01 */
1130 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
1131 switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
1132 case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
1133 packet_size = 188;
1134 break;
1135 case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
1136 packet_size = 376;
1137 break;
1138 case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
1139 packet_size = 564;
1140 break;
1141 case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
1142 packet_size = 752;
1143 break;
1144 }
1145 break;
1146 case CHIP_ID_EM2874:
1147 /*
1148 * FIXME: for now assumes 564 like it was before, but the
1149 * em2874 code should be added to return the proper value
1150 */
1151 packet_size = 564;
1152 break;
1153 case CHIP_ID_EM2884:
1154 case CHIP_ID_EM28174:
1155 default:
1156 /*
1157 * FIXME: same as em2874. 564 was enough for 22 Mbit DVB-T
1158 * but not enough for 44 Mbit DVB-C.
1159 */
1160 packet_size = 752;
1161 }
1162
1163 return packet_size;
1164}
1165EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);
1166
1167/* 1112/*
1168 * em28xx_wake_i2c() 1113 * em28xx_wake_i2c()
1169 * configure i2c attached devices 1114 * configure i2c attached devices
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index ac55de93c267..9449423098e0 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -164,12 +164,12 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb)
164 struct em28xx *dev = dvb->adapter.priv; 164 struct em28xx *dev = dvb->adapter.priv;
165 int max_dvb_packet_size; 165 int max_dvb_packet_size;
166 166
167 usb_set_interface(dev->udev, 0, 1); 167 usb_set_interface(dev->udev, 0, dev->dvb_alt);
168 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 168 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
169 if (rc < 0) 169 if (rc < 0)
170 return rc; 170 return rc;
171 171
172 max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev); 172 max_dvb_packet_size = dev->dvb_max_pkt_size;
173 if (max_dvb_packet_size < 0) 173 if (max_dvb_packet_size < 0)
174 return max_dvb_packet_size; 174 return max_dvb_packet_size;
175 dprintk(1, "Using %d buffers each with %d bytes\n", 175 dprintk(1, "Using %d buffers each with %d bytes\n",
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 66f792361b97..2f6268505726 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -12,6 +12,11 @@
12#define EM_GPO_2 (1 << 2) 12#define EM_GPO_2 (1 << 2)
13#define EM_GPO_3 (1 << 3) 13#define EM_GPO_3 (1 << 3)
14 14
15/* em28xx endpoints */
16#define EM28XX_EP_ANALOG 0x82
17#define EM28XX_EP_AUDIO 0x83
18#define EM28XX_EP_DIGITAL 0x84
19
15/* em2800 registers */ 20/* em2800 registers */
16#define EM2800_R08_AUDIOSRC 0x08 21#define EM2800_R08_AUDIOSRC 0x08
17 22
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 2dbb12c73339..7c3ebe2fcce5 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -598,6 +598,8 @@ struct em28xx {
598 int max_pkt_size; /* max packet size of isoc transaction */ 598 int max_pkt_size; /* max packet size of isoc transaction */
599 int num_alt; /* Number of alternative settings */ 599 int num_alt; /* Number of alternative settings */
600 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ 600 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
601 int dvb_alt; /* alternate for DVB */
602 unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */
601 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ 603 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
602 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc 604 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
603 transfer */ 605 transfer */