diff options
-rw-r--r-- | drivers/usb/media/ov511.c | 196 |
1 files changed, 2 insertions, 194 deletions
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 8af665bbe330..51e9cc06f7e3 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c | |||
@@ -204,22 +204,10 @@ MODULE_LICENSE("GPL"); | |||
204 | 204 | ||
205 | static struct usb_driver ov511_driver; | 205 | static struct usb_driver ov511_driver; |
206 | 206 | ||
207 | static struct ov51x_decomp_ops *ov511_decomp_ops; | ||
208 | static struct ov51x_decomp_ops *ov511_mmx_decomp_ops; | ||
209 | static struct ov51x_decomp_ops *ov518_decomp_ops; | ||
210 | static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; | ||
211 | |||
212 | /* Number of times to retry a failed I2C transaction. Increase this if you | 207 | /* Number of times to retry a failed I2C transaction. Increase this if you |
213 | * are getting "Failed to read sensor ID..." */ | 208 | * are getting "Failed to read sensor ID..." */ |
214 | static const int i2c_detect_tries = 5; | 209 | static const int i2c_detect_tries = 5; |
215 | 210 | ||
216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ | ||
217 | #if defined(__i386__) || defined(__x86_64__) | ||
218 | #define ov51x_mmx_available (cpu_has_mmx) | ||
219 | #else | ||
220 | #define ov51x_mmx_available (0) | ||
221 | #endif | ||
222 | |||
223 | static struct usb_device_id device_table [] = { | 211 | static struct usb_device_id device_table [] = { |
224 | { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, | 212 | { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, |
225 | { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, | 213 | { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, |
@@ -3012,93 +3000,18 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame, | |||
3012 | * | 3000 | * |
3013 | **********************************************************************/ | 3001 | **********************************************************************/ |
3014 | 3002 | ||
3015 | /* Chooses a decompression module, locks it, and sets ov->decomp_ops | ||
3016 | * accordingly. Returns -ENXIO if decompressor is not available, otherwise | ||
3017 | * returns 0 if no other error. | ||
3018 | */ | ||
3019 | static int | 3003 | static int |
3020 | request_decompressor(struct usb_ov511 *ov) | 3004 | request_decompressor(struct usb_ov511 *ov) |
3021 | { | 3005 | { |
3022 | if (!ov) | 3006 | if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) { |
3023 | return -ENODEV; | 3007 | err("No decompressor available"); |
3024 | |||
3025 | if (ov->decomp_ops) { | ||
3026 | err("ERROR: Decompressor already requested!"); | ||
3027 | return -EINVAL; | ||
3028 | } | ||
3029 | |||
3030 | lock_kernel(); | ||
3031 | |||
3032 | /* Try to get MMX, and fall back on no-MMX if necessary */ | ||
3033 | if (ov->bclass == BCL_OV511) { | ||
3034 | if (ov511_mmx_decomp_ops) { | ||
3035 | PDEBUG(3, "Using OV511 MMX decompressor"); | ||
3036 | ov->decomp_ops = ov511_mmx_decomp_ops; | ||
3037 | } else if (ov511_decomp_ops) { | ||
3038 | PDEBUG(3, "Using OV511 decompressor"); | ||
3039 | ov->decomp_ops = ov511_decomp_ops; | ||
3040 | } else { | ||
3041 | err("No decompressor available"); | ||
3042 | } | ||
3043 | } else if (ov->bclass == BCL_OV518) { | ||
3044 | if (ov518_mmx_decomp_ops) { | ||
3045 | PDEBUG(3, "Using OV518 MMX decompressor"); | ||
3046 | ov->decomp_ops = ov518_mmx_decomp_ops; | ||
3047 | } else if (ov518_decomp_ops) { | ||
3048 | PDEBUG(3, "Using OV518 decompressor"); | ||
3049 | ov->decomp_ops = ov518_decomp_ops; | ||
3050 | } else { | ||
3051 | err("No decompressor available"); | ||
3052 | } | ||
3053 | } else { | 3008 | } else { |
3054 | err("Unknown bridge"); | 3009 | err("Unknown bridge"); |
3055 | } | 3010 | } |
3056 | 3011 | ||
3057 | if (!ov->decomp_ops) | ||
3058 | goto nosys; | ||
3059 | |||
3060 | if (!ov->decomp_ops->owner) { | ||
3061 | ov->decomp_ops = NULL; | ||
3062 | goto nosys; | ||
3063 | } | ||
3064 | |||
3065 | if (!try_module_get(ov->decomp_ops->owner)) | ||
3066 | goto nosys; | ||
3067 | |||
3068 | unlock_kernel(); | ||
3069 | return 0; | ||
3070 | |||
3071 | nosys: | ||
3072 | unlock_kernel(); | ||
3073 | return -ENOSYS; | 3012 | return -ENOSYS; |
3074 | } | 3013 | } |
3075 | 3014 | ||
3076 | /* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even | ||
3077 | * if ov->decomp_ops is NULL. | ||
3078 | */ | ||
3079 | static void | ||
3080 | release_decompressor(struct usb_ov511 *ov) | ||
3081 | { | ||
3082 | int released = 0; /* Did we actually do anything? */ | ||
3083 | |||
3084 | if (!ov) | ||
3085 | return; | ||
3086 | |||
3087 | lock_kernel(); | ||
3088 | |||
3089 | if (ov->decomp_ops) { | ||
3090 | module_put(ov->decomp_ops->owner); | ||
3091 | released = 1; | ||
3092 | } | ||
3093 | |||
3094 | ov->decomp_ops = NULL; | ||
3095 | |||
3096 | unlock_kernel(); | ||
3097 | |||
3098 | if (released) | ||
3099 | PDEBUG(3, "Decompressor released"); | ||
3100 | } | ||
3101 | |||
3102 | static void | 3015 | static void |
3103 | decompress(struct usb_ov511 *ov, struct ov511_frame *frame, | 3016 | decompress(struct usb_ov511 *ov, struct ov511_frame *frame, |
3104 | unsigned char *pIn0, unsigned char *pOut0) | 3017 | unsigned char *pIn0, unsigned char *pOut0) |
@@ -3107,31 +3020,6 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, | |||
3107 | if (request_decompressor(ov)) | 3020 | if (request_decompressor(ov)) |
3108 | return; | 3021 | return; |
3109 | 3022 | ||
3110 | PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); | ||
3111 | |||
3112 | if (frame->format == VIDEO_PALETTE_GREY | ||
3113 | && ov->decomp_ops->decomp_400) { | ||
3114 | int ret = ov->decomp_ops->decomp_400( | ||
3115 | pIn0, | ||
3116 | pOut0, | ||
3117 | frame->compbuf, | ||
3118 | frame->rawwidth, | ||
3119 | frame->rawheight, | ||
3120 | frame->bytes_recvd); | ||
3121 | PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); | ||
3122 | } else if (frame->format != VIDEO_PALETTE_GREY | ||
3123 | && ov->decomp_ops->decomp_420) { | ||
3124 | int ret = ov->decomp_ops->decomp_420( | ||
3125 | pIn0, | ||
3126 | pOut0, | ||
3127 | frame->compbuf, | ||
3128 | frame->rawwidth, | ||
3129 | frame->rawheight, | ||
3130 | frame->bytes_recvd); | ||
3131 | PDEBUG(4, "DEBUG: decomp_420 returned %d", ret); | ||
3132 | } else { | ||
3133 | err("Decompressor does not support this format"); | ||
3134 | } | ||
3135 | } | 3023 | } |
3136 | 3024 | ||
3137 | /********************************************************************** | 3025 | /********************************************************************** |
@@ -4087,8 +3975,6 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) | |||
4087 | ov->user--; | 3975 | ov->user--; |
4088 | ov51x_stop_isoc(ov); | 3976 | ov51x_stop_isoc(ov); |
4089 | 3977 | ||
4090 | release_decompressor(ov); | ||
4091 | |||
4092 | if (ov->led_policy == LED_AUTO) | 3978 | if (ov->led_policy == LED_AUTO) |
4093 | ov51x_led_control(ov, 0); | 3979 | ov51x_led_control(ov, 0); |
4094 | 3980 | ||
@@ -6021,82 +5907,6 @@ static struct usb_driver ov511_driver = { | |||
6021 | * | 5907 | * |
6022 | ***************************************************************************/ | 5908 | ***************************************************************************/ |
6023 | 5909 | ||
6024 | /* Returns 0 for success */ | ||
6025 | int | ||
6026 | ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518, | ||
6027 | int mmx) | ||
6028 | { | ||
6029 | if (ver != DECOMP_INTERFACE_VER) { | ||
6030 | err("Decompression module has incompatible"); | ||
6031 | err("interface version %d", ver); | ||
6032 | err("Interface version %d is required", DECOMP_INTERFACE_VER); | ||
6033 | return -EINVAL; | ||
6034 | } | ||
6035 | |||
6036 | if (!ops) | ||
6037 | return -EFAULT; | ||
6038 | |||
6039 | if (mmx && !ov51x_mmx_available) { | ||
6040 | err("MMX not available on this system or kernel"); | ||
6041 | return -EINVAL; | ||
6042 | } | ||
6043 | |||
6044 | lock_kernel(); | ||
6045 | |||
6046 | if (ov518) { | ||
6047 | if (mmx) { | ||
6048 | if (ov518_mmx_decomp_ops) | ||
6049 | goto err_in_use; | ||
6050 | else | ||
6051 | ov518_mmx_decomp_ops = ops; | ||
6052 | } else { | ||
6053 | if (ov518_decomp_ops) | ||
6054 | goto err_in_use; | ||
6055 | else | ||
6056 | ov518_decomp_ops = ops; | ||
6057 | } | ||
6058 | } else { | ||
6059 | if (mmx) { | ||
6060 | if (ov511_mmx_decomp_ops) | ||
6061 | goto err_in_use; | ||
6062 | else | ||
6063 | ov511_mmx_decomp_ops = ops; | ||
6064 | } else { | ||
6065 | if (ov511_decomp_ops) | ||
6066 | goto err_in_use; | ||
6067 | else | ||
6068 | ov511_decomp_ops = ops; | ||
6069 | } | ||
6070 | } | ||
6071 | |||
6072 | unlock_kernel(); | ||
6073 | return 0; | ||
6074 | |||
6075 | err_in_use: | ||
6076 | unlock_kernel(); | ||
6077 | return -EBUSY; | ||
6078 | } | ||
6079 | |||
6080 | void | ||
6081 | ov511_deregister_decomp_module(int ov518, int mmx) | ||
6082 | { | ||
6083 | lock_kernel(); | ||
6084 | |||
6085 | if (ov518) { | ||
6086 | if (mmx) | ||
6087 | ov518_mmx_decomp_ops = NULL; | ||
6088 | else | ||
6089 | ov518_decomp_ops = NULL; | ||
6090 | } else { | ||
6091 | if (mmx) | ||
6092 | ov511_mmx_decomp_ops = NULL; | ||
6093 | else | ||
6094 | ov511_decomp_ops = NULL; | ||
6095 | } | ||
6096 | |||
6097 | unlock_kernel(); | ||
6098 | } | ||
6099 | |||
6100 | static int __init | 5910 | static int __init |
6101 | usb_ov511_init(void) | 5911 | usb_ov511_init(void) |
6102 | { | 5912 | { |
@@ -6123,5 +5933,3 @@ usb_ov511_exit(void) | |||
6123 | module_init(usb_ov511_init); | 5933 | module_init(usb_ov511_init); |
6124 | module_exit(usb_ov511_exit); | 5934 | module_exit(usb_ov511_exit); |
6125 | 5935 | ||
6126 | EXPORT_SYMBOL(ov511_register_decomp_module); | ||
6127 | EXPORT_SYMBOL(ov511_deregister_decomp_module); | ||