diff options
Diffstat (limited to 'drivers/media/usb/gspca')
-rw-r--r-- | drivers/media/usb/gspca/autogain_functions.c | 4 | ||||
-rw-r--r-- | drivers/media/usb/gspca/gspca.c | 29 | ||||
-rw-r--r-- | drivers/media/usb/gspca/gspca.h | 1 | ||||
-rw-r--r-- | drivers/media/usb/gspca/kinect.c | 98 | ||||
-rw-r--r-- | drivers/media/usb/gspca/pac7302.c | 9 | ||||
-rw-r--r-- | drivers/media/usb/gspca/sonixb.c | 2 |
6 files changed, 114 insertions, 29 deletions
diff --git a/drivers/media/usb/gspca/autogain_functions.c b/drivers/media/usb/gspca/autogain_functions.c index 67db674bb04..0e9ee8b50bb 100644 --- a/drivers/media/usb/gspca/autogain_functions.c +++ b/drivers/media/usb/gspca/autogain_functions.c @@ -121,9 +121,9 @@ int gspca_coarse_grained_expo_autogain( orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain); orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure); - gain_low = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) / + gain_low = (s32)(gspca_dev->gain->maximum - gspca_dev->gain->minimum) / 5 * 2 + gspca_dev->gain->minimum; - gain_high = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) / + gain_high = (s32)(gspca_dev->gain->maximum - gspca_dev->gain->minimum) / 5 * 4 + gspca_dev->gain->minimum; /* If we are of a multiple of deadzone, do multiple steps to reach the diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index f3a7ace0fac..e8cf23c91ce 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -603,10 +603,13 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) } /* - * look for an input transfer endpoint in an alternate setting + * look for an input transfer endpoint in an alternate setting. + * + * If xfer_ep is invalid, return the first valid ep found, otherwise + * look for exactly the ep with address equal to xfer_ep. */ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, - int xfer) + int xfer, int xfer_ep) { struct usb_host_endpoint *ep; int i, attr; @@ -616,7 +619,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; if (attr == xfer && ep->desc.wMaxPacketSize != 0 - && usb_endpoint_dir_in(&ep->desc)) + && usb_endpoint_dir_in(&ep->desc) + && (xfer_ep < 0 || ep->desc.bEndpointAddress == xfer_ep)) return ep; } return NULL; @@ -689,7 +693,8 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev, found = 0; for (j = 0; j < nbalt; j++) { ep = alt_xfer(&intf->altsetting[j], - USB_ENDPOINT_XFER_ISOC); + USB_ENDPOINT_XFER_ISOC, + gspca_dev->xfer_ep); if (ep == NULL) continue; if (ep->desc.bInterval == 0) { @@ -862,7 +867,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* if bulk or the subdriver forced an altsetting, get the endpoint */ if (gspca_dev->alt != 0) { gspca_dev->alt--; /* (previous version compatibility) */ - ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer); + ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer, + gspca_dev->xfer_ep); if (ep == NULL) { pr_err("bad altsetting %d\n", gspca_dev->alt); return -EIO; @@ -904,7 +910,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) if (!gspca_dev->cam.no_urb_create) { PDEBUG(D_STREAM, "init transfer alt %d", alt); ret = create_urbs(gspca_dev, - alt_xfer(&intf->altsetting[alt], xfer)); + alt_xfer(&intf->altsetting[alt], xfer, + gspca_dev->xfer_ep)); if (ret < 0) { destroy_urbs(gspca_dev); goto out; @@ -1102,8 +1109,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct gspca_dev *gspca_dev = video_drvdata(file); fmt->fmt.pix = gspca_dev->pixfmt; - /* some drivers use priv internally, zero it before giving it to - userspace */ + /* some drivers use priv internally, zero it before giving it back to + the core */ fmt->fmt.pix.priv = 0; return 0; } @@ -1139,8 +1146,8 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, fmt->fmt.pix.height = h; gspca_dev->sd_desc->try_fmt(gspca_dev, fmt); } - /* some drivers use priv internally, zero it before giving it to - userspace */ + /* some drivers use priv internally, zero it before giving it back to + the core */ fmt->fmt.pix.priv = 0; return mode; /* used when s_fmt */ } @@ -2030,6 +2037,7 @@ int gspca_dev_probe2(struct usb_interface *intf, } gspca_dev->dev = dev; gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber; + gspca_dev->xfer_ep = -1; /* check if any audio device */ if (dev->actconfig->desc.bNumInterfaces != 1) { @@ -2058,7 +2066,6 @@ int gspca_dev_probe2(struct usb_interface *intf, gspca_dev->vdev = gspca_template; gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev; video_set_drvdata(&gspca_dev->vdev, gspca_dev); - set_bit(V4L2_FL_USE_FH_PRIO, &gspca_dev->vdev.flags); gspca_dev->module = module; gspca_dev->present = 1; diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index 300642dc1a1..f06253cd746 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h @@ -205,6 +205,7 @@ struct gspca_dev { char memory; /* memory type (V4L2_MEMORY_xxx) */ __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ + int xfer_ep; /* USB transfer endpoint address */ u8 audio; /* presence of audio device */ /* (*) These variables are proteced by both usb_lock and queue_lock, diff --git a/drivers/media/usb/gspca/kinect.c b/drivers/media/usb/gspca/kinect.c index 081f0516280..45bc1f51c5d 100644 --- a/drivers/media/usb/gspca/kinect.c +++ b/drivers/media/usb/gspca/kinect.c @@ -36,6 +36,8 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver"); MODULE_LICENSE("GPL"); +static bool depth_mode; + struct pkt_hdr { uint8_t magic[2]; uint8_t pad; @@ -73,6 +75,14 @@ struct sd { #define FPS_HIGH 0x0100 +static const struct v4l2_pix_format depth_camera_mode[] = { + {640, 480, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE, + .bytesperline = 640 * 10 / 8, + .sizeimage = 640 * 480 * 10 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = MODE_640x488 | FORMAT_Y10B}, +}; + static const struct v4l2_pix_format video_camera_mode[] = { {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, .bytesperline = 640, @@ -219,7 +229,7 @@ static int write_register(struct gspca_dev *gspca_dev, uint16_t reg, } /* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, +static int sd_config_video(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; @@ -227,8 +237,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->cam_tag = 0; - /* Only video stream is supported for now, - * which has stream flag = 0x80 */ sd->stream_flag = 0x80; cam = &gspca_dev->cam; @@ -236,6 +244,8 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = video_camera_mode; cam->nmodes = ARRAY_SIZE(video_camera_mode); + gspca_dev->xfer_ep = 0x81; + #if 0 /* Setting those values is not needed for video stream */ cam->npkt = 15; @@ -245,6 +255,26 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } +static int sd_config_depth(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + sd->cam_tag = 0; + + sd->stream_flag = 0x70; + + cam = &gspca_dev->cam; + + cam->cam_mode = depth_camera_mode; + cam->nmodes = ARRAY_SIZE(depth_camera_mode); + + gspca_dev->xfer_ep = 0x82; + + return 0; +} + /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { @@ -253,7 +283,7 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int sd_start(struct gspca_dev *gspca_dev) +static int sd_start_video(struct gspca_dev *gspca_dev) { int mode; uint8_t fmt_reg, fmt_val; @@ -325,12 +355,39 @@ static int sd_start(struct gspca_dev *gspca_dev) return 0; } -static void sd_stopN(struct gspca_dev *gspca_dev) +static int sd_start_depth(struct gspca_dev *gspca_dev) +{ + /* turn off IR-reset function */ + write_register(gspca_dev, 0x105, 0x00); + + /* reset depth stream */ + write_register(gspca_dev, 0x06, 0x00); + /* Depth Stream Format 0x03: 11 bit stream | 0x02: 10 bit */ + write_register(gspca_dev, 0x12, 0x02); + /* Depth Stream Resolution 1: standard (640x480) */ + write_register(gspca_dev, 0x13, 0x01); + /* Depth Framerate / 0x1e (30): 30 fps */ + write_register(gspca_dev, 0x14, 0x1e); + /* Depth Stream Control / 2: Open Depth Stream */ + write_register(gspca_dev, 0x06, 0x02); + /* disable depth hflip / LSB = 0: Smoothing Disabled */ + write_register(gspca_dev, 0x17, 0x00); + + return 0; +} + +static void sd_stopN_video(struct gspca_dev *gspca_dev) { /* reset video stream */ write_register(gspca_dev, 0x05, 0x00); } +static void sd_stopN_depth(struct gspca_dev *gspca_dev) +{ + /* reset depth stream */ + write_register(gspca_dev, 0x06, 0x00); +} + static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len) { struct sd *sd = (struct sd *) gspca_dev; @@ -366,12 +423,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len) } /* sub-driver description */ -static const struct sd_desc sd_desc = { +static const struct sd_desc sd_desc_video = { .name = MODULE_NAME, - .config = sd_config, + .config = sd_config_video, .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, + .start = sd_start_video, + .stopN = sd_stopN_video, + .pkt_scan = sd_pkt_scan, + /* + .get_streamparm = sd_get_streamparm, + .set_streamparm = sd_set_streamparm, + */ +}; +static const struct sd_desc sd_desc_depth = { + .name = MODULE_NAME, + .config = sd_config_depth, + .init = sd_init, + .start = sd_start_depth, + .stopN = sd_stopN_depth, .pkt_scan = sd_pkt_scan, /* .get_streamparm = sd_get_streamparm, @@ -391,8 +460,12 @@ MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); + if (depth_mode) + return gspca_dev_probe(intf, id, &sd_desc_depth, + sizeof(struct sd), THIS_MODULE); + else + return gspca_dev_probe(intf, id, &sd_desc_video, + sizeof(struct sd), THIS_MODULE); } static struct usb_driver sd_driver = { @@ -408,3 +481,6 @@ static struct usb_driver sd_driver = { }; module_usb_driver(sd_driver); + +module_param(depth_mode, bool, 0644); +MODULE_PARM_DESC(depth_mode, "0=video 1=depth"); diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c index 2fd1c5e31a0..8b08bd0172f 100644 --- a/drivers/media/usb/gspca/pac7302.c +++ b/drivers/media/usb/gspca/pac7302.c @@ -394,9 +394,9 @@ static void setbrightcont(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ for (i = 0; i < 10; i++) { v = max[i]; - v += (sd->brightness->val - sd->brightness->maximum) - * 150 / sd->brightness->maximum; /* 200 ? */ - v -= delta[i] * sd->contrast->val / sd->contrast->maximum; + v += (sd->brightness->val - (s32)sd->brightness->maximum) + * 150 / (s32)sd->brightness->maximum; /* 200 ? */ + v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum; if (v < 0) v = 0; else if (v > 0xff) @@ -419,7 +419,7 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x11, 0x01); reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ for (i = 0; i < 9; i++) { - v = a[i] * sd->saturation->val / sd->saturation->maximum; + v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum; v += b[i]; reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); reg_w(gspca_dev, 0x0f + 2 * i + 1, v); @@ -928,6 +928,7 @@ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2620)}, {USB_DEVICE(0x093a, 0x2621)}, {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, + {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2625)}, {USB_DEVICE(0x093a, 0x2626)}, diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index ecbcb39feb7..6696b2ec34e 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c @@ -913,7 +913,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) desired_avg_lum, deadzone)) sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; } else { - int gain_knee = gspca_dev->gain->maximum * 9 / 10; + int gain_knee = (s32)gspca_dev->gain->maximum * 9 / 10; if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum, deadzone, gain_knee, sd->exposure_knee)) sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; |