Re: Kworld 340U (1b80:a340) kernel 4.8.0 ERROR: i2c_transfer returned: -6
Hi Kumar, I don't have time for the em28xx driver at the moment (and I also do not have access to a device with tda18271 tuner). But... Am 08.07.2017 um 22:29 schrieb Kumar Vivek: > New subscriber and first time poster. I have tried to read most of the > instructions and etiquettes regarding the mailing list but there might > still be some noob mistakes on my part. > > I have had this tuner for a while and I used it successfully in 2009 > (with help from Markus Rechberger - who provided me with the > appropriate patch). I saw that the patches were included in the kernel > drivers and this was fully supported. I tried to use it again recently > and ran into problems and hence this mail. I have spent days trying to > figure out the problem and have been unsuccessful. > > I am using kernel 4.8.0 > > The variant of this USB ATSC device I have has vid:pid = 1b80:a340 , > EM2870 USB bridge, lgdt3304 demodulator/Frontend, TDA18271HDC2 tuner. > > I loaded the em28xx module with debugging on - including i2c bus scan > and i2c transfer. > > [ 320.139648] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=0: > [ 320.139652] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 > [ 320.140008] <<< cf > [ 320.140038] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.140732] em2870 #0: found i2c device @ 0x1c on bus 0 [lgdt330x] > > . > [ 320.177163] (pipe 0x8280): IN: c0 02 00 00 a0 00 01 00 > [ 320.177541] <<< 1a > [ 320.177547] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.177663] em2870 #0: found i2c device @ 0xa0 on bus 0 [eeprom] > . > > [ 320.186289] (pipe 0x8280): IN: c0 02 00 00 c4 00 01 00 > [ 320.186659] <<< 84 > [ 320.186665] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.186945] em2870 #0: found i2c device @ 0xc4 on bus 0 [tuner (analog)] > > This is a bit strange since the tuner TDA18271HDC2 is at 0x60 (7 bit) > or 0xC0 (8 bit) i2c address and usually - i2cbus scan doesn't reveal > the tuner's address. > > And then this happens : > [ 320.203404] em2870 #0: Identified as KWorld PlusTV 340U or UB435-Q > (ATSC) (card=76) > [ 320.203406] em28xx: Currently, V4L2 is not supported on this model > [ 320.203407] em2870 #0: dvb set to isoc mode. > [ 320.260270] em2870 #0: Binding DVB extension > [ 320.260274] em2870 #0 em28xx_alloc_urbs :em28xx: called > em28xx_alloc_isoc in mode 2 > [ 320.260276] em2870 #0 em28xx_uninit_usb_xfer :em28xx: called > em28xx_uninit_usb_xfer in mode 2 > [ 320.260279] (pipe 0x8280): IN: c0 00 00 00 0c 00 01 00 <<< 00 > [ 320.260536] (pipe 0x8200): OUT: 40 00 00 00 0c 00 01 00 >>> 00 > [ 320.260631] (pipe 0x8200): OUT: 40 00 00 00 12 00 01 00 >>> 27 > [ 320.260833] (pipe 0x8200): OUT: 40 00 00 00 48 00 01 00 >>> 00 > [ 320.260987] (pipe 0x8200): OUT: 40 00 00 00 12 00 01 00 >>> 37 > [ 320.275990] (pipe 0x8280): IN: c0 00 00 00 08 00 01 00 <<< ff > [ 320.278154] (pipe 0x8200): OUT: 40 00 00 00 08 00 01 00 >>> 7d > [ 320.337050] em2870 #0 at em28xx_i2c_xfer: write nonstop addr=1c len=2: 00 > 01 > [ 320.337056] (pipe 0x8200): OUT: 40 03 00 00 1c 00 02 00 >>> > [ 320.337057] 00 01 > [ 320.337502] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.337618] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=1: > [ 320.337620] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 > [ 320.337860] <<< 30 > [ 320.337867] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > [ 320.337979] 30 > [ 320.337984] em2870 #0 at em28xx_i2c_xfer: write stop addr=1c len=3: 08 08 > 80 > [ 320.337987] (pipe 0x8200): OUT: 40 02 00 00 1c 00 03 00 >>> > [ 320.337988] 08 08 80 > [ 320.338518] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.338618] em2870 #0 at em28xx_i2c_xfer: write nonstop addr=1c len=2: 08 > 08 > [ 320.338622] (pipe 0x8200): OUT: 40 03 00 00 1c 00 02 00 >>> > [ 320.338623] 08 08 > [ 320.339018] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.339110] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=1: > [ 320.339113] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 > [ 320.339391] <<< 80 > [ 320.339397] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > [ 320.339490] 80 > [ 320.339496] em2870 #0 at em28xx_i2c_xfer: write stop addr=1c len=3: 08 08 > 00 > [ 320.339499] (pipe 0x8200): OUT: 40 02 00 00 1c 00 03 00 >>> > [ 320.339499] 08 08 00 > [ 320.340768] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 > > [ 320.341276] tda18271 12-0060: creating new instance > [ 320.341279] em2870 #0 at em28xx_i2c_xfer: write nonstop addr=c0 len=1: 00 > [ 320.341283] (pipe 0x8200): OUT: 40 03 00 00 c0 00 01 00 >>> > [ 320.341284] 00 > [ 320.341506] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 10 > [ 320.341637] ERROR: -6 This means that the i2c client did not ACK the i2c transfer. Due to the "phenomenons" you are describing, I would suspect the tda18271 is in
Re: [PATCH v3 1/2] em28xx: Ignore errors while reading from eeprom
Am 03.05.2017 um 04:12 schrieb Mauro Carvalho Chehab: > While testing support for Terratec H6 rev. 2, it was noticed > that reading from eeprom there causes a timeout error. > > Apparently, this is due to the need of properly setting GPIOs. > > In any case, the driver doesn't really require eeprom reading > to succeed, as this is currently used only for debug. > > So, Ignore such errors. > > Signed-off-by: Mauro Carvalho Chehab <mche...@s-opensource.com> > --- > drivers/media/usb/em28xx/em28xx-i2c.c | 2 -- > 1 file changed, 2 deletions(-) > > diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c > b/drivers/media/usb/em28xx/em28xx-i2c.c > index 8c472d5adb50..60b195c157b8 100644 > --- a/drivers/media/usb/em28xx/em28xx-i2c.c > +++ b/drivers/media/usb/em28xx/em28xx-i2c.c > @@ -982,8 +982,6 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, > dev_err(>intf->dev, > "%s: em28xx_i2_eeprom failed! retval [%d]\n", > __func__, retval); > - > - return retval; > } > } > Makes sense. Acked-by: Frank Schäfer <fschaefer@googlemail.com>
Re: [PATCH v3 2/2] em28xx: add support for new of Terratec H6
Am 03.05.2017 um 04:12 schrieb Mauro Carvalho Chehab: > There's a new version of Terratec H6 with uses USB ID > 0ccd:10b2. This version is similar to the old one (with is > supported via the HTC entry), except that this one has the > eeprom on the second bus. Last half of the sentence isn't true (leftover from v1). > On this board, one side of this board is labeled with: > dvbc v2.0 > The other side with: > 94V-0, MO2, RK-4221 with huge digits: 1107 > > With those patches, the board is properly detected: > > em28xx 1-1.5:1.0: New device TERRATEC TERRATCE H5 MKII @ 480 Mbps > (0ccd:10b2, interface 0, class 0) > em28xx 1-1.5:1.0: Audio interface 0 found (Vendor Class) > em28xx 1-1.5:1.0: Video interface 0 found: isoc > em28xx 1-1.5:1.0: DVB interface 0 found: isoc > em28xx 1-1.5:1.0: chip ID is em2884 > em28xx eeprom : 26 00 00 00 02 0b 0f e5 f5 64 01 60 09 e5 f5 64 > &d.`...d > em28xx eeprom 0010: 09 60 03 c2 c6 22 e5 f7 b4 03 13 e5 f6 b4 87 03 > .`...".. > em28xx eeprom 0020: 02 0a b9 e5 f6 b4 93 03 02 09 46 c2 c6 22 c2 c6 > ..F..".. > em28xx eeprom 0030: 22 00 60 00 ef 70 08 85 3d 82 85 3c 83 93 ff ef > ".`..p..=..< > em28xx eeprom 0040: 60 19 85 3d 82 85 3c 83 e4 93 12 07 a3 12 0a fe > `..=..<. > em28xx eeprom 0050: 05 3d e5 3d 70 02 05 3c 1f 80 e4 22 12 0b 06 02 > .=.=p..<..." > em28xx eeprom 0060: 07 e2 01 00 1a eb 67 95 cd 0c b2 10 f0 13 6b 03 > ..g...k. > em28xx eeprom 0070: 98 22 6a 1c 86 12 27 57 4e 16 29 00 60 00 00 00 > ."j...'WN.).`... > em28xx eeprom 0080: 02 00 00 00 5e 00 13 00 f0 10 44 82 82 00 00 00 > ^.D. > em28xx eeprom 0090: 5b 81 c0 00 00 00 20 40 20 80 02 20 10 01 00 00 > [. @ .. > em28xx eeprom 00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > > em28xx eeprom 00b0: c6 40 00 00 81 00 00 00 00 00 00 00 00 c4 00 00 > .@.. > em28xx eeprom 00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 03 > > em28xx eeprom 00d0: 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 > 1.2.3.4.5.6.7.8. > em28xx eeprom 00e0: 39 00 41 00 42 00 43 00 44 00 12 03 54 00 45 00 > 9.A.B.C.D...T.E. > em28xx eeprom 00f0: 52 00 52 00 41 00 54 00 45 00 43 00 22 03 54 00 > R.R.A.T.E.C.".T. Ok, so the eeprom issue seems to be gone. > em28xx 1-1.5:1.0: eeprom 000100: ... (skipped) > em28xx 1-1.5:1.0: EEPROM ID = 26 00 00 00, EEPROM hash = 0xbcd5a8cf > em28xx 1-1.5:1.0: EEPROM info: > em28xx 1-1.5:1.0: microcode start address = 0x0004, boot configuration = > 0x00 > em28xx 1-1.5:1.0: I2S audio, 5 sample rates > em28xx 1-1.5:1.0: 500mA max power > em28xx 1-1.5:1.0: Table at offset 0x27, strings=0x2298, 0x1c6a, 0x1286 > em28xx 1-1.5:1.0: Identified as Terratec Cinergy H6 rev. 2 (card=101) > em28xx 1-1.5:1.0: Currently, V4L2 is not supported on this model > em28xx 1-1.5:1.0: dvb set to isoc mode. > usbcore: registered new interface driver em28xx > em28xx 1-1.5:1.0: Binding audio extension > em28xx 1-1.5:1.0: em28xx-audio.c: Copyright (C) 2006 Markus Rechberger > em28xx 1-1.5:1.0: em28xx-audio.c: Copyright (C) 2007-2016 Mauro Carvalho > Chehab > em28xx 1-1.5:1.0: Endpoint 0x83 high-speed on intf 0 alt 7 interval = 8, > size 196 > em28xx 1-1.5:1.0: Number of URBs: 1, with 64 packets and 192 size > em28xx 1-1.5:1.0: Audio extension successfully initialized > em28xx: Registered (Em28xx Audio Extension) extension > em28xx 1-1.5:1.0: Binding DVB extension > drxk: status = 0x639260d9 > drxk: detected a drx-3926k, spin A3, xtal 20.250 MHz > drxk: DRXK driver version 0.9.4300 > drxk: frontend initialized. > tda18271 4-0060: creating new instance > tda18271: TDA18271HD/C2 detected @ 4-0060 This confirms that the tuner is a tda18271, hence... > dvbdev: DVB: registering new adapter (1-1.5:1.0) > em28xx 1-1.5:1.0: DVB: registering adapter 0 frontend 0 (DRXK DVB-C > DVB-T)... > dvbdev: dvb_create_media_entity: media entity 'DRXK DVB-C DVB-T' > registered. > dvbdev: dvb_create_media_entity: media entity 'dvb-demux' registered. > em28xx 1-1.5:1.0: DVB extension successfully initialized > em28xx: Registered (Em28xx dvb Extension) extension > em28xx 1-1.5:1.0: Registering input extension > rc rc0: 1-1.5:1.0 IR as > /devices/platform/soc/3f98.usb/usb1/1-1/1-1.5/1-1.5:1.0/rc/rc0 > Registered IR keymap rc-nec-terratec-cinergy-xs > input: 1-1.5:1.0 IR as > /devices/platform/soc/3f98.usb/usb1/1-1/1-1.5/1-1.5:1.0/rc/rc0/input0 > em28xx 1-1.5:1.0: Input extension successfully initalized > em28xx: Registered (Em28xx Input Extension) extension > tda18271: performing RF tracking filter calibration > tda18271: RF tracking filter calibration complete > > Signed-off-by: Mauro
Re: [PATCH 1/2] em28xx: allow setting the eeprom bus at cards struct
Am 01.05.2017 um 19:54 schrieb Mauro Carvalho Chehab: > Hi Frank, > > Em Mon, 1 May 2017 16:11:51 +0200 > Frank Schäfer <fschaefer@googlemail.com> escreveu: > >> Am 01.05.2017 um 13:38 schrieb Mauro Carvalho Chehab: >>> Right now, all devices use bus 0 for eeprom. However, newer >>> versions of Terratec H6 use a different buffer for eeprom. >>> >>> So, add support to use a different I2C address for eeprom. >> Has this been tested ? >> Did you read my reply to the previous patch version ?: >> See http://www.spinics.net/lists/linux-media/msg114860.html >> >> I doubt it will work. At least not for the device from the thread in the >> Kodi-forum. > Yes. Someone at IRC were complaining about this device (his nick is > buxy81). Ahh, you are in contact with him ? That's good. > According with the tests he did, with both patches his > device is now working. I guess it works because (due to the first patch) no eeprom is detected anymore. In this case the driver prints a "board has no eeprom" message to the log and continues. > That's said, it would be great if he could provide us more details > about the tests he did, with the logs enabled, in order for us to see > if the eeprom contents is properly read. Yes, further tests/details are required. Can you ask him to join the list ? Regards, Frank > > > Thanks, > Mauro
Re: [PATCH 1/2] em28xx: allow setting the eeprom bus at cards struct
Am 01.05.2017 um 13:38 schrieb Mauro Carvalho Chehab: > Right now, all devices use bus 0 for eeprom. However, newer > versions of Terratec H6 use a different buffer for eeprom. > > So, add support to use a different I2C address for eeprom. Has this been tested ? Did you read my reply to the previous patch version ?: See http://www.spinics.net/lists/linux-media/msg114860.html I doubt it will work. At least not for the device from the thread in the Kodi-forum. Regards, Frank > Signed-off-by: Mauro Carvalho Chehab> --- > drivers/media/usb/em28xx/em28xx-cards.c | 1 + > drivers/media/usb/em28xx/em28xx-i2c.c | 5 + > drivers/media/usb/em28xx/em28xx.h | 4 +++- > 3 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/usb/em28xx/em28xx-cards.c > b/drivers/media/usb/em28xx/em28xx-cards.c > index a12b599a1fa2..c7754303e88e 100644 > --- a/drivers/media/usb/em28xx/em28xx-cards.c > +++ b/drivers/media/usb/em28xx/em28xx-cards.c > @@ -2669,6 +2669,7 @@ static inline void em28xx_set_model(struct em28xx *dev) > > /* Should be initialized early, for I2C to work */ > dev->def_i2c_bus = dev->board.def_i2c_bus; > + dev->eeprom_i2c_bus = dev->board.eeprom_i2c_bus; > } > > /* Wait until AC97_RESET reports the expected value reliably before > proceeding. > diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c > b/drivers/media/usb/em28xx/em28xx-i2c.c > index 8c472d5adb50..df0ab4b6f18f 100644 > --- a/drivers/media/usb/em28xx/em28xx-i2c.c > +++ b/drivers/media/usb/em28xx/em28xx-i2c.c > @@ -665,8 +665,6 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned > bus, > *eedata = NULL; > *eedata_len = 0; > > - /* EEPROM is always on i2c bus 0 on all known devices. */ > - > dev->i2c_client[bus].addr = 0xa0 >> 1; > > /* Check if board has eeprom */ > @@ -975,8 +973,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, > dev->i2c_client[bus] = em28xx_client_template; > dev->i2c_client[bus].adapter = >i2c_adap[bus]; > > - /* Up to now, all eeproms are at bus 0 */ > - if (!bus) { > + if (bus == dev->eeprom_i2c_bus) { > retval = em28xx_i2c_eeprom(dev, bus, >eedata, > >eedata_len); > if ((retval < 0) && (retval != -ENODEV)) { > dev_err(>intf->dev, > diff --git a/drivers/media/usb/em28xx/em28xx.h > b/drivers/media/usb/em28xx/em28xx.h > index e8d97d5ec161..8117536343ab 100644 > --- a/drivers/media/usb/em28xx/em28xx.h > +++ b/drivers/media/usb/em28xx/em28xx.h > @@ -440,7 +440,8 @@ struct em28xx_board { > int vchannels; > int tuner_type; > int tuner_addr; > - unsigned def_i2c_bus; /* Default I2C bus */ > + unsigned def_i2c_bus; /* Default I2C bus */ > + unsigned eeprom_i2c_bus;/* EEPROM I2C bus */ > > /* i2c flags */ > unsigned int tda9887_conf; > @@ -643,6 +644,7 @@ struct em28xx { > > unsigned char eeprom_addrwidth_16bit:1; > unsigned def_i2c_bus; /* Default I2C bus */ > + unsigned eeprom_i2c_bus;/* EEPROM I2C bus */ > unsigned cur_i2c_bus; /* Current I2C bus */ > struct rt_mutex i2c_bus_lock; >
Re: em28xx module: misidentified card
Am 28.04.2017 um 13:22 schrieb Giuseppe Toscano: > I am trying to use eMPIA Technology, Inc. GrabBeeX+ Video Encoder > (card=21) but the em28xx driver erroneously identifies it as > EM2860/SAA711X Reference Design (card = 19). > Attached the output of lsusb and dmesg. > Card 21 is an em2800 device, while your device uses an em2710/em2820 (see log). Card 19 should work. Did you test it ? Regards, Frank > Best regards, > > Giuseppe Toscano
em28xx debug module parameters
Hi Mauro, is there a chance that we can clean up the em28xx debug module parameter mess ? There are currently 8 (!) of them. Do we have to maintain them all forever as "stable userspace interface" ? For example: - "reg_debug" is actually used for usb control message debugging - "core_debug" is abused for usb isoc debugging and not used for anything else - there is a module parameter "isoc_debug", too, but it is used by em28xx-v4l only ... Regards, Frank
[PATCH] em28xx: fix+improve the register (usb control message) debugging
- avoid duplicate debugging messages in em28xx_read_reg_req_len() - do not describe successful usb transfers in em28xx_read_reg_len() as "failed" - report errors in em28xx_write_regs_req(), too - print the usb error numbers, too Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-core.c | 35 +- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 19ccff41c7eb..76d3c2a5f9e4 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -91,22 +91,16 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (len > URB_MAX_CTRL_SIZE) return -EINVAL; - em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x ", -pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, -req, 0, 0, -reg & 0xff, reg >> 8, -len & 0xff, len >> 8); - mutex_lock(>ctrl_urb_lock); ret = usb_control_msg(udev, pipe, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x, reg, dev->urb_buf, len, HZ); if (ret < 0) { - em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed\n", + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, req, 0, 0, reg & 0xff, reg >> 8, -len & 0xff, len >> 8); +len & 0xff, len >> 8, ret); mutex_unlock(>ctrl_urb_lock); return usb_translate_errors(ret); } @@ -116,7 +110,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, mutex_unlock(>ctrl_urb_lock); - em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed <<< %*ph\n", + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x <<< %*ph\n", pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, req, 0, 0, reg & 0xff, reg >> 8, @@ -164,13 +158,6 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) return -EINVAL; - em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph\n", - pipe, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - req, 0, 0, - reg & 0xff, reg >> 8, - len & 0xff, len >> 8, len, buf); - mutex_lock(>ctrl_urb_lock); memcpy(dev->urb_buf, buf, len); ret = usb_control_msg(udev, pipe, req, @@ -178,8 +165,22 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, 0x, reg, dev->urb_buf, len, HZ); mutex_unlock(>ctrl_urb_lock); - if (ret < 0) + if (ret < 0) { + em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph failed with error %i\n", + pipe, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, len, buf, ret); return usb_translate_errors(ret); + } + + em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph\n", + pipe, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + req, 0, 0, + reg & 0xff, reg >> 8, + len & 0xff, len >> 8, len, buf); if (dev->wait_after_write) msleep(dev->wait_after_write); -- 2.12.2
Re: [PATCH] [RFC] em28xx: allow setting the eeprom bus at cards struct
Am 25.04.2017 um 12:06 schrieb Mauro Carvalho Chehab: > Right now, all devices use bus 0 for eeprom. However, > it seems that newer versions of Terratec H6 uses a different > buffer for eeprom. > > So, add support to use a different I2C address for eeprom and > add a new card ID for the board described at: > http://forum.kodi.tv/showthread.php?tid=312902 I'm not 100% sure, but IIRC the bridge expects the eeprom to be always on bus 0. Anyway, looking at the information provided by the thread creator, it seems that the eeprom is detected as usual on bus 0. Otherwise "board has no eeprom" would have been printed to the log. What happens here is that em28xx_i2c_read_block() fails with -ETIMEDOUT, which means that the i2c status reported by the em2884 is (still) 0x02 or 0x04 when the timeout is reached. See em28xx_i2c_send_bytes() and em28xx_i2c_recv_bytes(). Further tests/debugging is required to find out what exactly is going on. Turning on debug module paramters i2c_debug and reg_debug would help. > PS.: This patch was meant to allow testing the device. It may > be wrong or incomplete, as it doesn't attempt to set GPIOs. > > Signed-off-by: Mauro Carvalho Chehab> --- > drivers/media/usb/em28xx/em28xx-cards.c | 20 > drivers/media/usb/em28xx/em28xx-i2c.c | 5 + > drivers/media/usb/em28xx/em28xx.h | 5 - > 3 files changed, 25 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/usb/em28xx/em28xx-cards.c > b/drivers/media/usb/em28xx/em28xx-cards.c > index a12b599a1fa2..b788ae0d5646 100644 > --- a/drivers/media/usb/em28xx/em28xx-cards.c > +++ b/drivers/media/usb/em28xx/em28xx-cards.c > @@ -1193,6 +1193,23 @@ struct em28xx_board em28xx_boards[] = { > .i2c_speed= EM28XX_I2C_CLK_WAIT_ENABLE | > EM28XX_I2C_FREQ_400_KHZ, > }, > + [EM2884_BOARD_TERRATEC_H6] = { > + .name = "Terratec Cinergy H6", > + .has_dvb = 1, > + .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, > +#if 0 > + .tuner_type = TUNER_PHILIPS_TDA8290, According to the thread, the tuner is a TDA18271 !? Regards, Frank > + .tuner_addr = 0x41, > + .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ > + .tuner_gpio = terratec_h5_gpio, > +#else > + .tuner_type = TUNER_ABSENT, > +#endif > + .def_i2c_bus = 1, > + .eeprom_i2c_bus = 1, > + .i2c_speed= EM28XX_I2C_CLK_WAIT_ENABLE | > + EM28XX_I2C_FREQ_400_KHZ, > + }, > [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { > .name = "Hauppauge WinTV HVR 930C", > .has_dvb = 1, > @@ -2496,6 +2513,8 @@ struct usb_device_id em28xx_id_table[] = { > .driver_info = EM2884_BOARD_TERRATEC_H5 }, > { USB_DEVICE(0x0ccd, 0x10b6), /* H5 Rev. 3 */ > .driver_info = EM2884_BOARD_TERRATEC_H5 }, > + { USB_DEVICE(0x0ccd, 0x10b2), /* H6 */ > + .driver_info = EM2884_BOARD_TERRATEC_H6 }, > { USB_DEVICE(0x0ccd, 0x0084), > .driver_info = EM2860_BOARD_TERRATEC_AV350 }, > { USB_DEVICE(0x0ccd, 0x0096), > @@ -2669,6 +2688,7 @@ static inline void em28xx_set_model(struct em28xx *dev) > > /* Should be initialized early, for I2C to work */ > dev->def_i2c_bus = dev->board.def_i2c_bus; > + dev->eeprom_i2c_bus = dev->board.eeprom_i2c_bus; > } > > /* Wait until AC97_RESET reports the expected value reliably before > proceeding. > diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c > b/drivers/media/usb/em28xx/em28xx-i2c.c > index 8c472d5adb50..df0ab4b6f18f 100644 > --- a/drivers/media/usb/em28xx/em28xx-i2c.c > +++ b/drivers/media/usb/em28xx/em28xx-i2c.c > @@ -665,8 +665,6 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned > bus, > *eedata = NULL; > *eedata_len = 0; > > - /* EEPROM is always on i2c bus 0 on all known devices. */ > - > dev->i2c_client[bus].addr = 0xa0 >> 1; > > /* Check if board has eeprom */ > @@ -975,8 +973,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, > dev->i2c_client[bus] = em28xx_client_template; > dev->i2c_client[bus].adapter = >i2c_adap[bus]; > > - /* Up to now, all eeproms are at bus 0 */ > - if (!bus) { > + if (bus == dev->eeprom_i2c_bus) { > retval = em28xx_i2c_eeprom(dev, bus, >eedata, > >eedata_len); > if ((retval < 0) && (retval != -ENODEV)) { > dev_err(>intf->dev, > diff --git a/drivers/media/usb/em28xx/em28xx.h > b/drivers/media/usb/em28xx/em28xx.h > index e8d97d5ec161..a333ca954129 100644 > --- a/drivers/media/usb/em28xx/em28xx.h > +++ b/drivers/media/usb/em28xx/em28xx.h > @@ -148,6 +148,7 @@ > #define EM28178_BOARD_PLEX_PX_BCUD98 > #define
Re: em28xx i2c writing error
Am 15.04.2017 um 20:28 schrieb Anders Eriksson: > Hi Mauro, > > I've two devices using this driver, and whenever I have them both in > use I eventually (between 10K and 100K secs uptime) i2c write errors > such as in the log below. If only have one of the devices in use, the > machine is stable. > > The machine never recovers from the error. > > All help apreciated. > -Anders > > > > [0.00] Booting Linux on physical CPU 0xf00 > [0.00] Initializing cgroup subsys cpuset > [0.00] Initializing cgroup subsys cpu > [0.00] Initializing cgroup subsys cpuacct > [0.00] Linux version 4.4.15-v7+ (dc4@dc4-XPS13-9333) (gcc > version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #897 > SMP Tue Jul 12 18:42:55 BST 2016 > [0.00] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d > [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing > instruction cache > [0.00] Machine model: Raspberry Pi 2 Model B Rev 1.1 > [0.00] cma: Reserved 8 MiB at 0x3a80 > [0.00] Memory policy: Data cache writealloc > [0.00] On node 0 totalpages: 241664 > [0.00] free_area_init_node: node 0, pgdat 808c0e00, > node_mem_map b9fa6000 > [0.00] Normal zone: 2124 pages used for memmap > [0.00] Normal zone: 0 pages reserved > [0.00] Normal zone: 241664 pages, LIFO batch:31 > [0.00] [bcm2709_smp_init_cpus] enter (9520->f3003010) > [0.00] [bcm2709_smp_init_cpus] ncores=4 > [0.00] PERCPU: Embedded 13 pages/cpu @b9f62000 s22592 r8192 > d22464 u53248 > [0.00] pcpu-alloc: s22592 r8192 d22464 u53248 alloc=13*4096 > [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 > [0.00] Built 1 zonelists in Zone order, mobility grouping on. > Total pages: 239540 > [0.00] Kernel command line: dma.dmachans=0x7f35 > bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 > bcm2709.boardrev=0xa01041 bcm2709.serial=0x9aa48012 > smsc95xx.macaddr=B8:27:EB:A4:80:12 bcm2708_fb.fbswap=1 > bcm2709.uart_clock=4800 bcm2709.disk_led_gpio=47 > bcm2709.disk_led_active_low=0 vc_mem.mem_base=0x3dc0 > vc_mem.mem_size=0x3f00 root=/dev/mmcblk0p4 smsc95xx.turbo_mode=N > rootdelay=2 console=ttyAMA0,115200 console=tty0 kgdboc=ttyAMA0,115200 > init=/usr/lib/systemd/systemd ro > [0.00] PID hash table entries: 4096 (order: 2, 16384 bytes) > [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 > bytes) > [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) > [0.00] Memory: 939080K/966656K available (6344K kernel code, > 432K rwdata, 1712K rodata, 476K init, 764K bss, 19384K reserved, 8192K > cma-reserved) > [0.00] Virtual kernel memory layout: >vector : 0x - 0x1000 ( 4 kB) >fixmap : 0xffc0 - 0xfff0 (3072 kB) >vmalloc : 0xbb80 - 0xff80 (1088 MB) >lowmem : 0x8000 - 0xbb00 ( 944 MB) >modules : 0x7f00 - 0x8000 ( 16 MB) > .text : 0x80008000 - 0x807e6470 (8058 kB) > .init : 0x807e7000 - 0x8085e000 ( 476 kB) > .data : 0x8085e000 - 0x808ca108 ( 433 kB) > .bss : 0x808cd000 - 0x8098c1ac ( 765 kB) > [0.00] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 > [0.00] Hierarchical RCU implementation. > [0.00] Build-time adjustment of leaf fanout to 32. > [0.00] NR_IRQS:16 nr_irqs:16 16 > [0.00] Architected cp15 timer(s) running at 19.20MHz (phys). > [0.00] clocksource: arch_sys_counter: mask: 0xff > max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns > [0.11] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps > every 4398046511078ns > [0.32] Switching to timer-based delay loop, resolution 52ns > [0.000353] Console: colour dummy device 80x30 > [0.001539] console [tty0] enabled > [0.001591] Calibrating delay loop (skipped), value calculated > using timer frequency.. 38.40 BogoMIPS (lpj=192000) > [0.001667] pid_max: default: 32768 minimum: 301 > [0.002077] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) > [0.002128] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 > bytes) > [0.003338] Disabling cpuset control group subsystem > [0.003423] Initializing cgroup subsys io > [0.003483] Initializing cgroup subsys memory > [0.003563] Initializing cgroup subsys devices > [0.003615] Initializing cgroup subsys freezer > [0.003665] Initializing cgroup subsys net_cls > [0.003764] CPU: Testing write buffer coherency: ok > [0.003878] ftrace: allocating 21209 entries in 63 pages > [0.056189] CPU0: update cpu_capacity 1024 > [0.056269] CPU0: thread -1, cpu 0, socket 15, mpidr 8f00 > [0.056306] [bcm2709_smp_prepare_cpus] enter >
[PATCH v2] em28xx: simplify ID-reading from Micron sensors
Use i2c_smbus_read_word_data() instead of i2c_master_send() and i2c_master_recv() for reading the ID of Micorn sensors. i2c_smbus_read_word_data() assumes that byes are in little-endian, so, it uses: data->word = msgbuf1[0] | (msgbuf1[1] << 8); However, Micron datasheet describes the ID as if they were read in big-endian. So, we need to change the byte order in order to match the ID number as described on their datasheets. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> Acked-by: Mauro Carvalho Chehab <mche...@s-opensource.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 28 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 95eaa55356a9..ae87dd3e671f 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -97,8 +97,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; - __be16 id_be; u16 id; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; @@ -106,10 +104,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(client, , 1); + ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */ if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, @@ -117,24 +113,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) client->addr << 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - id = be16_to_cpu(id_be); + id = swab16(ret); /* LE -> BE */ /* Read chip ID from register 0xff */ - reg = 0xff; - ret = i2c_master_send(client, , 1); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - ret = i2c_master_recv(client, (u8 *)_be, 2); + ret = i2c_smbus_read_word_data(client, 0xff); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", @@ -142,10 +123,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) continue; } /* Validate chip ID to be sure we have a Micron device */ - if (id != be16_to_cpu(id_be)) + if (id != swab16(ret)) continue; /* Check chip ID */ - id = be16_to_cpu(id_be); switch (id) { case 0x1222: name = "MT9V012"; /* MI370 */ /* 640x480 */ -- 2.12.2
[PATCH 5/7] ov2640: fix duplicate width+height returning from ov2640_select_win()
ov2640_select_win() returns height and width values as part of struct ov2640_win_size, so there is no point in modifying the passed height and width parameters, too. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 6f0cc722477d..123767c58e83 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -775,21 +775,16 @@ static int ov2640_s_power(struct v4l2_subdev *sd, int on) } /* Select the nearest higher resolution for capture */ -static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height) +static const struct ov2640_win_size *ov2640_select_win(u32 width, u32 height) { int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1; for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) { - if (ov2640_supported_win_sizes[i].width >= *width && - ov2640_supported_win_sizes[i].height >= *height) { - *width = ov2640_supported_win_sizes[i].width; - *height = ov2640_supported_win_sizes[i].height; + if (ov2640_supported_win_sizes[i].width >= width && + ov2640_supported_win_sizes[i].height >= height) return _supported_win_sizes[i]; - } } - *width = ov2640_supported_win_sizes[default_size].width; - *height = ov2640_supported_win_sizes[default_size].height; return _supported_win_sizes[default_size]; } @@ -880,8 +875,7 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd, return -EINVAL; if (!priv->win) { - u32 width = SVGA_WIDTH, height = SVGA_HEIGHT; - priv->win = ov2640_select_win(, ); + priv->win = ov2640_select_win(SVGA_WIDTH, SVGA_HEIGHT); priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; } @@ -906,7 +900,9 @@ static int ov2640_set_fmt(struct v4l2_subdev *sd, return -EINVAL; /* select suitable win */ - win = ov2640_select_win(>width, >height); + win = ov2640_select_win(mf->width, mf->height); + mf->width = win->width; + mf->height = win->height; mf->field = V4L2_FIELD_NONE; mf->colorspace = V4L2_COLORSPACE_SRGB; -- 2.12.2
[PATCH 7/7] ov2640: add support for MEDIA_BUS_FMT_YVYU8_2X8 and MEDIA_BUS_FMT_VYUY8_2X8
Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 6aba0ffe486d..618230e782e7 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -634,6 +634,8 @@ static const struct regval_list ov2640_rgb565_le_regs[] = { static u32 ov2640_codes[] = { MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, MEDIA_BUS_FMT_RGB565_2X8_BE, MEDIA_BUS_FMT_RGB565_2X8_LE, }; @@ -795,6 +797,7 @@ static int ov2640_set_params(struct i2c_client *client, { struct ov2640_priv *priv = to_ov2640(client); const struct regval_list *selected_cfmt_regs; + u8 val; int ret; /* select win */ @@ -820,6 +823,14 @@ static int ov2640_set_params(struct i2c_client *client, dev_dbg(>dev, "%s: Selected cfmt UYVY", __func__); selected_cfmt_regs = ov2640_uyvy_regs; break; + case MEDIA_BUS_FMT_YVYU8_2X8: + dev_dbg(>dev, "%s: Selected cfmt YVYU", __func__); + selected_cfmt_regs = ov2640_yuyv_regs; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + dev_dbg(>dev, "%s: Selected cfmt VYUY", __func__); + selected_cfmt_regs = ov2640_uyvy_regs; + break; } /* reset hardware */ @@ -852,6 +863,11 @@ static int ov2640_set_params(struct i2c_client *client, ret = ov2640_write_array(client, selected_cfmt_regs); if (ret < 0) goto err; + val = (code == MEDIA_BUS_FMT_YVYU8_2X8) + || (code == MEDIA_BUS_FMT_VYUY8_2X8) ? CTRL0_VFIRST : 0x00; + ret = ov2640_mask_set(client, CTRL0, CTRL0_VFIRST, val); + if (ret < 0) + goto err; priv->cfmt_code = code; @@ -914,6 +930,8 @@ static int ov2640_set_fmt(struct v4l2_subdev *sd, case MEDIA_BUS_FMT_RGB565_2X8_LE: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: break; default: mf->code = MEDIA_BUS_FMT_UYVY8_2X8; -- 2.12.2
[PATCH 6/7] ov2640: fix vflip control
Enabling vflip currently causes wrong colors. It seems that (at least with the current sensor setup) REG04_VFLIP_IMG only changes the vertical readout direction. Because pixels are arranged RGRG... in odd lines and GBGB... in even lines, either a one line shift or even/odd line swap is required, too, but apparently this doesn't happen. I finally figured out that this can be done manually by setting REG04_VREF_EN. Looking at hflip, it turns out that bit REG04_HREF_EN is set there permanetly, but according to my tests has no effect on the pixel readout order. So my conclusion is that the current documentation of sensor register 0x04 is wrong (has changed after preliminary datasheet version 2.2). I'm pretty sure that automatic vertical line shift/switch can be enabled, too, but until anyone finds ot how this works, we have to stick with manual switching. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> Cc: stable <sta...@vger.kernel.org> --- drivers/media/i2c/ov2640.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 123767c58e83..6aba0ffe486d 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -716,8 +716,10 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_VFLIP: - val = ctrl->val ? REG04_VFLIP_IMG : 0x00; - return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val); + val = ctrl->val ? REG04_VFLIP_IMG | REG04_VREF_EN : 0x00; + return ov2640_mask_set(client, REG04, + REG04_VFLIP_IMG | REG04_VREF_EN, val); + /* NOTE: REG04_VREF_EN: 1 line shift / even/odd line swap */ case V4L2_CID_HFLIP: val = ctrl->val ? REG04_HFLIP_IMG : 0x00; return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val); -- 2.12.2
[PATCH 4/7] ov2640: add missing write to size change preamble
HSIZE and VSIZE bits 0 to 2 and HSIZE bit 11 are encoded in DSP register SIZEL. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 11f1b807c292..6f0cc722477d 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -500,6 +500,9 @@ static const struct regval_list ov2640_init_regs[] = { static const struct regval_list ov2640_size_change_preamble_regs[] = { { BANK_SEL, BANK_SEL_DSP }, { RESET, RESET_DVP }, + { SIZEL, SIZEL_HSIZE8_11_SET(UXGA_WIDTH) | +SIZEL_HSIZE8_SET(UXGA_WIDTH) | +SIZEL_VSIZE8_SET(UXGA_HEIGHT) }, { HSIZE8, HSIZE8_SET(UXGA_WIDTH) }, { VSIZE8, VSIZE8_SET(UXGA_HEIGHT) }, { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | -- 2.12.2
[PATCH 3/7] ov2640: add information about DSP register 0xc7
According to ov2640 software application notes, there are two Automatic White Balance (AWB) modes, which are selected by DSP register 0xc7: 1) Simple AWB: assumes the average color is gray + independent from lens - doesn't work well if captured area contains unbalanced colors (e.g. large blue background) 2) Advanced AWB: uses color temperature information + more accurate, works with all image contents - lens specific, requires calibration Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index fd1b215b6dec..11f1b807c292 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -106,6 +106,10 @@ #define CTRL1_AWB_GAIN 0x04 #define CTRL1_LENC 0x02 #define CTRL1_PRE 0x01 +/* REG 0xC7 (unknown name): affects Auto White Balance (AWB) + * AWB_OFF0x40 + * AWB_SIMPLE 0x10 + * AWB_ON 0x00 (Advanced AWB ?) */ #define R_DVP_SP0xD3 /* DVP output speed control */ #define R_DVP_SP_AUTO_MODE 0x80 #define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0); @@ -449,7 +453,7 @@ static const struct regval_list ov2640_init_regs[] = { { 0xc5, 0x11 }, { 0xc6, 0x51 }, { 0xbf, 0x80 }, - { 0xc7, 0x10 }, + { 0xc7, 0x10 }, /* simple AWB */ { 0xb6, 0x66 }, { 0xb8, 0xA5 }, { 0xb7, 0x64 }, -- 2.12.2
[PATCH 2/7] ov2640: improve banding filter register definitions/documentation
- add missing initialisation of sensor register COM25 (2 MSBs of banding filter AEC values) - add macros for setting the banding filter AEC values - add definitions for sensor register 0x5a, which is documented in Omnivisions software application notes Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index df9f6c7a929c..fd1b215b6dec 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -248,8 +248,19 @@ #define ZOOMS 0x49 /* Zoom: Vertical start point */ #define COM22 0x4B /* Flash light control */ #define COM25 0x4E /* For Banding operations */ +#define COM25_50HZ_BANDING_AEC_MSBS_MASK 0xC0 /* 50Hz Bd. AEC 2 MSBs */ +#define COM25_60HZ_BANDING_AEC_MSBS_MASK 0x30 /* 60Hz Bd. AEC 2 MSBs */ +#define COM25_50HZ_BANDING_AEC_MSBS_SET(x)VAL_SET(x, 0x3, 8, 6) +#define COM25_60HZ_BANDING_AEC_MSBS_SET(x)VAL_SET(x, 0x3, 8, 4) #define BD500x4F /* 50Hz Banding AEC 8 LSBs */ +#define BD50_50HZ_BANDING_AEC_LSBS_SET(x) VAL_SET(x, 0xFF, 0, 0) #define BD600x50 /* 60Hz Banding AEC 8 LSBs */ +#define BD60_60HZ_BANDING_AEC_LSBS_SET(x) VAL_SET(x, 0xFF, 0, 0) +#define REG5A 0x5A /* 50/60Hz Banding Maximum AEC Step */ +#define BD50_MAX_AEC_STEP_MASK 0xF0 /* 50Hz Banding Max. AEC Step */ +#define BD60_MAX_AEC_STEP_MASK 0x0F /* 60Hz Banding Max. AEC Step */ +#define BD50_MAX_AEC_STEP_SET(x) VAL_SET((x - 1), 0x0F, 0, 4) +#define BD60_MAX_AEC_STEP_SET(x) VAL_SET((x - 1), 0x0F, 0, 0) #define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */ #define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */ #define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */ @@ -356,9 +367,12 @@ static const struct regval_list ov2640_init_regs[] = { { 0x73, 0xc1 }, { 0x3d, 0x34 }, { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, - { 0x5a, 0x57 }, - { BD50, 0xbb }, - { BD60, 0x9c }, + { REG5A, BD50_MAX_AEC_STEP_SET(6) + | BD60_MAX_AEC_STEP_SET(8) },/* 0x57 */ + { COM25, COM25_50HZ_BANDING_AEC_MSBS_SET(0x0bb) + | COM25_60HZ_BANDING_AEC_MSBS_SET(0x09c) }, /* 0x00 */ + { BD50, BD50_50HZ_BANDING_AEC_LSBS_SET(0x0bb) }, /* 0xbb */ + { BD60, BD60_60HZ_BANDING_AEC_LSBS_SET(0x09c) }, /* 0x9c */ { BANK_SEL, BANK_SEL_DSP }, { 0xe5, 0x7f }, { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, -- 2.12.2
[PATCH 0/7] ov2640 fixes and improvements
First 5 patches are minor fixes/cleanups/improvements which I came across while testing Hans Verkuils patches and trying to figure out what's going wrong with vflip control. Patch 6 finally fixes the vflip bug. Patch 7 adds support for 2 new pixel formats. Frank Schäfer (7): ov2640: fix init sequence alignment ov2640: improve banding filter register definitions/documentation ov2640: add information about DSP register 0xc7 ov2640: add missing write to size change preamble ov2640: fix duplicate width+height returning from ov2640_select_win() ov2640: fix vflip control ov2640: add support for MEDIA_BUS_FMT_YVYU8_2X8 and MEDIA_BUS_FMT_VYUY8_2X8 drivers/media/i2c/ov2640.c | 96 -- 1 file changed, 67 insertions(+), 29 deletions(-) -- 2.12.2
[PATCH 1/7] ov2640: fix init sequence alignment
While we are at it, remove a misleading comment (copy/paste mistake) Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/i2c/ov2640.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index d55ca37dc12f..df9f6c7a929c 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -199,7 +199,7 @@ #define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */ #define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */ #define COM80x13 /* Common control 8 */ -#define COM8_DEF 0xC0 /* Banding filter ON/OFF */ +#define COM8_DEF 0xC0 #define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */ #define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ #define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ @@ -306,11 +306,11 @@ static const struct regval_list ov2640_init_regs[] = { { 0x2e, 0xdf }, { BANK_SEL, BANK_SEL_SENS }, { 0x3c, 0x32 }, - { CLKRC, CLKRC_DIV_SET(1) }, - { COM2, COM2_OCAP_Nx_SET(3) }, - { REG04, REG04_DEF | REG04_HREF_EN }, - { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN }, - { COM9, COM9_AGC_GAIN_8x | 0x08}, + { CLKRC, CLKRC_DIV_SET(1) }, + { COM2, COM2_OCAP_Nx_SET(3) }, + { REG04, REG04_DEF | REG04_HREF_EN }, + { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN }, + { COM9, COM9_AGC_GAIN_8x | 0x08}, { 0x2c, 0x0c }, { 0x33, 0x78 }, { 0x3a, 0x33 }, @@ -355,25 +355,25 @@ static const struct regval_list ov2640_init_regs[] = { { 0x71, 0x94 }, { 0x73, 0xc1 }, { 0x3d, 0x34 }, - { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, + { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, { 0x5a, 0x57 }, { BD50, 0xbb }, { BD60, 0x9c }, - { BANK_SEL, BANK_SEL_DSP }, + { BANK_SEL, BANK_SEL_DSP }, { 0xe5, 0x7f }, - { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, + { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, { 0x41, 0x24 }, - { RESET, RESET_JPEG | RESET_DVP }, + { RESET, RESET_JPEG | RESET_DVP }, { 0x76, 0xff }, { 0x33, 0xa0 }, { 0x42, 0x20 }, { 0x43, 0x18 }, { 0x4c, 0x00 }, - { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, + { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, { 0x88, 0x3f }, { 0xd7, 0x03 }, { 0xd9, 0x10 }, - { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 }, + { R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2 }, { 0xc8, 0x08 }, { 0xc9, 0x80 }, { BPADDR, 0x00 }, -- 2.12.2
[PATCH 2/5] em28xx: add missing auto-selections for build
With MEDIA_SUBDRV_AUTOSELECT enabled in the kernel config, the em28xx driver currently does't select some used subdrivers. Fix this by adding the missing auto-selections to the Kconfig file. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/Kconfig | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index aa131cf9989b..4cc029f18aa8 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig @@ -12,7 +12,7 @@ config VIDEO_EM28XX_V4L2 select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT - + select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT ---help--- This is a video4linux driver for Empia 28xx based TV cards. @@ -39,6 +39,7 @@ config VIDEO_EM28XX_DVB depends on VIDEO_EM28XX && DVB_CORE select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT + select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT select DVB_S921 if MEDIA_SUBDRV_AUTOSELECT @@ -61,6 +62,10 @@ config VIDEO_EM28XX_DVB select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_QM1D1C0042 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT ---help--- This adds support for DVB cards based on the Empiatech em28xx chips. -- 2.12.2
[PATCH 1/5] em28xx: get rid of the dummy clock source
The v4l2 dummy clock has been added with commit fc5d0f8a8878 ("V4L2: em28xx: register a V4L2 clock source") to be able to use the ov2640 soc_camera driver. Since commit 46796cfcd346 ("ov2640: use standard clk and enable it") it is no longer required. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 30 ++ drivers/media/usb/em28xx/em28xx-video.c | 6 -- drivers/media/usb/em28xx/em28xx.h| 1 - 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 2f59237ee399..d43f630050bb 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /* Possible i2c addresses of Micron sensors */ @@ -331,17 +330,9 @@ int em28xx_detect_sensor(struct em28xx *dev) int em28xx_init_camera(struct em28xx *dev) { - char clk_name[V4L2_CLK_NAME_SIZE]; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; struct i2c_adapter *adap = >i2c_adap[dev->def_i2c_bus]; struct em28xx_v4l2 *v4l2 = dev->v4l2; - int ret = 0; - - v4l2_clk_name_i2c(clk_name, sizeof(clk_name), - i2c_adapter_id(adap), client->addr); - v4l2->clk = v4l2_clk_register_fixed(clk_name, -EINVAL); - if (IS_ERR(v4l2->clk)) - return PTR_ERR(v4l2->clk); switch (dev->em28xx_sensor) { case EM28XX_MT9V011: @@ -371,10 +362,8 @@ int em28xx_init_camera(struct em28xx *dev) pdata.xtal = v4l2->sensor_xtal; if (NULL == v4l2_i2c_new_subdev_board(>v4l2_dev, adap, - _info, NULL)) { - ret = -ENODEV; - break; - } + _info, NULL)) + return -ENODEV; /* probably means GRGB 16 bit bayer */ v4l2->vinmode = 0x0d; v4l2->vinctl = 0x00; @@ -430,10 +419,8 @@ int em28xx_init_camera(struct em28xx *dev) subdev = v4l2_i2c_new_subdev_board(>v4l2_dev, adap, _info, NULL); - if (NULL == subdev) { - ret = -ENODEV; - break; - } + if (subdev == NULL) + return -ENODEV; format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; format.format.width = 640; @@ -450,14 +437,9 @@ int em28xx_init_camera(struct em28xx *dev) } case EM28XX_NOSENSOR: default: - ret = -EINVAL; - } - - if (ret < 0) { - v4l2_clk_unregister_fixed(v4l2->clk); - v4l2->clk = NULL; + return -EINVAL; } - return ret; + return 0; } EXPORT_SYMBOL_GPL(em28xx_init_camera); diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 8d93100334ea..3cbc3d4270a3 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -2140,11 +2139,6 @@ static int em28xx_v4l2_fini(struct em28xx *dev) v4l2_ctrl_handler_free(>ctrl_handler); v4l2_device_unregister(>v4l2_dev); - if (v4l2->clk) { - v4l2_clk_unregister_fixed(v4l2->clk); - v4l2->clk = NULL; - } - kref_put(>ref, em28xx_free_v4l2); mutex_unlock(>lock); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index e9f379959fa5..e8d97d5ec161 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -510,7 +510,6 @@ struct em28xx_v4l2 { struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_clk *clk; struct video_device vdev; struct video_device vbi_dev; -- 2.12.2
[PATCH 4/5] em28xx: shed some light on video input formats
CbYCrY has been identified by looking into the tvp5150 driver and the saa7115 datasheet. YUV formats have been verified with em2765 + ov2640 (VAD Laplace webcam). RGB8 formats have been verified with em2710/em2820 + mt9v011 (Silvercrest webcam 1.3mpix). I also did some cross-checking with these two camera devices and 0x08-0x0b are at least 16 bits per pixel formats on em2710/em2820, too, and 0x0c-0x0f are at least 8 bits per pixel formats on em2765, too. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 10 -- drivers/media/usb/em28xx/em28xx-reg.h| 18 ++ drivers/media/usb/em28xx/em28xx-video.c | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index d43f630050bb..95eaa55356a9 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -364,8 +364,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2_i2c_new_subdev_board(>v4l2_dev, adap, _info, NULL)) return -ENODEV; - /* probably means GRGB 16 bit bayer */ - v4l2->vinmode = 0x0d; + v4l2->vinmode = EM28XX_VINMODE_RGB8_GRBG; v4l2->vinctl = 0x00; break; @@ -376,8 +375,7 @@ int em28xx_init_camera(struct em28xx *dev) em28xx_initialize_mt9m001(dev); - /* probably means BGGR 16 bit bayer */ - v4l2->vinmode = 0x0c; + v4l2->vinmode = EM28XX_VINMODE_RGB8_BGGR; v4l2->vinctl = 0x00; break; @@ -389,7 +387,7 @@ int em28xx_init_camera(struct em28xx *dev) em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); em28xx_initialize_mt9m111(dev); - v4l2->vinmode = 0x0a; + v4l2->vinmode = EM28XX_VINMODE_YUV422_UYVY; v4l2->vinctl = 0x00; break; @@ -430,7 +428,7 @@ int em28xx_init_camera(struct em28xx *dev) /* NOTE: for UXGA=1600x1200 switch to 12MHz */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); - v4l2->vinmode = 0x08; + v4l2->vinmode = EM28XX_VINMODE_YUV422_YUYV; v4l2->vinctl = 0x00; break; diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index afe7a66d7dc8..747525ca7ed5 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -93,6 +93,24 @@ #define EM28XX_XCLK_FREQUENCY_24MHZ0x0b #define EM28XX_R10_VINMODE 0x10 + /* used by all non-camera devices: */ +#define EM28XX_VINMODE_YUV422_CbYCrY 0x10 + /* used by camera devices: */ +#define EM28XX_VINMODE_YUV422_YUYV0x08 +#define EM28XX_VINMODE_YUV422_YVYU0x09 +#define EM28XX_VINMODE_YUV422_UYVY0x0a +#define EM28XX_VINMODE_YUV422_VYUY0x0b +#define EM28XX_VINMODE_RGB8_BGGR 0x0c +#define EM28XX_VINMODE_RGB8_GRBG 0x0d +#define EM28XX_VINMODE_RGB8_GBRG 0x0e +#define EM28XX_VINMODE_RGB8_RGGB 0x0f + /* + * apparently: + * bit 0: swap component 1+2 with 3+4 + * => e.g.: YUYV => YVYU, BGGR => GRBG + * bit 1: swap component 1 with 2 and 3 with 4 + * => e.g.: YUYV => UYVY, BGGR => GBRG + */ #define EM28XX_R11_VINCTRL 0x11 diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3cbc3d4270a3..aaa83f9e5c1a 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -2459,7 +2459,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* * Default format, used for tvp5150 or saa711x output formats */ - v4l2->vinmode = 0x10; + v4l2->vinmode = EM28XX_VINMODE_YUV422_CbYCrY; v4l2->vinctl = EM28XX_VINCTRL_INTERLACED | EM28XX_VINCTRL_CCIR656_ENABLE; -- 2.12.2
[PATCH 3/5] em28xx: don't treat device as webcam if an unknown sensor is detected
With an unknown sensor, norm_maxw() and norm_maxh() return 0 as max. height and width values, which causes a devide by zero in size_to_scale(). Of course we could use speculative default values for unknown sensors, but the chance that the device works at this resolution without any driver/setup is very low and therefore not worth the efforts. Instead, just don't treat the device as camera. A message will then be printed to the log that the device isn't supported. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-cards.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 5f80a1b2fb8c..48c7fec47509 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2917,7 +2917,9 @@ static void em28xx_card_setup(struct em28xx *dev) * If sensor is not found, then it isn't a webcam. */ if (dev->board.is_webcam) { - if (em28xx_detect_sensor(dev) < 0) + em28xx_detect_sensor(dev); + if (dev->em28xx_sensor == EM28XX_NOSENSOR) + /* NOTE: error/unknown sensor/no sensor */ dev->board.is_webcam = 0; } @@ -3665,9 +3667,11 @@ static int em28xx_usb_probe(struct usb_interface *interface, try_bulk = usb_xfer_mode > 0; } - /* Disable V4L2 if the device doesn't have a decoder */ + /* Disable V4L2 if the device doesn't have a decoder or image sensor */ if (has_video && - dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) { + dev->board.decoder == EM28XX_NODECODER && + dev->em28xx_sensor == EM28XX_NOSENSOR) { + dev_err(>dev, "Currently, V4L2 is not supported on this model\n"); has_video = false; -- 2.12.2
[PATCH 5/5] em28xx: add support for V4L2_PIX_FMT_SRGGB8
Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-video.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index aaa83f9e5c1a..8d253a5df0a9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -116,6 +116,11 @@ static struct em28xx_fmt format[] = { .depth= 16, .reg = EM28XX_OUTFMT_RGB_16_656, }, { + .name = "8 bpp Bayer RGRG..GBGB", + .fourcc = V4L2_PIX_FMT_SRGGB8, + .depth= 8, + .reg = EM28XX_OUTFMT_RGB_8_RGRG, + }, { .name = "8 bpp Bayer BGBG..GRGR", .fourcc = V4L2_PIX_FMT_SBGGR8, .depth= 8, -- 2.12.2
Re: [PATCH 2/2] em28xx: simplify ID-reading from Micron sensors
Am 26.03.2017 um 16:24 schrieb Frank Schäfer: > > > Am 24.03.2017 um 20:16 schrieb Mauro Carvalho Chehab: >> Em Thu, 23 Mar 2017 19:03:20 +0100 >> Frank Schäfer <fschaefer@googlemail.com> escreveu: >> >>> Am 23.03.2017 um 13:56 schrieb Mauro Carvalho Chehab: >>>> Em Thu, 23 Mar 2017 13:01:32 +0100 >>>> Frank Schäfer <fschaefer@googlemail.com> escreveu: >>>> >>>>> Am 22.03.2017 um 15:46 schrieb Mauro Carvalho Chehab: >>>>>> Em Sun, 19 Feb 2017 19:29:18 +0100 >>>>>> Frank Schäfer <fschaefer@googlemail.com> escreveu: >>>>>> >>>>>>> Use i2c_smbus_read_word_data() instead of i2c_master_send() and >>>>>>> i2c_master_recv() for reading the ID of Micorn sensors. >>>>>>> Bytes need to be swapped afterwards, because >>>>>>> i2c_smbus_read_word_data() >>>>>>> assumes that the received bytes are little-endian byte order (as >>>>>>> specified >>>>>>> by smbus), while Micron sensors with 16 bit register width use >>>>>>> big endian >>>>>>> byte order. >>>>>>> >>>>>>> Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> >>>>>>> --- >>>>>>> drivers/media/usb/em28xx/em28xx-camera.c | 28 >>>>>>> >>>>>>> 1 file changed, 4 insertions(+), 24 deletions(-) >>>>>>> >>>>>>> diff --git a/drivers/media/usb/em28xx/em28xx-camera.c >>>>>>> b/drivers/media/usb/em28xx/em28xx-camera.c >>>>>>> index 7b4129ab1cf9..4839479624e7 100644 >>>>>>> --- a/drivers/media/usb/em28xx/em28xx-camera.c >>>>>>> +++ b/drivers/media/usb/em28xx/em28xx-camera.c >>>>>>> @@ -106,8 +106,6 @@ static int em28xx_probe_sensor_micron(struct >>>>>>> em28xx *dev) >>>>>>> { >>>>>>> int ret, i; >>>>>>> char *name; >>>>>>> -u8 reg; >>>>>>> -__be16 id_be; >>>>>>> u16 id; >>>>>>> struct i2c_client *client = >>>>>>> >i2c_client[dev->def_i2c_bus]; >>>>>>> @@ -115,10 +113,8 @@ static int >>>>>>> em28xx_probe_sensor_micron(struct em28xx *dev) >>>>>>> dev->em28xx_sensor = EM28XX_NOSENSOR; >>>>>>> for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; >>>>>>> i++) { >>>>>>> client->addr = micron_sensor_addrs[i]; >>>>>>> -/* NOTE: i2c_smbus_read_word_data() doesn't work with >>>>>>> BE data */ >>>>>>> /* Read chip ID from register 0x00 */ >>>>>>> -reg = 0x00; >>>>>>> -ret = i2c_master_send(client, , 1); >>>>>>> +ret = i2c_smbus_read_word_data(client, 0x00); /* >>>>>>> assumes LE */ >>>>>>> if (ret < 0) { >>>>>>> if (ret != -ENXIO) >>>>>>> dev_err(>intf->dev, >>>>>>> @@ -126,24 +122,9 @@ static int >>>>>>> em28xx_probe_sensor_micron(struct em28xx *dev) >>>>>>>client->addr << 1, ret); >>>>>>> continue; >>>>>>> } >>>>>>> -ret = i2c_master_recv(client, (u8 *)_be, 2); >>>>>>> -if (ret < 0) { >>>>>>> -dev_err(>intf->dev, >>>>>>> -"couldn't read from i2c device 0x%02x: error >>>>>>> %i\n", >>>>>>> -client->addr << 1, ret); >>>>>>> -continue; >>>>>>> -} >>>>>>> -id = be16_to_cpu(id_be); >>>>>>> +id = swab16(ret); /* LE -> BE */ >>>>>> That's wrong! You can't assume that CPU is BE, as some archs use LE. >>>>>> >>>>>> You should, instead, call le16_to_cpu(), to be sure that it will be >>>>>> doing the right thing. >>>>>> >>>>>> Something like: >>>>>> >>>>>> id = le16_to_cpu((__le16)ret); >>>>> SMBus read/write word transfers are always LE (see SMBus spec section >>>>> 6.5.5), >>>>> which is also what i2c_smbus_xfer_emulated() assumes: >>>>> http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L3485 >>>> I got that part, but, if the CPU is also LE, doing swab16() is >>>> wrong. It should swap it *only* if the CPU is BE. >>> No, it should always be swapped, because the bytes are always >>> transfered >>> in the wrong order. >>> The cpu endianess doesn't matter, (0x12 << 8) | 0x34 is always 0x1234. >> You still didn't get it. >> >> Let's assume that the ID is 0x148c (MT9M112). >> >> This value, represented in low endian, is stored in memory as: >> >> unsigned char __id[2] = { 0x8c, 0x14 }; >> >> If we do: >> u16 ret = *(u16 *)__id; >> >> What's stored at "ret" will depend if the sistem is LE or BE: >> >> on LE, ret == 0x148c >> on BE, ret == 0x8c14 >> >> If you do: >> u16 id = swapb16(val) >> >> you'll get: >> >> on LE, id == 0x8c14 >> on BE, id == 0x148c >> >> So, the value will be *wrong* at LE. >> >> However, if you do: >> id = le16_to_cpu((__le16)ret); >> >> On LE, this will evaluate to id = ret, and on BE, to id = swab16(ret). >> So, on both, you'll have: >> id = 0x148c. > > Can you please show me the code line(s) that make the value of the > word returned by i2c_smbus_read_word_data() cpu endianess dependent ? :) > Ping !? Cheers, Frank
Re: [PATCH 2/2] em28xx: simplify ID-reading from Micron sensors
Am 24.03.2017 um 20:16 schrieb Mauro Carvalho Chehab: Em Thu, 23 Mar 2017 19:03:20 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Am 23.03.2017 um 13:56 schrieb Mauro Carvalho Chehab: Em Thu, 23 Mar 2017 13:01:32 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Am 22.03.2017 um 15:46 schrieb Mauro Carvalho Chehab: Em Sun, 19 Feb 2017 19:29:18 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Use i2c_smbus_read_word_data() instead of i2c_master_send() and i2c_master_recv() for reading the ID of Micorn sensors. Bytes need to be swapped afterwards, because i2c_smbus_read_word_data() assumes that the received bytes are little-endian byte order (as specified by smbus), while Micron sensors with 16 bit register width use big endian byte order. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 28 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7b4129ab1cf9..4839479624e7 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -106,8 +106,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; - __be16 id_be; u16 id; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; @@ -115,10 +113,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(client, , 1); + ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */ if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, @@ -126,24 +122,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) client->addr << 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - id = be16_to_cpu(id_be); + id = swab16(ret); /* LE -> BE */ That's wrong! You can't assume that CPU is BE, as some archs use LE. You should, instead, call le16_to_cpu(), to be sure that it will be doing the right thing. Something like: id = le16_to_cpu((__le16)ret); SMBus read/write word transfers are always LE (see SMBus spec section 6.5.5), which is also what i2c_smbus_xfer_emulated() assumes: http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L3485 I got that part, but, if the CPU is also LE, doing swab16() is wrong. It should swap it *only* if the CPU is BE. No, it should always be swapped, because the bytes are always transfered in the wrong order. The cpu endianess doesn't matter, (0x12 << 8) | 0x34 is always 0x1234. You still didn't get it. Let's assume that the ID is 0x148c (MT9M112). This value, represented in low endian, is stored in memory as: unsigned char __id[2] = { 0x8c, 0x14 }; If we do: u16 ret = *(u16 *)__id; What's stored at "ret" will depend if the sistem is LE or BE: on LE, ret == 0x148c on BE, ret == 0x8c14 If you do: u16 id = swapb16(val) you'll get: on LE, id == 0x8c14 on BE, id == 0x148c So, the value will be *wrong* at LE. However, if you do: id = le16_to_cpu((__le16)ret); On LE, this will evaluate to id = ret, and on BE, to id = swab16(ret). So, on both, you'll have: id = 0x148c. Can you please show me the code line(s) that make the value of the word returned by i2c_smbus_read_word_data() cpu endianess dependent ? :) Cheers, Frank Thanks, Mauro
Re: [PATCH 2/2] em28xx: simplify ID-reading from Micron sensors
Am 23.03.2017 um 13:56 schrieb Mauro Carvalho Chehab: Em Thu, 23 Mar 2017 13:01:32 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Am 22.03.2017 um 15:46 schrieb Mauro Carvalho Chehab: Em Sun, 19 Feb 2017 19:29:18 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Use i2c_smbus_read_word_data() instead of i2c_master_send() and i2c_master_recv() for reading the ID of Micorn sensors. Bytes need to be swapped afterwards, because i2c_smbus_read_word_data() assumes that the received bytes are little-endian byte order (as specified by smbus), while Micron sensors with 16 bit register width use big endian byte order. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 28 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7b4129ab1cf9..4839479624e7 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -106,8 +106,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; - __be16 id_be; u16 id; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; @@ -115,10 +113,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(client, , 1); + ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */ if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, @@ -126,24 +122,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) client->addr << 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - id = be16_to_cpu(id_be); + id = swab16(ret); /* LE -> BE */ That's wrong! You can't assume that CPU is BE, as some archs use LE. You should, instead, call le16_to_cpu(), to be sure that it will be doing the right thing. Something like: id = le16_to_cpu((__le16)ret); SMBus read/write word transfers are always LE (see SMBus spec section 6.5.5), which is also what i2c_smbus_xfer_emulated() assumes: http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L3485 I got that part, but, if the CPU is also LE, doing swab16() is wrong. It should swap it *only* if the CPU is BE. No, it should always be swapped, because the bytes are always transfered in the wrong order. The cpu endianess doesn't matter, (0x12 << 8) | 0x34 is always 0x1234. Regards, Frank le16_to_cpu() should do the right thing, e. g. swap for BE CPUs or not swap otherwise. Thanks, Mauro
Re: [PATCH 2/2] em28xx: simplify ID-reading from Micron sensors
Am 22.03.2017 um 15:46 schrieb Mauro Carvalho Chehab: Em Sun, 19 Feb 2017 19:29:18 +0100 Frank Schäfer <fschaefer@googlemail.com> escreveu: Use i2c_smbus_read_word_data() instead of i2c_master_send() and i2c_master_recv() for reading the ID of Micorn sensors. Bytes need to be swapped afterwards, because i2c_smbus_read_word_data() assumes that the received bytes are little-endian byte order (as specified by smbus), while Micron sensors with 16 bit register width use big endian byte order. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 28 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7b4129ab1cf9..4839479624e7 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -106,8 +106,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; - __be16 id_be; u16 id; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; @@ -115,10 +113,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(client, , 1); + ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */ if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, @@ -126,24 +122,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) client->addr << 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - id = be16_to_cpu(id_be); + id = swab16(ret); /* LE -> BE */ That's wrong! You can't assume that CPU is BE, as some archs use LE. You should, instead, call le16_to_cpu(), to be sure that it will be doing the right thing. Something like: id = le16_to_cpu((__le16)ret); SMBus read/write word transfers are always LE (see SMBus spec section 6.5.5), which is also what i2c_smbus_xfer_emulated() assumes: http://lxr.free-electrons.com/source/drivers/i2c/i2c-core.c#L3485 Regards, Frank Regards, Thanks, Mauro
Re: [PATCHv3 10/15] ov2640: convert from soc-camera to a standard subdev sensor driver.
Am 06.03.2017 um 15:56 schrieb Hans Verkuil: From: Hans VerkuilConvert ov2640 to a standard subdev driver. The soc-camera driver no longer uses this driver, so it can safely be converted. Note: the s_power op has been dropped: this never worked. When the last open() is closed, then the power is turned off, and when it is opened again the power is turned on again, but the old state isn't restored. Someone else can figure out in the future how to get this working correctly, but I don't want to spend more time on this. Last two sections of this description are a leftover from v2. ;) Regards, Frank Signed-off-by: Hans Verkuil --- drivers/media/i2c/Kconfig | 11 drivers/media/i2c/Makefile | 1 + drivers/media/i2c/{soc_camera => }/ov2640.c | 89 + drivers/media/i2c/soc_camera/Kconfig| 6 -- drivers/media/i2c/soc_camera/Makefile | 1 - 5 files changed, 27 insertions(+), 81 deletions(-) rename drivers/media/i2c/{soc_camera => }/ov2640.c (94%) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index cee1dae6e014..db2c63f592c5 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -520,6 +520,17 @@ config VIDEO_APTINA_PLL config VIDEO_SMIAPP_PLL tristate +config VIDEO_OV2640 + tristate "OmniVision OV2640 sensor support" + depends on VIDEO_V4L2 && I2C && GPIOLIB + depends on MEDIA_CAMERA_SUPPORT + help + This is a Video4Linux2 sensor-level driver for the OmniVision + OV2640 camera. + + To compile this driver as a module, choose M here: the + module will be called ov2640. + config VIDEO_OV2659 tristate "OmniVision OV2659 sensor support" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 5bc7bbeb5499..50af1e11c85a 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o +obj-$(CONFIG_VIDEO_OV2640) += ov2640.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV9650) += ov9650.o diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/ov2640.c similarity index 94% rename from drivers/media/i2c/soc_camera/ov2640.c rename to drivers/media/i2c/ov2640.c index b9a0069f5b33..83f88efbce69 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -24,8 +24,8 @@ #include #include -#include #include +#include #include #include #include @@ -287,7 +287,6 @@ struct ov2640_priv { struct v4l2_clk *clk; const struct ov2640_win_size*win; - struct soc_camera_subdev_desc ssdd_dt; struct gpio_desc *resetb_gpio; struct gpio_desc *pwdn_gpio; }; @@ -677,13 +676,8 @@ static int ov2640_reset(struct i2c_client *client) } /* - * soc_camera_ops functions + * functions */ -static int ov2640_s_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = @@ -744,10 +738,16 @@ static int ov2640_s_register(struct v4l2_subdev *sd, static int ov2640_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct ov2640_priv *priv = to_ov2640(client); - return soc_camera_set_power(>dev, ssdd, priv->clk, on); + gpiod_direction_output(priv->pwdn_gpio, !on); + if (on && priv->resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv->resetb_gpio, 1); + usleep_range(3000, 5000); + gpiod_direction_output(priv->resetb_gpio, 0); + } + return 0; } /* Select the nearest higher resolution for capture */ @@ -994,26 +994,6 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { .s_power= ov2640_s_power, }; -static int ov2640_g_mbus_config(struct v4l2_subdev *sd, - struct v4l2_mbus_config *cfg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - - cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | - V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | - V4L2_MBUS_DATA_ACTIVE_HIGH; - cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); - - return 0; -} - -static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { -
Re: em28xx: new board id [1d19:6901]
Am 27.02.2017 um 21:21 schrieb Łukasz Strzeszkowski: Hi, I’ve found a new device which is not listed model: LogiLink VG0011 vendor/product: [1d19:6901] Dexatek Technology Ltd. mode: analog I am unable to load a driver, because there is no such vendor in driver list. dmesg output: [ 1232.506295] usb 2-4: new high-speed USB device number 4 using xhci_hcd [ 1232.637496] usb 2-4: New USB device found, idVendor=1d19, idProduct=6901 [ 1232.637500] usb 2-4: New USB device strings: Mfr=0, Product=1, SerialNumber=0 [ 1232.637502] usb 2-4: Product: USB 2861 Video [ 1232.660061] usbcore: registered new interface driver snd-usb-audio Regards Łukasz Strzeszkowski You can (temporarily) add the device id to the em28xx driver at runtime: modprobe em28xx echo 1d19 6901 > /sys/module/em28xx/drivers/usb:em28xx/new_id Then plug in the device and see what happens. HTH, Frank
[PATCH 2/2] em28xx: simplify ID-reading from Micron sensors
Use i2c_smbus_read_word_data() instead of i2c_master_send() and i2c_master_recv() for reading the ID of Micorn sensors. Bytes need to be swapped afterwards, because i2c_smbus_read_word_data() assumes that the received bytes are little-endian byte order (as specified by smbus), while Micron sensors with 16 bit register width use big endian byte order. Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 28 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7b4129ab1cf9..4839479624e7 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -106,8 +106,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; - __be16 id_be; u16 id; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; @@ -115,10 +113,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { client->addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(client, , 1); + ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */ if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, @@ -126,24 +122,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) client->addr << 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - id = be16_to_cpu(id_be); + id = swab16(ret); /* LE -> BE */ /* Read chip ID from register 0xff */ - reg = 0xff; - ret = i2c_master_send(client, , 1); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client->addr << 1, ret); - continue; - } - ret = i2c_master_recv(client, (u8 *)_be, 2); + ret = i2c_smbus_read_word_data(client, 0xff); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", @@ -151,10 +132,9 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) continue; } /* Validate chip ID to be sure we have a Micron device */ - if (id != be16_to_cpu(id_be)) + if (id != swab16(ret)) continue; /* Check chip ID */ - id = be16_to_cpu(id_be); switch (id) { case 0x1222: name = "MT9V012"; /* MI370 */ /* 640x480 */ -- 2.11.0
[PATCH 1/2] em28xx: reduce stack usage in sensor probing functions
It's no longer necessary to keep the i2c_client in the device struct unmodified until a sensor is found, so reduce stack usage in em28xx_probe_sensor_micron() and em28xx_probe_sensor_omnivision() by using a pointer to the client instead of a local copy. Reported-by: Arnd Bergmann <a...@arndb.de> Signed-off-by: Frank Schäfer <fschaefer@googlemail.com> --- drivers/media/usb/em28xx/em28xx-camera.c | 42 +++- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 89c890ba7dd6..7b4129ab1cf9 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -110,44 +110,44 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) __be16 id_be; u16 id; - struct i2c_client client = dev->i2c_client[dev->def_i2c_bus]; + struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { - client.addr = micron_sensor_addrs[i]; + client->addr = micron_sensor_addrs[i]; /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ reg = 0x00; - ret = i2c_master_send(, , 1); + ret = i2c_master_send(client, , 1); if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client->addr << 1, ret); continue; } - ret = i2c_master_recv(, (u8 *)_be, 2); + ret = i2c_master_recv(client, (u8 *)_be, 2); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client->addr << 1, ret); continue; } id = be16_to_cpu(id_be); /* Read chip ID from register 0xff */ reg = 0xff; - ret = i2c_master_send(, , 1); + ret = i2c_master_send(client, , 1); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client->addr << 1, ret); continue; } - ret = i2c_master_recv(, (u8 *)_be, 2); + ret = i2c_master_recv(client, (u8 *)_be, 2); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + client->addr << 1, ret); continue; } /* Validate chip ID to be sure we have a Micron device */ @@ -197,7 +197,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) dev_info(>intf->dev, "sensor %s detected\n", name); - dev->i2c_client[dev->def_i2c_bus].addr = client.addr; return 0; } @@ -213,30 +212,30 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) char *name; u8 reg; u16 id; - struct i2c_client client = dev->i2c_client[dev->def_i2c_bus]; + struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; dev->em28xx_sensor = EM28XX_NOSENSOR; /* NOTE: these devices have the register auto incrementation disabled * by default, so we have to use single byte reads ! */ for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) { - client.addr = omnivision_sensor_addrs[i]; + client->addr = omnivision_sensor_addrs[i]; /* Read manufacturer ID from registers 0x1c-0x1d (BE) */ reg = 0x1c; - ret = i2c_smbus_read_byte_data(, reg); + ret = i2c_smbus_read_byte_data(client, reg); if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: err
Re: [PATCH 2/4] [media] em28xx: reduce stack usage in probe functions
Hi Arnd, Am 13.02.2017 um 15:00 schrieb Hans Verkuil: Hi Arnd, I'll take the others of this patch series, but will postpone this one until it has been tested. I've asked Frank to see if he can test it, if not, then it will have to wait until March when I have access to an omnivision-em28xx device. Regards, Hans On 02/02/2017 03:53 PM, Arnd Bergmann wrote: The two i2c probe functions use a lot of stack since they put an i2c_client structure in a local variable: drivers/media/usb/em28xx/em28xx-camera.c: In function 'em28xx_probe_sensor_micron': drivers/media/usb/em28xx/em28xx-camera.c:205:1: error: the frame size of 1256 bytes is larger than 1152 bytes [-Werror=frame-larger-than=] drivers/media/usb/em28xx/em28xx-camera.c: In function 'em28xx_probe_sensor_omnivision': drivers/media/usb/em28xx/em28xx-camera.c:317:1: error: the frame size of 1248 bytes is larger than 1152 bytes [-Werror=frame-larger-than=] This cleans up both of the above by removing the need for those structures, calling the lower-level i2c function directly. in the past, it was necessary to keep dev->i2c_client[dev->def_i2c_bus] unmodified, otherwise bad things could have happened after sensor probing. In the meantime many things have been refactored/fixed and this seems to be no longer true. So we can go the simple way and just use a pointer to dev->i2c_client[dev->def_i2c_bus] instead. But let me test that with another device this weekend to be 100% sure. Regards, Frank Signed-off-by: Arnd Bergmann--- drivers/media/usb/em28xx/em28xx-camera.c | 87 ++-- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 89c890ba7dd6..e64940f95a91 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -99,6 +99,25 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev) return 0; } +/* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ +static int em28xx_i2c_read_chip_id(struct em28xx *dev, u16 addr, u8 reg, void *buf) +{ + struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; + struct i2c_msg msg[2]; + + msg[0].addr = addr; + msg[0].flags = client->flags & I2C_M_TEN; + msg[0].len = 1; + msg[0].buf = + msg[1].addr = addr; + msg[1].flags = client->flags & I2C_M_TEN; + msg[1].flags |= I2C_M_RD; + msg[1].len = 2; + msg[1].buf = buf; + + return i2c_transfer(client->adapter, msg, 2); +} + /* * Probes Micron sensors with 8 bit address and 16 bit register width */ @@ -106,48 +125,29 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) { int ret, i; char *name; - u8 reg; __be16 id_be; + u16 addr; u16 id; - struct i2c_client client = dev->i2c_client[dev->def_i2c_bus]; - dev->em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { - client.addr = micron_sensor_addrs[i]; - /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ + addr = micron_sensor_addrs[i]; /* Read chip ID from register 0x00 */ - reg = 0x00; - ret = i2c_master_send(, , 1); + ret = em28xx_i2c_read_chip_id(dev, addr, 0x00, _be); if (ret < 0) { if (ret != -ENXIO) dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); - continue; - } - ret = i2c_master_recv(, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + addr << 1, ret); continue; } id = be16_to_cpu(id_be); /* Read chip ID from register 0xff */ - reg = 0xff; - ret = i2c_master_send(, , 1); + ret = em28xx_i2c_read_chip_id(dev, addr, 0xff, _be); if (ret < 0) { dev_err(>intf->dev, "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); - continue; - } - ret = i2c_master_recv(, (u8 *)_be, 2); - if (ret < 0) { - dev_err(>intf->dev, - "couldn't read from i2c device 0x%02x: error %i\n", - client.addr << 1, ret); + addr << 1, ret);
Re: [PATCH 1/8] [media] em28xx: fix em28xx-input removal
Am 20.12.2014 um 15:51 schrieb Russell King - ARM Linux: On Sat, Dec 20, 2014 at 03:11:54PM +0100, Frank Schäfer wrote: Hi Russel, I guess you won't mind if I mis-spell your name too... Wow... it seems to be very easy to offend you... Sorry, that was definitely not my intention. I did not do this on purpose. It was just a simple mistake and I will try to avoid it in the future. I'd prefer to keep the button initialization related stuff together in em28xx_init_buttons() and do the cancel_delayed_work_sync() only if we have buttons (dev-num_button_polling_addresses). That's how we already do it with the IR work struct (see em28xx_ir_suspend()). Provided all places that touch buttons_query_work are properly updated that's fine, but to me that is fragile and asking for trouble. It's far better to ensure that everything is properly initialised so you don't have to remember to conditionalise every single reference to a work struct. In any case, delayed work struct initialisation is cheap - it doesn't involve any additional memory, it only initialises the various members of the struct (and the lockdep information for the static key) so there really is no argument against always initialising delayed works or normal works, timers, etc to avoid these kinds of bugs. Fair enough ! Regards, Frank Schäfer -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/8] Fix issues in em28xx
Am 20.12.2014 um 13:44 schrieb Russell King - ARM Linux: While testing a PCTV tripleSTICK 292e, a couple of issues were discovered. Firstly, disconnecting the device causes a lockdep splat, which is addressed in the first patch. Secondly, a number of kernel messages are missing their terminating newline characters, and these are spread over a range of commits and a range of kernel versions. Therefore, I've split the fixes up by offending commit, which should make backporting to stable trees easier. (Some need to be applied to 3.14 and on, some to 3.15 and on, etc.) It isn't clear who is the maintainer for this driver; there is no MAINTAINERS entry. If there is a maintainer, please ensure that they add themselves to this critical file. Thanks. drivers/media/usb/em28xx/em28xx-audio.c | 8 drivers/media/usb/em28xx/em28xx-core.c | 4 ++-- drivers/media/usb/em28xx/em28xx-dvb.c | 14 +++--- drivers/media/usb/em28xx/em28xx-input.c | 9 - drivers/media/usb/em28xx/em28xx-video.c | 6 +++--- 5 files changed, 20 insertions(+), 21 deletions(-) Reviewed-by: Frank Schäfer fschaefer@googlemail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/8] Fix issues in em28xx
Am 20.12.2014 um 13:44 schrieb Russell King - ARM Linux: It isn't clear who is the maintainer for this driver; there is no MAINTAINERS entry. If there is a maintainer, please ensure that they add themselves to this critical file. Thanks. (line 3598) EM28XX VIDEO4LINUX DRIVER M:Mauro Carvalho Chehab m.che...@samsung.com L:linux-media@vger.kernel.org W:http://linuxtv.org T:git git://linuxtv.org/media_tree.git S:Maintained F:drivers/media/usb/em28xx/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] dvb_usb_af9005: fix kernel panic on init if the driver is compiled in without IR symbols
This patches fixes an ancient bug in the dvb_usb_af9005 driver, which has been reported at least in the following threads: https://lkml.org/lkml/2009/2/4/350 https://lkml.org/lkml/2014/9/18/558 If the driver is compiled in without any IR support (neither DVB_USB_AF9005_REMOTE nor custom symbols), the symbol_request calls in af9005_usb_module_init() return pointers != NULL although the IR symbols are not available. This leads to the following oops: ... [8.529751] usbcore: registered new interface driver dvb_usb_af9005 [8.531584] BUG: unable to handle kernel paging request at 02e0 [8.533385] IP: [7d9d67c6] af9005_usb_module_init+0x6b/0x9d [8.535613] *pde = [8.536416] Oops: [#1] PREEMPT PREEMPT DEBUG_PAGEALLOCDEBUG_PAGEALLOC [8.537863] CPU: 0 PID: 1 Comm: swapper Not tainted 3.15.0-rc6-00151-ga5c075c #1 [8.539827] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 [8.541519] task: 89c9a670 ti: 89c9c000 task.ti: 89c9c000 [8.541519] EIP: 0060:[7d9d67c6] EFLAGS: 00010206 CPU: 0 [8.541519] EIP is at af9005_usb_module_init+0x6b/0x9d [8.541519] EAX: 02e0 EBX: ECX: 0006 EDX: [8.541519] ESI: EDI: 7da33ec8 EBP: 89c9df30 ESP: 89c9df2c [8.541519] DS: 007b ES: 007b FS: GS: 00e0 SS: 0068 [8.541519] CR0: 8005003b CR2: 02e0 CR3: 05a54000 CR4: 0690 [8.541519] Stack: [8.541519] 7d9d675b 89c9df90 7d992a49 7d7d5914 89c9df4c 7be3a800 7d08c58c 8a4c3968 [8.541519] 89c9df80 7be3a966 0192 0006 0006 7d7d3ff4 8a4c397a 0200 [8.541519] 7d6b1280 8a4c3979 0006 09a6 7da32db8 b13eec81 0006 09a6 [8.541519] Call Trace: [8.541519] [7d9d675b] ? ttusb2_driver_init+0x16/0x16 [8.541519] [7d992a49] do_one_initcall+0x77/0x106 [8.541519] [7be3a800] ? parameqn+0x2/0x35 [8.541519] [7be3a966] ? parse_args+0x113/0x25c [8.541519] [7d992bc2] kernel_init_freeable+0xea/0x167 [8.541519] [7cf01070] kernel_init+0x8/0xb8 [8.541519] [7cf27ec0] ret_from_kernel_thread+0x20/0x30 [8.541519] [7cf01068] ? rest_init+0x10c/0x10c [8.541519] Code: 08 c2 c7 05 44 ed f9 7d 00 00 e0 02 c7 05 40 ed f9 7d 00 00 e0 02 c7 05 3c ed f9 7d 00 00 e0 02 75 1f b8 00 00 e0 02 85 c0 74 16 a1 00 00 e0 02 c7 05 54 84 8e 7d 00 00 e0 02 a3 58 84 8e 7d eb [8.541519] EIP: [7d9d67c6] af9005_usb_module_init+0x6b/0x9d SS:ESP 0068:89c9df2c [8.541519] CR2: 02e0 [8.541519] ---[ end trace 768b6faf51370fc7 ]--- The prefered fix would be to convert the whole IR code to use the kernel IR infrastructure (which wasn't available at the time this driver had been created). Until anyone who still has this old hardware steps up an does the conversion, fix it by not calling the symbol_request calls if the driver is compiled in without the default IR symbols (CONFIG_DVB_USB_AF9005_REMOTE). Due to the IR related pointers beeing NULL by default, IR support will then be disabled. The downside of this solution is, that it will no longer be possible to compile custom IR symbols (not using CONFIG_DVB_USB_AF9005_REMOTE) in. Please note that this patch has NOT been tested with all possible cases. I don't have the hardware and could only verify that it fixes the reported bug. Reported-by: Fengguag Wu fengguang...@intel.com Signed-off-by: Frank Schäfer fschaefer@googlemail.com Cc: sta...@vger.kernel.org --- drivers/media/usb/dvb-usb/af9005.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c index af176b6..e6d3561 100644 --- a/drivers/media/usb/dvb-usb/af9005.c +++ b/drivers/media/usb/dvb-usb/af9005.c @@ -1081,9 +1081,12 @@ static int __init af9005_usb_module_init(void) err(usb_register failed. (%d), result); return result; } +#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE) + /* FIXME: convert to todays kernel IR infrastructure */ rc_decode = symbol_request(af9005_rc_decode); rc_keys = symbol_request(rc_map_af9005_table); rc_keys_size = symbol_request(rc_map_af9005_table_size); +#endif if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { err(af9005_rc_decode function not found, disabling remote); af9005_properties.rc.legacy.rc_query = NULL; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media/dvb_usb_af9005] BUG: unable to handle kernel paging request (WAS: [media/em28xx] BUG: unable to handle kernel)
Am 23.09.2014 um 23:03 schrieb Luca Olivetti: El 23/09/14 20:52, Frank Schäfer ha escrit: This seems to be an ancient bug, which is known at least since 5 1/2 years: https://lkml.org/lkml/2009/2/4/350 [...] #if defined(CONFIG_MODULE) || defined(CONFIG_DVB_USB_AF9005_REMOTE) What happens, if CONFIG_MODULES is enabled, but neither module af9005-remote nor any other IR module is available ? Has this ever been tested ? I think I tested at the time and symbol_request returned NULL in that case, however I'm not sure and I cannot find any documentation on how symbol_request is supposed to work in that case. Ok, thanks. I assume noone wants to invest some time into this old driver and covert it to todays kernel IR infrastructure as suggested by Antti ? :-) Then I'm going to send a patch with the #if defined(CONFIG_MODULE) || defined(CONFIG_DVB_USB_AF9005_REMOTE) approach. That's at least better than leaving the bug unfixed. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] em28xx: fix VBI handling logic
Am 24.09.2014 um 01:18 schrieb Mauro Carvalho Chehab: Em Tue, 23 Sep 2014 21:32:02 +0200 Frank Schäfer fschaefer@googlemail.com escreveu: Am 19.09.2014 um 18:02 schrieb Mauro Carvalho Chehab: When both VBI and video are streaming, and video stream is stopped, a subsequent trial to restart it will fail, because S_FMT will return -EBUSY. That prevents applications like zvbi to work properly. Please notice that, while this fix it fully for zvbi, the best is to get rid of streaming_users and res_get logic as a hole. However, this single-line patch is better to be merged at -stable. Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 08569cbccd95..d75e7f82dfb9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1351,7 +1351,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev-v4l2; - if (v4l2-streaming_users 0) + if (vb2_is_busy(v4l2-vb_vidq)) Looks dangerous. Why Dangerous? You are an experienced kernel developer. If you still fail to see that after so many years, sorry, I can't help you. Did you identify any problem? Yes I've identified a potential problem. Read it again, it's in the line you skipped in this reply. With what application? I would be willing to spend more time on this and test this critical patch (like I already did in the past). But I don't have access to analog TV here at the moment, sorry. It would have to wait ~2 weeks. My fault. I shouldn't have wasted any time on reviewing your patch. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] [media] em28xx-input: NULL dereference on error
Hi Dan, Am 25.09.2014 um 13:39 schrieb Dan Carpenter: We call kfree(ir-i2c_client); in the error handling and that doesn't work if ir is NULL. Fixes: 78e719a5f30b ('[media] em28xx-input: i2c IR decoders: improve i2c_client handling') Signed-off-by: Dan Carpenter dan.carpen...@oracle.com diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 581f6da..23f8f6a 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -712,8 +712,10 @@ static int em28xx_ir_init(struct em28xx *dev) em28xx_info(Registering input extension\n); ir = kzalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; rc = rc_allocate_device(); - if (!ir || !rc) + if (!rc) goto error; /* record handles to ourself */ I would prefer to fix it where the actual problem is located. Can you send an updated version that changes the code to do ... error: if (ir) kfree(ir-i2c_client); ... This makes the code less prone to future error handling changes. Thanks ! Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] em28xx: fix VBI handling logic
(Resending because my crappy modem crashed while sending) Am 25.09.2014 um 16:07 schrieb Mauro Carvalho Chehab: Em Thu, 25 Sep 2014 15:59:12 +0200 Frank Schäfer fschaefer@googlemail.com escreveu: Am 24.09.2014 um 01:18 schrieb Mauro Carvalho Chehab: Em Tue, 23 Sep 2014 21:32:02 +0200 Frank Schäfer fschaefer@googlemail.com escreveu: Am 19.09.2014 um 18:02 schrieb Mauro Carvalho Chehab: When both VBI and video are streaming, and video stream is stopped, a subsequent trial to restart it will fail, because S_FMT will return -EBUSY. That prevents applications like zvbi to work properly. Please notice that, while this fix it fully for zvbi, the best is to get rid of streaming_users and res_get logic as a hole. However, this single-line patch is better to be merged at -stable. Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 08569cbccd95..d75e7f82dfb9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1351,7 +1351,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev-v4l2; - if (v4l2-streaming_users 0) + if (vb2_is_busy(v4l2-vb_vidq)) Looks dangerous. Why Dangerous? You are an experienced kernel developer. If you still fail to see that after so many years, sorry, I can't help you. Did you identify any problem? Yes I've identified a potential problem. Read it again, it's in the line you skipped in this reply. Did you read the video_ioctl_ops struct? See: .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, Only the video node calls s_fmt_vid_cap. There's nothing to be set for VBI. In other words, a call to VIDIOC_S_FMT will actually call vidioc_g_fmt_vbi_cap() if called from VBI. So, I was unable to see any potencial issues. Yes, I checked that, too. No problems here. I was concerned about the||consequences of the em28xx_set_video_format||() call. It calls em28xx_resolution_set() which in turn calls em28xx_set_outfmt() em28xx_accumulator_set() em28xx_capture_area_set()|| em28xx_scaler_set() So lot's of device registers are reconfigured. That might cause problems even if the register values don't change. If that has been verified and it causes no problems, than of course everything is fine. Regards, Frank With what application? I would be willing to spend more time on this and test this critical patch (like I already did in the past). But I don't have access to analog TV here at the moment, sorry. It would have to wait ~2 weeks. On my tests with the 3 existing VBI apps, they all worked fine after the patch, no matter if the VBI or the video application is started first. That's why I asked. Regards, Mauro -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] [media] em28xx-input: NULL dereference on error
Am 25.09.2014 um 16:49 schrieb Dan Carpenter: On Thu, Sep 25, 2014 at 04:08:31PM +0200, Frank Schäfer wrote: ir = kzalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; rc = rc_allocate_device(); - if (!ir || !rc) + if (!rc) goto error; /* record handles to ourself */ I would prefer to fix it where the actual problem is located. Can you send an updated version that changes the code to do ... error: if (ir) kfree(ir-i2c_client); ... This makes the code less prone to future error handling changes. This kind of bug is called a One Err Bug because they are part of an anti-pattern of bad error handling where there is only one label. It was ok at the time it was written but it was fragile and broke when the code changed. One Err Bugs are very common kind of bug. I just reported a similar bug this morning. https://lkml.org/lkml/2014/9/25/91 In that case we freed some sysfs files which were not allocated. My view is that error handling code should not have if statements unless there is an if statement in the allocation code. This is way more readable. Another way that people deal with these kinds of errors if they don't like to return directly is they add an out: label. out: return ret; I hate out labels for how vague the name is but I also hate do-nothing gotos generally. When you're reading the code you assume that the goto does something but the name gives you no clue what it does so you have to interrupt what you are doing and scroll down to the bottom of the function and it doesn't do anything. It just returns. By this point you have forgotten where you were but it was somewhere reading in the middle of the function. Dan, I 100% agree with everything you are saying here about lables, error handling etc. And your fix is of course 100% valid. I would have a much better feeling if we add a NULL-pointer check before the kfree, because it makes things more difficult to break in the future. I've seen that happen too often. Anyway, go ahead with your patch. No need to waste more time. Acked-by: Frank Schäfer fschaefer@googlemail.com Thanks for pointing this out, em28xx can't get enough attention. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] em28xx: get rid of structs em28xx_ac97_mode and em28xx_audio_mode
Am 23.09.2014 um 02:02 schrieb Mauro Carvalho Chehab: Em Sat, 13 Sep 2014 10:52:22 +0200 Frank Schäfer fschaefer@googlemail.com escreveu: Now that we have enum em28xx_int_audio (none/i2s/ac97), it is no longer necessary to check dev-audio_mode.ac97 to determine the type of internal audio connection. There is also no need to save the type of the detected AC97 chip. Removing the AC97 chip is a bad idea, as the mux of each AC97 device is different. I don't remember anymore what device comes with the sigmatel chips, but it does have a different mixer than em202. The logic to set it different is not there basically for two reasons: 1) I don't have the device with sigmatel (I think someone borrowed it to me at that time, and for a very limited period of time); 2) there's a hole ac97 support at /sound. The idea is to re-use it instead of reinventing the wheel, but that requires time and a few different AC97 setups. 1.) WHICH devices to you think need AC97 chip type specific code ? 2.) WHEN are you going to implement it ? It's just a big dead ugly chunk of code, which causes confusion. So please, let's simplify the code. If we really need to distinguish between AC97 chips one day, we can reintroduce it again. Please note that I'm not removing the AC97 chip type detection, so we are not loosing any information that might be useful in the future. Btw, there are other em28xx devices with other non-em202 AC97 chips out there, with different settings (and even different sampling rates). Those AC97 devices are generally found at the grabber devices. I know. The VAD Laplace webcam is one of them. And the current audio code is broken for it. But the reason for that isn't that we do not distinguish enough between AC97 chips. The reason for that is, that we touch AC97 _at_all_ for USB audio class devices, which is evil, unnecessary and therefore also not done by the Windows driver. The situation is of course different for devices with usb vendor class audio (em28xx-alsa). But that's a separate issue which has nothing to do with this patch... ;-) Regards, Frank Regards, Mauro So replce the remaining checks of dev-audio_mode.ac97 with equivalent checks of dev-int_audio_type and get rid of struct em28xx_ac97_mode and finally the whole struct em28xx_audio_mode. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-audio.c | 2 +- drivers/media/usb/em28xx/em28xx-core.c | 36 ++--- drivers/media/usb/em28xx/em28xx-video.c | 2 +- drivers/media/usb/em28xx/em28xx.h | 13 4 files changed, 8 insertions(+), 45 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 90c7a83..c3a4224 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -933,7 +933,7 @@ static int em28xx_audio_init(struct em28xx *dev) INIT_WORK(adev-wq_trigger, audio_trigger); -if (dev-audio_mode.ac97 != EM28XX_NO_AC97) { +if (dev-int_audio_type == EM28XX_INT_AUDIO_AC97) { em28xx_cvol_new(card, dev, Video, AC97_VIDEO); em28xx_cvol_new(card, dev, Line In, AC97_LINE); em28xx_cvol_new(card, dev, Phone, AC97_PHONE); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index ed83e4e..7464e70 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -405,12 +405,8 @@ static int em28xx_set_audio_source(struct em28xx *dev) return ret; msleep(5); -switch (dev-audio_mode.ac97) { -case EM28XX_NO_AC97: -break; -default: +if (dev-int_audio_type == EM28XX_INT_AUDIO_AC97) ret = set_ac97_input(dev); -} return ret; } @@ -439,7 +435,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) /* It is assumed that all devices use master volume for output. It would be possible to use also line output. */ -if (dev-audio_mode.ac97 != EM28XX_NO_AC97) { +if (dev-int_audio_type == EM28XX_INT_AUDIO_AC97) { /* Mute all outputs */ for (i = 0; i ARRAY_SIZE(outputs); i++) { ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); @@ -462,7 +458,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_set_audio_source(dev); /* Sets volume */ -if (dev-audio_mode.ac97 != EM28XX_NO_AC97) { +if (dev-int_audio_type == EM28XX_INT_AUDIO_AC97) { int vol; em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200); @@ -544,14 +540,11 @@ int em28xx_audio_setup(struct em28xx *dev) em28xx_info(I2S Audio (%d sample rate(s))\n, i2s_samplerates); /* Skip the code that does AC97 vendor detection */ -dev-audio_mode.ac97
Re: [linuxtv-media:devel-3.17-rc6 491/499] drivers/media/usb/em28xx/em28xx.h:787:2: warning: 'vid' may be used uninitialized in this function
Am 23.09.2014 um 04:27 schrieb kbuild test robot: tree: git://linuxtv.org/media_tree.git devel-3.17-rc6 head: 7f8de65b0dc84c19e79d7a642a5655524c57035c commit: f5ac7a471e156f997833f94bad2228e57122c227 [491/499] [media] em28xx: remove some unnecessary fields from struct em28xx_audio_mode config: i386-randconfig-r0-0923 (attached as .config) reproduce: git checkout f5ac7a471e156f997833f94bad2228e57122c227 # save the attached .config to linux build tree make ARCH=i386 Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings: In file included from drivers/media/usb/em28xx/em28xx-core.c:35:0: drivers/media/usb/em28xx/em28xx-core.c: In function 'em28xx_audio_setup': drivers/media/usb/em28xx/em28xx.h:787:2: warning: 'vid' may be used uninitialized in this function [-Wmaybe-uninitialized] printk(KERN_INFO %s: fmt,\ ^ drivers/media/usb/em28xx/em28xx-core.c:507:6: note: 'vid' was declared here u32 vid; ^ This is a false warning. Applying https://patchwork.linuxtv.org/patch/25918/ makes it disappear. Regards, Frank vim +/vid +787 drivers/media/usb/em28xx/em28xx.h 47677e51 drivers/media/usb/em28xx/em28xx.h Mauro Carvalho Chehab 2014-03-05 771 void em28xx_free_device(struct kref *ref); c8793b03 drivers/media/video/em28xx/em28xx.h Mauro Carvalho Chehab 2008-01-13 772 855ff38e drivers/media/usb/em28xx/em28xx.h Frank Schaefer2013-03-27 773 /* Provided by em28xx-camera.c */ 855ff38e drivers/media/usb/em28xx/em28xx.h Frank Schaefer2013-03-27 774 int em28xx_detect_sensor(struct em28xx *dev); 855ff38e drivers/media/usb/em28xx/em28xx.h Frank Schaefer2013-03-27 775 int em28xx_init_camera(struct em28xx *dev); 855ff38e drivers/media/usb/em28xx/em28xx.h Frank Schaefer2013-03-27 776 a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 777 /* printk macros */ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 778 3acf2809 drivers/media/video/em28xx/em28xx.h Mauro Carvalho Chehab 2005-11-08 779 #define em28xx_err(fmt, arg...) do {\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 780printk(KERN_ERR fmt , ##arg); } while (0) a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 781 3acf2809 drivers/media/video/em28xx/em28xx.h Mauro Carvalho Chehab 2005-11-08 782 #define em28xx_errdev(fmt, arg...) do {\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 783printk(KERN_ERR %s: fmt,\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 784dev-name , ##arg); } while (0) a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 785 3acf2809 drivers/media/video/em28xx/em28xx.h Mauro Carvalho Chehab 2005-11-08 786 #define em28xx_info(fmt, arg...) do {\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 @787printk(KERN_INFO %s: fmt,\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 788dev-name , ##arg); } while (0) 3acf2809 drivers/media/video/em28xx/em28xx.h Mauro Carvalho Chehab 2005-11-08 789 #define em28xx_warn(fmt, arg...) do {\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 790printk(KERN_WARNING %s: fmt,\ a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 791dev-name , ##arg); } while (0) a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 792 a6c2ba28 drivers/media/video/em28xx/em28xx.h Andrew Morton 2005-11-08 793 #endif :: The code at line 787 was first introduced by commit :: a6c2ba283565dbc9f055dcb2ecba1971460bb535 [PATCH] v4l: 716: support for em28xx board family :: TO: a...@osdl.org a...@osdl.org :: CC: Linus Torvalds torva...@g5.osdl.org --- 0-DAY kernel build testing backend Open Source Technology Center http://lists.01.org/mailman/listinfo/kbuild Intel Corporation -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media/dvb_usb_af9005] BUG: unable to handle kernel paging request (WAS: [media/em28xx] BUG: unable to handle kernel)
Am 19.09.2014 um 21:55 schrieb Luca Olivetti: El 19/09/14 21:22, Frank Schäfer ha escrit: So symbol_request() returns pointers.!= NULL A closer look at the definition of symbol_request() shows, that it does nothing if CONFIG_MODULES is disabled (it just returns its argument). One possibility to fix this bug would be to embrace these three lines with #ifdef CONFIG_DVB_USB_AF9005_REMOTE ... #endif Luca, what do you think ? This seems to be an ancient bug, which is known at least since 5 1/2 years: https://lkml.org/lkml/2009/2/4/350 Well, it's been a while so I don't remember the details, but I think the same now as then ;-) The idea behind CONFIG_DVB_USB_AF9005_REMOTE was to provide an alternative implementation (based on lirc, at the time it wasn't in the kernel), since this adapter doesn't decode the IR pulses by itself. In theory you could leave it undefined but still provide an implementation in a different module. Just adding #ifdef CONFIG_DVB_USB_AF9005_REMOTE would nuke the (futile?) effort. Now, since the problem seems to be with CONFIG_MODULES disabled, maybe you could combine both conditions #if defined(CONFIG_MODULE) || defined(CONFIG_DVB_USB_AF9005_REMOTE) What happens, if CONFIG_MODULES is enabled, but neither module af9005-remote nor any other IR module is available ? Has this ever been tested ? Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] em28xx: fix VBI handling logic
Am 19.09.2014 um 18:02 schrieb Mauro Carvalho Chehab: When both VBI and video are streaming, and video stream is stopped, a subsequent trial to restart it will fail, because S_FMT will return -EBUSY. That prevents applications like zvbi to work properly. Please notice that, while this fix it fully for zvbi, the best is to get rid of streaming_users and res_get logic as a hole. However, this single-line patch is better to be merged at -stable. Signed-off-by: Mauro Carvalho Chehab mche...@osg.samsung.com diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 08569cbccd95..d75e7f82dfb9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1351,7 +1351,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev-v4l2; - if (v4l2-streaming_users 0) + if (vb2_is_busy(v4l2-vb_vidq)) Looks dangerous. Are you 100% sure that VIDIOC_S_FMT can have no effect on VBI capturing ? It seems to trigger writes to multiple registers... Regards, Frank return -EBUSY; vidioc_try_fmt_vid_cap(file, priv, f); -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [media/em28xx] BUG: unable to handle kernel
Hi Fengguang, thank you for reporting this issue. Am 19.09.2014 um 03:41 schrieb Fengguang Wu: Greetings, 0day kernel testing robot got the below dmesg and the first bad commit is git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master commit a5c075cfd2386a4f3ab4f8ed2830ebee557d4b3f Author: Frank Schaefer fschaefer@googlemail.com AuthorDate: Mon Mar 24 16:33:25 2014 -0300 Commit: Mauro Carvalho Chehab m.che...@samsung.com CommitDate: Fri May 23 13:44:42 2014 -0300 [media] em28xx: move fields wq_trigger and streaming_started from struct em28xx to struct em28xx_audio Both wq_trigger and stream_started are used only to control the em28xx alsa streaming. They don't belong to em28xx common struct. Signed-off-by: Frank Schäfer fschaefer@googlemail.com Signed-off-by: Hans Verkuil hans.verk...@cisco.com Signed-off-by: Mauro Carvalho Chehab m.che...@samsung.com This patch affects the em28xx-alsa module (em28xx-audio.c) only. Now take a look at your kernel config: ... # # Webcam, TV (analog/digital) USB devices # CONFIG_VIDEO_EM28XX=y CONFIG_VIDEO_EM28XX_V4L2=y # CONFIG_VIDEO_EM28XX_ALSA is not set CONFIG_VIDEO_EM28XX_DVB=y CONFIG_VIDEO_EM28XX_RC=y ... The em28xx-alsa module is disabled. Attached dmesg for the parent commit, too. It looks like the parent is actually clean, just that the rcu-tortuture tests take too long time. +--+++---+ | | 3319e6f839 | a5c075cfd2 | next-20140917 | +--+++---+ | boot_successes | 0 | 0 | 0 | | boot_failures| 80 | 20 | 11 | | BUG:kernel_boot_hang | 80 | 1 | 1 | | BUG:unable_to_handle_kernel | 0 | 19 | 10 | | Oops | 0 | 19 | 10 | | EIP_is_at_af9005_usb_module_init | 0 | 19 | 10 | | Kernel_panic-not_syncing:Fatal_exception | 0 | 19 | 10 | | backtrace:af9005_usb_module_init | 0 | 19 | 10 | | backtrace:kernel_init_freeable | 0 | 19 | 10 | | backtrace:_usb_module_init | 0 | 19 | 10 | +--+++---+ [8.528015] usbcore: registered new interface driver dvb_usb_ttusb2 [8.529751] usbcore: registered new interface driver dvb_usb_af9005 [8.529751] usbcore: registered new interface driver dvb_usb_af9005 [8.531584] BUG: unable to handle kernel [8.531584] BUG: unable to handle kernel paging requestpaging request at 02e0 at 02e0 [8.533385] IP: [8.533385] IP: [7d9d67c6] af9005_usb_module_init+0x6b/0x9d [7d9d67c6] af9005_usb_module_init+0x6b/0x9d And this tells us what is going wrong: (gdb) list *(af9005_usb_module_init+0x83) 0x2d11 is in af9005_usb_module_init (drivers/media/usb/dvb-usb/af9005.c:1092). 1087if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { 1088err(af9005_rc_decode function not found, disabling remote); 1089af9005_properties.rc.legacy.rc_query = NULL; 1090} else { 1091af9005_properties.rc.legacy.rc_map_table = rc_keys; 1092af9005_properties.rc.legacy.rc_map_size = *rc_keys_size; 1093} 1094 1095return 0; 1096} So it happens in line 1092 when rc_keys_size is accessed. According to your kernel config you have CONFIG_MODULES disabled CONFIG_DVB_USB_AF9005 enabled CONFIG_DVB_USB_AF9005_REMOTE disabled So af9005 is compiled in without remote control support. Thus we should have hit the if-path, which also prints a message about the missing remote control support. Instead, we have hit the else path, which means that rc_decode, rc_keys and rc_keys_size are all != NULL, although they should be NULL. You can verify this by enabling CONFIG_DVB_USB_AF9005_REMOTE. That makes the issue disappear. Now let's go a few lines up to see where these pointers come from: 1084 rc_decode = symbol_request(af9005_rc_decode); 1085 rc_keys = symbol_request(rc_map_af9005_table); 1086 rc_keys_size = symbol_request(rc_map_af9005_table_size); So symbol_request() returns pointers.!= NULL A closer look at the definition of symbol_request() shows, that it does nothing if CONFIG_MODULES is disabled (it just returns its argument). One possibility to fix this bug would be to embrace these three lines with #ifdef CONFIG_DVB_USB_AF9005_REMOTE ... #endif
[media/dvb_usb_af9005] BUG: unable to handle kernel paging request (WAS: [media/em28xx] BUG: unable to handle kernel)
(adjusting the title and adding Luca Olivetti (dvb_usb_af9005 author) and Antti Palosaari) Am 19.09.2014 um 21:01 schrieb Frank Schäfer: Hi Fengguang, thank you for reporting this issue. Am 19.09.2014 um 03:41 schrieb Fengguang Wu: [...] [8.528015] usbcore: registered new interface driver dvb_usb_ttusb2 [8.529751] usbcore: registered new interface driver dvb_usb_af9005 [8.529751] usbcore: registered new interface driver dvb_usb_af9005 [8.531584] BUG: unable to handle kernel [8.531584] BUG: unable to handle kernel paging requestpaging request at 02e0 at 02e0 [8.533385] IP: [8.533385] IP: [7d9d67c6] af9005_usb_module_init+0x6b/0x9d [7d9d67c6] af9005_usb_module_init+0x6b/0x9d And this tells us what is going wrong: (gdb) list *(af9005_usb_module_init+0x83) 0x2d11 is in af9005_usb_module_init (drivers/media/usb/dvb-usb/af9005.c:1092). 1087if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { 1088err(af9005_rc_decode function not found, disabling remote); 1089af9005_properties.rc.legacy.rc_query = NULL; 1090} else { 1091af9005_properties.rc.legacy.rc_map_table = rc_keys; 1092af9005_properties.rc.legacy.rc_map_size = *rc_keys_size; 1093} 1094 1095return 0; 1096} So it happens in line 1092 when rc_keys_size is accessed. According to your kernel config you have CONFIG_MODULES disabled CONFIG_DVB_USB_AF9005 enabled CONFIG_DVB_USB_AF9005_REMOTE disabled So af9005 is compiled in without remote control support. Thus we should have hit the if-path, which also prints a message about the missing remote control support. Instead, we have hit the else path, which means that rc_decode, rc_keys and rc_keys_size are all != NULL, although they should be NULL. You can verify this by enabling CONFIG_DVB_USB_AF9005_REMOTE. That makes the issue disappear. Now let's go a few lines up to see where these pointers come from: 1084 rc_decode = symbol_request(af9005_rc_decode); 1085 rc_keys = symbol_request(rc_map_af9005_table); 1086 rc_keys_size = symbol_request(rc_map_af9005_table_size); So symbol_request() returns pointers.!= NULL A closer look at the definition of symbol_request() shows, that it does nothing if CONFIG_MODULES is disabled (it just returns its argument). One possibility to fix this bug would be to embrace these three lines with #ifdef CONFIG_DVB_USB_AF9005_REMOTE ... #endif Luca, what do you think ? This seems to be an ancient bug, which is known at least since 5 1/2 years: https://lkml.org/lkml/2009/2/4/350 Regards, Frank Schäfer [8.535613] *pde = [8.535613] *pde = [8.536416] Oops: [#1] [8.536416] Oops: [#1] PREEMPT PREEMPT DEBUG_PAGEALLOCDEBUG_PAGEALLOC [8.537863] CPU: 0 PID: 1 Comm: swapper Not tainted 3.15.0-rc6-00151-ga5c075c #1 [8.537863] CPU: 0 PID: 1 Comm: swapper Not tainted 3.15.0-rc6-00151-ga5c075c #1 [8.539827] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 [8.539827] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 [8.541519] task: 89c9a670 ti: 89c9c000 task.ti: 89c9c000 [8.541519] task: 89c9a670 ti: 89c9c000 task.ti: 89c9c000 [8.541519] EIP: 0060:[7d9d67c6] EFLAGS: 00010206 CPU: 0 [8.541519] EIP: 0060:[7d9d67c6] EFLAGS: 00010206 CPU: 0 [8.541519] EIP is at af9005_usb_module_init+0x6b/0x9d [8.541519] EIP is at af9005_usb_module_init+0x6b/0x9d [8.541519] EAX: 02e0 EBX: ECX: 0006 EDX: [8.541519] EAX: 02e0 EBX: ECX: 0006 EDX: [8.541519] ESI: EDI: 7da33ec8 EBP: 89c9df30 ESP: 89c9df2c [8.541519] ESI: EDI: 7da33ec8 EBP: 89c9df30 ESP: 89c9df2c [8.541519] DS: 007b ES: 007b FS: GS: 00e0 SS: 0068 [8.541519] DS: 007b ES: 007b FS: GS: 00e0 SS: 0068 [8.541519] CR0: 8005003b CR2: 02e0 CR3: 05a54000 CR4: 0690 [8.541519] CR0: 8005003b CR2: 02e0 CR3: 05a54000 CR4: 0690 [8.541519] Stack: [8.541519] Stack: [8.541519] 7d9d675b [8.541519] 7d9d675b 89c9df90 89c9df90 7d992a49 7d992a49 7d7d5914 7d7d5914 89c9df4c 89c9df4c 7be3a800 7be3a800 7d08c58c 7d08c58c 8a4c3968 8a4c3968 [8.541519] 89c9df80 [8.541519] 89c9df80 7be3a966 7be3a966 0192 0192 0006 0006 0006 0006 7d7d3ff4 7d7d3ff4 8a4c397a 8a4c397a 0200 0200 [8.541519] 7d6b1280 [8.541519] 7d6b1280 8a4c3979 8a4c3979 0006 0006 09a6 09a6 7da32db8 7da32db8 b13eec81 b13eec81 0006 0006 09a6 09a6 [8.541519] Call Trace: [8.541519] Call Trace: [8.541519] [7d9d675b] ? ttusb2_driver_init+0x16/0x16 [8.541519
Re: [PATCH 4/4] em28xx-v4l: get rid of field users in struct em28xx_v4l2
Hi Hans, Am 18.09.2014 um 21:13 schrieb Hans Verkuil: Hi Frank, On 07/25/2014 07:48 PM, Frank Schäfer wrote: Instead of counting the number of opened file handles, use function v4l2_fh_is_singular_file() in em28xx_v4l2_open() and em28xx_v4l2_close() to determine if the file handle is the first/last opened one. This won't work: if you capture from both /dev/video and /dev/vbi and close one, then it stops all streaming. You are 100% right, v4l2_fh_is_singular() is a per device _node_ check. How could I miss that ? :/ I would just revert this patch completely. There is currently no core support for detecting when all users of all devices registered by a driver have left, so you don't have really have an alternative but to use your old code. Indeed. I will send a revert patch. Thanks for the hint ! Regards, Frank Regards, Hans Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 23 +-- drivers/media/usb/em28xx/em28xx.h | 1 - 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3a7ec3b..087ccf9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1883,9 +1883,8 @@ static int em28xx_v4l2_open(struct file *filp) return -EINVAL; } -em28xx_videodbg(open dev=%s type=%s users=%d\n, -video_device_node_name(vdev), v4l2_type_names[fh_type], -v4l2-users); +em28xx_videodbg(open dev=%s type=%s\n, +video_device_node_name(vdev), v4l2_type_names[fh_type]); if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; @@ -1898,7 +1897,9 @@ static int em28xx_v4l2_open(struct file *filp) return ret; } -if (v4l2-users == 0) { +if (v4l2_fh_is_singular_file(filp)) { +em28xx_videodbg(first opened filehandle, initializing device\n); + em28xx_set_mode(dev, EM28XX_ANALOG_MODE); if (vdev-vfl_type != VFL_TYPE_RADIO) @@ -1909,6 +1910,8 @@ static int em28xx_v4l2_open(struct file *filp) * of some i2c devices */ em28xx_wake_i2c(dev); +} else { +em28xx_videodbg(further filehandles are already opened\n); } if (vdev-vfl_type == VFL_TYPE_RADIO) { @@ -1918,7 +1921,6 @@ static int em28xx_v4l2_open(struct file *filp) kref_get(dev-ref); kref_get(v4l2-ref); -v4l2-users++; mutex_unlock(dev-lock); @@ -2025,12 +2027,11 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx_v4l2*v4l2 = dev-v4l2; int errCode; -em28xx_videodbg(users=%d\n, v4l2-users); - -vb2_fop_release(filp); mutex_lock(dev-lock); -if (v4l2-users == 1) { +if (v4l2_fh_is_singular_file(filp)) { +em28xx_videodbg(last opened filehandle, shutting down device\n); + /* No sense to try to write to the device */ if (dev-disconnected) goto exit; @@ -2049,10 +2050,12 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_errdev(cannot change alternate number to 0 (error=%i)\n, errCode); } +} else { +em28xx_videodbg(further opened filehandles left\n); } exit: -v4l2-users--; +vb2_fop_release(filp); kref_put(v4l2-ref, em28xx_free_v4l2); mutex_unlock(dev-lock); kref_put(dev-ref, em28xx_free_device); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 4360338..84ef8ef 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -524,7 +524,6 @@ struct em28xx_v4l2 { int sensor_yres; int sensor_xtal; -int users; /* user count for exclusive use */ int streaming_users;/* number of actively streaming users */ u32 frequency; /* selected tuner frequency */ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH for 3.17] Revert [media] em28xx-v4l: get rid of field users in struct em28xx_v4l2
This reverts commit 747dba7de2a51a3db58b665ed3bc8c07921546ec. It breaks concurrent vbi and video capturing: While v4l2-users is the number of users of the whole device (all device nodes), v4l2_fh_is_singular() only checks the number of users of a specific device node. As a result. if one device node is open and a second device node is opened (closed), the device is reinitialized (streaming is stopped). Reported-by: Hans Verkuil hans.verk...@cisco.com Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 23 ++- drivers/media/usb/em28xx/em28xx.h | 1 + 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 90dec29..cef266c 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1883,8 +1883,9 @@ static int em28xx_v4l2_open(struct file *filp) return -EINVAL; } - em28xx_videodbg(open dev=%s type=%s\n, - video_device_node_name(vdev), v4l2_type_names[fh_type]); + em28xx_videodbg(open dev=%s type=%s users=%d\n, + video_device_node_name(vdev), v4l2_type_names[fh_type], + v4l2-users); if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; @@ -1897,9 +1898,7 @@ static int em28xx_v4l2_open(struct file *filp) return ret; } - if (v4l2_fh_is_singular_file(filp)) { - em28xx_videodbg(first opened filehandle, initializing device\n); - + if (v4l2-users == 0) { em28xx_set_mode(dev, EM28XX_ANALOG_MODE); if (vdev-vfl_type != VFL_TYPE_RADIO) @@ -1910,8 +1909,6 @@ static int em28xx_v4l2_open(struct file *filp) * of some i2c devices */ em28xx_wake_i2c(dev); - } else { - em28xx_videodbg(further filehandles are already opened\n); } if (vdev-vfl_type == VFL_TYPE_RADIO) { @@ -1921,6 +1918,7 @@ static int em28xx_v4l2_open(struct file *filp) kref_get(dev-ref); kref_get(v4l2-ref); + v4l2-users++; mutex_unlock(dev-lock); @@ -2027,11 +2025,12 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx_v4l2*v4l2 = dev-v4l2; int errCode; - mutex_lock(dev-lock); + em28xx_videodbg(users=%d\n, v4l2-users); - if (v4l2_fh_is_singular_file(filp)) { - em28xx_videodbg(last opened filehandle, shutting down device\n); + vb2_fop_release(filp); + mutex_lock(dev-lock); + if (v4l2-users == 1) { /* No sense to try to write to the device */ if (dev-disconnected) goto exit; @@ -2050,12 +2049,10 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_errdev(cannot change alternate number to 0 (error=%i)\n, errCode); } - } else { - em28xx_videodbg(further opened filehandles left\n); } exit: - vb2_fop_release(filp); + v4l2-users--; kref_put(v4l2-ref, em28xx_free_v4l2); mutex_unlock(dev-lock); kref_put(dev-ref, em28xx_free_device); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 84ef8ef..4360338 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -524,6 +524,7 @@ struct em28xx_v4l2 { int sensor_yres; int sensor_xtal; + int users; /* user count for exclusive use */ int streaming_users;/* number of actively streaming users */ u32 frequency; /* selected tuner frequency */ -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] em28xx: clean up the audio variable mess
The audio variables in em28xx are a big mess: - many have misleading names - some are completely unnecessary - some duplicate in parts or even completely the meaning of others - some device features are described by combinations of multiple variables, which makes the code difficult to understand and allows inconsistencies So clean up the em28xx audio variables: - Patch 1 removes 3 unneeded audio variables. - Patch 2 replaces the variables has_alsa_audio and has_audio_class with a single enum variable describing the type of usb audio (no usb audio / audio class / vendor). - Patches 3+4 replace the variables has_audio and ac97 of struct em28xx_audio_mode with a single enum variable describing the type of internal audio connection (none / ac97 / i2s). Variable audio_mode is finally removed together with the obsolete structs em28xx_audio_mode and em28xx_ac97_mode. This simplifies the audio code a lot, making it much more self-explaining and easier to understand. It will hopefully reduce the risk of audio regression in the future. Frank Schäfer (4): em28xx: remove some unnecessary fields from struct em28xx_audio_mode em28xx: simplify usb audio class handling em28xx: get rid of field has_audio in struct em28xx_audio_mode em28xx: get rid of structs em28xx_ac97_mode and em28xx_audio_mode drivers/media/usb/em28xx/em28xx-audio.c | 10 ++--- drivers/media/usb/em28xx/em28xx-cards.c | 30 +++--- drivers/media/usb/em28xx/em28xx-core.c | 72 +++-- drivers/media/usb/em28xx/em28xx-video.c | 8 ++-- drivers/media/usb/em28xx/em28xx.h | 28 + 5 files changed, 59 insertions(+), 89 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] em28xx: get rid of field has_audio in struct em28xx_audio_mode
Field has_audio in struct em28xx_audio_mode is used together with value EM28XX_NO_AC97 of field ac97 to determine the internal type of audio (none/i2s/ac97). This makes the code difficult to understand: !dev-audio_mode.has_audio audio_mode.ac97 == EM28XX_NO_AC97 = no audio !dev-audio_mode.has_audio audio_mode.ac97 != EM28XX_NO_AC97 = BUG dev-audio_mode.has_audio dev-audio_mode.ac97 == EM28XX_NO_AC97 = AC97 audio dev-audio_mode.has_audio dev-audio_mode.ac97 != EM28XX_NO_AC97 = I2S audio Simplify the whole thing by introducing an enum em28xx_int_audio_type which describes the internal audio type (none, ac97, i2s) and is hooked directly to the device struct. Then get rid of field has_audio in struct em28xx_audio_mode. A follow-up patch will then remove struct em28xx_ac97_mode and finally the whole struct em28xx_audio_mode. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-core.c | 14 -- drivers/media/usb/em28xx/em28xx-video.c | 6 +++--- drivers/media/usb/em28xx/em28xx.h | 8 +++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 16747ca..ed83e4e 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -433,7 +433,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) int ret, i; u8 xclk; - if (!dev-audio_mode.has_audio) + if (dev-int_audio_type == EM28XX_INT_AUDIO_NONE) return 0; /* It is assumed that all devices use master volume for output. @@ -512,25 +512,25 @@ int em28xx_audio_setup(struct em28xx *dev) dev-chip_id == CHIP_ID_EM28174 || dev-chip_id == CHIP_ID_EM28178) { /* Digital only device - don't load any alsa module */ - dev-audio_mode.has_audio = false; + dev-int_audio_type = EM28XX_INT_AUDIO_NONE; dev-usb_audio_type = EM28XX_USB_AUDIO_NONE; return 0; } - dev-audio_mode.has_audio = true; - /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); em28xx_info(Config register raw data: 0x%02x\n, cfg); if (cfg 0) { /* Register read error? */ cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ + dev-int_audio_type = EM28XX_INT_AUDIO_AC97; } else if ((cfg EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { /* The device doesn't have vendor audio at all */ - dev-audio_mode.has_audio = false; + dev-int_audio_type = EM28XX_INT_AUDIO_NONE; dev-usb_audio_type = EM28XX_USB_AUDIO_NONE; return 0; } else if ((cfg EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { + dev-int_audio_type = EM28XX_INT_AUDIO_I2S; if (dev-chip_id CHIP_ID_EM2860 (cfg EM28XX_CHIPCFG_AUDIOMASK) == EM2820_CHIPCFG_I2S_1_SAMPRATE) @@ -546,6 +546,8 @@ int em28xx_audio_setup(struct em28xx *dev) /* Skip the code that does AC97 vendor detection */ dev-audio_mode.ac97 = EM28XX_NO_AC97; goto init_audio; + } else { + dev-int_audio_type = EM28XX_INT_AUDIO_AC97; } dev-audio_mode.ac97 = EM28XX_AC97_OTHER; @@ -561,7 +563,7 @@ int em28xx_audio_setup(struct em28xx *dev) dev-audio_mode.ac97 = EM28XX_NO_AC97; if (dev-usb_audio_type == EM28XX_USB_AUDIO_VENDOR) dev-usb_audio_type = EM28XX_USB_AUDIO_NONE; - dev-audio_mode.has_audio = false; + dev-int_audio_type = EM28XX_INT_AUDIO_NONE; goto init_audio; } diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3642438..3284de9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1720,7 +1720,7 @@ static int vidioc_querycap(struct file *file, void *priv, else cap-device_caps = V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE; - if (dev-audio_mode.has_audio) + if (dev-int_audio_type != EM28XX_INT_AUDIO_NONE) cap-device_caps |= V4L2_CAP_AUDIO; if (dev-tuner_type != TUNER_ABSENT) @@ -2514,7 +2514,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2_disable_ioctl(v4l2-vdev, VIDIOC_G_FREQUENCY); v4l2_disable_ioctl(v4l2-vdev, VIDIOC_S_FREQUENCY); } - if (!dev-audio_mode.has_audio) { + if (dev-int_audio_type == EM28XX_INT_AUDIO_NONE) { v4l2_disable_ioctl(v4l2-vdev, VIDIOC_G_AUDIO); v4l2_disable_ioctl(v4l2-vdev, VIDIOC_S_AUDIO); } @@ -2544,7 +2544,7 @@ static int em28xx_v4l2_init(struct em28xx *dev
[PATCH 1/4] em28xx: remove some unnecessary fields from struct em28xx_audio_mode
Fields ac97_feat, ac97_vendor_id and i2s_samplerates of struct em28xx_audio_mode are used nowhere, except in function em28xx_audio_setup(). So get rid of them and use local variables instead. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-core.c | 14 ++ drivers/media/usb/em28xx/em28xx.h | 6 -- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 2f82e92..0fe05ff 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -505,6 +505,7 @@ int em28xx_audio_setup(struct em28xx *dev) { int vid1, vid2, feat, cfg; u32 vid; + u8 i2s_samplerates; if (dev-chip_id == CHIP_ID_EM2870 || dev-chip_id == CHIP_ID_EM2874 || @@ -534,15 +535,15 @@ int em28xx_audio_setup(struct em28xx *dev) if (dev-chip_id CHIP_ID_EM2860 (cfg EM28XX_CHIPCFG_AUDIOMASK) == EM2820_CHIPCFG_I2S_1_SAMPRATE) - dev-audio_mode.i2s_samplerates = 1; + i2s_samplerates = 1; else if (dev-chip_id = CHIP_ID_EM2860 (cfg EM28XX_CHIPCFG_AUDIOMASK) == EM2860_CHIPCFG_I2S_5_SAMPRATES) - dev-audio_mode.i2s_samplerates = 5; + i2s_samplerates = 5; else - dev-audio_mode.i2s_samplerates = 3; + i2s_samplerates = 3; em28xx_info(I2S Audio (%d sample rate(s))\n, - dev-audio_mode.i2s_samplerates); + i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev-audio_mode.ac97 = EM28XX_NO_AC97; goto init_audio; @@ -569,15 +570,12 @@ int em28xx_audio_setup(struct em28xx *dev) goto init_audio; vid = vid1 16 | vid2; - - dev-audio_mode.ac97_vendor_id = vid; em28xx_warn(AC97 vendor ID = 0x%08x\n, vid); feat = em28xx_read_ac97(dev, AC97_RESET); if (feat 0) goto init_audio; - dev-audio_mode.ac97_feat = feat; em28xx_warn(AC97 features = 0x%04x\n, feat); /* Try to identify what audio processor we have */ @@ -597,7 +595,7 @@ init_audio: break; case EM28XX_AC97_SIGMATEL: - em28xx_info(Sigmatel audio processor detected(stac 97%02x)\n, - dev-audio_mode.ac97_vendor_id 0xff); + em28xx_info(Sigmatel audio processor detected (stac 97%02x)\n, + vid 0xff); break; case EM28XX_AC97_OTHER: em28xx_warn(Unknown AC97 audio processor detected!\n); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 84ef8ef..1f38163 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -309,13 +309,7 @@ enum em28xx_ac97_mode { struct em28xx_audio_mode { enum em28xx_ac97_mode ac97; - - u16 ac97_feat; - u32 ac97_vendor_id; - unsigned int has_audio:1; - - u8 i2s_samplerates; }; /* em28xx has two audio inputs: tuner and line in. -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] em28xx: simplify usb audio class handling
As far as we know devices can either have audio class or vendor class usb interfaces but not both at the same time. Even if both interface types could be provided by devices at the same time, the current code is totally broken for that case. So clean up and simplify the usb audio class handling by replacing fields has_audio_class (device has usb audio class compliant interface) and has_alsa_audio (device has vendor audio interface) in struct em28xx with a single enum em28xx_usb_audio_type. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-audio.c | 8 drivers/media/usb/em28xx/em28xx-cards.c | 30 -- drivers/media/usb/em28xx/em28xx-core.c | 8 drivers/media/usb/em28xx/em28xx.h | 9 +++-- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index e881ef7..90c7a83 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -893,7 +893,7 @@ static int em28xx_audio_init(struct em28xx *dev) static int devnr; int err; - if (!dev-has_alsa_audio) { + if (dev-usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { /* This device does not support the extension (in this case the device is expecting the snd-usb-audio module or doesn't have analog audio support at all) */ @@ -975,7 +975,7 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev == NULL) return 0; - if (!dev-has_alsa_audio) { + if (dev-usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { /* This device does not support the extension (in this case the device is expecting the snd-usb-audio module or doesn't have analog audio support at all) */ @@ -1003,7 +1003,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) if (dev == NULL) return 0; - if (!dev-has_alsa_audio) + if (dev-usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; em28xx_info(Suspending audio extension); @@ -1017,7 +1017,7 @@ static int em28xx_audio_resume(struct em28xx *dev) if (dev == NULL) return 0; - if (!dev-has_alsa_audio) + if (dev-usb_audio_type != EM28XX_USB_AUDIO_VENDOR) return 0; em28xx_info(Resuming audio extension); diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 582c1e1..f142588 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2931,9 +2931,9 @@ static void request_module_async(struct work_struct *work) #if defined(CONFIG_MODULES) defined(MODULE) if (dev-has_video) request_module(em28xx-v4l); - if (dev-has_audio_class) + if (dev-usb_audio_type == EM28XX_USB_AUDIO_CLASS) request_module(snd-usb-audio); - else if (dev-has_alsa_audio) + else if (dev-usb_audio_type == EM28XX_USB_AUDIO_VENDOR) request_module(em28xx-alsa); if (dev-board.has_dvb) request_module(em28xx-dvb); @@ -3180,7 +3180,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, struct usb_device *udev; struct em28xx *dev = NULL; int retval; - bool has_audio = false, has_video = false, has_dvb = false; + bool has_vendor_audio = false, has_video = false, has_dvb = false; int i, nr, try_bulk; const int ifnum = interface-altsetting[0].desc.bInterfaceNumber; char *speed; @@ -3262,7 +3262,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, break; case 0x83: if (usb_endpoint_xfer_isoc(e)) { - has_audio = true; + has_vendor_audio = true; } else { printk(KERN_INFO DRIVER_NAME : error: skipping audio endpoint 0x83, because it uses bulk transfers !\n); @@ -3318,7 +3318,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, } } - if (!(has_audio || has_video || has_dvb)) { + if (!(has_vendor_audio || has_video || has_dvb)) { retval = -ENODEV; goto err_free; } @@ -3365,25 +3365,27 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev-devno = nr; dev-model = id-driver_info; dev-alt = -1; - dev-is_audio_only = has_audio !(has_video || has_dvb); - dev-has_alsa_audio = has_audio; + dev-is_audio_only
[PATCH] em28xx: remove dead code line from em28xx_audio_setup()
Setting the value of the chip config register to EM28XX_CHIPCFG_AC97 in case of a read error is a leftover from the past which is no longer needed. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 91ea3e4..bfe0726 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -516,9 +516,8 @@ int em28xx_audio_setup(struct em28xx *dev) /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); em28xx_info(Config register raw data: 0x%02x\n, cfg); - if (cfg 0) { - /* Register read error? */ - cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ + if (cfg 0) { /* Register read error */ + /* Be conservative */ dev-int_audio_type = EM28XX_INT_AUDIO_AC97; } else if ((cfg EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { /* The device doesn't have vendor audio at all */ -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: strange empia device
Am 02.09.2014 um 08:28 schrieb Lorenzo Marcantonio: On Mon, Sep 01, 2014 at 07:58:52PM -0400, Andy Walls wrote: A Merlin firmware of 16 kB strongly suggests that this chip has an integarted Conexant CX25843 (Merlin Audio + Thresher Video = Mako) Broadtcast A/V decoder core. The chip might only have a Merlin integrated, but so far I've never encountered that. It will be easy enough to tell, if the Thresher registers don't respond or only respond with junk. However I strongly suspect that these drivers are for a whole *family* of empia device. The oem ini by roxio talks about three different parts... probably they give one sys file for everyone and the oem customizes the ini. In short the merlin fw may not be actually used for *this* part but only for other empia devices/configurations. Otherwise I wonder *why* a fscking 1.5MB of sys driver for a mostly dumb capture device... Right. There is also no firmware upload in the USB-log I have checked. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: strange empia device
Am 31.08.2014 um 17:41 schrieb Lorenzo Marcantonio: On Sun, Aug 31, 2014 at 04:50:08PM +0200, Frank Schäfer wrote: Hmm... could you send us the output of lsusb -v -d 1b80:e31d ? Sure, here is it. However it seems that roxio violated the most sacred USB rule (i.e. they use that vid/pid for two different kinds of hardware); What's the other device using this vid:pid and which hardware does it use ? in fact even people on Windows have troubles with it (and a guaranteed blue screen on Win8, it seems :D) I already had some experience in reverse engineering a webcam (in fact I even 'patched' the 8051 firmware and fully disassembled the win driver for one chinese Cypress EZ2 based cam), but that was very painful and I don't actually want to repeat the experience :D There is very likely no need to patch a firmware. ;-) The big task is the integrated decoder. Makes no fun without a datasheet. :/ Bus 002 Device 005: ID 1b80:e31d Afatech Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize064 idVendor 0x1b80 Afatech idProduct 0xe31d bcdDevice1.00 iManufacturer 0 iProduct1 Roxio Video Capture USB iSerial 2 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 406 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 4 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol255 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 11 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes1 Transfer TypeIsochronous Synch Type None Usage Type Data wMaxPacketSize 0x 1x 0 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes1 Transfer TypeIsochronous Synch Type None Usage Type Data wMaxPacketSize 0x 1x 0 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x8a EP 10 IN bmAttributes2 Transfer TypeBulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 1 bNumEndpoints 4 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol255 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 11 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes1 Transfer TypeIsochronous Synch Type None Usage Type Data wMaxPacketSize 0x 1x 0 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes1 Transfer Type
Re: HVR 900 (USB ID 2040:6500) no analogue sound reloaded
Am 01.09.2014 um 09:31 schrieb Oravecz Csaba: Sun Aug 31 17:07:00 2014 =?windows-1252?Q?Frank_Sch=E4fer?= kirjutas: Am 22.08.2014 um 21:03 schrieb Oravecz Csaba: I reported this issue earlier but for some reason it went pretty much unnoticed. The essence is that with the newest em28xx drivers now present in 3.14 kernels (i'm on stock fedora 3.14.15-100.fc19.i686.PAE) I can't get analogue sound from this card. I see that the code snippet that produced this output in the pre 3.14 versions em2882/3 #0: Config register raw data: 0x50 em2882/3 #0: AC97 vendor ID = 0x em2882/3 #0: AC97 features = 0x6a90 em2882/3 #0: Empia 202 AC97 audio processor detected is still there in em28xx-core.c, however, there is nothing like that in current kernel logs so it seems that this part of the code is just skipped, which I tend to think is not the intended behaviour. I have not gone any further to investigate the issue, rather I've simply copied the 'old' em28xx Thank you for reporting this issue. I suspect reverting commit b99f0aadd3 [media] em28xx: check if a device has audio earlier will resolve it. Can you check that ? Yes, that has indeed solved the problem. I assume this will slowly propagate into the mainstraim distros, in the meantime i can happily use the custom compiled reverted drivers. Thanks, o.cs. Ok, thanks for testing. I will send a patch reverting this commit later this evening. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH for 3.17] Revert [media] em28xx: check if a device has audio earlier
This reverts commit b99f0aadd33fad269c8e62b5bec8b5c012a44a56 Author: Mauro Carvalho Chehab m.che...@samsung.com Date: Fri Dec 27 00:16:13 2013 -0300 [media] em28xx: check if a device has audio earlier Better to split chipset detection from the audio setup. So, move the detection code to em28xx_init_dev(). It broke analog audio of the Hauppauge winTV HVR 900 and very likely many other em28xx devices. Background: The local variable has_audio in em28xx_usb_probe() describes if the currently probed _usb_interface_ has an audio endpoint, while dev-audio_mode.has_audio means that the _device_ as a whole provides analog audio. Hence it is wrong to set dev-audio_mode.has_audio = has_audio in em28xx_usb_probe(). As result, audio support is no longer detected and configured on devices which have the audio endpoint on a separate interface, because em28xx_audio_setup() bails out immediately at the beginning. Revert the faulty commit to restore the old audio detection procedure, which checks the chip configuration register to determine if the device has analog audio. Cc: sta...@vger.kernel.org# 3.14 to 3.16 Reported-by: Oravecz Csaba orav...@nytud.mta.hu Tested-by: Oravecz Csaba orav...@nytud.mta.hu Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-cards.c | 11 --- drivers/media/usb/em28xx/em28xx-core.c | 12 +++- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index a7e24848..912ea1b 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3098,16 +3098,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, } } - if (dev-chip_id == CHIP_ID_EM2870 || - dev-chip_id == CHIP_ID_EM2874 || - dev-chip_id == CHIP_ID_EM28174 || - dev-chip_id == CHIP_ID_EM28178) { - /* Digital only device - don't load any alsa module */ - dev-audio_mode.has_audio = false; - dev-has_audio_class = false; - dev-has_alsa_audio = false; - } - if (chip_name != default_chip_name) printk(KERN_INFO DRIVER_NAME : chip ID is %s\n, chip_name); @@ -3377,7 +3367,6 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev-alt = -1; dev-is_audio_only = has_audio !(has_video || has_dvb); dev-has_alsa_audio = has_audio; - dev-audio_mode.has_audio = has_audio; dev-has_video = has_video; dev-ifnum = ifnum; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 523d7e9..0f6caa4 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -506,8 +506,18 @@ int em28xx_audio_setup(struct em28xx *dev) int vid1, vid2, feat, cfg; u32 vid; - if (!dev-audio_mode.has_audio) + if (dev-chip_id == CHIP_ID_EM2870 || + dev-chip_id == CHIP_ID_EM2874 || + dev-chip_id == CHIP_ID_EM28174 || + dev-chip_id == CHIP_ID_EM28178) { + /* Digital only device - don't load any alsa module */ + dev-audio_mode.has_audio = false; + dev-has_audio_class = false; + dev-has_alsa_audio = false; return 0; + } + + dev-audio_mode.has_audio = true; /* See how this device is configured */ cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: strange empia device
Am 01.09.2014 um 21:03 schrieb Lorenzo Marcantonio: On Mon, Sep 01, 2014 at 08:14:25PM +0200, Frank Schäfer wrote: What's the other device using this vid:pid and which hardware does it use ? The previous generation of the tool: http://www.linuxtv.org/wiki/index.php/RoxioEasyVHStoDVD ... an easycap DC60+ clone. Doubly hating it since I bought is sure that it would have been supported! The big task is the integrated decoder. Makes no fun without a datasheet. :/ I presume that with decoder you mean the composite to YUV translator... Yes. With the datasheet is too easy :D :D strange thing is eMPIA says that linux is supported for some of their chip. But of course the 2980 isn't even advertised It had been advertised in past, but they removed all informations about it from their website. :-( and probably they only give you docs if you buy 100K pieces:( ...and sign an NDA (non-disclosure agreement). Thanks, looks like the other em2980 we have seen (Dazzle Video Capture USB V1.0). Please tell if there are other tests or captures you need. At the moment, no. By the way, even on Windows, transfer seems flaky. If the bus is not perfectly idle or there is some nontrivial CPU load often it loses transfer sync and the image get split (probably an isoc transfer get lost and it doesn't number the packets or something). Not our problem. ;-) Regards, Frank Had the same problem with the other chinese camera I used (USB suckitude knows no limits:P) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: strange empia device
Hi Lorenzo, Am 25.08.2014 um 21:01 schrieb Lorenzo Marcantonio: Just bought a roxio video capture dongle. Read around that it was an easycap clone (supported, then); it seems it's not so anymore :( It identifies as 1b80:e31d Roxio Video Capture USB (it also uses audio class for audio) Now comes the funny thing. Inside there is the usual E2P memory, a regulator or two and an empia marked EM2980 (*not* em2890!); some passive and nothing else. Digging around in the driver cab (emBDA.inf) shows that it seems an em28285 driver rebranded by roxio... it installs emBDAA.sys and emOEMA.sys (pretty big: about 1.5MB combined!); also a 16KB merlinFW.rom (presumably a firmware for the em chip? I tought they were fixed function); also the usual directshow .ax filter and some exe in autorun (emmona.exe: firmware/setup loader?). Looking in the em28xx gave me the idea that that thing is not supported (at least in my current 3.6.6)... however the empia sites says (here http://www.empiatech.com/wp/video-grabber-em282xx/) 28284 should be linux supported. Nothing said about 28285. And the chip is marked 2980?! by the way, forcing the driver to load I get this: [ 3439.787701] em28xx: New device Roxio Video Capture USB @ 480 Mbps (1b80:e31d, interface 0, class 0) [ 3439.787704] em28xx: Video interface 0 found [ 3439.787705] em28xx: DVB interface 0 found [ 3439.787866] em28xx #0: em28xx chip ID = 146 Is there any hope to make it work (even on git kernel there is nothing for chip id 146...)? See http://www.spinics.net/lists/linux-media/msg73699.html HTH, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: strange empia device
Am 31.08.2014 um 16:47 schrieb Frank Schäfer: Hi Lorenzo, Am 25.08.2014 um 21:01 schrieb Lorenzo Marcantonio: Just bought a roxio video capture dongle. Read around that it was an easycap clone (supported, then); it seems it's not so anymore :( It identifies as 1b80:e31d Roxio Video Capture USB (it also uses audio class for audio) Now comes the funny thing. Inside there is the usual E2P memory, a regulator or two and an empia marked EM2980 (*not* em2890!); some passive and nothing else. Digging around in the driver cab (emBDA.inf) shows that it seems an em28285 driver rebranded by roxio... it installs emBDAA.sys and emOEMA.sys (pretty big: about 1.5MB combined!); also a 16KB merlinFW.rom (presumably a firmware for the em chip? I tought they were fixed function); also the usual directshow .ax filter and some exe in autorun (emmona.exe: firmware/setup loader?). Looking in the em28xx gave me the idea that that thing is not supported (at least in my current 3.6.6)... however the empia sites says (here http://www.empiatech.com/wp/video-grabber-em282xx/) 28284 should be linux supported. Nothing said about 28285. And the chip is marked 2980?! by the way, forcing the driver to load I get this: [ 3439.787701] em28xx: New device Roxio Video Capture USB @ 480 Mbps (1b80:e31d, interface 0, class 0) [ 3439.787704] em28xx: Video interface 0 found [ 3439.787705] em28xx: DVB interface 0 found [ 3439.787866] em28xx #0: em28xx chip ID = 146 Is there any hope to make it work (even on git kernel there is nothing for chip id 146...)? See http://www.spinics.net/lists/linux-media/msg73699.html HTH, Frank Hmm... could you send us the output of lsusb -v -d 1b80:e31d ? Thanks, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: HVR 900 (USB ID 2040:6500) no analogue sound reloaded
Am 22.08.2014 um 21:03 schrieb Oravecz Csaba: I reported this issue earlier but for some reason it went pretty much unnoticed. The essence is that with the newest em28xx drivers now present in 3.14 kernels (i'm on stock fedora 3.14.15-100.fc19.i686.PAE) I can't get analogue sound from this card. I see that the code snippet that produced this output in the pre 3.14 versions em2882/3 #0: Config register raw data: 0x50 em2882/3 #0: AC97 vendor ID = 0x em2882/3 #0: AC97 features = 0x6a90 em2882/3 #0: Empia 202 AC97 audio processor detected is still there in em28xx-core.c, however, there is nothing like that in current kernel logs so it seems that this part of the code is just skipped, which I tend to think is not the intended behaviour. I have not gone any further to investigate the issue, rather I've simply copied the 'old' em28xx directory over the current one in the latest source and compiled the drivers in this way and so got back the old em28xx version, which is working well in the current kernel as well. I don't consider this an optimal solution so I would very much appreciate any help in this issue. best, o.cs. Thank you for reporting this issue. I suspect reverting commit b99f0aadd3 [media] em28xx: check if a device has audio earlier will resolve it. Can you check that ? Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] em28xx: fix compiler warnings
Am 09.08.2014 um 11:58 schrieb Hans Verkuil: On 08/07/2014 06:36 PM, Frank Schäfer wrote: Am 07.08.2014 um 08:45 schrieb Hans Verkuil: On 08/05/2014 05:18 PM, Frank Schäfer wrote: Hi Hans, Am 05.08.2014 um 09:00 schrieb Hans Verkuil: Fix three compiler warnings: drivers/media/usb/em28xx/em28xx-input.c: In function ‘em28xx_i2c_ir_handle_key’: drivers/media/usb/em28xx/em28xx-input.c:318:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ CC [M] drivers/media/usb/em28xx/em28xx-dvb.o drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_micron’: drivers/media/usb/em28xx/em28xx-camera.c:199:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_omnivision’: drivers/media/usb/em28xx/em28xx-camera.c:304:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ Hmmm... I don't get these weird warnings. How can I reproduce them ? I'm using gcc 4.9.1 and I'm compiling the kernel using just a regular make command. In my .config I have CONFIG_FRAME_WARN=1024. Weird. With gcc version 4.8.1 20130909 [gcc-4_8-branch revision 202388] I get much smaller frame sizes: Are you compiling for 32 or 64 bits? I'm compiling for 64 bits. Ah yes, it was a 32 bit kernel. With a 64 bit kernel I get frame sizes of 736-744 bytes. Hmm... still much smaller than the 1088-1096 bytes gcc 4.9.1 reports... ... drivers/media/usb/em28xx/em28xx-input.c: In function ‘em28xx_i2c_ir_handle_key’: drivers/media/usb/em28xx/em28xx-input.c:318:1: warning: the frame size of 424 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_micron’: drivers/media/usb/em28xx/em28xx-camera.c:199:1: warning: the frame size of 432 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_omnivision’: drivers/media/usb/em28xx/em28xx-camera.c:304:1: warning: the frame size of 428 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... [...] 2.) i2c rc key polling: em28xx_i2c_ir_handle_key() passes the client structure to one of the 4 get_key functions rc = ir-get_key_i2c(client, protocol, scancode); which either call i2c_transfer(client-adapter, msg, len) directly or the helper function i2c_master_recv(client, buf, len)) which creates an i2c message before calling i2c_transfer(). The only members used from the i2c_client struct are msg.addr = client-addr; msg.flags = client-flags I2C_M_TEN; So the only fields from struct i2c_client which need to be setup are adapter and addr and flags. Adapter an addres are initialized properly to client.adapter = ir-dev-i2c_adap[dev-def_i2c_bus]; client.addr = ir-i2c_dev_addr; The only thing which is indeed missing here and needs to be fixed is client.flags = 0; Are there no debugging calls that use client.name? No, only adpater, address and flags are required/used for an i2c_transfer(). Basically what I don't understand is why this isn't a proper i2c_client, registered and all and in its proper place in the /sys/ hierarchy. It feels very much like a quick hack. The ir i2c decoder is indeed a pure em28xx internal thing. No external client driver is used. Hence the code is straight forward. The only benefit of registering an i2c_client would be to make it available via sysfs. I'm not sure If it's worth the amount of extra work+code. And if nothing else, at least zero the struct before use. That will make any problems that this hack causes reproducible instead of dependent on whatever random values were on the stack. The only problem here is the missing initialization of field flags. It's a bug that needs to be fixed. Fortunately it doesn't cause any trouble. In general, if structs with optional fields are used, the reader of the code easily gets the feeling that something might be missing. I know what I'm talking about... ;-) A patch is in the works. Regards, Frank Regards, Hans -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] em28xx-input: i2c IR decoders: improve i2c_client handling
Instead of using a temporary stack allocated i2c_client in em28xx_i2c_ir_handle_key(), allocate/free the i2c_client at module init/uninit and hook it into struct em28xx_IR (if the device has an i2c IR decoder). This reduces the frame size of function em28xx_i2c_ir_handle_key() and speeds it up a bit. Also make sure that all fields of struct i2c_client are initialized properly. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-input.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index ed843bd..962446a 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -71,8 +71,7 @@ struct em28xx_IR { unsigned int last_readcount; u64 rc_type; - /* i2c slave address of external device (if used) */ - u16 i2c_dev_addr; + struct i2c_client *i2c_client; int (*get_key_i2c)(struct i2c_client *ir, enum rc_type *protocol, u32 *scancode); int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); @@ -294,16 +293,11 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) { - struct em28xx *dev = ir-dev; static u32 scancode; enum rc_type protocol; int rc; - struct i2c_client client; - - client.adapter = ir-dev-i2c_adap[dev-def_i2c_bus]; - client.addr = ir-i2c_dev_addr; - rc = ir-get_key_i2c(client, protocol, scancode); + rc = ir-get_key_i2c(ir-i2c_client, protocol, scancode); if (rc 0) { dprintk(ir-get_key_i2c() failed: %d\n, rc); return rc; @@ -361,7 +355,7 @@ static void em28xx_ir_work(struct work_struct *work) { struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work); - if (ir-i2c_dev_addr) /* external i2c device */ + if (ir-i2c_client) /* external i2c device */ em28xx_i2c_ir_handle_key(ir); else /* internal device */ em28xx_ir_handle_key(ir); @@ -756,7 +750,13 @@ static int em28xx_ir_init(struct em28xx *dev) goto error; } - ir-i2c_dev_addr = i2c_rc_dev_addr; + ir-i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!ir-i2c_client) + goto error; + ir-i2c_client-adapter = ir-dev-i2c_adap[dev-def_i2c_bus]; + ir-i2c_client-addr = i2c_rc_dev_addr; + ir-i2c_client-flags = 0; + /* NOTE: all other fields of i2c_client are unused */ } else {/* internal device */ switch (dev-chip_id) { case CHIP_ID_EM2860: @@ -815,6 +815,7 @@ static int em28xx_ir_init(struct em28xx *dev) return 0; error: + kfree(ir-i2c_client); dev-ir = NULL; rc_free_device(rc); kfree(ir); @@ -841,6 +842,8 @@ static int em28xx_ir_fini(struct em28xx *dev) if (ir-rc) rc_unregister_device(ir-rc); + kfree(ir-i2c_client); + /* done */ kfree(ir); dev-ir = NULL; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] em28xx-v4l: fix video buffer field order reporting in progressive mode
The correct field order in progressive mode is V4L2_FIELD_NONE, not V4L2_FIELD_INTERLACED. Cc: sta...@vger.kernel.org Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 9db219d..f6cf99f 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -435,7 +435,10 @@ static inline void finish_buffer(struct em28xx *dev, em28xx_isocdbg([%p/%d] wakeup\n, buf, buf-top_field); buf-vb.v4l2_buf.sequence = dev-v4l2-field_count++; - buf-vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; + if (dev-v4l2-progressive) + buf-vb.v4l2_buf.field = V4L2_FIELD_NONE; + else + buf-vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; v4l2_get_timestamp(buf-vb.v4l2_buf.timestamp); vb2_buffer_done(buf-vb, VB2_BUF_STATE_DONE); -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] em28xx-v4l: give back all active video buffers to the vb2 core properly on streaming stop
When a new video frame is started, the driver takes the next video buffer from the list of active buffers and moves it to dev-usb_ctl.vid_buf / dev-usb_ctl.vbi_buf for further processing. On streaming stop we currently only give back the pending buffers from the list but not the ones which are currently processed. This causes the following warning from the vb2 core since kernel 3.15: ... [ cut here ] WARNING: CPU: 1 PID: 2284 at drivers/media/v4l2-core/videobuf2-core.c:2115 __vb2_queue_cancel+0xed/0x150 [videobuf2_core]() [...] Call Trace: [c0769c46] dump_stack+0x48/0x69 [c0245b69] warn_slowpath_common+0x79/0x90 [f925e4ad] ? __vb2_queue_cancel+0xed/0x150 [videobuf2_core] [f925e4ad] ? __vb2_queue_cancel+0xed/0x150 [videobuf2_core] [c0245bfd] warn_slowpath_null+0x1d/0x20 [f925e4ad] __vb2_queue_cancel+0xed/0x150 [videobuf2_core] [f925fa35] vb2_internal_streamoff+0x35/0x90 [videobuf2_core] [f925fac5] vb2_streamoff+0x35/0x60 [videobuf2_core] [f925fb27] vb2_ioctl_streamoff+0x37/0x40 [videobuf2_core] [f8e45895] v4l_streamoff+0x15/0x20 [videodev] [f8e4925d] __video_do_ioctl+0x23d/0x2d0 [videodev] [f8e49020] ? video_ioctl2+0x20/0x20 [videodev] [f8e48c63] video_usercopy+0x203/0x5a0 [videodev] [f8e49020] ? video_ioctl2+0x20/0x20 [videodev] [c039d0e7] ? fsnotify+0x1e7/0x2b0 [f8e49012] video_ioctl2+0x12/0x20 [videodev] [f8e49020] ? video_ioctl2+0x20/0x20 [videodev] [f8e4461e] v4l2_ioctl+0xee/0x130 [videodev] [f8e44530] ? v4l2_open+0xf0/0xf0 [videodev] [c0378de2] do_vfs_ioctl+0x2e2/0x4d0 [c0368eec] ? vfs_write+0x13c/0x1c0 [c0369a8f] ? vfs_writev+0x2f/0x50 [c0379028] SyS_ioctl+0x58/0x80 [c076fff3] sysenter_do_call+0x12/0x12 ---[ end trace 5545f934409f13f4 ]--- ... Many thanks to Hans Verkuil, whose recently added check in the vb2 core unveiled this long standing issue and who has investigated it further. Cc: sta...@vger.kernel.org Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 90dec29..9db219d 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -994,13 +994,16 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) } spin_lock_irqsave(dev-slock, flags); + if (dev-usb_ctl.vid_buf != NULL) { + vb2_buffer_done(dev-usb_ctl.vid_buf-vb, VB2_BUF_STATE_ERROR); + dev-usb_ctl.vid_buf = NULL; + } while (!list_empty(vidq-active)) { struct em28xx_buffer *buf; buf = list_entry(vidq-active.next, struct em28xx_buffer, list); list_del(buf-list); vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR); } - dev-usb_ctl.vid_buf = NULL; spin_unlock_irqrestore(dev-slock, flags); } @@ -1021,13 +1024,16 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq) } spin_lock_irqsave(dev-slock, flags); + if (dev-usb_ctl.vbi_buf != NULL) { + vb2_buffer_done(dev-usb_ctl.vbi_buf-vb, VB2_BUF_STATE_ERROR); + dev-usb_ctl.vbi_buf = NULL; + } while (!list_empty(vbiq-active)) { struct em28xx_buffer *buf; buf = list_entry(vbiq-active.next, struct em28xx_buffer, list); list_del(buf-list); vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR); } - dev-usb_ctl.vbi_buf = NULL; spin_unlock_irqrestore(dev-slock, flags); } -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] em28xx: fix compiler warnings
Am 07.08.2014 um 08:45 schrieb Hans Verkuil: On 08/05/2014 05:18 PM, Frank Schäfer wrote: Hi Hans, Am 05.08.2014 um 09:00 schrieb Hans Verkuil: Fix three compiler warnings: drivers/media/usb/em28xx/em28xx-input.c: In function ‘em28xx_i2c_ir_handle_key’: drivers/media/usb/em28xx/em28xx-input.c:318:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ CC [M] drivers/media/usb/em28xx/em28xx-dvb.o drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_micron’: drivers/media/usb/em28xx/em28xx-camera.c:199:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_omnivision’: drivers/media/usb/em28xx/em28xx-camera.c:304:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ Hmmm... I don't get these weird warnings. How can I reproduce them ? I'm using gcc 4.9.1 and I'm compiling the kernel using just a regular make command. In my .config I have CONFIG_FRAME_WARN=1024. Weird. With gcc version 4.8.1 20130909 [gcc-4_8-branch revision 202388] I get much smaller frame sizes: ... drivers/media/usb/em28xx/em28xx-input.c: In function ‘em28xx_i2c_ir_handle_key’: drivers/media/usb/em28xx/em28xx-input.c:318:1: warning: the frame size of 424 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_micron’: drivers/media/usb/em28xx/em28xx-camera.c:199:1: warning: the frame size of 432 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_omnivision’: drivers/media/usb/em28xx/em28xx-camera.c:304:1: warning: the frame size of 428 bytes is larger than 256 bytes [-Wframe-larger-than=] } ^ ... Anyway, I really don't think a framesize of 1096 is a problem. Note: there is no way the code in em28xx_i2c_ir_handle_key() is correct: it's using an almost completely uninitialized i2c_client struct with random flags, dev and name fields. Can't this turned into a proper i2c_client struct in struct em28xx? At least with this patch it's no longer random data. Why do you think the client setup is random ? Well, this is the code: struct i2c_client client; client.adapter = ir-dev-i2c_adap[dev-def_i2c_bus]; client.addr = ir-i2c_dev_addr; All other fields of the client struct are undefined, but it is used as is. That can't be right. With my patch the i2c_client is either that that was used by the probe, or it is all zero. Which is still better than having random values. Take a closer look at the code: 1.) sensor probing: struct i2c_client client = dev-i2c_client[dev-def_i2c_bus]; dev-i2c_client[bus] is initialized on bus registration in em28xx_i2c_register(): dev-i2c_client[bus] = em28xx_client_template; dev-i2c_client[bus].adapter = dev-i2c_adap[bus]; em28xx_client_template is defined static: static struct i2c_client em28xx_client_template = { .name = em28xx internal, }; So nothing is random or undefined here. 2.) i2c rc key polling: em28xx_i2c_ir_handle_key() passes the client structure to one of the 4 get_key functions rc = ir-get_key_i2c(client, protocol, scancode); which either call i2c_transfer(client-adapter, msg, len) directly or the helper function i2c_master_recv(client, buf, len)) which creates an i2c message before calling i2c_transfer(). The only members used from the i2c_client struct are msg.addr = client-addr; msg.flags = client-flags I2C_M_TEN; So the only fields from struct i2c_client which need to be setup are adapter and addr and flags. Adapter an addres are initialized properly to client.adapter = ir-dev-i2c_adap[dev-def_i2c_bus]; client.addr = ir-i2c_dev_addr; The only thing which is indeed missing here and needs to be fixed is client.flags = 0; Which fields do you think are wrong ? AFAICS this patch doesn't change any fields. What's wrong with using local i2c_client variables ? Nothing, except that they take a lot of stack space which the compiler complains about. Well, it warns because you are forcing a warning. The stack in the kernel is limited, so this should be avoided. Limited to what ? 8k ? So what's the problem ? Indeed, the way the driver currently tracks i2c clients / subdevices is ... let's say improvable. But IMHO, we should go the opposite direction and get rid of the i2c_clients in the main device struct. They are in fact just temporary helpers and dangerous to use with devices with multiple i2c clients on the same bus. Feel free to find another solution, but allocating i2c_client structs on the stack is not the right solution. Putting temporary helper variables which are even unused by most devices into the main device struct is definitely is the wrong
Re: [PATCH] em28xx: fix compiler warnings
Hi Hans, Am 05.08.2014 um 09:00 schrieb Hans Verkuil: Fix three compiler warnings: drivers/media/usb/em28xx/em28xx-input.c: In function ‘em28xx_i2c_ir_handle_key’: drivers/media/usb/em28xx/em28xx-input.c:318:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ CC [M] drivers/media/usb/em28xx/em28xx-dvb.o drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_micron’: drivers/media/usb/em28xx/em28xx-camera.c:199:1: warning: the frame size of 1096 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ drivers/media/usb/em28xx/em28xx-camera.c: In function ‘em28xx_probe_sensor_omnivision’: drivers/media/usb/em28xx/em28xx-camera.c:304:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=] } ^ Hmmm... I don't get these weird warnings. How can I reproduce them ? Note: there is no way the code in em28xx_i2c_ir_handle_key() is correct: it's using an almost completely uninitialized i2c_client struct with random flags, dev and name fields. Can't this turned into a proper i2c_client struct in struct em28xx? At least with this patch it's no longer random data. Why do you think the client setup is random ? Which fields do you think are wrong ? AFAICS this patch doesn't change any fields. What's wrong with using local i2c_client variables ? Indeed, the way the driver currently tracks i2c clients / subdevices is ... let's say improvable. But IMHO, we should go the opposite direction and get rid of the i2c_clients in the main device struct. They are in fact just temporary helpers and dangerous to use with devices with multiple i2c clients on the same bus. Regards, Frank Signed-off-by: Hans Verkuil hans.verk...@cisco.com diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 6d2ea9a..c8490ba 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -110,40 +110,40 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) __be16 id_be; u16 id; - struct i2c_client client = dev-i2c_client[dev-def_i2c_bus]; + dev-tmp_i2c_client = dev-i2c_client[dev-def_i2c_bus]; dev-em28xx_sensor = EM28XX_NOSENSOR; for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { - client.addr = micron_sensor_addrs[i]; + dev-tmp_i2c_client.addr = micron_sensor_addrs[i]; /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */ /* Read chip ID from register 0x00 */ reg = 0x00; - ret = i2c_master_send(client, reg, 1); + ret = i2c_master_send(dev-tmp_i2c_client, reg, 1); if (ret 0) { if (ret != -ENXIO) em28xx_errdev(couldn't read from i2c device 0x%02x: error %i\n, - client.addr 1, ret); + dev-tmp_i2c_client.addr 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)id_be, 2); + ret = i2c_master_recv(dev-tmp_i2c_client, (u8 *)id_be, 2); if (ret 0) { em28xx_errdev(couldn't read from i2c device 0x%02x: error %i\n, - client.addr 1, ret); + dev-tmp_i2c_client.addr 1, ret); continue; } id = be16_to_cpu(id_be); /* Read chip ID from register 0xff */ reg = 0xff; - ret = i2c_master_send(client, reg, 1); + ret = i2c_master_send(dev-tmp_i2c_client, reg, 1); if (ret 0) { em28xx_errdev(couldn't read from i2c device 0x%02x: error %i\n, - client.addr 1, ret); + dev-tmp_i2c_client.addr 1, ret); continue; } - ret = i2c_master_recv(client, (u8 *)id_be, 2); + ret = i2c_master_recv(dev-tmp_i2c_client, (u8 *)id_be, 2); if (ret 0) { em28xx_errdev(couldn't read from i2c device 0x%02x: error %i\n, - client.addr 1, ret); + dev-tmp_i2c_client.addr 1, ret); continue; } /* Validate chip ID to be sure we have a Micron device */ @@ -191,7 +191,7 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) else em28xx_info(sensor %s detected\n, name); - dev-i2c_client[dev-def_i2c_bus].addr = client.addr; + dev-i2c_client[dev-def_i2c_bus].addr = dev-tmp_i2c_client.addr; return 0; } @@ -207,28 +207,29 @@ static
Re: em28xx vb2 warnings
Am 28.07.2014 um 17:27 schrieb Hans Verkuil: ... OK, I looked at it: the problem is in get_next_buf() and finish_field_prepare_next(). In get_next_buf() the driver gets a buffer from the active list and deletes it from that list. In finish_field_prepare_next() that buffer is given back to vb2 via finish_buffer(). But if you stop streaming and em28xx_stop_streaming() is called, then that buffer that is being processed isn't part of the active list anymore and so it is never given back. em28xx_stop_streaming() should give that buffer back as well, and that will keep everything in balance. The easiest solution seems to be to move the list_del() call from get_next_buf() to finish_buffer(). It seemed to work in a quick test, but I haven't looked at vbi support or corner cases. I leave that to you :-) Ok, thank you so far Hans ! I will see what I can do. Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: em28xx vb2 warnings
Am 25.07.2014 21:07, schrieb Hans Verkuil: On 07/25/2014 06:20 PM, Frank Schäfer wrote: Hi Hans, I'm getting the following warnings with the em28xx driver on streaming stop: [ 7597.346168] WARNING: CPU: 1 PID: 3730 at drivers/media/v4l2-core/videobuf2-core.c:2126 __vb2_queue_cancel+0xf5/0x150 [videobuf2_core]() [ 7597.346171] Modules linked in: em28xx_rc snd_usb_audio ov2640 soc_camera soc_mediabus em28xx_v4l videobuf2_core videobuf2_vmalloc videobuf2_memops snd_usbmidi_lib snd_rawmidi em28xx xt_pkttype xt_LOG xt_limit bnep af_packet bluetooth ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables rc_hauppauge ir_kbd_i2c arc4 tuner_simple tuner_types rtl8187 mac80211 tda9887 fuse tda8290 snd_hda_codec_analog tuner snd_hda_codec_hdmi snd_hda_codec_generic sr_mod cdrom snd_hda_intel snd_hda_controller snd_hda_codec msp3400 snd_hwdep cfg80211 bttv snd_pcm v4l2_common snd_seq ppdev powernow_k8 [ 7597.346230] snd_timer snd_seq_device pcspkr videodev serio_raw snd firewire_ohci firewire_core k8temp rfkill eeprom_93cx6 i2c_nforce2 usb_storage videobuf_dma_sg videobuf_core btcx_risc pata_jmicron rc_core usblp soundcore forcedeth crc_itu_t tveeprom ata_generic floppy sata_nv pata_amd asus_atk0110 parport_pc parport button sg dm_mod autofs4 radeon ttm drm_kms_helper drm fan thermal processor thermal_sys i2c_algo_bit scsi_dh_hp_sw scsi_dh_emc scsi_dh_rdac scsi_dh_alua scsi_dh [ 7597.346268] CPU: 1 PID: 3730 Comm: qv4l2 Tainted: GW 3.16.0-rc6-0.1-desktop+ #18 [ 7597.346271] Hardware name: System manufacturer System Product Name [...] [ 7597.346273] e09d9d3c c0780b62 e09d9d6c c0243359 c091deec [ 7597.346279] 0001 0e92 f870a4a4 084e f87054e5 f87054e5 e6905040 e2f61640 [ 7597.346285] ef85f4c8 e09d9d7c c02433ed 0009 e09d9d94 f87054e5 e2ef6550 [ 7597.346290] Call Trace: [ 7597.346300] [c0780b62] dump_stack+0x48/0x69 [ 7597.346305] [c0243359] warn_slowpath_common+0x79/0x90 [ 7597.346312] [f87054e5] ? __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346318] [f87054e5] ? __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346322] [c02433ed] warn_slowpath_null+0x1d/0x20 [ 7597.346327] [f87054e5] __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346333] [f8706b35] vb2_internal_streamoff+0x35/0x90 [videobuf2_core] [ 7597.346338] [c04b7cbb] ? _copy_from_user+0x3b/0x50 [ 7597.346344] [f8706bc5] vb2_streamoff+0x35/0x60 [videobuf2_core] [ 7597.346350] [c0699433] ? __sys_recvmsg+0x43/0x70 [ 7597.346356] [f8706c27] vb2_ioctl_streamoff+0x37/0x40 [videobuf2_core] [ 7597.346371] [f7c56805] v4l_streamoff+0x15/0x20 [videodev] [ 7597.346382] [f7c5962c] __video_do_ioctl+0x1fc/0x280 [videodev] [ 7597.346394] [f7c5908e] video_usercopy+0x1ce/0x550 [videodev] [ 7597.346399] [c038aac7] ? fsnotify+0x1e7/0x2b0 [ 7597.346410] [f7c59422] video_ioctl2+0x12/0x20 [videodev] [ 7597.346421] [f7c59430] ? video_ioctl2+0x20/0x20 [videodev] [ 7597.346430] [f7c55615] v4l2_ioctl+0xe5/0x120 [videodev] [ 7597.346439] [f7c55530] ? v4l2_open+0xf0/0xf0 [videodev] [ 7597.346443] [c03668e2] do_vfs_ioctl+0x2e2/0x4d0 [ 7597.346449] [c0356a3c] ? vfs_write+0x13c/0x1c0 [ 7597.346452] [c03575df] ? vfs_writev+0x2f/0x50 [ 7597.346455] [c0366b28] SyS_ioctl+0x58/0x80 [ 7597.346460] [c07870ec] sysenter_do_call+0x12/0x16 [ 7597.346463] ---[ end trace 16421a251cba8f63 ]--- There have been quite a few vb2 changes recently. Any idea what's wrong ? Could you take a look at this ? What it means is that the driver appears not to have given back all buffers to the vb2 core. I do see that this doesn't happen in start_streaming if an error occurs there (queued buffers should be returned to state DEQUEUED in that case), but stop_streaming seems to return it perfectly fine. If in your test case start_streaming failed, then that would explain it. No, streaming start doesn't fail. The test case is simple: start qv4l2, start streaming, stop streaming. Enable the VIDEO_ADV_DEBUG config option which will dump an overview of the vb2 ops: mismatched counts should be reported. I also enabled em28xx core_debug: ... [ 165.248346] usbcore: registered new interface driver em28xx [ 170.832072] usb 1-8: new high-speed USB device number 7 using ehci-pci [ 170.950968] usb 1-8: New USB device found, idVendor=2040, idProduct=4200 [ 170.950974] usb 1-8: New USB device strings: Mfr=0, Product=1, SerialNumber=2 [ 170.950976] usb 1-8: Product: WinTV USB2 [ 170.950979] usb 1-8: SerialNumber: 00 [ 170.952094] em28xx: New device WinTV USB2 @ 480 Mbps (2040:4200, interface 0, class 0) [ 170.952098] em28xx: Video interface 0 found: bulk isoc [ 170.952212] em28xx: chip ID is em2840 [ 171.048588
Re: [PATCH for v3.17] v4l2-ctrls: fix rounding calculation
Am 26.07.2014 18:02, schrieb Hans Verkuil: Commit 958c7c7e65 ([media] v4l2-ctrls: fix corner case in round-to-range code) broke controls that use a negative range. The cause was a s32/u32 mixup: ctrl-step is unsigned while all others are signed. So the result type of the expression '(ctrl)-maximum - ((ctrl)-step / 2)' became unsigned, making 'val = (ctrl)-maximum - ((ctrl)-step / 2)' true, since '((u32)-128) 128' (if val = -128, maximum = 128 and step = 1). So carefully cast (step / 2) to s32. There was one cast of step to s32 where it should have been u32 because both offset and step are unsigned, so casting to signed makes no sense there. You do need a cast to u32 there, because otherwise architectures that have no 64-bit division start complaining (step is a u64). Signed-off-by: Hans Verkuil hans.verk...@cisco.com Reported-by: Frank Schäfer fschaefer@googlemail.com diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 2d8ced8..9d0c7a1 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1347,14 +1347,14 @@ static void std_log(const struct v4l2_ctrl *ctrl) ({ \ offset_type offset; \ if ((ctrl)-maximum = 0 \ - val = (ctrl)-maximum - ((ctrl)-step / 2))\ + val = (ctrl)-maximum - (s32)((ctrl)-step / 2)) \ val = (ctrl)-maximum; \ else\ - val += (ctrl)-step / 2;\ + val += (s32)((ctrl)-step / 2); \ val = clamp_t(typeof(val), val, \ (ctrl)-minimum, (ctrl)-maximum);\ offset = (val) - (ctrl)-minimum; \ - offset = (ctrl)-step * (offset / (s32)(ctrl)-step); \ + offset = (ctrl)-step * (offset / (u32)(ctrl)-step); \ val = (ctrl)-minimum + offset; \ 0; \ }) @@ -1376,10 +1376,10 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, * the u64 divide that needs special care. */ val = ptr.p_s64[idx]; - if (ctrl-maximum = 0 val = ctrl-maximum - ctrl-step / 2) + if (ctrl-maximum = 0 val = ctrl-maximum - (s64)(ctrl-step / 2)) val = ctrl-maximum; else - val += ctrl-step / 2; + val += (s64)(ctrl-step / 2); val = clamp_t(s64, val, ctrl-minimum, ctrl-maximum); offset = val - ctrl-minimum; do_div(offset, ctrl-step); Tested-by: Frank Schäfer fschaefer@googlemail.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
em28xx vb2 warnings
Hi Hans, I'm getting the following warnings with the em28xx driver on streaming stop: [ 7597.346168] WARNING: CPU: 1 PID: 3730 at drivers/media/v4l2-core/videobuf2-core.c:2126 __vb2_queue_cancel+0xf5/0x150 [videobuf2_core]() [ 7597.346171] Modules linked in: em28xx_rc snd_usb_audio ov2640 soc_camera soc_mediabus em28xx_v4l videobuf2_core videobuf2_vmalloc videobuf2_memops snd_usbmidi_lib snd_rawmidi em28xx xt_pkttype xt_LOG xt_limit bnep af_packet bluetooth ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables rc_hauppauge ir_kbd_i2c arc4 tuner_simple tuner_types rtl8187 mac80211 tda9887 fuse tda8290 snd_hda_codec_analog tuner snd_hda_codec_hdmi snd_hda_codec_generic sr_mod cdrom snd_hda_intel snd_hda_controller snd_hda_codec msp3400 snd_hwdep cfg80211 bttv snd_pcm v4l2_common snd_seq ppdev powernow_k8 [ 7597.346230] snd_timer snd_seq_device pcspkr videodev serio_raw snd firewire_ohci firewire_core k8temp rfkill eeprom_93cx6 i2c_nforce2 usb_storage videobuf_dma_sg videobuf_core btcx_risc pata_jmicron rc_core usblp soundcore forcedeth crc_itu_t tveeprom ata_generic floppy sata_nv pata_amd asus_atk0110 parport_pc parport button sg dm_mod autofs4 radeon ttm drm_kms_helper drm fan thermal processor thermal_sys i2c_algo_bit scsi_dh_hp_sw scsi_dh_emc scsi_dh_rdac scsi_dh_alua scsi_dh [ 7597.346268] CPU: 1 PID: 3730 Comm: qv4l2 Tainted: GW 3.16.0-rc6-0.1-desktop+ #18 [ 7597.346271] Hardware name: System manufacturer System Product Name [...] [ 7597.346273] e09d9d3c c0780b62 e09d9d6c c0243359 c091deec [ 7597.346279] 0001 0e92 f870a4a4 084e f87054e5 f87054e5 e6905040 e2f61640 [ 7597.346285] ef85f4c8 e09d9d7c c02433ed 0009 e09d9d94 f87054e5 e2ef6550 [ 7597.346290] Call Trace: [ 7597.346300] [c0780b62] dump_stack+0x48/0x69 [ 7597.346305] [c0243359] warn_slowpath_common+0x79/0x90 [ 7597.346312] [f87054e5] ? __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346318] [f87054e5] ? __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346322] [c02433ed] warn_slowpath_null+0x1d/0x20 [ 7597.346327] [f87054e5] __vb2_queue_cancel+0xf5/0x150 [videobuf2_core] [ 7597.346333] [f8706b35] vb2_internal_streamoff+0x35/0x90 [videobuf2_core] [ 7597.346338] [c04b7cbb] ? _copy_from_user+0x3b/0x50 [ 7597.346344] [f8706bc5] vb2_streamoff+0x35/0x60 [videobuf2_core] [ 7597.346350] [c0699433] ? __sys_recvmsg+0x43/0x70 [ 7597.346356] [f8706c27] vb2_ioctl_streamoff+0x37/0x40 [videobuf2_core] [ 7597.346371] [f7c56805] v4l_streamoff+0x15/0x20 [videodev] [ 7597.346382] [f7c5962c] __video_do_ioctl+0x1fc/0x280 [videodev] [ 7597.346394] [f7c5908e] video_usercopy+0x1ce/0x550 [videodev] [ 7597.346399] [c038aac7] ? fsnotify+0x1e7/0x2b0 [ 7597.346410] [f7c59422] video_ioctl2+0x12/0x20 [videodev] [ 7597.346421] [f7c59430] ? video_ioctl2+0x20/0x20 [videodev] [ 7597.346430] [f7c55615] v4l2_ioctl+0xe5/0x120 [videodev] [ 7597.346439] [f7c55530] ? v4l2_open+0xf0/0xf0 [videodev] [ 7597.346443] [c03668e2] do_vfs_ioctl+0x2e2/0x4d0 [ 7597.346449] [c0356a3c] ? vfs_write+0x13c/0x1c0 [ 7597.346452] [c03575df] ? vfs_writev+0x2f/0x50 [ 7597.346455] [c0366b28] SyS_ioctl+0x58/0x80 [ 7597.346460] [c07870ec] sysenter_do_call+0x12/0x16 [ 7597.346463] ---[ end trace 16421a251cba8f63 ]--- There have been quite a few vb2 changes recently. Any idea what's wrong ? Could you take a look at this ? Regards, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] em28xx-v4l: get rid of field users in struct em28xx_v4l2
Instead of counting the number of opened file handles, use function v4l2_fh_is_singular_file() in em28xx_v4l2_open() and em28xx_v4l2_close() to determine if the file handle is the first/last opened one. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 23 +-- drivers/media/usb/em28xx/em28xx.h | 1 - 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3a7ec3b..087ccf9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1883,9 +1883,8 @@ static int em28xx_v4l2_open(struct file *filp) return -EINVAL; } - em28xx_videodbg(open dev=%s type=%s users=%d\n, - video_device_node_name(vdev), v4l2_type_names[fh_type], - v4l2-users); + em28xx_videodbg(open dev=%s type=%s\n, + video_device_node_name(vdev), v4l2_type_names[fh_type]); if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; @@ -1898,7 +1897,9 @@ static int em28xx_v4l2_open(struct file *filp) return ret; } - if (v4l2-users == 0) { + if (v4l2_fh_is_singular_file(filp)) { + em28xx_videodbg(first opened filehandle, initializing device\n); + em28xx_set_mode(dev, EM28XX_ANALOG_MODE); if (vdev-vfl_type != VFL_TYPE_RADIO) @@ -1909,6 +1910,8 @@ static int em28xx_v4l2_open(struct file *filp) * of some i2c devices */ em28xx_wake_i2c(dev); + } else { + em28xx_videodbg(further filehandles are already opened\n); } if (vdev-vfl_type == VFL_TYPE_RADIO) { @@ -1918,7 +1921,6 @@ static int em28xx_v4l2_open(struct file *filp) kref_get(dev-ref); kref_get(v4l2-ref); - v4l2-users++; mutex_unlock(dev-lock); @@ -2025,12 +2027,11 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx_v4l2*v4l2 = dev-v4l2; int errCode; - em28xx_videodbg(users=%d\n, v4l2-users); - - vb2_fop_release(filp); mutex_lock(dev-lock); - if (v4l2-users == 1) { + if (v4l2_fh_is_singular_file(filp)) { + em28xx_videodbg(last opened filehandle, shutting down device\n); + /* No sense to try to write to the device */ if (dev-disconnected) goto exit; @@ -2049,10 +2050,12 @@ static int em28xx_v4l2_close(struct file *filp) em28xx_errdev(cannot change alternate number to 0 (error=%i)\n, errCode); } + } else { + em28xx_videodbg(further opened filehandles left\n); } exit: - v4l2-users--; + vb2_fop_release(filp); kref_put(v4l2-ref, em28xx_free_v4l2); mutex_unlock(dev-lock); kref_put(dev-ref, em28xx_free_device); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 4360338..84ef8ef 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -524,7 +524,6 @@ struct em28xx_v4l2 { int sensor_yres; int sensor_xtal; - int users; /* user count for exclusive use */ int streaming_users;/* number of actively streaming users */ u32 frequency; /* selected tuner frequency */ -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] em28xx-v4l: simplify em28xx_v4l2_open() by using v4l2_fh_open()
Instead of calling ... struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); filp-private_data = fh; v4l2_fh_init(fh, vdev); v4l2_fh_add(fh); ... simply use function v4l2_fh_open() which does all of these calls for us. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 4eb4a6a..3a7ec3b 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1868,7 +1868,7 @@ static int em28xx_v4l2_open(struct file *filp) struct em28xx *dev = video_drvdata(filp); struct em28xx_v4l2 *v4l2 = dev-v4l2; enum v4l2_buf_type fh_type = 0; - struct v4l2_fh *fh; + int ret; switch (vdev-vfl_type) { case VFL_TYPE_GRABBER: @@ -1889,14 +1889,14 @@ static int em28xx_v4l2_open(struct file *filp) if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; - fh = kzalloc(sizeof(struct v4l2_fh), GFP_KERNEL); - if (!fh) { - em28xx_errdev(em28xx-video.c: Out of memory?!\n); + + ret = v4l2_fh_open(filp); + if (ret) { + em28xx_errdev(%s: v4l2_fh_open() returned error %d\n, + __func__, ret); mutex_unlock(dev-lock); - return -ENOMEM; + return ret; } - v4l2_fh_init(fh, vdev); - filp-private_data = fh; if (v4l2-users == 0) { em28xx_set_mode(dev, EM28XX_ANALOG_MODE); @@ -1921,7 +1921,6 @@ static int em28xx_v4l2_open(struct file *filp) v4l2-users++; mutex_unlock(dev-lock); - v4l2_fh_add(fh); return 0; } -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] some em28xx-v4l cleanup patches
This patch series consists of 4 cleanup patches for the em28xx-v4l module. Frank Schäfer (4): em28xx-v4l: simplify some pointers in em28xx_init_camera() em28xx-v4l: get rid of struct em28xx_fh em28xx-v4l: simplify em28xx_v4l2_open() by using v4l2_fh_open() em28xx-v4l: get rid of field users in struct em28xx_v4l2 drivers/media/usb/em28xx/em28xx-camera.c | 4 +- drivers/media/usb/em28xx/em28xx-video.c | 113 --- drivers/media/usb/em28xx/em28xx.h| 8 --- 3 files changed, 47 insertions(+), 78 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] em28xx-v4l: simplify some pointers in em28xx_init_camera()
Pointer v4l2 can be used instead of dev-v4l2, which saves some characters. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-camera.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 12d4c03..6d2ea9a 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -366,7 +366,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2-sensor_xtal = 430; pdata.xtal = v4l2-sensor_xtal; if (NULL == - v4l2_i2c_new_subdev_board(dev-v4l2-v4l2_dev, adap, + v4l2_i2c_new_subdev_board(v4l2-v4l2_dev, adap, mt9v011_info, NULL)) { ret = -ENODEV; break; @@ -423,7 +423,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2-sensor_yres = 480; subdev = -v4l2_i2c_new_subdev_board(dev-v4l2-v4l2_dev, adap, +v4l2_i2c_new_subdev_board(v4l2-v4l2_dev, adap, ov2640_info, NULL); if (NULL == subdev) { ret = -ENODEV; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] em28xx-v4l: get rid of struct em28xx_fh
struct em28xx_fh isn't needed anymore because the only used field which is left is struct v4l2_fh fh. Use struct v4l2_fh directly and remvove struct em28xx_fh. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 83 - drivers/media/usb/em28xx/em28xx.h | 7 --- 2 files changed, 29 insertions(+), 61 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 3f8b5aa..4eb4a6a 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1227,8 +1227,7 @@ static void scale_to_size(struct em28xx *dev, static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2*v4l2 = dev-v4l2; f-fmt.pix.width = v4l2-width; @@ -1261,8 +1260,7 @@ static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct em28xx_fh *fh= priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2*v4l2 = dev-v4l2; unsigned int width = f-fmt.pix.width; unsigned int height = f-fmt.pix.height; @@ -1355,8 +1353,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); *norm = dev-v4l2-norm; @@ -1365,8 +1362,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); v4l2_device_call_all(dev-v4l2-v4l2_dev, 0, video, querystd, norm); @@ -1375,8 +1371,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev-v4l2; struct v4l2_format f; @@ -1408,8 +1403,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *p) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev-v4l2; int rc = 0; @@ -1427,8 +1421,7 @@ static int vidioc_g_parm(struct file *file, void *priv, static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *p) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); p-parm.capture.readbuffers = EM28XX_MIN_BUF; return v4l2_device_call_until_err(dev-v4l2-v4l2_dev, @@ -1450,8 +1443,7 @@ static const char *iname[] = { static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); unsigned int n; n = i-index; @@ -1479,8 +1471,7 @@ static int vidioc_enum_input(struct file *file, void *priv, static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); *i = dev-ctl_input; @@ -1489,8 +1480,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); if (i = MAX_EM28XX_INPUT) return -EINVAL; @@ -1503,8 +1493,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) { - struct em28xx_fh *fh= priv; - struct em28xx *dev = fh-dev; + struct em28xx *dev = video_drvdata(file); switch (a-index) { case EM28XX_AMUX_VIDEO: @@ -1543,8
[PATCH] em28xx-v4l: fix disabling ioctl VIDIOC_S_PARM for vbi devices
Fixes an old copy+paste bug that has survived all recent code changes in this code area. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 087ccf9..90dec29 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -2528,7 +2528,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2-vbi_dev-queue-lock = v4l2-vb_vbi_queue_lock; /* disable inapplicable ioctls */ - v4l2_disable_ioctl(v4l2-vdev, VIDIOC_S_PARM); + v4l2_disable_ioctl(v4l2-vbi_dev, VIDIOC_S_PARM); if (dev-tuner_type == TUNER_ABSENT) { v4l2_disable_ioctl(v4l2-vbi_dev, VIDIOC_G_TUNER); v4l2_disable_ioctl(v4l2-vbi_dev, VIDIOC_S_TUNER); -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
v4l2-ctrls: negative integer control values broken
Hans, sorry for bothering you with another issue on friday evening. :-/ But it seems that commit 958c7c7e65 ([media] v4l2-ctrls: fix corner case in round-to-range code) introduced a regression for controls which are using a negative integer value range. All negative values are mapped to the maximum (positive) value (check em28xx brightness, red and blue balance bridge controls for example). Reverting this commit makes them working again. At a first glance I can't find a mistake... Have a nice weekend, Frank -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: New v4l2 driver does not allow brightness/contrast control
Am 07.07.2014 19:58, schrieb Rafael Coutinho: I have a v4l2 video capture board that using kernel 2.6 with v4l2 em28xx driver 3.0.36 allows me to control brightness, contrast etc... However in kernel 3.2 with v4l2 em28xx driver version 3.2.0 it does not. This is what I get from the latest driver: root@android:/ # v4l2-ctl --info Driver Info (not using libv4l2): Driver name : em28xx Card type : EM2860/SAA711X Reference Design Bus info : usb-musb-hdrc.1-1 Driver version: 3.2.0 Capabilities : 0x05020051 Video Capture VBI Capture Sliced VBI Capture Audio Read/Write Streaming root@android:/ # v4l2-ctl -d 0 -l volume (int): min=0 max=31 step=1 default=31 value=31 flags=slider mute (bool) : default=1 value=1 What could be wrong? Before kernel 3.10, the brightness (contrast, ...) controls are provided by the subdevice drivers. With kernel 3.10 I have introduced bridge level image controls, but they are currently only used/activated if the subdevice doesn't already provide them (as suggested by Mauro). Hth, Frank Schäfer -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] em28xx: fix i2c_set_adapdata() call in em28xx_i2c_register()
Hi Hans, Am 09.05.2014 10:40, schrieb Hans Verkuil: Hi Frank, I've got a comment about this patch: On 03/22/2014 02:01 PM, Frank Schäfer wrote: Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index ba6433c..04e8577 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -939,7 +939,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, dev-i2c_bus[bus].algo_type = algo_type; dev-i2c_bus[bus].dev = dev; dev-i2c_adap[bus].algo_data = dev-i2c_bus[bus]; -i2c_set_adapdata(dev-i2c_adap[bus], dev-v4l2_dev); +i2c_set_adapdata(dev-i2c_adap[bus], dev); As far as I can see nobody is calling i2c_get_adapdata. Should this line be removed altogether? If it is used somewhere, can you point me that? Good catch. Indeed, nobody is using it anymore so it can removed instead. Drop this patch, I will send a new one in a minute. I'm taking the other patches from this series (using the v2 version of patch 4/5) since those look fine. Thanks ! Regards, Frank Regards, Hans retval = i2c_add_adapter(dev-i2c_adap[bus]); if (retval 0) { -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] em28xx: remove the i2c_set_adapdata() call in em28xx_i2c_register()
It is no longer needed since nobody is calling i2c_get_adapdata() anymore. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index ba6433c..04e8577 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -939,7 +939,6 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, dev-i2c_bus[bus].algo_type = algo_type; dev-i2c_bus[bus].dev = dev; dev-i2c_adap[bus].algo_data = dev-i2c_bus[bus]; - i2c_set_adapdata(dev-i2c_adap[bus], dev-v4l2_dev); retval = i2c_add_adapter(dev-i2c_adap[bus]); if (retval 0) { -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/19] em28xx: start moving em28xx-v4l specific data to its own struct
Am 09.05.2014 11:17, schrieb Hans Verkuil: Some comments for future improvements: On 03/24/2014 08:33 PM, Frank Schäfer wrote: Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-camera.c | 4 +- drivers/media/usb/em28xx/em28xx-video.c | 160 +-- drivers/media/usb/em28xx/em28xx.h| 8 +- 3 files changed, 116 insertions(+), 56 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 505e050..daebef3 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -365,7 +365,7 @@ int em28xx_init_camera(struct em28xx *dev) dev-sensor_xtal = 430; pdata.xtal = dev-sensor_xtal; if (NULL == -v4l2_i2c_new_subdev_board(dev-v4l2_dev, adap, +v4l2_i2c_new_subdev_board(dev-v4l2-v4l2_dev, adap, mt9v011_info, NULL)) { ret = -ENODEV; break; @@ -422,7 +422,7 @@ int em28xx_init_camera(struct em28xx *dev) dev-sensor_yres = 480; subdev = - v4l2_i2c_new_subdev_board(dev-v4l2_dev, adap, + v4l2_i2c_new_subdev_board(dev-v4l2-v4l2_dev, adap, ov2640_info, NULL); if (NULL == subdev) { ret = -ENODEV; diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 45ad471..89947db 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -189,10 +189,11 @@ static int em28xx_vbi_supported(struct em28xx *dev) */ static void em28xx_wake_i2c(struct em28xx *dev) { -v4l2_device_call_all(dev-v4l2_dev, 0, core, reset, 0); -v4l2_device_call_all(dev-v4l2_dev, 0, video, s_routing, +struct v4l2_device *v4l2_dev = dev-v4l2-v4l2_dev; +v4l2_device_call_all(v4l2_dev, 0, core, reset, 0); +v4l2_device_call_all(v4l2_dev, 0, video, s_routing, INPUT(dev-ctl_input)-vmux, 0, 0); -v4l2_device_call_all(dev-v4l2_dev, 0, video, s_stream, 0); +v4l2_device_call_all(v4l2_dev, 0, video, s_stream, 0); } static int em28xx_colorlevels_set_default(struct em28xx *dev) @@ -952,7 +953,8 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) f.type = V4L2_TUNER_RADIO; else f.type = V4L2_TUNER_ANALOG_TV; -v4l2_device_call_all(dev-v4l2_dev, 0, tuner, s_frequency, f); +v4l2_device_call_all(dev-v4l2-v4l2_dev, + 0, tuner, s_frequency, f); } dev-streaming_users++; @@ -1083,6 +1085,7 @@ static int em28xx_vb2_setup(struct em28xx *dev) static void video_mux(struct em28xx *dev, int index) { +struct v4l2_device *v4l2_dev = dev-v4l2-v4l2_dev; dev-ctl_input = index; dev-ctl_ainput = INPUT(index)-amux; dev-ctl_aoutput = INPUT(index)-aout; @@ -1090,21 +1093,21 @@ static void video_mux(struct em28xx *dev, int index) if (!dev-ctl_aoutput) dev-ctl_aoutput = EM28XX_AOUT_MASTER; -v4l2_device_call_all(dev-v4l2_dev, 0, video, s_routing, +v4l2_device_call_all(v4l2_dev, 0, video, s_routing, INPUT(index)-vmux, 0, 0); if (dev-board.has_msp34xx) { if (dev-i2s_speed) { -v4l2_device_call_all(dev-v4l2_dev, 0, audio, +v4l2_device_call_all(v4l2_dev, 0, audio, s_i2s_clock_freq, dev-i2s_speed); } /* Note: this is msp3400 specific */ -v4l2_device_call_all(dev-v4l2_dev, 0, audio, s_routing, +v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, dev-ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); } if (dev-board.adecoder != EM28XX_NOADECODER) { -v4l2_device_call_all(dev-v4l2_dev, 0, audio, s_routing, +v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, dev-ctl_ainput, dev-ctl_aoutput, 0); } @@ -1344,7 +1347,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) struct em28xx_fh *fh = priv; struct em28xx *dev = fh-dev; -v4l2_device_call_all(dev-v4l2_dev, 0, video, querystd, norm); +v4l2_device_call_all(dev-v4l2-v4l2_dev, 0, video, querystd, norm); return 0; } @@ -1374,7 +1377,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) size_to_scale(dev, dev-width, dev-height, dev-hscale, dev-vscale); em28xx_resolution_set(dev); -v4l2_device_call_all(dev-v4l2_dev, 0, core, s_std, dev-norm); +v4l2_device_call_all(dev-v4l2-v4l2_dev, 0, core, s_std
Re: [PATCH 06/19] em28xx: move video_device structs from struct em28xx to struct v4l2
Am 09.05.2014 11:19, schrieb Hans Verkuil: On 03/24/2014 08:33 PM, Frank Schäfer wrote: Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 120 ++-- drivers/media/usb/em28xx/em28xx.h | 7 +- 2 files changed, 56 insertions(+), 71 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 4fb0053..7252eef 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1447,7 +1447,7 @@ static int vidioc_enum_input(struct file *file, void *priv, (EM28XX_VMUX_CABLE == INPUT(n)-type)) i-type = V4L2_INPUT_TYPE_TUNER; -i-std = dev-vdev-tvnorms; +i-std = dev-v4l2-vdev-tvnorms; /* webcams do not have the STD API */ if (dev-board.is_webcam) i-capabilities = 0; @@ -1691,9 +1691,10 @@ static int vidioc_s_register(struct file *file, void *priv, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { -struct video_device *vdev = video_devdata(file); -struct em28xx_fh *fh = priv; -struct em28xx *dev = fh-dev; +struct video_device *vdev = video_devdata(file); +struct em28xx_fh *fh = priv; +struct em28xx *dev = fh-dev; +struct em28xx_v4l2*v4l2 = dev-v4l2; strlcpy(cap-driver, em28xx, sizeof(cap-driver)); strlcpy(cap-card, em28xx_boards[dev-model].name, sizeof(cap-card)); @@ -1715,9 +1716,9 @@ static int vidioc_querycap(struct file *file, void *priv, cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; -if (dev-vbi_dev) +if (v4l2-vbi_dev) cap-capabilities |= V4L2_CAP_VBI_CAPTURE; -if (dev-radio_dev) +if (v4l2-radio_dev) cap-capabilities |= V4L2_CAP_RADIO; return 0; } @@ -1955,20 +1956,20 @@ static int em28xx_v4l2_fini(struct em28xx *dev) em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); -if (dev-radio_dev) { +if (v4l2-radio_dev) { em28xx_info(V4L2 device %s deregistered\n, -video_device_node_name(dev-radio_dev)); -video_unregister_device(dev-radio_dev); +video_device_node_name(v4l2-radio_dev)); +video_unregister_device(v4l2-radio_dev); } -if (dev-vbi_dev) { +if (v4l2-vbi_dev) { em28xx_info(V4L2 device %s deregistered\n, -video_device_node_name(dev-vbi_dev)); -video_unregister_device(dev-vbi_dev); +video_device_node_name(v4l2-vbi_dev)); +video_unregister_device(v4l2-vbi_dev); } -if (dev-vdev) { +if (v4l2-vdev) { em28xx_info(V4L2 device %s deregistered\n, -video_device_node_name(dev-vdev)); -video_unregister_device(dev-vdev); +video_device_node_name(v4l2-vdev)); +video_unregister_device(v4l2-vdev); } v4l2_ctrl_handler_free(v4l2-ctrl_handler); @@ -2061,23 +2062,6 @@ exit: return 0; } -/* - * em28xx_videodevice_release() - * called when the last user of the video device exits and frees the memeory - */ -static void em28xx_videodevice_release(struct video_device *vdev) -{ -struct em28xx *dev = video_get_drvdata(vdev); - -video_device_release(vdev); -if (vdev == dev-vdev) -dev-vdev = NULL; -else if (vdev == dev-vbi_dev) -dev-vbi_dev = NULL; -else if (vdev == dev-radio_dev) -dev-radio_dev = NULL; -} - static const struct v4l2_file_operations em28xx_v4l_fops = { .owner = THIS_MODULE, .open = em28xx_v4l2_open, @@ -2134,7 +2118,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct video_device em28xx_video_template = { .fops = em28xx_v4l_fops, .ioctl_ops = video_ioctl_ops, -.release= em28xx_videodevice_release, +.release= video_device_release, .tvnorms= V4L2_STD_ALL, }; @@ -2163,7 +2147,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device em28xx_radio_template = { .fops = radio_fops, .ioctl_ops = radio_ioctl_ops, -.release= em28xx_videodevice_release, +.release= video_device_release, }; /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ @@ -2493,36 +2477,36 @@ static int em28xx_v4l2_init(struct em28xx *dev) goto unregister_dev; /* allocate and fill video video_device struct */ -dev-vdev = em28xx_vdev_init(dev, em28xx_video_template, video); -if (!dev-vdev
[PATCH 15/19, REBASED] em28xx: move v4l2 user counting fields from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 27 +++ drivers/media/usb/em28xx/em28xx.h | 5 +++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 496dcef..aaab111 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -934,7 +934,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) if (rc) return rc; - if (dev-streaming_users == 0) { + if (v4l2-streaming_users == 0) { /* First active streaming user, so allocate all the URBs */ /* Allocate the USB bandwidth */ @@ -972,7 +972,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) 0, tuner, s_frequency, f); } - dev-streaming_users++; + v4l2-streaming_users++; return rc; } @@ -980,6 +980,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) static void em28xx_stop_streaming(struct vb2_queue *vq) { struct em28xx *dev = vb2_get_drv_priv(vq); + struct em28xx_v4l2 *v4l2 = dev-v4l2; struct em28xx_dmaqueue *vidq = dev-vidq; unsigned long flags = 0; @@ -987,7 +988,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) res_free(dev, vq-type); - if (dev-streaming_users-- == 1) { + if (v4l2-streaming_users-- == 1) { /* Last active user, so shutdown all the URBS */ em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); } @@ -1008,6 +1009,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) void em28xx_stop_vbi_streaming(struct vb2_queue *vq) { struct em28xx *dev = vb2_get_drv_priv(vq); + struct em28xx_v4l2 *v4l2 = dev-v4l2; struct em28xx_dmaqueue *vbiq = dev-vbiq; unsigned long flags = 0; @@ -1015,7 +1017,7 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq) res_free(dev, vq-type); - if (dev-streaming_users-- == 1) { + if (v4l2-streaming_users-- == 1) { /* Last active user, so shutdown all the URBS */ em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); } @@ -1344,8 +1346,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx *dev = video_drvdata(file); + struct em28xx_v4l2 *v4l2 = dev-v4l2; - if (dev-streaming_users 0) + if (v4l2-streaming_users 0) return -EBUSY; vidioc_try_fmt_vid_cap(file, priv, f); @@ -1384,7 +1387,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) if (norm == v4l2-norm) return 0; - if (dev-streaming_users 0) + if (v4l2-streaming_users 0) return -EBUSY; v4l2-norm = norm; @@ -1907,7 +1910,7 @@ static int em28xx_v4l2_open(struct file *filp) em28xx_videodbg(open dev=%s type=%s users=%d\n, video_device_node_name(vdev), v4l2_type_names[fh_type], - dev-users); + v4l2-users); if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; @@ -1922,7 +1925,7 @@ static int em28xx_v4l2_open(struct file *filp) fh-type = fh_type; filp-private_data = fh; - if (dev-users == 0) { + if (v4l2-users == 0) { em28xx_set_mode(dev, EM28XX_ANALOG_MODE); if (vdev-vfl_type != VFL_TYPE_RADIO) @@ -1942,7 +1945,7 @@ static int em28xx_v4l2_open(struct file *filp) kref_get(dev-ref); kref_get(v4l2-ref); - dev-users++; + v4l2-users++; mutex_unlock(dev-lock); v4l2_fh_add(fh-fh); @@ -2051,12 +2054,12 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx_v4l2*v4l2 = dev-v4l2; int errCode; - em28xx_videodbg(users=%d\n, dev-users); + em28xx_videodbg(users=%d\n, v4l2-users); vb2_fop_release(filp); mutex_lock(dev-lock); - if (dev-users == 1) { + if (v4l2-users == 1) { /* No sense to try to write to the device */ if (dev-disconnected) goto exit; @@ -2078,8 +2081,8 @@ static int em28xx_v4l2_close(struct file *filp) } exit: + v4l2-users--; kref_put(v4l2-ref, em28xx_free_v4l2); - dev-users--; mutex_unlock(dev-lock); kref_put(dev-ref, em28xx_free_device); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 91bb624..0585217 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -523,6 +523,9 @@ struct em28xx_v4l2 { int
Re: [PATCH 00/19] em28xx: clean up the main device struct and move sub-module specific data to its own data structs
Hi Hans, Am 09.05.2014 11:04, schrieb Hans Verkuil: Hi Frank, This looks good to me. I do have some comments for future cleanups and I'll reply to the relevant patches for that. However, before I can apply this patch series you need to take a look at my comments for this pre-requisite patch: https://patchwork.linuxtv.org/patch/23179/ That needs to be sorted before I can apply this series. Done: https://patchwork.linuxtv.org/patch/23882/ I've also sent a rebased version of patch 15/19: https://patchwork.linuxtv.org/patch/23883/ All other patches still apply. Many thanks for reviewing the patches and your comments ! Regards, Frank Regards, Hans On 03/24/2014 08:33 PM, Frank Schäfer wrote: This patch series cleans up the main device struct of the em28xx driver. Most of the patches (patches 3-16) are about moving the em28xx-v4l specific data to it's own dynamically allocated data structure. Patch 19 moves two em28xx-alsa specific fields to the em28xx_audio struct. Patches 17 and 18 remove two fields which aren't needed. Frank Schäfer (19): em28xx: move sub-module data structs to a common place in the main struct em28xx-video: simplify usage of the pointer to struct v4l2_ctrl_handler in em28xx_v4l2_init() em28xx: start moving em28xx-v4l specific data to its own struct em28xx: move struct v4l2_ctrl_handler ctrl_handler from struct em28xx to struct v4l2 em28xx: move struct v4l2_clk *clk from struct em28xx to struct v4l2 em28xx: move video_device structs from struct em28xx to struct v4l2 em28xx: move videobuf2 related data from struct em28xx to struct v4l2 em28xx: move v4l2 frame resolutions and scale data from struct em28xx to struct v4l2 em28xx: move vinmode and vinctrl data from struct em28xx to struct v4l2 em28xx: move TV norm from struct em28xx to struct v4l2 em28xx: move struct em28xx_fmt *format from struct em28xx to struct v4l2 em28xx: move progressive/interlaced fields from struct em28xx to struct v4l2 em28xx: move sensor parameter fields from struct em28xx to struct v4l2 em28xx: move capture state tracking fields from struct em28xx to struct v4l2 em28xx: move v4l2 user counting fields from struct em28xx to struct v4l2 em28xx: move tuner frequency field from struct em28xx to struct v4l2 em28xx: remove field tda9887_conf from struct em28xx em28xx: remove field tuner_addr from struct em28xx em28xx: move fields wq_trigger and streaming_started from struct em28xx to struct em28xx_audio drivers/media/usb/em28xx/em28xx-audio.c | 39 +- drivers/media/usb/em28xx/em28xx-camera.c | 51 +-- drivers/media/usb/em28xx/em28xx-cards.c | 9 - drivers/media/usb/em28xx/em28xx-vbi.c| 10 +- drivers/media/usb/em28xx/em28xx-video.c | 592 +-- drivers/media/usb/em28xx/em28xx.h| 120 --- 6 files changed, 452 insertions(+), 369 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: em2750 usb camera log as mentioned in dmesg
Am 28.03.2014 21:21, schrieb aaron.mo...@alsatis.net: Hi, I have endless problems since upgarding to ubuntu12.04 with my usb microscope and it's a big problem cos i need it for work. Which device are you talking about ? Which sensor does it use ? What does endless problems mean ? Which kernel are you using and what's the last working kernel version ? As suggested in dmesg I have sent you the log.. Interestingly the em2750 camera is Ok on my desk pc with Xubuntu 12.04... go figure.. But the desk pC is kinda hard to carry to customer sites. I hope to find a solution soon thanks Aaron [12699.292580] em28xx: New device @ 480 Mbps (eb1a:2750, interface 0, class 0) [12699.292585] em28xx: Video interface 0 found: isoc [12699.292636] em28xx: chip ID is em2750 [12699.476200] em2750 #0: board has no eeprom [12699.547792] em2750 #0: No sensor detected As you can see, no sensor is found. Does this also happen with the working kernel ? Regards, Frank Schäfer [12699.583014] em2750 #0: found i2c device @ 0xba on bus 0 [webcam sensor or tvp5150a] [12699.595736] em2750 #0: Your board has no unique USB ID and thus need a hint to be detected. [12699.595742] em2750 #0: You may try to use card=n insmod option to workaround that. [12699.595746] em2750 #0: Please send an email with this log to: [12699.595749] em2750 #0: V4L Mailing List linux-media@vger.kernel.org [12699.595752] em2750 #0: Board eeprom hash is 0x [12699.595756] em2750 #0: Board i2c devicelist hash is 0x1bdd0080 [12699.595759] em2750 #0: Here is a list of valid choices for the card=n insmod option: [12699.595764] em2750 #0: card=0 - Unknown EM2800 video grabber [12699.595768] em2750 #0: card=1 - Unknown EM2750/28xx video grabber [12699.595772] em2750 #0: card=2 - Terratec Cinergy 250 USB [12699.595776] em2750 #0: card=3 - Pinnacle PCTV USB 2 [12699.595779] em2750 #0: card=4 - Hauppauge WinTV USB 2 [12699.595783] em2750 #0: card=5 - MSI VOX USB 2.0 [12699.595786] em2750 #0: card=6 - Terratec Cinergy 200 USB [12699.595790] em2750 #0: card=7 - Leadtek Winfast USB II [12699.595793] em2750 #0: card=8 - Kworld USB2800 [12699.595798] em2750 #0: card=9 - Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U [12699.595802] em2750 #0: card=10 - Hauppauge WinTV HVR 900 [12699.595805] em2750 #0: card=11 - Terratec Hybrid XS [12699.595809] em2750 #0: card=12 - Kworld PVR TV 2800 RF [12699.595812] em2750 #0: card=13 - Terratec Prodigy XS [12699.595816] em2750 #0: card=14 - SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 [12699.595819] em2750 #0: card=15 - V-Gear PocketTV [12699.595823] em2750 #0: card=16 - Hauppauge WinTV HVR 950 [12699.595827] em2750 #0: card=17 - Pinnacle PCTV HD Pro Stick [12699.595830] em2750 #0: card=18 - Hauppauge WinTV HVR 900 (R2) [12699.595834] em2750 #0: card=19 - EM2860/SAA711X Reference Design [12699.595838] em2750 #0: card=20 - AMD ATI TV Wonder HD 600 [12699.595841] em2750 #0: card=21 - eMPIA Technology, Inc. GrabBeeX+ Video Encoder [12699.595845] em2750 #0: card=22 - EM2710/EM2750/EM2751 webcam grabber [12699.595849] em2750 #0: card=23 - Huaqi DLCW-130 [12699.595852] em2750 #0: card=24 - D-Link DUB-T210 TV Tuner [12699.595856] em2750 #0: card=25 - Gadmei UTV310 [12699.595859] em2750 #0: card=26 - Hercules Smart TV USB 2.0 [12699.595863] em2750 #0: card=27 - Pinnacle PCTV USB 2 (Philips FM1216ME) [12699.595867] em2750 #0: card=28 - Leadtek Winfast USB II Deluxe [12699.595870] em2750 #0: card=29 - EM2860/TVP5150 Reference Design [12699.595874] em2750 #0: card=30 - Videology 20K14XUSB USB2.0 [12699.595877] em2750 #0: card=31 - Usbgear VD204v9 [12699.595881] em2750 #0: card=32 - Supercomp USB 2.0 TV [12699.595884] em2750 #0: card=33 - Elgato Video Capture [12699.595888] em2750 #0: card=34 - Terratec Cinergy A Hybrid XS [12699.595891] em2750 #0: card=35 - Typhoon DVD Maker [12699.595895] em2750 #0: card=36 - NetGMBH Cam [12699.595898] em2750 #0: card=37 - Gadmei UTV330 [12699.595902] em2750 #0: card=38 - Yakumo MovieMixer [12699.595906] em2750 #0: card=39 - KWorld PVRTV 300U [12699.595909] em2750 #0: card=40 - Plextor ConvertX PX-TV100U [12699.595913] em2750 #0: card=41 - Kworld 350 U DVB-T [12699.595916] em2750 #0: card=42 - Kworld 355 U DVB-T [12699.595920] em2750 #0: card=43 - Terratec Cinergy T XS [12699.595924] em2750 #0: card=44 - Terratec Cinergy T XS (MT2060) [12699.595927] em2750 #0: card=45 - Pinnacle PCTV DVB-T [12699.595931] em2750 #0: card=46 - Compro, VideoMate U3 [12699.595934] em2750 #0: card=47 - KWorld DVB-T 305U [12699.595938] em2750 #0: card=48 - KWorld DVB-T 310U [12699.595941] em2750 #0: card=49 - MSI DigiVox A/D [12699.595945] em2750 #0: card=50 - MSI
Re: [PATCH 4/5] em28xx: remove function em28xx_compression_disable() and its call
Am 22.03.2014 14:01, schrieb Frank Schäfer: em28xx_compression_disable() is a single line function which is called only one time and this call also isn't needed. Register 0x26 is always configured as part of the scaler configuration, which in turn is always done when the resolution changes. And the initial resolution setting is applied at first device open. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 1 - drivers/media/usb/em28xx/em28xx.h | 6 -- 2 files changed, 7 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 0856e5d..e15ac75 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -2376,7 +2376,6 @@ static int em28xx_v4l2_init(struct em28xx *dev) (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_set_outfmt(dev); - em28xx_compression_disable(dev); /* Add image controls */ /* NOTE: at this point, the subdevices are already registered, so bridge diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index e95f4eb..dd6190c 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -793,12 +793,6 @@ int em28xx_init_camera(struct em28xx *dev); printk(KERN_WARNING %s: fmt,\ dev-name , ##arg); } while (0) -static inline int em28xx_compression_disable(struct em28xx *dev) -{ - /* side effect of disabling scaler and mixer */ - return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); -} - /*FIXME: maxw should be dependent of alt mode */ static inline unsigned int norm_maxw(struct em28xx *dev) { Please disregard this patch, I will send an updated version in a minute. -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/5] em28xx: remove function em28xx_compression_disable() and its call
em28xx_compression_disable() is a single line function which is called only one time and this call also isn't needed. Register 0x26 is always configured as part of the scaler configuration, which in turn is always done when the resolution changes. And the initial resolution setting is applied at first device open. Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 5 ++--- drivers/media/usb/em28xx/em28xx.h | 6 -- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 0856e5d..a2133d5 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -274,7 +274,7 @@ static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) { - u8 mode; + u8 mode = 0x00; /* the em2800 scaler only supports scaling down to 50% */ if (dev-board.is_em2800) { @@ -293,7 +293,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) to work correctly */ mode = (h || v) ? 0x30 : 0x00; } - return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); + return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode); } /* FIXME: this only function read values from dev */ @@ -2376,7 +2376,6 @@ static int em28xx_v4l2_init(struct em28xx *dev) (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_set_outfmt(dev); - em28xx_compression_disable(dev); /* Add image controls */ /* NOTE: at this point, the subdevices are already registered, so bridge diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index e95f4eb..dd6190c 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -793,12 +793,6 @@ int em28xx_init_camera(struct em28xx *dev); printk(KERN_WARNING %s: fmt,\ dev-name , ##arg); } while (0) -static inline int em28xx_compression_disable(struct em28xx *dev) -{ - /* side effect of disabling scaler and mixer */ - return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); -} - /*FIXME: maxw should be dependent of alt mode */ static inline unsigned int norm_maxw(struct em28xx *dev) { -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/19] em28xx: clean up the main device struct and move sub-module specific data to its own data structs
This patch series cleans up the main device struct of the em28xx driver. Most of the patches (patches 3-16) are about moving the em28xx-v4l specific data to it's own dynamically allocated data structure. Patch 19 moves two em28xx-alsa specific fields to the em28xx_audio struct. Patches 17 and 18 remove two fields which aren't needed. Frank Schäfer (19): em28xx: move sub-module data structs to a common place in the main struct em28xx-video: simplify usage of the pointer to struct v4l2_ctrl_handler in em28xx_v4l2_init() em28xx: start moving em28xx-v4l specific data to its own struct em28xx: move struct v4l2_ctrl_handler ctrl_handler from struct em28xx to struct v4l2 em28xx: move struct v4l2_clk *clk from struct em28xx to struct v4l2 em28xx: move video_device structs from struct em28xx to struct v4l2 em28xx: move videobuf2 related data from struct em28xx to struct v4l2 em28xx: move v4l2 frame resolutions and scale data from struct em28xx to struct v4l2 em28xx: move vinmode and vinctrl data from struct em28xx to struct v4l2 em28xx: move TV norm from struct em28xx to struct v4l2 em28xx: move struct em28xx_fmt *format from struct em28xx to struct v4l2 em28xx: move progressive/interlaced fields from struct em28xx to struct v4l2 em28xx: move sensor parameter fields from struct em28xx to struct v4l2 em28xx: move capture state tracking fields from struct em28xx to struct v4l2 em28xx: move v4l2 user counting fields from struct em28xx to struct v4l2 em28xx: move tuner frequency field from struct em28xx to struct v4l2 em28xx: remove field tda9887_conf from struct em28xx em28xx: remove field tuner_addr from struct em28xx em28xx: move fields wq_trigger and streaming_started from struct em28xx to struct em28xx_audio drivers/media/usb/em28xx/em28xx-audio.c | 39 +- drivers/media/usb/em28xx/em28xx-camera.c | 51 +-- drivers/media/usb/em28xx/em28xx-cards.c | 9 - drivers/media/usb/em28xx/em28xx-vbi.c| 10 +- drivers/media/usb/em28xx/em28xx-video.c | 592 +-- drivers/media/usb/em28xx/em28xx.h| 120 --- 6 files changed, 452 insertions(+), 369 deletions(-) -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/19] em28xx-video: simplify usage of the pointer to struct v4l2_ctrl_handler in em28xx_v4l2_init()
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 9df1826..45ad471 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -2403,35 +2403,35 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* Add image controls */ /* NOTE: at this point, the subdevices are already registered, so bridge * controls are only added/enabled when no subdevice provides them */ - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_CONTRAST)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_CONTRAST, 0, 0x1f, 1, CONTRAST_DEFAULT); - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_BRIGHTNESS)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_BRIGHTNESS, -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_SATURATION)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_SATURATION, 0, 0x1f, 1, SATURATION_DEFAULT); - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_BLUE_BALANCE)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_RED_BALANCE)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, RED_BALANCE_DEFAULT); - if (NULL == v4l2_ctrl_find(dev-ctrl_handler, V4L2_CID_SHARPNESS)) - v4l2_ctrl_new_std(dev-ctrl_handler, em28xx_ctrl_ops, + if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) + v4l2_ctrl_new_std(hdl, em28xx_ctrl_ops, V4L2_CID_SHARPNESS, 0, 0x0f, 1, SHARPNESS_DEFAULT); /* Reset image controls */ em28xx_colorlevels_set_default(dev); - v4l2_ctrl_handler_setup(dev-ctrl_handler); - ret = dev-ctrl_handler.error; + v4l2_ctrl_handler_setup(hdl); + ret = hdl-error; if (ret) goto unregister_dev; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/19] em28xx: move sub-module data structs to a common place in the main struct
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx.h | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 4beb1fa..9a3c496 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -541,6 +541,11 @@ struct em28xx_i2c_bus { struct em28xx { struct kref ref; + /* Sub-module data */ + struct em28xx_dvb *dvb; + struct em28xx_audio adev; + struct em28xx_IR *ir; + /* generic device properties */ char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ @@ -576,8 +581,6 @@ struct em28xx { struct em28xx_fmt *format; - struct em28xx_IR *ir; - /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; @@ -623,8 +626,6 @@ struct em28xx { unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */ - struct em28xx_audio adev; - /* capture state tracking */ int capture_type; unsigned char top_field:1; @@ -704,8 +705,6 @@ struct em28xx { /* Snapshot button input device */ char snapshot_button_path[30]; /* path of the input dev */ struct input_dev *sbutton_input_dev; - - struct em28xx_dvb *dvb; }; #define kref_to_dev(d) container_of(d, struct em28xx, ref) -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/19] em28xx: move struct v4l2_ctrl_handler ctrl_handler from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 13 + drivers/media/usb/em28xx/em28xx.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 89947db..22acb0f 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1138,7 +1138,9 @@ static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl) { - struct em28xx *dev = container_of(ctrl-handler, struct em28xx, ctrl_handler); + struct em28xx_v4l2 *v4l2 = + container_of(ctrl-handler, struct em28xx_v4l2, ctrl_handler); + struct em28xx *dev = v4l2-dev; int ret = -EINVAL; switch (ctrl-id) { @@ -1849,6 +1851,7 @@ void em28xx_free_v4l2(struct kref *ref) { struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref); + v4l2-dev-v4l2 = NULL; kfree(v4l2); } @@ -1968,7 +1971,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) video_unregister_device(dev-vdev); } - v4l2_ctrl_handler_free(dev-ctrl_handler); + v4l2_ctrl_handler_free(v4l2-ctrl_handler); v4l2_device_unregister(v4l2-v4l2_dev); if (dev-clk) { @@ -2276,7 +2279,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) u8 val; int ret; unsigned int maxw; - struct v4l2_ctrl_handler *hdl = dev-ctrl_handler; + struct v4l2_ctrl_handler *hdl; struct em28xx_v4l2 *v4l2; if (dev-is_audio_only) { @@ -2300,6 +2303,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) return -ENOMEM; } kref_init(v4l2-ref); + v4l2-dev = dev; dev-v4l2 = v4l2; ret = v4l2_device_register(dev-udev-dev, v4l2-v4l2_dev); @@ -2308,6 +2312,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) goto err; } + hdl = v4l2-ctrl_handler; v4l2_ctrl_handler_init(hdl, 8); v4l2-v4l2_dev.ctrl_handler = hdl; @@ -2594,7 +2599,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) return 0; unregister_dev: - v4l2_ctrl_handler_free(dev-ctrl_handler); + v4l2_ctrl_handler_free(v4l2-ctrl_handler); v4l2_device_unregister(v4l2-v4l2_dev); err: dev-v4l2 = NULL; diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index b18b968..910c2d8 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -499,8 +499,10 @@ struct em28xx_eeprom { struct em28xx_v4l2 { struct kref ref; + struct em28xx *dev; struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler ctrl_handler; }; struct em28xx_audio { @@ -566,7 +568,6 @@ struct em28xx { unsigned int has_alsa_audio:1; unsigned int is_audio_only:1; - struct v4l2_ctrl_handler ctrl_handler; struct v4l2_clk *clk; struct em28xx_board board; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/19] em28xx: move videobuf2 related data from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-cards.c | 2 -- drivers/media/usb/em28xx/em28xx-video.c | 15 +-- drivers/media/usb/em28xx/em28xx.h | 12 ++-- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index ff19833..a21cce1 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2991,8 +2991,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, const char *chip_name = default_chip_name; dev-udev = udev; - mutex_init(dev-vb_queue_lock); - mutex_init(dev-vb_vbi_queue_lock); mutex_init(dev-ctrl_urb_lock); spin_lock_init(dev-slock); diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 7252eef..301acef 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1049,9 +1049,10 @@ static int em28xx_vb2_setup(struct em28xx *dev) { int rc; struct vb2_queue *q; + struct em28xx_v4l2 *v4l2 = dev-v4l2; /* Setup Videobuf2 for Video capture */ - q = dev-vb_vidq; + q = v4l2-vb_vidq; q-type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q-io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q-timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; @@ -1065,7 +1066,7 @@ static int em28xx_vb2_setup(struct em28xx *dev) return rc; /* Setup Videobuf2 for VBI capture */ - q = dev-vb_vbiq; + q = v4l2-vb_vbiq; q-type = V4L2_BUF_TYPE_VBI_CAPTURE; q-io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR; q-timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; @@ -2483,8 +2484,10 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = -ENODEV; goto unregister_dev; } - v4l2-vdev-queue = dev-vb_vidq; - v4l2-vdev-queue-lock = dev-vb_queue_lock; + mutex_init(v4l2-vb_queue_lock); + mutex_init(v4l2-vb_vbi_queue_lock); + v4l2-vdev-queue = v4l2-vb_vidq; + v4l2-vdev-queue-lock = v4l2-vb_queue_lock; /* disable inapplicable ioctls */ if (dev-board.is_webcam) { @@ -2519,8 +2522,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2-vbi_dev = em28xx_vdev_init(dev, em28xx_video_template, vbi); - v4l2-vbi_dev-queue = dev-vb_vbiq; - v4l2-vbi_dev-queue-lock = dev-vb_vbi_queue_lock; + v4l2-vbi_dev-queue = v4l2-vb_vbiq; + v4l2-vbi_dev-queue-lock = v4l2-vb_vbi_queue_lock; /* disable inapplicable ioctls */ v4l2_disable_ioctl(v4l2-vdev, VIDIOC_S_PARM); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 88d0589..b02e8b1 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -508,6 +508,12 @@ struct em28xx_v4l2 { struct video_device *vdev; struct video_device *vbi_dev; struct video_device *radio_dev; + + /* Videobuf2 */ + struct vb2_queue vb_vidq; + struct vb2_queue vb_vbiq; + struct mutex vb_queue_lock; + struct mutex vb_vbi_queue_lock; }; struct em28xx_audio { @@ -649,12 +655,6 @@ struct em28xx { struct mutex lock; struct mutex ctrl_urb_lock; /* protects urb_buf */ - /* Videobuf2 */ - struct vb2_queue vb_vidq; - struct vb2_queue vb_vbiq; - struct mutex vb_queue_lock; - struct mutex vb_vbi_queue_lock; - /* resources in use */ unsigned int resources; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/19] em28xx: move video_device structs from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 120 ++-- drivers/media/usb/em28xx/em28xx.h | 7 +- 2 files changed, 56 insertions(+), 71 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 4fb0053..7252eef 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -1447,7 +1447,7 @@ static int vidioc_enum_input(struct file *file, void *priv, (EM28XX_VMUX_CABLE == INPUT(n)-type)) i-type = V4L2_INPUT_TYPE_TUNER; - i-std = dev-vdev-tvnorms; + i-std = dev-v4l2-vdev-tvnorms; /* webcams do not have the STD API */ if (dev-board.is_webcam) i-capabilities = 0; @@ -1691,9 +1691,10 @@ static int vidioc_s_register(struct file *file, void *priv, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct video_device *vdev = video_devdata(file); - struct em28xx_fh *fh = priv; - struct em28xx *dev = fh-dev; + struct video_device *vdev = video_devdata(file); + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh-dev; + struct em28xx_v4l2*v4l2 = dev-v4l2; strlcpy(cap-driver, em28xx, sizeof(cap-driver)); strlcpy(cap-card, em28xx_boards[dev-model].name, sizeof(cap-card)); @@ -1715,9 +1716,9 @@ static int vidioc_querycap(struct file *file, void *priv, cap-capabilities = cap-device_caps | V4L2_CAP_DEVICE_CAPS | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - if (dev-vbi_dev) + if (v4l2-vbi_dev) cap-capabilities |= V4L2_CAP_VBI_CAPTURE; - if (dev-radio_dev) + if (v4l2-radio_dev) cap-capabilities |= V4L2_CAP_RADIO; return 0; } @@ -1955,20 +1956,20 @@ static int em28xx_v4l2_fini(struct em28xx *dev) em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); - if (dev-radio_dev) { + if (v4l2-radio_dev) { em28xx_info(V4L2 device %s deregistered\n, - video_device_node_name(dev-radio_dev)); - video_unregister_device(dev-radio_dev); + video_device_node_name(v4l2-radio_dev)); + video_unregister_device(v4l2-radio_dev); } - if (dev-vbi_dev) { + if (v4l2-vbi_dev) { em28xx_info(V4L2 device %s deregistered\n, - video_device_node_name(dev-vbi_dev)); - video_unregister_device(dev-vbi_dev); + video_device_node_name(v4l2-vbi_dev)); + video_unregister_device(v4l2-vbi_dev); } - if (dev-vdev) { + if (v4l2-vdev) { em28xx_info(V4L2 device %s deregistered\n, - video_device_node_name(dev-vdev)); - video_unregister_device(dev-vdev); + video_device_node_name(v4l2-vdev)); + video_unregister_device(v4l2-vdev); } v4l2_ctrl_handler_free(v4l2-ctrl_handler); @@ -2061,23 +2062,6 @@ exit: return 0; } -/* - * em28xx_videodevice_release() - * called when the last user of the video device exits and frees the memeory - */ -static void em28xx_videodevice_release(struct video_device *vdev) -{ - struct em28xx *dev = video_get_drvdata(vdev); - - video_device_release(vdev); - if (vdev == dev-vdev) - dev-vdev = NULL; - else if (vdev == dev-vbi_dev) - dev-vbi_dev = NULL; - else if (vdev == dev-radio_dev) - dev-radio_dev = NULL; -} - static const struct v4l2_file_operations em28xx_v4l_fops = { .owner = THIS_MODULE, .open = em28xx_v4l2_open, @@ -2134,7 +2118,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct video_device em28xx_video_template = { .fops = em28xx_v4l_fops, .ioctl_ops = video_ioctl_ops, - .release= em28xx_videodevice_release, + .release= video_device_release, .tvnorms= V4L2_STD_ALL, }; @@ -2163,7 +2147,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device em28xx_radio_template = { .fops = radio_fops, .ioctl_ops = radio_ioctl_ops, - .release= em28xx_videodevice_release, + .release= video_device_release, }; /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ @@ -2493,36 +2477,36 @@ static int em28xx_v4l2_init(struct em28xx *dev) goto unregister_dev; /* allocate and fill video video_device struct */ - dev-vdev = em28xx_vdev_init(dev, em28xx_video_template, video); - if (!dev-vdev
[PATCH 15/19] em28xx: move v4l2 user counting fields from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 27 +++ drivers/media/usb/em28xx/em28xx.h | 5 +++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 496dcef..aaab111 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -934,7 +934,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) if (rc) return rc; - if (dev-streaming_users == 0) { + if (v4l2-streaming_users == 0) { /* First active streaming user, so allocate all the URBs */ /* Allocate the USB bandwidth */ @@ -972,7 +972,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) 0, tuner, s_frequency, f); } - dev-streaming_users++; + v4l2-streaming_users++; return rc; } @@ -980,6 +980,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) static int em28xx_stop_streaming(struct vb2_queue *vq) { struct em28xx *dev = vb2_get_drv_priv(vq); + struct em28xx_v4l2 *v4l2 = dev-v4l2; struct em28xx_dmaqueue *vidq = dev-vidq; unsigned long flags = 0; @@ -987,7 +988,7 @@ static int em28xx_stop_streaming(struct vb2_queue *vq) res_free(dev, vq-type); - if (dev-streaming_users-- == 1) { + if (v4l2-streaming_users-- == 1) { /* Last active user, so shutdown all the URBS */ em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); } @@ -1008,6 +1009,7 @@ static int em28xx_stop_streaming(struct vb2_queue *vq) int em28xx_stop_vbi_streaming(struct vb2_queue *vq) { struct em28xx *dev = vb2_get_drv_priv(vq); + struct em28xx_v4l2 *v4l2 = dev-v4l2; struct em28xx_dmaqueue *vbiq = dev-vbiq; unsigned long flags = 0; @@ -1015,7 +1017,7 @@ int em28xx_stop_vbi_streaming(struct vb2_queue *vq) res_free(dev, vq-type); - if (dev-streaming_users-- == 1) { + if (v4l2-streaming_users-- == 1) { /* Last active user, so shutdown all the URBS */ em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); } @@ -1344,8 +1346,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx *dev = video_drvdata(file); + struct em28xx_v4l2 *v4l2 = dev-v4l2; - if (dev-streaming_users 0) + if (v4l2-streaming_users 0) return -EBUSY; vidioc_try_fmt_vid_cap(file, priv, f); @@ -1384,7 +1387,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) if (norm == v4l2-norm) return 0; - if (dev-streaming_users 0) + if (v4l2-streaming_users 0) return -EBUSY; v4l2-norm = norm; @@ -1907,7 +1910,7 @@ static int em28xx_v4l2_open(struct file *filp) em28xx_videodbg(open dev=%s type=%s users=%d\n, video_device_node_name(vdev), v4l2_type_names[fh_type], - dev-users); + v4l2-users); if (mutex_lock_interruptible(dev-lock)) return -ERESTARTSYS; @@ -1922,7 +1925,7 @@ static int em28xx_v4l2_open(struct file *filp) fh-type = fh_type; filp-private_data = fh; - if (dev-users == 0) { + if (v4l2-users == 0) { em28xx_set_mode(dev, EM28XX_ANALOG_MODE); if (vdev-vfl_type != VFL_TYPE_RADIO) @@ -1942,7 +1945,7 @@ static int em28xx_v4l2_open(struct file *filp) kref_get(dev-ref); kref_get(v4l2-ref); - dev-users++; + v4l2-users++; mutex_unlock(dev-lock); v4l2_fh_add(fh-fh); @@ -2051,12 +2054,12 @@ static int em28xx_v4l2_close(struct file *filp) struct em28xx_v4l2*v4l2 = dev-v4l2; int errCode; - em28xx_videodbg(users=%d\n, dev-users); + em28xx_videodbg(users=%d\n, v4l2-users); vb2_fop_release(filp); mutex_lock(dev-lock); - if (dev-users == 1) { + if (v4l2-users == 1) { /* No sense to try to write to the device */ if (dev-disconnected) goto exit; @@ -2078,8 +2081,8 @@ static int em28xx_v4l2_close(struct file *filp) } exit: + v4l2-users--; kref_put(v4l2-ref, em28xx_free_v4l2); - dev-users--; mutex_unlock(dev-lock); kref_put(dev-ref, em28xx_free_device); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 91bb624..0585217 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -523,6 +523,9 @@ struct em28xx_v4l2 { int sensor_yres
[PATCH 12/19] em28xx: move progressive/interlaced fields from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-cards.c | 2 -- drivers/media/usb/em28xx/em28xx-video.c | 27 +-- drivers/media/usb/em28xx/em28xx.h | 10 +- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index a21cce1..64ea25a 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2682,8 +2682,6 @@ static void em28xx_card_setup(struct em28xx *dev) if (dev-board.is_webcam) { if (em28xx_detect_sensor(dev) 0) dev-board.is_webcam = 0; - else - dev-progressive = 1; } switch (dev-model) { diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index c316147..abb4e8e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -447,9 +447,10 @@ static void em28xx_copy_video(struct em28xx *dev, unsigned char *usb_buf, unsigned long len) { + struct em28xx_v4l2 *v4l2 = dev-v4l2; void *fieldstart, *startwrite, *startread; int linesdone, currlinedone, offset, lencopy, remain; - int bytesperline = dev-v4l2-width 1; + int bytesperline = v4l2-width 1; if (buf-pos + len buf-length) len = buf-length - buf-pos; @@ -457,7 +458,7 @@ static void em28xx_copy_video(struct em28xx *dev, startread = usb_buf; remain = len; - if (dev-progressive || buf-top_field) + if (v4l2-progressive || buf-top_field) fieldstart = buf-vb_buf; else /* interlaced mode, even nr. of lines */ fieldstart = buf-vb_buf + bytesperline; @@ -465,7 +466,7 @@ static void em28xx_copy_video(struct em28xx *dev, linesdone = buf-pos / bytesperline; currlinedone = buf-pos % bytesperline; - if (dev-progressive) + if (v4l2-progressive) offset = linesdone * bytesperline + currlinedone; else offset = linesdone * bytesperline * 2 + currlinedone; @@ -489,7 +490,7 @@ static void em28xx_copy_video(struct em28xx *dev, remain -= lencopy; while (remain 0) { - if (dev-progressive) + if (v4l2-progressive) startwrite += lencopy; else startwrite += lencopy + bytesperline; @@ -611,7 +612,9 @@ finish_field_prepare_next(struct em28xx *dev, struct em28xx_buffer *buf, struct em28xx_dmaqueue *dma_q) { - if (dev-progressive || dev-top_field) { /* Brand new frame */ + struct em28xx_v4l2 *v4l2 = dev-v4l2; + + if (v4l2-progressive || dev-top_field) { /* Brand new frame */ if (buf != NULL) finish_buffer(dev, buf); buf = get_next_buf(dev, dma_q); @@ -1234,10 +1237,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f-fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ - if (dev-progressive) + if (v4l2-progressive) f-fmt.pix.field = V4L2_FIELD_NONE; else - f-fmt.pix.field = dev-interlaced ? + f-fmt.pix.field = v4l2-interlaced_fieldmode ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; return 0; } @@ -1258,6 +1261,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { struct em28xx_fh *fh= priv; struct em28xx *dev = fh-dev; + struct em28xx_v4l2*v4l2 = dev-v4l2; unsigned int width = f-fmt.pix.width; unsigned int height = f-fmt.pix.height; unsigned int maxw = norm_maxw(dev); @@ -1299,10 +1303,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, f-fmt.pix.bytesperline = (width * fmt-depth + 7) 3; f-fmt.pix.sizeimage = f-fmt.pix.bytesperline * height; f-fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - if (dev-progressive) + if (v4l2-progressive) f-fmt.pix.field = V4L2_FIELD_NONE; else - f-fmt.pix.field = dev-interlaced ? + f-fmt.pix.field = v4l2-interlaced_fieldmode ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; f-fmt.pix.priv = 0; @@ -2316,6 +2320,9 @@ static int em28xx_v4l2_init(struct em28xx *dev) v4l2_ctrl_handler_init(hdl, 8); v4l2-v4l2_dev.ctrl_handler = hdl; + if (dev-board.is_webcam) + v4l2-progressive = 1; + /* * Default format, used for tvp5150 or saa711x output formats */ @@ -2430,7 +2437,7 @@ static
[PATCH 19/19] em28xx: move fields wq_trigger and streaming_started from struct em28xx to struct em28xx_audio
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-audio.c | 39 ++--- drivers/media/usb/em28xx/em28xx.h | 8 +++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index c1937ea..e5ed5b9 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -92,7 +92,7 @@ static void em28xx_audio_isocirq(struct urb *urb) if (dev-disconnected) { dprintk(device disconnected while streaming. URB status=%d.\n, urb-status); - atomic_set(dev-stream_started, 0); + atomic_set(dev-adev.stream_started, 0); return; } @@ -109,7 +109,7 @@ static void em28xx_audio_isocirq(struct urb *urb) break; } - if (atomic_read(dev-stream_started) == 0) + if (atomic_read(dev-adev.stream_started) == 0) return; if (dev-adev.capture_pcm_substream) { @@ -185,7 +185,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) em28xx_errdev(submit of audio urb failed (error=%i)\n, errCode); em28xx_deinit_isoc_audio(dev); - atomic_set(dev-stream_started, 0); + atomic_set(dev-adev.stream_started, 0); return errCode; } @@ -332,9 +332,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) dev-mute = 1; mutex_lock(dev-lock); dev-adev.users--; - if (atomic_read(dev-stream_started) 0) { - atomic_set(dev-stream_started, 0); - schedule_work(dev-wq_trigger); + if (atomic_read(dev-adev.stream_started) 0) { + atomic_set(dev-adev.stream_started, 0); + schedule_work(dev-adev.wq_trigger); } em28xx_audio_analog_set(dev); @@ -381,12 +381,13 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) { struct em28xx *dev = snd_pcm_substream_chip(substream); + struct em28xx_audio *adev = dev-adev; dprintk(Stop capture, if needed\n); - if (atomic_read(dev-stream_started) 0) { - atomic_set(dev-stream_started, 0); - schedule_work(dev-wq_trigger); + if (atomic_read(adev-stream_started) 0) { + atomic_set(adev-stream_started, 0); + schedule_work(adev-wq_trigger); } return 0; @@ -407,9 +408,11 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream) static void audio_trigger(struct work_struct *work) { - struct em28xx *dev = container_of(work, struct em28xx, wq_trigger); + struct em28xx_audio *adev = + container_of(work, struct em28xx_audio, wq_trigger); + struct em28xx *dev = container_of(adev, struct em28xx, adev); - if (atomic_read(dev-stream_started)) { + if (atomic_read(adev-stream_started)) { dprintk(starting capture); em28xx_init_audio_isoc(dev); } else { @@ -431,17 +434,17 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ case SNDRV_PCM_TRIGGER_START: - atomic_set(dev-stream_started, 1); + atomic_set(dev-adev.stream_started, 1); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ case SNDRV_PCM_TRIGGER_STOP: - atomic_set(dev-stream_started, 0); + atomic_set(dev-adev.stream_started, 0); break; default: retval = -EINVAL; } - schedule_work(dev-wq_trigger); + schedule_work(dev-adev.wq_trigger); return retval; } @@ -929,7 +932,7 @@ static int em28xx_audio_init(struct em28xx *dev) strcpy(card-shortname, Em28xx Audio); strcpy(card-longname, Empia Em28xx Audio); - INIT_WORK(dev-wq_trigger, audio_trigger); + INIT_WORK(adev-wq_trigger, audio_trigger); if (dev-audio_mode.ac97 != EM28XX_NO_AC97) { em28xx_cvol_new(card, dev, Video, AC97_VIDEO); @@ -984,7 +987,7 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev-adev.sndcard) { snd_card_disconnect(dev-adev.sndcard); - flush_work(dev-wq_trigger); + flush_work(dev-adev.wq_trigger); em28xx_audio_free_urb(dev); @@ -1006,7 +1009,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) em28xx_info(Suspending audio extension
[PATCH 11/19] em28xx: move struct em28xx_fmt *format from struct em28xx to struct v4l2
Signed-off-by: Frank Schäfer fschaefer@googlemail.com --- drivers/media/usb/em28xx/em28xx-video.c | 14 +++--- drivers/media/usb/em28xx/em28xx.h | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 821d182..c316147 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -222,7 +222,7 @@ static int em28xx_set_outfmt(struct em28xx *dev) u8 fmt, vinctrl; struct em28xx_v4l2 *v4l2 = dev-v4l2; - fmt = dev-format-reg; + fmt = v4l2-format-reg; if (!dev-is_em25xx) fmt |= 0x20; /* @@ -877,7 +877,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, size = fmt-fmt.pix.sizeimage; else size = -(v4l2-width * v4l2-height * dev-format-depth + 7) 3; + (v4l2-width * v4l2-height * v4l2-format-depth + 7) 3; if (size == 0) return -EINVAL; @@ -901,7 +901,7 @@ buffer_prepare(struct vb2_buffer *vb) em28xx_videodbg(%s, field=%d\n, __func__, vb-v4l2_buf.field); - size = (v4l2-width * v4l2-height * dev-format-depth + 7) 3; + size = (v4l2-width * v4l2-height * v4l2-format-depth + 7) 3; if (vb2_plane_size(vb, 0) size) { em28xx_videodbg(%s data will not fit into plane (%lu %lu)\n, @@ -1228,8 +1228,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f-fmt.pix.width = v4l2-width; f-fmt.pix.height = v4l2-height; - f-fmt.pix.pixelformat = dev-format-fourcc; - f-fmt.pix.bytesperline = (v4l2-width * dev-format-depth + 7) 3; + f-fmt.pix.pixelformat = v4l2-format-fourcc; + f-fmt.pix.bytesperline = (v4l2-width * v4l2-format-depth + 7) 3; f-fmt.pix.sizeimage = f-fmt.pix.bytesperline * v4l2-height; f-fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -1319,7 +1319,7 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, if (!fmt) return -EINVAL; - dev-format = fmt; + v4l2-format = fmt; v4l2-width = width; v4l2-height = height; @@ -2433,7 +2433,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) dev-interlaced = EM28XX_INTERLACED_DEFAULT; /* Analog specific initialization */ - dev-format = format[0]; + v4l2-format = format[0]; maxw = norm_maxw(dev); /* MaxPacketSize for em2800 is too small to capture at full resolution diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index f0b3b8c..dd93a37 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -518,6 +518,7 @@ struct em28xx_v4l2 { u8 vinmode; u8 vinctl; + struct em28xx_fmt *format; v4l2_std_id norm; /* selected tv norm */ /* Frame properties */ @@ -606,8 +607,6 @@ struct em28xx { struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ atomic_t stream_started; /* stream should be running if true */ - struct em28xx_fmt *format; - /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; -- 1.8.4.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html