Re: [PATCH RFC v3 2/6] v4l2-ctrl: Add helper function for control range update
Hi Sylwester, On Wed January 23 2013 23:21:57 Sylwester Nawrocki wrote: > This patch adds a helper function that allows to modify range, > i.e. minimum, maximum, step and default value of a v4l2 control, > after the control has been created and initialized. This is helpful > in situations when range of a control depends on user configurable > parameters, e.g. camera sensor absolute exposure time depending on > an output image resolution and frame rate. > > v4l2_ctrl_modify_range() function allows to modify range of an > INTEGER, BOOL, MENU, INTEGER_MENU and BITMASK type controls. > > Based on a patch from Hans Verkuil http://patchwork.linuxtv.org/patch/8654. > > Signed-off-by: Sylwester Nawrocki > Acked-by: Hans Verkuil I've been playing around with this a bit, using this vivi patch: diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c index c46d2e8..85bc314 100644 --- a/drivers/media/platform/vivi.c +++ b/drivers/media/platform/vivi.c @@ -1093,6 +1093,15 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; dev->input = i; + /* +* Modify the brightness range depending on the input. +* This makes it easy to use vivi to test if applications can +* handle control range modifications and is also how this is +* typically used in practice as different inputs may be hooked +* up to different receivers with different control ranges. +*/ + v4l2_ctrl_modify_range(dev->brightness, + 128 * i, 255 + 128 * i, 1, 127 + 128 * i); precalculate_bars(dev); precalculate_line(dev); return 0; And it made me wonder if it wouldn't be more sensible if modify_range would also update the current value to the new default value? You get weird effects otherwise where the new value is clamped to either the minimum or maximum value if the current value falls outside the new range. Regards, Hans PS: qv4l2 has been updated to support range update events. -- 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: davinci: kconfig: fix incorrect selects
Hi Sekhar, Thanks for the patch! few nits below also version number for patch is missing as this should have been v2 :) BTW this patch still is not present in media list. On Mon, Mar 11, 2013 at 5:52 PM, Sekhar Nori wrote: > drivers/media/platform/davinci/Kconfig uses selects where > it should be using 'depends on'. This results in warnings of > the following sort when doing randconfig builds. > > warning: (VIDEO_DM6446_CCDC && VIDEO_DM355_CCDC && VIDEO_ISIF && > VIDEO_DAVINCI_VPBE_DISPLAY) selects VIDEO_VPSS_SYSTEM which has unmet direct > dependencies (MEDIA_SUPPORT && V4L_PLATFORM_DRIVERS && ARCH_DAVINCI) > > The VPIF kconfigs had a strange 'select' and 'depends on' cross > linkage which have been fixed as well by removing unneeded > VIDEO_DAVINCI_VPIF config symbol. > > Similarly, remove the unnecessary VIDEO_VPSS_SYSTEM and > VIDEO_VPFE_CAPTURE. They don't select any independent functionality > and were being used to manage code dependencies which can > be handled using makefile. > > Selecting video modules is now dependent on all ARCH_DAVINCI > instead of specific EVMs and SoCs earlier. This should help build > coverage. Remove unnecessary 'default y' for some config symbols. > > While at it, fix the Kconfig help text to make it more readable > and fix names of modules created. > > Rename VIDEO_ISIF to VIDEO_DM365_ISIF as per suggestion from > Prabhakar. > > This patch has only been build tested; I have tried to not break > any existing assumptions. I do not have the setup to test video, > so any test reports welcome. > > Reported-by: Russell King > Signed-off-by: Sekhar Nori > --- > drivers/media/platform/davinci/Kconfig | 99 > +++ > drivers/media/platform/davinci/Makefile | 17 ++ > 2 files changed, 39 insertions(+), 77 deletions(-) > > diff --git a/drivers/media/platform/davinci/Kconfig > b/drivers/media/platform/davinci/Kconfig > index ccfde4e..86f7f34 100644 > --- a/drivers/media/platform/davinci/Kconfig > +++ b/drivers/media/platform/davinci/Kconfig > @@ -1,64 +1,33 @@ > config VIDEO_DAVINCI_VPIF_DISPLAY > - tristate "DM646x/DA850/OMAPL138 EVM Video Display" > - depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || > MACH_DAVINCI_DA850_EVM) > + tristate "TI DaVinci VPIF Video Display" > + depends on VIDEO_DEV && ARCH_DAVINCI > select VIDEOBUF2_DMA_CONTIG > - select VIDEO_DAVINCI_VPIF > select VIDEO_ADV7343 if MEDIA_SUBDRV_AUTOSELECT > select VIDEO_THS7303 if MEDIA_SUBDRV_AUTOSELECT > help > Enables Davinci VPIF module used for display devices. > - This module is common for following DM6467/DA850/OMAPL138 > - based display devices. > + This module is used for display on TI DM6467/DA850/OMAPL138 > + SoCs. > > - To compile this driver as a module, choose M here: the > - module will be called vpif_display. > + To compile this driver as a module, choose M here. There will > + be two modules called vpif.ko and vpif_display.ko > > config VIDEO_DAVINCI_VPIF_CAPTURE > - tristate "DM646x/DA850/OMAPL138 EVM Video Capture" > - depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || > MACH_DAVINCI_DA850_EVM) > + tristate "TI DaVinci VPIF Video Capture" > + depends on VIDEO_DEV && ARCH_DAVINCI > select VIDEOBUF2_DMA_CONTIG > - select VIDEO_DAVINCI_VPIF > help > - Enables Davinci VPIF module used for captur devices. > - This module is common for following DM6467/DA850/OMAPL138 > - based capture devices. > + Enables Davinci VPIF module used for capture devices. > + This module is used for capture on TI DM6467/DA850/OMAPL138 > + SoCs. > > - To compile this driver as a module, choose M here: the > - module will be called vpif_capture. > - > -config VIDEO_DAVINCI_VPIF > - tristate "DaVinci VPIF Driver" > - depends on VIDEO_DAVINCI_VPIF_DISPLAY || VIDEO_DAVINCI_VPIF_CAPTURE > - help > - Support for DaVinci VPIF Driver. > - > - To compile this driver as a module, choose M here: the > - module will be called vpif. > - > -config VIDEO_VPSS_SYSTEM > - tristate "VPSS System module driver" > - depends on ARCH_DAVINCI > - help > - Support for vpss system module for video driver > - > -config VIDEO_VPFE_CAPTURE > - tristate "VPFE Video Capture Driver" > - depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3) > - depends on I2C > - select VIDEOBUF_DMA_CONTIG > - help > - Support for DMx/AMx VPFE based frame grabber. This is the > - common V4L2 module for following DMx/AMx SoCs from Texas > - Instruments:- DM6446, DM365, DM355 & AM3517/05. > - > - To compile this driver as a module, choose M here: the > - module will be called vpfe-capture. > + To compile this driver as a module, choose M her
Re: [PATCH -next] [media] davinci: vpfe: fix return value check in vpfe_enable_clock()
Hi Wei, Thanks for the patch! I'll queue it up for v3.10 On Mon, Mar 11, 2013 at 7:27 PM, Wei Yongjun wrote: > From: Wei Yongjun > > In case of error, the function clk_get() returns ERR_PTR() > and never returns NULL. The NULL test in the return value > check should be replaced with IS_ERR(). > > Signed-off-by: Wei Yongjun Acked-by: Lad, Prabhakar Regards, --Prabhakar Lad > --- > drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c > b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c > index 7b35171..6a8222c 100644 > --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c > +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c > @@ -243,7 +243,7 @@ static int vpfe_enable_clock(struct vpfe_device *vpfe_dev) > > vpfe_dev->clks[i] = > clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]); > - if (vpfe_dev->clks[i] == NULL) { > + if (IS_ERR(vpfe_dev->clks[i])) { > v4l2_err(vpfe_dev->pdev->driver, > "Failed to get clock %s\n", > vpfe_cfg->clocks[i]); > @@ -264,7 +264,7 @@ static int vpfe_enable_clock(struct vpfe_device *vpfe_dev) > return 0; > out: > for (i = 0; i < vpfe_cfg->num_clocks; i++) > - if (vpfe_dev->clks[i]) { > + if (!IS_ERR(vpfe_dev->clks[i])) { > clk_disable_unprepare(vpfe_dev->clks[i]); > clk_put(vpfe_dev->clks[i]); > } > > -- > 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 -- 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: [REVIEW PATCH 11/15] au0828: fix disconnect sequence.
On Mon, Mar 11, 2013 at 5:00 PM, Hans Verkuil wrote: > From: Hans Verkuil > > The driver crashed when the device was disconnected while an application > still had a device node open. Fixed by using the release() callback of struct > v4l2_device. This is all obviously good stuff. I actually spent a couple of days working through various disconnect scenarios, but hadn't had a chance to do a PULL request. I will review my tree and see if you missed any other cases that I took care of. Devin -- Devin J. Heitmueller - Kernel Labs http://www.kernellabs.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 v7] [media] Add a V4L2 OF parser
Hi Guennadi, On 03/11/2013 04:03 PM, Guennadi Liakhovetski wrote: Hi Sylwester Thanks for continuing this work! You have made a great progress compared to my initial version, and I should really have looked at each your submitted new revision, unfortunately, I haven't managed that. So, sorry for chiming back in so late in the game, but maybe we still manage to get it in on time for 3.10. Let me know if you'd like me to do the next couple of rounds :) Or if you disagree with my comments and prefer your present state. I'm glad to hear you can focus on this again. Please feel free to spin next improved version of this. :-) And let me hold on predicting in which kernel version this patch has a chance to be merged upstream ;) In fact, I couldn't spent as much time on this as I would like to.. When we are more or less done with the parser I would like to carry on with the asynchronous subdev registration support. I have a bit different idea on how it could be implemented, comparing to your latest proposal. But don't yet have any POC. My feelings are we should integrate it more with existing V4L2 data structures, and have the clocks associated with struct device, rather than subdev driver. But then come issues at the common clock framework, like not implemented clk_unregister() or no clk_get/clk_put per a clock provider driver. On Fri, 8 Mar 2013, Sylwester Nawrocki wrote: From: Guennadi Liakhovetski Add a V4L2 OF parser, implementing bindings documented in Documentation/devicetree/bindings/media/video-interfaces.txt. Signed-off-by: Guennadi Liakhovetski [s.nawro...@samsung.com: various corrections and improvements since the initial version] Signed-off-by: Sylwester Nawrocki --- The last version of the bindings documentation patch can be found at: https://patchwork.kernel.org/patch/2074951 Changes since v6: - minor v4l2_of_get_remote_port_parent() function cleanup. Changes since v5: - renamed v4l2_of_parse_mipi_csi2 -> v4l2_of_parse_csi_bus, - corrected v4l2_of_get_remote_port_parent() function declaration for !CONFIG_OF, - reworked v4l2_of_get_next_endpoint() function to consider the 'port' nodes can be grouped under optional 'ports' node, - added kerneldoc description for v4l2_of_get_next_endpoint() function. Changes since v4: - reworked v4l2_of_get_remote_port() function to consider cases where 'port' nodes are grouped in a parent 'ports' node, - rearranged struct v4l2_of_endpoint and related changes added in the parser code, - added kerneldoc description for struct v4l2_of_endpoint, - s/link/endpoint in the comments, --- drivers/media/v4l2-core/Makefile |3 + drivers/media/v4l2-core/v4l2-of.c | 261 + include/media/v4l2-of.h | 98 ++ 3 files changed, 362 insertions(+) create mode 100644 drivers/media/v4l2-core/v4l2-of.c create mode 100644 include/media/v4l2-of.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index c2d61d4..00f64d6 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -9,6 +9,9 @@ videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif +ifeq ($(CONFIG_OF),y) + videodev-objs += v4l2-of.o +endif obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c new file mode 100644 index 000..cbd18f6 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-of.c @@ -0,0 +1,261 @@ +/* + * V4L2 OF binding parsing library + * + * Copyright (C) 2012 Renesas Electronics Corp. + * Author: Guennadi Liakhovetski + * + * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. + * Sylwester Nawrocki You probably want to put your copyright at the top as the newer one, isn't it the usual order - newest first? Yes, I guess you're right. + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include + +/** + * v4l2_of_parse_csi_bus() - parse MIPI CSI-2 bus properties + * @node: pointer to endpoint device_node + * @endpoint: pointer to v4l2_of_endpoint data structure + * + * Return: 0 on success or negative error value otherwise. + */ +int v4l2_of_parse_csi_bus(const struct device_node *node, + struct v4l2_of_endpoint *endpoint) +{ + struct v4l2_mbus_mipi_csi2 *mipi_csi2 =&endpoint->mbus.mipi_csi2; + u32 data_lanes[ARRAY_SIZE(mipi_csi2->data_lanes)]; + struct property *prop; + const __be32 *lane = NULL; + u32 v; + int i = 0; + + prop = of_find_property(node, "data-lanes", NULL); + if (!prop) + return -EINVAL; Oh... Wel
Re: Fw: [patch 02/03 v2] usb hid quirks for Masterkit MA901 usb radio
Hi Jiri and Mauro, all, On Fri, Dec 28, 2012 at 4:29 PM, Mauro Carvalho Chehab wrote: > Hi Jiri, > > There's another radio device that it is incorrectly detected as an HID driver. > As I'll be applying the driver's patch via the media tree, do you mind if I > also > apply this hid patch there? > > Thanks! > Mauro > > Forwarded message: > > Date: Mon, 12 Nov 2012 07:57:03 +0100 > From: Alexey Klimov > To: linux-media@vger.kernel.org > Subject: [patch 02/03 v2] usb hid quirks for Masterkit MA901 usb radio > > > Don't let Masterkit MA901 USB radio be handled by usb hid drivers. > > This device will be handled by radio-ma901.c driver. > > Signed-off-by: Alexey Klimov > > > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > index 5de3bb3..8e06569 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -2025,6 +2025,7 @@ static const struct hid_device_id hid_ignore_list[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, > { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, > USB_DEVICE_ID_MADCATZ_BEATPAD) }, > + { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, > USB_DEVICE_ID_MASTERKIT_MA901RADIO) }, > { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, > { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, > { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h > index 1dcb76f..17aa4f6 100644 > --- a/drivers/hid/hid-ids.h > +++ b/drivers/hid/hid-ids.h > @@ -533,6 +533,9 @@ > #define USB_VENDOR_ID_MADCATZ 0x0738 > #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 > > +#define USB_VENDOR_ID_MASTERKIT0x16c0 > +#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df > + > #define USB_VENDOR_ID_MCC 0x09db > #define USB_DEVICE_ID_MCC_PMD1024LS0x0076 > #define USB_DEVICE_ID_MCC_PMD1208LS0x007a Well, since patch also was pushed to stable trees like 3.5, 3.8, 3.2 and this fact made me look a little closer to usb ids. Actually, i googled these usb ids: 16c0 05df, link: http://www.google.com/search?q=16c0+05df and here comes some doubts. For my eyes it looks like this usb radio consists of two chips: atmel tiny85 + actually fm tuner KT0830EG. It looks like tiny85 is used in many devices with the same usb ids like in our patch and people works with tiny85 using some software under linux. I don't know if linux software using hiddev/hidraw devices but this patch doesn't allow appearing of /dev/hiddev or /dev/hidraw files for any usb device with ids 0x16c0 0x05df, right? Is there any chance that using such patch we can break some linux software that uses /dev/hid* files and related functionality to communicate with tiny85? Please note that i'm not expert in tiny85 chip and i don't have any deep knowledges on how usb ids are allocated for every device in the world. Masterkit company changed (or was able to change?) only Manufacturer, Product, Serial fields in ma901 usb radio. I attached lsusb output in the end of letter. Bad thing here is that Masterkit has other usb not radio devices with the same usb ids based on tiny85 on the market. Sorry if i'm over-alarmed, i just really dont want to break any userspace programs by this patch. If everything above is correct then i can use some dev->product, dev->manufacturer, dev->serial checks in probe() function in radio-ma901.c driver in the way like it's done in radio-keene.c driver in probe function. If for example probe will discover that product doesn't match then i can return -ENODEV. It's just an idea. But i don't know if it is possible to do something with hid quirks: revert and put comments somewhere or workaround and additional checks? Well, any comments are welcome. -- Best regards, Klimov Alexey lsusb output: Bus 003 Device 002: ID 16c0:05df VOTI Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x16c0 VOTI idProduct 0x05df bcdDevice1.00 iManufacturer 1 www.masterkit.ru iProduct2 MA901 iSerial 3 SHS bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 250mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceS
Re: [PATCH] m920x: silence compiler warning
On Mon, 11 Mar 2013 19:25:10 +0200 Antti Palosaari wrote: > drivers/media/usb/dvb-usb/m920x.c: In function ‘m920x_probe’: > drivers/media/usb/dvb-usb/m920x.c:91:6: warning: ‘ret’ may be used > uninitialized in this function [-Wuninitialized] > drivers/media/usb/dvb-usb/m920x.c:70:6: note: ‘ret’ was declared here > > Signed-off-by: Antti Palosaari Acked-by: Antonio Ospite And thanks. BTW Antti, there was another patch for this warning: http://thread.gmane.org/gmane.linux.kernel/1450717 but your change is easier to validate. > --- > drivers/media/usb/dvb-usb/m920x.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/media/usb/dvb-usb/m920x.c > b/drivers/media/usb/dvb-usb/m920x.c > index 92afeb2..f5e4654 100644 > --- a/drivers/media/usb/dvb-usb/m920x.c > +++ b/drivers/media/usb/dvb-usb/m920x.c > @@ -67,7 +67,7 @@ static inline int m920x_write(struct usb_device *udev, u8 > request, > static inline int m920x_write_seq(struct usb_device *udev, u8 request, > struct m920x_inits *seq) > { > - int ret; > + int ret = 0; > while (seq->address) { > ret = m920x_write(udev, request, seq->data, seq->address); > if (ret != 0) > -- > 1.7.11.7 > > -- > 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 > -- Antonio Ospite http://ao2.it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? -- 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] block i2c tuner reads for Avermedia Twinstar in the af9035 driver
On 03/11/2013 10:02 PM, Jose Alberto Reguero wrote: On Lunes, 11 de marzo de 2013 14:57:37 Antti Palosaari escribió: On 03/11/2013 01:51 PM, Jose Alberto Reguero wrote: On Lunes, 11 de febrero de 2013 14:48:18 Jose Alberto Reguero escribió: On Domingo, 10 de febrero de 2013 22:11:53 Antti Palosaari escribió: On 02/10/2013 09:43 PM, Jose Alberto Reguero wrote: This patch block the i2c tuner reads for Avermedia Twinstar. If it's needed other pids can be added. Signed-off-by: Jose Alberto Reguero diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.c linux.new/drivers/media/usb/dvb-usb-v2/af9035.c --- linux/drivers/media/usb/dvb-usb-v2/af9035.c 2013-01-07 05:45:57.0 +0100 +++ linux.new/drivers/media/usb/dvb-usb-v2/af9035.c 2013-02-08 22:55:08.304089054 +0100 @@ -232,7 +232,11 @@ static int af9035_i2c_master_xfer(struct buf[3] = 0x00; /* reg addr MSB */ buf[4] = 0x00; /* reg addr LSB */ memcpy(&buf[5], msg[0].buf, msg[0].len); - ret = af9035_ctrl_msg(d, &req); + if (state->block_read) { + msg[1].buf[0] = 0x3f; + ret = 0; + } else + ret = af9035_ctrl_msg(d, &req); } } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { if (msg[0].len > 40) { @@ -638,6 +642,17 @@ static int af9035_read_config(struct dvb for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) state->af9033_config[i].clock = clock_lut[tmp]; + state->block_read = false; + + if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && + le16_to_cpu(d->udev->descriptor.idProduct) == + USB_PID_AVERMEDIA_TWINSTAR) { + dev_dbg(&d->udev->dev, + "%s: AverMedia Twinstar: block i2c read from tuner\n", + __func__); + state->block_read = true; + } + return 0; err: diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.h linux.new/drivers/media/usb/dvb-usb-v2/af9035.h --- linux/drivers/media/usb/dvb-usb-v2/af9035.h 2013-01-07 05:45:57.0 +0100 +++ linux.new/drivers/media/usb/dvb-usb-v2/af9035.h 2013-02-08 22:52:42.293842710 +0100 @@ -54,6 +54,7 @@ struct usb_req { struct state { u8 seq; /* packet sequence number */ bool dual_mode; + bool block_read; struct af9033_config af9033_config[2]; }; Could you test if faking tuner ID during attach() is enough? Also, I would like to know what is returned error code from firmware when it fails. Enable debugs to see it. It should print something like that: af9035_ctrl_msg: command=03 failed fw error=2 diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index a1e953a..5a4f28d 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1082,9 +1082,22 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) tuner_addr = 0x60 | 0x80; /* I2C bus hack */ } + // fake used tuner for demod firmware / i2c adapter + if (adap->id == 0) + ret = af9035_wr_reg(d, 0x00f641, AF9033_TUNER_FC0011); + else + ret = af9035_wr_reg(d, 0x10f641, AF9033_TUNER_FC0011); + /* attach tuner */ fe = dvb_attach(mxl5007t_attach, adap->fe[0], &d->i2c_adap, tuner_addr, &af9035_mxl5007t_config[adap->id]); + + // return correct tuner + if (adap->id == 0) + ret = af9035_wr_reg(d, 0x00f641, AF9033_TUNER_MXL5007T); + else + ret = af9035_wr_reg(d, 0x10f641, AF9033_TUNER_MXL5007T); + break; case AF9033_TUNER_TDA18218: /* attach tuner */ regards Antti I will try with fake tuner, but I can't test unil next weekend. If I remember, the read operation is performed, and return good value, but after that, all the i2c transfers fail. Seee: http://www.mail-archive.com/linux-media@vger.kernel.org/msg56346.html Jose Alberto I tried with fake tuner without success: [ 1346.707405] DVB: registering new adapter (AVerMedia Twinstar (A825)) [ 1346.959043] i2c i2c-1: af9033: firmware version: LINK=11.5.9.0 OFDM=5.17.9.1 [ 1346.962920] usb 1-2: DVB: registering adapter 0 frontend 0 (Afatech AF9033 (DVB-T))... [ 1347.439354] mxl5007t 1-0060: creating new instance [ 1347.440644] mxl5007t_get_chip_id: unknown rev (3f) [ 1347.440652] mxl5007t_get_chip_id: MxL5007T detected @ 1-0060 [ 1347.443023] mxl5007t_write_reg: 472: failed! [ 1347.443031] mxl5007t_attach: error -121 on line 9
Re: [REVIEW PATCH 00/42] go7007: complete overhaul
On Mon March 11 2013 12:45:38 Hans Verkuil wrote: > Hi all, > > This patch series updates the staging go7007 driver to the latest > V4L2 frameworks and actually makes it work reliably. > > Some highlights: > > - moved the custom i2c drivers to media/i2c. > - replaced the s2250-loader by a common loader for all the supported > devices. > - replaced all MPEG-related custom ioctls by standard ioctls and FMT > support. > - added the saa7134-go7007 combination (similar to the saa7134-empress). > > In addition I've made some V4L2 core and saa7115 changes (the first 6 > patches): > > - eliminate false lockdep warnings when dealing with nested control > handlers. This patch is a slightly modified version from the one Andy > posted a long time ago. > - add support to easily test if any subdevices support a particular operation. > - fix a few bugs in the code that tests if an ioctl is available: it didn't > take 'disabling of ioctls' into account. > - added additional configuration flags to saa7115, needed by the go7007. > - improved querystd support in saa7115. > > This driver now passes all v4l2-compliance tests. > > Volokh, I've merged your tw2804 v4l2 framework cleanup patches into one > with my modifications on top. I hope you don't mind. > > It has been tested with: > > - Plextor PX-TV402U (PAL model) > - Sensoray S2250S (generously provided by Sensoray, all audio inputs > now work!) > - Sensoray Model 614 (saa7134+go7007 PCI board, generously provided by > Sensoray) > - WIS X-Men II sensor board (generously provided by Sensoray) > - Adlink PCI-MPG24 surveillance board and it has also been tested with: - Plextor PX-M402U (it arrived today) 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] [media] soc_camera: remove two outdated selects
Release v2.6.30 removed the MT9M001_PCA9536_SWITCH and MT9V022_PCA9536_SWITCH Kconfig symbols, in commits 36034dc325ecab63c8cfb992fbf9a1a8e94738a2 ("V4L/DVB (11032): mt9m001: allow setting of bus width from board code") and e958e27adeade7fa085dd396a8a0dfaef7e338c1 ("V4L/DVB (11033): mt9v022: allow setting of bus width from board code"). These two commits removed all gpio related code from these two drivers. But they skipped removing their two selects of GPIO_PCA953X. Remove these now as they are outdated. Their dependencies can never evaluate to true anyhow. Signed-off-by: Paul Bolle --- Tested by grepping the tree. drivers/media/i2c/soc_camera/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig index 6dff2b7..23d352f 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig @@ -9,7 +9,6 @@ config SOC_CAMERA_IMX074 config SOC_CAMERA_MT9M001 tristate "mt9m001 support" depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9M001_PCA9536_SWITCH help This driver supports MT9M001 cameras from Micron, monochrome and colour models. @@ -36,7 +35,6 @@ config SOC_CAMERA_MT9T112 config SOC_CAMERA_MT9V022 tristate "mt9v022 and mt9v024 support" depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9V022_PCA9536_SWITCH help This driver supports MT9V022 cameras from Micron -- 1.7.11.7 -- 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: Custom device names for v4l2 devices
Hi Vinay, On Monday 11 March 2013 10:55:37 vka...@codeaurora.org wrote: > > Names of V4L2 device nodes keep on varying depending on target, on some > > targets, the device node assigned to my device is /dev/video21 and on some > > it is /dev/video15. In order to determine my device, i am opening it, > > reading the capabilities, enumerating its formats and then chose the one > > matching my requirements. This is impacting start-up latency. One way to > > resolve this without impacting start-up latency is to give custom name to > > my V4L2 device node (/dev/custom_name instead of /dev/video21). This needs > > following change in V4L2 framework. Please review this patch. If you have > > faced similar problem please let me know. Shouldn't this be implemented in userspace as udev rules instead ? > > --- a/drivers/media/video/v4l2-dev.c > > +++ b/drivers/media/video/v4l2-dev.c > > @@ -676,7 +676,8 @@ int __video_register_device(struct video_device *vdev, > > int type, int nr, > > > > vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); > > if (vdev->parent) > > > > vdev->dev.parent = vdev->parent; > > > > - dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); > > + if (!dev_name(&vdev->dev)) > > + dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); > > > > ret = device_register(&vdev->dev); > > if (ret < 0) { > > > > printk(KERN_ERR "%s: device_register failed\n", __func__); -- Regards, Laurent Pinchart -- 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
cron job: media_tree daily build: WARNINGS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Mon Mar 11 19:00:22 CET 2013 git branch: test git hash: 457ba4ce4f435d0b4dd82a0acc6c796e541a2ea7 gcc version:i686-linux-gcc (GCC) 4.7.2 host hardware: x86_64 host os:3.8.03-marune linux-git-arm-davinci: WARNINGS linux-git-arm-exynos: WARNINGS linux-git-arm-omap: WARNINGS linux-git-blackfin: WARNINGS linux-git-i686: OK linux-git-m32r: OK linux-git-mips: WARNINGS linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.31.14-i686: WARNINGS linux-2.6.32.27-i686: WARNINGS linux-2.6.33.7-i686: WARNINGS linux-2.6.34.7-i686: WARNINGS linux-2.6.35.9-i686: WARNINGS linux-2.6.36.4-i686: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-3.0.60-i686: WARNINGS linux-3.1.10-i686: WARNINGS linux-3.2.37-i686: WARNINGS linux-3.3.8-i686: WARNINGS linux-3.4.27-i686: WARNINGS linux-3.5.7-i686: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.8-i686: OK linux-3.9-rc1-i686: OK linux-2.6.31.14-x86_64: WARNINGS linux-2.6.32.27-x86_64: WARNINGS linux-2.6.33.7-x86_64: WARNINGS linux-2.6.34.7-x86_64: WARNINGS linux-2.6.35.9-x86_64: WARNINGS linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.37-x86_64: WARNINGS linux-3.3.8-x86_64: WARNINGS linux-3.4.27-x86_64: WARNINGS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9-rc1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- 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
[REVIEW PATCH 03/15] au0828: frequency handling fixes.
From: Hans Verkuil - define an initial frequency - return an error if g_frequency is called for an invalid tuner index - get the clamped frequency value after setting it: i.e. the tuner driver may clamp the given frequency to a valid frequency range and ctrl_freq should get that actual clamped frequency. - remove obsolete tuner type checks (done by the core). Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 4254b2c..25b18d397 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1521,8 +1521,6 @@ static int vidioc_s_tuner(struct file *file, void *priv, if (t->index != 0) return -EINVAL; - t->type = V4L2_TUNER_ANALOG_TV; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); @@ -1544,7 +1542,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; - freq->type = V4L2_TUNER_ANALOG_TV; + if (freq->tuner != 0) + return -EINVAL; freq->frequency = dev->ctrl_freq; return 0; } @@ -1557,10 +1556,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (freq->tuner != 0) return -EINVAL; - if (freq->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - dev->ctrl_freq = freq->frequency; if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); @@ -1575,6 +1570,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, } v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq); + /* Get the actual set (and possibly clamped) frequency */ + v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, freq); + dev->ctrl_freq = freq->frequency; if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0); @@ -1978,6 +1976,7 @@ int au0828_analog_register(struct au0828_dev *dev, dev->frame_size = dev->field_size << 1; dev->bytesperline = dev->width << 1; dev->ctrl_ainput = 0; + dev->ctrl_freq = 960; /* allocate and fill v4l2 video struct */ dev->vdev = video_device_alloc(); -- 1.7.10.4 -- 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
[REVIEW PATCH 04/15] au0828: fix intendation coding style issue.
From: Hans Verkuil No code change, just fixing a wrong indentation. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 25b18d397..e3d8a3c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1561,12 +1561,12 @@ static int vidioc_s_frequency(struct file *file, void *priv, dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); if (dev->std_set_in_tuner_core == 0) { - /* If we've never sent the standard in tuner core, do so now. We -don't do this at device probe because we don't want to incur -the cost of a firmware load */ - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, - dev->vdev->tvnorms); - dev->std_set_in_tuner_core = 1; + /* If we've never sent the standard in tuner core, do so now. + We don't do this at device probe because we don't want to + incur the cost of a firmware load */ + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, +dev->vdev->tvnorms); + dev->std_set_in_tuner_core = 1; } v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq); -- 1.7.10.4 -- 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
[REVIEW PATCH 08/15] au0828: add try_fmt_vbi support, zero vbi.reserved, pix.priv.
From: Hans Verkuil Also get rid of unnecessary format type check. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 07287ef..3c3e4d6 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1182,9 +1182,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd, int width = format->fmt.pix.width; int height = format->fmt.pix.height; - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - /* If they are demanding a format other than the one we support, bail out (tvtime asks for UYVY and then retries with YUYV) */ if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY) @@ -1203,6 +1200,7 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd, format->fmt.pix.sizeimage = width * height * 2; format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; format->fmt.pix.field = V4L2_FIELD_INTERLACED; + format->fmt.pix.priv = 0; if (cmd == VIDIOC_TRY_FMT) return 0; @@ -1289,6 +1287,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.sizeimage = dev->frame_size; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */ f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.priv = 0; return 0; } @@ -1595,6 +1594,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, format->fmt.vbi.count[1] = dev->vbi_height; format->fmt.vbi.start[0] = 21; format->fmt.vbi.start[1] = 284; + memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved)); return 0; } @@ -1878,6 +1878,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .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_enumaudio = vidioc_enumaudio, .vidioc_g_audio = vidioc_g_audio, -- 1.7.10.4 -- 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
[REVIEW PATCH 05/15] au0828: fix audio input handling.
From: Hans Verkuil - V4L2_CAP_AUDIO was set, but enumaudio was not implemented. - audioset was never filled by enum_input - ctrl_ainput was never updated when switching the video input - g_audio was broken due to faulty logic: g_audio should set the index, it doesn't receive it from the user. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 35 +++ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index e3d8a3c..e4a24fa 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1373,10 +1373,13 @@ static int vidioc_enum_input(struct file *file, void *priv, input->index = tmp; strcpy(input->name, inames[AUVI_INPUT(tmp).type]); if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) || - (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) + (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) { input->type |= V4L2_INPUT_TYPE_TUNER; - else + input->audioset = 1; + } else { input->type |= V4L2_INPUT_TYPE_CAMERA; + input->audioset = 2; + } input->std = dev->vdev->tvnorms; @@ -1408,12 +1411,15 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index) switch (AUVI_INPUT(index).type) { case AU0828_VMUX_SVIDEO: dev->input_type = AU0828_VMUX_SVIDEO; + dev->ctrl_ainput = 1; break; case AU0828_VMUX_COMPOSITE: dev->input_type = AU0828_VMUX_COMPOSITE; + dev->ctrl_ainput = 1; break; case AU0828_VMUX_TELEVISION: dev->input_type = AU0828_VMUX_TELEVISION; + dev->ctrl_ainput = 0; break; default: dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n", @@ -1450,23 +1456,32 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index) return 0; } +static int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + + if (a->index == 0) + strcpy(a->name, "Television"); + else + strcpy(a->name, "Line in"); + + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) { struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; - unsigned int index = a->index; - if (a->index > 1) - return -EINVAL; - - index = dev->ctrl_ainput; - if (index == 0) + a->index = dev->ctrl_ainput; + if (a->index == 0) strcpy(a->name, "Television"); else strcpy(a->name, "Line in"); a->capability = V4L2_AUDCAP_STEREO; - a->index = index; return 0; } @@ -1474,6 +1489,7 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio { struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; + if (a->index != dev->ctrl_ainput) return -EINVAL; return 0; @@ -1876,6 +1892,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, + .vidioc_enumaudio = vidioc_enumaudio, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, .vidioc_cropcap = vidioc_cropcap, -- 1.7.10.4 -- 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
[REVIEW PATCH 09/15] au0828: replace deprecated current_norm by g_std.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 15 +-- drivers/media/usb/au0828/au0828.h |1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 3c3e4d6..62308fe 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1322,7 +1322,7 @@ out: return rc; } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) { struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; @@ -1339,10 +1339,20 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0); + dev->std = *norm; return 0; } +static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) +{ + struct au0828_fh *fh = priv; + struct au0828_dev *dev = fh->dev; + + *norm = dev->std; + return 0; +} + static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *input) { @@ -1889,6 +1899,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_qbuf= vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_s_std = vidioc_s_std, + .vidioc_g_std = vidioc_g_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, @@ -1913,7 +1924,6 @@ static const struct video_device au0828_video_template = { .release= video_device_release, .ioctl_ops = &video_ioctl_ops, .tvnorms= V4L2_STD_NTSC_M, - .current_norm = V4L2_STD_NTSC_M, }; /**/ @@ -1982,6 +1992,7 @@ int au0828_analog_register(struct au0828_dev *dev, dev->bytesperline = dev->width << 1; dev->ctrl_ainput = 0; dev->ctrl_freq = 960; + dev->std = V4L2_STD_NTSC_M; /* allocate and fill v4l2 video struct */ dev->vdev = video_device_alloc(); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index ad40048..ef1f57f 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -222,6 +222,7 @@ struct au0828_dev { int vbi_width; int vbi_height; u32 vbi_read; + v4l2_std_id std; u32 field_size; u32 frame_size; u32 bytesperline; -- 1.7.10.4 -- 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
[REVIEW PATCH 12/15] au0828: simplify i2c_gate_ctrl.
From: Hans Verkuil Turn it into a simple function. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index a41e5ae..ac89b2c5 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -59,6 +59,12 @@ do {\ } \ } while (0) +static inline void i2c_gate_ctrl(struct au0828_dev *dev, int val) +{ + if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) + dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, val); +} + static inline void print_err_status(struct au0828_dev *dev, int packet, int status) { @@ -1320,8 +1326,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); + i2c_gate_ctrl(dev, 1); /* FIXME: when we support something other than NTSC, we are going to have to make the au0828 bridge adjust the size of its capture @@ -1330,8 +1335,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm); dev->std_set_in_tuner_core = 1; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0); + i2c_gate_ctrl(dev, 0); dev->std = *norm; return 0; @@ -1517,13 +1521,11 @@ static int vidioc_s_tuner(struct file *file, void *priv, if (t->index != 0) return -EINVAL; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); + i2c_gate_ctrl(dev, 1); v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0); + i2c_gate_ctrl(dev, 0); dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal, t->afc); @@ -1553,8 +1555,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (freq->tuner != 0) return -EINVAL; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1); + i2c_gate_ctrl(dev, 1); if (dev->std_set_in_tuner_core == 0) { /* If we've never sent the standard in tuner core, do so now. @@ -1570,8 +1571,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, freq); dev->ctrl_freq = freq->frequency; - if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl) - dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0); + i2c_gate_ctrl(dev, 0); au0828_analog_stream_reset(dev); -- 1.7.10.4 -- 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
[REVIEW PATCH 11/15] au0828: fix disconnect sequence.
From: Hans Verkuil The driver crashed when the device was disconnected while an application still had a device node open. Fixed by using the release() callback of struct v4l2_device. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-core.c | 48 --- drivers/media/usb/au0828/au0828-video.c |9 +- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index ffd3bcb..bd9d19a 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -125,36 +125,48 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, return status; } -static void au0828_usb_disconnect(struct usb_interface *interface) +static void au0828_usb_release(struct au0828_dev *dev) { - struct au0828_dev *dev = usb_get_intfdata(interface); - - dprintk(1, "%s()\n", __func__); - - /* Digital TV */ - au0828_dvb_unregister(dev); - -#ifdef CONFIG_VIDEO_AU0828_V4L2 - if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) - au0828_analog_unregister(dev); -#endif - /* I2C */ au0828_i2c_unregister(dev); + kfree(dev); +} + #ifdef CONFIG_VIDEO_AU0828_V4L2 +static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) +{ + struct au0828_dev *dev = + container_of(v4l2_dev, struct au0828_dev, v4l2_dev); + v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); + au0828_usb_release(dev); +} #endif - usb_set_intfdata(interface, NULL); +static void au0828_usb_disconnect(struct usb_interface *interface) +{ + struct au0828_dev *dev = usb_get_intfdata(interface); + + dprintk(1, "%s()\n", __func__); + + /* Digital TV */ + au0828_dvb_unregister(dev); + usb_set_intfdata(interface, NULL); mutex_lock(&dev->mutex); dev->usbdev = NULL; mutex_unlock(&dev->mutex); - - kfree(dev); - +#ifdef CONFIG_VIDEO_AU0828_V4L2 + if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) { + au0828_analog_unregister(dev); + v4l2_device_disconnect(&dev->v4l2_dev); + v4l2_device_put(&dev->v4l2_dev); + return; + } +#endif + au0828_usb_release(dev); } static int au0828_usb_probe(struct usb_interface *interface, @@ -203,6 +215,8 @@ static int au0828_usb_probe(struct usb_interface *interface, dev->boardnr = id->driver_info; #ifdef CONFIG_VIDEO_AU0828_V4L2 + dev->v4l2_dev.release = au0828_usb_v4l2_release; + /* Create the v4l2_device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 62308fe..a41e5ae 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1063,14 +1063,7 @@ static int au0828_v4l2_close(struct file *filp) res_free(fh, AU0828_RESOURCE_VBI); } - if (dev->users == 1) { - if (dev->dev_state & DEV_DISCONNECTED) { - au0828_analog_unregister(dev); - kfree(fh); - kfree(dev); - return 0; - } - + if (dev->users == 1 && video_is_registered(video_devdata(filp))) { au0828_analog_stream_disable(dev); au0828_uninit_isoc(dev); -- 1.7.10.4 -- 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
[REVIEW PATCH 15/15] au0828: improve firmware loading & locking.
From: Hans Verkuil - open/close/read and poll need to take the core lock as well. - when the tuner goes to sleep we should set std_set_in_tuner_core to 0 since the tuner loses the firmware at that time. - initialize the tuner if std_set_in_tuner_core == 0 whenever: 1) g/s_tuner, s_std or s_frequency is called 2) read or poll is called 3) streamon is called Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 66 --- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index cc1e861..1aee330 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -998,11 +998,17 @@ static int au0828_v4l2_open(struct file *filp) v4l2_fh_init(&fh->fh, vdev); filp->private_data = fh; - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { + if (mutex_lock_interruptible(&dev->lock)) { + kfree(fh); + return -ERESTARTSYS; + } + if (dev->users == 0) { /* set au0828 interface0 to AS5 here again */ ret = usb_set_interface(dev->usbdev, 0, 5); if (ret < 0) { + mutex_unlock(&dev->lock); printk(KERN_INFO "Au0828 can't set alternate to 5!\n"); + kfree(fh); return -EBUSY; } @@ -1017,6 +1023,7 @@ static int au0828_v4l2_open(struct file *filp) } dev->users++; + mutex_unlock(&dev->lock); videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops, NULL, &dev->slock, @@ -1044,6 +1051,7 @@ static int au0828_v4l2_close(struct file *filp) v4l2_fh_del(&fh->fh); v4l2_fh_exit(&fh->fh); + mutex_lock(&dev->lock); if (res_check(fh, AU0828_RESOURCE_VIDEO)) { /* Cancel timeout thread in case they didn't call streamoff */ dev->vid_timeout_running = 0; @@ -1069,6 +1077,7 @@ static int au0828_v4l2_close(struct file *filp) /* Save some power by putting tuner to sleep */ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); + dev->std_set_in_tuner_core = 0; /* When close the device, set the usb intf0 into alt0 to free USB bandwidth */ @@ -1076,6 +1085,7 @@ static int au0828_v4l2_close(struct file *filp) if (ret < 0) printk(KERN_INFO "Au0828 can't set alternate to 0!\n"); } + mutex_unlock(&dev->lock); videobuf_mmap_free(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vbiq); @@ -1085,6 +1095,26 @@ static int au0828_v4l2_close(struct file *filp) return 0; } +/* Must be called with dev->lock held */ +static void au0828_init_tuner(struct au0828_dev *dev) +{ + struct v4l2_frequency f = { + .frequency = dev->ctrl_freq, + .type = V4L2_TUNER_ANALOG_TV, + }; + + if (dev->std_set_in_tuner_core) + return; + dev->std_set_in_tuner_core = 1; + i2c_gate_ctrl(dev, 1); + /* If we've never sent the standard in tuner core, do so now. + We don't do this at device probe because we don't want to + incur the cost of a firmware load */ + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->std); + v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); + i2c_gate_ctrl(dev, 0); +} + static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf, size_t count, loff_t *pos) { @@ -1096,6 +1126,11 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf, if (rc < 0) return rc; + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + au0828_init_tuner(dev); + mutex_unlock(&dev->lock); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (res_locked(dev, AU0828_RESOURCE_VIDEO)) return -EBUSY; @@ -1136,6 +1171,11 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait) if (!(req_events & (POLLIN | POLLRDNORM))) return res; + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + au0828_init_tuner(dev); + mutex_unlock(&dev->lock); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (!res_get(fh, AU0828_RESOURCE_VIDEO)) return POLLERR; @@ -1319,6 +1359,10 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; + dev->std = *norm; + + au0828_init_tuner(dev); + i2c_gate_ctrl(dev, 1); /* FIXME: when we s
[REVIEW PATCH 14/15] au0828: fix initial video routing.
From: Hans Verkuil After loading the module the initial video routing is not setup. Explicitly call s_input to get this right. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 30 ++ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 1f06d97..cc1e861 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1391,20 +1391,10 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) return 0; } -static int vidioc_s_input(struct file *file, void *priv, unsigned int index) +static void au0828_s_input(struct au0828_dev *dev, int index) { - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; int i; - dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__, - index); - if (index >= AU0828_MAX_INPUT) - return -EINVAL; - if (AUVI_INPUT(index).type == 0) - return -EINVAL; - dev->ctrl_input = index; - switch (AUVI_INPUT(index).type) { case AU0828_VMUX_SVIDEO: dev->input_type = AU0828_VMUX_SVIDEO; @@ -1419,7 +1409,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index) dev->ctrl_ainput = 0; break; default: - dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n", + dprintk(1, "unknown input type set [%d]\n", AUVI_INPUT(index).type); break; } @@ -1450,6 +1440,21 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index) v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, AUVI_INPUT(index).amux, 0, 0); +} + +static int vidioc_s_input(struct file *file, void *priv, unsigned int index) +{ + struct au0828_fh *fh = priv; + struct au0828_dev *dev = fh->dev; + + dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__, + index); + if (index >= AU0828_MAX_INPUT) + return -EINVAL; + if (AUVI_INPUT(index).type == 0) + return -EINVAL; + dev->ctrl_input = index; + au0828_s_input(dev, index); return 0; } @@ -1981,6 +1986,7 @@ int au0828_analog_register(struct au0828_dev *dev, dev->ctrl_ainput = 0; dev->ctrl_freq = 960; dev->std = V4L2_STD_NTSC_M; + au0828_s_input(dev, 0); /* allocate and fill v4l2 video struct */ dev->vdev = video_device_alloc(); -- 1.7.10.4 -- 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
[REVIEW PATCH 06/15] au0828: convert to the control framework.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-core.c | 15 ++-- drivers/media/usb/au0828/au0828-video.c | 39 ++- drivers/media/usb/au0828/au0828.h |2 ++ 3 files changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 1e6f40e..ffd3bcb 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -143,6 +143,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_i2c_unregister(dev); #ifdef CONFIG_VIDEO_AU0828_V4L2 + v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); #endif @@ -205,12 +206,22 @@ static int au0828_usb_probe(struct usb_interface *interface, /* Create the v4l2_device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { - printk(KERN_ERR "%s() v4l2_device_register failed\n", + pr_err("%s() v4l2_device_register failed\n", __func__); mutex_unlock(&dev->lock); kfree(dev); - return -EIO; + return retval; } + /* This control handler will inherit the controls from au8522 */ + retval = v4l2_ctrl_handler_init(&dev->v4l2_ctrl_hdl, 4); + if (retval) { + pr_err("%s() v4l2_ctrl_handler_init failed\n", + __func__); + mutex_unlock(&dev->lock); + kfree(dev); + return retval; + } + dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl; #endif /* Power Up the bridge */ diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index e4a24fa..7d762c0 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1226,18 +1226,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd, } -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); - if (qc->type) - return 0; - else - return -EINVAL; -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1495,26 +1483,6 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio return 0; } -static int vidioc_g_ctrl(struct file *file, void *priv, -struct v4l2_control *ctrl) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); - return 0; - -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); - return 0; -} - static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct au0828_fh *fh = priv; @@ -1904,9 +1872,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon= vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_g_tuner = vidioc_g_tuner, @@ -2012,13 +1977,13 @@ int au0828_analog_register(struct au0828_dev *dev, /* Fill the video capture device struct */ *dev->vdev = au0828_video_template; - dev->vdev->parent = &dev->usbdev->dev; + dev->vdev->v4l2_dev = &dev->v4l2_dev; dev->vdev->lock = &dev->lock; strcpy(dev->vdev->name, "au0828a video"); /* Setup the VBI device */ *dev->vbi_dev = au0828_video_template; - dev->vbi_dev->parent = &dev->usbdev->dev; + dev->vbi_dev->v4l2_dev = &dev->v4l2_dev; dev->vbi_dev->lock = &dev->lock; strcpy(dev->vbi_dev->name, "au0828a vbi"); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index e579ff6..803af10 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -28,6 +28,7 @@ #include #include #include +#include /* DVB */ #include "demux.h" @@ -202,6 +203,7 @@ struct au0828_dev { #ifdef CONFIG_VIDEO_AU0828_V4L2 /* Analog */ struct
[REVIEW PATCH 13/15] au0828: don't change global state information on open().
From: Hans Verkuil Just opening a device shouldn't have any side-effects. Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c |9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index ac89b2c5..1f06d97 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1005,11 +1005,6 @@ static int au0828_v4l2_open(struct file *filp) printk(KERN_INFO "Au0828 can't set alternate to 5!\n"); return -EBUSY; } - dev->width = NTSC_STD_W; - dev->height = NTSC_STD_H; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->width * dev->height; - dev->bytesperline = dev->width * 2; au0828_analog_stream_enable(dev); au0828_analog_stream_reset(dev); @@ -1031,8 +1026,6 @@ static int au0828_v4l2_open(struct file *filp) &dev->lock); /* VBI Setup */ - dev->vbi_width = 720; - dev->vbi_height = 1; videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops, NULL, &dev->slock, V4L2_BUF_TYPE_VBI_CAPTURE, @@ -1983,6 +1976,8 @@ int au0828_analog_register(struct au0828_dev *dev, dev->field_size = dev->width * dev->height; dev->frame_size = dev->field_size << 1; dev->bytesperline = dev->width << 1; + dev->vbi_width = 720; + dev->vbi_height = 1; dev->ctrl_ainput = 0; dev->ctrl_freq = 960; dev->std = V4L2_STD_NTSC_M; -- 1.7.10.4 -- 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
[REVIEW PATCH 02/15] au0828: fix querycap.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 8b9e826..4254b2c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1241,20 +1241,25 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct au0828_fh *fh = priv; + struct video_device *vdev = video_devdata(file); + struct au0828_fh *fh = priv; struct au0828_dev *dev = fh->dev; strlcpy(cap->driver, "au0828", sizeof(cap->driver)); strlcpy(cap->card, dev->board.name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); + usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info)); - /*set the device capabilities */ - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_AUDIO | + /* set the device capabilities */ + cap->device_caps = V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_TUNER; + if (vdev->vfl_type == VFL_TYPE_GRABBER) + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + else + cap->device_caps |= V4L2_CAP_VBI_CAPTURE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE; return 0; } -- 1.7.10.4 -- 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
[REVIEW PATCH 10/15] au8522_decoder: remove obsolete control ops.
From: Hans Verkuil Now that au0828 has been converted to the control framework these compatilibity ops are no longer needed. Signed-off-by: Hans Verkuil --- drivers/media/dvb-frontends/au8522_decoder.c |7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index be2c802..aa7be74 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -649,13 +649,6 @@ static int au8522_g_chip_ident(struct v4l2_subdev *sd, static const struct v4l2_subdev_core_ops au8522_core_ops = { .log_status = v4l2_ctrl_subdev_log_status, - .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, - .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, - .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, - .g_ctrl = v4l2_subdev_g_ctrl, - .s_ctrl = v4l2_subdev_s_ctrl, - .queryctrl = v4l2_subdev_queryctrl, - .querymenu = v4l2_subdev_querymenu, .g_chip_ident = au8522_g_chip_ident, .reset = au8522_reset, #ifdef CONFIG_VIDEO_ADV_DEBUG -- 1.7.10.4 -- 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
[REVIEW PATCH 01/15] au8522_decoder: convert to the control framework.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/media/dvb-frontends/au8522_decoder.c | 130 +- drivers/media/dvb-frontends/au8522_priv.h|6 +- 2 files changed, 46 insertions(+), 90 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 5243ba6..be2c802 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -229,15 +229,11 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) /* Provide reasonable defaults for picture tuning values */ au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07); au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed); - state->brightness = 0xed - 128; au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79); - state->contrast = 0x79; au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); - state->saturation = 0x80; au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); - state->hue = 0x00; /* Other decoder registers */ au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); @@ -489,75 +485,32 @@ static void set_audio_input(struct au8522_state *state, int aud_input) /* --- */ -static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int au8522_s_ctrl(struct v4l2_ctrl *ctrl) { - struct au8522_state *state = to_state(sd); + struct au8522_state *state = + container_of(ctrl->handler, struct au8522_state, hdl); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - state->brightness = ctrl->value; au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, - ctrl->value - 128); + ctrl->val - 128); break; case V4L2_CID_CONTRAST: - state->contrast = ctrl->value; au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, - ctrl->value); + ctrl->val); break; case V4L2_CID_SATURATION: - state->saturation = ctrl->value; au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, - ctrl->value); + ctrl->val); au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, - ctrl->value); + ctrl->val); break; case V4L2_CID_HUE: - state->hue = ctrl->value; au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, - ctrl->value >> 8); + ctrl->val >> 8); au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, - ctrl->value & 0xFF); - break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - /* Not yet implemented */ - default: - return -EINVAL; - } - - return 0; -} - -static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct au8522_state *state = to_state(sd); - - /* Note that we are using values cached in the state structure instead - of reading the registers due to issues with i2c reads not working - properly/consistently yet on the HVR-950q */ - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = state->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = state->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = state->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = state->hue; + ctrl->val & 0xFF); break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - /* Not yet supported */ default: return -EINVAL; } @@ -616,26 +569,6 @@ static int au8522_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, - AU
[REVIEW PATCH 07/15] au0828: add prio, control event and log_status support
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/media/usb/au0828/au0828-video.c | 42 --- drivers/media/usb/au0828/au0828.h |4 +++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 7d762c0..07287ef 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "au0828.h" @@ -988,6 +989,7 @@ static int au0828_v4l2_open(struct file *filp) fh->type = type; fh->dev = dev; + v4l2_fh_init(&fh->fh, vdev); filp->private_data = fh; if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { @@ -1031,6 +1033,7 @@ static int au0828_v4l2_open(struct file *filp) V4L2_FIELD_SEQ_TB, sizeof(struct au0828_buffer), fh, &dev->lock); + v4l2_fh_add(&fh->fh); return ret; } @@ -1040,6 +1043,8 @@ static int au0828_v4l2_close(struct file *filp) struct au0828_fh *fh = filp->private_data; struct au0828_dev *dev = fh->dev; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); if (res_check(fh, AU0828_RESOURCE_VIDEO)) { /* Cancel timeout thread in case they didn't call streamoff */ dev->vid_timeout_running = 0; @@ -1061,6 +1066,7 @@ static int au0828_v4l2_close(struct file *filp) if (dev->users == 1) { if (dev->dev_state & DEV_DISCONNECTED) { au0828_analog_unregister(dev); + kfree(fh); kfree(dev); return 0; } @@ -1128,23 +1134,27 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait) { struct au0828_fh *fh = filp->private_data; struct au0828_dev *dev = fh->dev; - int rc; + unsigned long req_events = poll_requested_events(wait); + unsigned int res; - rc = check_dev(dev); - if (rc < 0) - return rc; + if (check_dev(dev) < 0) + return POLLERR; + + res = v4l2_ctrl_poll(filp, wait); + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (!res_get(fh, AU0828_RESOURCE_VIDEO)) return POLLERR; - return videobuf_poll_stream(filp, &fh->vb_vidq, wait); - } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + return res | videobuf_poll_stream(filp, &fh->vb_vidq, wait); + } + if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { if (!res_get(fh, AU0828_RESOURCE_VBI)) return POLLERR; - return videobuf_poll_stream(filp, &fh->vb_vbiq, wait); - } else { - return POLLERR; + return res | videobuf_poll_stream(filp, &fh->vb_vbiq, wait); } + return POLLERR; } static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) @@ -1760,6 +1770,15 @@ static int vidioc_s_register(struct file *file, void *priv, } #endif +static int vidioc_log_status(struct file *file, void *fh) +{ + struct video_device *vdev = video_devdata(file); + + v4l2_ctrl_log_status(file, fh); + v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status); + return 0; +} + static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb) { @@ -1883,6 +1902,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_register = vidioc_s_register, #endif .vidioc_g_chip_ident= vidioc_g_chip_ident, + .vidioc_log_status = vidioc_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static const struct video_device au0828_video_template = { @@ -1979,12 +2001,14 @@ int au0828_analog_register(struct au0828_dev *dev, *dev->vdev = au0828_video_template; dev->vdev->v4l2_dev = &dev->v4l2_dev; dev->vdev->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags); strcpy(dev->vdev->name, "au0828a video"); /* Setup the VBI device */ *dev->vbi_dev = au0828_video_template; dev->vbi_dev->v4l2_dev = &dev->v4l2_dev; dev->vbi_dev->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags); strcpy(dev->vbi_dev->name, "au0828a vbi"); /* Register the v4l2 device */ diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 803af10..ad40048 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/a
[REVIEW PATCH 00/15] au0828: v4l2-compliance cleanups
Hi all, This patch series converts the au0828/au8522 drivers to the latest frameworks, except for vb2 as usual. Tested with a WinTV aero generously donated by Hauppauge some time ago. I also did a lot of fixes in the disconnect handling and setting up the right routing/std information at the right time. It is now working correctly as far as I can tell: if I stick it in my PC and run qv4l2 it actually picks up the tuner signal right away (if I set it to the correct frequency of course). If someone has additional hardware, then that would be nice if that can be tested as well. My git branch is here: http://git.linuxtv.org/hverkuil/media_tree.git/shortlog/refs/heads/au0828 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
Re: omap3isp: iommu register problem.
Hi Javier, On Monday 11 March 2013 16:28:58 javier Martin wrote: > On 11 March 2013 16:01, Laurent Pinchart wrote: > > On Monday 11 March 2013 13:18:12 javier Martin wrote: > >> I've just found the following thread where te problem is explained: > >> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/08636 > >> 4.h tml > >> > >> The problem is related with the order iommu and omap3isp are probed > >> when both are built-in. If I load omap3isp as a module the problem is > >> gone. > >> > >> However, according to the previous thread, omap3isp register should > >> return error but an oops should not be generated. So I think there is > >> a bug here anyway. > > > > Does the following patch (compile-tested only) fix the issue ? > > > > diff --git a/drivers/media/platform/omap3isp/isp.c > > b/drivers/media/platform/omap3isp/isp.c index 6e5ad8e..4d889be 100644 > > --- a/drivers/media/platform/omap3isp/isp.c > > +++ b/drivers/media/platform/omap3isp/isp.c > > @@ -2123,6 +2123,7 @@ static int isp_probe(struct platform_device *pdev) > > ret = iommu_attach_device(isp->domain, &pdev->dev); > > if (ret) { > > dev_err(&pdev->dev, "can't attach iommu device: %d\n", > > ret); > > + ret = -EPROBE_DEFER; > > goto free_domain; > > } > > > > @@ -2161,6 +2162,7 @@ detach_dev: > > iommu_detach_device(isp->domain, &pdev->dev); > > free_domain: > > iommu_domain_free(isp->domain); > > + isp->domain = NULL; > > error_isp: > > omap3isp_put(isp); > > error: > > Yes, that solves the problems. Great. I'll push the patch to v3.10 then. > [2.706939] omap3isp omap3isp: Revision 15.0 found > [2.712402] omap_iommu_attach: 1 > [2.715942] omap_iommu_attach: 2 > [2.719329] omap_iommu_attach: 3 > [2.722778] omap_iommu_attach: 4 > [2.726135] omap_iommu_attach: 5 > [2.729553] iommu_enable: 1 > [2.732482] iommu_enable: 2, arch_iommu = c0599adc > [2.737548] iommu_enable: 3 > [2.740478] iommu_enable: 5 > [2.743652] omap-iommu omap-iommu.0: mmu_isp: version 1.1 > [2.749389] omap_iommu_attach: 6 > [2.752807] omap_iommu_attach: 7 > [2.756195] omap_iommu_attach: 8 > [2.759613] omap_iommu_attach: 9 > [2.763977] omap3isp omap3isp: hist: DMA channel = 2 > [2.770904] drivers/rtc/hctosys.c: unable to open rtc device (rtc0) > [2.778839] ALSA device list: > [2.781982] No soundcards found. > [2.799285] mt9m111 2-0048: mt9m111: driver needs platform data > [2.805603] mt9m111: probe of 2-0048 failed with error -22 > [2.814849] omap3isp omap3isp: isp_register_subdev_group: Unable to > register subdev mt9m111 > > The error I get now seems more related to the fact that I am trying to > use a soc-camera sensor (mt9m111) with a non-soc-camera host > (omap3isp) and I probably need some extra platform code. > > Do you know any board in mainline in a similar situation? There's none yet I'm afraid. We don't have the necessary infrastructure in place yet to allow this. Guennadi might be able to give you a bit more information about the current status. -- Regards, Laurent Pinchart -- 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] block i2c tuner reads for Avermedia Twinstar in the af9035 driver
On Lunes, 11 de marzo de 2013 14:57:37 Antti Palosaari escribió: > On 03/11/2013 01:51 PM, Jose Alberto Reguero wrote: > > On Lunes, 11 de febrero de 2013 14:48:18 Jose Alberto Reguero escribió: > >> On Domingo, 10 de febrero de 2013 22:11:53 Antti Palosaari escribió: > >>> On 02/10/2013 09:43 PM, Jose Alberto Reguero wrote: > This patch block the i2c tuner reads for Avermedia Twinstar. If it's > needed other pids can be added. > > Signed-off-by: Jose Alberto Reguero > > diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.c > linux.new/drivers/media/usb/dvb-usb-v2/af9035.c --- > linux/drivers/media/usb/dvb-usb-v2/af9035.c 2013-01-07 > 05:45:57.0 +0100 +++ > linux.new/drivers/media/usb/dvb-usb-v2/af9035.c 2013-02-08 > 22:55:08.304089054 +0100 @@ -232,7 +232,11 @@ static int > af9035_i2c_master_xfer(struct > > buf[3] = 0x00; /* reg addr MSB */ > buf[4] = 0x00; /* reg addr LSB */ > memcpy(&buf[5], msg[0].buf, msg[0].len); > > -ret = af9035_ctrl_msg(d, &req); > +if (state->block_read) { > +msg[1].buf[0] = 0x3f; > +ret = 0; > +} else > +ret = af9035_ctrl_msg(d, &req); > > } > > } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { > > if (msg[0].len > 40) { > > @@ -638,6 +642,17 @@ static int af9035_read_config(struct dvb > > for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) > > state->af9033_config[i].clock = clock_lut[tmp]; > > +state->block_read = false; > + > +if (le16_to_cpu(d->udev->descriptor.idVendor) == > USB_VID_AVERMEDIA && > +le16_to_cpu(d->udev->descriptor.idProduct) == > +USB_PID_AVERMEDIA_TWINSTAR) { > +dev_dbg(&d->udev->dev, > +"%s: AverMedia Twinstar: block i2c read > from tuner\n", > +__func__); > +state->block_read = true; > +} > + > > return 0; > > err: > diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.h > linux.new/drivers/media/usb/dvb-usb-v2/af9035.h --- > linux/drivers/media/usb/dvb-usb-v2/af9035.h 2013-01-07 > 05:45:57.0 +0100 +++ > linux.new/drivers/media/usb/dvb-usb-v2/af9035.h 2013-02-08 > 22:52:42.293842710 +0100 @@ -54,6 +54,7 @@ struct usb_req { > > struct state { > > u8 seq; /* packet sequence number */ > bool dual_mode; > > +bool block_read; > > struct af9033_config af9033_config[2]; > > }; > >>> > >>> Could you test if faking tuner ID during attach() is enough? > >>> > >>> Also, I would like to know what is returned error code from firmware > >>> when it fails. Enable debugs to see it. It should print something like > >>> that: af9035_ctrl_msg: command=03 failed fw error=2 > >>> > >>> > >>> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c > >>> b/drivers/media/usb/dvb-usb-v2/af9035.c > >>> index a1e953a..5a4f28d 100644 > >>> --- a/drivers/media/usb/dvb-usb-v2/af9035.c > >>> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c > >>> @@ -1082,9 +1082,22 @@ static int af9035_tuner_attach(struct > >>> dvb_usb_adapter *adap) > >>> > >>> tuner_addr = 0x60 | 0x80; /* I2C bus hack */ > >>> > >>> } > >>> > >>> + // fake used tuner for demod firmware / i2c adapter > >>> + if (adap->id == 0) > >>> + ret = af9035_wr_reg(d, 0x00f641, > >>> AF9033_TUNER_FC0011); > >>> + else > >>> + ret = af9035_wr_reg(d, 0x10f641, > >>> AF9033_TUNER_FC0011); > >>> + > >>> > >>> /* attach tuner */ > >>> fe = dvb_attach(mxl5007t_attach, adap->fe[0], > >>> &d->i2c_adap, > >>> > >>> tuner_addr, > >>> > >>> &af9035_mxl5007t_config[adap->id]); > >>> + > >>> + // return correct tuner > >>> + if (adap->id == 0) > >>> + ret = af9035_wr_reg(d, 0x00f641, > >>> AF9033_TUNER_MXL5007T); > >>> + else > >>> + ret = af9035_wr_reg(d, 0x10f641, > >>> AF9033_TUNER_MXL5007T); > >>> + > >>> > >>> break; > >>> > >>> case AF9033_TUNER_TDA18218: > >>> /* attach tuner */ > >>> > >>> regard
[RFC PATCH 8/8] s5p-fimc: Create media links for the FIMC-IS entities
Create disabled links from the FIMC-LITE subdevs to the FIMC-IS-ISP subdev and from FIMC-IS-ISP to all FIMC subdevs. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 78 +++- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 1521dec..5304da5 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -807,9 +807,17 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, struct fimc_sensor_info *s_info = NULL; struct media_entity *sink; unsigned int flags = 0; - int ret, i; + int i, ret = 0; - for (i = 0; i < FIMC_MAX_DEVS; i++) { + if (sensor) { + s_info = v4l2_get_subdev_hostdata(sensor); + /* Skip direct FIMC links in the logical FIMC-IS sensor path */ + if (s_info && s_info->pdata.fimc_bus_type == + FIMC_BUS_TYPE_ISP_WRITEBACK) + ret = 1; + } + + for (i = 0; !ret && i < FIMC_MAX_DEVS; i++) { if (!fmd->fimc[i]) continue; /* @@ -838,7 +846,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (flags == 0 || sensor == NULL) continue; - s_info = v4l2_get_subdev_hostdata(sensor); + if (!WARN_ON(s_info == NULL)) { unsigned long irq_flags; spin_lock_irqsave(&fmd->slock, irq_flags); @@ -851,25 +859,20 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc_lite[i]) continue; - if (link_mask & (1 << (i + FIMC_MAX_DEVS))) - flags = MEDIA_LNK_FL_ENABLED; - else - flags = 0; - sink = &fmd->fimc_lite[i]->subdev.entity; ret = media_entity_create_link(source, pad, sink, - FLITE_SD_PAD_SINK, flags); + FLITE_SD_PAD_SINK, 0); if (ret) return ret; /* Notify FIMC-LITE subdev entity */ ret = media_entity_call(sink, link_setup, &sink->pads[0], - &source->pads[pad], flags); + &source->pads[pad], 0); if (ret) break; - v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n", - source->name, flags ? '=' : '-', sink->name); + v4l2_info(&fmd->v4l2_dev, "created link [%s] -> [%s]\n", + source->name, sink->name); } return 0; } @@ -878,26 +881,59 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, static int __fimc_md_create_flite_source_links(struct fimc_md *fmd) { struct media_entity *source, *sink; - unsigned int flags = MEDIA_LNK_FL_ENABLED; int i, ret = 0; for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) { struct fimc_lite *fimc = fmd->fimc_lite[i]; + if (fimc == NULL) continue; + source = &fimc->subdev.entity; sink = &fimc->vfd.entity; /* FIMC-LITE's subdev and video node */ ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA, - sink, 0, flags); + sink, 0, 0); + if (ret) + break; + /* Link from FIMC-LITE to IS-ISP subdev */ + sink = &fmd->fimc_is->isp.subdev.entity; + ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP, + sink, 0, 0); if (ret) break; - /* TODO: create links to other entities */ } return ret; } +/* Create FIMC-IS links */ +static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd) +{ + struct media_entity *source, *sink; + int i, ret; + + source = &fmd->fimc_is->isp.subdev.entity; + + for (i = 0; i < FIMC_MAX_DEVS; i++) { + if (fmd->fimc[i] == NULL) + continue; + + /* Link from IS-ISP subdev to FIMC */ + sink = &fmd->fimc[i]->vid_cap.subdev.entity; + ret = media_entity_create_link(source, FIMC_IS_SD_PAD_SRC_FIFO, + sink, FIMC_SD_PAD_SINK_FIFO, 0); + if (ret) + return ret; + } + + /* Link from IS-ISP subdev
[RFC PATCH 6/8] fimc-is: Add Exynos4x12 FIMC-IS device tree bindings documentation
Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- .../devicetree/bindings/media/exynos4-fimc-is.txt | 41 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/exynos4-fimc-is.txt diff --git a/Documentation/devicetree/bindings/media/exynos4-fimc-is.txt b/Documentation/devicetree/bindings/media/exynos4-fimc-is.txt new file mode 100644 index 000..ef994d1 --- /dev/null +++ b/Documentation/devicetree/bindings/media/exynos4-fimc-is.txt @@ -0,0 +1,41 @@ +Exynos4x12 SoC series Imaging Subsystem (FIMC-IS) + +The FIMC-IS is an subsystem for processing image signal from an image sensor. +The Exynos4x12 SoC series FIMC-IS V1.5 comprises of a dedicated ARM Cortex-A5 +processor, ISP, DRC and FD IP blocks and peripheral IPs such as I2C, SPI, UART +bus controllers, Multi-PWM and ADC. + +fimc-is node + + +Required properties: + +- compatible : should be "samsung,exynos4212-fimc-is" for Exynos4212 and + Exynos4412 SoCs; +- reg : physical base address and size of the device memory mapped + registers; +- interrupts : should contain FIMC-IS interrupts; + +The following are the FIMC-IS peripheral device nodes and can be specified +either standalone or as fimc-is child nodes. + +pmu subnode +--- + +Required properties: + - reg : should contain PMU physical base address of the memory mapped + registers and size, the value of size should be 0x3000. + + +i2c-isp (ISP I2C bus controller) nodes +-- + +Required properties: + +- compatible : should be "samsung,exynos4212-i2c-isp" for Exynos4212 and + Exynos4412 SoCs; +- reg : physical base address and size of the device memory mapped + registers; + +For the above nodes it is required to specify a pinctrl state named "default", +according to the pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt. -- 1.7.9.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
[RFC PATCH 7/8] s5p-fimc: Add fimc-is subdevs registration
This patch allows to register FIMC-IS device represented by FIMC-IS-ISP subdev to the top level media device driver. The use_isp platform data structure field allows to select whether the fimc-is ISP subdev should be tried to be registered or not. Signed-off-by: Sylwester Nawrocki Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 51 ++-- drivers/media/platform/s5p-fimc/fimc-mdevice.h | 15 +++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index e9e5337..1521dec 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -31,6 +31,7 @@ #include #include "fimc-core.h" +#include "fimc-is.h" #include "fimc-lite.h" #include "fimc-mdevice.h" #include "mipi-csis.h" @@ -85,9 +86,11 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, case GRP_ID_FIMC: /* No need to control FIMC subdev through subdev ops */ break; + case GRP_ID_FIMC_IS: + p->subdevs[IDX_IS_ISP] = sd; + break; default: - pr_warn("%s: Unknown subdev grp_id: %#x\n", - __func__, sd->grp_id); + break; } me = &sd->entity; if (me->num_pads == 1) @@ -291,6 +294,7 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) if (!client) return; + v4l2_device_unregister_subdev(sd); if (!client->dev.of_node) { @@ -341,7 +345,11 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd, goto mod_put; v4l2_set_subdev_hostdata(sd, si); - sd->grp_id = GRP_ID_SENSOR; + if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) + sd->grp_id = GRP_ID_FIMC_IS_SENSOR; + else + sd->grp_id = GRP_ID_SENSOR; + si->subdev = sd; v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", sd->name, fmd->num_sensors); @@ -360,7 +368,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, struct device_node *port, unsigned int index) { - struct device_node *rem, *endpoint; + struct device_node *rem, *endpoint, *np; struct fimc_source_info *pd; struct v4l2_of_endpoint bus_cfg; u32 tmp, reg = 0; @@ -415,6 +423,18 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n", reg, rem->full_name); } + /* +* For FIMC-IS handled sensors, that are placed under fimc-is-i2c +* device node, FIMC is connected to the FIMC-IS through its ISP +* Writeback input. Sensors are attached to the FIMC-LITE hostdata +* interface directly or through MIPI-CSIS, depending on the external +* media bus used. This needs to be handled in a more reliable way, +* not by just checking parent's node name. +*/ + if ((np = of_get_parent(rem)) && !of_node_cmp(np->name, "i2c-isp")) + pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK; + else + pd->fimc_bus_type = pd->sensor_bus_type; ret = fimc_md_of_add_sensor(fmd, rem, index); of_node_put(rem); @@ -607,6 +627,22 @@ static int register_csis_entity(struct fimc_md *fmd, return ret; } +static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is) +{ + struct v4l2_subdev *sd = &is->isp.subdev; + int ret; + + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); + if (ret) { + v4l2_err(&fmd->v4l2_dev, +"Failed to register FIMC-ISP (%d)\n", ret); + return ret; + } + + fmd->fimc_is = is; + return 0; +} + static int fimc_md_register_platform_entity(struct fimc_md *fmd, struct platform_device *pdev, int plat_entity) @@ -634,6 +670,9 @@ static int fimc_md_register_platform_entity(struct fimc_md *fmd, case IDX_CSIS: ret = register_csis_entity(fmd, pdev, drvdata); break; + case IDX_IS_ISP: + ret = register_fimc_is_entity(fmd, drvdata); + break; default: ret = -ENODEV; } @@ -697,6 +736,8 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, /* If driver of any entity isn't ready try all again later. */ if (!strcmp(node->nam
[RFC PATCH 5/8] s5p-fimc: Add ISP video capture driver stubs
This patch adds a video capture node for the FIMC-IS ISP IP block and Makefile/Kconfig to actually enable the driver's compilation. The ISP video capture driver is still a work in progress. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/Kconfig | 13 + drivers/media/platform/s5p-fimc/Makefile |4 + drivers/media/platform/s5p-fimc/fimc-isp-video.c | 414 ++ drivers/media/platform/s5p-fimc/fimc-isp-video.h | 50 +++ 4 files changed, 481 insertions(+) create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp-video.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp-video.h diff --git a/drivers/media/platform/s5p-fimc/Kconfig b/drivers/media/platform/s5p-fimc/Kconfig index c16b20d..1253e25 100644 --- a/drivers/media/platform/s5p-fimc/Kconfig +++ b/drivers/media/platform/s5p-fimc/Kconfig @@ -46,4 +46,17 @@ config VIDEO_EXYNOS_FIMC_LITE module will be called exynos-fimc-lite. endif +if (SOC_EXYNOS4212 || SOC_EXYNOS4412) && OF && !ARCH_MULTIPLATFORM + +config VIDEO_EXYNOS4_FIMC_IS + tristate "EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver" + select VIDEOBUF2_DMA_CONTIG + help + This is a V4L2 driver for Samsung EXYNOS4x12 SoC FIMC-IS + (Imaging Subsystem). + + To compile this driver as a module, choose M here: the + module will be called exynos-fimc-is. +endif + endif # VIDEO_SAMSUNG_S5P_FIMC diff --git a/drivers/media/platform/s5p-fimc/Makefile b/drivers/media/platform/s5p-fimc/Makefile index 4648514..55b171a 100644 --- a/drivers/media/platform/s5p-fimc/Makefile +++ b/drivers/media/platform/s5p-fimc/Makefile @@ -1,7 +1,11 @@ s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o fimc-mdevice.o exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o +exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o +exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o +exynos-fimc-is-objs += fimc-isp-video.o s5p-csis-objs := mipi-csis.o obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o +obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)+= exynos-fimc-is.o obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o diff --git a/drivers/media/platform/s5p-fimc/fimc-isp-video.c b/drivers/media/platform/s5p-fimc/fimc-isp-video.c new file mode 100644 index 000..bdeacaa --- /dev/null +++ b/drivers/media/platform/s5p-fimc/fimc-isp-video.c @@ -0,0 +1,414 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Sylwester Nawrocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "fimc-mdevice.h" +#include "fimc-core.h" +#include "fimc-is.h" + +static int isp_video_capture_start_streaming(struct vb2_queue *q, + unsigned int count) +{ + /* TODO: start ISP output DMA */ + return 0; +} + +static int isp_video_capture_stop_streaming(struct vb2_queue *q) +{ + /* TODO: stop ISP output DMA */ + return 0; +} + +static int isp_video_capture_queue_setup(struct vb2_queue *vq, + const struct v4l2_format *pfmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *allocators[]) +{ + const struct v4l2_pix_format_mplane *pixm = NULL; + struct fimc_isp *isp = vq->drv_priv; + struct fimc_isp_frame *frame = &isp->out_frame; + const struct fimc_fmt *fmt = isp->video_capture_format; + unsigned long wh; + int i; + + if (pfmt) { + pixm = &pfmt->fmt.pix_mp; + fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, -1); + wh = pixm->width * pixm->height; + } else { + wh = frame->f_width * frame->f_height; + } + + if (fmt == NULL) + return -EINVAL; + + *num_planes = fmt->memplanes; + + for (i = 0; i < fmt->memplanes; i++) { + unsigned int size = (wh * fmt->depth[i]) / 8; + if (pixm) + sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); + else + sizes[i] = size; + allocators[i] = isp->alloc_ctx; + } + + return 0; +} + +static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb->vb2_queue; + struct fimc_isp *isp = vq->drv_priv; + int i; + + if (isp->video_capture_format == NULL) + return -EINVAL; + + for
[RFC PATCH 4/8] s5p-fimc: Add common FIMC-IS image sensor driver
This subdev driver currently only handles an image sensor's power supplies and reset signal. There is no any I2C communication here as it is handled by the ISP's firmware. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-is-sensor.c | 308 ++ drivers/media/platform/s5p-fimc/fimc-is-sensor.h | 80 ++ 2 files changed, 388 insertions(+) create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-sensor.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-sensor.h diff --git a/drivers/media/platform/s5p-fimc/fimc-is-sensor.c b/drivers/media/platform/s5p-fimc/fimc-is-sensor.c new file mode 100644 index 000..151915c --- /dev/null +++ b/drivers/media/platform/s5p-fimc/fimc-is-sensor.c @@ -0,0 +1,308 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Sylwester Nawrocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fimc-is.h" +#include "fimc-is-sensor.h" + +#define DRIVER_NAME "FIMC-IS-SENSOR" + +static const char * const sensor_supply_names[] = { + "svdda", + "svddio", +}; + +static const struct v4l2_mbus_framefmt fimc_is_sensor_formats[] = { + { + .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + } +}; + +static struct fimc_is_sensor *sd_to_fimc_is_sensor(struct v4l2_subdev *sd) +{ + return container_of(sd, struct fimc_is_sensor, subdev); +} + +static const struct v4l2_mbus_framefmt *find_sensor_format( + struct v4l2_mbus_framefmt *mf) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fimc_is_sensor_formats); i++) + if (mf->code == fimc_is_sensor_formats[i].code) + return &fimc_is_sensor_formats[i]; + + return &fimc_is_sensor_formats[0]; +} + +static int fimc_is_sensor_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index >= ARRAY_SIZE(fimc_is_sensor_formats)) + return -EINVAL; + + code->code = fimc_is_sensor_formats[code->index].code; + return 0; +} + +static void fimc_is_sensor_try_format(struct fimc_is_sensor *sensor, + struct v4l2_mbus_framefmt *mf) +{ + const struct sensor_drv_data *dd = sensor->drvdata; + const struct v4l2_mbus_framefmt *fmt; + + fmt = find_sensor_format(mf); + mf->code = fmt->code; + v4l_bound_align_image(&mf->width, 16 + 8, dd->width, 0, + &mf->height, 12 + 8, dd->height, 0, 0); +} + +static struct v4l2_mbus_framefmt *__fimc_is_sensor_get_format( + struct fimc_is_sensor *sensor, struct v4l2_subdev_fh *fh, + u32 pad, enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL; + + return &sensor->format; +} + +static int fimc_is_sensor_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *fmt) +{ + struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); + struct v4l2_mbus_framefmt *mf; + + fimc_is_sensor_try_format(sensor, &fmt->format); + + mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which); + if (mf) { + mutex_lock(&sensor->lock); + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) + sensor->format = *mf; + mutex_unlock(&sensor->lock); + } + return 0; +} + +static int fimc_is_sensor_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *fmt) +{ + struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); + struct v4l2_mbus_framefmt *mf; + + mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which); + + mutex_lock(&sensor->lock); + fmt->format = *mf; + mutex_unlock(&sensor->lock); + return 0; +} + +static struct v4l2_subdev_pad_ops fimc_is_sensor_pad_ops = { + .enum_mbus_code = fimc_is_sensor_enum_mbus_code, + .get_fmt= fimc_is_sensor_get_fmt, + .set_fmt= fimc_is_sensor_set_fmt, +}; + +static int fimc_is_sensor_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(
[RFC PATCH 3/8] s5p-fimc: Add FIMC-IS parameter region definitions
This patch adds ISP processing parameters interface files. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-is-param.c | 971 + drivers/media/platform/s5p-fimc/fimc-is-param.h | 1018 +++ 2 files changed, 1989 insertions(+) create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-param.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-param.h diff --git a/drivers/media/platform/s5p-fimc/fimc-is-param.c b/drivers/media/platform/s5p-fimc/fimc-is-param.c new file mode 100644 index 000..5674c3b --- /dev/null +++ b/drivers/media/platform/s5p-fimc/fimc-is-param.c @@ -0,0 +1,971 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * + * Authors: Younghwan Joo + * Sylwester Nawrocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "fimc-is.h" +#include "fimc-is-command.h" +#include "fimc-is-errno.h" +#include "fimc-is-param.h" +#include "fimc-is-regs.h" +#include "fimc-is-sensor.h" + +static void __hw_param_copy(void *dst, void *src) +{ + memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE); +} + +void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is) +{ + struct param_global_shotmode *dst, *src; + + dst = &is->is_p_region->parameter.global.shotmode; + src = &is->cfg_param[is->scenario_id].global.shotmode; + __hw_param_copy(dst, src); +} + +void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is) +{ + struct param_sensor_framerate *dst, *src; + + dst = &is->is_p_region->parameter.sensor.frame_rate; + src = &is->cfg_param[is->scenario_id].sensor.frame_rate; + __hw_param_copy(dst, src); +} + +int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) +{ + struct is_param_region *par = &is->is_p_region->parameter; + struct is_config_param *cfg = &is->cfg_param[is->scenario_id]; + + switch (offset) { + case PARAM_ISP_CONTROL: + __hw_param_copy(&par->isp.control, &cfg->isp.control); + break; + + case PARAM_ISP_OTF_INPUT: + __hw_param_copy(&par->isp.otf_input, &cfg->isp.otf_input); + break; + + case PARAM_ISP_DMA1_INPUT: + __hw_param_copy(&par->isp.dma1_input, &cfg->isp.dma1_input); + break; + + case PARAM_ISP_DMA2_INPUT: + __hw_param_copy(&par->isp.dma2_input, &cfg->isp.dma2_input); + break; + + case PARAM_ISP_AA: + __hw_param_copy(&par->isp.aa, &cfg->isp.aa); + break; + + case PARAM_ISP_FLASH: + __hw_param_copy(&par->isp.flash, &cfg->isp.flash); + break; + + case PARAM_ISP_AWB: + __hw_param_copy(&par->isp.awb, &cfg->isp.awb); + break; + + case PARAM_ISP_IMAGE_EFFECT: + __hw_param_copy(&par->isp.effect, &cfg->isp.effect); + break; + + case PARAM_ISP_ISO: + __hw_param_copy(&par->isp.iso, &cfg->isp.iso); + break; + + case PARAM_ISP_ADJUST: + __hw_param_copy(&par->isp.adjust, &cfg->isp.adjust); + break; + + case PARAM_ISP_METERING: + __hw_param_copy(&par->isp.metering, &cfg->isp.metering); + break; + + case PARAM_ISP_AFC: + __hw_param_copy(&par->isp.afc, &cfg->isp.afc); + break; + + case PARAM_ISP_OTF_OUTPUT: + __hw_param_copy(&par->isp.otf_output, &cfg->isp.otf_output); + break; + + case PARAM_ISP_DMA1_OUTPUT: + __hw_param_copy(&par->isp.dma1_output, &cfg->isp.dma1_output); + break; + + case PARAM_ISP_DMA2_OUTPUT: + __hw_param_copy(&par->isp.dma2_output, &cfg->isp.dma2_output); + break; + + case PARAM_DRC_CONTROL: + __hw_param_copy(&par->drc.control, &cfg->drc.control); + break; + + case PARAM_DRC_OTF_INPUT: + __hw_param_copy(&par->drc.otf_input, &cfg->drc.otf_input); + break; + + case PARAM_DRC_DMA_INPUT: + __hw_param_copy(&par->drc.dma_input, &cfg->drc.dma_input); + break; + + case PARAM_DRC_OTF_OUTPUT: + __hw_param_copy(&par->drc.otf_output, &cfg->drc.otf_output); + break; + + case PARAM_FD_CONTROL: + __hw_param_copy(&par->fd.control, &cfg
[RFC PATCH 2/8] s5p-fimc: Add FIMC-IS ISP I2C bus driver
This patch adds the ISP I2C bus controller driver files. Creating a standard I2C bus adapter, even if the driver doesn't actually communicates with the hardware and it is instead used by the ISP firmware running on the Cortex-A5, allows to use standard hardware description in the device tree. As the sensor would have actually had a standard V4L2 sub-device driver run on the host CPU. This approach allows to adapt the driver with a relatively small effort should the Imaging Subsystem architecture change so that the I2C bus is controlled by the host CPU, rather than the internal FIMC-IS ARM CPU. The image sensor drivers can be standard I2C client driver, as in case of most existing image sensor driver. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-is-i2c.c | 81 + drivers/media/platform/s5p-fimc/fimc-is-i2c.h | 15 + 2 files changed, 96 insertions(+) create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-i2c.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-i2c.h diff --git a/drivers/media/platform/s5p-fimc/fimc-is-i2c.c b/drivers/media/platform/s5p-fimc/fimc-is-i2c.c new file mode 100644 index 000..d4c75dc --- /dev/null +++ b/drivers/media/platform/s5p-fimc/fimc-is-i2c.c @@ -0,0 +1,81 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Sylwester Nawrocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ + +#include +#include +#include +#include "fimc-is-i2c.h" + +/* + * An empty algorithm is used as the actual I2C bus controller driver + * is implemented in the FIMC-IS subsystem firmware and the host CPU + * doesn't touch the hardware. + */ +static const struct i2c_algorithm fimc_is_i2c_algorithm; + +static int fimc_is_i2c_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct i2c_adapter *i2c_adap; + int ret; + + i2c_adap = devm_kzalloc(&pdev->dev, sizeof(*i2c_adap), GFP_KERNEL); + + i2c_adap->dev.of_node = node; + i2c_adap->dev.parent = &pdev->dev; + strlcpy(i2c_adap->name, "exynos4x12-is-i2c", sizeof(i2c_adap->name)); + i2c_adap->owner = THIS_MODULE; + i2c_adap->algo = &fimc_is_i2c_algorithm; + i2c_adap->class = I2C_CLASS_SPD; + + ret = i2c_add_adapter(i2c_adap); + if (ret < 0) { + dev_err(&pdev->dev, "failed to add I2C bus %s\n", + node->full_name); + return ret; + } + of_i2c_register_devices(i2c_adap); + + return 0; +} + +static int fimc_is_i2c_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id fimc_is_i2c_of_match[] = { + { .compatible = FIMC_IS_I2C_COMPATIBLE }, + { }, +}; +MODULE_DEVICE_TABLE(of, fimc_is_i2c_of_match); + +static struct platform_driver fimc_is_i2c_driver = { + .probe = fimc_is_i2c_probe, + .remove = fimc_is_i2c_remove, + .driver = { + .of_match_table = fimc_is_i2c_of_match, + .name = "fimc-is-i2c", + .owner = THIS_MODULE, + } +}; + +int fimc_is_register_i2c_driver(void) +{ + return platform_driver_register(&fimc_is_i2c_driver); +} + +void fimc_is_unregister_i2c_driver(void) +{ + platform_driver_unregister(&fimc_is_i2c_driver); +} + diff --git a/drivers/media/platform/s5p-fimc/fimc-is-i2c.h b/drivers/media/platform/s5p-fimc/fimc-is-i2c.h new file mode 100644 index 000..0d38d6b --- /dev/null +++ b/drivers/media/platform/s5p-fimc/fimc-is-i2c.h @@ -0,0 +1,15 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Sylwester Nawrocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define FIMC_IS_I2C_COMPATIBLE "samsung,exynos4212-i2c-isp" + +int fimc_is_register_i2c_driver(void); +void fimc_is_unregister_i2c_driver(void); -- 1.7.9.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
[RFC PATCH 0/8] A V4L2 driver for Exynos4x12 Imaging Subsystem
This patch series is an initial version of a driver for the camera ISP subsystem (FIMC-IS) embedded in Samsung Exynos4x12 SoCs. The FIMC-IS subsystem is build around a ARM Cortex-A5 CPU that controls its dedicated peripherals, like I2C, SPI, UART, PWM, ADC,... and the ISP chain. There are 3 hardware image processing blocks: ISP, DRC (dynamic range compression) and FD (face detection) that are normally controlled by the Cortex-A5 firmware. The driver currently exposes two additional sub-device to user space: the image sensor and FIMC-IS-ISP sub-device. Another one might be added in future for the FD features. The FIMC-IS has various data inputs, it can capture data from memory or from other SoC IP blocks (FIMC-LITE). It is currently plugged between FIMC-LITE and FIMC IP blocks, so there is a media pipeline like: sensor -> MIPI-CSIS -> FIMC-LITE -> FIMC-IS-ISP -> FIMC -> memory A raw Bayer image data can be captured from the ISP block which has it's own DMA engines. Support for this is not really included in this series though, only a video capture node driver stubs are added. This is a bit complicated code, nevertheless I would really appreciate any review comments you might have. And this is just a basic set of futures this patch series addresses. Others include input/output DMA support for the DRC and FD blocks, support for more ISP controls, etc. But it all is not immediately needed to make use of this really great ISP! A full git tree with all dependencies can be found at: git://linuxtv.org/snawrocki/samsung.git http://git.linuxtv.org/snawrocki/samsung.git/exynos4-fimc-is Sylwester Nawrocki (8): s5p-fimc: Add Exynos4x12 FIMC-IS driver s5p-fimc: Add FIMC-IS ISP I2C bus driver s5p-fimc: Add FIMC-IS parameter region definitions s5p-fimc: Add common FIMC-IS image sensor driver s5p-fimc: Add ISP video capture driver stubs fimc-is: Add Exynos4x12 FIMC-IS device tree bindings documentation s5p-fimc: Add fimc-is subdevs registration s5p-fimc: Create media links for the FIMC-IS entities .../devicetree/bindings/media/exynos4-fimc-is.txt | 41 + drivers/media/platform/s5p-fimc/Kconfig| 13 + drivers/media/platform/s5p-fimc/Makefile |4 + drivers/media/platform/s5p-fimc/fimc-is-command.h | 147 +++ drivers/media/platform/s5p-fimc/fimc-is-errno.c| 272 ++ drivers/media/platform/s5p-fimc/fimc-is-errno.h| 248 + drivers/media/platform/s5p-fimc/fimc-is-i2c.c | 81 ++ drivers/media/platform/s5p-fimc/fimc-is-i2c.h | 15 + drivers/media/platform/s5p-fimc/fimc-is-param.c| 971 +++ drivers/media/platform/s5p-fimc/fimc-is-param.h| 1018 drivers/media/platform/s5p-fimc/fimc-is-regs.c | 242 + drivers/media/platform/s5p-fimc/fimc-is-regs.h | 164 drivers/media/platform/s5p-fimc/fimc-is-sensor.c | 308 ++ drivers/media/platform/s5p-fimc/fimc-is-sensor.h | 80 ++ drivers/media/platform/s5p-fimc/fimc-is.c | 970 +++ drivers/media/platform/s5p-fimc/fimc-is.h | 344 +++ drivers/media/platform/s5p-fimc/fimc-isp-video.c | 414 drivers/media/platform/s5p-fimc/fimc-isp-video.h | 50 + drivers/media/platform/s5p-fimc/fimc-isp.c | 791 +++ drivers/media/platform/s5p-fimc/fimc-isp.h | 205 drivers/media/platform/s5p-fimc/fimc-mdevice.c | 129 ++- drivers/media/platform/s5p-fimc/fimc-mdevice.h | 15 + 22 files changed, 6502 insertions(+), 20 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/exynos4-fimc-is.txt create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-command.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-errno.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-errno.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-i2c.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-i2c.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-param.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-param.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-regs.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-regs.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-sensor.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is-sensor.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-is.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-is.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp-video.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp-video.h create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp.c create mode 100644 drivers/media/platform/s5p-fimc/fimc-isp.h -- 1.7.9.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 RFC 11/11] V4L: Add MATRIX option to V4L2_CID_EXPOSURE_METERING control
This patch adds a menu option to the V4L2_CID_EXPOSURE_METERING control for multi-zone metering. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- Documentation/DocBook/media/v4l/controls.xml |9 - drivers/media/v4l2-core/v4l2-ctrls.c |1 + include/uapi/linux/v4l2-controls.h |1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml index 7fe5be1..0484a7d 100644 --- a/Documentation/DocBook/media/v4l/controls.xml +++ b/Documentation/DocBook/media/v4l/controls.xml @@ -3159,6 +3159,13 @@ giving priority to the center of the metered area. V4L2_EXPOSURE_METERING_SPOT Measure only very small area at the center of the frame. + + V4L2_EXPOSURE_METERING_MATRIX + A multi-zone metering. The light intensity is measured +in several points of the frame and the the results are combined. The +algorithm of the zones selection and their significance in calculating the +final value is device dependant. + @@ -3986,7 +3993,7 @@ interface and may change in the future. Flash Control IDs - + diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 4b45d49..6b56d7b 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -234,6 +234,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id) "Average", "Center Weighted", "Spot", + "Matrix", NULL }; static const char * const camera_auto_focus_range[] = { diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index f56c945..22556a2 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -642,6 +642,7 @@ enum v4l2_exposure_metering { V4L2_EXPOSURE_METERING_AVERAGE = 0, V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1, V4L2_EXPOSURE_METERING_SPOT = 2, + V4L2_EXPOSURE_METERING_MATRIX = 3, }; #define V4L2_CID_SCENE_MODE(V4L2_CID_CAMERA_CLASS_BASE+26) -- 1.7.9.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 RFC 10/11] s5p-fimc: Remove dependency on fimc-core.h in fimc-lite driver
Drop fimc-lite.h header inclusion to make the exynos-fimc-lite module independent on other modules. Move struct fimc_fmt declaration to the driver's private headers as it is used in multiple modules. Reported-by: Shaik Ameer Basha Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-core.h | 32 - drivers/media/platform/s5p-fimc/fimc-lite.c |1 - drivers/media/platform/s5p-fimc/fimc-lite.h |3 +-- include/media/s5p_fimc.h| 34 +++ 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h index d95aa66..6e2fa1a 100644 --- a/drivers/media/platform/s5p-fimc/fimc-core.h +++ b/drivers/media/platform/s5p-fimc/fimc-core.h @@ -40,7 +40,6 @@ #define DMA_MIN_SIZE 8 #define FIMC_CAMIF_MAX_HEIGHT 0x2000 #define FIMC_MAX_JPEG_BUF_SIZE (10 * SZ_1M) -#define FIMC_MAX_PLANES3 #define FIMC_PIX_LIMITS_MAX6 #define FIMC_DEF_MIN_SIZE 16 #define FIMC_DEF_HEIGHT_ALIGN 2 @@ -138,37 +137,6 @@ enum fimc_color_fmt { #defineFIMC_COLOR_RANGE_NARROW (1 << 3) /** - * struct fimc_fmt - the driver's internal color format data - * @mbus_code: Media Bus pixel code, -1 if not applicable - * @name: format description - * @fourcc: the fourcc code for this format, 0 if not applicable - * @color: the corresponding fimc_color_fmt - * @memplanes: number of physically non-contiguous data planes - * @colplanes: number of physically contiguous data planes - * @depth: per plane driver's private 'number of bits per pixel' - * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no) - * @flags: flags indicating which operation mode format applies to - */ -struct fimc_fmt { - enum v4l2_mbus_pixelcode mbus_code; - char*name; - u32 fourcc; - u32 color; - u16 memplanes; - u16 colplanes; - u8 depth[VIDEO_MAX_PLANES]; - u16 mdataplanes; - u16 flags; -#define FMT_FLAGS_CAM (1 << 0) -#define FMT_FLAGS_M2M_IN (1 << 1) -#define FMT_FLAGS_M2M_OUT (1 << 2) -#define FMT_FLAGS_M2M (1 << 1 | 1 << 2) -#define FMT_HAS_ALPHA (1 << 3) -#define FMT_FLAGS_COMPRESSED (1 << 4) -#define FMT_FLAGS_WRITEBACK(1 << 5) -}; - -/** * struct fimc_dma_offset - pixel offset information for DMA * @y_h: y value horizontal offset * @y_v: y value vertical offset diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c index 97050ee..412fcb8 100644 --- a/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -32,7 +32,6 @@ #include #include "fimc-mdevice.h" -#include "fimc-core.h" #include "fimc-lite.h" #include "fimc-lite-reg.h" diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.h b/drivers/media/platform/s5p-fimc/fimc-lite.h index 7085761..4c234508 100644 --- a/drivers/media/platform/s5p-fimc/fimc-lite.h +++ b/drivers/media/platform/s5p-fimc/fimc-lite.h @@ -20,12 +20,11 @@ #include #include +#include #include #include #include -#include "fimc-core.h" - #define FIMC_LITE_DRV_NAME "exynos-fimc-lite" #define FLITE_CLK_NAME "flite" #define FIMC_LITE_MAX_DEVS 2 diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h index e2434bb..2363aff 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/s5p_fimc.h @@ -13,6 +13,7 @@ #define S5P_FIMC_H_ #include +#include /* * Enumeration of data inputs to the camera subsystem. @@ -93,6 +94,39 @@ struct s5p_platform_fimc { */ #define S5P_FIMC_TX_END_NOTIFY _IO('e', 0) +#define FIMC_MAX_PLANES3 + +/** + * struct fimc_fmt - color format data structure + * @mbus_code: media bus pixel code, -1 if not applicable + * @name: format description + * @fourcc: fourcc code for this format, 0 if not applicable + * @color: the driver's private color format id + * @memplanes: number of physically non-contiguous data planes + * @colplanes: number of physically contiguous data planes + * @depth: per plane driver's private 'number of bits per pixel' + * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no) + * @flags: flags indicating which operation mode format applies to + */ +struct fimc_fmt { + enum v4l2_mbus_pixelcode mbus_code; + char*name; + u32 fourcc; + u32 color; + u16 memplanes; + u16 colplanes; + u8 depth[FIMC_MAX_PLANES]; + u16 mdataplanes; + u16 flags; +#define FMT_FLAGS_CAM (1 << 0) +#define FMT_FLAGS_M2M_IN (1 << 1) +#define FMT_FLAGS_M2M_OUT (1 << 2) +#define FMT_FLAGS_M2M (1 << 1 | 1 << 2) +#define FMT_HAS_ALPHA (1 << 3) +#define FMT_FLAGS_COMPRESSED (1 << 4) +#define FMT_FLAGS_WRITEBACK(1 << 5
[PATCH RFC 09/11] s5p-fimc: Ensure proper s_power() call order in the ISP datapaths
Since the FIMC-IS firmware communicates with an image sensor directly through the ISP I2C bus controllers the sub-devices power supplies cannot be simply enabled from left to right or disabled from right to left along the processing pipeline. Thus a subdev index to call s_power() on is looked up from a table, rather than doing the op call based on increasing/decreasing indexes. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 26 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index c99802d..e9e5337 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -128,23 +128,33 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on) * * Needs to be called with the graph mutex held. */ -static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state) +static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool on) { - unsigned int i; - int ret; + static const u8 seq[2][IDX_MAX - 1] = { + { IDX_IS_ISP, IDX_SENSOR, IDX_CSIS, IDX_FLITE }, + { IDX_CSIS, IDX_FLITE, IDX_SENSOR, IDX_IS_ISP }, + }; + int i, ret = 0; if (p->subdevs[IDX_SENSOR] == NULL) return -ENXIO; - for (i = 0; i < IDX_MAX; i++) { - unsigned int idx = state ? (IDX_MAX - 1) - i : i; + for (i = 0; i < IDX_MAX - 1; i++) { + unsigned int idx = seq[on][i]; + + ret = __subdev_set_power(p->subdevs[idx], on); + - ret = __subdev_set_power(p->subdevs[idx], state); if (ret < 0 && ret != -ENXIO) - return ret; + goto error; } - return 0; +error: + for (; i >= 0; i--) { + unsigned int idx = seq[on][i]; + __subdev_set_power(p->subdevs[idx], !on); + } + return ret; } /** -- 1.7.9.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 RFC 08/11] s5p-fimc: Ensure proper s_stream() call order in the ISP datapaths
Since the FIMC-IS firmware communicates with an image sensor directly through the ISP I2C bus controllers data streaming cannot be simply enabled from left to right or disabled from right to left along the processing pipeline. Thus a subdev index to call s_stream() on is looked up from a table, rather than doing the op call based on increasing/decreasing indexes. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index c336ed1..c99802d 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -194,28 +194,36 @@ static int __fimc_pipeline_close(struct fimc_pipeline *p) } /** - * __fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs + * __fimc_pipeline_s_stream - call s_stream() on pipeline subdevs * @pipeline: video pipeline structure - * @on: passed as the s_stream call argument + * @on: passed as the s_stream() callback argument */ static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on) { - int i, ret; + static const u8 seq[2][IDX_MAX] = { + { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE }, + { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, + }; + int i, ret = 0; if (p->subdevs[IDX_SENSOR] == NULL) return -ENODEV; for (i = 0; i < IDX_MAX; i++) { - unsigned int idx = on ? (IDX_MAX - 1) - i : i; + unsigned int idx = seq[on][i]; ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on); if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) - return ret; + goto error; } - return 0; - +error: + for (; i >= 0; i--) { + unsigned int idx = seq[on][i]; + v4l2_subdev_call(p->subdevs[idx], video, s_stream, !on); + } + return ret; } /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */ -- 1.7.9.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 RFC 07/11] s5p-fimc: Ensure CAMCLK clock can be enabled by FIMC-LITE devices
In configurations where FIMC-LITE is used to capture image signal from an external sensor only we need to ensure one of FIMC devices is in active power state and the "fimc" gate clock is enabled. Otherwise the CAMCLK clock output signal will be masked off preventing an external sensor's operation. This affect processing pipelines like: - sensor -> FIMC-LITE -> memory - sensor -> MIPI-CSIS -> FIMC-LITE -> memory Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 18 ++ drivers/media/platform/s5p-fimc/fimc-mdevice.h |2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index d26b7bf..c336ed1 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -464,7 +464,6 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) { struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data; struct device_node *of_node = fmd->pdev->dev.of_node; - struct fimc_dev *fd = NULL; int num_clients = 0; int ret, i; @@ -472,13 +471,10 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) * Runtime resume one of the FIMC entities to make sure * the sclk_cam clocks are not globally disabled. */ - for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++) - if (fmd->fimc[i]) - fd = fmd->fimc[i]; - if (!fd) + if (!fmd->pmf) return -ENXIO; - ret = pm_runtime_get_sync(&fd->pdev->dev); + ret = pm_runtime_get_sync(fmd->pmf); if (ret < 0) return ret; @@ -512,7 +508,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) } } - pm_runtime_put(&fd->pdev->dev); + pm_runtime_put(fmd->pmf); return ret; } @@ -557,6 +553,8 @@ static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc) ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (!ret) { + if (!fmd->pmf && fimc->pdev) + fmd->pmf = &fimc->pdev->dev; fmd->fimc[fimc->id] = fimc; fimc->vid_cap.user_subdev_api = fmd->user_subdev_api; } else { @@ -1048,7 +1046,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, struct fimc_camclk_info *camclk; int ret = 0; - if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL) + if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf) return -EINVAL; camclk = &fmd->camclk[pdata->clk_id]; @@ -1064,6 +1062,9 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (camclk->use_count++ == 0) { clk_set_rate(camclk->clock, pdata->clk_frequency); camclk->frequency = pdata->clk_frequency; + ret = pm_runtime_get_sync(fmd->pmf); + if (ret < 0) + return ret; ret = clk_enable(camclk->clock); dbg("Enabled camclk %d: f: %lu", pdata->clk_id, clk_get_rate(camclk->clock)); @@ -1076,6 +1077,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (--camclk->use_count == 0) { clk_disable(camclk->clock); + pm_runtime_put(fmd->pmf); dbg("Disabled camclk %d", pdata->clk_id); } return ret; diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.h b/drivers/media/platform/s5p-fimc/fimc-mdevice.h index 91be5db..a827bf9 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.h @@ -80,6 +80,7 @@ struct fimc_sensor_info { * @num_sensors: actual number of registered sensors * @camclk: external sensor clock information * @fimc: array of registered fimc devices + * @pmf: handle to the CAMCLK clock control FIMC helper device * @media_dev: top level media device * @v4l2_dev: top level v4l2_device holding up the subdevs * @pdev: platform device this media device is hooked up into @@ -97,6 +98,7 @@ struct fimc_md { struct clk *wbclk[FIMC_MAX_WBCLKS]; struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS]; struct fimc_dev *fimc[FIMC_MAX_DEVS]; + struct device *pmf; struct media_device media_dev; struct v4l2_device v4l2_dev; struct platform_device *pdev; -- 1.7.9.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 RFC 06/11] s5p-fimc: Add the FIMC ISP writeback input support
A second sink pad is added to each FIMC.N subdev that will be used to link it to the ISP subdev. Only V4L2_MBUS_FMT_YUV10_1X30 format is supported at the pad FIMC_SD_PAD_SINK_FIFO. TODO: - Implement the FIMC input bus type selection based on state of media link from FIMC-IS-ISP to FIMC.N subdev. - Implement an interface for CAMBLK registers, the CAMBLK glue logic registers are shared by multiple drivers so this probably belongs to the platform at arch/arm/mach-exynos/. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-capture.c | 31 +++ drivers/media/platform/s5p-fimc/fimc-core.c|4 ++ drivers/media/platform/s5p-fimc/fimc-core.h|6 ++- drivers/media/platform/s5p-fimc/fimc-mdevice.c |5 ++ drivers/media/platform/s5p-fimc/fimc-reg.c | 65 +++- drivers/media/platform/s5p-fimc/fimc-reg.h | 10 6 files changed, 108 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 52abc9f..a3a58c4 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -46,6 +46,9 @@ static int fimc_capture_hw_init(struct fimc_dev *fimc) sensor = v4l2_get_subdev_hostdata(p->subdevs[IDX_SENSOR]); + if (sensor->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) + fimc_hw_camblk_set_isp_wb(fimc, 1 << fimc->id, 1); + spin_lock_irqsave(&fimc->slock, flags); fimc_prepare_dma_offset(ctx, &ctx->d_frame); fimc_set_yuv_order(ctx); @@ -647,18 +650,22 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, fimc_fmt_is_user_defined(ctx->s_frame.fmt->color)) *code = ctx->s_frame.fmt->mbus_code; - if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK) + if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad == FIMC_SD_PAD_SOURCE) mask |= FMT_FLAGS_M2M; + if (pad == FIMC_SD_PAD_SINK_FIFO) + mask = FMT_FLAGS_WRITEBACK; + ffmt = fimc_find_format(fourcc, code, mask, 0); if (WARN_ON(!ffmt)) return NULL; + if (code) *code = ffmt->mbus_code; if (fourcc) *fourcc = ffmt->fourcc; - if (pad == FIMC_SD_PAD_SINK) { + if (pad != FIMC_SD_PAD_SOURCE) { max_w = fimc_fmt_is_user_defined(ffmt->color) ? pl->scaler_dis_w : pl->scaler_en_w; /* Apply the camera input interface pixel constraints */ @@ -1552,12 +1559,16 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, } mf = &fmt->format; mf->colorspace = V4L2_COLORSPACE_JPEG; - ff = fmt->pad == FIMC_SD_PAD_SINK ? &ctx->s_frame : &ctx->d_frame; + if (fmt->pad == FIMC_SD_PAD_SOURCE) + ff = &ctx->d_frame; + else + ff = &ctx->s_frame; mutex_lock(&fimc->lock); /* The pixel code is same on both input and output pad */ if (!WARN_ON(ctx->s_frame.fmt == NULL)) mf->code = ctx->s_frame.fmt->mbus_code; + mf->width = ff->f_width; mf->height = ff->f_height; mutex_unlock(&fimc->lock); @@ -1601,9 +1612,10 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, fimc_alpha_ctrl_update(ctx); fimc_capture_mark_jpeg_xfer(ctx, ffmt->color); - - ff = fmt->pad == FIMC_SD_PAD_SINK ? - &ctx->s_frame : &ctx->d_frame; + if (fmt->pad == FIMC_SD_PAD_SOURCE) + ff = &ctx->d_frame; + else + ff = &ctx->s_frame; mutex_lock(&fimc->lock); set_frame_bounds(ff, mf->width, mf->height); @@ -1614,7 +1626,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE))) set_frame_crop(ff, 0, 0, mf->width, mf->height); - if (fmt->pad == FIMC_SD_PAD_SINK) + if (fmt->pad != FIMC_SD_PAD_SOURCE) ctx->state &= ~FIMC_COMPOSE; mutex_unlock(&fimc->lock); return 0; @@ -1630,7 +1642,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, struct v4l2_rect *r = &sel->r; struct v4l2_rect *try_sel; - if (sel->pad != FIMC_SD_PAD_SINK) + if (sel->pad == FIMC_SD_PAD_SOURCE) return -EINVAL; mutex_lock(&fimc->lock); @@ -1686,7 +1698,7 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, struct v4l2_rect *try_sel; unsigned long flags; - if (sel->pad != FIMC_SD_PAD_SINK) + if (sel->pad == FIMC_SD_PAD_SOURCE) return -EINVAL; mutex_lock(&fimc->lock); @@ -1892,6 +1904,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc) snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->id);
[PATCH RFC 05/11] s5p-fimc: Add support for PIXELASYNCMx clocks
This patch ads handling of clocks for the CAMBLK subsystem which is a glue logic for FIMC-IS or LCD controller and FIMC IP. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 41 +++- drivers/media/platform/s5p-fimc/fimc-mdevice.h |8 + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 0a7c95b..b9f9976 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -944,7 +944,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) } /* - * The peripheral sensor clock management. + * The peripheral sensor and CAM_BLK (PIXELASYNCMx) clocks management. */ static void fimc_md_put_clocks(struct fimc_md *fmd) { @@ -957,6 +957,17 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) clk_put(fmd->camclk[i].clock); fmd->camclk[i].clock = ERR_PTR(-EINVAL); } + + /* Writeback (PIXELASYNCMx) clocks */ + for (i = 0; i < FIMC_MAX_WBCLKS; i++) { + if (IS_ERR(fmd->wbclk[i])) + continue; + /* FIXME: find better place to disable this clock! */ + clk_disable(fmd->wbclk[i]); + clk_unprepare(fmd->wbclk[i]); + clk_put(fmd->wbclk[i]); + fmd->wbclk[i] = ERR_PTR(-EINVAL); + } } static int fimc_md_get_clocks(struct fimc_md *fmd) @@ -993,6 +1004,34 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) if (ret) fimc_md_put_clocks(fmd); + if (!fmd->use_isp) + return 0; + /* +* For now get only PIXELASYNCM1 clock (Writeback B/ISP), +* leave PIXELASYNCM0 out for the display driver. +*/ + for (i = CLK_IDX_WB_B; i < FIMC_MAX_WBCLKS; i++) { + snprintf(clk_name, sizeof(clk_name), "pxl_async%u", i); + clock = clk_get(dev, clk_name); + if (IS_ERR(clock)) { + v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s\n", + clk_name); + ret = PTR_ERR(clock); + break; + } + ret = clk_prepare(clock); + if (ret < 0) { + clk_put(clock); + fmd->wbclk[i] = ERR_PTR(-EINVAL); + break; + } + fmd->wbclk[i] = clock; + /* FIXME: find better place to enable this clock! */ + clk_enable(clock); + } + if (ret) + fimc_md_put_clocks(fmd); + return ret; } diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.h b/drivers/media/platform/s5p-fimc/fimc-mdevice.h index 5d6146e..91be5db 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.h @@ -41,6 +41,13 @@ #define FIMC_MAX_SENSORS 8 #define FIMC_MAX_CAMCLKS 2 +/* LCD/ISP Writeback clocks (PIXELASYNCMx) */ +enum { + CLK_IDX_WB_A, + CLK_IDX_WB_B, + FIMC_MAX_WBCLKS +}; + struct fimc_csis_info { struct v4l2_subdev *sd; int id; @@ -87,6 +94,7 @@ struct fimc_md { struct fimc_sensor_info sensor[FIMC_MAX_SENSORS]; int num_sensors; struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS]; + struct clk *wbclk[FIMC_MAX_WBCLKS]; struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS]; struct fimc_dev *fimc[FIMC_MAX_DEVS]; struct media_device media_dev; -- 1.7.9.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 RFC 04/11] s5p-fimc: Update graph traversal for entities with multiple source pads
We cannot assume that the passed entity the fimc_pipeline_prepare() function is supposed to start the media graph traversal from will always have its sink pad at pad index 0. Find the starting media entity's sink pad by iterating over its all pads and checking the pad flags. This ensures proper handling of FIMC, FIMC-LITE and FIMC-IS-ISP subdevs that have more than one sink and one source pad. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 22 ++ 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 19cd628..0a7c95b 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -47,7 +47,6 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, static void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me) { - struct media_pad *pad = &me->pads[0]; struct v4l2_subdev *sd; int i; @@ -55,15 +54,21 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, p->subdevs[i] = NULL; while (1) { - if (!(pad->flags & MEDIA_PAD_FL_SINK)) - break; + struct media_pad *pad = NULL; + + /* Find remote source pad */ + for (i = 0; i < me->num_pads; i++) { + struct media_pad *spad = &me->pads[i]; + if (!(spad->flags & MEDIA_PAD_FL_SINK)) + continue; + pad = media_entity_remote_source(spad); + if (pad) + break; + } - /* source pad */ - pad = media_entity_remote_source(pad); if (pad == NULL || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) break; - sd = media_entity_to_v4l2_subdev(pad->entity); switch (sd->grp_id) { @@ -84,8 +89,9 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, pr_warn("%s: Unknown subdev grp_id: %#x\n", __func__, sd->grp_id); } - /* sink pad */ - pad = &sd->entity.pads[0]; + me = &sd->entity; + if (me->num_pads == 1) + break; } } -- 1.7.9.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 RFC 03/11] s5p-csis: Add parent clock setup
With this patch the driver will set "parent" clock as a parent clock of "mux" clock. When the samsung clocks driver is reworked to use new composite clock type, the "mux" clock can be removed. "parent" clock should be set in relevant dtsi file and can be overwritten in a board dts file. This way it is ensured the SCLK_CSIS has correct parent clock set, and the parent clock can be selected per each board if required. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/mipi-csis.c | 66 ++- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/mipi-csis.c b/drivers/media/platform/s5p-fimc/mipi-csis.c index 4673625..6854c9e 100644 --- a/drivers/media/platform/s5p-fimc/mipi-csis.c +++ b/drivers/media/platform/s5p-fimc/mipi-csis.c @@ -108,13 +108,17 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); #define S5PCSIS_PKTDATA_SIZE SZ_4K enum { - CSIS_CLK_MUX, + CSIS_CLK_BUS, CSIS_CLK_GATE, + CSIS_CLK_MUX, + CSIS_CLK_PARENT, }; static char *csi_clock_name[] = { - [CSIS_CLK_MUX] = "sclk_csis", + [CSIS_CLK_BUS] = "sclk_csis", [CSIS_CLK_GATE] = "csis", + [CSIS_CLK_MUX] = "mux", + [CSIS_CLK_PARENT] = "parent", }; #define NUM_CSIS_CLOCKSARRAY_SIZE(csi_clock_name) #define DEFAULT_SCLK_CSIS_FREQ 16600UL @@ -362,7 +366,7 @@ static void s5pcsis_set_params(struct csis_state *state) s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW); } -static void s5pcsis_clk_put(struct csis_state *state) +static void s5pcsis_put_clocks(struct csis_state *state) { int i; @@ -375,11 +379,16 @@ static void s5pcsis_clk_put(struct csis_state *state) } } -static int s5pcsis_clk_get(struct csis_state *state) +static int s5pcsis_get_clocks(struct csis_state *state) { struct device *dev = &state->pdev->dev; + unsigned int num_clocks = NUM_CSIS_CLOCKS; int i, ret; + /* Skip parent and mux clocks for non-dt platforms */ + if (!dev->of_node) + num_clocks -= 2; + for (i = 0; i < NUM_CSIS_CLOCKS; i++) state->clock[i] = ERR_PTR(-EINVAL); @@ -398,11 +407,32 @@ static int s5pcsis_clk_get(struct csis_state *state) } return 0; err: - s5pcsis_clk_put(state); + s5pcsis_put_clocks(state); dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]); return ret; } +static int s5pcsis_setup_clocks(struct csis_state *state) +{ + int ret; + + if (!IS_ERR(state->clock[CSIS_CLK_PARENT])) { + ret = clk_set_parent(state->clock[CSIS_CLK_MUX], +state->clock[CSIS_CLK_PARENT]); + if (ret < 0) { + dev_err(&state->pdev->dev, + "%s(): failed to set parent: %d\n", + __func__, ret); + return ret; + } + } + ret = clk_set_rate(state->clock[CSIS_CLK_BUS], + state->clk_frequency); + if (ret < 0) + return ret; + return clk_enable(state->clock[CSIS_CLK_BUS]); +} + static void dump_regs(struct csis_state *state, const char *label) { struct { @@ -725,8 +755,10 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev, dev_err(&pdev->dev, "Platform data not specified\n"); return -EINVAL; } - - state->clk_frequency = pdata->clk_rate; + if (pdata->clk_rate) + state->clk_frequency = pdata->clk_rate; + else + state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; state->num_lanes = pdata->lanes; state->hs_settle = pdata->hs_settle; state->index = max(0, pdev->id); @@ -830,19 +862,11 @@ static int s5pcsis_probe(struct platform_device *pdev) if (ret) return ret; - ret = s5pcsis_clk_get(state); + ret = s5pcsis_get_clocks(state); if (ret < 0) return ret; - if (state->clk_frequency) - ret = clk_set_rate(state->clock[CSIS_CLK_MUX], - state->clk_frequency); - else - dev_WARN(dev, "No clock frequency specified!\n"); - if (ret < 0) - goto e_clkput; - - ret = clk_enable(state->clock[CSIS_CLK_MUX]); + ret = s5pcsis_setup_clocks(state); if (ret < 0) goto e_clkput; @@ -885,9 +909,9 @@ static int s5pcsis_probe(struct platform_device *pdev) return 0; e_clkdis: - clk_disable(state->clock[CSIS_CLK_MUX]); + clk_disable(state->clock[CSIS_CLK_BUS]); e_clkput: - s5pcsis_clk_put(state); + s5pcsis_put_clocks(state); return ret; } @@ -990,9 +1014,9 @@ static int s5pcsis_remove(struct platform_device *pdev
[PATCH RFC 02/11] s5p-fimc: Add parent clock setup
With this patch the driver will set "parent" clock as a parent clock of "mux" clock. When the samsung clocks driver is reworked to use new composite clock type, the "mux" clock can be removed. "parent" clock should be set in related dtsi file and can be overwritten in a board dts file. This way it is ensured the SCLK_FIMC clock has correct parent clock set, and the parent clock can be selected per each board if required. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-core.c | 63 ++- drivers/media/platform/s5p-fimc/fimc-core.h |6 ++- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-core.c b/drivers/media/platform/s5p-fimc/fimc-core.c index d7fe332..c968e80 100644 --- a/drivers/media/platform/s5p-fimc/fimc-core.c +++ b/drivers/media/platform/s5p-fimc/fimc-core.c @@ -33,8 +33,8 @@ #include "fimc-reg.h" #include "fimc-mdevice.h" -static char *fimc_clocks[MAX_FIMC_CLOCKS] = { - "sclk_fimc", "fimc" +static char *fimc_clocks[CLK_FIMC_MAX] = { + "sclk_fimc", "fimc", "mux", "parent" }; static struct fimc_fmt fimc_formats[] = { @@ -787,10 +787,10 @@ struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, return def_fmt; } -static void fimc_clk_put(struct fimc_dev *fimc) +static void fimc_put_clocks(struct fimc_dev *fimc) { int i; - for (i = 0; i < MAX_FIMC_CLOCKS; i++) { + for (i = 0; i < CLK_FIMC_MAX; i++) { if (IS_ERR(fimc->clock[i])) continue; clk_unprepare(fimc->clock[i]); @@ -799,15 +799,21 @@ static void fimc_clk_put(struct fimc_dev *fimc) } } -static int fimc_clk_get(struct fimc_dev *fimc) +static int fimc_get_clocks(struct fimc_dev *fimc) { + struct device *dev = &fimc->pdev->dev; + unsigned int num_clocks = CLK_FIMC_MAX; int i, ret; - for (i = 0; i < MAX_FIMC_CLOCKS; i++) + /* Skip parent and mux clocks for non-dt platforms */ + if (!dev->of_node) + num_clocks -= 2; + + for (i = 0; i < CLK_FIMC_MAX; i++) fimc->clock[i] = ERR_PTR(-EINVAL); - for (i = 0; i < MAX_FIMC_CLOCKS; i++) { - fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]); + for (i = 0; i < num_clocks; i++) { + fimc->clock[i] = clk_get(dev, fimc_clocks[i]); if (IS_ERR(fimc->clock[i])) { ret = PTR_ERR(fimc->clock[i]); goto err; @@ -821,12 +827,32 @@ static int fimc_clk_get(struct fimc_dev *fimc) } return 0; err: - fimc_clk_put(fimc); - dev_err(&fimc->pdev->dev, "failed to get clock: %s\n", - fimc_clocks[i]); + fimc_put_clocks(fimc); + dev_err(dev, "failed to get clock: %s\n", fimc_clocks[i]); return -ENXIO; } +static int fimc_setup_clocks(struct fimc_dev *fimc, unsigned long freq) +{ + int ret; + + if (!IS_ERR(fimc->clock[CLK_PARENT])) { + ret = clk_set_parent(fimc->clock[CLK_MUX], +fimc->clock[CLK_PARENT]); + if (ret < 0) { + dev_err(&fimc->pdev->dev, + "%s(): failed to set parent: %d\n", + __func__, ret); + return ret; + } + } + ret = clk_set_rate(fimc->clock[CLK_BUS], freq); + if (ret < 0) + return ret; + + return clk_enable(fimc->clock[CLK_BUS]); +} + static int fimc_m2m_suspend(struct fimc_dev *fimc) { unsigned long flags; @@ -968,18 +994,13 @@ static int fimc_probe(struct platform_device *pdev) return -ENXIO; } - ret = fimc_clk_get(fimc); - if (ret) + ret = fimc_get_clocks(fimc); + if (ret < 0) return ret; - if (lclk_freq == 0) lclk_freq = fimc->drv_data->lclk_frequency; - ret = clk_set_rate(fimc->clock[CLK_BUS], lclk_freq); - if (ret < 0) - return ret; - - ret = clk_enable(fimc->clock[CLK_BUS]); + ret = fimc_setup_clocks(fimc, lclk_freq); if (ret < 0) return ret; @@ -1016,7 +1037,7 @@ err_sd: fimc_unregister_capture_subdev(fimc); err_clk: clk_disable(fimc->clock[CLK_BUS]); - fimc_clk_put(fimc); + fimc_put_clocks(fimc); return ret; } @@ -1103,7 +1124,7 @@ static int fimc_remove(struct platform_device *pdev) vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); clk_disable(fimc->clock[CLK_BUS]); - fimc_clk_put(fimc); + fimc_put_clocks(fimc); dev_info(&pdev->dev, "driver unloaded\n"); return 0; diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h index 58b674e..67e3201 100644 --- a/driver
[PATCH RFC 01/11] s5p-fimc: Added error checks for pipeline stream on callbacks
From: Andrzej Hajda set_stream error for pipelines is logged or reported to user space if possible. Signed-off-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- drivers/media/platform/s5p-fimc/fimc-capture.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 2a1da4c..52abc9f 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -286,8 +286,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) fimc_activate_capture(ctx); if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) - fimc_pipeline_call(fimc, set_stream, - &fimc->pipeline, 1); + return fimc_pipeline_call(fimc, set_stream, + &fimc->pipeline, 1); } return 0; @@ -443,12 +443,17 @@ static void buffer_queue(struct vb2_buffer *vb) if (vb2_is_streaming(&vid_cap->vbq) && vid_cap->active_buf_cnt >= min_bufs && !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) { + int ret; + fimc_activate_capture(ctx); spin_unlock_irqrestore(&fimc->slock, flags); - if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) - fimc_pipeline_call(fimc, set_stream, - &fimc->pipeline, 1); + if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) + return; + + ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1); + if (ret < 0) + v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret); return; } spin_unlock_irqrestore(&fimc->slock, flags); -- 1.7.9.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 RFC 00/11] s5p-fimc: Exynos4x12 FIMC-IS support prerequisite
This patch series contains couple fixes to the s5p-fimc driver and changes necessary for the Exynos4x12 FIMC-IS support. Andrzej Hajda (1): s5p-fimc: Added error checks for pipeline stream on callbacks Sylwester Nawrocki (10): s5p-fimc: Add parent clock setup s5p-csis: Add parent clock setup s5p-fimc: Update graph traversal for entities with multiple source pads s5p-fimc: Add support for PIXELASYNCMx clocks s5p-fimc: Add the FIMC ISP writeback input support s5p-fimc: Ensure CAMCLK clock can be enabled by FIMC-LITE devices s5p-fimc: Ensure proper s_stream() call order in the ISP datapaths s5p-fimc: Ensure proper s_power() call order in the ISP datapaths s5p-fimc: Remove dependency on fimc-core.h in fimc-lite driver V4L: Add MATRIX option to V4L2_CID_EXPOSURE_METERING control Documentation/DocBook/media/v4l/controls.xml |9 +- drivers/media/platform/s5p-fimc/fimc-capture.c | 46 +--- drivers/media/platform/s5p-fimc/fimc-core.c| 67 drivers/media/platform/s5p-fimc/fimc-core.h| 42 ++-- drivers/media/platform/s5p-fimc/fimc-lite.c|1 - drivers/media/platform/s5p-fimc/fimc-lite.h|3 +- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 134 ++-- drivers/media/platform/s5p-fimc/fimc-mdevice.h | 10 ++ drivers/media/platform/s5p-fimc/fimc-reg.c | 65 +++- drivers/media/platform/s5p-fimc/fimc-reg.h | 10 ++ drivers/media/platform/s5p-fimc/mipi-csis.c| 66 drivers/media/v4l2-core/v4l2-ctrls.c |1 + include/media/s5p_fimc.h | 34 ++ include/uapi/linux/v4l2-controls.h |1 + 14 files changed, 360 insertions(+), 129 deletions(-) -- 1.7.9.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: Custom device names for v4l2 devices
Please suggest. Thanks Vinay > Hi > > Names of V4L2 device nodes keep on varying depending on target, on some > targets, the device node assigned to my device is /dev/video21 and on some > it is /dev/video15. In order to determine my device, i am opening it, > reading the capabilities, enumerating its formats and then chose the one > matching my requirements. This is impacting start-up latency. One way to > resolve this without impacting start-up latency is to give custom name to > my V4L2 device node (/dev/custom_name instead of /dev/video21). This needs > following change in V4L2 framework. Please review this patch. If you have > faced similar problem please let me know. > > --- a/drivers/media/video/v4l2-dev.c > +++ b/drivers/media/video/v4l2-dev.c > @@ -676,7 +676,8 @@ int __video_register_device(struct video_device *vdev, > int type, int nr, > vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); > if (vdev->parent) > vdev->dev.parent = vdev->parent; > - dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); > + if (!dev_name(&vdev->dev)) > + dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); > ret = device_register(&vdev->dev); > if (ret < 0) { > printk(KERN_ERR "%s: device_register failed\n", __func__); > > > Thanks > Vinay > -- 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] m920x: silence compiler warning
drivers/media/usb/dvb-usb/m920x.c: In function ‘m920x_probe’: drivers/media/usb/dvb-usb/m920x.c:91:6: warning: ‘ret’ may be used uninitialized in this function [-Wuninitialized] drivers/media/usb/dvb-usb/m920x.c:70:6: note: ‘ret’ was declared here Signed-off-by: Antti Palosaari --- drivers/media/usb/dvb-usb/m920x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index 92afeb2..f5e4654 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -67,7 +67,7 @@ static inline int m920x_write(struct usb_device *udev, u8 request, static inline int m920x_write_seq(struct usb_device *udev, u8 request, struct m920x_inits *seq) { - int ret; + int ret = 0; while (seq->address) { ret = m920x_write(udev, request, seq->data, seq->address); if (ret != 0) -- 1.7.11.7 -- 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] [media] ts2020: use customise option correctly
The Kconfig entry for "TS2020 based tuners" defaults to modular if DVB_FE_CUSTOMISE is set. But that Kconfig symbol was replaced with MEDIA_SUBDRV_AUTOSELECT as of v3.7. So use the new symbol. And negate the logic, so we are in line with all the similar entries in this file. Signed-off-by: Paul Bolle --- Entirely untested. drivers/media/dvb-frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 6f809a7..0e2ec6f 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -210,7 +210,7 @@ config DVB_SI21XX config DVB_TS2020 tristate "Montage Tehnology TS2020 based tuners" depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE + default m if !MEDIA_SUBDRV_AUTOSELECT help A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner. -- 1.7.11.7 -- 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: omap3isp: iommu register problem.
Hi Laurent, thank you for your answer. On 11 March 2013 16:01, Laurent Pinchart wrote: > Hi Javier, > > On Monday 11 March 2013 13:18:12 javier Martin wrote: >> I've just found the following thread where te problem is explained: >> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/086364.h >> tml >> >> The problem is related with the order iommu and omap3isp are probed >> when both are built-in. If I load omap3isp as a module the problem is >> gone. >> >> However, according to the previous thread, omap3isp register should >> return error but an oops should not be generated. So I think there is >> a bug here anyway. > > Does the following patch (compile-tested only) fix the issue ? > > diff --git a/drivers/media/platform/omap3isp/isp.c > b/drivers/media/platform/omap3isp/isp.c > index 6e5ad8e..4d889be 100644 > --- a/drivers/media/platform/omap3isp/isp.c > +++ b/drivers/media/platform/omap3isp/isp.c > @@ -2123,6 +2123,7 @@ static int isp_probe(struct platform_device *pdev) > ret = iommu_attach_device(isp->domain, &pdev->dev); > if (ret) { > dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret); > + ret = -EPROBE_DEFER; > goto free_domain; > } > > @@ -2161,6 +2162,7 @@ detach_dev: > iommu_detach_device(isp->domain, &pdev->dev); > free_domain: > iommu_domain_free(isp->domain); > + isp->domain = NULL; > error_isp: > omap3isp_put(isp); > error: > Yes, that solves the problems. [2.706939] omap3isp omap3isp: Revision 15.0 found [2.712402] omap_iommu_attach: 1 [2.715942] omap_iommu_attach: 2 [2.719329] omap_iommu_attach: 3 [2.722778] omap_iommu_attach: 4 [2.726135] omap_iommu_attach: 5 [2.729553] iommu_enable: 1 [2.732482] iommu_enable: 2, arch_iommu = c0599adc [2.737548] iommu_enable: 3 [2.740478] iommu_enable: 5 [2.743652] omap-iommu omap-iommu.0: mmu_isp: version 1.1 [2.749389] omap_iommu_attach: 6 [2.752807] omap_iommu_attach: 7 [2.756195] omap_iommu_attach: 8 [2.759613] omap_iommu_attach: 9 [2.763977] omap3isp omap3isp: hist: DMA channel = 2 [2.770904] drivers/rtc/hctosys.c: unable to open rtc device (rtc0) [2.778839] ALSA device list: [2.781982] No soundcards found. [2.799285] mt9m111 2-0048: mt9m111: driver needs platform data [2.805603] mt9m111: probe of 2-0048 failed with error -22 [2.814849] omap3isp omap3isp: isp_register_subdev_group: Unable to register subdev mt9m111 The error I get now seems more related to the fact that I am trying to use a soc-camera sensor (mt9m111) with a non-soc-camera host (omap3isp) and I probably need some extra platform code. Do you know any board in mainline in a similar situation? Regards. -- Javier Martin Vista Silicon S.L. CDTUC - FASE C - Oficina S-345 Avda de los Castros s/n 39005- Santander. Cantabria. Spain +34 942 25 32 60 www.vista-silicon.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 v7] [media] Add a V4L2 OF parser
Hi Sylwester Thanks for continuing this work! You have made a great progress compared to my initial version, and I should really have looked at each your submitted new revision, unfortunately, I haven't managed that. So, sorry for chiming back in so late in the game, but maybe we still manage to get it in on time for 3.10. Let me know if you'd like me to do the next couple of rounds :) Or if you disagree with my comments and prefer your present state. On Fri, 8 Mar 2013, Sylwester Nawrocki wrote: > From: Guennadi Liakhovetski > > Add a V4L2 OF parser, implementing bindings documented in > Documentation/devicetree/bindings/media/video-interfaces.txt. > > Signed-off-by: Guennadi Liakhovetski > [s.nawro...@samsung.com: various corrections and improvements > since the initial version] > Signed-off-by: Sylwester Nawrocki > --- > The last version of the bindings documentation patch can be found > at: https://patchwork.kernel.org/patch/2074951 > > Changes since v6: > - minor v4l2_of_get_remote_port_parent() function cleanup. > > Changes since v5: > - renamed v4l2_of_parse_mipi_csi2 -> v4l2_of_parse_csi_bus, > - corrected v4l2_of_get_remote_port_parent() function declaration >for !CONFIG_OF, > - reworked v4l2_of_get_next_endpoint() function to consider the >'port' nodes can be grouped under optional 'ports' node, > - added kerneldoc description for v4l2_of_get_next_endpoint() >function. > > Changes since v4: > - reworked v4l2_of_get_remote_port() function to consider cases >where 'port' nodes are grouped in a parent 'ports' node, > - rearranged struct v4l2_of_endpoint and related changes added >in the parser code, > - added kerneldoc description for struct v4l2_of_endpoint, > - s/link/endpoint in the comments, > --- > drivers/media/v4l2-core/Makefile |3 + > drivers/media/v4l2-core/v4l2-of.c | 261 > + > include/media/v4l2-of.h | 98 ++ > 3 files changed, 362 insertions(+) > create mode 100644 drivers/media/v4l2-core/v4l2-of.c > create mode 100644 include/media/v4l2-of.h > > diff --git a/drivers/media/v4l2-core/Makefile > b/drivers/media/v4l2-core/Makefile > index c2d61d4..00f64d6 100644 > --- a/drivers/media/v4l2-core/Makefile > +++ b/drivers/media/v4l2-core/Makefile > @@ -9,6 +9,9 @@ videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o > v4l2-fh.o \ > ifeq ($(CONFIG_COMPAT),y) >videodev-objs += v4l2-compat-ioctl32.o > endif > +ifeq ($(CONFIG_OF),y) > + videodev-objs += v4l2-of.o > +endif > > obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o > obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o > diff --git a/drivers/media/v4l2-core/v4l2-of.c > b/drivers/media/v4l2-core/v4l2-of.c > new file mode 100644 > index 000..cbd18f6 > --- /dev/null > +++ b/drivers/media/v4l2-core/v4l2-of.c > @@ -0,0 +1,261 @@ > +/* > + * V4L2 OF binding parsing library > + * > + * Copyright (C) 2012 Renesas Electronics Corp. > + * Author: Guennadi Liakhovetski > + * > + * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. > + * Sylwester Nawrocki You probably want to put your copyright at the top as the newer one, isn't it the usual order - newest first? > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of version 2 of the GNU General Public License as > + * published by the Free Software Foundation. > + */ > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +/** > + * v4l2_of_parse_csi_bus() - parse MIPI CSI-2 bus properties > + * @node: pointer to endpoint device_node > + * @endpoint: pointer to v4l2_of_endpoint data structure > + * > + * Return: 0 on success or negative error value otherwise. > + */ > +int v4l2_of_parse_csi_bus(const struct device_node *node, > + struct v4l2_of_endpoint *endpoint) > +{ > + struct v4l2_mbus_mipi_csi2 *mipi_csi2 = &endpoint->mbus.mipi_csi2; > + u32 data_lanes[ARRAY_SIZE(mipi_csi2->data_lanes)]; > + struct property *prop; > + const __be32 *lane = NULL; > + u32 v; > + int i = 0; > + > + prop = of_find_property(node, "data-lanes", NULL); > + if (!prop) > + return -EINVAL; Oh... Well, first - this isn't an error to not specify "data-lanes." Below you also try to continue configuring the CSI-2 properties in this "error" case, but since you return here, you skip parsing all clock-related properties... > + do { > + lane = of_prop_next_u32(prop, lane, &data_lanes[i]); > + } while (lane && i++ < ARRAY_SIZE(data_lanes)); you could do this as a "for" loop, but then you'd have an additional if-break check inside, so, maybe your do-while is a prettier solution here. > + > + mipi_csi2->num_data_lanes = i; > + while (i--) > + mipi_csi2->data_lanes[i] = data_lanes[i]; > + > + if (!of_property_read_u32(node, "clock-lanes", &v)) > + mipi_csi2->clock_lane = v;
Re: omap3isp: iommu register problem.
Hi Javier, On Monday 11 March 2013 13:18:12 javier Martin wrote: > I've just found the following thread where te problem is explained: > http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/086364.h > tml > > The problem is related with the order iommu and omap3isp are probed > when both are built-in. If I load omap3isp as a module the problem is > gone. > > However, according to the previous thread, omap3isp register should > return error but an oops should not be generated. So I think there is > a bug here anyway. Does the following patch (compile-tested only) fix the issue ? diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 6e5ad8e..4d889be 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2123,6 +2123,7 @@ static int isp_probe(struct platform_device *pdev) ret = iommu_attach_device(isp->domain, &pdev->dev); if (ret) { dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret); + ret = -EPROBE_DEFER; goto free_domain; } @@ -2161,6 +2162,7 @@ detach_dev: iommu_detach_device(isp->domain, &pdev->dev); free_domain: iommu_domain_free(isp->domain); + isp->domain = NULL; error_isp: omap3isp_put(isp); error: -- Regards, Laurent Pinchart -- 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] block i2c tuner reads for Avermedia Twinstar in the af9035 driver
On 03/11/2013 01:51 PM, Jose Alberto Reguero wrote: On Lunes, 11 de febrero de 2013 14:48:18 Jose Alberto Reguero escribió: On Domingo, 10 de febrero de 2013 22:11:53 Antti Palosaari escribió: On 02/10/2013 09:43 PM, Jose Alberto Reguero wrote: This patch block the i2c tuner reads for Avermedia Twinstar. If it's needed other pids can be added. Signed-off-by: Jose Alberto Reguero diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.c linux.new/drivers/media/usb/dvb-usb-v2/af9035.c --- linux/drivers/media/usb/dvb-usb-v2/af9035.c 2013-01-07 05:45:57.0 +0100 +++ linux.new/drivers/media/usb/dvb-usb-v2/af9035.c 2013-02-08 22:55:08.304089054 +0100 @@ -232,7 +232,11 @@ static int af9035_i2c_master_xfer(struct buf[3] = 0x00; /* reg addr MSB */ buf[4] = 0x00; /* reg addr LSB */ memcpy(&buf[5], msg[0].buf, msg[0].len); - ret = af9035_ctrl_msg(d, &req); + if (state->block_read) { + msg[1].buf[0] = 0x3f; + ret = 0; + } else + ret = af9035_ctrl_msg(d, &req); } } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { if (msg[0].len > 40) { @@ -638,6 +642,17 @@ static int af9035_read_config(struct dvb for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) state->af9033_config[i].clock = clock_lut[tmp]; + state->block_read = false; + + if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && + le16_to_cpu(d->udev->descriptor.idProduct) == + USB_PID_AVERMEDIA_TWINSTAR) { + dev_dbg(&d->udev->dev, + "%s: AverMedia Twinstar: block i2c read from tuner\n", + __func__); + state->block_read = true; + } + return 0; err: diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.h linux.new/drivers/media/usb/dvb-usb-v2/af9035.h --- linux/drivers/media/usb/dvb-usb-v2/af9035.h 2013-01-07 05:45:57.0 +0100 +++ linux.new/drivers/media/usb/dvb-usb-v2/af9035.h 2013-02-08 22:52:42.293842710 +0100 @@ -54,6 +54,7 @@ struct usb_req { struct state { u8 seq; /* packet sequence number */ bool dual_mode; + bool block_read; struct af9033_config af9033_config[2]; }; Could you test if faking tuner ID during attach() is enough? Also, I would like to know what is returned error code from firmware when it fails. Enable debugs to see it. It should print something like that: af9035_ctrl_msg: command=03 failed fw error=2 diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index a1e953a..5a4f28d 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1082,9 +1082,22 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap) tuner_addr = 0x60 | 0x80; /* I2C bus hack */ } + // fake used tuner for demod firmware / i2c adapter + if (adap->id == 0) + ret = af9035_wr_reg(d, 0x00f641, AF9033_TUNER_FC0011); + else + ret = af9035_wr_reg(d, 0x10f641, AF9033_TUNER_FC0011); + /* attach tuner */ fe = dvb_attach(mxl5007t_attach, adap->fe[0], &d->i2c_adap, tuner_addr, &af9035_mxl5007t_config[adap->id]); + + // return correct tuner + if (adap->id == 0) + ret = af9035_wr_reg(d, 0x00f641, AF9033_TUNER_MXL5007T); + else + ret = af9035_wr_reg(d, 0x10f641, AF9033_TUNER_MXL5007T); + break; case AF9033_TUNER_TDA18218: /* attach tuner */ regards Antti I will try with fake tuner, but I can't test unil next weekend. If I remember, the read operation is performed, and return good value, but after that, all the i2c transfers fail. Seee: http://www.mail-archive.com/linux-media@vger.kernel.org/msg56346.html Jose Alberto I tried with fake tuner without success: [ 1346.707405] DVB: registering new adapter (AVerMedia Twinstar (A825)) [ 1346.959043] i2c i2c-1: af9033: firmware version: LINK=11.5.9.0 OFDM=5.17.9.1 [ 1346.962920] usb 1-2: DVB: registering adapter 0 frontend 0 (Afatech AF9033 (DVB-T))... [ 1347.439354] mxl5007t 1-0060: creating new instance [ 1347.440644] mxl5007t_get_chip_id: unknown rev (3f) [ 1347.440652] mxl5007t_get_chip_id: MxL5007T detected @ 1-0060 [ 1347.443023] mxl5007t_write_reg: 472: failed! [ 1347.443031] mxl5007t_attach: error -121 on line 903 [ 1347.443790] usb 1-2: dvb_usb_v2: 'AVerMedia Twinstar (A825)' error while loading driver (-19) [ 1347.446624] usb 1-2: dvb_u
Re: omap3isp: iommu register problem.
I've just found the following thread where te problem is explained: http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/086364.html The problem is related with the order iommu and omap3isp are probed when both are built-in. If I load omap3isp as a module the problem is gone. However, according to the previous thread, omap3isp register should return error but an oops should not be generated. So I think there is a bug here anyway. -- Javier Martin Vista Silicon S.L. CDTUC - FASE C - Oficina S-345 Avda de los Castros s/n 39005- Santander. Cantabria. Spain +34 942 25 32 60 www.vista-silicon.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: dvb-apps: Additional channels for Netherlands
On 09-03-13 15:45, Dmitry Katsubo wrote: Dear LinuxTV developers, Hoi Dimitry, When I was playing with "scan" utility, I paid attention to comments in file /usr/share/dvb/dvb-t/nl-All # The Netherlands, whole country # Created from http://radio-tv-nederland.nl/TV%20zenderlijst%20Nederland.xls # and http://radio-tv-nederland.nl/dvbt/dvbt-lokaal.html and what is interesting the comments refer to radio-stations only. TV zenderlijst is pure DVB-T frequencies. I have not found a single FM frequency there. Note that if you open it via their website, there are two lists, FM zenderlijst and TV zenderlijst. After I have completed the scan (I leave in the Netherlands in Delft area) I have not found few TV stations. I think that the list is missing 522MHz and 698MHz. After I have added them (see patch file), I was able to complete the scan. However I think that I have made an error, because I can't watch TV channels fount on the newly added frequencies. Can somebody help me to improve "nl-All" file? You are probably using an old scan file. I pushed an updated version a week or two ago. I'm still working on an automated way to have daily frequency releases, but even then it can take a while before packagers pick it up. Until then, you are free to use: http://git.linuxtv.org/dtv-scan-tables.git/blob_plain/HEAD:/dvb-t/nl-All As for your patch, I think it's wrong. On 522 Mhz (through the country, Delft as well) we have NTS4 (Bouquet 5) which is on a 2/3 coding rate, in your patch it's at 1/2. On 698 MHz we have NTS1 (Bouquet 2) which is on a code rate of 1/2. Feel free to correct me if I'm wrong. Thanks. Additional links: http://dvbt4all.nl/digitenne/zenders/zuid-holland-noord/delft/ http://nl.wikipedia.org/wiki/DVB-T-frequenties -- 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
[REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware
From: Hans Verkuil The v2 of this function doesn't do DMA to objects on the stack like its predecessor does. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/Makefile |4 ++-- drivers/staging/media/go7007/s2250-loader.c |7 --- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile index 5bed78b..f9c8e0f 100644 --- a/drivers/staging/media/go7007/Makefile +++ b/drivers/staging/media/go7007/Makefile @@ -11,8 +11,8 @@ s2250-y := s2250-board.o #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3 -# S2250 needs cypress ezusb loader from dvb-usb -ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb +# S2250 needs cypress ezusb loader from dvb-usb-v2 +ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2 ccflags-y += -Idrivers/media/dvb-frontends ccflags-y += -Idrivers/media/dvb-core diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c index 72e5175..6453ec0 100644 --- a/drivers/staging/media/go7007/s2250-loader.c +++ b/drivers/staging/media/go7007/s2250-loader.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #define S2250_LOADER_FIRMWARE "s2250_loader.fw" #define S2250_FIRMWARE "s2250.fw" @@ -104,7 +105,7 @@ static int s2250loader_probe(struct usb_interface *interface, S2250_LOADER_FIRMWARE); goto failed2; } - ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { dev_err(&interface->dev, "loader download failed\n"); @@ -117,7 +118,7 @@ static int s2250loader_probe(struct usb_interface *interface, S2250_FIRMWARE); goto failed2; } - ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); release_firmware(fw); if (0 != ret) { dev_err(&interface->dev, "firmware_s2250 download failed\n"); -- 1.7.10.4 -- 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
[REVIEW PATCH 22/42] go7007: fix DMA related errors.
From: Hans Verkuil - Don't pass data allocated on the stack to usb_control_msg. - Use dma_mapping_error after calling dma_map_page(). Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h|1 + drivers/staging/media/go7007/go7007-usb.c | 36 +++-- drivers/staging/media/go7007/s2250-board.c|2 +- drivers/staging/media/go7007/saa7134-go7007.c |4 +-- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 1c4b049..daae6dd 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -188,6 +188,7 @@ struct go7007 { int audio_enabled; struct v4l2_subdev *sd_video; struct v4l2_subdev *sd_audio; + u8 usb_buf[16]; /* Video input */ int input; diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 0b1af50..f496720 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -652,7 +652,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go, { struct go7007_usb *usb = go->hpi_context; int i, r; - u16 status_reg; + u16 status_reg = 0; int timeout = 500; #ifdef GO7007_USB_DEBUG @@ -664,15 +664,17 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go, r = usb_control_msg(usb->usbdev, usb_rcvctrlpipe(usb->usbdev, 0), 0x14, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, HPI_STATUS_ADDR, &status_reg, + 0, HPI_STATUS_ADDR, go->usb_buf, sizeof(status_reg), timeout); if (r < 0) - goto write_int_error; - __le16_to_cpus(&status_reg); + break; + status_reg = le16_to_cpu(*((u16 *)go->usb_buf)); if (!(status_reg & 0x0010)) break; msleep(10); } + if (r < 0) + goto write_int_error; if (i == 100) { printk(KERN_ERR "go7007-usb: device is hung, status reg = 0x%04x\n", @@ -700,7 +702,6 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go, int addr, int data) { struct go7007_usb *usb = go->hpi_context; - u8 *tbuf; int r; int timeout = 500; @@ -709,17 +710,14 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go, "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data); #endif - tbuf = kzalloc(8, GFP_KERNEL); - if (tbuf == NULL) - return -ENOMEM; - tbuf[0] = data & 0xff; - tbuf[1] = data >> 8; - tbuf[2] = addr & 0xff; - tbuf[3] = addr >> 8; + go->usb_buf[0] = data & 0xff; + go->usb_buf[1] = data >> 8; + go->usb_buf[2] = addr & 0xff; + go->usb_buf[3] = addr >> 8; + go->usb_buf[4] = go->usb_buf[5] = go->usb_buf[6] = go->usb_buf[7] = 0; r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00, USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa, - 0xf0f0, tbuf, 8, timeout); - kfree(tbuf); + 0xf0f0, go->usb_buf, 8, timeout); if (r < 0) { printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r); return r; @@ -913,7 +911,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter, { struct go7007 *go = i2c_get_adapdata(adapter); struct go7007_usb *usb = go->hpi_context; - u8 buf[16]; + u8 *buf = go->usb_buf; int buf_len, i; int ret = -EIO; @@ -1169,14 +1167,12 @@ static int go7007_usb_probe(struct usb_interface *intf, /* Probe the tuner model on the TV402U */ if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) { - u8 data[3]; - /* Board strapping indicates tuner model */ - if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) { + if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) { printk(KERN_ERR "go7007-usb: GPIO read failed!\n"); goto initfail; } - switch (data[0] >> 6) { + switch (go->usb_buf[0] >> 6) { case 1: go->board_id = GO7007_BOARDID_PX_TV402U_EU; go->tuner_type = TUNER_SONY_BTF_PG472Z; @@ -1309,8 +1305,8 @@ static void go7007_usb_disconnect(struct usb_interface *intf) kfree(go->hpi_context); - go7007_remove(go); go->status = STATUS_SHUTDOWN;
Re: [PATCH] block i2c tuner reads for Avermedia Twinstar in the af9035 driver
On Lunes, 11 de febrero de 2013 14:48:18 Jose Alberto Reguero escribió: > On Domingo, 10 de febrero de 2013 22:11:53 Antti Palosaari escribió: > > On 02/10/2013 09:43 PM, Jose Alberto Reguero wrote: > > > This patch block the i2c tuner reads for Avermedia Twinstar. If it's > > > needed other pids can be added. > > > > > > Signed-off-by: Jose Alberto Reguero > > > > > > diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.c > > > linux.new/drivers/media/usb/dvb-usb-v2/af9035.c --- > > > linux/drivers/media/usb/dvb-usb-v2/af9035.c 2013-01-07 > > > 05:45:57.0 +0100 +++ > > > linux.new/drivers/media/usb/dvb-usb-v2/af9035.c 2013-02-08 > > > 22:55:08.304089054 +0100 @@ -232,7 +232,11 @@ static int > > > af9035_i2c_master_xfer(struct > > > > > > buf[3] = 0x00; /* reg addr MSB */ > > > buf[4] = 0x00; /* reg addr LSB */ > > > memcpy(&buf[5], msg[0].buf, msg[0].len); > > > > > > - ret = af9035_ctrl_msg(d, &req); > > > + if (state->block_read) { > > > + msg[1].buf[0] = 0x3f; > > > + ret = 0; > > > + } else > > > + ret = af9035_ctrl_msg(d, &req); > > > > > > } > > > > > > } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { > > > > > > if (msg[0].len > 40) { > > > > > > @@ -638,6 +642,17 @@ static int af9035_read_config(struct dvb > > > > > > for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) > > > > > > state->af9033_config[i].clock = clock_lut[tmp]; > > > > > > + state->block_read = false; > > > + > > > + if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && > > > + le16_to_cpu(d->udev->descriptor.idProduct) == > > > + USB_PID_AVERMEDIA_TWINSTAR) { > > > + dev_dbg(&d->udev->dev, > > > + "%s: AverMedia Twinstar: block i2c read from > > > tuner\n", > > > + __func__); > > > + state->block_read = true; > > > + } > > > + > > > > > > return 0; > > > > > > err: > > > diff -upr linux/drivers/media/usb/dvb-usb-v2/af9035.h > > > linux.new/drivers/media/usb/dvb-usb-v2/af9035.h --- > > > linux/drivers/media/usb/dvb-usb-v2/af9035.h 2013-01-07 > > > 05:45:57.0 +0100 +++ > > > linux.new/drivers/media/usb/dvb-usb-v2/af9035.h 2013-02-08 > > > 22:52:42.293842710 +0100 @@ -54,6 +54,7 @@ struct usb_req { > > > > > > struct state { > > > > > > u8 seq; /* packet sequence number */ > > > bool dual_mode; > > > > > > + bool block_read; > > > > > > struct af9033_config af9033_config[2]; > > > > > > }; > > > > Could you test if faking tuner ID during attach() is enough? > > > > Also, I would like to know what is returned error code from firmware > > when it fails. Enable debugs to see it. It should print something like > > that: af9035_ctrl_msg: command=03 failed fw error=2 > > > > > > diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c > > b/drivers/media/usb/dvb-usb-v2/af9035.c > > index a1e953a..5a4f28d 100644 > > --- a/drivers/media/usb/dvb-usb-v2/af9035.c > > +++ b/drivers/media/usb/dvb-usb-v2/af9035.c > > @@ -1082,9 +1082,22 @@ static int af9035_tuner_attach(struct > > dvb_usb_adapter *adap) > > > > tuner_addr = 0x60 | 0x80; /* I2C bus hack */ > > > > } > > > > + // fake used tuner for demod firmware / i2c adapter > > + if (adap->id == 0) > > + ret = af9035_wr_reg(d, 0x00f641, > > AF9033_TUNER_FC0011); > > + else > > + ret = af9035_wr_reg(d, 0x10f641, > > AF9033_TUNER_FC0011); > > + > > > > /* attach tuner */ > > fe = dvb_attach(mxl5007t_attach, adap->fe[0], > > &d->i2c_adap, > > > > tuner_addr, > > > > &af9035_mxl5007t_config[adap->id]); > > + > > + // return correct tuner > > + if (adap->id == 0) > > + ret = af9035_wr_reg(d, 0x00f641, > > AF9033_TUNER_MXL5007T); > > + else > > + ret = af9035_wr_reg(d, 0x10f641, > > AF9033_TUNER_MXL5007T); > > + > > > > break; > > > > case AF9033_TUNER_TDA18218: > > /* attach tuner */ > > > > regards > > Antti > > I will try with fake tuner, but I can't test unil next weekend. > If I remember, the read operation is performed, and return good value, > but after that, all the i2c transfers fail. Seee: > > http://www.mail-archive.com/linux-media@vger.kernel.org/msg56346.html > > Jose Alberto > > I tried with fake tuner without success: [ 1346.707405] DVB: registering new adapter (AVerMedia Twinstar (A825)) [
Re: [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock
On Mon March 11 2013 12:45:39 Hans Verkuil wrote: > From: Andy Walls Oops, somehow I messed up Andy's email. I've corrected it in my git tree. Regards, Hans > > When calling v4l2_ctrl_add_handler(), lockdep would detect a potential > recursive locking problem on a situation that is by design intended and > not a recursive lock. This happened because all struct > v4l2_ctrl_handler.lock mutexes were created as members of the same lock > class in v4l2_ctrl_handler_init(), and v4l2_ctrl_add_handler() takes the > hdl->lock on two different v4l2_ctrl_handler instances. > > This change breaks the large lockdep lock class for struct > v4l2_ctrl_handler.lock and breaks it into v4l2_ctrl_handler > instantiation specific lock classes with meaningful class names. > > This will validly eliminate lockdep alarms for v4l2_ctrl_handler locking > validation, as long as the relationships between drivers adding v4l2 > controls to their own handler from other v4l2 drivers' control handlers > remains straightforward. > > struct v4l2_ctrl_handler.lock lock classes are created with names such > that the output of cat /proc/lockdep indicates where in the v4l2 driver > code v4l2_ctrl_handle_init() is being called on instantiations: > > a045f490 FD: 10 BD:8 +.+...: cx2341x:1534:(hdl)->lock > a0497d20 FD: 12 BD:2 +.+.+.: saa7115:1581:(hdl)->lock > a04ac660 FD: 14 BD:2 +.+.+.: msp3400_driver:756:(hdl)->lock > a0484b90 FD: 12 BD:1 +.+.+.: > ivtv_gpio:366:(&itv->hdl_gpio)->lock > a04eb530 FD: 11 BD:2 +.+.+.: > cx25840_core:1982:(&state->hdl)->lock > a04fbc80 FD: 11 BD:3 +.+.+.: wm8775:246:(&state->hdl)->lock > > Some lock chains, that were previously causing the recursion alarms, are > now visible in the output of cat /proc/lockdep_chains: > > irq_context: 0 > [a0497d20] saa7115:1581:(hdl)->lock > [a045f490] cx2341x:1534:(hdl)->lock > > irq_context: 0 > [a04ac660] msp3400_driver:756:(hdl)->lock > [a045f490] cx2341x:1534:(hdl)->lock > > irq_context: 0 > [a0484b90] ivtv_gpio:366:(&itv->hdl_gpio)->lock > [a045f490] cx2341x:1534:(hdl)->lock > > irq_context: 0 > [a04eb530] cx25840_core:1982:(&state->hdl)->lock > [a045f490] cx2341x:1534:(hdl)->lock > > irq_context: 0 > [a04fbc80] wm8775:246:(&state->hdl)->lock > [a045f490] cx2341x:1534:(hdl)->lock > > Signed-off-by: Andy Walls md.metrocast.net> > [hans.verk...@cisco.com: keep mutex_init in v4l2_ctrl_handler_init_class] > Signed-off-by: Hans Verkuil > --- > drivers/media/v4l2-core/v4l2-ctrls.c |8 +--- > include/media/v4l2-ctrls.h | 29 ++--- > 2 files changed, 31 insertions(+), 6 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c > b/drivers/media/v4l2-core/v4l2-ctrls.c > index 6b28b58..b36d1ec 100644 > --- a/drivers/media/v4l2-core/v4l2-ctrls.c > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c > @@ -1362,11 +1362,13 @@ static inline int handler_set_err(struct > v4l2_ctrl_handler *hdl, int err) > } > > /* Initialize the handler */ > -int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, > -unsigned nr_of_controls_hint) > +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, > + unsigned nr_of_controls_hint, > + struct lock_class_key *key, const char *name) > { > hdl->lock = &hdl->_lock; > mutex_init(hdl->lock); > + lockdep_set_class_and_name(hdl->lock, key, name); > INIT_LIST_HEAD(&hdl->ctrls); > INIT_LIST_HEAD(&hdl->ctrl_refs); > hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; > @@ -1375,7 +1377,7 @@ int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler > *hdl, > hdl->error = hdl->buckets ? 0 : -ENOMEM; > return hdl->error; > } > -EXPORT_SYMBOL(v4l2_ctrl_handler_init); > +EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); > > /* Free all controls and control refs */ > void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) > diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h > index f00d42b..7343a27 100644 > --- a/include/media/v4l2-ctrls.h > +++ b/include/media/v4l2-ctrls.h > @@ -259,7 +259,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum > v4l2_ctrl_type *type, > s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags); > > > -/** v4l2_ctrl_handler_init() - Initialize the control handler. > +/** v4l2_ctrl_handler_init_class() - Initialize the control handler. >* @hdl:The control handler. >* @nr_of_controls_hint: A hint of how many controls this handler is >* expected to refer to. This is the total number, so including > @@ -268,12 +268,35 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum > v4l2_ctrl_type *type, >* are allocated) or the control lookup becomes slower (not enough >* buckets are a
[REVIEW PATCH 15/42] go7007: i2c initialization changes for tw2804
From: Volokh Konstantin Do i2c initialization via struct item as tw2804 has a 0x00 i2c address, so we need to use the I2C_CLIENT_TEN flag for validity. Signed-off-by: Volokh Konstantin Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 20 +++- drivers/staging/media/go7007/go7007-priv.h |3 ++- drivers/staging/media/go7007/go7007-usb.c|1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 6695091..2e5be70 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -196,18 +196,22 @@ int go7007_reset_encoder(struct go7007 *go) /* * Attempt to instantiate an I2C client by ID, probably loading a module. */ -static int init_i2c_module(struct i2c_adapter *adapter, const char *type, - int addr) +static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *const i2c) { struct go7007 *go = i2c_get_adapdata(adapter); struct v4l2_device *v4l2_dev = &go->v4l2_dev; + struct i2c_board_info info; - if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL)) + memset(&info, 0, sizeof(info)); + strlcpy(info.type, i2c->type, sizeof(info.type)); + info.addr = i2c->addr; + info.flags = i2c->flags; + + if (v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL)) return 0; - dev_info(&adapter->dev, -"go7007: probing for module i2c:%s failed\n", type); - return -1; + printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type); + return -EINVAL; } /* @@ -243,9 +247,7 @@ int go7007_register_encoder(struct go7007 *go) } if (go->i2c_adapter_online) { for (i = 0; i < go->board_info->num_i2c_devs; ++i) - init_i2c_module(&go->i2c_adapter, - go->board_info->i2c_devs[i].type, - go->board_info->i2c_devs[i].addr); + init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]); if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) i2c_clients_command(&go->i2c_adapter, DECODER_SET_CHANNEL, &go->channel_number); diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index b58c394..b9ebdfb 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -88,10 +88,11 @@ struct go7007_board_info { int audio_bclk_div; int audio_main_div; int num_i2c_devs; - struct { + struct go_i2c { const char *type; int id; int addr; + u32 flags; } i2c_devs[4]; int num_inputs; struct { diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index a8f..b44f9b1 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -398,6 +398,7 @@ static struct go7007_usb_board board_adlink_mpg24 = { .type = "wis_tw2804", .id = I2C_DRIVERID_WIS_TW2804, .addr = 0x00, /* yes, really */ + .flags = I2C_CLIENT_TEN, }, }, .num_inputs = 1, -- 1.7.10.4 -- 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
[REVIEW PATCH 10/42] ov7640: add new ov7640 driver
From: Hans Verkuil This based on the wis-ov7640.c driver that's part of the go7007 driver. It has been converted to a v4l subdev driver by Pete Eberlein, and I made additional cleanups. Based on work by: Pete Eberlein Signed-off-by: Hans Verkuil Cc: Pete Eberlein --- drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/Makefile |3 +- drivers/media/i2c/ov7640.c | 106 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 drivers/media/i2c/ov7640.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 70dbae2..fe5f9d0 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -395,6 +395,17 @@ config VIDEO_APTINA_PLL config VIDEO_SMIAPP_PLL tristate +config VIDEO_OV7640 + tristate "OmniVision OV7640 sensor support" + depends on I2C && VIDEO_V4L2 + depends on MEDIA_CAMERA_SUPPORT + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV7640 camera. + + To compile this driver as a module, choose M here: the + module will be called ov7640. + config VIDEO_OV7670 tristate "OmniVision OV7670 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 4c57075..adf9504 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -47,7 +47,8 @@ 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_OV7670) += ov7670.o +obj-$(CONFIG_VIDEO_OV7640) += ov7640.o +obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV9650) += ov9650.o obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c new file mode 100644 index 000..b0cc927 --- /dev/null +++ b/drivers/media/i2c/ov7640.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2006 Micronas USA Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("OmniVision ov7640 sensor driver"); +MODULE_LICENSE("GPL v2"); + +static const u8 initial_registers[] = { + 0x12, 0x80, + 0x12, 0x54, + 0x14, 0x24, + 0x15, 0x01, + 0x28, 0x20, + 0x75, 0x82, + 0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */ +}; + +static int write_regs(struct i2c_client *client, const u8 *regs) +{ + int i; + + for (i = 0; regs[i] != 0xFF; i += 2) + if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0) + return -1; + return 0; +} + +/* --- */ + +static const struct v4l2_subdev_ops ov7640_ops; + +static int ov7640_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct v4l2_subdev *sd; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + v4l2_i2c_subdev_init(sd, client, &ov7640_ops); + + client->flags = I2C_CLIENT_SCCB; + + v4l_info(client, "chip found @ 0x%02x (%s)\n", + client->addr << 1, client->adapter->name); + + if (write_regs(client, initial_registers) < 0) { + v4l_err(client, "error initializing OV7640\n"); + kfree(sd); + return -ENODEV; + } + + return 0; +} + + +static int ov7640_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_device_unregister_subdev(sd); + kfree(sd); + return 0; +} + +static const struct i2c_device_id ov7640_id[] = { + { "ov7640", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov7640_id); + +static struct i2c_driver ov7640_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "ov7640", + }, + .probe = ov7640_probe, + .remove = ov7640_remove, +
[REVIEW PATCH 11/42] uda1342: add new uda1342 audio codec driver
From: Hans Verkuil This based on the wis-uda1342.c driver that's part of the go7007 driver. It has been converted to a v4l subdev driver by Pete Eberlein, and I made additional cleanups. Based on work by: Pete Eberlein Signed-off-by: Hans Verkuil Cc: Pete Eberlein --- drivers/media/i2c/Kconfig |9 drivers/media/i2c/Makefile |1 + drivers/media/i2c/uda1342.c | 113 +++ include/media/uda1342.h | 29 +++ 4 files changed, 152 insertions(+) create mode 100644 drivers/media/i2c/uda1342.c create mode 100644 include/media/uda1342.h diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index fe5f9d0..8000642 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -112,6 +112,15 @@ config VIDEO_TLV320AIC23B To compile this driver as a module, choose M here: the module will be called tlv320aic23b. +config VIDEO_UDA1342 + tristate "Philips UDA1342 audio codec" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Philips UDA1342 audio codec. + + To compile this driver as a module, choose M here: the + module will be called uda1342. + config VIDEO_WM8775 tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index adf9504..b1775b3 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o obj-$(CONFIG_VIDEO_M52790) += m52790.o obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o +obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o obj-$(CONFIG_VIDEO_WM8775) += wm8775.o obj-$(CONFIG_VIDEO_WM8739) += wm8739.o obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c new file mode 100644 index 000..3af4085 --- /dev/null +++ b/drivers/media/i2c/uda1342.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005-2006 Micronas USA Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int write_reg(struct i2c_client *client, int reg, int value) +{ + /* UDA1342 wants MSB first, but SMBus sends LSB first */ + i2c_smbus_write_word_data(client, reg, swab16(value)); + return 0; +} + +static int uda1342_s_routing(struct v4l2_subdev *sd, + u32 input, u32 output, u32 config) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + switch (input) { + case UDA1342_IN1: + write_reg(client, 0x00, 0x1241); /* select input 1 */ + break; + case UDA1342_IN2: + write_reg(client, 0x00, 0x1441); /* select input 2 */ + break; + default: + v4l2_err(sd, "input %d not supported\n", input); + break; + } + return 0; +} + +static const struct v4l2_subdev_audio_ops uda1342_audio_ops = { + .s_routing = uda1342_s_routing, +}; + +static const struct v4l2_subdev_ops uda1342_ops = { + .audio = &uda1342_audio_ops, +}; + +static int uda1342_probe(struct i2c_client *client, +const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct v4l2_subdev *sd; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n", + client->addr, adapter->name); + + sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + + v4l2_i2c_subdev_init(sd, client, &uda1342_ops); + + write_reg(client, 0x00, 0x8000); /* reset registers */ + write_reg(client, 0x00, 0x1241); /* select input 1 */ + + v4l_info(client, "chip found @ 0x%02x (%s)\n", + client->addr << 1, client->adapter->name); + + return 0; +} + +static int uda1342_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_device_unregister_subdev(sd); + kfree(sd); + return 0; +} + +static const struct i2c_device_id ud
[REVIEW PATCH 18/42] go7007: add audio input ioctls.
From: Hans Verkuil Since we now know what audio inputs there are, we can also get/set and enumerate them. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-v4l2.c | 51 ++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index bab4a31..b79cda8 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -608,9 +608,10 @@ static int vidioc_querycap(struct file *file, void *priv, cap->version = KERNEL_VERSION(0, 9, 8); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */ + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + if (go->board_info->num_aud_inputs) + cap->device_caps |= V4L2_CAP_AUDIO; if (go->board_info->flags & GO7007_BOARD_HAS_TUNER) cap->capabilities |= V4L2_CAP_TUNER; @@ -1191,7 +1192,10 @@ static int vidioc_enum_input(struct file *file, void *priv, else inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->audioset = 0; + if (go->board_info->num_aud_inputs) + inp->audioset = (1 << go->board_info->num_aud_inputs) - 1; + else + inp->audioset = 0; inp->tuner = 0; if (go->board_info->sensor_flags & GO7007_SENSOR_TV) inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | @@ -1212,6 +1216,39 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) return 0; } +static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) +{ + struct go7007 *go = video_drvdata(file); + + if (a->index >= go->board_info->num_aud_inputs) + return -EINVAL; + strlcpy(a->name, go->board_info->aud_inputs[a->index].name, sizeof(a->name)); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) +{ + struct go7007 *go = video_drvdata(file); + + a->index = go->aud_input; + strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name, sizeof(a->name)); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) +{ + struct go7007 *go = video_drvdata(file); + + if (a->index >= go->board_info->num_aud_inputs) + return -EINVAL; + go->aud_input = a->index; + v4l2_subdev_call(go->sd_audio, audio, s_routing, + go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0); + return 0; +} + static int vidioc_s_input(struct file *file, void *priv, unsigned int input) { struct go7007 *go = ((struct go7007_file *) priv)->go; @@ -1772,6 +1809,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_enum_input= vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, + .vidioc_enumaudio = vidioc_enumaudio, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_ctrl= vidioc_g_ctrl, .vidioc_s_ctrl= vidioc_s_ctrl, @@ -1816,6 +1856,11 @@ int go7007_v4l2_init(struct go7007 *go) go->video_dev = NULL; return rv; } + if (go->board_info->num_aud_inputs == 0) { + v4l2_disable_ioctl(go->video_dev, VIDIOC_G_AUDIO); + v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO); + v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO); + } rv = v4l2_device_register(go->dev, &go->v4l2_dev); if (rv < 0) { video_device_release(go->video_dev); -- 1.7.10.4 -- 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
[REVIEW PATCH 20/42] go7007: go7007: add device_caps and bus_info support to querycap.
From: Hans Verkuil And don't set the version field, the core does that for you. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h|1 + drivers/staging/media/go7007/go7007-usb.c |1 + drivers/staging/media/go7007/go7007-v4l2.c| 10 +++--- drivers/staging/media/go7007/saa7134-go7007.c |1 + 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 898eb5b..1c4b049 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -171,6 +171,7 @@ enum go7007_parser_state { struct go7007 { struct device *dev; + u8 bus_info[32]; struct go7007_board_info *board_info; unsigned int board_id; int tuner_type; diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 5e3e5a0..0b1af50 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -1087,6 +1087,7 @@ static int go7007_usb_probe(struct usb_interface *intf, goto allocfail; usb->board = board; usb->usbdev = usbdev; + usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info)); go->board_id = id->driver_info; strncpy(go->name, name, sizeof(go->name)); if (board->flags & GO7007_USB_EZUSB) diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index b79cda8..6f14ac5 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -602,19 +602,15 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->driver, "go7007", sizeof(cap->driver)); strlcpy(cap->card, go->name, sizeof(cap->card)); -#if 0 - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); -#endif - - cap->version = KERNEL_VERSION(0, 9, 8); + strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; if (go->board_info->num_aud_inputs) cap->device_caps |= V4L2_CAP_AUDIO; if (go->board_info->flags & GO7007_BOARD_HAS_TUNER) - cap->capabilities |= V4L2_CAP_TUNER; - + cap->device_caps |= V4L2_CAP_TUNER; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c index e037a39..d65e17a 100644 --- a/drivers/staging/media/go7007/saa7134-go7007.c +++ b/drivers/staging/media/go7007/saa7134-go7007.c @@ -456,6 +456,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev) if (go == NULL) goto allocfail; go->board_id = GO7007_BOARDID_PCI_VOYAGER; + snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci)); strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name)); go->hpi_ops = &saa7134_go7007_hpi_ops; go->hpi_context = saa; -- 1.7.10.4 -- 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
[REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs.
From: Hans Verkuil Instead of using the wis-* drivers we now use the standard 'proper' subdev drivers. The board configuration tables now also list the possible audio inputs, this will be used later to implement audio inputs. Special mention deserves a little change in set_capture_size() where the height passed to s_mbus_fmt is doubled: that is because the saa7115 driver expects to see the frame height, not the field height as the wis_saa7115 driver did. Another change is that the tuner input is moved from last to the first input, which is consistent with the common practice in other video drivers. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/Kconfig | 77 ++--- drivers/staging/media/go7007/Makefile | 12 --- drivers/staging/media/go7007/go7007-driver.c | 29 +-- drivers/staging/media/go7007/go7007-i2c.c |1 - drivers/staging/media/go7007/go7007-priv.h| 18 +++- drivers/staging/media/go7007/go7007-usb.c | 112 + drivers/staging/media/go7007/go7007-v4l2.c| 18 +++- drivers/staging/media/go7007/saa7134-go7007.c |2 +- 8 files changed, 135 insertions(+), 134 deletions(-) diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig index 7dfb281..da32031 100644 --- a/drivers/staging/media/go7007/Kconfig +++ b/drivers/staging/media/go7007/Kconfig @@ -8,6 +8,12 @@ config VIDEO_GO7007 select VIDEO_TVEEPROM select SND_PCM select CRC32 + select VIDEO_SONY_BTF_MPX if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT default N ---help--- This is a video4linux driver for the WIS GO7007 MPEG @@ -36,74 +42,3 @@ config VIDEO_GO7007_USB_S2250_BOARD To compile this driver as a module, choose M here: the module will be called s2250 - -config VIDEO_GO7007_OV7640 - tristate "OV7640 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the OV7640 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-ov7640 - -config VIDEO_GO7007_SAA7113 - tristate "SAA7113 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the SAA7113 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-saa7113 - -config VIDEO_GO7007_SAA7115 - tristate "SAA7115 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the SAA7115 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-saa7115 - -config VIDEO_GO7007_TW9903 - tristate "TW9903 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the TW9903 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-tw9903 - -config VIDEO_GO7007_UDA1342 - tristate "UDA1342 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the UDA1342 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-uda1342 - -config VIDEO_GO7007_SONY_TUNER - tristate "Sony tuner subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the Sony Tuner sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-sony-tuner - -config VIDEO_GO7007_TW2804 - tristate "TW2804 subdev support" - depends on VIDEO_GO7007 - default N - ---help--- - This is a video4linux driver for the TW2804 sub-device. - - To compile this driver as a module, choose M here: the - module will be called wis-tw2804 - diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile index 3fdbef5..5bed78b 100644 --- a/drivers/staging/media/go7007/Makefile +++ b/drivers/staging/media/go7007/Makefile @@ -1,18 +1,6 @@ -#obj-m += go7007.o go7007-usb.o snd-go7007.o wis-saa7115.o wis-tw9903.o \ - wis-uda1342.o wis-sony-tuner.o wis-saa7113.o wis-ov7640.o \ - wis-tw2804.o - - obj-$(CONFIG_VIDEO_GO7007) += go7007.o obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o -obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o -obj-$(CONFIG_VID
[REVIEW PATCH 07/42] go7007: fix i2c_xfer return codes.
From: Hans Verkuil The i2c_xfer functions didn't return the proper error codes and (especially important) on success they returned 0 instead of the number of transferred messages. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-i2c.c | 20 ++-- drivers/staging/media/go7007/go7007-usb.c |6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c index 39456a3..1d0a400 100644 --- a/drivers/staging/media/go7007/go7007-i2c.c +++ b/drivers/staging/media/go7007/go7007-i2c.c @@ -52,11 +52,11 @@ static DEFINE_MUTEX(adlink_mpg24_i2c_lock); static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read, u16 command, int flags, u8 *data) { - int i, ret = -1; + int i, ret = -EIO; u16 val; if (go->status == STATUS_SHUTDOWN) - return -1; + return -ENODEV; #ifdef GO7007_I2C_DEBUG if (read) @@ -146,7 +146,7 @@ static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr, struct go7007 *go = i2c_get_adapdata(adapter); if (size != I2C_SMBUS_BYTE_DATA) - return -1; + return -EIO; return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command, flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte); } @@ -170,26 +170,26 @@ static int go7007_i2c_master_xfer(struct i2c_adapter *adapter, (msgs[i].flags & I2C_M_RD) || !(msgs[i + 1].flags & I2C_M_RD) || msgs[i + 1].len != 1) - return -1; + return -EIO; if (go7007_i2c_xfer(go, msgs[i].addr, 1, (msgs[i].buf[0] << 8) | msgs[i].buf[1], 0x01, &msgs[i + 1].buf[0]) < 0) - return -1; + return -EIO; ++i; } else if (msgs[i].len == 3) { if (msgs[i].flags & I2C_M_RD) - return -1; + return -EIO; if (msgs[i].len != 3) - return -1; + return -EIO; if (go7007_i2c_xfer(go, msgs[i].addr, 0, (msgs[i].buf[0] << 8) | msgs[i].buf[1], 0x01, &msgs[i].buf[2]) < 0) - return -1; + return -EIO; } else - return -1; + return -EIO; } - return 0; + return num; } static u32 go7007_functionality(struct i2c_adapter *adapter) diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 9dbf5ec..914b247 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -876,10 +876,10 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter, struct go7007_usb *usb = go->hpi_context; u8 buf[16]; int buf_len, i; - int ret = -1; + int ret = -EIO; if (go->status == STATUS_SHUTDOWN) - return -1; + return -ENODEV; mutex_lock(&usb->i2c_lock); @@ -936,7 +936,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter, memcpy(msgs[i].buf, buf + 1, msgs[i].len); } } - ret = 0; + ret = num; i2c_done: mutex_unlock(&usb->i2c_lock); -- 1.7.10.4 -- 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
[REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder.
From: Hans Verkuil This based on the wis-tw9903.c driver that's part of the go7007 driver. It has been converted to a v4l subdev driver by Pete Eberlein, and I made additional cleanups. Based on work by: Pete Eberlein Signed-off-by: Hans Verkuil Cc: Pete Eberlein --- drivers/media/i2c/Kconfig | 10 ++ drivers/media/i2c/Makefile |1 + drivers/media/i2c/tw9903.c | 274 3 files changed, 285 insertions(+) create mode 100644 drivers/media/i2c/tw9903.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 8000642..eb9ef55 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -301,6 +301,16 @@ config VIDEO_TVP7002 To compile this driver as a module, choose M here: the module will be called tvp7002. +config VIDEO_TW9903 + tristate "Techwell TW9903 video decoder" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Techwell 9903 multi-standard video decoder + with high quality down scaler. + + To compile this driver as a module, choose M here: the + module will be called tw9903. + config VIDEO_VPX3220 tristate "vpx3220a, vpx3216b & vpx3214c video decoders" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index b1775b3..af8fb29 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o +obj-$(CONFIG_VIDEO_TW9903) += tw9903.o obj-$(CONFIG_VIDEO_CS5345) += cs5345.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o obj-$(CONFIG_VIDEO_M52790) += m52790.o diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c new file mode 100644 index 000..82626ea --- /dev/null +++ b/drivers/media/i2c/tw9903.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2005-2006 Micronas USA Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("TW9903 I2C subdev driver"); +MODULE_LICENSE("GPL v2"); + +/* + * This driver is based on the wis-tw9903.c source that was in + * drivers/staging/media/go7007. That source had commented out code for + * saturation and scaling (neither seemed to work). If anyone ever gets + * hardware to test this driver, then that code might be useful to look at. + * You need to get the kernel sources of, say, kernel 3.8 where that + * wis-tw9903 driver is still present. + */ + +struct tw9903 { + struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; + v4l2_std_id norm; +}; + +static inline struct tw9903 *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct tw9903, sd); +} + +static const u8 initial_registers[] = { + 0x02, 0x44, /* input 1, composite */ + 0x03, 0x92, /* correct digital format */ + 0x04, 0x00, + 0x05, 0x80, /* or 0x00 for PAL */ + 0x06, 0x40, /* second internal current reference */ + 0x07, 0x02, /* window */ + 0x08, 0x14, /* window */ + 0x09, 0xf0, /* window */ + 0x0a, 0x81, /* window */ + 0x0b, 0xd0, /* window */ + 0x0c, 0x8c, + 0x0d, 0x00, /* scaling */ + 0x0e, 0x11, /* scaling */ + 0x0f, 0x00, /* scaling */ + 0x10, 0x00, /* brightness */ + 0x11, 0x60, /* contrast */ + 0x12, 0x01, /* sharpness */ + 0x13, 0x7f, /* U gain */ + 0x14, 0x5a, /* V gain */ + 0x15, 0x00, /* hue */ + 0x16, 0xc3, /* sharpness */ + 0x18, 0x00, + 0x19, 0x58, /* vbi */ + 0x1a, 0x80, + 0x1c, 0x0f, /* video norm */ + 0x1d, 0x7f, /* video norm */ + 0x20, 0xa0, /* clamping gain (working 0x50) */ + 0x21, 0x22, + 0x22, 0xf0, + 0x23, 0xfe, + 0x24, 0x3c, + 0x25, 0x38, + 0x26, 0x44, + 0x27, 0x20, + 0x28, 0x00, + 0x29, 0x15, + 0x2a, 0xa0, + 0x2b, 0x44, + 0x2c, 0x37, + 0x2d, 0x00, + 0x2e, 0xa5, /* burst PLL control (working: a9) */ + 0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */ + 0x31, 0x00, + 0x33, 0x22, + 0x34, 0x11, + 0x35, 0x35, + 0x3b, 0x05, +
[REVIEW PATCH 25/42] go7007: convert to the control framework and remove obsolete JPEGCOMP support.
From: Hans Verkuil Just add a read-only V4L2_CID_JPEG_ACTIVE_MARKER control to replace the JPEGCOMP support. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 11 +- drivers/staging/media/go7007/go7007-priv.h |3 + drivers/staging/media/go7007/go7007-v4l2.c | 249 +++--- 3 files changed, 71 insertions(+), 192 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index dca85d8..d689989 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -268,12 +268,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs) ret = go7007_init_encoder(go); mutex_unlock(&go->hw_lock); if (ret < 0) - return -1; + return ret; + + ret = go7007_v4l2_ctrl_init(go); + if (ret < 0) + return ret; if (!go->i2c_adapter_online && go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) { - if (go7007_i2c_init(go) < 0) - return -1; + ret = go7007_i2c_init(go); + if (ret < 0) + return ret; go->i2c_adapter_online = 1; } if (go->i2c_adapter_online) { diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 54cfc0a..d127a8d 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -22,6 +22,7 @@ */ #include +#include struct go7007; @@ -182,6 +183,7 @@ struct go7007 { void *boot_fw; unsigned boot_fw_len; struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler hdl; enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; spinlock_t spinlock; struct mutex hw_lock; @@ -296,6 +298,7 @@ int go7007_i2c_remove(struct go7007 *go); /* go7007-v4l2.c */ int go7007_v4l2_init(struct go7007 *go); +int go7007_v4l2_ctrl_init(struct go7007 *go); void go7007_v4l2_remove(struct go7007 *go); /* snd-go7007.c */ diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 53d2cbc..cb89af3 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -42,9 +42,6 @@ #ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM #defineV4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */ #endif -#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4 -#defineV4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 -#endif #define call_all(dev, o, f, args...) \ v4l2_device_call_until_err(dev, 0, o, f, ##args) @@ -387,67 +384,18 @@ static int clip_to_modet_map(struct go7007 *go, int region, } #endif -static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl) +static int go7007_s_ctrl(struct v4l2_ctrl *ctrl) { - static const u32 mpeg_ctrls[] = { - V4L2_CID_MPEG_CLASS, - V4L2_CID_MPEG_STREAM_TYPE, - V4L2_CID_MPEG_VIDEO_ENCODING, - V4L2_CID_MPEG_VIDEO_ASPECT, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - V4L2_CID_MPEG_VIDEO_BITRATE, - 0 - }; - static const u32 *ctrl_classes[] = { - mpeg_ctrls, - NULL - }; - - ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id); - - switch (ctrl->id) { - case V4L2_CID_MPEG_CLASS: - return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(ctrl, - V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, - V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1, - V4L2_MPEG_STREAM_TYPE_MPEG_ELEM); - case V4L2_CID_MPEG_VIDEO_ENCODING: - return v4l2_ctrl_query_fill(ctrl, - V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(ctrl, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_16x9, 1, - V4L2_MPEG_VIDEO_ASPECT_1x1); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15); - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0); - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(ctrl, - 64000, - 1000, 1, - 150); - default: - return -EINVAL; -
[REVIEW PATCH 28/42] go7007: add log_status support.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-v4l2.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 186a56b..d3eef8d 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -1188,6 +1188,14 @@ static int vidioc_s_frequency(struct file *file, void *priv, return call_all(&go->v4l2_dev, tuner, s_frequency, f); } +static int vidioc_log_status(struct file *file, void *priv) +{ + struct go7007 *go = ((struct go7007_file *) priv)->go; + + v4l2_ctrl_log_status(file, priv); + return call_all(&go->v4l2_dev, core, log_status); +} + static int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap) { @@ -1654,7 +1662,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_cropcap = vidioc_cropcap, .vidioc_g_crop= vidioc_g_crop, .vidioc_s_crop= vidioc_s_crop, - .vidioc_log_status= v4l2_ctrl_log_status, + .vidioc_log_status= vidioc_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -- 1.7.10.4 -- 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
[REVIEW PATCH 31/42] go7007: simplify the PX-TV402U board ID handling.
From: Hans Verkuil There really is no need to split out the board IDs for each tuner. That's what the tuner_type is for, after all. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h | 15 ++- drivers/staging/media/go7007/go7007-usb.c |9 +++-- drivers/staging/media/go7007/go7007-v4l2.c |9 - 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index c2fafb2..a6ef67b 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -36,15 +36,12 @@ struct go7007; #define GO7007_BOARDID_XMEN_II 5 #define GO7007_BOARDID_XMEN_III6 #define GO7007_BOARDID_MATRIX_REV 7 -#define GO7007_BOARDID_PX_M402U16 -#define GO7007_BOARDID_PX_TV402U_ANY 17 /* need to check tuner model */ -#define GO7007_BOARDID_PX_TV402U_NA18 /* detected NTSC tuner */ -#define GO7007_BOARDID_PX_TV402U_EU19 /* detected PAL tuner */ -#define GO7007_BOARDID_PX_TV402U_JP20 /* detected NTSC-J tuner */ -#define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */ -#define GO7007_BOARDID_ENDURA 22 -#define GO7007_BOARDID_ADLINK_MPG2423 -#define GO7007_BOARDID_SENSORAY_2250 24 /* Sensoray 2250/2251 */ +#define GO7007_BOARDID_PX_M402U8 +#define GO7007_BOARDID_PX_TV402U 9 +#define GO7007_BOARDID_LIFEVIEW_LR192 10 /* TV Walker Ultra */ +#define GO7007_BOARDID_ENDURA 11 +#define GO7007_BOARDID_ADLINK_MPG2412 +#define GO7007_BOARDID_SENSORAY_2250 13 /* Sensoray 2250/2251 */ /* Various characteristics of each board */ #define GO7007_BOARD_HAS_AUDIO (1<<0) diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 14d1cda..53c5b16 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -568,7 +568,7 @@ static const struct usb_device_id go7007_usb_id_table[] = { .idProduct = 0xa104, /* Product ID of TV402U */ .bcdDevice_lo = 0x1, .bcdDevice_hi = 0x1, - .driver_info= (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY, + .driver_info= (kernel_ulong_t)GO7007_BOARDID_PX_TV402U, }, { .match_flags= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, @@ -1079,7 +1079,7 @@ static int go7007_usb_probe(struct usb_interface *intf, name = "Plextor PX-M402U"; board = &board_matrix_ii; break; - case GO7007_BOARDID_PX_TV402U_ANY: + case GO7007_BOARDID_PX_TV402U: name = "Plextor PX-TV402U (unknown tuner)"; board = &board_px_tv402u; break; @@ -1200,7 +1200,7 @@ static int go7007_usb_probe(struct usb_interface *intf, num_i2c_devs = go->board_info->num_i2c_devs; /* Probe the tuner model on the TV402U */ - if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) { + if (go->board_id == GO7007_BOARDID_PX_TV402U) { /* Board strapping indicates tuner model */ if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) { printk(KERN_ERR "go7007-usb: GPIO read failed!\n"); @@ -1208,14 +1208,12 @@ static int go7007_usb_probe(struct usb_interface *intf, } switch (go->usb_buf[0] >> 6) { case 1: - go->board_id = GO7007_BOARDID_PX_TV402U_EU; go->tuner_type = TUNER_SONY_BTF_PG472Z; go->std = V4L2_STD_PAL; strncpy(go->name, "Plextor PX-TV402U-EU", sizeof(go->name)); break; case 2: - go->board_id = GO7007_BOARDID_PX_TV402U_JP; go->tuner_type = TUNER_SONY_BTF_PK467Z; go->std = V4L2_STD_NTSC_M_JP; num_i2c_devs -= 2; @@ -1223,7 +1221,6 @@ static int go7007_usb_probe(struct usb_interface *intf, sizeof(go->name)); break; case 3: - go->board_id = GO7007_BOARDID_PX_TV402U_NA; go->tuner_type = TUNER_SONY_BTF_PB463Z; num_i2c_devs -= 2; strncpy(go->name, "Plextor PX-TV402U-NA", diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index df5296f..fd6cae0 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -1075,15 +1075,6 @@ static int vidioc_s_tuner(struct file *file, void *priv, if (t->index != 0) return -EINVAL; - switch (go->board_id) { - case GO70
[REVIEW PATCH 33/42] go7007: drop struct go7007_file
From: Hans Verkuil Remove struct go7007_file: all fields contained in that struct are moved to the go7007 struct since they are really global values. The lock has just been deleted (what's the point of a per-fh lock??). Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h | 11 +- drivers/staging/media/go7007/go7007-v4l2.c | 177 ++-- 2 files changed, 67 insertions(+), 121 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 7f79cc1..2c0afb1 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -141,14 +141,6 @@ struct go7007_buffer { int mapped; }; -struct go7007_file { - struct v4l2_fh fh; - struct go7007 *go; - struct mutex lock; - int buf_count; - struct go7007_buffer *bufs; -}; - #define GO7007_RATIO_1_1 0 #define GO7007_RATIO_4_3 1 #define GO7007_RATIO_16_9 2 @@ -242,6 +234,9 @@ struct go7007 { u32 next_seq; struct list_head stream; wait_queue_head_t frame_waitq; + int buf_count; + struct go7007_buffer *bufs; + struct v4l2_fh *bufs_owner; /* Audio streaming */ void (*audio_deliver)(struct go7007 *go, u8 *buf, int length); diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 972f8a5..191af80 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -88,41 +88,19 @@ static int go7007_streamoff(struct go7007 *go) return 0; } -static int go7007_open(struct file *file) -{ - struct go7007 *go = video_get_drvdata(video_devdata(file)); - struct go7007_file *gofh; - - if (go->status != STATUS_ONLINE) - return -EBUSY; - gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL); - if (gofh == NULL) - return -ENOMEM; - gofh->go = go; - mutex_init(&gofh->lock); - gofh->buf_count = 0; - file->private_data = gofh; - v4l2_fh_init(&gofh->fh, video_devdata(file)); - v4l2_fh_add(&gofh->fh); - return 0; -} - static int go7007_release(struct file *file) { - struct go7007_file *gofh = file->private_data; - struct go7007 *go = gofh->go; + struct go7007 *go = video_drvdata(file); - if (gofh->buf_count > 0) { + if (file->private_data == go->bufs_owner && go->buf_count > 0) { go7007_streamoff(go); go->in_use = 0; - kfree(gofh->bufs); - gofh->buf_count = 0; + kfree(go->bufs); + go->bufs = NULL; + go->buf_count = 0; + go->bufs_owner = NULL; } - v4l2_fh_del(&gofh->fh); - v4l2_fh_exit(&gofh->fh); - kfree(gofh); - file->private_data = NULL; - return 0; + return v4l2_fh_release(file); } static bool valid_pixelformat(u32 pixelformat) @@ -428,7 +406,7 @@ static int clip_to_modet_map(struct go7007 *go, int region, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct go7007 *go = ((struct go7007_file *) priv)->go; + struct go7007 *go = video_drvdata(file); strlcpy(cap->driver, "go7007", sizeof(cap->driver)); strlcpy(cap->card, go->name, sizeof(cap->card)); @@ -480,7 +458,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { - struct go7007 *go = ((struct go7007_file *) priv)->go; + struct go7007 *go = video_drvdata(file); fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt->fmt.pix.width = go->width; @@ -497,7 +475,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { - struct go7007 *go = ((struct go7007_file *) priv)->go; + struct go7007 *go = video_drvdata(file); return set_capture_size(go, fmt, 1); } @@ -505,7 +483,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { - struct go7007 *go = ((struct go7007_file *) priv)->go; + struct go7007 *go = video_drvdata(file); if (go->streaming) return -EBUSY; @@ -516,8 +494,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *req) { - struct go7007_file *gofh = priv; - struct go7007 *go = gofh->go; + struct go7007 *go = video_drvdata(file);
[REVIEW PATCH 21/42] go7007: remove current_norm.
From: Hans Verkuil It's deprecated and replaced by g_std. Since this driver already implements g_std the use of current_norm can just be removed. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-v4l2.c |1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 6f14ac5..b470306 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -1834,7 +1834,6 @@ static struct video_device go7007_template = { .release= go7007_vfl_release, .ioctl_ops = &video_ioctl_ops, .tvnorms= V4L2_STD_ALL, - .current_norm = V4L2_STD_NTSC, }; int go7007_v4l2_init(struct go7007 *go) -- 1.7.10.4 -- 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
[REVIEW PATCH 14/42] tw2804: modify ADC power control
From: Volokh Konstantin Switch off all ADC (max 4) with first init, we control it when starting/stopping streaming. Signed-off-by: Volokh Konstantin Signed-off-by: Hans Verkuil --- drivers/media/i2c/tw2804.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c index 4bb5ba6..441b766 100644 --- a/drivers/media/i2c/tw2804.c +++ b/drivers/media/i2c/tw2804.c @@ -53,6 +53,7 @@ static const u8 global_registers[] = { 0x3d, 0x80, 0x3e, 0x82, 0x3f, 0x82, + 0x78, 0x0f, 0xff, 0xff, /* Terminator (reg 0xff does not exist) */ }; -- 1.7.10.4 -- 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
[REVIEW PATCH 34/42] go7007: convert to core locking and vb2.
From: Hans Verkuil Convert this driver to videobuf2 and core locking. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/Kconfig |2 +- drivers/staging/media/go7007/go7007-driver.c | 156 --- drivers/staging/media/go7007/go7007-priv.h| 27 +- drivers/staging/media/go7007/go7007-usb.c |9 +- drivers/staging/media/go7007/go7007-v4l2.c| 535 ++--- drivers/staging/media/go7007/saa7134-go7007.c |2 +- 6 files changed, 205 insertions(+), 526 deletions(-) diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig index da32031..46cb7bf 100644 --- a/drivers/staging/media/go7007/Kconfig +++ b/drivers/staging/media/go7007/Kconfig @@ -2,7 +2,7 @@ config VIDEO_GO7007 tristate "WIS GO7007 MPEG encoder support" depends on VIDEO_DEV && PCI && I2C depends on SND - select VIDEOBUF_DMA_SG + select VIDEOBUF2_VMALLOC depends on RC_CORE select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 732b452..075de4d 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -363,48 +363,54 @@ start_error: /* * Store a byte in the current video buffer, if there is one. */ -static inline void store_byte(struct go7007_buffer *gobuf, u8 byte) +static inline void store_byte(struct go7007_buffer *vb, u8 byte) { - if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) { - unsigned int pgidx = gobuf->offset >> PAGE_SHIFT; - unsigned int pgoff = gobuf->offset & ~PAGE_MASK; + if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) { + u8 *ptr = vb2_plane_vaddr(&vb->vb, 0); - *((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte; - ++gobuf->offset; - ++gobuf->bytesused; + ptr[vb->vb.v4l2_planes[0].bytesused++] = byte; } } /* * Deliver the last video buffer and get a new one to start writing to. */ -static void frame_boundary(struct go7007 *go) +static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb) { - struct go7007_buffer *gobuf; + struct go7007_buffer *vb_tmp = NULL; + u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused; int i; - if (go->active_buf) { - if (go->active_buf->modet_active) { - if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) { + if (vb) { + if (vb->modet_active) { + if (*bytesused + 216 < GO7007_BUF_SIZE) { for (i = 0; i < 216; ++i) - store_byte(go->active_buf, - go->active_map[i]); - go->active_buf->bytesused -= 216; + store_byte(vb, go->active_map[i]); + *bytesused -= 216; } else - go->active_buf->modet_active = 0; + vb->modet_active = 0; } - go->active_buf->state = BUF_STATE_DONE; - wake_up_interruptible(&go->frame_waitq); - go->active_buf = NULL; + vb->vb.v4l2_buf.sequence = go->next_seq++; + v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp); + vb_tmp = vb; + spin_lock(&go->spinlock); + list_del(&vb->list); + if (list_empty(&go->vidq_active)) + vb = NULL; + else + vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list); + go->active_buf = vb; + spin_unlock(&go->spinlock); + vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE); + return vb; } - list_for_each_entry(gobuf, &go->stream, stream) - if (gobuf->state == BUF_STATE_QUEUED) { - gobuf->seq = go->next_seq; - do_gettimeofday(&gobuf->timestamp); - go->active_buf = gobuf; - break; - } - ++go->next_seq; + spin_lock(&go->spinlock); + if (!list_empty(&go->vidq_active)) + vb = go->active_buf = + list_first_entry(&go->vidq_active, struct go7007_buffer, list); + spin_unlock(&go->spinlock); + go->next_seq++; + return vb; } static void write_bitmap_word(struct go7007 *go) @@ -428,10 +434,9 @@ static void write_bitmap_word(struct go7007 *go) */ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length) { + struct go7007_buffer *vb = go->active_buf; int i, seq_start_code = -1, frame_start_co
[REVIEW PATCH 39/42] go7007-loader: renamed from s2250-loader
From: Hans Verkuil All s2250 names are renamed to go7007. This will be the generic go7007 firmware loader for any go7007 device, not just for the s2250/1. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/Kconfig | 24 ++-- drivers/staging/media/go7007/Makefile|7 +- drivers/staging/media/go7007/go7007-loader.c | 169 + drivers/staging/media/go7007/s2250-loader.c | 170 -- drivers/staging/media/go7007/s2250-loader.h | 24 5 files changed, 189 insertions(+), 205 deletions(-) create mode 100644 drivers/staging/media/go7007/go7007-loader.c delete mode 100644 drivers/staging/media/go7007/s2250-loader.c delete mode 100644 drivers/staging/media/go7007/s2250-loader.h diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig index 46cb7bf..957277c 100644 --- a/drivers/staging/media/go7007/Kconfig +++ b/drivers/staging/media/go7007/Kconfig @@ -1,13 +1,10 @@ config VIDEO_GO7007 tristate "WIS GO7007 MPEG encoder support" - depends on VIDEO_DEV && PCI && I2C + depends on VIDEO_DEV && I2C depends on SND select VIDEOBUF2_VMALLOC - depends on RC_CORE select VIDEO_TUNER - select VIDEO_TVEEPROM select SND_PCM - select CRC32 select VIDEO_SONY_BTF_MPX if MEDIA_SUBDRV_AUTOSELECT select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT @@ -20,7 +17,7 @@ config VIDEO_GO7007 encoder chip. To compile this driver as a module, choose M here: the - module will be called go7007 + module will be called go7007. config VIDEO_GO7007_USB tristate "WIS GO7007 USB support" @@ -31,14 +28,25 @@ config VIDEO_GO7007_USB encoder chip over USB. To compile this driver as a module, choose M here: the - module will be called go7007-usb + module will be called go7007-usb. + +config VIDEO_GO7007_LOADER + tristate "WIS GO7007 Loader support" + depends on VIDEO_GO7007 && DVB_USB + default y + ---help--- + This is a go7007 firmware loader driver for the WIS GO7007 + MPEG encoder chip over USB. + + To compile this driver as a module, choose M here: the + module will be called go7007-loader. config VIDEO_GO7007_USB_S2250_BOARD tristate "Sensoray 2250/2251 support" - depends on VIDEO_GO7007_USB && DVB_USB + depends on VIDEO_GO7007_USB && USB default N ---help--- This is a video4linux driver for the Sensoray 2250/2251 device. To compile this driver as a module, choose M here: the - module will be called s2250 + module will be called s2250. diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile index 7885c21..e94ab0d 100644 --- a/drivers/staging/media/go7007/Makefile +++ b/drivers/staging/media/go7007/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_VIDEO_GO7007) += go7007.o obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o -obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o +obj-$(CONFIG_VIDEO_GO7007_LOADER) += go7007-loader.o +obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ snd-go7007.o @@ -11,8 +12,8 @@ s2250-y := s2250-board.o obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134 -# S2250 needs cypress ezusb loader from dvb-usb-v2 -ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2 +# go7007-loader needs cypress ezusb loader from dvb-usb-v2 +ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/usb/dvb-usb-v2 ccflags-y += -Idrivers/media/dvb-frontends ccflags-y += -Idrivers/media/dvb-core diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c new file mode 100644 index 000..730a4f8 --- /dev/null +++ b/drivers/staging/media/go7007/go7007-loader.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2008 Sensoray Company Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +#define S2250_LOADER_FIRMWARE "s2250_loade
[REVIEW PATCH 40/42] go7007-loader: add support for the other devices and move fw files
From: Hans Verkuil Add support for the other devices that need to load the boot firmware. All firmware files are now placed in a single go7007 directory. Also remove the device_extension_s stuff: this is clearly a left-over from the olden days. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c |4 +- drivers/staging/media/go7007/go7007-loader.c | 131 ++--- drivers/staging/media/go7007/go7007-usb.c | 22 ++--- drivers/staging/media/go7007/saa7134-go7007.c |3 +- 4 files changed, 68 insertions(+), 92 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 0fd3f10..4378223 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -90,7 +90,7 @@ EXPORT_SYMBOL(go7007_read_addr); static int go7007_load_encoder(struct go7007 *go) { const struct firmware *fw_entry; - char fw_name[] = "go7007fw.bin"; + char fw_name[] = "go7007/go7007fw.bin"; void *bounce; int fw_len, rv = 0; u16 intr_val, intr_data; @@ -126,7 +126,7 @@ static int go7007_load_encoder(struct go7007 *go) return rv; } -MODULE_FIRMWARE("go7007fw.bin"); +MODULE_FIRMWARE("go7007/go7007fw.bin"); /* * Boot the encoder and register the I2C adapter if requested. Do the diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c index 730a4f8..4ce53d6 100644 --- a/drivers/staging/media/go7007/go7007-loader.c +++ b/drivers/staging/media/go7007/go7007-loader.c @@ -22,86 +22,67 @@ #include #include -#define S2250_LOADER_FIRMWARE "s2250_loader.fw" -#define S2250_FIRMWARE "2250.fw" - -typedef struct device_extension_s { -struct kref kref; -int minor; -struct usb_device *usbdev; -} device_extension_t, *pdevice_extension_t; - -#define USB_go7007_loader_MAJOR 240 -#define USB_go7007_loader_MINOR_BASE 0 -#define MAX_DEVICES 256 - -static pdevice_extension_t go7007_dev_table[MAX_DEVICES]; -static DEFINE_MUTEX(go7007_dev_table_mutex); +struct fw_config { + u16 vendor; + u16 product; + const char * const fw_name1; + const char * const fw_name2; +}; -#define to_go7007_loader_dev_common(d) container_of(d, device_extension_t, kref) -static void go7007_loader_delete(struct kref *kref) -{ - pdevice_extension_t s = to_go7007_loader_dev_common(kref); - go7007_dev_table[s->minor] = NULL; - kfree(s); -} +struct fw_config fw_configs[] = { + { 0x1943, 0xa250, "go7007/s2250-1.fw", "go7007/s2250-2.fw" }, + { 0x093b, 0xa002, "go7007/px-m402u.fw", NULL }, + { 0x093b, 0xa004, "go7007/px-tv402u.fw", NULL }, + { 0x0eb1, 0x, "go7007/lr192.fw", NULL }, + { 0x0eb1, 0x6668, "go7007/wis-startrek.fw", NULL }, + { 0, 0, NULL, NULL } +}; +MODULE_FIRMWARE("go7007/s2250-1.fw"); +MODULE_FIRMWARE("go7007/s2250-2.fw"); +MODULE_FIRMWARE("go7007/px-m402u.fw"); +MODULE_FIRMWARE("go7007/px-tv402u.fw"); +MODULE_FIRMWARE("go7007/lr192.fw"); +MODULE_FIRMWARE("go7007/wis-startrek.fw"); static int go7007_loader_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *usbdev; - int minor, ret; - pdevice_extension_t s = NULL; const struct firmware *fw; + u16 vendor, product; + const char *fw1, *fw2; + int ret; + int i; usbdev = usb_get_dev(interface_to_usbdev(interface)); - if (!usbdev) { - dev_err(&interface->dev, "Enter go7007_loader_probe failed\n"); - return -1; - } - dev_info(&interface->dev, "vendor id 0x%x, device id 0x%x devnum:%d\n", -usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, -usbdev->devnum); + if (!usbdev) + goto failed2; if (usbdev->descriptor.bNumConfigurations != 1) { dev_err(&interface->dev, "can't handle multiple config\n"); - return -1; - } - mutex_lock(&go7007_dev_table_mutex); - - for (minor = 0; minor < MAX_DEVICES; minor++) { - if (go7007_dev_table[minor] == NULL) - break; + return -ENODEV; } - if (minor < 0 || minor >= MAX_DEVICES) { - dev_err(&interface->dev, "Invalid minor: %d\n", minor); - goto failed; - } - - /* Allocate dev data structure */ - s = kmalloc(sizeof(device_extension_t), GFP_KERNEL); - if (s == NULL) - goto failed; - - go7007_dev_table[minor] = s; + vendor = le16_to_cpu(usbdev->descriptor.idVendor); + product = le16_to_cpu(usbdev->descriptor.idProduct); - dev_info(&interface->dev, -"Device %d on Bus %d Minor %d\n", -usbdev->devnum, usbdev->bus->busnum, minor); + for (i =
[REVIEW PATCH 37/42] saa7134-go7007: add support for this combination.
From: Pete Eberlein Add support for the Sensoray model 614 board, which is a saa7134 with a go7007 MPEG encoder. Signed-off-by: Pete Eberlein [hans.verk...@cisco.com: updated to make it merge correctly] Signed-off-by: Hans Verkuil --- drivers/media/pci/saa7134/saa7134-cards.c | 29 ++ drivers/media/pci/saa7134/saa7134-core.c | 10 ++- drivers/media/pci/saa7134/saa7134.h |5 ++ drivers/staging/media/go7007/Makefile |4 +- drivers/staging/media/go7007/saa7134-go7007.c | 117 +++-- 5 files changed, 115 insertions(+), 50 deletions(-) diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index dc68cf1..9a53794 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -5790,6 +5790,29 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x601, } }, }, + [SAA7134_BOARD_WIS_VOYAGER] = { + .name = "WIS Voyager or compatible", + .audio_clock= 0x0020, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_GO7007, + .inputs = { { + .name = name_comp1, + .vmux = 0, + .amux = LINE2, + }, { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_svideo, + .vmux = 6, + .amux = LINE1, + } }, + }, }; @@ -7037,6 +7060,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice= 0x0911, .driver_data = SAA7134_BOARD_SENSORAY811_911, }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor= 0x1905, /* WIS */ + .subdevice= 0x7007, + .driver_data = SAA7134_BOARD_WIS_VOYAGER, + }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 8fd24e7..0a849ea 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -156,6 +156,8 @@ static void request_module_async(struct work_struct *work){ request_module("saa7134-empress"); if (card_is_dvb(dev)) request_module("saa7134-dvb"); + if (card_is_go7007(dev)) + request_module("saa7134-go7007"); if (alsa) { if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130) request_module("saa7134-alsa"); @@ -557,8 +559,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) saa7134_irq_vbi_done(dev,status); if ((report & SAA7134_IRQ_REPORT_DONE_RA2) && - card_has_mpeg(dev)) - saa7134_irq_ts_done(dev,status); + card_has_mpeg(dev)) { + if (dev->mops->irq_ts_done != NULL) + dev->mops->irq_ts_done(dev, status); + else + saa7134_irq_ts_done(dev, status); + } if (report & SAA7134_IRQ_REPORT_GPIO16) { switch (dev->has_remote) { diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 71eefef..e337e6c 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -334,6 +334,7 @@ struct saa7134_card_ir { #define SAA7134_BOARD_KWORLD_PC150U 189 #define SAA7134_BOARD_ASUSTeK_PS3_100 190 #define SAA7134_BOARD_HAWELL_HW_9004V1 191 +#define SAA7134_BOARD_WIS_VOYAGER 192 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 @@ -364,6 +365,7 @@ enum saa7134_mpeg_type { SAA7134_MPEG_UNUSED, SAA7134_MPEG_EMPRESS, SAA7134_MPEG_DVB, + SAA7134_MPEG_GO7007, }; enum saa7134_mpeg_ts_type { @@ -403,6 +405,7 @@ struct saa7134_board { #define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) #define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg) #define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg) +#define card_is_go7007(dev) (SAA7134_MPEG_GO7007 == saa7134_boards[dev->board].mpeg) #define card_has_mpeg(dev)(SAA7134_MPEG_UNUSED
[REVIEW PATCH 42/42] MAINTAINERS: add the go7007 driver.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- MAINTAINERS |5 + 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ff2fcc9..5703edd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7550,6 +7550,11 @@ M: David Täht S: Odd Fixes F: drivers/staging/frontier/ +STAGING - GO7007 MPEG CODEC +M: Hans Verkuil +S: Maintained +F: drivers/staging/media/go7007/ + STAGING - INDUSTRIAL IO M: Jonathan Cameron L: linux-...@vger.kernel.org -- 1.7.10.4 -- 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
[REVIEW PATCH 41/42] go7007: update the README
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/README | 14 -- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README index aeba132..779fe3f 100644 --- a/drivers/staging/media/go7007/README +++ b/drivers/staging/media/go7007/README @@ -1,11 +1,5 @@ Todo: - - checkpatch.pl cleanups - - sparse cleanups - - lots of little modules, should be merged together - and added to the build. - - testing? - - handle churn in v4l layer. - -Please send patches to Greg Kroah-Hartman and Cc: Ross -Cohen as well. - + - create an API for motion detection + - figure out how to distribute the firmware files + - let s2250-board use i2c subdevs as well instead of hardcoding + support for the i2c devices. -- 1.7.10.4 -- 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
[REVIEW PATCH 38/42] s2250: add comment describing the hardware.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/s2250-board.c |7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c index cb36427..beaa98b 100644 --- a/drivers/staging/media/go7007/s2250-board.c +++ b/drivers/staging/media/go7007/s2250-board.c @@ -29,6 +29,13 @@ MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver"); MODULE_LICENSE("GPL v2"); +/* + * Note: this board has two i2c devices: a vpx3226f and a tlv320aic23b. + * Due to the unusual way these are accessed on this device we do not + * reuse the i2c drivers, but instead they are implemented in this + * driver. It would be nice to improve on this, though. + */ + #define TLV320_ADDRESS 0x34 #define VPX322_ADDR_ANALOGCONTROL1 0x02 #define VPX322_ADDR_BRIGHTNESS00x0127 -- 1.7.10.4 -- 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
[REVIEW PATCH 36/42] go7007: remove cropping functions
From: Hans Verkuil Remove these dummy cropping functions: cropping was never implemented. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-v4l2.c | 92 1 file changed, 92 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 2e5bc02..24d93b4 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -842,95 +842,6 @@ static int vidioc_log_status(struct file *file, void *priv) return call_all(&go->v4l2_dev, core, log_status); } -static int vidioc_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cropcap) -{ - struct go7007 *go = video_drvdata(file); - - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* These specify the raw input of the sensor */ - switch (go->standard) { - case GO7007_STD_NTSC: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = 480; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = 720; - cropcap->defrect.height = 480; - break; - case GO7007_STD_PAL: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = 576; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = 720; - cropcap->defrect.height = 576; - break; - case GO7007_STD_OTHER: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = go->board_info->sensor_width; - cropcap->bounds.height = go->board_info->sensor_height; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = go->board_info->sensor_width; - cropcap->defrect.height = go->board_info->sensor_height; - break; - } - - return 0; -} - -static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ - struct go7007 *go = video_drvdata(file); - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - /* These specify the raw input of the sensor */ - switch (go->standard) { - case GO7007_STD_NTSC: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = 720; - crop->c.height = 480; - break; - case GO7007_STD_PAL: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = 720; - crop->c.height = 576; - break; - case GO7007_STD_OTHER: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = go->board_info->sensor_width; - crop->c.height = go->board_info->sensor_height; - break; - } - - return 0; -} - -/* FIXME: vidioc_s_crop is not really implemented!!! - */ -static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) -{ - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return 0; -} - /* FIXME: Those ioctls are private, and not needed, since several standard extended controls already provide streaming control. @@ -1006,9 +917,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_parm= vidioc_s_parm, .vidioc_enum_framesizes = vidioc_enum_framesizes, .vidioc_enum_frameintervals = vidioc_enum_frameintervals, - .vidioc_cropcap = vidioc_cropcap, - .vidioc_g_crop= vidioc_g_crop, - .vidioc_s_crop= vidioc_s_crop, .vidioc_log_status= vidioc_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -- 1.7.10.4 -- 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
[REVIEW PATCH 35/42] go7007: embed struct video_device
From: Hans Verkuil Do not allocate it, but just embed in the go7007 struct. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c |1 - drivers/staging/media/go7007/go7007-priv.h|2 +- drivers/staging/media/go7007/go7007-usb.c |2 +- drivers/staging/media/go7007/go7007-v4l2.c| 56 ++--- drivers/staging/media/go7007/saa7134-go7007.c |2 +- 5 files changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 075de4d..0fd3f10 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -639,7 +639,6 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) mutex_init(&go->hw_lock); init_waitqueue_head(&go->frame_waitq); spin_lock_init(&go->spinlock); - go->video_dev = NULL; go->status = STATUS_INIT; memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter)); go->i2c_adapter_online = 0; diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 30148eb..0914fa3 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -156,7 +156,7 @@ struct go7007 { int tuner_type; int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */ char name[64]; - struct video_device *video_dev; + struct video_device vdev; void *boot_fw; unsigned boot_fw_len; struct v4l2_device v4l2_dev; diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index c95538c..2a1cda2 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -1324,7 +1324,7 @@ static void go7007_usb_disconnect(struct usb_interface *intf) go->status = STATUS_SHUTDOWN; v4l2_device_disconnect(&go->v4l2_dev); - video_unregister_device(go->video_dev); + video_unregister_device(&go->vdev); mutex_unlock(&go->serialize_lock); mutex_unlock(&go->queue_lock); diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index 46db491..2e5bc02 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -967,11 +967,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop * } #endif -static void go7007_vfl_release(struct video_device *vfd) -{ - video_device_release(vfd); -} - static struct v4l2_file_operations go7007_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, @@ -1022,7 +1017,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static struct video_device go7007_template = { .name = "go7007", .fops = &go7007_fops, - .release= go7007_vfl_release, + .release= video_device_release_empty, .ioctl_ops = &video_ioctl_ops, .tvnorms= V4L2_STD_ALL, }; @@ -1062,6 +1057,7 @@ int go7007_v4l2_ctrl_init(struct go7007 *go) int go7007_v4l2_init(struct go7007 *go) { + struct video_device *vdev = &go->vdev; int rv; mutex_init(&go->serialize_lock); @@ -1079,22 +1075,19 @@ int go7007_v4l2_init(struct go7007 *go) rv = vb2_queue_init(&go->vidq); if (rv) return rv; - go->video_dev = video_device_alloc(); - if (go->video_dev == NULL) - return -ENOMEM; - *go->video_dev = go7007_template; - go->video_dev->lock = &go->serialize_lock; - go->video_dev->queue = &go->vidq; - set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags); - video_set_drvdata(go->video_dev, go); - go->video_dev->v4l2_dev = &go->v4l2_dev; + *vdev = go7007_template; + vdev->lock = &go->serialize_lock; + vdev->queue = &go->vidq; + set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); + video_set_drvdata(vdev, go); + vdev->v4l2_dev = &go->v4l2_dev; if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd)) - v4l2_disable_ioctl(go->video_dev, VIDIOC_QUERYSTD); + v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD); if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) { - v4l2_disable_ioctl(go->video_dev, VIDIOC_S_FREQUENCY); - v4l2_disable_ioctl(go->video_dev, VIDIOC_G_FREQUENCY); - v4l2_disable_ioctl(go->video_dev, VIDIOC_S_TUNER); - v4l2_disable_ioctl(go->video_dev, VIDIOC_G_TUNER); + v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY); + v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER); + v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER); } else {
[REVIEW PATCH 32/42] go7007: set up the saa7115 audio clock correctly.
From: Hans Verkuil The s_crystal_freq operation has to be called for the saa7115 to set up the audio clock correctly. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h |1 + drivers/staging/media/go7007/go7007-usb.c |5 - drivers/staging/media/go7007/go7007-v4l2.c |7 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index a6ef67b..7f79cc1 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -60,6 +60,7 @@ struct go7007; #define GO7007_SENSOR_TV (1<<7) #define GO7007_SENSOR_VBI (1<<8) #define GO7007_SENSOR_SCALING (1<<9) +#define GO7007_SENSOR_SAA7115 (1<<10) /* Characteristics of audio sensor devices */ #define GO7007_AUDIO_I2S_MODE_1(1) diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 53c5b16..5c7a19e6 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -88,6 +88,7 @@ static struct go7007_usb_board board_matrix_ii = { .sensor_flags= GO7007_SENSOR_656 | GO7007_SENSOR_VALID_ENABLE | GO7007_SENSOR_TV | + GO7007_SENSOR_SAA7115 | GO7007_SENSOR_VBI | GO7007_SENSOR_SCALING, .num_i2c_devs= 1, @@ -131,7 +132,7 @@ static struct go7007_usb_board board_matrix_reload = { .num_i2c_devs= 1, .i2c_devs= { { - .type = "saa7115", + .type = "saa7113", .addr = 0x25, .is_video = 1, }, @@ -160,6 +161,7 @@ static struct go7007_usb_board board_star_trek = { .sensor_flags= GO7007_SENSOR_656 | GO7007_SENSOR_VALID_ENABLE | GO7007_SENSOR_TV | + GO7007_SENSOR_SAA7115 | GO7007_SENSOR_VBI | GO7007_SENSOR_SCALING, .audio_flags = GO7007_AUDIO_I2S_MODE_1 | @@ -207,6 +209,7 @@ static struct go7007_usb_board board_px_tv402u = { .sensor_flags= GO7007_SENSOR_656 | GO7007_SENSOR_VALID_ENABLE | GO7007_SENSOR_TV | + GO7007_SENSOR_SAA7115 | GO7007_SENSOR_VBI | GO7007_SENSOR_SCALING, .audio_flags = GO7007_AUDIO_I2S_MODE_1 | diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index fd6cae0..972f8a5 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "go7007.h" #include "go7007-priv.h" @@ -1461,6 +1462,12 @@ int go7007_v4l2_init(struct go7007 *go) v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO); v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO); } + /* Setup correct crystal frequency on this board */ + if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115) + v4l2_subdev_call(go->sd_video, video, s_crystal_freq, + SAA7115_FREQ_24_576_MHZ, + SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC | + SAA7115_FREQ_FL_DOUBLE_ASCLK); go7007_s_input(go); if (go->board_info->sensor_flags & GO7007_SENSOR_TV) go7007_s_std(go); -- 1.7.10.4 -- 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
[REVIEW PATCH 30/42] go7007: standardize MPEG handling support.
From: Hans Verkuil The go7007 produces elementary streams, so we shouldn't use the STREAM_TYPE control, since that is for multiplexed streams. Instead use V4L2_PIX_FMT_MPEG1/2/4. Initially set up all the values for MPEG-2 dvd-mode, and select the dvd_mode field if those values match that setup precisely. Clean up lots of obsolete code relating to the custom ioctls for the MPEG support. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 16 +- drivers/staging/media/go7007/go7007-fw.c | 78 ++-- drivers/staging/media/go7007/go7007-priv.h | 13 +- drivers/staging/media/go7007/go7007-v4l2.c | 507 +++--- drivers/staging/media/go7007/go7007.h| 74 5 files changed, 181 insertions(+), 507 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index eac91bc..732b452 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -433,12 +433,12 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length) spin_lock(&go->spinlock); switch (go->format) { - case GO7007_FORMAT_MPEG4: + case V4L2_PIX_FMT_MPEG4: seq_start_code = 0xB0; frame_start_code = 0xB6; break; - case GO7007_FORMAT_MPEG1: - case GO7007_FORMAT_MPEG2: + case V4L2_PIX_FMT_MPEG1: + case V4L2_PIX_FMT_MPEG2: seq_start_code = 0xB3; frame_start_code = 0x00; break; @@ -518,9 +518,9 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length) } /* If this is the start of a new MPEG frame, * get a new buffer */ - if ((go->format == GO7007_FORMAT_MPEG1 || - go->format == GO7007_FORMAT_MPEG2 || - go->format == GO7007_FORMAT_MPEG4) && + if ((go->format == V4L2_PIX_FMT_MPEG1 || +go->format == V4L2_PIX_FMT_MPEG2 || +go->format == V4L2_PIX_FMT_MPEG4) && (buf[i] == seq_start_code || buf[i] == 0xB8 || /* GOP code */ buf[i] == frame_start_code)) { @@ -577,7 +577,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length) /* go->state remains STATE_FF */ break; case 0xD8: - if (go->format == GO7007_FORMAT_MJPEG) + if (go->format == V4L2_PIX_FMT_MJPEG) frame_boundary(go); /* fall through */ default: @@ -654,8 +654,8 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) go->encoder_h_halve = 0; go->encoder_v_halve = 0; go->encoder_subsample = 0; + go->format = V4L2_PIX_FMT_MJPEG; go->streaming = 0; - go->format = GO7007_FORMAT_MJPEG; go->bitrate = 150; go->fps_scale = 1; go->pali = 0; diff --git a/drivers/staging/media/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c index a5ede1c..524ba48 100644 --- a/drivers/staging/media/go7007/go7007-fw.c +++ b/drivers/staging/media/go7007/go7007-fw.c @@ -455,9 +455,9 @@ static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf, CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13); CODE_ADD(c, 0x, 16); - CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4); + CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4); if (frame != PFRAME) - CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4); + CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4); else CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */ CODE_ADD(c, 0, 3); /* What is this?? */ @@ -466,7 +466,7 @@ static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf, if (j != 8) CODE_ADD(c, 0, j); - if (go->format == GO7007_FORMAT_MPEG2) { + if (go->format == V4L2_PIX_FMT_MPEG2) { CODE_ADD(c, 0x1, 24); CODE_ADD(c, 0xb5, 8); CODE_ADD(c, 0x844, 12); @@ -537,7 +537,7 @@ static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext) int i, aspect_ratio, picture_rate; CODE_GEN(c, buf + 6); - if (go->format == GO7007_FORMAT_MPEG1) { + if (go->format == V4L2_PIX_FMT_MPEG1) { switch (go->aspect_ratio) { case GO7007_RATIO_4_3: aspect_ratio
[REVIEW PATCH 29/42] go7007: tuner/std related fixes.
From: Hans Verkuil - The Adlink is initially detected as a sensor board, so the driver config is set up as if it was a sensor. Later the driver discovers that it really is a video capture card and that means that the driver configuration has to be updated for a PAL/NTSC capture card. - Setup the correct initial std based on the TV tuner type. - Remember the exact std the user selected, don't map it to STD_PAL or NTSC. - Use v4l2_disable_ioctl to disable ioctls based on the board config and drop a lot of checking code in each of those ioctls since that is no longer needed. - enum_input should use tvnorms to fill its std field. - configure the input, std and initial tuner frequency at driver initialization. - fix std handling in the s2250 driver. - the code handling scaling for devices without a scaler was broken. This is now fixed. - correctly set readbuffers and capability in g/s_parm. - remove the bogus test for capturemode in s_parm. - correctly implement enum_framesizes/intervals. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 35 ++-- drivers/staging/media/go7007/go7007-priv.h |3 + drivers/staging/media/go7007/go7007-usb.c|3 + drivers/staging/media/go7007/go7007-v4l2.c | 255 -- drivers/staging/media/go7007/s2250-board.c | 13 +- 5 files changed, 154 insertions(+), 155 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index d689989..eac91bc 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -650,19 +650,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) init_waitqueue_head(&go->interrupt_waitq); go->in_use = 0; go->input = 0; - if (board->sensor_flags & GO7007_SENSOR_TV) { - go->standard = GO7007_STD_NTSC; - go->width = 720; - go->height = 480; - go->sensor_framerate = 3; - } else { - go->standard = GO7007_STD_OTHER; - go->width = board->sensor_width; - go->height = board->sensor_height; - go->sensor_framerate = board->sensor_framerate; - } - go->encoder_v_offset = board->sensor_v_offset; - go->encoder_h_offset = board->sensor_h_offset; + go7007_update_board(go); go->encoder_h_halve = 0; go->encoder_v_halve = 0; go->encoder_subsample = 0; @@ -692,4 +680,25 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) } EXPORT_SYMBOL(go7007_alloc); +void go7007_update_board(struct go7007 *go) +{ + struct go7007_board_info *board = go->board_info; + + if (board->sensor_flags & GO7007_SENSOR_TV) { + go->standard = GO7007_STD_NTSC; + go->std = V4L2_STD_NTSC_M; + go->width = 720; + go->height = 480; + go->sensor_framerate = 3; + } else { + go->standard = GO7007_STD_OTHER; + go->width = board->sensor_width; + go->height = board->sensor_height; + go->sensor_framerate = board->sensor_framerate; + } + go->encoder_v_offset = board->sensor_v_offset; + go->encoder_h_offset = board->sensor_h_offset; +} +EXPORT_SYMBOL(go7007_update_board); + MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index 2321fd7..bf874dd 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -200,6 +200,7 @@ struct go7007 { int input; int aud_input; enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard; + v4l2_std_id std; int sensor_framerate; int width; int height; @@ -291,6 +292,8 @@ int go7007_start_encoder(struct go7007 *go); void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length); struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev); +void go7007_update_board(struct go7007 *go); + /* go7007-fw.c */ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen); diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 2d349f4..14d1cda 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -1193,6 +1193,7 @@ static int go7007_usb_probe(struct usb_interface *intf, "Adlink PCI-MPG24, channel #%d", channel); } + go7007_update_board(go); } } @@ -1209,12 +1210,14 @@ static int go7007_usb_probe(struct usb_interface *intf, case 1:
[REVIEW PATCH 26/42] s2250: convert to the control framework.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/s2250-board.c | 149 +--- 1 file changed, 46 insertions(+), 103 deletions(-) diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c index 2266e1b..5899513 100644 --- a/drivers/staging/media/go7007/s2250-board.c +++ b/drivers/staging/media/go7007/s2250-board.c @@ -116,6 +116,7 @@ static u16 vid_regs_fp_pal[] = { struct s2250 { struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; v4l2_std_id std; int input; int brightness; @@ -370,110 +371,36 @@ static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) return 0; } -static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query) +static int s2250_s_ctrl(struct v4l2_ctrl *ctrl) { - switch (query->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(query, 0, 100, 1, 50); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(query, 0, 100, 1, 50); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(query, 0, 100, 1, 50); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(query, -50, 50, 1, 0); - default: - return -EINVAL; - } - return 0; -} - -static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct s2250 *state = to_state(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int value1; + struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl); + struct i2c_client *client = v4l2_get_subdevdata(&state->sd); u16 oldvalue; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - if (ctrl->value > 100) - state->brightness = 100; - else if (ctrl->value < 0) - state->brightness = 0; - else - state->brightness = ctrl->value; - value1 = (state->brightness - 50) * 255 / 100; read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue); write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, -value1 | (oldvalue & ~0xff)); +ctrl->val | (oldvalue & ~0xff)); read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue); write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, -value1 | (oldvalue & ~0xff)); +ctrl->val | (oldvalue & ~0xff)); write_reg_fp(client, 0x140, 0x60); break; case V4L2_CID_CONTRAST: - if (ctrl->value > 100) - state->contrast = 100; - else if (ctrl->value < 0) - state->contrast = 0; - else - state->contrast = ctrl->value; - value1 = state->contrast * 0x40 / 100; - if (value1 > 0x3f) - value1 = 0x3f; /* max */ read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue); write_reg_fp(client, VPX322_ADDR_CONTRAST0, -value1 | (oldvalue & ~0x3f)); +ctrl->val | (oldvalue & ~0x3f)); read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue); write_reg_fp(client, VPX322_ADDR_CONTRAST1, -value1 | (oldvalue & ~0x3f)); +ctrl->val | (oldvalue & ~0x3f)); write_reg_fp(client, 0x140, 0x60); break; case V4L2_CID_SATURATION: - if (ctrl->value > 100) - state->saturation = 100; - else if (ctrl->value < 0) - state->saturation = 0; - else - state->saturation = ctrl->value; - value1 = state->saturation * 4140 / 100; - if (value1 > 4094) - value1 = 4094; - write_reg_fp(client, VPX322_ADDR_SAT, value1); - break; - case V4L2_CID_HUE: - if (ctrl->value > 50) - state->hue = 50; - else if (ctrl->value < -50) - state->hue = -50; - else - state->hue = ctrl->value; - /* clamp the hue range */ - value1 = state->hue * 280 / 50; - write_reg_fp(client, VPX322_ADDR_HUE, value1); - break; - default: - return -EINVAL; - } - return 0; -} - -static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct s2250 *state = to_state(sd); - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = state->brightness; - bre
[REVIEW PATCH 27/42] go7007: add prio and control event support.
From: Hans Verkuil Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-priv.h |2 ++ drivers/staging/media/go7007/go7007-v4l2.c | 23 ++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index d127a8d..2321fd7 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -23,6 +23,7 @@ #include #include +#include struct go7007; @@ -143,6 +144,7 @@ struct go7007_buffer { }; struct go7007_file { + struct v4l2_fh fh; struct go7007 *go; struct mutex lock; int buf_count; diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index cb89af3..186a56b 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -27,13 +27,14 @@ #include #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include +#include #include "go7007.h" #include "go7007-priv.h" @@ -101,6 +102,8 @@ static int go7007_open(struct file *file) mutex_init(&gofh->lock); gofh->buf_count = 0; file->private_data = gofh; + v4l2_fh_init(&gofh->fh, video_devdata(file)); + v4l2_fh_add(&gofh->fh); return 0; } @@ -115,6 +118,8 @@ static int go7007_release(struct file *file) kfree(gofh->bufs); gofh->buf_count = 0; } + v4l2_fh_del(&gofh->fh); + v4l2_fh_exit(&gofh->fh); kfree(gofh); file->private_data = NULL; return 0; @@ -1582,16 +1587,20 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma) static unsigned int go7007_poll(struct file *file, poll_table *wait) { + unsigned long req_events = poll_requested_events(wait); struct go7007_file *gofh = file->private_data; struct go7007_buffer *gobuf; + unsigned int res = v4l2_ctrl_poll(file, wait); + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; if (list_empty(&gofh->go->stream)) return POLLERR; gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream); poll_wait(file, &gofh->go->frame_waitq, wait); if (gobuf->state == BUF_STATE_DONE) - return POLLIN | POLLRDNORM; - return 0; + return res | POLLIN | POLLRDNORM; + return res; } static void go7007_vfl_release(struct video_device *vfd) @@ -1645,6 +1654,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_cropcap = vidioc_cropcap, .vidioc_g_crop= vidioc_g_crop, .vidioc_s_crop= vidioc_s_crop, + .vidioc_log_status= v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device go7007_template = { @@ -1707,6 +1719,7 @@ int go7007_v4l2_init(struct go7007 *go) if (go->video_dev == NULL) return -ENOMEM; *go->video_dev = go7007_template; + set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags); video_set_drvdata(go->video_dev, go); go->video_dev->v4l2_dev = &go->v4l2_dev; rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1); -- 1.7.10.4 -- 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
[REVIEW PATCH 24/42] go7007: fix unregister/disconnect handling.
From: Hans Verkuil - use the v4l2_device's release() callback - remove the unnecessary ref_count - don't free usb data structures on disconnect, only do that in the final release callback. This is the correct way in order to safely handle disconnect and removal of modules. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 63 +--- drivers/staging/media/go7007/go7007-priv.h|4 +- drivers/staging/media/go7007/go7007-usb.c | 64 +++-- drivers/staging/media/go7007/go7007-v4l2.c| 22 + drivers/staging/media/go7007/saa7134-go7007.c |7 ++- drivers/staging/media/go7007/snd-go7007.c |5 +- 6 files changed, 85 insertions(+), 80 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index db9a4b3..dca85d8 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -221,6 +221,31 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con } /* + * Detach and unregister the encoder. The go7007 struct won't be freed + * until v4l2 finishes releasing its resources and all associated fds are + * closed by applications. + */ +static void go7007_remove(struct v4l2_device *v4l2_dev) +{ + struct go7007 *go = container_of(v4l2_dev, struct go7007, v4l2_dev); + + v4l2_device_unregister(v4l2_dev); + if (go->hpi_ops->release) + go->hpi_ops->release(go); + if (go->i2c_adapter_online) { + if (i2c_del_adapter(&go->i2c_adapter) == 0) + go->i2c_adapter_online = 0; + else + v4l2_err(&go->v4l2_dev, + "error removing I2C adapter!\n"); + } + + kfree(go->boot_fw); + go7007_v4l2_remove(go); + kfree(go); +} + +/* * Finalize the GO7007 hardware setup, register the on-board I2C adapter * (if used on this board), load the I2C client driver for the sensor * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2 @@ -234,17 +259,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs) dev_info(go->dev, "go7007: registering new %s\n", go->name); + go->v4l2_dev.release = go7007_remove; + ret = v4l2_device_register(go->dev, &go->v4l2_dev); + if (ret < 0) + return ret; + mutex_lock(&go->hw_lock); ret = go7007_init_encoder(go); mutex_unlock(&go->hw_lock); if (ret < 0) return -1; - /* v4l2 init must happen before i2c subdevs */ - ret = go7007_v4l2_init(go); - if (ret < 0) - return ret; - if (!go->i2c_adapter_online && go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) { if (go7007_i2c_init(go) < 0) @@ -269,6 +294,11 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs) v4l2_subdev_call(go->sd_video, video, s_routing, 0, 0, go->channel_number + 1); } + + ret = go7007_v4l2_init(go); + if (ret < 0) + return ret; + if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) { go->audio_enabled = 1; go7007_snd_init(go); @@ -608,7 +638,6 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) init_waitqueue_head(&go->frame_waitq); spin_lock_init(&go->spinlock); go->video_dev = NULL; - go->ref_count = 0; go->status = STATUS_INIT; memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter)); go->i2c_adapter_online = 0; @@ -658,26 +687,4 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) } EXPORT_SYMBOL(go7007_alloc); -/* - * Detach and unregister the encoder. The go7007 struct won't be freed - * until v4l2 finishes releasing its resources and all associated fds are - * closed by applications. - */ -void go7007_remove(struct go7007 *go) -{ - if (go->i2c_adapter_online) { - if (i2c_del_adapter(&go->i2c_adapter) == 0) - go->i2c_adapter_online = 0; - else - v4l2_err(&go->v4l2_dev, - "error removing I2C adapter!\n"); - } - - if (go->audio_enabled) - go7007_snd_remove(go); - kfree(go->boot_fw); - go7007_v4l2_remove(go); -} -EXPORT_SYMBOL(go7007_remove); - MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index d390120..54cfc0a 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -117,6 +117,7 @@ struct go7007_hpi_ops { int (*stream_stop)(struct go7007 *go); int (*send_firmware)(s
[REVIEW PATCH 23/42] go7007: remember boot firmware.
From: Hans Verkuil Don't load it everytime you stop encoding. Instead remember it. Another reason for not loading it every time is that this could be called from within the release() file operation, which turns out to be deadly. Signed-off-by: Hans Verkuil --- drivers/staging/media/go7007/go7007-driver.c | 43 +- drivers/staging/media/go7007/go7007-priv.h |2 ++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c index 09d0ef4..db9a4b3 100644 --- a/drivers/staging/media/go7007/go7007-driver.c +++ b/drivers/staging/media/go7007/go7007-driver.c @@ -95,34 +95,34 @@ static int go7007_load_encoder(struct go7007 *go) int fw_len, rv = 0; u16 intr_val, intr_data; - if (request_firmware(&fw_entry, fw_name, go->dev)) { - v4l2_err(go, "unable to load firmware from file " - "\"%s\"\n", fw_name); - return -1; - } - if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { - v4l2_err(go, "file \"%s\" does not appear to be " - "go7007 firmware\n", fw_name); - release_firmware(fw_entry); - return -1; - } - fw_len = fw_entry->size - 16; - bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL); - if (bounce == NULL) { - v4l2_err(go, "unable to allocate %d bytes for " - "firmware transfer\n", fw_len); + if (go->boot_fw == NULL) { + if (request_firmware(&fw_entry, fw_name, go->dev)) { + v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name); + return -1; + } + if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { + v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name); + release_firmware(fw_entry); + return -1; + } + fw_len = fw_entry->size - 16; + bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL); + if (bounce == NULL) { + v4l2_err(go, "unable to allocate %d bytes for firmware transfer\n", fw_len); + release_firmware(fw_entry); + return -1; + } release_firmware(fw_entry); - return -1; + go->boot_fw_len = fw_len; + go->boot_fw = bounce; } - release_firmware(fw_entry); if (go7007_interface_reset(go) < 0 || - go7007_send_firmware(go, bounce, fw_len) < 0 || - go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || + go7007_send_firmware(go, go->boot_fw, go->boot_fw_len) < 0 || + go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || (intr_val & ~0x1) != 0x5a5a) { v4l2_err(go, "error transferring firmware\n"); rv = -1; } - kfree(bounce); return rv; } @@ -675,6 +675,7 @@ void go7007_remove(struct go7007 *go) if (go->audio_enabled) go7007_snd_remove(go); + kfree(go->boot_fw); go7007_v4l2_remove(go); } EXPORT_SYMBOL(go7007_remove); diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h index daae6dd..d390120 100644 --- a/drivers/staging/media/go7007/go7007-priv.h +++ b/drivers/staging/media/go7007/go7007-priv.h @@ -178,6 +178,8 @@ struct go7007 { int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */ char name[64]; struct video_device *video_dev; + void *boot_fw; + unsigned boot_fw_len; struct v4l2_device v4l2_dev; int ref_count; enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; -- 1.7.10.4 -- 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
[REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner
From: Hans Verkuil The Sony BTF PG472Z has an internal MPX to deal with mono/stereo/bilingual audio. This is split off from the wis-sony-tuner driver that is part of the go7007 driver as it should be a separate i2c sub-device driver. The wis-sony-tuner is really three i2c devices: a standard tuner, a tda9887 compatible demodulator and this mpx. After this patch the wis-sony-tuner can be replaced by this driver and the standard tuner driver. Signed-off-by: Hans Verkuil --- drivers/media/i2c/Kconfig| 11 +- drivers/media/i2c/Makefile |1 + drivers/media/i2c/sony-btf-mpx.c | 399 ++ 3 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 drivers/media/i2c/sony-btf-mpx.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 7b771ba..70dbae2 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -133,7 +133,7 @@ config VIDEO_WM8739 module will be called wm8739. config VIDEO_VP27SMPX - tristate "Panasonic VP27s internal MPX" + tristate "Panasonic VP27's internal MPX" depends on VIDEO_V4L2 && I2C ---help--- Support for the internal MPX of the Panasonic VP27s tuner. @@ -141,6 +141,15 @@ config VIDEO_VP27SMPX To compile this driver as a module, choose M here: the module will be called vp27smpx. +config VIDEO_SONY_BTF_MPX + tristate "Sony BTF's internal MPX" + depends on VIDEO_V4L2 && I2C + help + Support for the internal MPX of the Sony BTF-PG472Z tuner. + + To compile this driver as a module, choose M here: the + module will be called sony-btf-mpx. + comment "RDS decoders" config VIDEO_SAA6588 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index cfefd30..4c57075 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o obj-$(CONFIG_VIDEO_WM8775) += wm8775.o obj-$(CONFIG_VIDEO_WM8739) += wm8739.o 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_OV7670) += ov7670.o diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c new file mode 100644 index 000..bc73e8f --- /dev/null +++ b/drivers/media/i2c/sony-btf-mpx.c @@ -0,0 +1,399 @@ +/* + * Copyright (C) 2005-2006 Micronas USA Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("sony-btf-mpx driver"); +MODULE_LICENSE("GPL v2"); + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n"); + +/* #define MPX_DEBUG */ + +/* + * Note: + * + * AS(IF/MPX) pin: LOW HIGH/OPEN + * IF/MPX address: 0x42/0x40 0x43/0x44 + */ + + +static int force_mpx_mode = -1; +module_param(force_mpx_mode, int, 0644); + +struct sony_btf_mpx { + struct v4l2_subdev sd; + int mpxmode; + u32 audmode; +}; + +static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sony_btf_mpx, sd); +} + +static int mpx_write(struct i2c_client *client, int dev, int addr, int val) +{ + u8 buffer[5]; + struct i2c_msg msg; + + buffer[0] = dev; + buffer[1] = addr >> 8; + buffer[2] = addr & 0xff; + buffer[3] = val >> 8; + buffer[4] = val & 0xff; + msg.addr = client->addr; + msg.flags = 0; + msg.len = 5; + msg.buf = buffer; + i2c_transfer(client->adapter, &msg, 1); + return 0; +} + +/* + * MPX register values for the BTF-PG472Z: + * + * FM_ NICAM_ SCART_ + * MODUS SOURCEACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME + * 10/0030 12/0008 12/0013 12/000E 12/0010 12/ 10/0020 12/ + * --- + * Auto 1003002001002603500000017500 + * + * B/G + * Mono1003002001002603500000037500 + * A2 1003002001002601500000037500 + * NICAM 1
[REVIEW PATCH 06/42] saa7115: add support for double-rate ASCLK
From: Hans Verkuil Some devices expect a double rate ASCLK. Add a flag to let the driver know through the s_crystal_freq call. Signed-off-by: Hans Verkuil --- drivers/media/i2c/saa7115.c | 16 +++- include/media/saa7115.h |7 --- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index d301442..9d3dbb3 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -83,9 +83,10 @@ struct saa711x_state { u32 ident; u32 audclk_freq; u32 crystal_freq; - u8 ucgc; + bool ucgc; u8 cgcdiv; - u8 apll; + bool apll; + bool double_asclk; }; static inline struct saa711x_state *to_state(struct v4l2_subdev *sd) @@ -732,8 +733,12 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq) if (state->apll) acc |= 0x08; + if (state->double_asclk) { + acpf <<= 1; + acni <<= 1; + } saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03); - saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10); + saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk); saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc); saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff); @@ -1302,9 +1307,10 @@ static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags) if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ) return -EINVAL; state->crystal_freq = freq; + state->double_asclk = flags & SAA7115_FREQ_FL_DOUBLE_ASCLK; state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; - state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; - state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; + state->ucgc = flags & SAA7115_FREQ_FL_UCGC; + state->apll = flags & SAA7115_FREQ_FL_APLL; saa711x_s_clock_freq(sd, state->audclk_freq); return 0; } diff --git a/include/media/saa7115.h b/include/media/saa7115.h index 8b2ecc6..4079186 100644 --- a/include/media/saa7115.h +++ b/include/media/saa7115.h @@ -59,9 +59,10 @@ #define SAA7115_FREQ_24_576_MHZ 24576000 /* 24.576 MHz crystal */ /* SAA7115 v4l2_crystal_freq audio clock control flags */ -#define SAA7115_FREQ_FL_UCGC (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */ -#define SAA7115_FREQ_FL_CGCDIV (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */ -#define SAA7115_FREQ_FL_APLL (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */ +#define SAA7115_FREQ_FL_UCGC (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */ +#define SAA7115_FREQ_FL_CGCDIV (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */ +#define SAA7115_FREQ_FL_APLL (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */ +#define SAA7115_FREQ_FL_DOUBLE_ASCLK (1 << 3) /* SA 39, LRDIV, SAA7114/5 only */ #endif -- 1.7.10.4 -- 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
[REVIEW PATCH 13/42] tw2804: add support for the Techwell tw2804.
From: Hans Verkuil This is based on the wis-tw2804.c driver that's part of the go7007 driver. It has been converted to a v4l subdev driver by Volokh Konstantin, and I made additional cleanups. Based on work by: Volokh Konstantin Signed-off-by: Hans Verkuil Cc: Volokh Konstantin --- drivers/media/i2c/Kconfig | 11 +- drivers/media/i2c/Makefile |1 + drivers/media/i2c/tw2804.c | 467 3 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 drivers/media/i2c/tw2804.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index eb9ef55..4c03684 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -301,11 +301,20 @@ config VIDEO_TVP7002 To compile this driver as a module, choose M here: the module will be called tvp7002. +config VIDEO_TW2804 + tristate "Techwell TW2804 multiple video decoder" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Techwell tw2804 multiple video decoder. + + To compile this driver as a module, choose M here: the + module will be called tw2804. + config VIDEO_TW9903 tristate "Techwell TW9903 video decoder" depends on VIDEO_V4L2 && I2C ---help--- - Support for the Techwell 9903 multi-standard video decoder + Support for the Techwell tw9903 multi-standard video decoder with high quality down scaler. To compile this driver as a module, choose M here: the diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index af8fb29..399050a 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o +obj-$(CONFIG_VIDEO_TW2804) += tw2804.o obj-$(CONFIG_VIDEO_TW9903) += tw9903.o obj-$(CONFIG_VIDEO_CS5345) += cs5345.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c new file mode 100644 index 000..4bb5ba6 --- /dev/null +++ b/drivers/media/i2c/tw2804.c @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2005-2006 Micronas USA Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TW2804_REG_AUTOGAIN0x02 +#define TW2804_REG_HUE 0x0f +#define TW2804_REG_SATURATION 0x10 +#define TW2804_REG_CONTRAST0x11 +#define TW2804_REG_BRIGHTNESS 0x12 +#define TW2804_REG_COLOR_KILLER0x14 +#define TW2804_REG_GAIN0x3c +#define TW2804_REG_CHROMA_GAIN 0x3d +#define TW2804_REG_BLUE_BALANCE0x3e +#define TW2804_REG_RED_BALANCE 0x3f + +struct tw2804 { + struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; + u8 channel:2; + u8 input:1; + int norm; +}; + +static const u8 global_registers[] = { + 0x39, 0x00, + 0x3a, 0xff, + 0x3b, 0x84, + 0x3c, 0x80, + 0x3d, 0x80, + 0x3e, 0x82, + 0x3f, 0x82, + 0xff, 0xff, /* Terminator (reg 0xff does not exist) */ +}; + +static const u8 channel_registers[] = { + 0x01, 0xc4, + 0x02, 0xa5, + 0x03, 0x20, + 0x04, 0xd0, + 0x05, 0x20, + 0x06, 0xd0, + 0x07, 0x88, + 0x08, 0x20, + 0x09, 0x07, + 0x0a, 0xf0, + 0x0b, 0x07, + 0x0c, 0xf0, + 0x0d, 0x40, + 0x0e, 0xd2, + 0x0f, 0x80, + 0x10, 0x80, + 0x11, 0x80, + 0x12, 0x80, + 0x13, 0x1f, + 0x14, 0x00, + 0x15, 0x00, + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0xff, + 0x19, 0xff, + 0x1a, 0xff, + 0x1b, 0xff, + 0x1c, 0xff, + 0x1d, 0xff, + 0x1e, 0xff, + 0x1f, 0xff, + 0x20, 0x07, + 0x21, 0x07, + 0x22, 0x00, + 0x23, 0x91, + 0x24, 0x51, + 0x25, 0x03, + 0x26, 0x00, + 0x27, 0x00, + 0x28, 0x00, + 0x29, 0x00, + 0x2a, 0x00, + 0x2b, 0x00, + 0x2c, 0x00, + 0x2d, 0x00, + 0x2e, 0x00, + 0x2f, 0x00, + 0x30, 0x00, + 0x31, 0x00, + 0x32, 0x00, + 0x33,
[REVIEW PATCH 08/42] tuner: add Sony BTF tuners
From: Hans Verkuil This adds support for three Sony BTF tuners: TUNER_SONY_BTF_PG472Z: PAL+SECAM TUNER_SONY_BTF_PK467Z: NTSC-M-JP TUNER_SONY_BTF_PB463Z: NTSC-M These come from the go7007 staging driver where they were implemented in the wis-sony-tuner i2c driver. Adding support for these tuners to tuner-types.c is the first step towards removing the wis-sony-tuner driver. Signed-off-by: Hans Verkuil --- Documentation/video4linux/CARDLIST.tuner |3 ++ drivers/media/tuners/tuner-types.c | 69 drivers/staging/media/go7007/go7007-usb.c |1 + drivers/staging/media/go7007/go7007-v4l2.c |1 + drivers/staging/media/go7007/wis-i2c.h |6 --- include/media/tuner.h |4 ++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index c83f6e4..5b83a3f 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -86,3 +86,6 @@ tuner=85 - Philips FQ1236 MK5 tuner=86 - Tena TNF5337 MFD tuner=87 - Xceive 4000 tuner tuner=88 - Xceive 5000C tuner +tuner=89 - Sony PAL+SECAM (BTF-PG472Z) +tuner=90 - Sony NTSC-M-JP (BTF-PK467Z) +tuner=91 - Sony NTSC-M (BTF-PB463Z) diff --git a/drivers/media/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c index 2da4440..98bc15a 100644 --- a/drivers/media/tuners/tuner-types.c +++ b/drivers/media/tuners/tuner-types.c @@ -1381,6 +1381,58 @@ static struct tuner_params tuner_philips_fq1236_mk5_params[] = { }, }; +/* - Sony BTF-PG472Z PAL/SECAM --- */ + +static struct tuner_range tuner_sony_btf_pg472z_ranges[] = { + { 16 * 144.25 /*MHz*/, 0xc6, 0x01, }, + { 16 * 427.25 /*MHz*/, 0xc6, 0x02, }, + { 16 * 999.99, 0xc6, 0x04, }, +}; + +static struct tuner_params tuner_sony_btf_pg472z_params[] = { + { + .type = TUNER_PARAM_TYPE_PAL, + .ranges = tuner_sony_btf_pg472z_ranges, + .count = ARRAY_SIZE(tuner_sony_btf_pg472z_ranges), + .has_tda9887 = 1, + .port1_active = 1, + .port2_invert_for_secam_lc = 1, + }, +}; + +/* 90-99 */ +/* - Sony BTF-PG467Z NTSC-M-JP --- */ + +static struct tuner_range tuner_sony_btf_pg467z_ranges[] = { + { 16 * 220.25 /*MHz*/, 0xc6, 0x01, }, + { 16 * 467.25 /*MHz*/, 0xc6, 0x02, }, + { 16 * 999.99, 0xc6, 0x04, }, +}; + +static struct tuner_params tuner_sony_btf_pg467z_params[] = { + { + .type = TUNER_PARAM_TYPE_NTSC, + .ranges = tuner_sony_btf_pg467z_ranges, + .count = ARRAY_SIZE(tuner_sony_btf_pg467z_ranges), + }, +}; + +/* - Sony BTF-PG463Z NTSC-M --- */ + +static struct tuner_range tuner_sony_btf_pg463z_ranges[] = { + { 16 * 130.25 /*MHz*/, 0xc6, 0x01, }, + { 16 * 364.25 /*MHz*/, 0xc6, 0x02, }, + { 16 * 999.99, 0xc6, 0x04, }, +}; + +static struct tuner_params tuner_sony_btf_pg463z_params[] = { + { + .type = TUNER_PARAM_TYPE_NTSC, + .ranges = tuner_sony_btf_pg463z_ranges, + .count = ARRAY_SIZE(tuner_sony_btf_pg463z_ranges), + }, +}; + /* - */ struct tunertype tuners[] = { @@ -1872,6 +1924,23 @@ struct tunertype tuners[] = { .name = "Xceive 5000C tuner", /* see xc5000.c for details */ }, + [TUNER_SONY_BTF_PG472Z] = { + .name = "Sony BTF-PG472Z PAL/SECAM", + .params = tuner_sony_btf_pg472z_params, + .count = ARRAY_SIZE(tuner_sony_btf_pg472z_params), + }, + + /* 90-99 */ + [TUNER_SONY_BTF_PK467Z] = { + .name = "Sony BTF-PK467Z NTSC-M-JP", + .params = tuner_sony_btf_pg467z_params, + .count = ARRAY_SIZE(tuner_sony_btf_pg467z_params), + }, + [TUNER_SONY_BTF_PB463Z] = { + .name = "Sony BTF-PB463Z NTSC-M", + .params = tuner_sony_btf_pg463z_params, + .count = ARRAY_SIZE(tuner_sony_btf_pg463z_params), + }, }; EXPORT_SYMBOL(tuners); diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 914b247..a8f 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "go7007-priv.h" #include "wis-i2c.h" diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index cb9fe33..e115132 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c @@ -1238,6 +1238,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, if (!go->i2c_adapter_online) return -EIO;
[REVIEW PATCH 05/42] saa7115: improve querystd handling for the saa7115.
From: Hans Verkuil The saa7115 has better PAL/NTSC detection, so it can detect PAL even though the chip is currently set up for NTSC. Signed-off-by: Hans Verkuil --- drivers/media/i2c/saa7115.c | 56 +-- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index f249b20..d301442 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1360,6 +1360,34 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) */ reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC); + + if (state->ident == V4L2_IDENT_SAA7115) { + reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); + + v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e); + + switch (reg1e & 0x03) { + case 1: + *std &= V4L2_STD_NTSC; + break; + case 2: + /* +* V4L2_STD_PAL just cover the european PAL standards. +* This is wrong, as the device could also be using an +* other PAL standard. +*/ + *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | + V4L2_STD_PAL_M | V4L2_STD_PAL_60; + break; + case 3: + *std &= V4L2_STD_SECAM; + break; + default: + /* Can't detect anything */ + break; + } + } + v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f); /* horizontal/vertical not locked */ @@ -1371,34 +1399,6 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) else *std &= V4L2_STD_625_50; - if (state->ident != V4L2_IDENT_SAA7115) - goto ret; - - reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); - - switch (reg1e & 0x03) { - case 1: - *std &= V4L2_STD_NTSC; - break; - case 2: - /* -* V4L2_STD_PAL just cover the european PAL standards. -* This is wrong, as the device could also be using an -* other PAL standard. -*/ - *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | - V4L2_STD_PAL_M | V4L2_STD_PAL_60; - break; - case 3: - *std &= V4L2_STD_SECAM; - break; - default: - /* Can't detect anything */ - break; - } - - v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e); - ret: v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std); -- 1.7.10.4 -- 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
[REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops.
From: Hans Verkuil This patch adds a v4l2_subdev_has_op() macro and a v4l2_device_has_op macro to quickly check if a specific subdev or any subdev supports a particular subdev operation. This makes it easy for drivers to disable certain ioctls if none of the subdevs supports the necessary functionality. Signed-off-by: Hans Verkuil --- include/media/v4l2-device.h | 13 + include/media/v4l2-subdev.h |3 +++ 2 files changed, 16 insertions(+) diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index d61febf..c9b1593 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -190,4 +190,17 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); ##args);\ }) +#define v4l2_device_has_op(v4l2_dev, o, f) \ +({ \ + struct v4l2_subdev *__sd; \ + bool __result = false; \ + list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) { \ + if (v4l2_subdev_has_op(__sd, o, f)) { \ + __result = true;\ + break; \ + } \ + } \ + __result; \ +}) + #endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index b137a5e..0740c06 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -687,4 +687,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, ((!(sd) || !(sd)->v4l2_dev || !(sd)->v4l2_dev->notify) ? -ENODEV : \ (sd)->v4l2_dev->notify((sd), (notification), (arg))) +#define v4l2_subdev_has_op(sd, o, f) \ + ((sd)->ops->o && (sd)->ops->o->f) + #endif -- 1.7.10.4 -- 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
[REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock
From: Andy Walls When calling v4l2_ctrl_add_handler(), lockdep would detect a potential recursive locking problem on a situation that is by design intended and not a recursive lock. This happened because all struct v4l2_ctrl_handler.lock mutexes were created as members of the same lock class in v4l2_ctrl_handler_init(), and v4l2_ctrl_add_handler() takes the hdl->lock on two different v4l2_ctrl_handler instances. This change breaks the large lockdep lock class for struct v4l2_ctrl_handler.lock and breaks it into v4l2_ctrl_handler instantiation specific lock classes with meaningful class names. This will validly eliminate lockdep alarms for v4l2_ctrl_handler locking validation, as long as the relationships between drivers adding v4l2 controls to their own handler from other v4l2 drivers' control handlers remains straightforward. struct v4l2_ctrl_handler.lock lock classes are created with names such that the output of cat /proc/lockdep indicates where in the v4l2 driver code v4l2_ctrl_handle_init() is being called on instantiations: a045f490 FD: 10 BD:8 +.+...: cx2341x:1534:(hdl)->lock a0497d20 FD: 12 BD:2 +.+.+.: saa7115:1581:(hdl)->lock a04ac660 FD: 14 BD:2 +.+.+.: msp3400_driver:756:(hdl)->lock a0484b90 FD: 12 BD:1 +.+.+.: ivtv_gpio:366:(&itv->hdl_gpio)->lock a04eb530 FD: 11 BD:2 +.+.+.: cx25840_core:1982:(&state->hdl)->lock a04fbc80 FD: 11 BD:3 +.+.+.: wm8775:246:(&state->hdl)->lock Some lock chains, that were previously causing the recursion alarms, are now visible in the output of cat /proc/lockdep_chains: irq_context: 0 [a0497d20] saa7115:1581:(hdl)->lock [a045f490] cx2341x:1534:(hdl)->lock irq_context: 0 [a04ac660] msp3400_driver:756:(hdl)->lock [a045f490] cx2341x:1534:(hdl)->lock irq_context: 0 [a0484b90] ivtv_gpio:366:(&itv->hdl_gpio)->lock [a045f490] cx2341x:1534:(hdl)->lock irq_context: 0 [a04eb530] cx25840_core:1982:(&state->hdl)->lock [a045f490] cx2341x:1534:(hdl)->lock irq_context: 0 [a04fbc80] wm8775:246:(&state->hdl)->lock [a045f490] cx2341x:1534:(hdl)->lock Signed-off-by: Andy Walls md.metrocast.net> [hans.verk...@cisco.com: keep mutex_init in v4l2_ctrl_handler_init_class] Signed-off-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-ctrls.c |8 +--- include/media/v4l2-ctrls.h | 29 ++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 6b28b58..b36d1ec 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1362,11 +1362,13 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) } /* Initialize the handler */ -int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, - unsigned nr_of_controls_hint) +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, +unsigned nr_of_controls_hint, +struct lock_class_key *key, const char *name) { hdl->lock = &hdl->_lock; mutex_init(hdl->lock); + lockdep_set_class_and_name(hdl->lock, key, name); INIT_LIST_HEAD(&hdl->ctrls); INIT_LIST_HEAD(&hdl->ctrl_refs); hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; @@ -1375,7 +1377,7 @@ int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, hdl->error = hdl->buckets ? 0 : -ENOMEM; return hdl->error; } -EXPORT_SYMBOL(v4l2_ctrl_handler_init); +EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); /* Free all controls and control refs */ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index f00d42b..7343a27 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -259,7 +259,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags); -/** v4l2_ctrl_handler_init() - Initialize the control handler. +/** v4l2_ctrl_handler_init_class() - Initialize the control handler. * @hdl: The control handler. * @nr_of_controls_hint: A hint of how many controls this handler is *expected to refer to. This is the total number, so including @@ -268,12 +268,35 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, *are allocated) or the control lookup becomes slower (not enough *buckets are allocated, so there are more slow list lookups). *It will always work, though. + * @key: Used by the lock validator if CONFIG_LOCKDEP is set. + * @name: Used by the lock validator if CONFIG_LOCKDEP is set. * * Returns an error if the buckets could not be allocated. This error will * also be stored in @hdl->err