diff options
-rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 2 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 148 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 59 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 4 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-reg.h | 5 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 2 |
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: | |||
3111 | static int em28xx_usb_probe(struct usb_interface *interface, | 3111 | static 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 | ||
3322 | unlock_and_free: | ||
3323 | mutex_unlock(&dev->lock); | ||
3324 | |||
3325 | err_free: | ||
3326 | kfree(dev->alt_max_pkt_size); | ||
3327 | kfree(dev); | ||
3328 | |||
3333 | err: | 3329 | err: |
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 | } |
1109 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | 1110 | EXPORT_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) */ | ||
1113 | int 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 | } | ||
1165 | EXPORT_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 */ |