aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEzequiel GarcĂ­a <elezegarcia@gmail.com>2012-02-24 09:24:14 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-15 07:53:46 -0400
commitab019fd41d993911ba32db0204bb1233682705ee (patch)
tree1635ffc06f9ca904be58fbec5e55c5b579b85b6e /drivers
parentad3537b56742848743aa11d42ccc1d336682bd5b (diff)
[media] staging: easycap: Split device struct alloc and retrieval code
When the device is probed a driver struct is either allocated or retrieved. This operation is logically splitted in several functions. Signed-off-by: Ezequiel Garcia <elezegarcia@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/media/easycap/easycap_main.c384
1 files changed, 216 insertions, 168 deletions
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index d0fe34afc2e5..c4198be6344c 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -2842,6 +2842,209 @@ static void easycap_complete(struct urb *purb)
2842 return; 2842 return;
2843} 2843}
2844 2844
2845static struct easycap *alloc_easycap(u8 bInterfaceNumber)
2846{
2847 struct easycap *peasycap;
2848 int i;
2849
2850 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
2851 if (!peasycap) {
2852 SAY("ERROR: Could not allocate peasycap\n");
2853 return NULL;
2854 }
2855
2856 if (mutex_lock_interruptible(&mutex_dongle)) {
2857 SAY("ERROR: cannot lock mutex_dongle\n");
2858 kfree(peasycap);
2859 return NULL;
2860 }
2861
2862 /* Find a free dongle in easycapdc60_dongle array */
2863 for (i = 0; i < DONGLE_MANY; i++) {
2864
2865 if ((!easycapdc60_dongle[i].peasycap) &&
2866 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_video)) &&
2867 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_audio))) {
2868
2869 easycapdc60_dongle[i].peasycap = peasycap;
2870 peasycap->isdongle = i;
2871 JOM(8, "intf[%i]: peasycap-->easycap"
2872 "_dongle[%i].peasycap\n",
2873 bInterfaceNumber, i);
2874 break;
2875 }
2876 }
2877
2878 mutex_unlock(&mutex_dongle);
2879
2880 if (i >= DONGLE_MANY) {
2881 SAM("ERROR: too many dongles\n");
2882 kfree(peasycap);
2883 return NULL;
2884 }
2885
2886 return peasycap;
2887}
2888
2889/*
2890 * FIXME: Identify the appropriate pointer peasycap for interfaces
2891 * 1 and 2. The address of peasycap->pusb_device is reluctantly used
2892 * for this purpose.
2893 */
2894static struct easycap *get_easycap(struct usb_device *usbdev,
2895 u8 bInterfaceNumber)
2896{
2897 int i;
2898 struct easycap *peasycap;
2899
2900 for (i = 0; i < DONGLE_MANY; i++) {
2901 if (easycapdc60_dongle[i].peasycap->pusb_device == usbdev) {
2902 peasycap = easycapdc60_dongle[i].peasycap;
2903 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
2904 bInterfaceNumber, i);
2905 break;
2906 }
2907 }
2908 if (i >= DONGLE_MANY) {
2909 SAY("ERROR: peasycap is unknown when probing interface %i\n",
2910 bInterfaceNumber);
2911 return NULL;
2912 }
2913 if (!peasycap) {
2914 SAY("ERROR: peasycap is NULL when probing interface %i\n",
2915 bInterfaceNumber);
2916 return NULL;
2917 }
2918
2919 return peasycap;
2920}
2921
2922static void init_easycap(struct easycap *peasycap,
2923 struct usb_device *usbdev,
2924 struct usb_interface *intf,
2925 u8 bInterfaceNumber)
2926{
2927 /* Save usb_device and usb_interface */
2928 peasycap->pusb_device = usbdev;
2929 peasycap->pusb_interface = intf;
2930
2931 peasycap->minor = -1;
2932 kref_init(&peasycap->kref);
2933 JOM(8, "intf[%i]: after kref_init(..._video) "
2934 "%i=peasycap->kref.refcount.counter\n",
2935 bInterfaceNumber, peasycap->kref.refcount.counter);
2936
2937 /* module params */
2938 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
2939
2940 init_waitqueue_head(&peasycap->wq_video);
2941 init_waitqueue_head(&peasycap->wq_audio);
2942 init_waitqueue_head(&peasycap->wq_trigger);
2943
2944 peasycap->allocation_video_struct = sizeof(struct easycap);
2945
2946 peasycap->microphone = false;
2947
2948 peasycap->video_interface = -1;
2949 peasycap->video_altsetting_on = -1;
2950 peasycap->video_altsetting_off = -1;
2951 peasycap->video_endpointnumber = -1;
2952 peasycap->video_isoc_maxframesize = -1;
2953 peasycap->video_isoc_buffer_size = -1;
2954
2955 peasycap->audio_interface = -1;
2956 peasycap->audio_altsetting_on = -1;
2957 peasycap->audio_altsetting_off = -1;
2958 peasycap->audio_endpointnumber = -1;
2959 peasycap->audio_isoc_maxframesize = -1;
2960 peasycap->audio_isoc_buffer_size = -1;
2961
2962 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
2963}
2964
2965static int populate_inputset(struct easycap *peasycap)
2966{
2967 struct inputset *inputset;
2968 struct easycap_format *peasycap_format;
2969 struct v4l2_pix_format *pix;
2970 int m, i, k, mask, fmtidx;
2971 s32 value;
2972
2973 inputset = peasycap->inputset;
2974
2975 /* FIXME: peasycap->ntsc is not yet initialized */
2976 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
2977
2978 m = 0;
2979 mask = 0;
2980 for (i = 0; easycap_standard[i].mask != 0xffff; i++) {
2981 if (fmtidx == easycap_standard[i].v4l2_standard.index) {
2982 m++;
2983 for (k = 0; k < INPUT_MANY; k++)
2984 inputset[k].standard_offset = i;
2985 mask = easycap_standard[i].mask;
2986 }
2987 }
2988
2989 if (m != 1) {
2990 SAM("ERROR: inputset->standard_offset unpopulated, %i=m\n", m);
2991 return -ENOENT;
2992 }
2993
2994 peasycap_format = &easycap_format[0];
2995 m = 0;
2996 for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
2997 pix = &peasycap_format->v4l2_format.fmt.pix;
2998 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F))
2999 && pix->field == V4L2_FIELD_NONE
3000 && pix->pixelformat == V4L2_PIX_FMT_UYVY
3001 && pix->width == 640 && pix->height == 480) {
3002 m++;
3003 for (k = 0; k < INPUT_MANY; k++)
3004 inputset[k].format_offset = i;
3005 break;
3006 }
3007 peasycap_format++;
3008 }
3009 if (m != 1) {
3010 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3011 return -ENOENT;
3012 }
3013
3014 m = 0;
3015 for (i = 0; easycap_control[i].id != 0xffffffff; i++) {
3016 value = easycap_control[i].default_value;
3017 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
3018 m++;
3019 for (k = 0; k < INPUT_MANY; k++)
3020 inputset[k].brightness = value;
3021 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
3022 m++;
3023 for (k = 0; k < INPUT_MANY; k++)
3024 inputset[k].contrast = value;
3025 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
3026 m++;
3027 for (k = 0; k < INPUT_MANY; k++)
3028 inputset[k].saturation = value;
3029 } else if (V4L2_CID_HUE == easycap_control[i].id) {
3030 m++;
3031 for (k = 0; k < INPUT_MANY; k++)
3032 inputset[k].hue = value;
3033 }
3034 }
3035
3036 if (m != 4) {
3037 SAM("ERROR: inputset[]->brightness underpopulated\n");
3038 return -ENOENT;
3039 }
3040
3041 for (k = 0; k < INPUT_MANY; k++)
3042 inputset[k].input = k;
3043 JOM(4, "populated inputset[]\n");
3044
3045 return 0;
3046}
3047
2845static const struct v4l2_file_operations v4l2_fops = { 3048static const struct v4l2_file_operations v4l2_fops = {
2846 .owner = THIS_MODULE, 3049 .owner = THIS_MODULE,
2847 .open = easycap_open_noinode, 3050 .open = easycap_open_noinode,
@@ -2863,7 +3066,6 @@ static int easycap_usb_probe(struct usb_interface *intf,
2863 struct usb_interface_descriptor *interface; 3066 struct usb_interface_descriptor *interface;
2864 struct urb *purb; 3067 struct urb *purb;
2865 struct easycap *peasycap; 3068 struct easycap *peasycap;
2866 int ndong;
2867 struct data_urb *pdata_urb; 3069 struct data_urb *pdata_urb;
2868 int i, j, k, m, rc; 3070 int i, j, k, m, rc;
2869 u8 bInterfaceNumber; 3071 u8 bInterfaceNumber;
@@ -2874,11 +3076,6 @@ static int easycap_usb_probe(struct usb_interface *intf,
2874 int okepn[8]; 3076 int okepn[8];
2875 int okmps[8]; 3077 int okmps[8];
2876 int maxpacketsize; 3078 int maxpacketsize;
2877 u16 mask;
2878 s32 value;
2879 struct easycap_format *peasycap_format;
2880 int fmtidx;
2881 struct inputset *inputset;
2882 3079
2883 usbdev = interface_to_usbdev(intf); 3080 usbdev = interface_to_usbdev(intf);
2884 3081
@@ -2916,76 +3113,16 @@ static int easycap_usb_probe(struct usb_interface *intf,
2916 * interfaces 1 and 2 are probed. 3113 * interfaces 1 and 2 are probed.
2917 */ 3114 */
2918 if (0 == bInterfaceNumber) { 3115 if (0 == bInterfaceNumber) {
2919 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); 3116 /*
2920 if (!peasycap) { 3117 * Alloc structure and save it in a free slot in
2921 SAY("ERROR: Could not allocate peasycap\n"); 3118 * easycapdc60_dongle array
2922 return -ENOMEM; 3119 */
2923 } 3120 peasycap = alloc_easycap(bInterfaceNumber);
2924 3121 if (!peasycap)
2925 /* Perform urgent initializations */
2926 peasycap->minor = -1;
2927 kref_init(&peasycap->kref);
2928 JOM(8, "intf[%i]: after kref_init(..._video) "
2929 "%i=peasycap->kref.refcount.counter\n",
2930 bInterfaceNumber, peasycap->kref.refcount.counter);
2931
2932 /* module params */
2933 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
2934
2935 init_waitqueue_head(&peasycap->wq_video);
2936 init_waitqueue_head(&peasycap->wq_audio);
2937 init_waitqueue_head(&peasycap->wq_trigger);
2938
2939 if (mutex_lock_interruptible(&mutex_dongle)) {
2940 SAY("ERROR: cannot down mutex_dongle\n");
2941 return -ERESTARTSYS;
2942 }
2943
2944 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
2945 if ((!easycapdc60_dongle[ndong].peasycap) &&
2946 (!mutex_is_locked(&easycapdc60_dongle
2947 [ndong].mutex_video)) &&
2948 (!mutex_is_locked(&easycapdc60_dongle
2949 [ndong].mutex_audio))) {
2950 easycapdc60_dongle[ndong].peasycap = peasycap;
2951 peasycap->isdongle = ndong;
2952 JOM(8, "intf[%i]: peasycap-->easycap"
2953 "_dongle[%i].peasycap\n",
2954 bInterfaceNumber, ndong);
2955 break;
2956 }
2957 }
2958
2959 if (DONGLE_MANY <= ndong) {
2960 SAM("ERROR: too many dongles\n");
2961 mutex_unlock(&mutex_dongle);
2962 return -ENOMEM; 3122 return -ENOMEM;
2963 }
2964 mutex_unlock(&mutex_dongle);
2965 3123
2966 peasycap->allocation_video_struct = sizeof(struct easycap); 3124 /* Perform basic struct initialization */
2967 3125 init_easycap(peasycap, usbdev, intf, bInterfaceNumber);
2968 /* and further initialize the structure */
2969 peasycap->pusb_device = usbdev;
2970 peasycap->pusb_interface = intf;
2971
2972 peasycap->microphone = false;
2973
2974 peasycap->video_interface = -1;
2975 peasycap->video_altsetting_on = -1;
2976 peasycap->video_altsetting_off = -1;
2977 peasycap->video_endpointnumber = -1;
2978 peasycap->video_isoc_maxframesize = -1;
2979 peasycap->video_isoc_buffer_size = -1;
2980
2981 peasycap->audio_interface = -1;
2982 peasycap->audio_altsetting_on = -1;
2983 peasycap->audio_altsetting_off = -1;
2984 peasycap->audio_endpointnumber = -1;
2985 peasycap->audio_isoc_maxframesize = -1;
2986 peasycap->audio_isoc_buffer_size = -1;
2987
2988 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
2989 3126
2990 /* Dynamically fill in the available formats */ 3127 /* Dynamically fill in the available formats */
2991 rc = easycap_video_fillin_formats(); 3128 rc = easycap_video_fillin_formats();
@@ -2996,103 +3133,14 @@ static int easycap_usb_probe(struct usb_interface *intf,
2996 JOM(4, "%i formats available\n", rc); 3133 JOM(4, "%i formats available\n", rc);
2997 3134
2998 /* Populate easycap.inputset[] */ 3135 /* Populate easycap.inputset[] */
2999 inputset = peasycap->inputset; 3136 rc = populate_inputset(peasycap);
3000 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; 3137 if (rc < 0)
3001 m = 0; 3138 return rc;
3002 mask = 0;
3003 for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) {
3004 if (fmtidx == easycap_standard[i].v4l2_standard.index) {
3005 m++;
3006 for (k = 0; k < INPUT_MANY; k++)
3007 inputset[k].standard_offset = i;
3008
3009 mask = easycap_standard[i].mask;
3010 }
3011 }
3012 if (1 != m) {
3013 SAM("ERROR: "
3014 "inputset->standard_offset unpopulated, %i=m\n", m);
3015 return -ENOENT;
3016 }
3017
3018 peasycap_format = &easycap_format[0];
3019 m = 0;
3020 for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
3021 struct v4l2_pix_format *pix =
3022 &peasycap_format->v4l2_format.fmt.pix;
3023 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) &&
3024 pix->field == V4L2_FIELD_NONE &&
3025 pix->pixelformat == V4L2_PIX_FMT_UYVY &&
3026 pix->width == 640 && pix->height == 480) {
3027 m++;
3028 for (k = 0; k < INPUT_MANY; k++)
3029 inputset[k].format_offset = i;
3030 break;
3031 }
3032 peasycap_format++;
3033 }
3034 if (1 != m) {
3035 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3036 return -ENOENT;
3037 }
3038
3039 m = 0;
3040 for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) {
3041 value = easycap_control[i].default_value;
3042 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
3043 m++;
3044 for (k = 0; k < INPUT_MANY; k++)
3045 inputset[k].brightness = value;
3046 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
3047 m++;
3048 for (k = 0; k < INPUT_MANY; k++)
3049 inputset[k].contrast = value;
3050 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
3051 m++;
3052 for (k = 0; k < INPUT_MANY; k++)
3053 inputset[k].saturation = value;
3054 } else if (V4L2_CID_HUE == easycap_control[i].id) {
3055 m++;
3056 for (k = 0; k < INPUT_MANY; k++)
3057 inputset[k].hue = value;
3058 }
3059 }
3060
3061 if (4 != m) {
3062 SAM("ERROR: inputset[]->brightness underpopulated\n");
3063 return -ENOENT;
3064 }
3065 for (k = 0; k < INPUT_MANY; k++)
3066 inputset[k].input = k;
3067 JOM(4, "populated inputset[]\n");
3068 JOM(4, "finished initialization\n"); 3139 JOM(4, "finished initialization\n");
3069 } else { 3140 } else {
3070 3141 peasycap = get_easycap(usbdev, bInterfaceNumber);
3071 /* 3142 if (!peasycap)
3072 * FIXME: Identify the appropriate pointer
3073 * peasycap for interfaces 1 and 2.
3074 * The address of peasycap->pusb_device
3075 * is reluctantly used for this purpose.
3076 */
3077 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
3078 if (usbdev == easycapdc60_dongle[ndong].peasycap->
3079 pusb_device) {
3080 peasycap = easycapdc60_dongle[ndong].peasycap;
3081 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
3082 bInterfaceNumber, ndong);
3083 break;
3084 }
3085 }
3086 if (DONGLE_MANY <= ndong) {
3087 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3088 bInterfaceNumber);
3089 return -ENODEV; 3143 return -ENODEV;
3090 }
3091 if (!peasycap) {
3092 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3093 bInterfaceNumber);
3094 return -ENODEV;
3095 }
3096 } 3144 }
3097 3145
3098 if ((USB_CLASS_VIDEO == bInterfaceClass) || 3146 if ((USB_CLASS_VIDEO == bInterfaceClass) ||