From patchwork Tue Nov 9 15:09:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 311352 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oA9FAExi001897 for ; Tue, 9 Nov 2010 15:10:14 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752002Ab0KIPKE (ORCPT ); Tue, 9 Nov 2010 10:10:04 -0500 Received: from casper.infradead.org ([85.118.1.10]:47591 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751439Ab0KIPKE (ORCPT ); Tue, 9 Nov 2010 10:10:04 -0500 Received: from 201-26-165-226.dial-up.telesp.net.br ([201.26.165.226] helo=[192.168.30.170]) by casper.infradead.org with esmtpsa (Exim 4.72 #1 (Red Hat Linux)) id 1PFppg-0002Aw-Sx; Tue, 09 Nov 2010 15:10:01 +0000 Message-ID: <4CD96444.4080404@infradead.org> Date: Tue, 09 Nov 2010 13:09:56 -0200 From: Mauro Carvalho Chehab User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100827 Red Hat/3.1.3-1.el6 Lightning/1.0b2 Thunderbird/3.1.3 MIME-Version: 1.0 To: Hans de Goede CC: Linux Media Mailing List , Lee Jones , Jean-Francois Moine Subject: Re: [GIT PATCHES FOR 2.6.37] Various gspca patches References: <1288182926-25400-1-git-send-email-hdegoede@redhat.com> In-Reply-To: <1288182926-25400-1-git-send-email-hdegoede@redhat.com> X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org See http://www.infradead.org/rpr.html Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 09 Nov 2010 15:10:15 +0000 (UTC) diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx.c linux/drivers/media/video/gspca/stv06xx/stv06xx.c --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx.c 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx.c 2010-11-09 12:41:24.000000000 -0200 @@ -263,7 +263,21 @@ static int stv06xx_init(struct gspca_dev static int stv06xx_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int err; + struct usb_host_interface *alt; + struct usb_interface *intf; + int err, packet_size; + + intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); + alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); + if (!alt) { + PDEBUG(D_ERR, "Couldn't get altsetting"); + return -EIO; + } + + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); + err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); + if (err < 0) + return err; /* Prepare the sensor for start */ err = sd->sensor->start(sd); @@ -282,6 +296,43 @@ out: return (err < 0) ? err : 0; } +static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) +{ + struct usb_host_interface *alt; + struct sd *sd = (struct sd *) gspca_dev; + + /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ + alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + alt->endpoint[0].desc.wMaxPacketSize = + cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); + + return 0; +} + +static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) +{ + int ret, packet_size, min_packet_size; + struct usb_host_interface *alt; + struct sd *sd = (struct sd *) gspca_dev; + + alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1]; + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); + min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; + if (packet_size <= min_packet_size) + return -EIO; + + packet_size -= 100; + if (packet_size < min_packet_size) + packet_size = min_packet_size; + alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); + + ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); + if (ret < 0) + PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); + + return ret; +} + static void stv06xx_stopN(struct gspca_dev *gspca_dev) { int err; @@ -462,6 +513,8 @@ static const struct sd_desc sd_desc = { .start = stv06xx_start, .stopN = stv06xx_stopN, .pkt_scan = stv06xx_pkt_scan, + .isoc_init = stv06xx_isoc_init, + .isoc_nego = stv06xx_isoc_nego, #ifdef CONFIG_INPUT .int_pkt_scan = sd_int_pkt_scan, #endif diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h 2010-11-09 12:41:24.000000000 -0200 @@ -146,6 +146,11 @@ const struct stv06xx_sensor stv06xx_sens .i2c_addr = (0x55 << 1), .i2c_len = 1, + /* FIXME (see if we can lower min_packet_size, needs testing, and also + adjusting framerate when the bandwidth gets lower) */ + .min_packet_size = { 847 }, + .max_packet_size = { 847 }, + .init = hdcs_init, .probe = hdcs_probe_1x00, .start = hdcs_start, @@ -160,6 +165,11 @@ const struct stv06xx_sensor stv06xx_sens .i2c_addr = (0x55 << 1), .i2c_len = 1, + /* FIXME (see if we can lower min_packet_size, needs testing, and also + adjusting framerate when the bandwidthm gets lower) */ + .min_packet_size = { 847 }, + .max_packet_size = { 847 }, + .init = hdcs_init, .probe = hdcs_probe_1020, .start = hdcs_start, @@ -177,7 +187,6 @@ static const u16 stv_bridge_init[][2] = {STV_REG04, 0x07}, {STV_SCAN_RATE, 0x20}, - {STV_ISO_SIZE_L, 847}, {STV_Y_CTRL, 0x01}, {STV_X_CTRL, 0x0a} }; diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c 2010-11-09 12:41:24.000000000 -0200 @@ -208,11 +208,24 @@ static int pb0100_probe(struct sd *sd) static int pb0100_start(struct sd *sd) { - int err; + int err, packet_size, max_packet_size; + struct usb_host_interface *alt; + struct usb_interface *intf; struct cam *cam = &sd->gspca_dev.cam; s32 *sensor_settings = sd->sensor_priv; u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; + intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); + alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); + + /* If we don't have enough bandwidth use a lower framerate */ + max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode]; + if (packet_size < max_packet_size) + stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); + else + stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1)); + /* Setup sensor window */ if (mode & PB0100_CROP_TO_VGA) { stv06xx_write_sensor(sd, PB_RSTART, 30); @@ -328,9 +341,6 @@ static int pb0100_init(struct sd *sd) stv06xx_write_bridge(sd, STV_REG03, 0x45); stv06xx_write_bridge(sd, STV_REG04, 0x07); - /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */ - stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847); - /* Scan/timing for the sensor */ stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); stv06xx_write_sensor(sd, PB_CFILLIN, 14); diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h 2010-11-09 12:41:24.000000000 -0200 @@ -138,6 +138,9 @@ const struct stv06xx_sensor stv06xx_sens .i2c_addr = 0xba, .i2c_len = 2, + .min_packet_size = { 635, 847 }, + .max_packet_size = { 847, 923 }, + .init = pb0100_init, .probe = pb0100_probe, .start = pb0100_start, diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h 2010-11-09 12:41:24.000000000 -0200 @@ -53,6 +53,10 @@ struct stv06xx_sensor { /* length of an i2c word */ u8 i2c_len; + /* Isoc packet size (per mode) */ + int min_packet_size[4]; + int max_packet_size[4]; + /* Probes if the sensor is connected */ int (*probe)(struct sd *sd); diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c linux/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c 2010-11-09 12:41:24.000000000 -0200 @@ -213,7 +213,6 @@ static int st6422_init(struct sd *sd) { 0x150e, 0x8e }, { 0x150f, 0x37 }, { 0x15c0, 0x00 }, - { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */ { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ @@ -237,23 +236,9 @@ static void st6422_disconnect(struct sd static int st6422_start(struct sd *sd) { - int err, packet_size; + int err; struct cam *cam = &sd->gspca_dev.cam; s32 *sensor_settings = sd->sensor_priv; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - err = stv06xx_write_bridge(sd, 0x15c1, packet_size); - if (err < 0) - return err; if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) err = stv06xx_write_bridge(sd, 0x1505, 0x0f); diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h linux/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h 2010-11-09 12:41:24.000000000 -0200 @@ -49,6 +49,9 @@ static int st6422_set_exposure(struct gs const struct stv06xx_sensor stv06xx_sensor_st6422 = { .name = "ST6422", + /* No known way to lower framerate in case of less bandwidth */ + .min_packet_size = { 300, 847 }, + .max_packet_size = { 300, 847 }, .init = st6422_init, .probe = st6422_probe, .start = st6422_start, diff -upNr oldtree/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h --- oldtree/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h 2010-11-09 12:41:28.000000000 -0200 +++ linux/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h 2010-11-09 12:41:24.000000000 -0200 @@ -197,6 +197,10 @@ const struct stv06xx_sensor stv06xx_sens .i2c_flush = 5, .i2c_addr = 0x20, .i2c_len = 1, + /* FIXME (see if we can lower packet_size-s, needs testing, and also + adjusting framerate when the bandwidth gets lower) */ + .min_packet_size = { 1023 }, + .max_packet_size = { 1023 }, .init = vv6410_init, .probe = vv6410_probe, .start = vv6410_start, @@ -220,10 +224,6 @@ static const u8 x1536[] = { /* 0x1536 - 0x02, 0x00, 0x60, 0x01, 0x20, 0x01 }; -static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */ - 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */ -}; - static const struct stv_init stv_bridge_init[] = { /* This reg is written twice. Some kind of reset? */ {NULL, 0x1620, 0x80}, @@ -232,7 +232,6 @@ static const struct stv_init stv_bridge_ {NULL, 0x1423, 0x04}, {x1500, 0x1500, ARRAY_SIZE(x1500)}, {x1536, 0x1536, ARRAY_SIZE(x1536)}, - {x15c1, 0x15c1, ARRAY_SIZE(x15c1)} }; static const u8 vv6410_sensor_init[][2] = {