aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/media/ov511.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/media/ov511.c')
-rw-r--r--drivers/usb/media/ov511.c196
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
205static struct usb_driver ov511_driver; 205static struct usb_driver ov511_driver;
206 206
207static struct ov51x_decomp_ops *ov511_decomp_ops;
208static struct ov51x_decomp_ops *ov511_mmx_decomp_ops;
209static struct ov51x_decomp_ops *ov518_decomp_ops;
210static 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..." */
214static const int i2c_detect_tries = 5; 209static 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
223static struct usb_device_id device_table [] = { 211static 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 */
3019static int 3003static int
3020request_decompressor(struct usb_ov511 *ov) 3004request_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 */
3079static void
3080release_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
3102static void 3015static void
3103decompress(struct usb_ov511 *ov, struct ov511_frame *frame, 3016decompress(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 */
6025int
6026ov511_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
6075err_in_use:
6076 unlock_kernel();
6077 return -EBUSY;
6078}
6079
6080void
6081ov511_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
6100static int __init 5910static int __init
6101usb_ov511_init(void) 5911usb_ov511_init(void)
6102{ 5912{
@@ -6123,5 +5933,3 @@ usb_ov511_exit(void)
6123module_init(usb_ov511_init); 5933module_init(usb_ov511_init);
6124module_exit(usb_ov511_exit); 5934module_exit(usb_ov511_exit);
6125 5935
6126EXPORT_SYMBOL(ov511_register_decomp_module);
6127EXPORT_SYMBOL(ov511_deregister_decomp_module);