Re: [PATCH v4 04/21] doc: media/v4l-drivers: Add Qualcomm Camera Subsystem driver document
Hi Hans, On 18.08.2017 10:45, Hans Verkuil wrote: > Hi Todor, > > A few small comments below: > > On 08/08/2017 03:30 PM, Todor Tomov wrote: >> Add a document to describe Qualcomm Camera Subsystem driver. >> >> Signed-off-by: Todor Tomov >> --- >> Documentation/media/v4l-drivers/qcom_camss.rst | 124 >> + >> 1 file changed, 124 insertions(+) >> create mode 100644 Documentation/media/v4l-drivers/qcom_camss.rst >> >> diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst >> b/Documentation/media/v4l-drivers/qcom_camss.rst >> new file mode 100644 >> index 000..4707ea7 >> --- /dev/null >> +++ b/Documentation/media/v4l-drivers/qcom_camss.rst >> @@ -0,0 +1,124 @@ >> +.. include:: >> + >> +Qualcomm Camera Subsystem driver >> + >> + >> +Introduction >> + >> + >> +This file documents the Qualcomm Camera Subsystem driver located under >> +drivers/media/platform/qcom/camss-8x16. >> + >> +The current version of the driver supports the Camera Subsystem found on >> +Qualcomm MSM8916 and APQ8016 processors. >> + >> +The driver implements V4L2, Media controller and V4L2 subdev interfaces. >> +Camera sensor using V4L2 subdev interface in the kernel is supported. >> + >> +The driver is implemented using as a reference the Qualcomm Camera Subsystem >> +driver for Android as found in Code Aurora [#f1]_. >> + >> + >> +Qualcomm Camera Subsystem hardware >> +-- >> + >> +The Camera Subsystem hardware found on 8x16 processors and supported by the >> +driver consists of: >> + >> +- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. >> + A separate camera sensor can be connected to each of the CSIPHY module; >> +- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application >> layer >> + of the CSI2 receivers. A CSID can decode data stream from any of the >> CSIPHY. >> + Each CSID also contains a TG (Test Generator) block which can generate >> + artificial input data for test purposes; >> +- ISPIF (ISP Interface) module. Handles the routing of the data streams from >> + the CSIDs to the inputs of the VFE; >> +- VFE (Video Front End) module. Contains a pipeline of image processing >> hardware >> + blocks. The VFE has different input interfaces. The PIX input interface >> feeds >> + the input data to the image processing pipeline. Three RDI input >> interfaces >> + bypass the image processing pipeline. The VFE also contains the AXI bus >> + interface which writes the output data to memory. > > Can you explain what PIX and RDI stand for? > > I would also think it is a good idea to add a comment at the top of the > various > subdev sources that say a bit more than just "CSID Module". > > A simple "CSID (CSI Decoder) Module" is enough. Just so the reader knows what > it is all about. > > Otherwise I don't have any more comments about this series. > > I don't need a v5 for this, if you can just post one patch for this > documentation > and one patch improving the source comments as described above, then that's > fine with me. Thank you for the review again. I'll post two additional patches to add explanations of the abbreviations. > > Regards, > > Hans > >> + >> + >> +Supported functionality >> +--- >> + >> +The current version of the driver supports: >> + >> +- input from camera sensor via CSIPHY; >> +- generation of test input data by the TG in CSID; >> +- raw dump of the input data to memory. RDI interface of VFE is supported. >> + PIX interface (ISP processing, statistics engines, resize/crop, format >> + conversion) is not supported in the current version; >> +- concurrent and independent usage of two data inputs - could be camera >> sensors >> + and/or TG. >> + >> + >> +Driver Architecture and Design >> +-- >> + >> +The driver implements the V4L2 subdev interface. With the goal to model the >> +hardware links between the modules and to expose a clean, logical and usable >> +interface, the driver is split into V4L2 sub-devices as follows: >> + >> +- 2 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device; >> +- 2 CSID sub-devices - each CSID is represented by a single sub-device; >> +- 2 ISPIF sub-devices - ISPIF is represented by a number of sub-dev
[PATCH 2/2] media: camss: Add abbreviations explanation
Add abbreviations explanation at the top header blocks in source files. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/camss-csid.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-csid.h | 2 +- drivers/media/platform/qcom/camss-8x16/camss-ispif.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-ispif.h | 2 +- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss-8x16/camss-csid.c index 792c14a..64df828 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c @@ -1,7 +1,7 @@ /* * camss-csid.c * - * Qualcomm MSM Camera Subsystem - CSID Module + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.h b/drivers/media/platform/qcom/camss-8x16/camss-csid.h index 4df7018..8682d30 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.h @@ -1,7 +1,7 @@ /* * camss-csid.h * - * Qualcomm MSM Camera Subsystem - CSID Module + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module * * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c index 54d1946..24da529 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -1,7 +1,7 @@ /* * camss-ispif.c * - * Qualcomm MSM Camera Subsystem - ISPIF Module + * Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h index 6659020..f668306 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h @@ -1,7 +1,7 @@ /* * camss-ispif.h * - * Qualcomm MSM Camera Subsystem - ISPIF Module + * Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module * * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 1c86b10..94d635e 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -1,7 +1,7 @@ /* * camss-vfe.c * - * Qualcomm MSM Camera Subsystem - VFE Module + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index 88c29d0..53d5b66 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -1,7 +1,7 @@ /* * camss-vfe.h * - * Qualcomm MSM Camera Subsystem - VFE Module + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. -- 2.7.4
[PATCH 1/2] doc: media/v4l-drivers/qcom_camss: Add abbreviations explanation
Add explanations for VFE's PIX and RDI interfaces. Signed-off-by: Todor Tomov --- Documentation/media/v4l-drivers/qcom_camss.rst | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst index 7ef632a..9e66b7b 100644 --- a/Documentation/media/v4l-drivers/qcom_camss.rst +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -34,11 +34,12 @@ driver consists of: - ISPIF (ISP Interface) module. Handles the routing of the data streams from the CSIDs to the inputs of the VFE; - VFE (Video Front End) module. Contains a pipeline of image processing hardware - blocks. The VFE has different input interfaces. The PIX input interface feeds - the input data to the image processing pipeline. The image processing pipeline - contains also a scale and crop module at the end. Three RDI input interfaces - bypass the image processing pipeline. The VFE also contains the AXI bus - interface which writes the output data to memory. + blocks. The VFE has different input interfaces. The PIX (Pixel) input + interface feeds the input data to the image processing pipeline. The image + processing pipeline contains also a scale and crop module at the end. Three + RDI (Raw Dump Interface) input interfaces bypass the image processing + pipeline. The VFE also contains the AXI bus interface which writes the output + data to memory. Supported functionality -- 2.7.4
Re: [PATCH v2 10/19] media: camss: Enable building
Hi, (for everyone's information:) This error is caused by a missing patch [1] which is needed by this patchset. The relevant patch has been reviewed and accepted but merging was delayed until there is a driver actually using the formats which the patch adds. I'll include the relevant patch in my next version of the patchset so we will avoid this error next time. [1] https://git.linuxtv.org/sailus/media_tree.git/commit/?h=packed12-postponed&id=549c02da6eed8dc4566632a9af9233bf99ba99d8 Best regards, Todor On 06/20/2017 01:30 PM, kbuild test robot wrote: > Hi Todor, > > [auto build test ERROR on linuxtv-media/master] > [also build test ERROR on v4.12-rc6 next-20170620] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Todor-Tomov/Qualcomm-8x16-Camera-Subsystem-driver/20170620-132806 > base: git://linuxtv.org/media_tree.git master > config: ia64-allmodconfig (attached as .config) > compiler: ia64-linux-gcc (GCC) 6.2.0 > reproduce: > wget > https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O > ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=ia64 > > All errors (new ones prefixed by >>): > >>> drivers/media/platform/qcom/camss-8x16/video.c:53:32: error: >>> 'V4L2_PIX_FMT_SRGGB12P' undeclared here (not in a function) > { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 }, >^ >>> drivers/media/platform/qcom/camss-8x16/video.c:54:32: error: >>> 'V4L2_PIX_FMT_SGBRG12P' undeclared here (not in a function) > { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 }, >^ >>> drivers/media/platform/qcom/camss-8x16/video.c:55:32: error: >>> 'V4L2_PIX_FMT_SGRBG12P' undeclared here (not in a function) > { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 }, >^ > > vim +/V4L2_PIX_FMT_SRGGB12P +53 drivers/media/platform/qcom/camss-8x16/video.c > > 58991044 Todor Tomov 2017-06-19 47 { MEDIA_BUS_FMT_SGRBG8_1X8, > V4L2_PIX_FMT_SGRBG8, 8 }, > 58991044 Todor Tomov 2017-06-19 48 { MEDIA_BUS_FMT_SRGGB8_1X8, > V4L2_PIX_FMT_SRGGB8, 8 }, > 58991044 Todor Tomov 2017-06-19 49 { MEDIA_BUS_FMT_SBGGR10_1X10, > V4L2_PIX_FMT_SBGGR10P, 10 }, > 58991044 Todor Tomov 2017-06-19 50 { MEDIA_BUS_FMT_SGBRG10_1X10, > V4L2_PIX_FMT_SGBRG10P, 10 }, > 58991044 Todor Tomov 2017-06-19 51 { MEDIA_BUS_FMT_SGRBG10_1X10, > V4L2_PIX_FMT_SGRBG10P, 10 }, > 58991044 Todor Tomov 2017-06-19 52 { MEDIA_BUS_FMT_SRGGB10_1X10, > V4L2_PIX_FMT_SRGGB10P, 10 }, > 58991044 Todor Tomov 2017-06-19 @53 { MEDIA_BUS_FMT_SBGGR12_1X12, > V4L2_PIX_FMT_SRGGB12P, 12 }, > 58991044 Todor Tomov 2017-06-19 @54 { MEDIA_BUS_FMT_SGBRG12_1X12, > V4L2_PIX_FMT_SGBRG12P, 12 }, > 58991044 Todor Tomov 2017-06-19 @55 { MEDIA_BUS_FMT_SGRBG12_1X12, > V4L2_PIX_FMT_SGRBG12P, 12 }, > 58991044 Todor Tomov 2017-06-19 56 { MEDIA_BUS_FMT_SRGGB12_1X12, > V4L2_PIX_FMT_SRGGB12P, 12 } > 58991044 Todor Tomov 2017-06-19 57 }; > 58991044 Todor Tomov 2017-06-19 58 > > :: The code at line 53 was first introduced by commit > :: 589910444c8d657c5d9992f6ebf1c0bf5a75e68a media: camss: Add files which > handle the video device nodes > > :: TO: Todor Tomov > :: CC: 0day robot > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation > -- Best regards, Todor Tomov
Re: [PATCH v4 04/21] doc: media/v4l-drivers: Add Qualcomm Camera Subsystem driver document
Hi Daniel, On 16.10.2017 18:01, Daniel Mack wrote: > Hi, > > On 28.08.2017 09:10, Todor Tomov wrote: >> On 25.08.2017 17:10, Daniel Mack wrote: >>> Could you explain how ISPIF, CSID and CSIPHY are related? >>> >>> I have a userspace test setup that works fine for USB webcams, but when >>> operating on any of the video devices exposed by this driver, the >>> lowlevel functions such as .s_power of the ISPIF, CSID, CSIPHY and the >>> sensor driver layers aren't called into. >> >> Have you activated the media controller links? The s_power is called >> when the subdev is part of a pipeline in which the video device node >> is opened. You can see example configurations for the Qualcomm CAMSS >> driver on: >> https://github.com/96boards/documentation/blob/master/ConsumerEdition/DragonBoard-410c/Guides/CameraModule.md >> This will probably answer most of your questions. > > It did in fact, yes. Thanks again for the pointer. > > I am however struggling getting a 4-lane OV13855 camera to work with > this camss driver, and I'd be happy to hear about similar setups that work. > > In short, here's what my setup looks like: > > 1. I wrote a driver for the OV13855 sensor, based on the one for OV13858 > but with updated register values. It announces > MEDIA_BUS_FMT_SBGGR10_1X10 as bus format which is what the sensor should > be sending, if I understand the specs correctly. > > > 2. The DTS snippet for the endpoint connection look like this: > > &blsp_i2c6 { > cam0: ov13855@16 { > /* ... */ > port { > cam0_ep: endpoint { > clock-lanes = <1>; > data-lanes = <0 2 3 4>; > remote-endpoint = <&csiphy0_ep>; > }; > }; > }; > }; > > &camss { > ports { > port@0 { > reg = <0>; > csiphy0_ep: endpoint { > clock-lanes = <1>; > data-lanes = <0 2 3 4>; > remote-endpoint = <&cam0_ep>; > }; > }; > }; > }; > > There are also no lane swaps or any intermediate components in hardware. > We've checked the electrical bits many times, and that end seems alright. > > > 3. The pads and links are set up like this: > > # media-ctl -d /dev/media0 -l > '"msm_csiphy0":1->"msm_csid0":0[1],"msm_csid0":1->"msm_ispif0":0[1],"msm_ispif0":1->"msm_vfe0_rdi0":0[1]' > > # media-ctl -d /dev/media0 -V '"ov13855 > 1-0010":0[fmt:SBGGR10_1X10/4224x3136 > field:none],"msm_csiphy0":0[fmt:SBGGR10_1X10/4224x3136 > field:none],"msm_csid0":0[fmt:SBGGR10_1X10/4224x3136 > field:none],"msm_ispif0":0[fmt:SBGGR10_1X10/4224x3136 > field:none],"msm_vfe0_rdi0":0[fmt:SBGGR10_1X10/4224x3136 field:none]' > > Both commands succeed. > > > 4. When streaming is started, the power consumption of the device goes > up, all necessary external clocks and voltages are provided and are > stable, and I can see a continuous stream of data on all 4 MIPI lanes > using an oscilloscope. > > > 5. Capturing frames with the following yavta command doesn't work > though. The task is mostly stuck in the buffer dequeing ioctl: > > # yavta -B capture-mplane -c10 -I -n 5 -f SBGGR10P -s 4224x3136 /dev/video0 > > vfe_isr() does fire sometimes with VFE_0_IRQ_STATUS_1_RDIn_SOF(0) set, > but very occasionally only, and the frames do not contain data. > > FWIW, an ov6540 is connected to port 1 of the camss, and this sensor > works fine. > > I'd be grateful for any pointer about what I could investigate on. > Everything that you have described seems correct. As you say that frames do not contain any data, do VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG fire at all or not? Do you see any interrupts on the ISPIF? Which? Could you please share what hardware setup you have - mezzanine and camera module. -- Best regards, Todor Tomov
[PATCH 22/32] media: camss: ispif: Add support for 8x96
ISPIF hardware modules on 8x16 and 8x96 are similar. However on 8x96 the ISPIF routes data to two VFE hardware modules. Add separate interrupt handler for 8x96 to handle the additional interrupts. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-ispif.c | 76 - 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 8b04f8a..b124cd3 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -116,13 +116,77 @@ static const u32 ispif_formats[] = { }; /* - * ispif_isr - ISPIF module interrupt handler + * ispif_isr_8x96 - ISPIF module interrupt handler for 8x96 * @irq: Interrupt line * @dev: ISPIF device * * Return IRQ_HANDLED on success */ -static irqreturn_t ispif_isr(int irq, void *dev) +static irqreturn_t ispif_isr_8x96(int irq, void *dev) +{ + struct ispif_device *ispif = dev; + u32 value0, value1, value2, value3, value4, value5; + + value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); + value1 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(0)); + value2 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(0)); + value3 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(1)); + value4 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(1)); + value5 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(1)); + + writel_relaxed(value0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(0)); + writel_relaxed(value1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(0)); + writel_relaxed(value2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(0)); + writel_relaxed(value3, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(1)); + writel_relaxed(value4, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(1)); + writel_relaxed(value5, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(1)); + + writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); + + if ((value0 >> 27) & 0x1) + complete(&ispif->reset_complete); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); + + if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); + + if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 pix0 overflow\n"); + + if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi0 overflow\n"); + + if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 pix1 overflow\n"); + + if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi1 overflow\n"); + + if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi2 overflow\n"); + + return IRQ_HANDLED; +} + +/* + * ispif_isr_8x16 - ISPIF module interrupt handler for 8x16 + * @irq: Interrupt line + * @dev: ISPIF device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t ispif_isr_8x16(int irq, void *dev) { struct ispif_device *ispif = dev; u32 value0, value1, value2; @@ -954,8 +1018,14 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ispif->irq = r->start; snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", dev_name(dev), MSM_ISPIF_NAME); - ret = devm_request_irq(dev, ispif->irq, ispif_isr, + if (to_camss(ispif)->version == CAMSS_8x16) + ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16, IRQF_TRIGGER_RISING, ispif->irq_name, ispif); + else if (to_camss(ispif)->version == CAMSS_8x96) + ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96, + IRQF_TRIGGER_RISING, ispif->irq_name, ispif); + else + ret = -EINVAL; if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); return ret; -- 2.7.4
[PATCH 32/32] media: doc: media/v4l-drivers: Update Qualcomm CAMSS driver document for 8x96
Update the document to describe the support of Camera Subsystem on MSM8996/APQ8096. Signed-off-by: Todor Tomov --- Documentation/media/v4l-drivers/qcom_camss.rst | 93 +++--- .../media/v4l-drivers/qcom_camss_8x96_graph.dot| 104 + 2 files changed, 164 insertions(+), 33 deletions(-) create mode 100644 Documentation/media/v4l-drivers/qcom_camss_8x96_graph.dot diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst index 9e66b7b..f27c8df 100644 --- a/Documentation/media/v4l-drivers/qcom_camss.rst +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -7,34 +7,34 @@ Introduction This file documents the Qualcomm Camera Subsystem driver located under -drivers/media/platform/qcom/camss-8x16. +drivers/media/platform/qcom/camss. The current version of the driver supports the Camera Subsystem found on -Qualcomm MSM8916 and APQ8016 processors. +Qualcomm MSM8916/APQ8016 and MSM8996/APQ8096 processors. The driver implements V4L2, Media controller and V4L2 subdev interfaces. Camera sensor using V4L2 subdev interface in the kernel is supported. The driver is implemented using as a reference the Qualcomm Camera Subsystem -driver for Android as found in Code Aurora [#f1]_. +driver for Android as found in Code Aurora [#f1]_ [#f2]_. Qualcomm Camera Subsystem hardware -- -The Camera Subsystem hardware found on 8x16 processors and supported by the -driver consists of: +The Camera Subsystem hardware found on 8x16 / 8x96 processors and supported by +the driver consists of: -- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. +- 2 / 3 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. A separate camera sensor can be connected to each of the CSIPHY module; -- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application layer - of the CSI2 receivers. A CSID can decode data stream from any of the CSIPHY. - Each CSID also contains a TG (Test Generator) block which can generate +- 2 / 4 CSID (CSI Decoder) modules. They handle the Protocol and Application + layer of the CSI2 receivers. A CSID can decode data stream from any of the + CSIPHY. Each CSID also contains a TG (Test Generator) block which can generate artificial input data for test purposes; - ISPIF (ISP Interface) module. Handles the routing of the data streams from the CSIDs to the inputs of the VFE; -- VFE (Video Front End) module. Contains a pipeline of image processing hardware - blocks. The VFE has different input interfaces. The PIX (Pixel) input +- 1 / 2 VFE (Video Front End) module(s). Contain a pipeline of image processing + hardware blocks. The VFE has different input interfaces. The PIX (Pixel) input interface feeds the input data to the image processing pipeline. The image processing pipeline contains also a scale and crop module at the end. Three RDI (Raw Dump Interface) input interfaces bypass the image processing @@ -49,18 +49,33 @@ The current version of the driver supports: - Input from camera sensor via CSIPHY; - Generation of test input data by the TG in CSID; -- RDI interface of VFE - raw dump of the input data to memory. +- RDI interface of VFE - Supported formats: + - Raw dump of the input data to memory. - - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / -V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); - - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / -V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); - - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / -V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P); - - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / -V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). +Supported formats: + +- YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); +- MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / + V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); +- MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / + V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P / + V4L2_PIX_FMT_Y10P); +- MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / + V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). +- (8x96 only) MIPI RAW14 (14bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB14P / + V4L2_PIX_FMT_SGBRG14P / V4L2_PIX_FMT_SGRBG14P / V4L2_PIX_FMT_SRGGB14P). + + - (8x96 only) Format conversion of the input data. + +Supported input formats: + +- MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / V4L2_PIX_FMT_Y10P). + +Supported output formats: + +- Plain16 RAW10 (10bit unpacked Bayer RAW - V4L2_PIX_FMT_SBGGR10 / V4L2_PIX_FMT_Y10
[PATCH 19/32] media: camss: csiphy: Unify lane handling
Restructure lane configuration so it is simpler and will allow similar (although not the same) handling for different hardware versions. Signed-off-by: Todor Tomov --- .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 48 -- drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +- drivers/media/platform/qcom/camss/camss-csiphy.h | 3 +- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c index 7325906..5f499be 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c @@ -86,7 +86,7 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, { struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; u8 settle_cnt; - u8 val; + u8 val, l = 0; int i = 0; settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data, @@ -104,34 +104,38 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, val = cfg->combo_mode << 4; writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); - while (lane_mask) { - if (lane_mask & 0x1) { - writel_relaxed(0x10, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG2(i)); - writel_relaxed(settle_cnt, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG3(i)); - writel_relaxed(0x3f, csiphy->base + - CAMSS_CSI_PHY_INTERRUPT_MASKn(i)); - writel_relaxed(0x3f, csiphy->base + - CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); - } - - lane_mask >>= 1; - i++; + for (i = 0; i <= c->num_data; i++) { + if (i == c->num_data) + l = c->clk.pos; + else + l = c->data[i].pos; + + writel_relaxed(0x10, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(l)); + writel_relaxed(settle_cnt, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG3(l)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_MASKn(l)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(l)); } } -static void csiphy_lanes_disable(struct csiphy_device *csiphy, u8 lane_mask) +static void csiphy_lanes_disable(struct csiphy_device *csiphy, +struct csiphy_config *cfg) { + struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; + u8 l = 0; int i = 0; - while (lane_mask) { - if (lane_mask & 0x1) - writel_relaxed(0x0, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG2(i)); + for (i = 0; i <= c->num_data; i++) { + if (i == c->num_data) + l = c->clk.pos; + else + l = c->data[i].pos; - lane_mask >>= 1; - i++; + writel_relaxed(0x0, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(l)); } writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_PWR_CFG); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 14a9a66..99686f9 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -292,9 +292,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) */ static void csiphy_stream_off(struct csiphy_device *csiphy) { - u8 lane_mask = csiphy_get_lane_mask(&csiphy->cfg.csi2->lane_cfg); - - csiphy->ops->lanes_disable(csiphy, lane_mask); + csiphy->ops->lanes_disable(csiphy, &csiphy->cfg); } diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 8f61b7d..07e5906 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -51,7 +51,8 @@ struct csiphy_hw_ops { void (*lanes_enable)(struct csiphy_device *csiphy, struct csiphy_config *cfg, u32 pixel_clock, u8 bpp, u8 lane_mask); - void (*lanes_disable)(struct csiphy_device *csiphy, u8 lane_mask); + void (*lanes_disable)(struct csiphy_device *csiphy, + struct csiphy_config *cfg); irqreturn_t (*isr)(int irq, void *dev); }; -- 2.7.4
[PATCH v3 03/35] media: v4l: Add new 10-bit packed grayscale format
The new format will be called V4L2_PIX_FMT_Y10P. It is similar to the V4L2_PIX_FMT_SBGGR10P family formats but V4L2_PIX_FMT_Y10P is a grayscale format. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/pixfmt-y10p.rst | 33 Documentation/media/uapi/v4l/yuv-formats.rst | 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 36 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst new file mode 100644 index 000..13b5713 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst @@ -0,0 +1,33 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-Y10P: + +** +V4L2_PIX_FMT_Y10P ('Y10P') +** + +Grey-scale image as a MIPI RAW10 packed array + + +Description +=== + +This is a packed grey-scale image format with a depth of 10 bits per +pixel. Every four consecutive pixels are packed into 5 bytes. Each of +the first 4 bytes contain the 8 high order bits of the pixels, and +the 5th byte contains the 2 least significants bits of each pixel, +in the same order. + +**Bit-packed representation.** + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 +:widths: 8 8 8 8 64 + +* - Y'\ :sub:`00[9:2]` + - Y'\ :sub:`01[9:2]` + - Y'\ :sub:`02[9:2]` + - Y'\ :sub:`03[9:2]` + - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4) + Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0) diff --git a/Documentation/media/uapi/v4l/yuv-formats.rst b/Documentation/media/uapi/v4l/yuv-formats.rst index 3334ea4..9ab0592 100644 --- a/Documentation/media/uapi/v4l/yuv-formats.rst +++ b/Documentation/media/uapi/v4l/yuv-formats.rst @@ -29,6 +29,7 @@ to brightness information. pixfmt-y10 pixfmt-y12 pixfmt-y10b +pixfmt-y10p pixfmt-y16 pixfmt-y16-be pixfmt-y8i diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 0167056..2e3b1f0 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1184,6 +1184,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index a15e03b..fc177d8 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -522,6 +522,7 @@ struct v4l2_pix_format { /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ +#define V4L2_PIX_FMT_Y10Pv4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ -- 2.7.4
[PATCH v3 02/35] media: v4l: Add new 2X8 10-bit grayscale media bus code
The code will be called MEDIA_BUS_FMT_Y10_2X8_PADHI_LE. It is similar to MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE but MEDIA_BUS_FMT_Y10_2X8_PADHI_LE describes grayscale data. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/subdev-formats.rst | 72 + include/uapi/linux/media-bus-format.h | 3 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index a4739f7..8e73fcf 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -4318,6 +4318,78 @@ the following codes. - y\ :sub:`2` - y\ :sub:`1` - y\ :sub:`0` +* .. _MEDIA-BUS-FMT-Y10-2X8-PADHI_LE: + + - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE + - 0x202c + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` +* - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - y\ :sub:`9` + - y\ :sub:`8` * .. _MEDIA-BUS-FMT-UYVY10-2X10: - MEDIA_BUS_FMT_UYVY10_2X10 diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 9e35117..d6a5a3b 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -62,7 +62,7 @@ #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a -/* YUV (including grey) - next is 0x202c */ +/* YUV (including grey) - next is 0x202d */ #define MEDIA_BUS_FMT_Y8_1X8 0x2001 #define MEDIA_BUS_FMT_UV8_1X8 0x2015 #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 @@ -74,6 +74,7 @@ #define MEDIA_BUS_FMT_YUYV8_2X80x2008 #define MEDIA_BUS_FMT_YVYU8_2X80x2009 #define MEDIA_BUS_FMT_Y10_1X10 0x200a +#define MEDIA_BUS_FMT_Y10_2X8_PADHI_LE 0x202c #define MEDIA_BUS_FMT_UYVY10_2X10 0x2018 #define MEDIA_BUS_FMT_VYUY10_2X10 0x2019 #define MEDIA_BUS_FMT_YUYV10_2X10 0x200b -- 2.7.4
[PATCH v3 01/35] doc-rst: Add packed Bayer raw14 pixel formats
From: Sakari Ailus These formats are compressed 14-bit raw bayer formats with four different pixel orders. They are similar to 10-bit variants. The formats added by this patch are V4L2_PIX_FMT_SBGGR14P V4L2_PIX_FMT_SGBRG14P V4L2_PIX_FMT_SGRBG14P V4L2_PIX_FMT_SRGGB14P Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil --- Documentation/media/uapi/v4l/pixfmt-rgb.rst | 1 + Documentation/media/uapi/v4l/pixfmt-srggb14p.rst | 127 +++ include/uapi/linux/videodev2.h | 5 + 3 files changed, 133 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb14p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index cf2ef7d..1f9a7e3 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -19,4 +19,5 @@ RGB Formats pixfmt-srggb10-ipu3 pixfmt-srggb12 pixfmt-srggb12p +pixfmt-srggb14p pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst new file mode 100644 index 000..88d20c0 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst @@ -0,0 +1,127 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB14P: +.. _v4l2-pix-fmt-sbggr14p: +.. _v4l2-pix-fmt-sgbrg14p: +.. _v4l2-pix-fmt-sgrbg14p: + +*** +V4L2_PIX_FMT_SRGGB14P ('pRCC'), V4L2_PIX_FMT_SGRBG14P ('pgCC'), V4L2_PIX_FMT_SGBRG14P ('pGCC'), V4L2_PIX_FMT_SBGGR14P ('pBCC'), +*** + +*man V4L2_PIX_FMT_SRGGB14P(2)* + +V4L2_PIX_FMT_SGRBG14P +V4L2_PIX_FMT_SGBRG14P +V4L2_PIX_FMT_SBGGR14P +14-bit packed Bayer formats + + +Description +=== + +These four pixel formats are packed raw sRGB / Bayer formats with 14 +bits per colour. Every four consecutive samples are packed into seven +bytes. Each of the first four bytes contain the eight high order bits +of the pixels, and the three following bytes contains the six least +significants bits of each pixel, in the same order. + +Each n-pixel row contains n/2 green samples and n/2 blue or red samples, +with alternating green-red and green-blue rows. They are conventionally +described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example +of one of these formats: + +**Byte Order.** +Each cell is one byte. + + + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 +:widths: 2 1 1 1 1 1 1 1 + + +- .. row 1 + + - start + 0: + + - B\ :sub:`00high` + + - G\ :sub:`01high` + + - B\ :sub:`02high` + + - G\ :sub:`03high` + + - G\ :sub:`01low bits 1--0`\ (bits 7--6) + B\ :sub:`00low bits 5--0`\ (bits 5--0) + + - R\ :sub:`02low bits 3--0`\ (bits 7--4) + G\ :sub:`01low bits 5--2`\ (bits 3--0) + + - G\ :sub:`03low bits 5--0`\ (bits 7--2) + R\ :sub:`02low bits 5--4`\ (bits 1--0) + +- .. row 2 + + - start + 7: + + - G\ :sub:`00high` + + - R\ :sub:`01high` + + - G\ :sub:`02high` + + - R\ :sub:`03high` + + - R\ :sub:`01low bits 1--0`\ (bits 7--6) + G\ :sub:`00low bits 5--0`\ (bits 5--0) + + - G\ :sub:`02low bits 3--0`\ (bits 7--4) + R\ :sub:`01low bits 5--2`\ (bits 3--0) + + - R\ :sub:`03low bits 5--0`\ (bits 7--2) + G\ :sub:`02low bits 5--4`\ (bits 1--0) + +- .. row 3 + + - start + 14 + + - B\ :sub:`20high` + + - G\ :sub:`21high` + + - B\ :sub:`22high` + + - G\ :sub:`23high` + + - G\ :sub:`21low bits 1--0`\ (bits 7--6) + B\ :sub:`20low bits 5--0`\ (bits 5--0) + + - R\ :sub:`22low bits 3--0`\ (bits 7--4) + G\ :sub:`21low bits 5--2`\ (bits 3--0) + + - G\ :sub:`23low bits 5--0`\ (bits 7--2) + R\ :sub:`22low bits 5--4`\ (bits 1--0) + +- .. row 4 + + - start + 21 + + - G\ :sub:`30high` + + - R\ :sub:`31high` + + - G\ :sub:`32high` + + - R\ :sub:`33high` + + - R\ :sub:`31low bits 1--0`\ (bits 7--6) + G\ :sub:`30low bits 5--0`\ (bits 5--0) + + - G\ :sub:`32low bits 3--0`\ (bits 7--4) + R\ :sub:`31low bits 5--2`\ (bits 3--0) + + - R\ :sub:`33low bits 5--0`\ (bits 7--2) + G\ :sub:`32low bits 5--4`\ (bits 1--0) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 600877b..a15e03b 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -609,6 +609,11 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') #define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') #define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') +
Re: [PATCH v3 18/35] media: camss: Add basic runtime PM support
Hi Sakari, Thank you for review. On 24.07.2018 15:49, Sakari Ailus wrote: > Hi Todor, > > On Mon, Jul 23, 2018 at 02:02:35PM +0300, Todor Tomov wrote: >> There is a PM domain for each of the VFE hardware modules. Add >> support for basic runtime PM support to be able to control the >> PM domains. When a PM domain needs to be powered on - a device >> link is created. When a PM domain needs to be powered off - >> its device link is removed. This allows separate and >> independent control of the PM domains. >> >> Suspend/Resume is still not supported. >> >> Signed-off-by: Todor Tomov >> --- >> drivers/media/platform/qcom/camss/camss-csid.c | 4 ++ >> drivers/media/platform/qcom/camss/camss-csiphy.c | 5 ++ >> drivers/media/platform/qcom/camss/camss-ispif.c | 19 ++- >> drivers/media/platform/qcom/camss/camss-vfe.c| 13 + >> drivers/media/platform/qcom/camss/camss.c| 63 >> >> drivers/media/platform/qcom/camss/camss.h| 11 + >> 6 files changed, 113 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c >> b/drivers/media/platform/qcom/camss/camss-csid.c >> index 627ef44..ea2b0ba 100644 >> --- a/drivers/media/platform/qcom/camss/camss-csid.c >> +++ b/drivers/media/platform/qcom/camss/camss-csid.c >> @@ -13,6 +13,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -316,6 +317,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) >> if (on) { >> u32 hw_version; >> >> +pm_runtime_get_sync(dev); >> + >> ret = regulator_enable(csid->vdda); > > Shouldn't the regulator be enabled in the runtime_resume callback instead? Ideally - yes, but it becomes more complex (different pipelines are possible and we have only one callback) so (at least for now) I have left it as it is and stated in the commit message that suspend/resume is still not supported. > >> if (ret < 0) >> return ret; > > Note that you'll need pm_runtime_put() in in error handling here. Perhaps > elsewhere, too. Yes, I'll add it here and on all other places. > > Can powering on the device (i.e. pm_runtime_get_sync() call) fail? I'd really like to say that it cannot fail :) at least the callback is empty for now and cannot fail, but the logic in pm_runtime_get_sync() is not that simple and I'm really not sure. I'll add checks in the code in case it fails. > >> @@ -348,6 +351,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) >> disable_irq(csid->irq); >> camss_disable_clocks(csid->nclocks, csid->clock); >> ret = regulator_disable(csid->vdda); >> +pm_runtime_put_sync(dev); >> } >> >> return ret; >> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c >> b/drivers/media/platform/qcom/camss/camss-csiphy.c >> index 0383e94..2db78791 100644 >> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c >> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c >> @@ -13,6 +13,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -240,6 +241,8 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int >> on) >> u8 hw_version; >> int ret; >> >> +pm_runtime_get_sync(dev); >> + >> ret = csiphy_set_clock_rates(csiphy); >> if (ret < 0) >> return ret; > > Like here. Yes, I'll add it here too. -- Best regards, Todor Tomov
Re: [PATCH v3 17/35] media: camss: Add 8x96 resources
On 24.07.2018 15:21, Sakari Ailus wrote: > Hi Todor, > > On Mon, Jul 23, 2018 at 02:02:34PM +0300, Todor Tomov wrote: > ... >> @@ -61,7 +59,8 @@ struct ispif_device { >> struct mutex power_lock; >> struct ispif_intf_cmd_reg intf_cmd[MSM_ISPIF_VFE_NUM]; >> struct mutex config_lock; >> -struct ispif_line line[MSM_ISPIF_LINE_NUM]; >> +int line_num; > > unsigned int? Yes, thanks :) > > I guess if there are only such changes then a patch on top of the current > set might be more practical than a new version of the entire set. > -- Best regards, Todor Tomov
Re: [PATCH v3 35/35] media: v4l2-ioctl: Add format descriptions for packed Bayer raw14 pixel formats
Hi Sakari, Thanks for review. On 24.07.2018 15:52, Sakari Ailus wrote: > Hi Todor, > > On Mon, Jul 23, 2018 at 02:02:52PM +0300, Todor Tomov wrote: >> This removes warning "Unknown pixelformat" for the following formats: >> V4L2_PIX_FMT_SBGGR14P >> V4L2_PIX_FMT_SGBRG14P >> V4L2_PIX_FMT_SGRBG14P >> V4L2_PIX_FMT_SRGGB14P >> >> CC: Sakari Ailus >> Signed-off-by: Todor Tomov >> --- >> drivers/media/v4l2-core/v4l2-ioctl.c | 4 >> 1 file changed, 4 insertions(+) >> >> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c >> b/drivers/media/v4l2-core/v4l2-ioctl.c >> index 2e3b1f0..e8f7c89 100644 >> --- a/drivers/media/v4l2-core/v4l2-ioctl.c >> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c >> @@ -1260,6 +1260,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) >> case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG >> Packed"; break; >> case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG >> Packed"; break; >> case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB >> Packed"; break; >> +case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR >> Packed"; break; >> +case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG >> Packed"; break; >> +case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG >> Packed"; break; >> +case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB >> Packed"; break; >> case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; >> case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; >> case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; > > You could merge this to the patch that adds the format definitions. Or: Yes. I think we are going to have v4 so I will merge it with the patch which adds the format definitions. > > Acked-by: Sakari Ailus > > And preferrably move it to earlier in the patchset where new formats are > added. > -- Best regards, Todor Tomov
[PATCH v4 01/34] doc-rst: Add packed Bayer raw14 pixel formats
From: Sakari Ailus These formats are compressed 14-bit raw bayer formats with four different pixel orders. They are similar to 10-bit variants. The formats added by this patch are V4L2_PIX_FMT_SBGGR14P V4L2_PIX_FMT_SGBRG14P V4L2_PIX_FMT_SGRBG14P V4L2_PIX_FMT_SRGGB14P Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/pixfmt-rgb.rst | 1 + Documentation/media/uapi/v4l/pixfmt-srggb14p.rst | 127 +++ drivers/media/v4l2-core/v4l2-ioctl.c | 4 + include/uapi/linux/videodev2.h | 5 + 4 files changed, 137 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb14p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index cf2ef7d..1f9a7e3 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -19,4 +19,5 @@ RGB Formats pixfmt-srggb10-ipu3 pixfmt-srggb12 pixfmt-srggb12p +pixfmt-srggb14p pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst new file mode 100644 index 000..88d20c0 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst @@ -0,0 +1,127 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB14P: +.. _v4l2-pix-fmt-sbggr14p: +.. _v4l2-pix-fmt-sgbrg14p: +.. _v4l2-pix-fmt-sgrbg14p: + +*** +V4L2_PIX_FMT_SRGGB14P ('pRCC'), V4L2_PIX_FMT_SGRBG14P ('pgCC'), V4L2_PIX_FMT_SGBRG14P ('pGCC'), V4L2_PIX_FMT_SBGGR14P ('pBCC'), +*** + +*man V4L2_PIX_FMT_SRGGB14P(2)* + +V4L2_PIX_FMT_SGRBG14P +V4L2_PIX_FMT_SGBRG14P +V4L2_PIX_FMT_SBGGR14P +14-bit packed Bayer formats + + +Description +=== + +These four pixel formats are packed raw sRGB / Bayer formats with 14 +bits per colour. Every four consecutive samples are packed into seven +bytes. Each of the first four bytes contain the eight high order bits +of the pixels, and the three following bytes contains the six least +significants bits of each pixel, in the same order. + +Each n-pixel row contains n/2 green samples and n/2 blue or red samples, +with alternating green-red and green-blue rows. They are conventionally +described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example +of one of these formats: + +**Byte Order.** +Each cell is one byte. + + + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 +:widths: 2 1 1 1 1 1 1 1 + + +- .. row 1 + + - start + 0: + + - B\ :sub:`00high` + + - G\ :sub:`01high` + + - B\ :sub:`02high` + + - G\ :sub:`03high` + + - G\ :sub:`01low bits 1--0`\ (bits 7--6) + B\ :sub:`00low bits 5--0`\ (bits 5--0) + + - R\ :sub:`02low bits 3--0`\ (bits 7--4) + G\ :sub:`01low bits 5--2`\ (bits 3--0) + + - G\ :sub:`03low bits 5--0`\ (bits 7--2) + R\ :sub:`02low bits 5--4`\ (bits 1--0) + +- .. row 2 + + - start + 7: + + - G\ :sub:`00high` + + - R\ :sub:`01high` + + - G\ :sub:`02high` + + - R\ :sub:`03high` + + - R\ :sub:`01low bits 1--0`\ (bits 7--6) + G\ :sub:`00low bits 5--0`\ (bits 5--0) + + - G\ :sub:`02low bits 3--0`\ (bits 7--4) + R\ :sub:`01low bits 5--2`\ (bits 3--0) + + - R\ :sub:`03low bits 5--0`\ (bits 7--2) + G\ :sub:`02low bits 5--4`\ (bits 1--0) + +- .. row 3 + + - start + 14 + + - B\ :sub:`20high` + + - G\ :sub:`21high` + + - B\ :sub:`22high` + + - G\ :sub:`23high` + + - G\ :sub:`21low bits 1--0`\ (bits 7--6) + B\ :sub:`20low bits 5--0`\ (bits 5--0) + + - R\ :sub:`22low bits 3--0`\ (bits 7--4) + G\ :sub:`21low bits 5--2`\ (bits 3--0) + + - G\ :sub:`23low bits 5--0`\ (bits 7--2) + R\ :sub:`22low bits 5--4`\ (bits 1--0) + +- .. row 4 + + - start + 21 + + - G\ :sub:`30high` + + - R\ :sub:`31high` + + - G\ :sub:`32high` + + - R\ :sub:`33high` + + - R\ :sub:`31low bits 1--0`\ (bits 7--6) + G\ :sub:`30low bits 5--0`\ (bits 5--0) + + - G\ :sub:`32low bits 3--0`\ (bits 7--4) + R\ :sub:`31low bits 5--2`\ (bits 3--0) + + - R\ :sub:`33low bits 5--0`\ (bits 7--2) + G\ :sub:`32low bits 5--4`\ (bits 1--0) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 0167056..04e1231 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1259,6 +1259,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
[PATCH v4 18/34] media: camss: Add basic runtime PM support
There is a PM domain for each of the VFE hardware modules. Add support for basic runtime PM support to be able to control the PM domains. When a PM domain needs to be powered on - a device link is created. When a PM domain needs to be powered off - its device link is removed. This allows separate and independent control of the PM domains. Suspend/Resume is still not supported. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 13 - drivers/media/platform/qcom/camss/camss-csiphy.c | 15 +- drivers/media/platform/qcom/camss/camss-ispif.c | 26 -- drivers/media/platform/qcom/camss/camss-vfe.c| 17 +++ drivers/media/platform/qcom/camss/camss.c| 63 drivers/media/platform/qcom/camss/camss.h| 11 + 6 files changed, 139 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 627ef44..3ba087f 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -316,19 +317,27 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) if (on) { u32 hw_version; - ret = regulator_enable(csid->vdda); + ret = pm_runtime_get_sync(dev); if (ret < 0) return ret; + ret = regulator_enable(csid->vdda); + if (ret < 0) { + pm_runtime_put_sync(dev); + return ret; + } + ret = csid_set_clock_rates(csid); if (ret < 0) { regulator_disable(csid->vdda); + pm_runtime_put_sync(dev); return ret; } ret = camss_enable_clocks(csid->nclocks, csid->clock, dev); if (ret < 0) { regulator_disable(csid->vdda); + pm_runtime_put_sync(dev); return ret; } @@ -339,6 +348,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); regulator_disable(csid->vdda); + pm_runtime_put_sync(dev); return ret; } @@ -348,6 +358,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); ret = regulator_disable(csid->vdda); + pm_runtime_put_sync(dev); } return ret; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 0383e94..4aeaedb 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -240,13 +241,21 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) u8 hw_version; int ret; - ret = csiphy_set_clock_rates(csiphy); + ret = pm_runtime_get_sync(dev); if (ret < 0) return ret; + ret = csiphy_set_clock_rates(csiphy); + if (ret < 0) { + pm_runtime_put_sync(dev); + return ret; + } + ret = camss_enable_clocks(csiphy->nclocks, csiphy->clock, dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_sync(dev); return ret; + } enable_irq(csiphy->irq); @@ -259,6 +268,8 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) disable_irq(csiphy->irq); camss_disable_clocks(csiphy->nclocks, csiphy->clock); + + pm_runtime_put_sync(dev); } return 0; diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index ed50cc5..2c6c0d2 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,14 @@ static int ispif_reset(struct ispif_device *ispif) u32 val; int ret; + ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); + if (ret < 0) + return ret; + + ret = camss_pm_domain_on(to_camss(
[PATCH v4 33/34] media: doc: media/v4l-drivers: Update Qualcomm CAMSS driver document for 8x96
Update the document to describe the support of Camera Subsystem on MSM8996/APQ8096. Signed-off-by: Todor Tomov --- Documentation/media/v4l-drivers/qcom_camss.rst | 93 +++--- .../media/v4l-drivers/qcom_camss_8x96_graph.dot| 104 + 2 files changed, 164 insertions(+), 33 deletions(-) create mode 100644 Documentation/media/v4l-drivers/qcom_camss_8x96_graph.dot diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst index 9e66b7b..f27c8df 100644 --- a/Documentation/media/v4l-drivers/qcom_camss.rst +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -7,34 +7,34 @@ Introduction This file documents the Qualcomm Camera Subsystem driver located under -drivers/media/platform/qcom/camss-8x16. +drivers/media/platform/qcom/camss. The current version of the driver supports the Camera Subsystem found on -Qualcomm MSM8916 and APQ8016 processors. +Qualcomm MSM8916/APQ8016 and MSM8996/APQ8096 processors. The driver implements V4L2, Media controller and V4L2 subdev interfaces. Camera sensor using V4L2 subdev interface in the kernel is supported. The driver is implemented using as a reference the Qualcomm Camera Subsystem -driver for Android as found in Code Aurora [#f1]_. +driver for Android as found in Code Aurora [#f1]_ [#f2]_. Qualcomm Camera Subsystem hardware -- -The Camera Subsystem hardware found on 8x16 processors and supported by the -driver consists of: +The Camera Subsystem hardware found on 8x16 / 8x96 processors and supported by +the driver consists of: -- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. +- 2 / 3 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. A separate camera sensor can be connected to each of the CSIPHY module; -- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application layer - of the CSI2 receivers. A CSID can decode data stream from any of the CSIPHY. - Each CSID also contains a TG (Test Generator) block which can generate +- 2 / 4 CSID (CSI Decoder) modules. They handle the Protocol and Application + layer of the CSI2 receivers. A CSID can decode data stream from any of the + CSIPHY. Each CSID also contains a TG (Test Generator) block which can generate artificial input data for test purposes; - ISPIF (ISP Interface) module. Handles the routing of the data streams from the CSIDs to the inputs of the VFE; -- VFE (Video Front End) module. Contains a pipeline of image processing hardware - blocks. The VFE has different input interfaces. The PIX (Pixel) input +- 1 / 2 VFE (Video Front End) module(s). Contain a pipeline of image processing + hardware blocks. The VFE has different input interfaces. The PIX (Pixel) input interface feeds the input data to the image processing pipeline. The image processing pipeline contains also a scale and crop module at the end. Three RDI (Raw Dump Interface) input interfaces bypass the image processing @@ -49,18 +49,33 @@ The current version of the driver supports: - Input from camera sensor via CSIPHY; - Generation of test input data by the TG in CSID; -- RDI interface of VFE - raw dump of the input data to memory. +- RDI interface of VFE - Supported formats: + - Raw dump of the input data to memory. - - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / -V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); - - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / -V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); - - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / -V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P); - - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / -V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). +Supported formats: + +- YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); +- MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / + V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); +- MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / + V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P / + V4L2_PIX_FMT_Y10P); +- MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / + V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). +- (8x96 only) MIPI RAW14 (14bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB14P / + V4L2_PIX_FMT_SGBRG14P / V4L2_PIX_FMT_SGRBG14P / V4L2_PIX_FMT_SRGGB14P). + + - (8x96 only) Format conversion of the input data. + +Supported input formats: + +- MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / V4L2_PIX_FMT_Y10P). + +Supported output formats: + +- Plain16 RAW10 (10bit unpacked Bayer RAW - V4L2_PIX_FMT_SBGGR10 / V4L2_PIX_FMT_Y10
[PATCH v4 13/34] media: camss: vfe: Get line pointer as container of video_out
Simplify getting of the line pointer by using the container_of macro instead of traversing media controller links. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-vfe.c | 38 +++ 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 51ad3f8..77167f1 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -2038,26 +2038,6 @@ static void vfe_put(struct vfe_device *vfe) } /* - * vfe_video_pad_to_line - Get pointer to VFE line by media pad - * @pad: Media pad - * - * Return pointer to vfe line structure - */ -static struct vfe_line *vfe_video_pad_to_line(struct media_pad *pad) -{ - struct media_pad *vfe_pad; - struct v4l2_subdev *subdev; - - vfe_pad = media_entity_remote_pad(pad); - if (vfe_pad == NULL) - return NULL; - - subdev = media_entity_to_v4l2_subdev(vfe_pad->entity); - - return container_of(subdev, struct vfe_line, subdev); -} - -/* * vfe_queue_buffer - Add empty buffer * @vid: Video device structure * @buf: Buffer to be enqueued @@ -2070,16 +2050,11 @@ static struct vfe_line *vfe_video_pad_to_line(struct media_pad *pad) static int vfe_queue_buffer(struct camss_video *vid, struct camss_buffer *buf) { - struct vfe_device *vfe = &vid->camss->vfe; - struct vfe_line *line; + struct vfe_line *line = container_of(vid, struct vfe_line, video_out); + struct vfe_device *vfe = to_vfe(line); struct vfe_output *output; unsigned long flags; - line = vfe_video_pad_to_line(&vid->pad); - if (!line) { - dev_err(to_device(vfe), "Can not queue buffer\n"); - return -1; - } output = &line->output; spin_lock_irqsave(&vfe->output_lock, flags); @@ -2104,16 +2079,11 @@ static int vfe_queue_buffer(struct camss_video *vid, static int vfe_flush_buffers(struct camss_video *vid, enum vb2_buffer_state state) { - struct vfe_device *vfe = &vid->camss->vfe; - struct vfe_line *line; + struct vfe_line *line = container_of(vid, struct vfe_line, video_out); + struct vfe_device *vfe = to_vfe(line); struct vfe_output *output; unsigned long flags; - line = vfe_video_pad_to_line(&vid->pad); - if (!line) { - dev_err(to_device(vfe), "Can not flush buffers\n"); - return -1; - } output = &line->output; spin_lock_irqsave(&vfe->output_lock, flags); -- 2.7.4
[PATCH v4 31/34] media: camss: Add support for RAW MIPI14 on 8x96
Add support for RAW MIPI14 format for RDI mode on 8x96. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 30 drivers/media/platform/qcom/camss/camss-csiphy.c | 4 drivers/media/platform/qcom/camss/camss-ispif.c | 4 drivers/media/platform/qcom/camss/camss-vfe.c| 4 drivers/media/platform/qcom/camss/camss-video.c | 8 +++ 5 files changed, 50 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 0715a8e..472884d 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -63,11 +63,13 @@ #define DATA_TYPE_RAW_8BIT 0x2a #define DATA_TYPE_RAW_10BIT0x2b #define DATA_TYPE_RAW_12BIT0x2c +#define DATA_TYPE_RAW_14BIT0x2d #define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 #define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 #define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 #define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 +#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8 #define CSID_RESET_TIMEOUT_MS 500 @@ -306,6 +308,34 @@ static const struct csid_format csid_formats_8x96[] = { DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, 1, + }, + { + MEDIA_BUS_FMT_SBGGR14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, } }; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 3cdab59..cae3e8b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -64,6 +64,10 @@ static const struct csiphy_format csiphy_formats_8x96[] = { { MEDIA_BUS_FMT_SGBRG12_1X12, 12 }, { MEDIA_BUS_FMT_SGRBG12_1X12, 12 }, { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + { MEDIA_BUS_FMT_SBGGR14_1X14, 14 }, + { MEDIA_BUS_FMT_SGBRG14_1X14, 14 }, + { MEDIA_BUS_FMT_SGRBG14_1X14, 14 }, + { MEDIA_BUS_FMT_SRGGB14_1X14, 14 }, }; /* diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 81d6351..3e2f341 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -140,6 +140,10 @@ static const u32 ispif_formats_8x96[] = { MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR14_1X14, + MEDIA_BUS_FMT_SGBRG14_1X14, + MEDIA_BUS_FMT_SGRBG14_1X14, + MEDIA_BUS_FMT_SRGGB14_1X14, }; /* diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 11d37b7..9675309 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -94,6 +94,10 @@ static const struct vfe_format formats_rdi_8x96[] = { { MEDIA_BUS_FMT_SGBRG12_1X12, 12 }, { MEDIA_BUS_FMT_SGRBG12_1X12, 12 }, { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + { MEDIA_BUS_FMT_SBGGR14_1X14, 14 }, + { MEDIA_BUS_FMT_SGBRG14_1X14, 14 }, + { MEDIA_BUS_FMT_SGRBG14_1X14, 14 }, + { MEDIA_BUS_FMT_SRGGB14_1X14, 14 }, }; static const struct vfe_format formats_pix_8x96[] = { diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c index 28d53bf..2e19bc8 100644 --- a/drivers/media/platform/qcom/camss/camss-video.c +++ b/drivers/media/platform/qcom/camss/camss-video.c @@ -111,6 +111,14 @@ static const struct camss_format_info formats_rdi_8x96[] = { { { 1, 1 } }, { { 1, 1 } }, { 12 } }, { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1, { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14
[PATCH v4 24/34] media: camss: vfe: Split to hardware dependent and independent parts
This will allow to add support for different hardware. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/Makefile|1 + drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 1006 +++ drivers/media/platform/qcom/camss/camss-vfe.c | 1074 ++--- drivers/media/platform/qcom/camss/camss-vfe.h | 73 +- 4 files changed, 1169 insertions(+), 985 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-4-1.c diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 36b9f7c..38dc56e 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -7,6 +7,7 @@ qcom-camss-objs += \ camss-csiphy-3ph-1-0.o \ camss-csiphy.o \ camss-ispif.o \ + camss-vfe-4-1.o \ camss-vfe.o \ camss-video.o \ diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c new file mode 100644 index 000..070c0c3 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -0,0 +1,1006 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-vfe-4-1.c + * + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.1 + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2018 Linaro Ltd. + */ + +#include +#include + +#include "camss-vfe.h" + +#define VFE_0_HW_VERSION 0x000 + +#define VFE_0_GLOBAL_RESET_CMD 0x00c +#define VFE_0_GLOBAL_RESET_CMD_COREBIT(0) +#define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1) +#define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2) +#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3) +#define VFE_0_GLOBAL_RESET_CMD_REGISTERBIT(4) +#define VFE_0_GLOBAL_RESET_CMD_TIMER BIT(5) +#define VFE_0_GLOBAL_RESET_CMD_PM BIT(6) +#define VFE_0_GLOBAL_RESET_CMD_BUS_MISRBIT(7) +#define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(8) + +#define VFE_0_MODULE_CFG 0x018 +#define VFE_0_MODULE_CFG_DEMUX BIT(2) +#define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE BIT(3) +#define VFE_0_MODULE_CFG_SCALE_ENC BIT(23) +#define VFE_0_MODULE_CFG_CROP_ENC BIT(27) + +#define VFE_0_CORE_CFG 0x01c +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR0x4 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB0x5 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY0x6 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY0x7 + +#define VFE_0_IRQ_CMD 0x024 +#define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0) + +#define VFE_0_IRQ_MASK_0 0x028 +#define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0) +#define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1) +#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)BIT((n) + 5) +#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \ + ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)) +#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) +#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) +#define VFE_0_IRQ_MASK_0_RESET_ACK BIT(31) +#define VFE_0_IRQ_MASK_1 0x02c +#define VFE_0_IRQ_MASK_1_CAMIF_ERROR BIT(0) +#define VFE_0_IRQ_MASK_1_VIOLATION BIT(7) +#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK BIT(8) +#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)BIT((n) + 9) +#define VFE_0_IRQ_MASK_1_RDIn_SOF(n) BIT((n) + 29) + +#define VFE_0_IRQ_CLEAR_0 0x030 +#define VFE_0_IRQ_CLEAR_1 0x034 + +#define VFE_0_IRQ_STATUS_0 0x038 +#define VFE_0_IRQ_STATUS_0_CAMIF_SOF BIT(0) +#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5) +#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)\ + ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)) +#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) +#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) +#define VFE_0_IRQ_STATUS_0_RESET_ACK BIT(31) +#define VFE_0_IRQ_STATUS_1 0x03c +#define VFE_0_IRQ_STATUS_1_VIOLATION BIT(7) +#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACKBIT(8) +#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) BIT((n) + 29) + +#define VFE_0_IRQ_COMPOSITE_MASK_0 0x40 +#define VFE_0_VIOLATION_STATUS 0x48 + +#define VFE_0_BUS_CMD 0x4c +#define VFE_0_BUS_CMD_Mx_RLD_CMD(x)BIT(x) + +#define VFE_0_BUS_CFG 0x050 + +#define VFE_0_BUS_XBAR_CFG_x(x)(0x58 + 0x4 * ((x) / 2)) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(1) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA(0x3 <
[PATCH v4 17/34] media: camss: Add 8x96 resources
Add structs with 8x96 resources. As the number of CSIPHY, CSID and VFE hardware modules is different on 8x16 and 8x96 select the number at runtime and allocate needed structures dynamically. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 20 +- drivers/media/platform/qcom/camss/camss-csid.h | 3 +- drivers/media/platform/qcom/camss/camss-csiphy.c | 19 +- drivers/media/platform/qcom/camss/camss-csiphy.h | 4 +- drivers/media/platform/qcom/camss/camss-ispif.c | 35 ++- drivers/media/platform/qcom/camss/camss-ispif.h | 9 +- drivers/media/platform/qcom/camss/camss-vfe.c| 61 ++-- drivers/media/platform/qcom/camss/camss-vfe.h| 4 +- drivers/media/platform/qcom/camss/camss.c| 354 ++- drivers/media/platform/qcom/camss/camss.h| 20 +- 10 files changed, 390 insertions(+), 139 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 3cde07e..627ef44 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -219,7 +219,7 @@ static irqreturn_t csid_isr(int irq, void *dev) */ static int csid_set_clock_rates(struct csid_device *csid) { - struct device *dev = to_device_index(csid, csid->id); + struct device *dev = csid->camss->dev; u32 pixel_clock; int i, j; int ret; @@ -232,7 +232,9 @@ static int csid_set_clock_rates(struct csid_device *csid) struct camss_clock *clock = &csid->clock[i]; if (!strcmp(clock->name, "csi0") || - !strcmp(clock->name, "csi1")) { + !strcmp(clock->name, "csi1") || + !strcmp(clock->name, "csi2") || + !strcmp(clock->name, "csi3")) { u8 bpp = csid_get_fmt_entry( csid->fmt[MSM_CSIPHY_PAD_SINK].code)->bpp; u8 num_lanes = csid->phy.lane_cnt; @@ -291,8 +293,7 @@ static int csid_reset(struct csid_device *csid) time = wait_for_completion_timeout(&csid->reset_complete, msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); if (!time) { - dev_err(to_device_index(csid, csid->id), - "CSID reset timeout\n"); + dev_err(csid->camss->dev, "CSID reset timeout\n"); return -EIO; } @@ -309,7 +310,7 @@ static int csid_reset(struct csid_device *csid) static int csid_set_power(struct v4l2_subdev *sd, int on) { struct csid_device *csid = v4l2_get_subdevdata(sd); - struct device *dev = to_device_index(csid, csid->id); + struct device *dev = csid->camss->dev; int ret; if (on) { @@ -375,7 +376,7 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) ret = v4l2_ctrl_handler_setup(&csid->ctrls); if (ret < 0) { - dev_err(to_device_index(csid, csid->id), + dev_err(csid->camss->dev, "could not sync v4l2 controls: %d\n", ret); return ret; } @@ -796,15 +797,16 @@ static const struct v4l2_ctrl_ops csid_ctrl_ops = { * * Return 0 on success or a negative error code otherwise */ -int msm_csid_subdev_init(struct csid_device *csid, +int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, const struct resources *res, u8 id) { - struct device *dev = to_device_index(csid, id); + struct device *dev = camss->dev; struct platform_device *pdev = to_platform_device(dev); struct resource *r; int i, j; int ret; + csid->camss = camss; csid->id = id; /* Memory */ @@ -1018,7 +1020,7 @@ int msm_csid_register_entity(struct csid_device *csid, { struct v4l2_subdev *sd = &csid->subdev; struct media_pad *pads = csid->pads; - struct device *dev = to_device_index(csid, csid->id); + struct device *dev = csid->camss->dev; int ret; v4l2_subdev_init(sd, &csid_v4l2_ops); diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index ae1d045..ed605fd 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -42,6 +42,7 @@ struct csid_phy_config { }; struct csid_device { + struct camss *camss; u8 id; struct v4l2_subdev subdev; struct media_pad pads[MSM_CSID_PADS_NUM]; @@ -61,7 +62,7 @@ struct csid_device { struct resources; -int msm_csid_subdev_init(struct csid_device *csid, +int msm_csid_subdev_init(struct cams
[PATCH v4 34/34] media: camss: csid: Add support for events triggered by user controls
Changing a user control value can trigger an event to other users. Add support for that. Signed-off-by: Todor Tomov Acked-by: Sakari Ailus --- drivers/media/platform/qcom/camss/camss-csid.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 6e141af..729b318 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "camss-csid.h" @@ -1273,6 +1274,8 @@ static int csid_link_setup(struct media_entity *entity, static const struct v4l2_subdev_core_ops csid_core_ops = { .s_power = csid_set_power, + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, }; static const struct v4l2_subdev_video_ops csid_video_ops = { @@ -1318,7 +1321,8 @@ int msm_csid_register_entity(struct csid_device *csid, v4l2_subdev_init(sd, &csid_v4l2_ops); sd->internal_ops = &csid_v4l2_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | +V4L2_SUBDEV_FL_HAS_EVENTS; snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", MSM_CSID_NAME, csid->id); v4l2_set_subdevdata(sd, csid); -- 2.7.4
[PATCH v4 28/34] media: camss: vfe: Add support for UYVY output from VFE on 8x96
Add support to output UYVY formats from the VFE (via the PIX interface). A configuration for the realign module in the VFE is added. As the realign module is present on 8x96 but not on 8x16, this is supported on 8x96 only. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 6 + drivers/media/platform/qcom/camss/camss-vfe-4-7.c | 129 ++ drivers/media/platform/qcom/camss/camss-vfe.c | 31 +- drivers/media/platform/qcom/camss/camss-vfe.h | 2 + drivers/media/platform/qcom/camss/camss-video.c | 8 ++ 5 files changed, 152 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 41184dc..da3a9fe 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -542,6 +542,11 @@ static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, } } +static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line, + u8 enable) +{ + /* empty */ +} static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) { vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), @@ -989,6 +994,7 @@ const struct vfe_hw_ops vfe_ops_4_1 = { .wm_set_subsample = vfe_wm_set_subsample, .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, .set_xbar_cfg = vfe_set_xbar_cfg, + .set_realign_cfg = vfe_set_realign_cfg, .set_rdi_cid = vfe_set_rdi_cid, .reg_update = vfe_reg_update, .reg_update_clear = vfe_reg_update_clear, diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 45e6711..4c584bf 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -34,6 +34,7 @@ #define VFE_0_MODULE_ZOOM_EN 0x04c #define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1) #define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2) +#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF BIT(9) #define VFE_0_CORE_CFG 0x050 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR0x4 @@ -87,6 +88,9 @@ #define VFE_0_BUS_XBAR_CFG_x(x)(0x90 + 0x4 * ((x) / 2)) #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(2) +#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN BIT(3) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA (0x1 << 4) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER (0x2 << 4) #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA(0x3 << 4) #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0x0 @@ -221,6 +225,11 @@ #define VFE_0_CLAMP_ENC_MIN_CFG_CH1(0x0 << 8) #define VFE_0_CLAMP_ENC_MIN_CFG_CH2(0x0 << 16) +#define VFE_0_REALIGN_BUF_CFG 0xaac +#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL BIT(2) +#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) +#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) + #define CAMIF_TIMEOUT_SLEEP_US 1000 #define CAMIF_TIMEOUT_ALL_US 100 @@ -311,7 +320,7 @@ static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) -static int vfe_word_per_line(u32 format, u32 pixel_per_line) +static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line) { int val = 0; @@ -333,6 +342,11 @@ static int vfe_word_per_line(u32 format, u32 pixel_per_line) return val; } +static int vfe_word_per_line_by_bytes(u32 bytes_per_line) +{ + return CALC_WORD(bytes_per_line, 1, 8); +} + static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, u16 *width, u16 *height, u16 *bytesperline) { @@ -351,6 +365,15 @@ static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, *height = pix->height; *bytesperline = pix->plane_fmt[0].bytesperline; break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_UYVY: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[plane].bytesperline; + break; + } } @@ -365,7 +388,7 @@ static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline); - wpl = vfe_word_per_line(pix->pixelformat, width); + wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width); reg = height - 1; reg |= ((wpl + 3) / 4 - 1)
[PATCH v4 25/34] media: camss: vfe: Add support for 8x96
Add VFE hardware dependent part for 8x96. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/Makefile | 1 + drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 6 + .../camss/{camss-vfe-4-1.c => camss-vfe-4-7.c} | 347 - drivers/media/platform/qcom/camss/camss-vfe.c | 4 + drivers/media/platform/qcom/camss/camss-vfe.h | 2 + 5 files changed, 209 insertions(+), 151 deletions(-) copy drivers/media/platform/qcom/camss/{camss-vfe-4-1.c => camss-vfe-4-7.c} (75%) diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 38dc56e..f5e6e25 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -8,6 +8,7 @@ qcom-camss-objs += \ camss-csiphy.o \ camss-ispif.o \ camss-vfe-4-1.o \ + camss-vfe-4-7.o \ camss-vfe.o \ camss-video.o \ diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 070c0c3..41184dc 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -789,6 +789,11 @@ static void vfe_set_qos(struct vfe_device *vfe) writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); } +static void vfe_set_ds(struct vfe_device *vfe) +{ + /* empty */ +} + static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) { u32 val = VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(wm); @@ -995,6 +1000,7 @@ const struct vfe_hw_ops vfe_ops_4_1 = { .set_crop_cfg = vfe_set_crop_cfg, .set_clamp_cfg = vfe_set_clamp_cfg, .set_qos = vfe_set_qos, + .set_ds = vfe_set_ds, .set_cgc_override = vfe_set_cgc_override, .set_camif_cfg = vfe_set_camif_cfg, .set_camif_cmd = vfe_set_camif_cmd, diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c similarity index 75% copy from drivers/media/platform/qcom/camss/camss-vfe-4-1.c copy to drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 070c0c3..45e6711 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* - * camss-vfe-4-1.c + * camss-vfe-4-7.c * - * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.1 + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.7 * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2018 Linaro Ltd. @@ -15,33 +15,37 @@ #define VFE_0_HW_VERSION 0x000 -#define VFE_0_GLOBAL_RESET_CMD 0x00c +#define VFE_0_GLOBAL_RESET_CMD 0x018 #define VFE_0_GLOBAL_RESET_CMD_COREBIT(0) #define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1) #define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2) #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3) #define VFE_0_GLOBAL_RESET_CMD_REGISTERBIT(4) -#define VFE_0_GLOBAL_RESET_CMD_TIMER BIT(5) -#define VFE_0_GLOBAL_RESET_CMD_PM BIT(6) -#define VFE_0_GLOBAL_RESET_CMD_BUS_MISRBIT(7) -#define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(8) - -#define VFE_0_MODULE_CFG 0x018 -#define VFE_0_MODULE_CFG_DEMUX BIT(2) -#define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE BIT(3) -#define VFE_0_MODULE_CFG_SCALE_ENC BIT(23) -#define VFE_0_MODULE_CFG_CROP_ENC BIT(27) - -#define VFE_0_CORE_CFG 0x01c +#define VFE_0_GLOBAL_RESET_CMD_PM BIT(5) +#define VFE_0_GLOBAL_RESET_CMD_BUS_MISRBIT(6) +#define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(7) +#define VFE_0_GLOBAL_RESET_CMD_DSP BIT(8) +#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGCBIT(9) + +#define VFE_0_MODULE_LENS_EN 0x040 +#define VFE_0_MODULE_LENS_EN_DEMUX BIT(2) +#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE BIT(3) + +#define VFE_0_MODULE_ZOOM_EN 0x04c +#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1) +#define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2) + +#define VFE_0_CORE_CFG 0x050 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR0x4 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB0x5 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY0x6 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY0x7 +#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN BIT(4) -#define VFE_0_IRQ_CMD 0x024 +#define VFE_0_IRQ_CMD 0x058 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0) -#define VFE_0_IRQ_MASK_0 0x028 +#define VFE_0_IRQ_MASK_0 0x05c #define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0) #define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1) #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)BIT((n) + 5) @@ -50,17 +54,17 @@
[PATCH v4 26/34] media: camss: Format configuration per hardware version
As the 8x16 and 8x96 support different formats, separate the arrays which contain the supported formats. For the VFE also add separate arrays for RDI and PIX subdevices. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 196 +++ drivers/media/platform/qcom/camss/camss-csid.h | 2 + drivers/media/platform/qcom/camss/camss-csiphy.c | 145 - drivers/media/platform/qcom/camss/camss-csiphy.h | 2 + drivers/media/platform/qcom/camss/camss-ispif.c | 43 - drivers/media/platform/qcom/camss/camss-ispif.h | 2 + drivers/media/platform/qcom/camss/camss-vfe.c| 189 -- drivers/media/platform/qcom/camss/camss-vfe.h| 2 + drivers/media/platform/qcom/camss/camss-video.c | 97 ++- 9 files changed, 467 insertions(+), 211 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 915835e..db960da 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -62,7 +62,7 @@ #define CSID_RESET_TIMEOUT_MS 500 -struct csid_fmts { +struct csid_format { u32 code; u8 data_type; u8 decode_format; @@ -70,7 +70,7 @@ struct csid_fmts { u8 spp; /* bus samples per pixel */ }; -static const struct csid_fmts csid_input_fmts[] = { +static const struct csid_format csid_formats_8x16[] = { { MEDIA_BUS_FMT_UYVY8_2X8, DATA_TYPE_YUV422_8BIT, @@ -185,17 +185,135 @@ static const struct csid_fmts csid_input_fmts[] = { } }; -static const struct csid_fmts *csid_get_fmt_entry(u32 code) +static const struct csid_format csid_formats_8x96[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + } +}; + +static const struct csid_format *csid_get_fmt_entry( + const struct csid_format *formats, + unsigned int nformat
[PATCH v4 21/34] media: camss: csiphy: Add support for 8x96
Add CSIPHY hardware dependent part for 8x96. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/Makefile | 1 + .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 256 + drivers/media/platform/qcom/camss/camss-csiphy.c | 2 + drivers/media/platform/qcom/camss/camss-csiphy.h | 1 + 4 files changed, 260 insertions(+) create mode 100644 drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 0446b24..36b9f7c 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -4,6 +4,7 @@ qcom-camss-objs += \ camss.o \ camss-csid.o \ camss-csiphy-2ph-1-0.o \ + camss-csiphy-3ph-1-0.o \ camss-csiphy.o \ camss-ispif.o \ camss-vfe.o \ diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c new file mode 100644 index 000..bcd0dfd --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-csiphy-3ph-1-0.c + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v1.0 + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016-2018 Linaro Ltd. + */ + +#include "camss-csiphy.h" + +#include +#include + +#define CSIPHY_3PH_LNn_CFG1(n) (0x000 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG(BIT(7) | BIT(6)) +#define CSIPHY_3PH_LNn_CFG2(n) (0x004 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG2_LP_REC_EN_INT BIT(3) +#define CSIPHY_3PH_LNn_CFG3(n) (0x008 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG4(n) (0x00c + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS 0xa4 +#define CSIPHY_3PH_LNn_CFG5(n) (0x010 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG5_T_HS_DTERM 0x02 +#define CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT 0x50 +#define CSIPHY_3PH_LNn_TEST_IMP(n) (0x01c + 0x100 * (n)) +#define CSIPHY_3PH_LNn_TEST_IMP_HS_TERM_IMP0xa +#define CSIPHY_3PH_LNn_MISC1(n)(0x028 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_MISC1_IS_CLKLANEBIT(2) +#define CSIPHY_3PH_LNn_CFG6(n) (0x02c + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG6_SWI_FORCE_INIT_EXITBIT(0) +#define CSIPHY_3PH_LNn_CFG7(n) (0x030 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG7_SWI_T_INIT 0x2 +#define CSIPHY_3PH_LNn_CFG8(n) (0x034 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG8_SWI_SKIP_WAKEUPBIT(0) +#define CSIPHY_3PH_LNn_CFG8_SKEW_FILTER_ENABLE BIT(1) +#define CSIPHY_3PH_LNn_CFG9(n) (0x038 + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CFG9_SWI_T_WAKEUP 0x1 +#define CSIPHY_3PH_LNn_CSI_LANE_CTRL15(n) (0x03c + 0x100 * (n)) +#define CSIPHY_3PH_LNn_CSI_LANE_CTRL15_SWI_SOT_SYMBOL 0xb8 + +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(n) (0x800 + 0x4 * (n)) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0) +#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_IDBIT(1) +#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(n) (0x8b0 + 0x4 * (n)) + +static void csiphy_hw_version_read(struct csiphy_device *csiphy, + struct device *dev) +{ + u32 hw_version; + + writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID, + csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6)); + + hw_version = readl_relaxed(csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(12)); + hw_version |= readl_relaxed(csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(13)) << 8; + hw_version |= readl_relaxed(csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(14)) << 16; + hw_version |= readl_relaxed(csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(15)) << 24; + + dev_err(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version); +} + +/* + * csiphy_reset - Perform software reset on CSIPHY module + * @csiphy: CSIPHY device + */ +static void csiphy_reset(struct csiphy_device *csiphy) +{ + writel_relaxed(0x1, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0)); + usleep_range(5000, 8000); + writel_relaxed(0x0, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0)); +} + +static irqreturn_t csiphy_isr(int irq, void *dev) +{ + struct csiphy_device *csiphy = dev; + int i; + + for (i = 0; i < 11; i++) { + int c = i + 22; + u8 val = readl_relaxed(csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMO
[PATCH v4 29/34] media: camss: csid: Different format support on source pad
Usually the format on the source pad is the same as on the sink pad. However the CSID is able to do some format conversions. To support this make the format on the source pad selectable amongst a list of formats. This list can be different for each sink pad format. This is still not used but will be when the format conversions are implemented. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 69 +- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index db960da..cf543fa 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -300,6 +300,47 @@ static const struct csid_format csid_formats_8x96[] = { } }; +static u32 csid_find_code(u32 *code, unsigned int n_code, + unsigned int index, u32 req_code) +{ + int i; + + if (!req_code && (index >= n_code)) + return 0; + + for (i = 0; i < n_code; i++) + if (req_code) { + if (req_code == code[i]) + return req_code; + } else { + if (i == index) + return code[i]; + } + + return code[0]; +} + +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, +unsigned int index, u32 src_req_code) +{ + if (csid->camss->version == CAMSS_8x16) { + if (index > 0) + return 0; + + return sink_code; + } else if (csid->camss->version == CAMSS_8x96) { + switch (sink_code) { + default: + if (index > 0) + return 0; + + return sink_code; + } + } else { + return 0; + } +} + static const struct csid_format *csid_get_fmt_entry( const struct csid_format *formats, unsigned int nformat, @@ -674,15 +715,15 @@ static void csid_try_format(struct csid_device *csid, case MSM_CSID_PAD_SRC: if (csid->testgen_mode->cur.val == 0) { - /* Test generator is disabled, keep pad formats */ - /* in sync - set and return a format same as sink pad */ - struct v4l2_mbus_framefmt format; + /* Test generator is disabled, */ + /* keep pad formats in sync */ + u32 code = fmt->code; - format = *__csid_get_format(csid, cfg, - MSM_CSID_PAD_SINK, which); - *fmt = format; + *fmt = *__csid_get_format(csid, cfg, + MSM_CSID_PAD_SINK, which); + fmt->code = csid_src_pad_code(csid, fmt->code, 0, code); } else { - /* Test generator is enabled, set format on source*/ + /* Test generator is enabled, set format on source */ /* pad to allow test generator usage */ for (i = 0; i < csid->nformats; i++) @@ -716,7 +757,6 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_mbus_code_enum *code) { struct csid_device *csid = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *format; if (code->pad == MSM_CSID_PAD_SINK) { if (code->index >= csid->nformats) @@ -725,13 +765,16 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, code->code = csid->formats[code->index].code; } else { if (csid->testgen_mode->cur.val == 0) { - if (code->index > 0) - return -EINVAL; + struct v4l2_mbus_framefmt *sink_fmt; - format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SINK, - code->which); + sink_fmt = __csid_get_format(csid, cfg, +MSM_CSID_PAD_SINK, +code->which); - code->code = format->code; + code->code = csid_src_pad_code(csid, sink_fmt->code, + code->index, 0); + if (!code->code) + return -EINVAL; } else { if (code->index >= csid->nformats) return -EINVAL; -- 2.7.4
[PATCH v4 32/34] media: camss: Add support for 10-bit grayscale formats
Add support for 10-bit packed V4L2_PIX_FMT_Y10P (on 8x16 and 8x96) and unpacked V4L2_PIX_FMT_Y10 (on 8x96 only) pixel formats. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 50 +++- drivers/media/platform/qcom/camss/camss-csiphy.c | 2 + drivers/media/platform/qcom/camss/camss-ispif.c | 6 ++- drivers/media/platform/qcom/camss/camss-vfe.c| 3 ++ drivers/media/platform/qcom/camss/camss-video.c | 6 +++ 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 472884d..6e141af 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -193,7 +193,14 @@ static const struct csid_format csid_formats_8x16[] = { DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, 1, - } + }, + { + MEDIA_BUS_FMT_Y10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, }; static const struct csid_format csid_formats_8x96[] = { @@ -336,7 +343,14 @@ static const struct csid_format csid_formats_8x96[] = { DECODE_FORMAT_UNCOMPRESSED_14_BIT, 14, 1, - } + }, + { + MEDIA_BUS_FMT_Y10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, }; static u32 csid_find_code(u32 *code, unsigned int n_code, @@ -379,6 +393,16 @@ static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, return csid_find_code(src_code, ARRAY_SIZE(src_code), index, src_req_code); } + case MEDIA_BUS_FMT_Y10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + index, src_req_code); + } default: if (index > 0) return 0; @@ -689,15 +713,21 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) val |= CAMSS_CSID_CID_n_CFG_RDI_EN; val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; - if (csid->camss->version == CAMSS_8x96 && - csid->fmt[MSM_CSID_PAD_SINK].code == - MEDIA_BUS_FMT_SBGGR10_1X10 && - csid->fmt[MSM_CSID_PAD_SRC].code == - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { - val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING; - val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16; - val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB; + + if (csid->camss->version == CAMSS_8x96) { + u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code; + u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code; + + if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 && +src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) || + (sink_code == MEDIA_BUS_FMT_Y10_1X10 && +src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) { + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB; + } } + writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(ver, cid)); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index cae3e8b..4559f3b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -45,6 +45,7 @@ static const struct csiphy_format csiphy_formats_8x16[] = { { MEDIA_BUS_FMT_SGBRG12_1X12, 12 }, { MEDIA_BUS_FMT_SGRBG12_1X12, 12 }, { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + { MEDIA_BUS_FMT_Y10_1X10, 10 }, }; static const struct csiphy_format csiphy_formats_8x96[] = { @@ -68,6 +69,7 @@ static const struct csiphy_format csiphy_formats_8x96[] = { { MEDIA_BUS_FMT_SGBRG14_1X14, 14 }, { MEDIA_BUS_FMT_SGRBG14_1X14, 14 }, { MEDIA_BUS_FMT_SRGGB1
[PATCH v4 27/34] media: camss: vfe: Different format support on source pad
Rework the format selection on the source pad. Make the format on the source pad selectable amongst a list of formats. This list can be different for each sink pad format. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-vfe.c | 172 -- 1 file changed, 135 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index c27097c..dc353d6 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -124,6 +124,131 @@ static u8 vfe_get_bpp(const struct vfe_format *formats, return formats[0].bpp; } +static u32 vfe_find_code(u32 *code, unsigned int n_code, +unsigned int index, u32 req_code) +{ + int i; + + if (!req_code && (index >= n_code)) + return 0; + + for (i = 0; i < n_code; i++) + if (req_code) { + if (req_code == code[i]) + return req_code; + } else { + if (i == index) + return code[i]; + } + + return code[0]; +} + +static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, + unsigned int index, u32 src_req_code) +{ + struct vfe_device *vfe = to_vfe(line); + + if (vfe->camss->version == CAMSS_8x16) + switch (sink_code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_YVYU8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_YVYU8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_UYVY8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_VYUY8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_VYUY8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + default: + if (index > 0) + return 0; + + return sink_code; + } + else if (vfe->camss->version == CAMSS_8x96) + switch (sink_code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_YVYU8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_YVYU8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_UYVY8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1_5X8, + }; + + return vfe_find_code(src_code, ARRAY_SIZE(src_code), +index, src_req_code); + } + case MEDIA_BUS_FMT_VYUY8_2X8: + { + u32 src_code[] = { + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_VYUY8_1_5X8, + }; + + return vfe_find_code(
[PATCH v4 15/34] media: dt-bindings: media: qcom,camss: Fix whitespaces
Use tabs. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov Reviewed-by: Rob Herring --- .../devicetree/bindings/media/qcom,camss.txt | 92 +++--- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt index 032e8ed..e938eb0 100644 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -53,25 +53,25 @@ Qualcomm Camera Subsystem Usage: required Value type: Definition: Should contain the following entries: -- "top_ahb" -- "ispif_ahb" -- "csiphy0_timer" -- "csiphy1_timer" -- "csi0_ahb" -- "csi0" -- "csi0_phy" -- "csi0_pix" -- "csi0_rdi" -- "csi1_ahb" -- "csi1" -- "csi1_phy" -- "csi1_pix" -- "csi1_rdi" -- "ahb" -- "vfe0" -- "csi_vfe0" -- "vfe_ahb" -- "vfe_axi" + - "top_ahb" + - "ispif_ahb" + - "csiphy0_timer" + - "csiphy1_timer" + - "csi0_ahb" + - "csi0" + - "csi0_phy" + - "csi0_pix" + - "csi0_rdi" + - "csi1_ahb" + - "csi1" + - "csi1_phy" + - "csi1_pix" + - "csi1_rdi" + - "ahb" + - "vfe0" + - "csi_vfe0" + - "vfe_ahb" + - "vfe_axi" - vdda-supply: Usage: required Value type: @@ -95,17 +95,17 @@ Qualcomm Camera Subsystem - clock-lanes: Usage: required Value type: -Definition: The physical clock lane index. The value -must always be <1> as the physical clock -lane is lane 1. + Definition: The physical clock lane index. The value + must always be <1> as the physical clock + lane is lane 1. - data-lanes: Usage: required Value type: -Definition: An array of physical data lanes indexes. -Position of an entry determines the logical -lane number, while the value of an entry -indicates physical lane index. Lane swapping -is supported. + Definition: An array of physical data lanes indexes. + Position of an entry determines the logical + lane number, while the value of an entry + indicates physical lane index. Lane swapping + is supported. * An Example @@ -161,25 +161,25 @@ Qualcomm Camera Subsystem <&gcc GCC_CAMSS_CSI_VFE0_CLK>, <&gcc GCC_CAMSS_VFE_AHB_CLK>, <&gcc GCC_CAMSS_VFE_AXI_CLK>; -clock-names = "top_ahb", -"ispif_ahb", -"csiphy0_timer", -"csiphy1_timer", -"csi0_ahb", -"csi0", -"csi0_phy", -"csi0_pix", -"csi0_rdi", -"csi1_ahb", -"csi1", -"csi1_phy", -"csi1_pix", -"csi1_rdi", -"ahb", -"vfe0", -"csi_vfe0", -"vfe_ahb", -"vfe_axi"; + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + &qu
[PATCH v4 19/34] media: camss: csiphy: Split to hardware dependent and independent parts
This will allow to add support for different hardware. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/Makefile | 1 + .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 173 + drivers/media/platform/qcom/camss/camss-csiphy.c | 171 +++- drivers/media/platform/qcom/camss/camss-csiphy.h | 17 ++ 4 files changed, 214 insertions(+), 148 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 3c4024f..0446b24 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -3,6 +3,7 @@ qcom-camss-objs += \ camss.o \ camss-csid.o \ + camss-csiphy-2ph-1-0.o \ camss-csiphy.o \ camss-ispif.o \ camss-vfe.o \ diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c new file mode 100644 index 000..7325906 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-csiphy-2ph-1-0.c + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module 2phase v1.0 + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016-2018 Linaro Ltd. + */ + +#include "camss-csiphy.h" + +#include +#include + +#define CAMSS_CSI_PHY_LNn_CFG2(n) (0x004 + 0x40 * (n)) +#define CAMSS_CSI_PHY_LNn_CFG3(n) (0x008 + 0x40 * (n)) +#define CAMSS_CSI_PHY_GLBL_RESET 0x140 +#define CAMSS_CSI_PHY_GLBL_PWR_CFG 0x144 +#define CAMSS_CSI_PHY_GLBL_IRQ_CMD 0x164 +#define CAMSS_CSI_PHY_HW_VERSION 0x188 +#define CAMSS_CSI_PHY_INTERRUPT_STATUSn(n) (0x18c + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_MASKn(n) (0x1ac + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_CLEARn(n) (0x1cc + 0x4 * (n)) +#define CAMSS_CSI_PHY_GLBL_T_INIT_CFG0 0x1ec +#define CAMSS_CSI_PHY_T_WAKEUP_CFG00x1f4 + +static void csiphy_hw_version_read(struct csiphy_device *csiphy, + struct device *dev) +{ + u8 hw_version = readl_relaxed(csiphy->base + + CAMSS_CSI_PHY_HW_VERSION); + + dev_dbg(dev, "CSIPHY HW Version = 0x%02x\n", hw_version); +} + +/* + * csiphy_reset - Perform software reset on CSIPHY module + * @csiphy: CSIPHY device + */ +static void csiphy_reset(struct csiphy_device *csiphy) +{ + writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); + usleep_range(5000, 8000); + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); +} + +/* + * csiphy_settle_cnt_calc - Calculate settle count value + * + * Helper function to calculate settle count value. This is + * based on the CSI2 T_hs_settle parameter which in turn + * is calculated based on the CSI2 transmitter pixel clock + * frequency. + * + * Return settle count value or 0 if the CSI2 pixel clock + * frequency is not available + */ +static u8 csiphy_settle_cnt_calc(u32 pixel_clock, u8 bpp, u8 num_lanes, +u32 timer_clk_rate) +{ + u32 mipi_clock; /* Hz */ + u32 ui; /* ps */ + u32 timer_period; /* ps */ + u32 t_hs_prepare_max; /* ps */ + u32 t_hs_prepare_zero_min; /* ps */ + u32 t_hs_settle; /* ps */ + u8 settle_cnt; + + mipi_clock = pixel_clock * bpp / (2 * num_lanes); + ui = div_u64(1LL, mipi_clock); + ui /= 2; + t_hs_prepare_max = 85000 + 6 * ui; + t_hs_prepare_zero_min = 145000 + 10 * ui; + t_hs_settle = (t_hs_prepare_max + t_hs_prepare_zero_min) / 2; + + timer_period = div_u64(1LL, timer_clk_rate); + settle_cnt = t_hs_settle / timer_period - 1; + + return settle_cnt; +} + +static void csiphy_lanes_enable(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + u32 pixel_clock, u8 bpp, u8 lane_mask) +{ + struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; + u8 settle_cnt; + u8 val; + int i = 0; + + settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data, + csiphy->timer_clk_rate); + + writel_relaxed(0x1, csiphy->base + + CAMSS_CSI_PHY_GLBL_T_INIT_CFG0); + writel_relaxed(0x1, csiphy->base + + CAMSS_CSI_PHY_T_WAKEUP_CFG0); + + val = 0x1; + val |= lane_mask << 1; + writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_PWR_CFG); + + val = cfg->combo_mode << 4; + writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_R
[PATCH v4 30/34] media: camss: csid: MIPI10 to Plain16 format conversion
Use the PRDI mode on 8x96 to allow to configure RAW MIPI10 to Plain16 format conversion. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 33 - drivers/media/platform/qcom/camss/camss-ispif.c | 64 + drivers/media/platform/qcom/camss/camss-vfe.c | 1 + drivers/media/platform/qcom/camss/camss-video.c | 2 + 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index cf543fa..0715a8e 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -32,6 +32,15 @@ (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n)) #define CAMSS_CSID_CID_n_CFG(v, n) \ (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0) +#define CAMSS_CSID_CID_n_CFG_RDI_ENBIT(1) +#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4 +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8(0 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING(1 << 10) #define CAMSS_CSID_IRQ_CLEAR_CMD(v)((v) == CAMSS_8x16 ? 0x060 : 0x064) #define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068) #define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c) @@ -330,6 +339,16 @@ static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, return sink_code; } else if (csid->camss->version == CAMSS_8x96) { switch (sink_code) { + case MEDIA_BUS_FMT_SBGGR10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + index, src_req_code); + } default: if (index > 0) return 0; @@ -636,7 +655,19 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(ver, vc)); - val = (df << 4) | 0x3; + val = CAMSS_CSID_CID_n_CFG_ISPIF_EN; + val |= CAMSS_CSID_CID_n_CFG_RDI_EN; + val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; + if (csid->camss->version == CAMSS_8x96 && + csid->fmt[MSM_CSID_PAD_SINK].code == + MEDIA_BUS_FMT_SBGGR10_1X10 && + csid->fmt[MSM_CSID_PAD_SRC].code == + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB; + } writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(ver, cid)); diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 146d5d2..81d6351 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -76,6 +76,13 @@ (0x254 + 0x200 * (m) + 0x4 * (n)) #define ISPIF_VFE_m_RDI_INTF_n_CID_MASK(m, n) \ (0x264 + 0x200 * (m) + 0x4 * (n)) +/* PACK_CFG registers are 8x96 only */ +#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(m, n)\ + (0x270 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(m, n)\ + (0x27c + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0_CID_c_PLAIN(c) \ + (1 << ((cid % 8) * 4)) #define ISPIF_VFE_m_PIX_INTF_n_STATUS(m, n)\ (0x2c0 + 0x200 * (m) + 0x4 * (n)) #define ISPIF_VFE_m_RDI_INTF_n_STATUS(m, n)\ @@ -128,6 +135,7 @@ static const u32 ispif_formats_8x96[] = { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, MEDIA_BUS_FMT_SBGGR12_1X12,
[PATCH v4 22/34] media: camss: csid: Add support for 8x96
CSID hardware modules on 8x16 and 8x96 are similar. There is no need to duplicate the code by adding separate versions. Just update the register macros to return the correct register addresses. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 60 -- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 3ba087f..915835e 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -27,21 +27,26 @@ #define CAMSS_CSID_HW_VERSION 0x0 #define CAMSS_CSID_CORE_CTRL_0 0x004 #define CAMSS_CSID_CORE_CTRL_1 0x008 -#define CAMSS_CSID_RST_CMD 0x00c -#define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n)) -#define CAMSS_CSID_CID_n_CFG(n)(0x020 + 0x4 * (n)) -#define CAMSS_CSID_IRQ_CLEAR_CMD 0x060 -#define CAMSS_CSID_IRQ_MASK0x064 -#define CAMSS_CSID_IRQ_STATUS 0x068 -#define CAMSS_CSID_TG_CTRL 0x0a0 +#define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010) +#define CAMSS_CSID_CID_LUT_VC_n(v, n) \ + (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG(v, n) \ + (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n)) +#define CAMSS_CSID_IRQ_CLEAR_CMD(v)((v) == CAMSS_8x16 ? 0x060 : 0x064) +#define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068) +#define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c) +#define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8) #define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436 #define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437 -#define CAMSS_CSID_TG_VC_CFG 0x0a4 +#define CAMSS_CSID_TG_VC_CFG(v)((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac) #define CAMSS_CSID_TG_VC_CFG_H_BLANKING0x3ff #define CAMSS_CSID_TG_VC_CFG_V_BLANKING0x7f -#define CAMSS_CSID_TG_DT_n_CGG_0(n)(0x0ac + 0xc * (n)) -#define CAMSS_CSID_TG_DT_n_CGG_1(n)(0x0b0 + 0xc * (n)) -#define CAMSS_CSID_TG_DT_n_CGG_2(n)(0x0b4 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \ + (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \ + (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \ + (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n)) #define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 #define DATA_TYPE_YUV422_8BIT 0x1e @@ -203,10 +208,11 @@ static const struct csid_fmts *csid_get_fmt_entry(u32 code) static irqreturn_t csid_isr(int irq, void *dev) { struct csid_device *csid = dev; + enum camss_version ver = csid->camss->version; u32 value; - value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS); - writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD); + value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver)); + writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver)); if ((value >> 11) & 0x1) complete(&csid->reset_complete); @@ -289,7 +295,8 @@ static int csid_reset(struct csid_device *csid) reinit_completion(&csid->reset_complete); - writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD); + writel_relaxed(0x7fff, csid->base + + CAMSS_CSID_RST_CMD(csid->camss->version)); time = wait_for_completion_timeout(&csid->reset_complete, msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); @@ -377,6 +384,7 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) { struct csid_device *csid = v4l2_get_subdevdata(sd); struct csid_testgen_config *tg = &csid->testgen; + enum camss_version ver = csid->camss->version; u32 val; if (enable) { @@ -409,13 +417,14 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) /* 1:0 VC */ val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) | ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13); - writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG); + writel_relaxed(val, csid->base + + CAMSS_CSID_TG_VC_CFG(ver)); /* 28:16 bytes per lines, 12:0 num of lines */ val = ((num_bytes_per_line & 0x1fff) << 16) | (num_lines & 0x1fff); writel_relaxed(val, csid->base + - CAMSS_CSID_TG_DT_n_CGG_0(0)); +
[PATCH v4 12/34] media: camss: vfe: Fix to_vfe() macro member name
Use the member name which is "line" instead of the pointer argument. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-vfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 256dc2d..51ad3f8 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -30,7 +30,7 @@ ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)])) #define to_vfe(ptr_line) \ - container_of(vfe_line_array(ptr_line), struct vfe_device, ptr_line) + container_of(vfe_line_array(ptr_line), struct vfe_device, line) #define VFE_0_HW_VERSION 0x000 -- 2.7.4
[PATCH v4 23/34] media: camss: ispif: Add support for 8x96
ISPIF hardware modules on 8x16 and 8x96 are similar. However on 8x96 the ISPIF routes data to two VFE hardware modules. Add separate interrupt handler for 8x96 to handle the additional interrupts. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-ispif.c | 76 - 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 2c6c0d2..ae80732 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -116,13 +116,77 @@ static const u32 ispif_formats[] = { }; /* - * ispif_isr - ISPIF module interrupt handler + * ispif_isr_8x96 - ISPIF module interrupt handler for 8x96 * @irq: Interrupt line * @dev: ISPIF device * * Return IRQ_HANDLED on success */ -static irqreturn_t ispif_isr(int irq, void *dev) +static irqreturn_t ispif_isr_8x96(int irq, void *dev) +{ + struct ispif_device *ispif = dev; + u32 value0, value1, value2, value3, value4, value5; + + value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); + value1 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(0)); + value2 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(0)); + value3 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(1)); + value4 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(1)); + value5 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(1)); + + writel_relaxed(value0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(0)); + writel_relaxed(value1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(0)); + writel_relaxed(value2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(0)); + writel_relaxed(value3, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(1)); + writel_relaxed(value4, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(1)); + writel_relaxed(value5, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(1)); + + writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); + + if ((value0 >> 27) & 0x1) + complete(&ispif->reset_complete); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); + + if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); + + if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 pix0 overflow\n"); + + if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi0 overflow\n"); + + if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 pix1 overflow\n"); + + if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi1 overflow\n"); + + if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE1 rdi2 overflow\n"); + + return IRQ_HANDLED; +} + +/* + * ispif_isr_8x16 - ISPIF module interrupt handler for 8x16 + * @irq: Interrupt line + * @dev: ISPIF device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t ispif_isr_8x16(int irq, void *dev) { struct ispif_device *ispif = dev; u32 value0, value1, value2; @@ -959,8 +1023,14 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ispif->irq = r->start; snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", dev_name(dev), MSM_ISPIF_NAME); - ret = devm_request_irq(dev, ispif->irq, ispif_isr, + if (to_camss(ispif)->version == CAMSS_8x16) + ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16, IRQF_TRIGGER_RISING, ispif->irq_name, ispif); + else if (to_camss(ispif)->version == CAMSS_8x96) + ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96, + IRQF_TRIGGER_RISING, ispif->irq_name, ispif); + else + ret = -EINVAL; if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); return ret; -- 2.7.4
[PATCH v4 00/34] Qualcomm Camera Subsystem driver - 8x96 support
4) Link: 0x02f1 (msm_csid2 to interface /dev/v4l-subdev5) Link: 0x02f3 (msm_csid3 to interface /dev/v4l-subdev6) Link: 0x02f5 (msm_ispif0 to interface /dev/v4l-subdev7) Link: 0x02f7 (msm_ispif1 to interface /dev/v4l-subdev8) Link: 0x02f9 (msm_ispif2 to interface /dev/v4l-subdev9) Link: 0x02fb (msm_ispif3 to interface /dev/v4l-subdev10) Link: 0x02fd (msm_vfe0_rdi0 to interface /dev/v4l-subdev11) Link: 0x02ff (msm_vfe0_rdi1 to interface /dev/v4l-subdev12) Link: 0x02000101 (msm_vfe0_rdi2 to interface /dev/v4l-subdev13) Link: 0x02000103 (msm_vfe0_pix to interface /dev/v4l-subdev14) Link: 0x02000105 (msm_vfe1_rdi0 to interface /dev/v4l-subdev15) Link: 0x02000107 (msm_vfe1_rdi1 to interface /dev/v4l-subdev16) Link: 0x02000109 (msm_vfe1_rdi2 to interface /dev/v4l-subdev17) Link: 0x0200010b (msm_vfe1_pix to interface /dev/v4l-subdev18) Link: 0x0200010d (ov5645 3-0039 to interface /dev/v4l-subdev19) test MEDIA_IOC_G_TOPOLOGY: OK Entities: 28 Interfaces: 28 Pads: 47 Links: 97 Entity: 0x0001 (Name: 'msm_csiphy0', Type: V4L2 I/O, DevPath: /dev/v4l-subdev0) Entity: 0x0004 (Name: 'msm_csiphy1', Type: V4L2 I/O, DevPath: /dev/v4l-subdev1) Entity: 0x0007 (Name: 'msm_csiphy2', Type: V4L2 I/O, DevPath: /dev/v4l-subdev2) Entity: 0x000a (Name: 'msm_csid0', Type: V4L2 I/O, DevPath: /dev/v4l-subdev3) Entity: 0x000d (Name: 'msm_csid1', Type: V4L2 I/O, DevPath: /dev/v4l-subdev4) Entity: 0x0010 (Name: 'msm_csid2', Type: V4L2 I/O, DevPath: /dev/v4l-subdev5) Entity: 0x0013 (Name: 'msm_csid3', Type: V4L2 I/O, DevPath: /dev/v4l-subdev6) Entity: 0x0016 (Name: 'msm_ispif0', Type: V4L2 I/O, DevPath: /dev/v4l-subdev7) Entity: 0x0019 (Name: 'msm_ispif1', Type: V4L2 I/O, DevPath: /dev/v4l-subdev8) Entity: 0x001c (Name: 'msm_ispif2', Type: V4L2 I/O, DevPath: /dev/v4l-subdev9) Entity: 0x001f (Name: 'msm_ispif3', Type: V4L2 I/O, DevPath: /dev/v4l-subdev10) Entity: 0x0022 (Name: 'msm_vfe0_rdi0', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev11) Entity: 0x0025 (Name: 'msm_vfe0_video0', Type: V4L2 I/O, DevPath: /dev/video0) Entity: 0x002b (Name: 'msm_vfe0_rdi1', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev12) Entity: 0x002e (Name: 'msm_vfe0_video1', Type: V4L2 I/O, DevPath: /dev/video1) Entity: 0x0034 (Name: 'msm_vfe0_rdi2', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev13) Entity: 0x0037 (Name: 'msm_vfe0_video2', Type: V4L2 I/O, DevPath: /dev/video2) Entity: 0x003d (Name: 'msm_vfe0_pix', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev14) Entity: 0x0040 (Name: 'msm_vfe0_video3', Type: V4L2 I/O, DevPath: /dev/video3) Entity: 0x0046 (Name: 'msm_vfe1_rdi0', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev15) Entity: 0x0049 (Name: 'msm_vfe1_video0', Type: V4L2 I/O, DevPath: /dev/video4) Entity: 0x004f (Name: 'msm_vfe1_rdi1', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev16) Entity: 0x0052 (Name: 'msm_vfe1_video1', Type: V4L2 I/O, DevPath: /dev/video5) Entity: 0x0058 (Name: 'msm_vfe1_rdi2', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev17) Entity: 0x005b (Name: 'msm_vfe1_video2', Type: V4L2 I/O, DevPath: /dev/video6) Entity: 0x0061 (Name: 'msm_vfe1_pix', Type: Unknown V4L2 Sub-Device, DevPath: /dev/v4l-subdev18) Entity: 0x0064 (Name: 'msm_vfe1_video3', Type: V4L2 I/O, DevPath: /dev/video7) Entity: 0x00e2 (Name: 'ov5645 3-0039', Type: Camera Sensor, DevPath: /dev/v4l-subdev19) test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK test MEDIA_IOC_SETUP_LINK: OK Total: 7, Succeeded: 7, Failed: 0, Warnings: 0 Sakari Ailus (1): doc-rst: Add packed Bayer raw14 pixel formats Todor Tomov (33): media: v4l: Add new 2X8 10-bit grayscale media bus code media: v4l: Add new 10-bit packed grayscale format media: Rename CAMSS driver path media: camss: Use SPDX license headers media: camss: Fix
[PATCH v4 11/34] media: camss: csid: Configure data type and decode format properly
The CSID decodes the input data stream. When the input comes from the Test Generator the format of the stream is set on the source media pad. When the input comes from the CSIPHY the format is the one on the sink media pad. Use the proper format for each case. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index c0fef17..3cde07e 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -384,9 +384,6 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK])) return -ENOLINK; - dt = csid_get_fmt_entry(csid->fmt[MSM_CSID_PAD_SRC].code)-> - data_type; - if (tg->enabled) { /* Config Test Generator */ struct v4l2_mbus_framefmt *f = @@ -408,6 +405,9 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0)); + dt = csid_get_fmt_entry( + csid->fmt[MSM_CSID_PAD_SRC].code)->data_type; + /* 5:0 data type */ val = dt; writel_relaxed(val, csid->base + @@ -417,6 +417,9 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) val = tg->payload_mode; writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0)); + + df = csid_get_fmt_entry( + csid->fmt[MSM_CSID_PAD_SRC].code)->decode_format; } else { struct csid_phy_config *phy = &csid->phy; @@ -431,13 +434,16 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1); + + dt = csid_get_fmt_entry( + csid->fmt[MSM_CSID_PAD_SINK].code)->data_type; + df = csid_get_fmt_entry( + csid->fmt[MSM_CSID_PAD_SINK].code)->decode_format; } /* Config LUT */ dt_shift = (cid % 4) * 8; - df = csid_get_fmt_entry(csid->fmt[MSM_CSID_PAD_SINK].code)-> - decode_format; val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); val &= ~(0xff << dt_shift); -- 2.7.4
[PATCH v4 16/34] media: dt-bindings: media: qcom,camss: Add 8996 bindings
Update binding document for MSM8996. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov Reviewed-by: Rob Herring --- .../devicetree/bindings/media/qcom,camss.txt | 44 +++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt index e938eb0..09eb6ed 100644 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -5,8 +5,9 @@ Qualcomm Camera Subsystem - compatible: Usage: required Value type: - Definition: Should contain: + Definition: Should contain one of: - "qcom,msm8916-camss" + - "qcom,msm8996-camss" - reg: Usage: required Value type: @@ -19,11 +20,16 @@ Qualcomm Camera Subsystem - "csiphy0_clk_mux" - "csiphy1" - "csiphy1_clk_mux" + - "csiphy2" (8996 only) + - "csiphy2_clk_mux" (8996 only) - "csid0" - "csid1" + - "csid2" (8996 only) + - "csid3" (8996 only) - "ispif" - "csi_clk_mux" - "vfe0" + - "vfe1"(8996 only) - interrupts: Usage: required Value type: @@ -34,10 +40,14 @@ Qualcomm Camera Subsystem Definition: Should contain the following entries: - "csiphy0" - "csiphy1" + - "csiphy2" (8996 only) - "csid0" - "csid1" + - "csid2" (8996 only) + - "csid3" (8996 only) - "ispif" - "vfe0" + - "vfe1"(8996 only) - power-domains: Usage: required Value type: @@ -57,6 +67,7 @@ Qualcomm Camera Subsystem - "ispif_ahb" - "csiphy0_timer" - "csiphy1_timer" + - "csiphy2_timer" (8996 only) - "csi0_ahb" - "csi0" - "csi0_phy" @@ -67,9 +78,25 @@ Qualcomm Camera Subsystem - "csi1_phy" - "csi1_pix" - "csi1_rdi" + - "csi2_ahb"(8996 only) + - "csi2"(8996 only) + - "csi2_phy"(8996 only) + - "csi2_pix"(8996 only) + - "csi2_rdi"(8996 only) + - "csi3_ahb"(8996 only) + - "csi3"(8996 only) + - "csi3_phy"(8996 only) + - "csi3_pix"(8996 only) + - "csi3_rdi"(8996 only) - "ahb" - "vfe0" - "csi_vfe0" + - "vfe0_ahb", (8996 only) + - "vfe0_stream",(8996 only) + - "vfe1", (8996 only) + - "csi_vfe1", (8996 only) + - "vfe1_ahb", (8996 only) + - "vfe1_stream",(8996 only) - "vfe_ahb" - "vfe_axi" - vdda-supply: @@ -90,14 +117,18 @@ Qualcomm Camera Subsystem - reg: Usage: required Value type: - Definition: Selects CSI2 PHY interface - PHY0 or PHY1. + Definition: Selects CSI2 PHY interface - PHY0, PHY1 + or PHY2 (8996 only) Endpoint node properties: - clock-lanes: Usage: required Value type: - Definition: The physical clock lane index. The value - must always be <1> as the physical clock - lane is lane 1. + Definition: The physical clock lane index. On 8916 + the value must always be <1> as the physical + clock lane is lane 1. On 8996 the value must + always be <7> a
[PATCH v4 20/34] media: camss: csiphy: Unify lane handling
Restructure lane configuration so it is simpler and will allow similar (although not the same) handling for different hardware versions. Signed-off-by: Todor Tomov --- .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 48 -- drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +- drivers/media/platform/qcom/camss/camss-csiphy.h | 3 +- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c index 7325906..5f499be 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c @@ -86,7 +86,7 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, { struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; u8 settle_cnt; - u8 val; + u8 val, l = 0; int i = 0; settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data, @@ -104,34 +104,38 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, val = cfg->combo_mode << 4; writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); - while (lane_mask) { - if (lane_mask & 0x1) { - writel_relaxed(0x10, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG2(i)); - writel_relaxed(settle_cnt, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG3(i)); - writel_relaxed(0x3f, csiphy->base + - CAMSS_CSI_PHY_INTERRUPT_MASKn(i)); - writel_relaxed(0x3f, csiphy->base + - CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); - } - - lane_mask >>= 1; - i++; + for (i = 0; i <= c->num_data; i++) { + if (i == c->num_data) + l = c->clk.pos; + else + l = c->data[i].pos; + + writel_relaxed(0x10, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(l)); + writel_relaxed(settle_cnt, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG3(l)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_MASKn(l)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(l)); } } -static void csiphy_lanes_disable(struct csiphy_device *csiphy, u8 lane_mask) +static void csiphy_lanes_disable(struct csiphy_device *csiphy, +struct csiphy_config *cfg) { + struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; + u8 l = 0; int i = 0; - while (lane_mask) { - if (lane_mask & 0x1) - writel_relaxed(0x0, csiphy->base + - CAMSS_CSI_PHY_LNn_CFG2(i)); + for (i = 0; i <= c->num_data; i++) { + if (i == c->num_data) + l = c->clk.pos; + else + l = c->data[i].pos; - lane_mask >>= 1; - i++; + writel_relaxed(0x0, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(l)); } writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_PWR_CFG); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 8d10e85..d35eea0 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -296,9 +296,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) */ static void csiphy_stream_off(struct csiphy_device *csiphy) { - u8 lane_mask = csiphy_get_lane_mask(&csiphy->cfg.csi2->lane_cfg); - - csiphy->ops->lanes_disable(csiphy, lane_mask); + csiphy->ops->lanes_disable(csiphy, &csiphy->cfg); } diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index edad941..e3dd257 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -51,7 +51,8 @@ struct csiphy_hw_ops { void (*lanes_enable)(struct csiphy_device *csiphy, struct csiphy_config *cfg, u32 pixel_clock, u8 bpp, u8 lane_mask); - void (*lanes_disable)(struct csiphy_device *csiphy, u8 lane_mask); + void (*lanes_disable)(struct csiphy_device *csiphy, + struct csiphy_config *cfg); irqreturn_t (*isr)(int irq, void *dev); }; -- 2.7.4
[PATCH v4 08/34] media: dt-bindings: media: qcom,camss: Unify the clock names
Use more logical clock names - similar to the names in documentation. This will allow better handling of the clocks in the driver when support for more hardware versions is added - equivalent clocks on different hardware versions will have the same name. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov --- .../devicetree/bindings/media/qcom,camss.txt | 24 +++--- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt index cadeceb..032e8ed 100644 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -53,7 +53,7 @@ Qualcomm Camera Subsystem Usage: required Value type: Definition: Should contain the following entries: -- "camss_top_ahb" +- "top_ahb" - "ispif_ahb" - "csiphy0_timer" - "csiphy1_timer" @@ -67,11 +67,11 @@ Qualcomm Camera Subsystem - "csi1_phy" - "csi1_pix" - "csi1_rdi" -- "camss_ahb" -- "camss_vfe_vfe" -- "camss_csi_vfe" -- "iface" -- "bus" +- "ahb" +- "vfe0" +- "csi_vfe0" +- "vfe_ahb" +- "vfe_axi" - vdda-supply: Usage: required Value type: @@ -161,7 +161,7 @@ Qualcomm Camera Subsystem <&gcc GCC_CAMSS_CSI_VFE0_CLK>, <&gcc GCC_CAMSS_VFE_AHB_CLK>, <&gcc GCC_CAMSS_VFE_AXI_CLK>; -clock-names = "camss_top_ahb", +clock-names = "top_ahb", "ispif_ahb", "csiphy0_timer", "csiphy1_timer", @@ -175,11 +175,11 @@ Qualcomm Camera Subsystem "csi1_phy", "csi1_pix", "csi1_rdi", -"camss_ahb", -"camss_vfe_vfe", -"camss_csi_vfe", -"iface", -"bus"; +"ahb", +"vfe0", +"csi_vfe0", +"vfe_ahb", +"vfe_axi"; vdda-supply = <&pm8916_l2>; iommus = <&apps_iommu 3>; ports { -- 2.7.4
[PATCH v4 14/34] media: camss: vfe: Do not disable CAMIF when clearing its status
Use "no change" value when clearing CAMIF status and make sure this is done before configuring the new command. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-vfe.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 77167f1..15a1a01 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -156,6 +156,7 @@ #define VFE_0_CAMIF_CMD0x2f4 #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0 #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1 +#define VFE_0_CAMIF_CMD_NO_CHANGE 3 #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS (1 << 2) #define VFE_0_CAMIF_CFG0x2f8 #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN (1 << 6) @@ -1021,8 +1022,10 @@ static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line) static void vfe_set_camif_cmd(struct vfe_device *vfe, u32 cmd) { - writel_relaxed(VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS, + writel_relaxed(VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | + VFE_0_CAMIF_CMD_NO_CHANGE, vfe->base + VFE_0_CAMIF_CMD); + wmb(); writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); } -- 2.7.4
[PATCH v4 05/34] media: camss: Use SPDX license headers
Use SPDX license headers for all files of the Qualcomm CAMSS driver. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csid.c | 10 +- drivers/media/platform/qcom/camss/camss-csid.h | 10 +- drivers/media/platform/qcom/camss/camss-csiphy.c | 10 +- drivers/media/platform/qcom/camss/camss-csiphy.h | 10 +- drivers/media/platform/qcom/camss/camss-ispif.c | 10 +- drivers/media/platform/qcom/camss/camss-ispif.h | 10 +- drivers/media/platform/qcom/camss/camss-vfe.c| 10 +- drivers/media/platform/qcom/camss/camss-vfe.h| 10 +- drivers/media/platform/qcom/camss/camss-video.c | 10 +- drivers/media/platform/qcom/camss/camss-video.h | 10 +- drivers/media/platform/qcom/camss/camss.c| 10 +- drivers/media/platform/qcom/camss/camss.h| 10 +- 12 files changed, 12 insertions(+), 108 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 39ea27b..c0fef17 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * camss-csid.c * @@ -5,15 +6,6 @@ * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2018 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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. */ #include #include diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index 801..ae1d045 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * camss-csid.h * @@ -5,15 +6,6 @@ * * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2018 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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. */ #ifndef QC_MSM_CAMSS_CSID_H #define QC_MSM_CAMSS_CSID_H diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 642de25..b37e691 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * camss-csiphy.c * @@ -5,15 +6,6 @@ * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2016-2018 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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. */ #include #include diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 9a42209..76fa239 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * camss-csiphy.h * @@ -5,15 +6,6 @@ * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2016-2018 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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. */ #ifndef QC_MSM_CAMSS_CSIPHY_H #define QC_MSM_CAMSS_CSIPHY_H diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 636d5e7..5ad719d 100644
[PATCH v4 07/34] media: camss: csiphy: Ensure clock mux config is done before the rest
Add a write memory barier after clock mux config and before the rest of the csiphy config. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csiphy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index b37e691..2a9adcd 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -364,6 +364,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) val |= cfg->csid_id; } writel_relaxed(val, csiphy->base_clk_mux); + wmb(); writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_T_INIT_CFG0); -- 2.7.4
[PATCH v4 04/34] media: Rename CAMSS driver path
Support for camera subsystem on QComm MSM8996/APQ8096 is to be added so remove hardware version from CAMSS driver's path. Signed-off-by: Todor Tomov --- MAINTAINERS | 2 +- drivers/media/platform/Kconfig | 2 +- drivers/media/platform/Makefile | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/Makefile | 0 drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csid.c | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csid.h | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csiphy.c | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csiphy.h | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-ispif.c | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-ispif.h | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-vfe.c| 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-vfe.h| 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-video.c | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss-video.h | 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss.c| 2 +- drivers/media/platform/qcom/{camss-8x16 => camss}/camss.h| 2 +- 16 files changed, 15 insertions(+), 15 deletions(-) rename drivers/media/platform/qcom/{camss-8x16 => camss}/Makefile (100%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csid.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csid.h (98%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csiphy.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-csiphy.h (97%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-ispif.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-ispif.h (98%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-vfe.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-vfe.h (98%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-video.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss-video.h (98%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss.c (99%) rename drivers/media/platform/qcom/{camss-8x16 => camss}/camss.h (98%) diff --git a/MAINTAINERS b/MAINTAINERS index 329d428..f8b3a1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11918,7 +11918,7 @@ L: linux-me...@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/media/qcom,camss.txt F: Documentation/media/v4l-drivers/qcom_camss.rst -F: drivers/media/platform/qcom/camss-8x16/ +F: drivers/media/platform/qcom/camss/ QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096 M: Ilia Lin diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 1cf4011..2bb88d3 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -90,7 +90,7 @@ config VIDEO_PXA27x This is a v4l2 driver for the PXA27x Quick Capture Interface config VIDEO_QCOM_CAMSS - tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver" + tristate "Qualcomm V4L2 Camera Subsystem driver" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST select VIDEOBUF2_DMA_SG diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 890f919..fac3a89 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -88,7 +88,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/ -obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/ +obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ diff --git a/drivers/media/platform/qcom/camss-8x16/Makefile b/drivers/media/platform/qcom/camss/Makefile similarity index 100% rename from drivers/media/platform/qcom/camss-8x16/Makefile rename to drivers/media/platform/qcom/camss/Makefile diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c similarity index 99% rename from drivers/media/platform/qcom/camss-8x16/camss-csid.c rename to drivers/media/platform/qcom/camss/camss-csid.c index 226f36e..39ea27b 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -4,7 +4,7 @@ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. - * Copyright (C) 2015-2017 Linaro Ltd. + * Copyright (C) 2015-2018 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General
[PATCH v4 06/34] media: camss: Fix OF node usage
of_graph_get_next_endpoint increases the refcount of the returned node and decreases the refcount of the passed node. Take this into account and use of_node_put properly. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 45285eb..abf6184 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -296,6 +296,7 @@ static int camss_of_parse_ports(struct device *dev, if (of_device_is_available(node)) notifier->num_subdevs++; + of_node_put(node); size = sizeof(*notifier->subdevs) * notifier->num_subdevs; notifier->subdevs = devm_kzalloc(dev, size, GFP_KERNEL); if (!notifier->subdevs) { @@ -326,16 +327,16 @@ static int camss_of_parse_ports(struct device *dev, } remote = of_graph_get_remote_port_parent(node); - of_node_put(node); - if (!remote) { dev_err(dev, "Cannot get remote parent\n"); + of_node_put(node); return -EINVAL; } csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; csd->asd.match.fwnode = of_fwnode_handle(remote); } + of_node_put(node); return notifier->num_subdevs; } -- 2.7.4
[PATCH v4 10/34] media: camss: csiphy: Update settle count calculation
Update settle count calculation as per specification. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss-csiphy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 2a9adcd..6158ffd 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -329,7 +329,7 @@ static u8 csiphy_settle_cnt_calc(struct csiphy_device *csiphy) t_hs_settle = (t_hs_prepare_max + t_hs_prepare_zero_min) / 2; timer_period = div_u64(1LL, csiphy->timer_clk_rate); - settle_cnt = t_hs_settle / timer_period; + settle_cnt = t_hs_settle / timer_period - 1; return settle_cnt; } -- 2.7.4
[PATCH v4 09/34] media: camss: Unify the clock names
Use more logical clock names - similar to the names in documentation. This will allow better handling of the clocks in the driver when support for more hardware versions is added - equivalent clocks on different hardware versions will have the same name. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss/camss.c | 20 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index abf6184..0b663e0 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -32,8 +32,7 @@ static const struct resources csiphy_res[] = { /* CSIPHY0 */ { .regulator = { NULL }, - .clock = { "camss_top_ahb", "ispif_ahb", - "camss_ahb", "csiphy0_timer" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, @@ -45,8 +44,7 @@ static const struct resources csiphy_res[] = { /* CSIPHY1 */ { .regulator = { NULL }, - .clock = { "camss_top_ahb", "ispif_ahb", - "camss_ahb", "csiphy1_timer" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, .clock_rate = { { 0 }, { 0 }, { 0 }, @@ -60,8 +58,7 @@ static const struct resources csid_res[] = { /* CSID0 */ { .regulator = { "vdda" }, - .clock = { "camss_top_ahb", "ispif_ahb", - "csi0_ahb", "camss_ahb", + .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, .clock_rate = { { 0 }, { 0 }, @@ -78,8 +75,7 @@ static const struct resources csid_res[] = { /* CSID1 */ { .regulator = { "vdda" }, - .clock = { "camss_top_ahb", "ispif_ahb", - "csi1_ahb", "camss_ahb", + .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, .clock_rate = { { 0 }, { 0 }, @@ -96,10 +92,10 @@ static const struct resources csid_res[] = { static const struct resources_ispif ispif_res = { /* ISPIF */ - .clock = { "camss_top_ahb", "camss_ahb", "ispif_ahb", + .clock = { "top_ahb", "ahb", "ispif_ahb", "csi0", "csi0_pix", "csi0_rdi", "csi1", "csi1_pix", "csi1_rdi" }, - .clock_for_reset = { "camss_vfe_vfe", "camss_csi_vfe" }, + .clock_for_reset = { "vfe0", "csi_vfe0" }, .reg = { "ispif", "csi_clk_mux" }, .interrupt = "ispif" @@ -108,8 +104,8 @@ static const struct resources_ispif ispif_res = { static const struct resources vfe_res = { /* VFE0 */ .regulator = { NULL }, - .clock = { "camss_top_ahb", "camss_vfe_vfe", "camss_csi_vfe", - "iface", "bus", "camss_ahb" }, + .clock = { "top_ahb", "vfe0", "csi_vfe0", + "vfe_ahb", "vfe_axi", "ahb" }, .clock_rate = { { 0 }, { 5000, 8000, 1, 16000, 17778, 2, 26667, 32000, -- 2.7.4
[PATCH v4 03/34] media: v4l: Add new 10-bit packed grayscale format
The new format will be called V4L2_PIX_FMT_Y10P. It is similar to the V4L2_PIX_FMT_SBGGR10P family formats but V4L2_PIX_FMT_Y10P is a grayscale format. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/pixfmt-y10p.rst | 33 Documentation/media/uapi/v4l/yuv-formats.rst | 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 36 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst new file mode 100644 index 000..13b5713 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst @@ -0,0 +1,33 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-Y10P: + +** +V4L2_PIX_FMT_Y10P ('Y10P') +** + +Grey-scale image as a MIPI RAW10 packed array + + +Description +=== + +This is a packed grey-scale image format with a depth of 10 bits per +pixel. Every four consecutive pixels are packed into 5 bytes. Each of +the first 4 bytes contain the 8 high order bits of the pixels, and +the 5th byte contains the 2 least significants bits of each pixel, +in the same order. + +**Bit-packed representation.** + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 +:widths: 8 8 8 8 64 + +* - Y'\ :sub:`00[9:2]` + - Y'\ :sub:`01[9:2]` + - Y'\ :sub:`02[9:2]` + - Y'\ :sub:`03[9:2]` + - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4) + Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0) diff --git a/Documentation/media/uapi/v4l/yuv-formats.rst b/Documentation/media/uapi/v4l/yuv-formats.rst index 3334ea4..9ab0592 100644 --- a/Documentation/media/uapi/v4l/yuv-formats.rst +++ b/Documentation/media/uapi/v4l/yuv-formats.rst @@ -29,6 +29,7 @@ to brightness information. pixfmt-y10 pixfmt-y12 pixfmt-y10b +pixfmt-y10p pixfmt-y16 pixfmt-y16-be pixfmt-y8i diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 04e1231..e8f7c89 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1184,6 +1184,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index a15e03b..fc177d8 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -522,6 +522,7 @@ struct v4l2_pix_format { /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ +#define V4L2_PIX_FMT_Y10Pv4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ -- 2.7.4
[PATCH v4 02/34] media: v4l: Add new 2X8 10-bit grayscale media bus code
The code will be called MEDIA_BUS_FMT_Y10_2X8_PADHI_LE. It is similar to MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE but MEDIA_BUS_FMT_Y10_2X8_PADHI_LE describes grayscale data. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/subdev-formats.rst | 72 + include/uapi/linux/media-bus-format.h | 3 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index a4739f7..8e73fcf 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -4318,6 +4318,78 @@ the following codes. - y\ :sub:`2` - y\ :sub:`1` - y\ :sub:`0` +* .. _MEDIA-BUS-FMT-Y10-2X8-PADHI_LE: + + - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE + - 0x202c + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` +* - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - y\ :sub:`9` + - y\ :sub:`8` * .. _MEDIA-BUS-FMT-UYVY10-2X10: - MEDIA_BUS_FMT_UYVY10_2X10 diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 9e35117..d6a5a3b 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -62,7 +62,7 @@ #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a -/* YUV (including grey) - next is 0x202c */ +/* YUV (including grey) - next is 0x202d */ #define MEDIA_BUS_FMT_Y8_1X8 0x2001 #define MEDIA_BUS_FMT_UV8_1X8 0x2015 #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 @@ -74,6 +74,7 @@ #define MEDIA_BUS_FMT_YUYV8_2X80x2008 #define MEDIA_BUS_FMT_YVYU8_2X80x2009 #define MEDIA_BUS_FMT_Y10_1X10 0x200a +#define MEDIA_BUS_FMT_Y10_2X8_PADHI_LE 0x202c #define MEDIA_BUS_FMT_UYVY10_2X10 0x2018 #define MEDIA_BUS_FMT_VYUY10_2X10 0x2019 #define MEDIA_BUS_FMT_YUYV10_2X10 0x200b -- 2.7.4
Re: [PATCH v3] [media] Use common error handling code in 19 functions
Hi Markus, Thank you for the patch. On 9.03.2018 22:10, SF Markus Elfring wrote: > From: Markus Elfring > Date: Fri, 9 Mar 2018 21:00:12 +0100 > > Adjust jump targets so that a bit of exception handling can be better > reused at the end of these functions. > > This issue was partly detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring > --- > > v3: > Laurent Pinchart and Todor Tomov requested a few adjustments. > Updates were rebased on source files from Linux next-20180308. > > v2: > Hans Verkuil insisted on patch squashing. Thus several changes > were recombined based on source files from Linux next-20180216. > > The implementation of the function "tda8261_set_params" was improved > after a notification by Christoph Böhmwalder on 2017-09-26. > > drivers/media/dvb-core/dmxdev.c| 16 > drivers/media/dvb-frontends/tda1004x.c | 20 ++ > drivers/media/dvb-frontends/tda8261.c | 19 ++ > drivers/media/pci/bt8xx/dst.c | 19 ++ > drivers/media/pci/bt8xx/dst_ca.c | 30 +++ > drivers/media/pci/cx88/cx88-input.c| 17 + > drivers/media/platform/omap3isp/ispvideo.c | 28 ++ > .../media/platform/qcom/camss-8x16/camss-csid.c| 19 +- > drivers/media/tuners/tuner-xc2028.c| 30 +++ > drivers/media/usb/cpia2/cpia2_usb.c| 13 --- > drivers/media/usb/gspca/gspca.c| 17 + > drivers/media/usb/gspca/sn9c20x.c | 17 + > drivers/media/usb/pvrusb2/pvrusb2-ioread.c | 10 +++-- > drivers/media/usb/tm6000/tm6000-cards.c| 7 ++-- > drivers/media/usb/tm6000/tm6000-dvb.c | 11 -- > drivers/media/usb/tm6000/tm6000-video.c| 13 --- > drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 13 +++ > drivers/media/usb/ttusb-dec/ttusb_dec.c| 43 > -- > 18 files changed, 171 insertions(+), 171 deletions(-) > > diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c > b/drivers/media/platform/qcom/camss-8x16/camss-csid.c > index 64df82817de3..5c790d8c1f80 100644 > --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c > +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c > @@ -328,16 +328,12 @@ static int csid_set_power(struct v4l2_subdev *sd, int > on) > return ret; > > ret = csid_set_clock_rates(csid); > - if (ret < 0) { > - regulator_disable(csid->vdda); > - return ret; > - } > + if (ret < 0) > + goto disable_regulator; > > ret = camss_enable_clocks(csid->nclocks, csid->clock, dev); > - if (ret < 0) { > - regulator_disable(csid->vdda); > - return ret; > - } > + if (ret < 0) > + goto disable_regulator; > > enable_irq(csid->irq); > > @@ -345,8 +341,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) > if (ret < 0) { > disable_irq(csid->irq); > camss_disable_clocks(csid->nclocks, csid->clock); > - regulator_disable(csid->vdda); > - return ret; > + goto disable_regulator; > } > > hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION); > @@ -358,6 +353,10 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) > } > > return ret; > + > +disable_regulator: > + regulator_disable(csid->vdda); > + return ret; > } > For the QComm CAMSS part of the patch: Acked-by: Todor Tomov -- Best regards, Todor Tomov
[PATCH v2 0/2] Add support for ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. -- Version 2: - changed ov7251 node's name in DT binding example; - SPDX licence identifier; - better names for register value defines; - remove power reference counting and leave a power state only; - use v4l2_find_nearest_size() to find sensor mode by requested size; - set ycbcr_enc, quantization and xfer_func in set_fmt; - use struct fwnode_handle instead of struct device_node; - add comment in driver about external clock value. ------ Todor Tomov (2): dt-bindings: media: Binding document for OV7251 camera sensor media: Add a driver for the ov7251 camera sensor .../devicetree/bindings/media/i2c/ov7251.txt | 51 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1494 4 files changed, 1559 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt create mode 100644 drivers/media/i2c/ov7251.c -- 2.7.4
[PATCH v2 0/2] Add support for ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. -- Version 2: - changed ov7251 node's name in DT binding example; - SPDX licence identifier; - better names for register value defines; - remove power reference counting and leave a power state only; - use v4l2_find_nearest_size() to find sensor mode by requested size; - set ycbcr_enc, quantization and xfer_func in set_fmt; - use struct fwnode_handle instead of struct device_node; - add comment in driver about external clock value. ------ Todor Tomov (2): dt-bindings: media: Binding document for OV7251 camera sensor media: Add a driver for the ov7251 camera sensor .../devicetree/bindings/media/i2c/ov7251.txt | 51 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1494 4 files changed, 1559 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt create mode 100644 drivers/media/i2c/ov7251.c -- 2.7.4
[PATCH v2 1/2] dt-bindings: media: Binding document for OV7251 camera sensor
Add the document for ov7251 device tree binding. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov Reviewed-by: Rob Herring --- .../devicetree/bindings/media/i2c/ov7251.txt | 51 ++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov7251.txt b/Documentation/devicetree/bindings/media/i2c/ov7251.txt new file mode 100644 index 000..4ee6888 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov7251.txt @@ -0,0 +1,51 @@ +* Omnivision 1/7.5-Inch B&W VGA CMOS Digital Image Sensor + +The Omnivision OV7251 is a 1/7.5-Inch CMOS active pixel digital image sensor with +an active array size of 640H x 480V. It is programmable through a serial I2C +interface. + +Required Properties: +- compatible: Value should be "ovti,ov7251". +- clocks: Reference to the xclk clock. +- clock-names: Should be "xclk". +- clock-frequency: Frequency of the xclk clock. +- enable-gpios: Chip enable GPIO. Polarity is GPIO_ACTIVE_HIGH. This corresponds + to the hardware pin XSHUTDOWN which is physically active low. +- vdddo-supply: Chip digital IO regulator. +- vdda-supply: Chip analog regulator. +- vddd-supply: Chip digital core regulator. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + &i2c1 { + ... + + ov7251: camera-sensor@60 { + compatible = "ovti,ov7251"; + reg = <0x60>; + + enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_bw_default>; + + clocks = <&clks 200>; + clock-names = "xclk"; + clock-frequency = <2400>; + + vdddo-supply = <&camera_dovdd_1v8>; + vdda-supply = <&camera_avdd_2v8>; + vddd-supply = <&camera_dvdd_1v2>; + + port { + ov7251_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0>; + remote-endpoint = <&csi0_ep>; + }; + }; + }; + }; -- 2.7.4
[PATCH v2 2/2] media: Add a driver for the ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. The driver supports the following modes: - 640x480 30fps - 640x480 60fps - 640x480 90fps Output format is MIPI RAW 10. The driver supports configuration via user controls for: - exposure and gain; - horizontal and vertical flip; - test pattern. Signed-off-by: Todor Tomov --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1494 3 files changed, 1508 insertions(+) create mode 100644 drivers/media/i2c/ov7251.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 541f0d28..89aecb3 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -688,6 +688,19 @@ config VIDEO_OV5695 To compile this driver as a module, choose M here: the module will be called ov5695. +config VIDEO_OV7251 + tristate "OmniVision OV7251 sensor support" + depends on OF + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV7251 camera. + + To compile this driver as a module, choose M here: the + module will be called ov7251. + config VIDEO_OV772X tristate "OmniVision OV772x sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index ea34aee..c8585b1 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o obj-$(CONFIG_VIDEO_OV5670) += ov5670.o obj-$(CONFIG_VIDEO_OV5695) += ov5695.o obj-$(CONFIG_VIDEO_OV6650) += ov6650.o +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV772X) += ov772x.o diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c new file mode 100644 index 000..7b401a9 --- /dev/null +++ b/drivers/media/i2c/ov7251.c @@ -0,0 +1,1494 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the OV7251 camera sensor. + * + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OV7251_VOLTAGE_ANALOG 280 +#define OV7251_VOLTAGE_DIGITAL_CORE 150 +#define OV7251_VOLTAGE_DIGITAL_IO 180 + +#define OV7251_SC_MODE_SELECT 0x0100 +#define OV7251_SC_MODE_SELECT_SW_STANDBY 0x0 +#define OV7251_SC_MODE_SELECT_STREAMING0x1 + +#define OV7251_CHIP_ID_HIGH0x300a +#define OV7251_CHIP_ID_HIGH_BYTE 0x77 +#define OV7251_CHIP_ID_LOW 0x300b +#define OV7251_CHIP_ID_LOW_BYTE0x50 +#define OV7251_SC_GP_IO_IN10x3029 +#define OV7251_AEC_EXPO_0 0x3500 +#define OV7251_AEC_EXPO_1 0x3501 +#define OV7251_AEC_EXPO_2 0x3502 +#define OV7251_AEC_AGC_ADJ_0 0x350a +#define OV7251_AEC_AGC_ADJ_1 0x350b +#define OV7251_TIMING_FORMAT1 0x3820 +#define OV7251_TIMING_FORMAT1_VFLIPBIT(2) +#define OV7251_TIMING_FORMAT2 0x3821 +#define OV7251_TIMING_FORMAT2_MIRROR BIT(2) +#define OV7251_PRE_ISP_00 0x5e00 +#define OV7251_PRE_ISP_00_TEST_PATTERN BIT(7) + +struct reg_value { + u16 reg; + u8 val; +}; + +struct ov7251_mode_info { + u32 width; + u32 height; + const struct reg_value *data; + u32 data_size; + u32 pixel_clock; + u32 link_freq; + u16 exposure_max; + u16 exposure_def; + struct v4l2_fract timeperframe; +}; + +struct ov7251 { + struct i2c_client *i2c_client; + struct device *dev; + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_fwnode_endpoint ep; + struct v4l2_mbus_framefmt fmt; + struct v4l2_rect crop; + struct clk *xclk; + + struct regulator *io_regulator; + struct regulator *core_regulator; + struct regulator *analog_regulator; + + const struct ov7251_mode_info *current_mode; + + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *pixel_clock; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + + /* Cached register values */ + u8 aec_pk_manual; + u8 pre_isp_00; + u8 timing_format1; + u8 timing_format2; + + struct mutex power_lock; /* lock to protect power state */ + bool power_on; + + struct gpio_desc *enable_gpio; +}; + +static inline struct ov7251 *to_ov7251(struct v4l2_subde
[PATCH 2/2] arm64: dts: qcom: msm8996: Add CAMSS support
Add a node for the Camera Subsystem present on the Qualcomm MSM8996 SoC. Signed-off-by: Todor Tomov --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 135 ++ 1 file changed, 135 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index a4d087e5..8585c61 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -967,6 +967,141 @@ status = "ok"; }; + camss: camss@a0 { + compatible = "qcom,msm8996-camss"; + reg = <0xa34000 0x1000>, + <0xa00030 0x4>, + <0xa35000 0x1000>, + <0xa00038 0x4>, + <0xa36000 0x1000>, + <0xa00040 0x4>, + <0xa3 0x100>, + <0xa30400 0x100>, + <0xa30800 0x100>, + <0xa30c00 0x100>, + <0xa31000 0x500>, + <0xa00020 0x10>, + <0xa1 0x1000>, + <0xa14000 0x1000>; + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csiphy2", + "csiphy2_clk_mux", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "csi_clk_mux", + "vfe0", + "vfe1"; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csiphy0", + "csiphy1", + "csiphy2", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "vfe0", + "vfe1"; + power-domains = <&mmcc VFE0_GDSC>; + clocks = <&mmcc CAMSS_TOP_AHB_CLK>, + <&mmcc CAMSS_ISPIF_AHB_CLK>, + <&mmcc CAMSS_CSI0PHYTIMER_CLK>, + <&mmcc CAMSS_CSI1PHYTIMER_CLK>, + <&mmcc CAMSS_CSI2PHYTIMER_CLK>, + <&mmcc CAMSS_CSI0_AHB_CLK>, + <&mmcc CAMSS_CSI0_CLK>, + <&mmcc CAMSS_CSI0PHY_CLK>, + <&mmcc CAMSS_CSI0PIX_CLK>, + <&mmcc CAMSS_CSI0RDI_CLK>, + <&mmcc CAMSS_CSI1_AHB_CLK>, + <&mmcc CAMSS_CSI1_CLK>, + <&mmcc CAMSS_CSI1PHY_CLK>, + <&mmcc CAMSS_CSI1PIX_CLK>, + <&mmcc CAMSS_CSI1RDI_CLK>, + <&mmcc CAMSS_CSI2_AHB_CLK>, + <&mmcc CAMSS_CSI2_CLK>, + <&mmcc CAMSS_CSI2PHY_CLK>, + <&mmcc CAMSS_CSI2PIX_CLK>, + <&mmcc CAMSS_CSI2RDI_CLK>, + <&mmcc CAMSS_CSI3_AHB_CLK>, + <&mmcc CAMSS_CSI3_CLK>, + <&mmcc CAMSS_CSI3PHY_CLK>, + <&mmcc CAMSS_CSI3PIX_CLK>, + <&mmcc CAMSS_CSI3RDI_CLK>, + <&mmcc CAMSS_AHB_CLK>, + <&mmcc CAMSS_VFE0_CLK>, +
[PATCH 1/2] arm64: dts: qcom: msm8996: Add VFE SMMU node
Add VFE SMMU node. Signed-off-by: Todor Tomov --- This patch depends on patchset: https://lore.kernel.org/patchwork/cover/1013166/ arch/arm64/boot/dts/qcom/msm8996.dtsi | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 13bb964..a4d087e5 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -950,6 +950,23 @@ }; }; + vfe_smmu: arm,smmu@da { + compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; + reg = <0xda 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + power-domains = <&mmcc MMAGIC_CAMSS_GDSC>; + clocks = <&mmcc SMMU_VFE_AHB_CLK>, +<&mmcc SMMU_VFE_AXI_CLK>; + clock-names = "iface", + "bus"; + #iommu-cells = <1>; + status = "ok"; + }; + agnoc@0 { power-domains = <&gcc AGGRE0_NOC_GDSC>; compatible = "simple-pm-bus"; -- 2.7.4
[PATCH 2/2] arm64: dts: qcom: Add pinctrls for camera sensors
Add pinctrls required for camera sensors: - power down signal; - reset signal; - camera external clock. Signed-off-by: Todor Tomov --- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 64 arch/arm64/boot/dts/qcom/msm8996-pins.dtsi | 96 ++ 2 files changed, 160 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 990120c..aa9a0ff 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -701,4 +701,68 @@ bias-disable; }; }; + + camera_front_default: camera_front_default { + pinmux_pwdn { + function = "gpio"; + pins = "gpio33"; + }; + pinconf_pwdn { + pins = "gpio33"; + drive-strength = <16>; + bias-disable; + }; + + pinmux_rst { + function = "gpio"; + pins = "gpio28"; + }; + pinconf_rst { + pins = "gpio28"; + drive-strength = <16>; + bias-disable; + }; + + pinmux_mclk1 { + function = "cam_mclk1"; + pins = "gpio27"; + }; + pinconf_mclk1 { + pins = "gpio27"; + drive-strength = <16>; + bias-disable; + }; + }; + + camera_rear_default: camera_rear_default { + pinmux_pwdn { + function = "gpio"; + pins = "gpio34"; + }; + pinconf_pwdn { + pins = "gpio34"; + drive-strength = <16>; + bias-disable; + }; + +pinmux_rst { + function = "gpio"; + pins = "gpio35"; + }; + pinconf_rst { + pins = "gpio35"; + drive-strength = <16>; + bias-disable; + }; + + pinmux_mclk0 { + function = "cam_mclk0"; + pins = "gpio26"; + }; + pinconf_mclk0 { + pins = "gpio26"; + drive-strength = <16>; + bias-disable; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi index d6a0a4a..8d5114d 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi @@ -519,4 +519,100 @@ bias-disable; }; }; + + camera_board_default: camera_board_default { + mux_pwdn { + function = "gpio"; + pins = "gpio98"; + }; + config_pwdn { + pins = "gpio98"; + drive-strength = <16>; + bias-disable; + }; + + mux_rst { + function = "gpio"; + pins = "gpio104"; + }; + config_rst { + pins = "gpio104"; + drive-strength = <16>; + bias-disable; + }; + + mux_mclk1 { + function = "cam_mclk"; + pins = "gpio14"; + }; + config_mclk1 { + pins = "gpio14"; + drive-strength = <16>; + bias-disable; + }; + }; + + camera_front_default: camera_front_default { + mux_pwdn { + function = "gpio"; + pins = "gpio133"; + }; + config_pwdn { + pins = "gpio133"; + drive-strength = <16>; + bias-disable; + }; + + mux_rst { + function = "gpio"; + pins = "gpio23"; + }; + config_rst { + pins = "gpio23"; + drive-strength = <16>; +
[PATCH 1/2] arm64: dts: qcom: Add Camera Control Interface pinctrls
Add pinctrls required for Camera Control Interface. Signed-off-by: Todor Tomov --- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 12 arch/arm64/boot/dts/qcom/msm8996-pins.dtsi | 24 2 files changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 390a2fa..990120c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -689,4 +689,16 @@ bias-pull-up; }; }; + + cci0_default: cci0_default { + pinmux { + function = "cci_i2c"; + pins = "gpio29", "gpio30"; + }; + pinconf { + pins = "gpio29", "gpio30"; + drive-strength = <16>; + bias-disable; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi index c5c42e9..d6a0a4a 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi @@ -495,4 +495,28 @@ bias-disable; }; }; + + cci0_default: cci0_default { + pinmux { + function = "cci_i2c"; + pins = "gpio17", "gpio18"; + }; + pinconf { + pins = "gpio17", "gpio18"; + drive-strength = <16>; + bias-disable; + }; + }; + + cci1_default: cci1_default { + pinmux { + function = "cci_i2c"; + pins = "gpio19", "gpio20"; + }; + pinconf { + pins = "gpio19", "gpio20"; + drive-strength = <16>; + bias-disable; + }; + }; }; -- 2.7.4
[PATCH 1/2] arm64: dts: qcom: msm8916: Add IOMMU sub-node for VFE context bank
Add IOMMU sub-node for VFE secure context bank. Signed-off-by: Todor Tomov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index d302d8d..da9867b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -778,6 +778,13 @@ clock-names = "iface", "bus"; qcom,iommu-secure-id = <17>; + // vfe: + iommu-ctx@3000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x3000 0x1000>; + interrupts = ; + }; + // mdp_0: iommu-ctx@4000 { compatible = "qcom,msm-iommu-v1-ns"; -- 2.7.4
[PATCH 2/2] arm64: dts: qcom: msm8916: Add CAMSS support
Add a node for the Camera Subsystem present on the Qualcomm MSM8916 SoC. Signed-off-by: Todor Tomov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 80 +++ 1 file changed, 80 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index da9867b..7f7ad86 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1396,6 +1396,86 @@ compatible = "venus-encoder"; }; }; + + camss: camss@1b0 { + compatible = "qcom,msm8916-camss"; + reg = <0x1b0ac00 0x200>, + <0x1b00030 0x4>, + <0x1b0b000 0x200>, + <0x1b00038 0x4>, + <0x1b08000 0x100>, + <0x1b08400 0x100>, + <0x1b0a000 0x500>, + <0x1b00020 0x10>, + <0x1b1 0x1000>; + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csid0", + "csid1", + "ispif", + "csi_clk_mux", + "vfe0"; + interrupts = , + , + , + , + , + ; + interrupt-names = "csiphy0", + "csiphy1", + "csid0", + "csid1", + "ispif", + "vfe0"; + power-domains = <&gcc VFE_GDSC>; + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI0_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0_CLK>, + <&gcc GCC_CAMSS_CSI0PHY_CLK>, + <&gcc GCC_CAMSS_CSI0PIX_CLK>, + <&gcc GCC_CAMSS_CSI0RDI_CLK>, + <&gcc GCC_CAMSS_CSI1_AHB_CLK>, + <&gcc GCC_CAMSS_CSI1_CLK>, + <&gcc GCC_CAMSS_CSI1PHY_CLK>, + <&gcc GCC_CAMSS_CSI1PIX_CLK>, + <&gcc GCC_CAMSS_CSI1RDI_CLK>, + <&gcc GCC_CAMSS_AHB_CLK>, + <&gcc GCC_CAMSS_VFE0_CLK>, + <&gcc GCC_CAMSS_CSI_VFE0_CLK>, + <&gcc GCC_CAMSS_VFE_AHB_CLK>, + <&gcc GCC_CAMSS_VFE_AXI_CLK>; + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "ahb", + "vfe0", + "csi_vfe0", + "vfe_ahb", + "vfe_axi"; + vdda-supply = <&pm8916_l2>; + iommus = <&apps_iommu 3>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; }; smd { -- 2.7.4
Re: [v2,2/2] media: Add a driver for the ov7251 camera sensor
Hi Jacopo, Thank you for your prompt review. On 23.03.2018 15:40, jacopo mondi wrote: > Hi Todor, >thanks for the patch. > > When running checkpatch --strict I see a few warning you can easily > close (braces indentation mostly, and one additional empty line at > line 1048). Thank you for pointing me to the --strict mode. There are a few CHECKs for braces alignment for which the alignment is still better as it is now I think. However there were also a few reasonable points and I have updated the code according to them. > > A few more nits below. > > On Fri, Mar 23, 2018 at 12:14:20PM +0800, Todor Tomov wrote: >> The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image >> Sensor from Omnivision. >> >> The driver supports the following modes: >> - 640x480 30fps >> - 640x480 60fps >> - 640x480 90fps >> >> Output format is MIPI RAW 10. >> >> The driver supports configuration via user controls for: >> - exposure and gain; >> - horizontal and vertical flip; >> - test pattern. >> >> Signed-off-by: Todor Tomov >> --- >> drivers/media/i2c/Kconfig | 13 + >> drivers/media/i2c/Makefile |1 + >> drivers/media/i2c/ov7251.c | 1494 >> >> 3 files changed, 1508 insertions(+) >> create mode 100644 drivers/media/i2c/ov7251.c >> >> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >> index 541f0d28..89aecb3 100644 >> --- a/drivers/media/i2c/Kconfig >> +++ b/drivers/media/i2c/Kconfig >> @@ -688,6 +688,19 @@ config VIDEO_OV5695 >>To compile this driver as a module, choose M here: the >>module will be called ov5695. >> >> +config VIDEO_OV7251 >> +tristate "OmniVision OV7251 sensor support" >> +depends on OF >> +depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API >> +depends on MEDIA_CAMERA_SUPPORT >> +select V4L2_FWNODE >> +---help--- >> + This is a Video4Linux2 sensor-level driver for the OmniVision >> + OV7251 camera. >> + >> + To compile this driver as a module, choose M here: the >> + module will be called ov7251. >> + >> config VIDEO_OV772X >> tristate "OmniVision OV772x sensor support" >> depends on I2C && VIDEO_V4L2 >> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile >> index ea34aee..c8585b1 100644 >> --- a/drivers/media/i2c/Makefile >> +++ b/drivers/media/i2c/Makefile >> @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o >> obj-$(CONFIG_VIDEO_OV5670) += ov5670.o >> obj-$(CONFIG_VIDEO_OV5695) += ov5695.o >> obj-$(CONFIG_VIDEO_OV6650) += ov6650.o >> +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o >> obj-$(CONFIG_VIDEO_OV7640) += ov7640.o >> obj-$(CONFIG_VIDEO_OV7670) += ov7670.o >> obj-$(CONFIG_VIDEO_OV772X) += ov772x.o >> diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c >> new file mode 100644 >> index 000..7b401a9 >> --- /dev/null >> +++ b/drivers/media/i2c/ov7251.c >> @@ -0,0 +1,1494 @@ >> +static int ov7251_s_power(struct v4l2_subdev *sd, int on) >> +{ >> +struct ov7251 *ov7251 = to_ov7251(sd); >> +int ret = 0; >> + >> +mutex_lock(&ov7251->power_lock); >> + >> +/* >> + * If the power state is modified from 0 to 1 or from 1 to 0, >> + * update the power state. >> + */ >> +if (ov7251->power_on == !on) { > > if (ov7251->power_on == !!on) { > mutex_unlock(&ov7251->power_lock); > return 0; > } > > And you can save one indentation level and remove ret initialization. > Good hint, I'd rather save one indentation level by: if (ov7251->power_on == !!on) goto exit; > >> +if (on) { >> +ret = ov7251_set_power_on(ov7251); >> +if (ret < 0) >> +goto exit; >> + >> +ret = ov7251_set_register_array(ov7251, >> +ov7251_global_init_setting, >> +ARRAY_SIZE(ov7251_global_init_setting)); >> +if (ret < 0) { >> +dev_err(ov7251->dev, >> +"could not set init registers\n"); >> +ov7251_set_power_off(ov7251); >> +goto exit; >
Re: [v2,2/2] media: Add a driver for the ov7251 camera sensor
Hi Sakari On 29.03.2018 11:29, Sakari Ailus wrote: > Hi Todor and Jacopo, > > On Thu, Mar 29, 2018 at 10:50:10AM +0300, Todor Tomov wrote: > ... >>>> +static const struct of_device_id ov7251_of_match[] = { >>>> + { .compatible = "ovti,ov7251" }, >>>> + { /* sentinel */ } >>>> +}; >>>> +MODULE_DEVICE_TABLE(of, ov7251_of_match); >>>> + >>>> +static struct i2c_driver ov7251_i2c_driver = { >>>> + .driver = { >>>> + .of_match_table = of_match_ptr(ov7251_of_match), >>>> + .name = "ov7251", >>>> + }, >>>> + .probe = ov7251_probe, >>>> + .remove = ov7251_remove, >>>> + .id_table = ov7251_id, >>> >>> As this driver depends on CONFIG_OF, I've been suggested to use probe_new >>> and >>> get rid of i2c id_tables. >> >> Yes, I'll do that. > > The proposal sounds good to me but rather than adding CONFIG_OF dependency, > I'd instead suggest changing the of_property_read_u32 to > fwnode_property_read_u32; then the driver may work on ACPI based systems as > well. Ok. > There's another change needed, too, which is not using of_match_ptr > macro, but instead assigning the of_match_table unconditionally. In that case the MODULE_DEVICE_TABLE(i2c, ...) is again not needed? And matching will be again via of_match_table? > > Up to you. > Thank you for your help! Best regards, Todor Tomov
[PATCH 1/2] media: v4l: Add new 2X8 10-bit grayscale media bus code
The code will be called MEDIA_BUS_FMT_Y10_2X8_PADHI_LE. It is similar to MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE but MEDIA_BUS_FMT_Y10_2X8_PADHI_LE describes grayscale data. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/subdev-formats.rst | 72 + include/uapi/linux/media-bus-format.h | 3 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 9fcabe7..c4fb0bf 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -4315,6 +4315,78 @@ the following codes. - y\ :sub:`2` - y\ :sub:`1` - y\ :sub:`0` +* .. _MEDIA-BUS-FMT-Y10-2X8-PADHI_LE: + + - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE + - 0x202c + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` +* - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - y\ :sub:`9` + - y\ :sub:`8` * .. _MEDIA-BUS-FMT-UYVY10-2X10: - MEDIA_BUS_FMT_UYVY10_2X10 diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 9e35117..d6a5a3b 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -62,7 +62,7 @@ #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a -/* YUV (including grey) - next is 0x202c */ +/* YUV (including grey) - next is 0x202d */ #define MEDIA_BUS_FMT_Y8_1X8 0x2001 #define MEDIA_BUS_FMT_UV8_1X8 0x2015 #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 @@ -74,6 +74,7 @@ #define MEDIA_BUS_FMT_YUYV8_2X80x2008 #define MEDIA_BUS_FMT_YVYU8_2X80x2009 #define MEDIA_BUS_FMT_Y10_1X10 0x200a +#define MEDIA_BUS_FMT_Y10_2X8_PADHI_LE 0x202c #define MEDIA_BUS_FMT_UYVY10_2X10 0x2018 #define MEDIA_BUS_FMT_VYUY10_2X10 0x2019 #define MEDIA_BUS_FMT_YUYV10_2X10 0x200b -- 2.7.4
[PATCH 0/2] Add new grayscale formats
The following two patches add one new media bus code and one new pixel format. Both are for 10bit grayscale data. They will be used by the future version of the QComm CAMSS driver when receiving the frame data from the OV7251 grayscale camera sensor. Todor Tomov (2): media: v4l: Add new 2X8 10-bit grayscale media bus code media: v4l: Add new 10-bit packed grayscale format Documentation/media/uapi/v4l/pixfmt-y10p.rst| 31 +++ Documentation/media/uapi/v4l/subdev-formats.rst | 72 + Documentation/media/uapi/v4l/yuv-formats.rst| 1 + drivers/media/v4l2-core/v4l2-ioctl.c| 1 + include/uapi/linux/media-bus-format.h | 3 +- include/uapi/linux/videodev2.h | 1 + 6 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst -- 2.7.4
[PATCH 2/2] media: v4l: Add new 10-bit packed grayscale format
The new format will be called V4L2_PIX_FMT_Y10P. It is similar to the V4L2_PIX_FMT_SBGGR10P family formats but V4L2_PIX_FMT_Y10P is a grayscale format. Signed-off-by: Todor Tomov --- Documentation/media/uapi/v4l/pixfmt-y10p.rst | 31 Documentation/media/uapi/v4l/yuv-formats.rst | 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 34 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst new file mode 100644 index 000..0018fe7 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst @@ -0,0 +1,31 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-Y10P: + +** +V4L2_PIX_FMT_Y10P ('Y10P') +** + +Grey-scale image as a MIPI RAW10 packed array + + +Description +=== + +This is a packed grey-scale image format with a depth of 10 bits per +pixel. Every four consecutive pixels are packed into 5 bytes. Each of +the first 4 bytes contain the 8 high order bits of the pixels, and +the 5th byte contains the 2 least significants bits of each pixel, +in the same order. + +**Bit-packed representation.** + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 + +* - Y'\ :sub:`00[9:2]` + - Y'\ :sub:`01[9:2]` + - Y'\ :sub:`02[9:2]` + - Y'\ :sub:`03[9:2]` + - Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[1:0]`\ Y'\ :sub:`01[1:0]`\ Y'\ :sub:`00[1:0]` diff --git a/Documentation/media/uapi/v4l/yuv-formats.rst b/Documentation/media/uapi/v4l/yuv-formats.rst index 3334ea4..9ab0592 100644 --- a/Documentation/media/uapi/v4l/yuv-formats.rst +++ b/Documentation/media/uapi/v4l/yuv-formats.rst @@ -29,6 +29,7 @@ to brightness information. pixfmt-y10 pixfmt-y12 pixfmt-y10b +pixfmt-y10p pixfmt-y16 pixfmt-y16-be pixfmt-y8i diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f48c505..bdf2399 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1147,6 +1147,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 600877b..b24ab720 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -522,6 +522,7 @@ struct v4l2_pix_format { /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ +#define V4L2_PIX_FMT_Y10Pv4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ -- 2.7.4
Re: [PATCH v3 2/2] media: Add a driver for the ov7251 camera sensor
Hi, On 25.04.2018 13:54, Sakari Ailus wrote: > Hi Todor, > > Thanks for the update. Just a few minor comments below. Thanks for the review again, Sakari. I'm preparing the next version. Best regards, Todor
[PATCH v4 2/2] media: Add a driver for the ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. The driver supports the following modes: - 640x480 30fps - 640x480 60fps - 640x480 90fps Output format is 10bit B&W RAW - MEDIA_BUS_FMT_Y10_1X10. The driver supports configuration via user controls for: - exposure and gain; - horizontal and vertical flip; - test pattern. Signed-off-by: Todor Tomov Reviewed-by: Jacopo Mondi --- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1503 3 files changed, 1516 insertions(+) create mode 100644 drivers/media/i2c/ov7251.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 541f0d28..3dd16c6 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -688,6 +688,18 @@ config VIDEO_OV5695 To compile this driver as a module, choose M here: the module will be called ov5695. +config VIDEO_OV7251 + tristate "OmniVision OV7251 sensor support" + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + help + This is a Video4Linux2 sensor-level driver for the OmniVision + OV7251 camera. + + To compile this driver as a module, choose M here: the + module will be called ov7251. + config VIDEO_OV772X tristate "OmniVision OV772x sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index ea34aee..c8585b1 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o obj-$(CONFIG_VIDEO_OV5670) += ov5670.o obj-$(CONFIG_VIDEO_OV5695) += ov5695.o obj-$(CONFIG_VIDEO_OV6650) += ov6650.o +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV772X) += ov772x.o diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c new file mode 100644 index 000..c05a9de --- /dev/null +++ b/drivers/media/i2c/ov7251.c @@ -0,0 +1,1503 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the OV7251 camera sensor. + * + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OV7251_SC_MODE_SELECT 0x0100 +#define OV7251_SC_MODE_SELECT_SW_STANDBY 0x0 +#define OV7251_SC_MODE_SELECT_STREAMING0x1 + +#define OV7251_CHIP_ID_HIGH0x300a +#define OV7251_CHIP_ID_HIGH_BYTE 0x77 +#define OV7251_CHIP_ID_LOW 0x300b +#define OV7251_CHIP_ID_LOW_BYTE0x50 +#define OV7251_SC_GP_IO_IN10x3029 +#define OV7251_AEC_EXPO_0 0x3500 +#define OV7251_AEC_EXPO_1 0x3501 +#define OV7251_AEC_EXPO_2 0x3502 +#define OV7251_AEC_AGC_ADJ_0 0x350a +#define OV7251_AEC_AGC_ADJ_1 0x350b +#define OV7251_TIMING_FORMAT1 0x3820 +#define OV7251_TIMING_FORMAT1_VFLIPBIT(2) +#define OV7251_TIMING_FORMAT2 0x3821 +#define OV7251_TIMING_FORMAT2_MIRROR BIT(2) +#define OV7251_PRE_ISP_00 0x5e00 +#define OV7251_PRE_ISP_00_TEST_PATTERN BIT(7) + +struct reg_value { + u16 reg; + u8 val; +}; + +struct ov7251_mode_info { + u32 width; + u32 height; + const struct reg_value *data; + u32 data_size; + u32 pixel_clock; + u32 link_freq; + u16 exposure_max; + u16 exposure_def; + struct v4l2_fract timeperframe; +}; + +struct ov7251 { + struct i2c_client *i2c_client; + struct device *dev; + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_fwnode_endpoint ep; + struct v4l2_mbus_framefmt fmt; + struct v4l2_rect crop; + struct clk *xclk; + u32 xclk_freq; + + struct regulator *io_regulator; + struct regulator *core_regulator; + struct regulator *analog_regulator; + + const struct ov7251_mode_info *current_mode; + + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *pixel_clock; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + + /* Cached register values */ + u8 aec_pk_manual; + u8 pre_isp_00; + u8 timing_format1; + u8 timing_format2; + + struct mutex lock; /* lock to protect power state, ctrls and mode */ + bool power_on; + + struct gpio_desc *enable_gpio; +}; + +static inline struct ov7251 *to_ov7251(struct v4l2_subdev *sd) +{ + return container_of(sd, struct ov7251, sd); +} + +static const struct reg_value ov7251_global_init_sett
[PATCH v4 1/2] dt-bindings: media: Binding document for OV7251 camera sensor
Add the document for ov7251 device tree binding. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov Reviewed-by: Rob Herring --- .../devicetree/bindings/media/i2c/ov7251.txt | 52 ++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov7251.txt b/Documentation/devicetree/bindings/media/i2c/ov7251.txt new file mode 100644 index 000..8281151 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov7251.txt @@ -0,0 +1,52 @@ +* Omnivision 1/7.5-Inch B&W VGA CMOS Digital Image Sensor + +The Omnivision OV7251 is a 1/7.5-Inch CMOS active pixel digital image sensor +with an active array size of 640H x 480V. It is programmable through a serial +I2C interface. + +Required Properties: +- compatible: Value should be "ovti,ov7251". +- clocks: Reference to the xclk clock. +- clock-names: Should be "xclk". +- clock-frequency: Frequency of the xclk clock. +- enable-gpios: Chip enable GPIO. Polarity is GPIO_ACTIVE_HIGH. This corresponds + to the hardware pin XSHUTDOWN which is physically active low. +- vdddo-supply: Chip digital IO regulator. +- vdda-supply: Chip analog regulator. +- vddd-supply: Chip digital core regulator. + +The device node shall contain one 'port' child node with a single 'endpoint' +subnode for its digital output video port, in accordance with the video +interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + &i2c1 { + ... + + ov7251: camera-sensor@60 { + compatible = "ovti,ov7251"; + reg = <0x60>; + + enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_bw_default>; + + clocks = <&clks 200>; + clock-names = "xclk"; + clock-frequency = <2400>; + + vdddo-supply = <&camera_dovdd_1v8>; + vdda-supply = <&camera_avdd_2v8>; + vddd-supply = <&camera_dvdd_1v2>; + + port { + ov7251_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0>; + remote-endpoint = <&csi0_ep>; + }; + }; + }; + }; -- 2.7.4
[PATCH v4 0/2] Add support for ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. -- Version 4: - remove OF dependency; - use only stack memory in ov7251_write_seq_regs(); - use DIV_ROUND_UP to round up sleep interval after gpio config; - minor style changes. -- Version 3: - DT binding: added that there shall be a single endpoint node in the port node; - added a comment for regulator enable order; - set exposure and gain with a single i2c transaction; - caclulate sleep after gpio config from external clock frequency; - use MEDIA_BUS_FMT_Y10_1X10 format code; - lock for power state, controls, mode and start streaming; - remove regulator_set_voltage(); - use probe_new(); - remove i2c_device_id table; - change of_property_read_u32 to fwnode_property_read_u32; - few corrections from checkpatch --strict. -- Version 2: - changed ov7251 node's name in DT binding example; - SPDX licence identifier; - better names for register value defines; - remove power reference counting and leave a power state only; - use v4l2_find_nearest_size() to find sensor mode by requested size; - set ycbcr_enc, quantization and xfer_func in set_fmt; - use struct fwnode_handle instead of struct device_node; - add comment in driver about external clock value. ------ Todor Tomov (2): dt-bindings: media: Binding document for OV7251 camera sensor media: Add a driver for the ov7251 camera sensor .../devicetree/bindings/media/i2c/ov7251.txt | 52 + drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1503 4 files changed, 1568 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt create mode 100644 drivers/media/i2c/ov7251.c -- 2.7.4
Re: [PATCH v4 2/2] media: Add a driver for the ov7251 camera sensor
Hi Sakari, On 26.04.2018 09:50, Sakari Ailus wrote: > Hi Todor, > > On Wed, Apr 25, 2018 at 07:20:46PM +0300, Todor Tomov wrote: > ... >> +static int ov7251_write_reg(struct ov7251 *ov7251, u16 reg, u8 val) >> +{ >> +u8 regbuf[3]; >> +int ret; >> + >> +regbuf[0] = reg >> 8; >> +regbuf[1] = reg & 0xff; >> +regbuf[2] = val; >> + >> +ret = i2c_master_send(ov7251->i2c_client, regbuf, 3); >> +if (ret < 0) { >> +dev_err(ov7251->dev, "%s: write reg error %d: reg=%x, val=%x\n", >> +__func__, ret, reg, val); >> +return ret; >> +} >> + >> +return 0; > > How about: > > return ov7251_write_seq_regs(ov7251, reg, &val, 1); > > And put the function below ov2751_write_seq_regs(). I'm not sure... It will calculate message length each time and then check that it is not greater than 5, which it is. Seems redundant. > >> +} >> + >> +static int ov7251_write_seq_regs(struct ov7251 *ov7251, u16 reg, u8 *val, >> + u8 num) >> +{ >> +const u8 maxregbuf = 5; >> +u8 regbuf[maxregbuf]; >> +u8 nregbuf = sizeof(reg) + num * sizeof(*val); >> +int ret = 0; >> + >> +if (nregbuf > maxregbuf) >> +return -EINVAL; >> + >> +regbuf[0] = reg >> 8; >> +regbuf[1] = reg & 0xff; >> + >> +memcpy(regbuf + 2, val, num); >> + >> +ret = i2c_master_send(ov7251->i2c_client, regbuf, nregbuf); >> +if (ret < 0) { >> +dev_err(ov7251->dev, "%s: write seq regs error %d: first >> reg=%x\n", > > This line is over 80... Yes indeed. Somehow checkpatch does not report this line, I don't know why. > > If you're happy with these, I can make the changes, too; they're trivial. Only the second one? Thanks :) > >> +__func__, ret, reg); >> +return ret; >> +} >> + >> +return 0; >> +} > -- Best regards, Todor Tomov
Re: [PATCH v4 2/2] media: Add a driver for the ov7251 camera sensor
On 26.04.2018 15:04, Sakari Ailus wrote: > On Thu, Apr 26, 2018 at 10:16:56AM +0300, Sakari Ailus wrote: >> On Thu, Apr 26, 2018 at 10:04:25AM +0300, Todor Tomov wrote: >>> Hi Sakari, >>> >>> On 26.04.2018 09:50, Sakari Ailus wrote: >>>> Hi Todor, >>>> >>>> On Wed, Apr 25, 2018 at 07:20:46PM +0300, Todor Tomov wrote: >>>> ... >>>>> +static int ov7251_write_reg(struct ov7251 *ov7251, u16 reg, u8 val) >>>>> +{ >>>>> + u8 regbuf[3]; >>>>> + int ret; >>>>> + >>>>> + regbuf[0] = reg >> 8; >>>>> + regbuf[1] = reg & 0xff; >>>>> + regbuf[2] = val; >>>>> + >>>>> + ret = i2c_master_send(ov7251->i2c_client, regbuf, 3); >>>>> + if (ret < 0) { >>>>> + dev_err(ov7251->dev, "%s: write reg error %d: reg=%x, val=%x\n", >>>>> + __func__, ret, reg, val); >>>>> + return ret; >>>>> + } >>>>> + >>>>> + return 0; >>>> >>>> How about: >>>> >>>>return ov7251_write_seq_regs(ov7251, reg, &val, 1); >>>> >>>> And put the function below ov2751_write_seq_regs(). >>> >>> I'm not sure... It will calculate message length each time and then check >>> that it is not greater than 5, which it is. Seems redundant. >>> >>>> >>>>> +} >>>>> + >>>>> +static int ov7251_write_seq_regs(struct ov7251 *ov7251, u16 reg, u8 *val, >>>>> + u8 num) >>>>> +{ >>>>> + const u8 maxregbuf = 5; >>>>> + u8 regbuf[maxregbuf]; > > Apparently this leads to bad positive sparse warning. I'd fix it by: > > diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c > index 3e2c0c03dfa9..d3ebb7529fca 100644 > --- a/drivers/media/i2c/ov7251.c > +++ b/drivers/media/i2c/ov7251.c > @@ -643,12 +643,11 @@ static int ov7251_write_reg(struct ov7251 *ov7251, u16 > reg, u8 val) > static int ov7251_write_seq_regs(struct ov7251 *ov7251, u16 reg, u8 *val, > u8 num) > { > - const u8 maxregbuf = 5; > - u8 regbuf[maxregbuf]; > + u8 regbuf[5]; > u8 nregbuf = sizeof(reg) + num * sizeof(*val); > int ret = 0; > > - if (nregbuf > maxregbuf) > + if (nregbuf > sizeof(regbuf)) > return -EINVAL; > > regbuf[0] = reg >> 8; > > Let me know if you're happy with that; I can merge it to the original > patch. Yes, thanks. > >>>>> + u8 nregbuf = sizeof(reg) + num * sizeof(*val); >>>>> + int ret = 0; >>>>> + >>>>> + if (nregbuf > maxregbuf) >>>>> + return -EINVAL; >>>>> + >>>>> + regbuf[0] = reg >> 8; >>>>> + regbuf[1] = reg & 0xff; >>>>> + >>>>> + memcpy(regbuf + 2, val, num); >>>>> + >>>>> + ret = i2c_master_send(ov7251->i2c_client, regbuf, nregbuf); >>>>> + if (ret < 0) { >>>>> + dev_err(ov7251->dev, "%s: write seq regs error %d: first >>>>> reg=%x\n", >>>> >>>> This line is over 80... >>> >>> Yes indeed. Somehow checkpatch does not report this line, I don't know why. >>> >>>> >>>> If you're happy with these, I can make the changes, too; they're trivial. >>> >>> Only the second one? Thanks :) >> >> Works for me. I'd still think the overhead of managing the buffer is >> irrelevant where to having an extra function to do essentially the same >> thing is a source of maintenance and review work. Note that we're even now >> spending time to discuss it. ;-) >> >> -- >> Kind regards, >> >> Sakari Ailus >> e-mail: sakari.ai...@iki.fi > -- Best regards, Todor Tomov
[PATCH] mailmap: Add an entry for my email address
My @linaro.org email address doesn't exist anymore so add a mailmap entry to map it to my @gmail.com address. Signed-off-by: Todor Tomov --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 45d358534ac5..9ad06d88190c 100644 --- a/.mailmap +++ b/.mailmap @@ -228,6 +228,7 @@ Sumit Semwal Tejun Heo Thomas Graf Thomas Pedersen +Todor Tomov Tony Luck TripleX Chung TripleX Chung -- 2.11.0
Re: [PATCH v2 2/2] media: Add a driver for the ov7251 camera sensor
Hi Sakari, On 17.04.2018 23:10, Sakari Ailus wrote: > Hi Todor, > > On Tue, Apr 17, 2018 at 06:32:07PM +0300, Todor Tomov wrote: > ... >>>> +static int ov7251_regulators_enable(struct ov7251 *ov7251) >>>> +{ >>>> + int ret; >>>> + >>>> + ret = regulator_enable(ov7251->io_regulator); >>> >>> How about regulator_bulk_enable() here, and bulk_disable below? >> >> I'm not using the bulk API because usually there is a power up >> sequence and intervals that must be followed. For this sensor >> the only constraint is that core regulator must be enabled >> after io regulator. But the bulk API doesn't guarantee the >> order. > > Could you add a comment explaining this? Otherwise it won't take long until > someone "fixes" the code. Sure :D I'm adding a comment. > > ... > >>>> +static int ov7251_read_reg(struct ov7251 *ov7251, u16 reg, u8 *val) >>>> +{ >>>> + u8 regbuf[2]; >>>> + int ret; >>>> + >>>> + regbuf[0] = reg >> 8; >>>> + regbuf[1] = reg & 0xff; >>>> + >>>> + ret = i2c_master_send(ov7251->i2c_client, regbuf, 2); >>>> + if (ret < 0) { >>>> + dev_err(ov7251->dev, "%s: write reg error %d: reg=%x\n", >>>> + __func__, ret, reg); >>>> + return ret; >>>> + } >>>> + >>>> + ret = i2c_master_recv(ov7251->i2c_client, val, 1); >>>> + if (ret < 0) { >>>> + dev_err(ov7251->dev, "%s: read reg error %d: reg=%x\n", >>>> + __func__, ret, reg); >>>> + return ret; >>>> + } >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int ov7251_set_exposure(struct ov7251 *ov7251, s32 exposure) >>>> +{ >>>> + int ret; >>>> + >>>> + ret = ov7251_write_reg(ov7251, OV7251_AEC_EXPO_0, >>>> + (exposure & 0xf000) >> 12); >>>> + if (ret < 0) >>>> + return ret; >>>> + >>>> + ret = ov7251_write_reg(ov7251, OV7251_AEC_EXPO_1, >>>> + (exposure & 0x0ff0) >> 4); >>>> + if (ret < 0) >>>> + return ret; >>>> + >>>> + return ov7251_write_reg(ov7251, OV7251_AEC_EXPO_2, >>>> + (exposure & 0x000f) << 4); >>> >>> It's not a good idea to access multi-octet registers separately. Depending >>> on the hardware implementation, the hardware could latch the value in the >>> middle of an update. This is only an issue during streaming in practice >>> though. >> >> Good point. The sensor has a group write functionality which can be used >> to solve this but in general is intended >> to apply a group of exposure and gain settings in the same frame. However >> it seems to me that is not possible to use this functionality efficiently >> with the currently available user controls. The group write is configured >> using an id for a group of commands. So if we configure exposure and gain >> separately (a group for each): >> - if the driver uses same group id for exposure and gain, if both controls >> are received in one frame the second will overwrite the first (the >> first will not be applied); >> - if the driver uses different group id for exposure and gain, it will not >> be possible for the user to change exposure and gain in the same frame >> (as some exposure algorithms do) and it will lead again to frames with >> "incorrect" brightness. >> >> To do this correctly we will have to extend the API to be able to apply >> exposure and gain "atomically": >> - a single user control which will set both exposure and gain and it will >> guarantee that they will be applied in the same frame; >> - some kind of: begin, set exposure, set gain, end, launch -API >> >> What do you think? >> >> Actually, I'm a little bit surprised that I didn't find anything >> like this already. And there are already a number of sensor drivers >> which update more than one register to set exposure. > > The latter of the two would be preferred as it isn't limited to exposure > and gain only. Still, you could address the problem for this driver by > simply writing the register in a single transaction. Thanks for suggestion. I've tried the single transaction, I will send the next version of the driver shortly. -- Best regards, Todor Tomov
[PATCH v3 1/2] dt-bindings: media: Binding document for OV7251 camera sensor
Add the document for ov7251 device tree binding. CC: Rob Herring CC: Mark Rutland CC: devicet...@vger.kernel.org Signed-off-by: Todor Tomov Reviewed-by: Rob Herring --- .../devicetree/bindings/media/i2c/ov7251.txt | 52 ++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov7251.txt b/Documentation/devicetree/bindings/media/i2c/ov7251.txt new file mode 100644 index 000..8281151 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov7251.txt @@ -0,0 +1,52 @@ +* Omnivision 1/7.5-Inch B&W VGA CMOS Digital Image Sensor + +The Omnivision OV7251 is a 1/7.5-Inch CMOS active pixel digital image sensor +with an active array size of 640H x 480V. It is programmable through a serial +I2C interface. + +Required Properties: +- compatible: Value should be "ovti,ov7251". +- clocks: Reference to the xclk clock. +- clock-names: Should be "xclk". +- clock-frequency: Frequency of the xclk clock. +- enable-gpios: Chip enable GPIO. Polarity is GPIO_ACTIVE_HIGH. This corresponds + to the hardware pin XSHUTDOWN which is physically active low. +- vdddo-supply: Chip digital IO regulator. +- vdda-supply: Chip analog regulator. +- vddd-supply: Chip digital core regulator. + +The device node shall contain one 'port' child node with a single 'endpoint' +subnode for its digital output video port, in accordance with the video +interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + &i2c1 { + ... + + ov7251: camera-sensor@60 { + compatible = "ovti,ov7251"; + reg = <0x60>; + + enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_bw_default>; + + clocks = <&clks 200>; + clock-names = "xclk"; + clock-frequency = <2400>; + + vdddo-supply = <&camera_dovdd_1v8>; + vdda-supply = <&camera_avdd_2v8>; + vddd-supply = <&camera_dvdd_1v2>; + + port { + ov7251_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0>; + remote-endpoint = <&csi0_ep>; + }; + }; + }; + }; -- 2.7.4
[PATCH v3 0/2] Add support for ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. -- Version 3: - DT binding: added that there shall be a single endpoint node in the port node; - added a comment for regulator enable order; - set exposure and gain with a single i2c transaction; - caclulate sleep after gpio config from external clock frequency; - use MEDIA_BUS_FMT_Y10_1X10 format code; - lock for power state, controls, mode and start streaming; - remove regulator_set_voltage(); - use probe_new(); - remove i2c_device_id table; - change of_property_read_u32 to fwnode_property_read_u32; - few corrections from checkpatch --strict. -- Version 2: - changed ov7251 node's name in DT binding example; - SPDX licence identifier; - better names for register value defines; - remove power reference counting and leave a power state only; - use v4l2_find_nearest_size() to find sensor mode by requested size; - set ycbcr_enc, quantization and xfer_func in set_fmt; - use struct fwnode_handle instead of struct device_node; - add comment in driver about external clock value. ------ Todor Tomov (2): dt-bindings: media: Binding document for OV7251 camera sensor media: Add a driver for the ov7251 camera sensor .../devicetree/bindings/media/i2c/ov7251.txt | 52 + drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1501 4 files changed, 1567 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7251.txt create mode 100644 drivers/media/i2c/ov7251.c -- 2.7.4
[PATCH v3 2/2] media: Add a driver for the ov7251 camera sensor
The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image Sensor from Omnivision. The driver supports the following modes: - 640x480 30fps - 640x480 60fps - 640x480 90fps Output format is 10bit B&W RAW - MEDIA_BUS_FMT_Y10_1X10. The driver supports configuration via user controls for: - exposure and gain; - horizontal and vertical flip; - test pattern. Signed-off-by: Todor Tomov Reviewed-by: Jacopo Mondi --- drivers/media/i2c/Kconfig | 13 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov7251.c | 1501 3 files changed, 1515 insertions(+) create mode 100644 drivers/media/i2c/ov7251.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 541f0d28..1ff7aaf 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -688,6 +688,19 @@ config VIDEO_OV5695 To compile this driver as a module, choose M here: the module will be called ov5695. +config VIDEO_OV7251 + tristate "OmniVision OV7251 sensor support" + depends on OF + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + help + This is a Video4Linux2 sensor-level driver for the OmniVision + OV7251 camera. + + To compile this driver as a module, choose M here: the + module will be called ov7251. + config VIDEO_OV772X tristate "OmniVision OV772x sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index ea34aee..c8585b1 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o obj-$(CONFIG_VIDEO_OV5670) += ov5670.o obj-$(CONFIG_VIDEO_OV5695) += ov5695.o obj-$(CONFIG_VIDEO_OV6650) += ov6650.o +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV772X) += ov772x.o diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c new file mode 100644 index 000..69e70a0 --- /dev/null +++ b/drivers/media/i2c/ov7251.c @@ -0,0 +1,1501 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the OV7251 camera sensor. + * + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OV7251_SC_MODE_SELECT 0x0100 +#define OV7251_SC_MODE_SELECT_SW_STANDBY 0x0 +#define OV7251_SC_MODE_SELECT_STREAMING0x1 + +#define OV7251_CHIP_ID_HIGH0x300a +#define OV7251_CHIP_ID_HIGH_BYTE 0x77 +#define OV7251_CHIP_ID_LOW 0x300b +#define OV7251_CHIP_ID_LOW_BYTE0x50 +#define OV7251_SC_GP_IO_IN10x3029 +#define OV7251_AEC_EXPO_0 0x3500 +#define OV7251_AEC_EXPO_1 0x3501 +#define OV7251_AEC_EXPO_2 0x3502 +#define OV7251_AEC_AGC_ADJ_0 0x350a +#define OV7251_AEC_AGC_ADJ_1 0x350b +#define OV7251_TIMING_FORMAT1 0x3820 +#define OV7251_TIMING_FORMAT1_VFLIPBIT(2) +#define OV7251_TIMING_FORMAT2 0x3821 +#define OV7251_TIMING_FORMAT2_MIRROR BIT(2) +#define OV7251_PRE_ISP_00 0x5e00 +#define OV7251_PRE_ISP_00_TEST_PATTERN BIT(7) + +struct reg_value { + u16 reg; + u8 val; +}; + +struct ov7251_mode_info { + u32 width; + u32 height; + const struct reg_value *data; + u32 data_size; + u32 pixel_clock; + u32 link_freq; + u16 exposure_max; + u16 exposure_def; + struct v4l2_fract timeperframe; +}; + +struct ov7251 { + struct i2c_client *i2c_client; + struct device *dev; + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_fwnode_endpoint ep; + struct v4l2_mbus_framefmt fmt; + struct v4l2_rect crop; + struct clk *xclk; + u32 xclk_freq; + + struct regulator *io_regulator; + struct regulator *core_regulator; + struct regulator *analog_regulator; + + const struct ov7251_mode_info *current_mode; + + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *pixel_clock; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + + /* Cached register values */ + u8 aec_pk_manual; + u8 pre_isp_00; + u8 timing_format1; + u8 timing_format2; + + struct mutex lock; /* lock to protect power state, ctrls and mode */ + bool power_on; + + struct gpio_desc *enable_gpio; +}; + +static inline struct ov7251 *to_ov7251(struct v4l2_subdev *sd) +{ + return container_of(sd, struct ov7251, sd); +} + +static const struct reg_val
Re: [dragonboard] [PATCH 1/1] dts: qcom: db820c: Add gpio-line-names property
Hi Mani, Thank you for the patch. On 14.04.2018 06:18, Manivannan Sadhasivam wrote: > Add gpio-line-names property for Dragonboard820c based on APQ8096 SoC. > There are 4 gpio-controllers present on this board, including the > APQ8096 SoC, PM8994 (GPIO and MPP) and PMI8994 (GPIO). > > Lines names are derived from 96Boards CE Specification 1.0, Appendix > "Expansion Connector Signal Description". Line names for PMI8994 MPP > pins are not added due to the absence of the gpio-controller support. > > Signed-off-by: Manivannan Sadhasivam > --- > arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 240 > +++ > 1 file changed, 240 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > index 1c8f1b86472d..1c1deef031c6 100644 > --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > @@ -19,6 +19,34 @@ > #include > #include > > +/* > + * GPIO name legend: proper name = the GPIO line is used as GPIO > + * NC = not connected (pin out but not routed from the chip to > + * anything the board) > + * "[PER]" = pin is muxed for [peripheral] (not GPIO) > + * LSEC= Low Speed External Connector > + * HSEC= High Speed External Connector > + * P HSEC = Primary High Speed External Connector > + * S HSEC = Secondary High Speed External Connector > + * J14 = Camera Connector > + * TP = Test Points > + * > + * Line names are taken from the schematic "DragonBoard 820c", > + * drawing no: LM25-P2751-1 > + * > + * For the lines routed to the external connectors the > + * lines are named after the 96Boards CE Specification 1.0, > + * Appendix "Expansion Connector Signal Description". > + * > + * When the 96Board naming of a line and the schematic name of > + * the same line are in conflict, the 96Board specification > + * takes precedence, which means that the external UART on the > + * LSEC is named UART0 while the schematic and SoC names this > + * UART3. This is only for the informational lines i.e. "[FOO]", It seems to me that this can lead to some confusion for cases when some schematic names have 96board names and others don't. (An example below.) However I don't really see any better way to do it. I'm wondering whether adding the schematic name in the comment (for gpios which are named with 96board names) can help a little. What do you think? Or any other idea? > + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only > + * ones actually used for GPIO. > + */ > + > / { > aliases { > serial0 = &blsp2_uart1; > @@ -90,6 +118,218 @@ > status = "okay"; > }; > > + pinctrl@101 { > + gpio-line-names = > + "[SPI0_DOUT]", /* GPIO_0, LSEC pin 14 */ > + "[SPI0_DIN]", /* GPIO_1, LSEC pin 10 */ > + "[SPI0_CS]", /* GPIO_2, LSEC pin 12 */ > + "[SPI0_SCLK]", /* GPIO_3, LSEC pin 8 */ > + "[UART1_TxD]", /* GPIO_4, LSEC pin 11 */ > + "[UART1_RxD]", /* GPIO_5, LSEC pin 13 */ > + "[I2C1_SDA]", /* GPIO_6, LSEC pin 21 */ > + "[I2C1_SCL]", /* GPIO_7, LSEC pin 19 */ > + "GPIO-H", /* GPIO_8, LSEC pin 30 */ > + "TP93", /* GPIO_9 */ > + "GPIO-G", /* GPIO_10, LSEC pin 29 */ > + "[MDP_VSYNC_S]", /* GPIO_11, P HSEC pin 55 */ > + "NC", /* GPIO_12 */ > + "[CSI0_MCLK]", /* GPIO_13, P HSEC pin 15 */ > + "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ > + "[CSI1_MCLK]", /* GPIO_15, P HSEC pin 17 */ This could be a little misleading. 96Board name / schametic name: CSI0_MCLK / CAM_MCLK0 - / CAM_MCLK1 CSI1_MCLK / CAM_MCLK2 -- Best regards, Todor Tomov
Re: [PATCH v2 1/1] dts: qcom: db820c: Add gpio-line-names property
Hi Mani, On 18.04.2018 16:46, Manivannan Sadhasivam wrote: > Add gpio-line-names property for Dragonboard820c based on APQ8096 SoC. > There are 4 gpio-controllers present on this board, including the > APQ8096 SoC, PM8994 (GPIO and MPP) and PMI8994 (GPIO). > > Lines names are derived from 96Boards CE Specification 1.0, Appendix > "Expansion Connector Signal Description". Line names for PMI8994 MPP > pins are not added due to the absence of the gpio-controller support. > > Signed-off-by: Manivannan Sadhasivam Thank you for adding the schematic names to the comments. You can have my: Reviewed-by: Todor Tomov > --- > arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 239 > +++ > 1 file changed, 239 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > index 1c8f1b86472d..473530527e27 100644 > --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi > @@ -19,6 +19,33 @@ > #include > #include > > +/* > + * GPIO name legend: proper name = the GPIO line is used as GPIO > + * NC = not connected (pin out but not routed from the chip to > + * anything the board) > + * "[PER]" = pin is muxed for [peripheral] (not GPIO) > + * LSEC= Low Speed External Connector > + * P HSEC = Primary High Speed External Connector > + * S HSEC = Secondary High Speed External Connector > + * J14 = Camera Connector > + * TP = Test Points > + * > + * Line names are taken from the schematic "DragonBoard 820c", > + * drawing no: LM25-P2751-1 > + * > + * For the lines routed to the external connectors the > + * lines are named after the 96Boards CE Specification 1.0, > + * Appendix "Expansion Connector Signal Description". > + * > + * When the 96Board naming of a line and the schematic name of > + * the same line are in conflict, the 96Board specification > + * takes precedence, which means that the external UART on the > + * LSEC is named UART0 while the schematic and SoC names this > + * UART3. This is only for the informational lines i.e. "[FOO]", > + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only > + * ones actually used for GPIO. > + */ > + > / { > aliases { > serial0 = &blsp2_uart1; > @@ -90,6 +117,218 @@ > status = "okay"; > }; > > + pinctrl@101 { > + gpio-line-names = > + "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC > pin 14 */ > + "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC > pin 10 */ > + "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC > pin 12 */ > + "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC > pin 8 */ > + "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC > pin 11 */ > + "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC > pin 13 */ > + "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC > pin 21 */ > + "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC > pin 19 */ > + "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 > */ > + "TP93", /* GPIO_9 */ > + "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 > */ > + "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */ > + "NC", /* GPIO_12 */ > + "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC > pin 15 */ > + "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ > + "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC > pin 17 */ > + "TP99", /* GPIO_16 */ > + "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC > pin 34 */ > + "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC > pin 32 */ > + "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */ > + "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */ > + "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */ > + "FLASH_STROBE_TRIG&qu
Re: [PATCH] [media] ov5645: Move an error code assignment in ov5645_probe()
Hi, On 15.03.2018 00:17, Sakari Ailus wrote: > On Wed, Mar 14, 2018 at 10:15:43PM +0100, SF Markus Elfring wrote: >> From: Markus Elfring >> Date: Wed, 14 Mar 2018 22:02:52 +0100 >> >> Move an assignment for a specific error code so that it is stored only once >> in this function implementation. >> >> This issue was detected by using the Coccinelle software. > > How? > >> >> Signed-off-by: Markus Elfring >> --- >> drivers/media/i2c/ov5645.c | 6 +- >> 1 file changed, 1 insertion(+), 5 deletions(-) >> >> diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c >> index d28845f7356f..374576380fd4 100644 >> --- a/drivers/media/i2c/ov5645.c >> +++ b/drivers/media/i2c/ov5645.c >> @@ -1284,13 +1284,11 @@ static int ov5645_probe(struct i2c_client *client, >> ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high); >> if (ret < 0 || chip_id_high != OV5645_CHIP_ID_HIGH_BYTE) { >> dev_err(dev, "could not read ID high\n"); >> -ret = -ENODEV; >> goto power_down; >> } >> ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_LOW, &chip_id_low); >> if (ret < 0 || chip_id_low != OV5645_CHIP_ID_LOW_BYTE) { >> dev_err(dev, "could not read ID low\n"); >> -ret = -ENODEV; >> goto power_down; >> } >> >> @@ -1300,7 +1298,6 @@ static int ov5645_probe(struct i2c_client *client, >>&ov5645->aec_pk_manual); >> if (ret < 0) { >> dev_err(dev, "could not read AEC/AGC mode\n"); >> -ret = -ENODEV; >> goto power_down; >> } >> >> @@ -1308,7 +1305,6 @@ static int ov5645_probe(struct i2c_client *client, >>&ov5645->timing_tc_reg20); >> if (ret < 0) { >> dev_err(dev, "could not read vflip value\n"); >> -ret = -ENODEV; >> goto power_down; >> } >> >> @@ -1316,7 +1312,6 @@ static int ov5645_probe(struct i2c_client *client, >>&ov5645->timing_tc_reg21); >> if (ret < 0) { >> dev_err(dev, "could not read hflip value\n"); >> -ret = -ENODEV; >> goto power_down; >> } >> >> @@ -1334,6 +1329,7 @@ static int ov5645_probe(struct i2c_client *client, >> >> power_down: >> ov5645_s_power(&ov5645->sd, false); >> +ret = -ENODEV; > > I don't think this is where people would expect you to set the error code > in general. It should rather take place before goto, not after it. That'd > mean another variable, and I'm not convinced the result would improve the > driver. I agree with Sakari. > >> free_entity: >> media_entity_cleanup(&ov5645->sd.entity); >> free_ctrl: > -- Best regards, Todor Tomov
Re: [PATCH 2/2] media: v4l: Add new 10-bit packed grayscale format
Hi Sakari, On 7.05.2018 13:59, Sakari Ailus wrote: > Hi Todor, > > On Fri, Apr 27, 2018 at 02:40:39PM +0300, Todor Tomov wrote: >> The new format will be called V4L2_PIX_FMT_Y10P. >> It is similar to the V4L2_PIX_FMT_SBGGR10P family formats >> but V4L2_PIX_FMT_Y10P is a grayscale format. >> >> Signed-off-by: Todor Tomov >> --- >> Documentation/media/uapi/v4l/pixfmt-y10p.rst | 31 >> >> Documentation/media/uapi/v4l/yuv-formats.rst | 1 + >> drivers/media/v4l2-core/v4l2-ioctl.c | 1 + >> include/uapi/linux/videodev2.h | 1 + >> 4 files changed, 34 insertions(+) >> create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst >> >> diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst >> b/Documentation/media/uapi/v4l/pixfmt-y10p.rst >> new file mode 100644 >> index 000..0018fe7 >> --- /dev/null >> +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst >> @@ -0,0 +1,31 @@ >> +.. -*- coding: utf-8; mode: rst -*- >> + >> +.. _V4L2-PIX-FMT-Y10P: >> + >> +** >> +V4L2_PIX_FMT_Y10P ('Y10P') >> +** >> + >> +Grey-scale image as a MIPI RAW10 packed array >> + >> + >> +Description >> +=== >> + >> +This is a packed grey-scale image format with a depth of 10 bits per >> +pixel. Every four consecutive pixels are packed into 5 bytes. Each of >> +the first 4 bytes contain the 8 high order bits of the pixels, and >> +the 5th byte contains the 2 least significants bits of each pixel, >> +in the same order. >> + >> +**Bit-packed representation.** >> + >> +.. flat-table:: >> +:header-rows: 0 >> +:stub-columns: 0 >> + >> +* - Y'\ :sub:`00[9:2]` >> + - Y'\ :sub:`01[9:2]` >> + - Y'\ :sub:`02[9:2]` >> + - Y'\ :sub:`03[9:2]` >> + - Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[1:0]`\ Y'\ :sub:`01[1:0]`\ Y'\ >> :sub:`00[1:0]` > > Could you add which exact bits the two LSBs of each pixel go to in the last > byte, as in the 10-bit packed Bayer format documentation? Thank you for review. I'll add and send v2. Best regards, Todor > >> diff --git a/Documentation/media/uapi/v4l/yuv-formats.rst >> b/Documentation/media/uapi/v4l/yuv-formats.rst >> index 3334ea4..9ab0592 100644 >> --- a/Documentation/media/uapi/v4l/yuv-formats.rst >> +++ b/Documentation/media/uapi/v4l/yuv-formats.rst >> @@ -29,6 +29,7 @@ to brightness information. >> pixfmt-y10 >> pixfmt-y12 >> pixfmt-y10b >> +pixfmt-y10p >> pixfmt-y16 >> pixfmt-y16-be >> pixfmt-y8i >> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c >> b/drivers/media/v4l2-core/v4l2-ioctl.c >> index f48c505..bdf2399 100644 >> --- a/drivers/media/v4l2-core/v4l2-ioctl.c >> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c >> @@ -1147,6 +1147,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) >> case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; >> case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; >> case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; >> break; >> +case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI >> Packed)"; break; >> case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; >> break; >> case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; >> break; >> case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; >> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h >> index 600877b..b24ab720 100644 >> --- a/include/uapi/linux/videodev2.h >> +++ b/include/uapi/linux/videodev2.h >> @@ -522,6 +522,7 @@ struct v4l2_pix_format { >> >> /* Grey bit-packed formats */ >> #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10 >> Greyscale bit-packed */ >> +#define V4L2_PIX_FMT_Y10Pv4l2_fourcc('Y', '1', '0', 'P') /* 10 >> Greyscale, MIPI RAW10 packed */ >> >> /* Palette formats */ >> #define V4L2_PIX_FMT_PAL8v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit >> palette */ >> -- >> 2.7.4 >> >
[PATCH v2] media: v4l: Add new 10-bit packed grayscale format
The new format will be called V4L2_PIX_FMT_Y10P. It is similar to the V4L2_PIX_FMT_SBGGR10P family formats but V4L2_PIX_FMT_Y10P is a grayscale format. Signed-off-by: Todor Tomov --- v2: - doc: improved bit-packed representation: added bit positions for LSB bits; - doc: improved bit-packed representation: added table column widths. Documentation/media/uapi/v4l/pixfmt-y10p.rst | 33 Documentation/media/uapi/v4l/yuv-formats.rst | 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 36 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-y10p.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst new file mode 100644 index 000..13b5713 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst @@ -0,0 +1,33 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-Y10P: + +** +V4L2_PIX_FMT_Y10P ('Y10P') +** + +Grey-scale image as a MIPI RAW10 packed array + + +Description +=== + +This is a packed grey-scale image format with a depth of 10 bits per +pixel. Every four consecutive pixels are packed into 5 bytes. Each of +the first 4 bytes contain the 8 high order bits of the pixels, and +the 5th byte contains the 2 least significants bits of each pixel, +in the same order. + +**Bit-packed representation.** + +.. flat-table:: +:header-rows: 0 +:stub-columns: 0 +:widths: 8 8 8 8 64 + +* - Y'\ :sub:`00[9:2]` + - Y'\ :sub:`01[9:2]` + - Y'\ :sub:`02[9:2]` + - Y'\ :sub:`03[9:2]` + - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4) + Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0) diff --git a/Documentation/media/uapi/v4l/yuv-formats.rst b/Documentation/media/uapi/v4l/yuv-formats.rst index 3334ea4..9ab0592 100644 --- a/Documentation/media/uapi/v4l/yuv-formats.rst +++ b/Documentation/media/uapi/v4l/yuv-formats.rst @@ -29,6 +29,7 @@ to brightness information. pixfmt-y10 pixfmt-y12 pixfmt-y10b +pixfmt-y10p pixfmt-y16 pixfmt-y16-be pixfmt-y8i diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index de5d96d..dececea 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1147,6 +1147,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 600877b..b24ab720 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -522,6 +522,7 @@ struct v4l2_pix_format { /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ +#define V4L2_PIX_FMT_Y10Pv4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ -- 2.7.4
Re: [PATCH v2 2/2] media: Add a driver for the ov7251 camera sensor
Hi Sakari, Thank you for the review. On 29.03.2018 14:51, Sakari Ailus wrote: > Hi Todor, > > Thanks for the patch. A few quick comments below... > > On Fri, Mar 23, 2018 at 12:14:20PM +0800, Todor Tomov wrote: >> The ov7251 sensor is a 1/7.5-Inch B&W VGA (640x480) CMOS Digital Image >> Sensor from Omnivision. >> >> The driver supports the following modes: >> - 640x480 30fps >> - 640x480 60fps >> - 640x480 90fps >> >> Output format is MIPI RAW 10. >> >> The driver supports configuration via user controls for: >> - exposure and gain; >> - horizontal and vertical flip; >> - test pattern. >> >> Signed-off-by: Todor Tomov >> --- >> drivers/media/i2c/Kconfig | 13 + >> drivers/media/i2c/Makefile |1 + >> drivers/media/i2c/ov7251.c | 1494 >> >> 3 files changed, 1508 insertions(+) >> create mode 100644 drivers/media/i2c/ov7251.c >> >> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >> index 541f0d28..89aecb3 100644 >> --- a/drivers/media/i2c/Kconfig >> +++ b/drivers/media/i2c/Kconfig >> @@ -688,6 +688,19 @@ config VIDEO_OV5695 >>To compile this driver as a module, choose M here: the >>module will be called ov5695. >> >> +config VIDEO_OV7251 >> +tristate "OmniVision OV7251 sensor support" >> +depends on OF >> +depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API >> +depends on MEDIA_CAMERA_SUPPORT >> +select V4L2_FWNODE >> +---help--- >> + This is a Video4Linux2 sensor-level driver for the OmniVision >> + OV7251 camera. >> + >> + To compile this driver as a module, choose M here: the >> + module will be called ov7251. >> + >> config VIDEO_OV772X >> tristate "OmniVision OV772x sensor support" >> depends on I2C && VIDEO_V4L2 >> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile >> index ea34aee..c8585b1 100644 >> --- a/drivers/media/i2c/Makefile >> +++ b/drivers/media/i2c/Makefile >> @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o >> obj-$(CONFIG_VIDEO_OV5670) += ov5670.o >> obj-$(CONFIG_VIDEO_OV5695) += ov5695.o >> obj-$(CONFIG_VIDEO_OV6650) += ov6650.o >> +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o >> obj-$(CONFIG_VIDEO_OV7640) += ov7640.o >> obj-$(CONFIG_VIDEO_OV7670) += ov7670.o >> obj-$(CONFIG_VIDEO_OV772X) += ov772x.o >> diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c >> new file mode 100644 >> index 000..7b401a9 >> --- /dev/null >> +++ b/drivers/media/i2c/ov7251.c >> @@ -0,0 +1,1494 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Driver for the OV7251 camera sensor. >> + * >> + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. >> + * Copyright (c) 2017-2018, Linaro Ltd. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define OV7251_VOLTAGE_ANALOG 280 >> +#define OV7251_VOLTAGE_DIGITAL_CORE 150 >> +#define OV7251_VOLTAGE_DIGITAL_IO 180 >> + >> +#define OV7251_SC_MODE_SELECT 0x0100 >> +#define OV7251_SC_MODE_SELECT_SW_STANDBY0x0 >> +#define OV7251_SC_MODE_SELECT_STREAMING 0x1 >> + >> +#define OV7251_CHIP_ID_HIGH 0x300a >> +#define OV7251_CHIP_ID_HIGH_BYTE0x77 >> +#define OV7251_CHIP_ID_LOW 0x300b >> +#define OV7251_CHIP_ID_LOW_BYTE 0x50 >> +#define OV7251_SC_GP_IO_IN1 0x3029 >> +#define OV7251_AEC_EXPO_0 0x3500 >> +#define OV7251_AEC_EXPO_1 0x3501 >> +#define OV7251_AEC_EXPO_2 0x3502 >> +#define OV7251_AEC_AGC_ADJ_00x350a >> +#define OV7251_AEC_AGC_ADJ_10x350b >> +#define OV7251_TIMING_FORMAT1 0x3820 >> +#define OV7251_TIMING_FORMAT1_VFLIP BIT(2) >> +#define OV7251_TIMING_FORMAT2 0x3821 >> +#define OV7251_TIMING_FORMAT2_MIRRORBIT(2) >> +#define OV7251_PRE_ISP_00 0x5e00 >> +#define OV7251_PRE_ISP_00_TEST_PATTERN BIT(7) >> + >> +struct reg_value { >> +u16 reg; >> +u8 val; >>
Re: [PATCH 08/10] media: camss: Add files which handle the video device nodes
Hi Laurent, Thank you for the detailed review. On 12/05/2016 05:22 PM, Laurent Pinchart wrote: > Hi Todor, > > Thank you for the patch. > > On Friday 25 Nov 2016 16:57:20 Todor Tomov wrote: >> These files handle the video device nodes of the camss driver. > > camss is a quite generic, I'm a bit concerned about claiming that acronym in > the global kernel namespace. Would it be too long if we prefixed symbols with > msm_camss instead ? Ok. Are you concerned about camss_enable_clocks() and camss_disable_clocks() or you have something else in mind too? > >> Signed-off-by: Todor Tomov >> --- >> drivers/media/platform/qcom/camss-8x16/video.c | 597 ++ >> drivers/media/platform/qcom/camss-8x16/video.h | 67 +++ >> 2 files changed, 664 insertions(+) >> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.c >> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.h >> >> diff --git a/drivers/media/platform/qcom/camss-8x16/video.c >> b/drivers/media/platform/qcom/camss-8x16/video.c new file mode 100644 >> index 000..0bf8ea9 >> --- /dev/null >> +++ b/drivers/media/platform/qcom/camss-8x16/video.c >> @@ -0,0 +1,597 @@ >> +/* >> + * video.c >> + * >> + * Qualcomm MSM Camera Subsystem - V4L2 device node >> + * >> + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. >> + * Copyright (C) 2015-2016 Linaro Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 and >> + * only 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. >> + */ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "video.h" >> +#include "camss.h" >> + >> +/* >> + * struct format_info - ISP media bus format information >> + * @code: V4L2 media bus format code >> + * @pixelformat: V4L2 pixel format FCC identifier >> + * @bpp: Bits per pixel when stored in memory >> + */ >> +static const struct format_info { >> +u32 code; >> +u32 pixelformat; >> +unsigned int bpp; >> +} formats[] = { >> +{ MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 16 }, >> +{ MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 16 }, >> +{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 16 }, >> +{ MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 16 }, >> +{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8 }, >> +{ MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8 }, >> +{ MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8 }, >> +{ MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8 }, >> +{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 10 }, >> +{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 10 }, >> +{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 10 }, >> +{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 10 }, >> +{ MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 }, >> +{ MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 }, >> +{ MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 }, >> +{ MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 } >> +}; >> + >> +/* >> --- >> -- + * Helper functions >> + */ >> + >> +/* >> + * video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format >> + * @mbus: v4l2_mbus_framefmt format (input) >> + * @pix: v4l2_pix_format format (output) >> + * >> + * Fill the output pix structure with information from the input mbus >> format. >> + * >> + * Return 0 on success or a negative error code otherwise >> + */ >> +static unsigned int video_mbus_to_pix(const struct v4l2_mbus_framefmt >> *mbus, >> + struct v4l2_pix_format *pix) >> +{ >> +unsigned int i; >> + >> +memset(pix, 0, sizeof(*pix)); >> +pix->width = mbus->width; >> +pix->height = mbus->height; >> + >> +for (i = 0; i < ARRAY_SIZE(formats); ++i) { >> +if (formats[i].code == mbus->code) >> +
Re: [PATCH 00/10] Qualcomm 8x16 Camera Subsystem driver
Hi Hans, On 01/09/2017 03:08 PM, Hans Verkuil wrote: > Hi Todor, > > What is the status of this patch series? There were comments for patch 1/10 > and 8/10, > and I haven't seen a v2 of this patch series. And Happy new year! I'm just starting today for the new year and this is the first thing to do - go over the comments received. I'll reply for each of them. Thank you for your notification and the also for the review done! Best regards, Todor > > Regards, > > Hans > > On 11/25/2016 03:56 PM, Todor Tomov wrote: >> This patchset adds basic support for the Qualcomm Camera Subsystem found >> on Qualcomm MSM8916 and APQ8016 processors. >> >> The driver implements V4L2, Media controller and V4L2 subdev interfaces. >> Camera sensor using V4L2 subdev interface in the kernel is supported. >> >> The driver is implemented using as a reference the Qualcomm Camera >> Subsystem driver for Android as found in Code Aurora [1]. >> >> The driver supports raw dump of the input data to memory. ISP processing >> is not supported. >> >> The driver is tested on Dragonboard 410C (APQ8016) with one and two >> OV5645 camera sensors. media-ctl [2] and yavta [3] applications were >> used for testing. Also Gstreamer 1.4.4 with v4l2src plugin is supported. >> >> More information is present in the document added by the third patch. >> >> >> The patchset depends on: >> v4l: Add packed Bayer raw12 pixel formats [4] >> media: venus: enable building of Venus video codec driver [5] >> >> >> V4L2 compliance test result: >> >> root@linaro-alip:~/v4l-utils/utils/v4l2-compliance# ./v4l2-compliance -s -d >> /dev/video0 >> v4l2-compliance SHA : 6a760145f1a6809591a1cb17ee1b06913e4fddd1 >> >> Driver Info: >> Driver name : qcom-camss >> Card type : Qualcomm Camera Subsystem >> Bus info : platform:qcom-camss >> Driver version: 4.9.0 >> Capabilities : 0x8421 >> Video Capture >> Streaming >> Extended Pix Format >> Device Capabilities >> Device Caps : 0x0421 >> Video Capture >> Streaming >> Extended Pix Format >> >> Compliance test for device /dev/video0 (not using libv4l2): >> >> Required ioctls: >> test VIDIOC_QUERYCAP: OK >> >> Allow for multiple opens: >> test second video open: OK >> test VIDIOC_QUERYCAP: OK >> test VIDIOC_G/S_PRIORITY: OK >> test for unlimited opens: OK >> >> Debug ioctls: >> test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported) >> test VIDIOC_LOG_STATUS: OK (Not Supported) >> >> Input ioctls: >> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported) >> test VIDIOC_G/S_FREQUENCY: OK (Not Supported) >> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported) >> test VIDIOC_ENUMAUDIO: OK (Not Supported) >> test VIDIOC_G/S/ENUMINPUT: OK >> test VIDIOC_G/S_AUDIO: OK (Not Supported) >> Inputs: 1 Audio Inputs: 0 Tuners: 0 >> >> Output ioctls: >> test VIDIOC_G/S_MODULATOR: OK (Not Supported) >> test VIDIOC_G/S_FREQUENCY: OK (Not Supported) >> test VIDIOC_ENUMAUDOUT: OK (Not Supported) >> test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported) >> test VIDIOC_G/S_AUDOUT: OK (Not Supported) >> Outputs: 0 Audio Outputs: 0 Modulators: 0 >> >> Input/Output configuration ioctls: >> test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported) >> test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported) >> test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported) >> test VIDIOC_G/S_EDID: OK (Not Supported) >> >> Test input 0: >> >> Control ioctls: >> test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported) >> test VIDIOC_QUERYCTRL: OK (Not Supported) >> test VIDIOC_G/S_CTRL: OK (Not Supported) >> test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported) >> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported) >> test VIDIOC_G/S_JPEGCOMP: OK (Not Supported) >> Standard Controls: 0 Private Controls: 0 >> >> Format ioctls: >> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK >> test VIDIOC_G/S_PARM: OK (Not Supported) >>
Re: [PATCH 01/10] doc: DT: camss: Binding document for Qualcomm Camera subsystem driver
Hi Rob, Happy new year, And thank you for the review. On 12/01/2016 12:03 AM, Rob Herring wrote: > On Fri, Nov 25, 2016 at 04:56:53PM +0200, Todor Tomov wrote: >> Add DT binding document for Qualcomm Camera subsystem driver. >> >> Signed-off-by: Todor Tomov >> --- >> .../devicetree/bindings/media/qcom,camss.txt | 196 >> + >> 1 file changed, 196 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/media/qcom,camss.txt >> >> diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt >> b/Documentation/devicetree/bindings/media/qcom,camss.txt >> new file mode 100644 >> index 000..76ad89a >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt >> @@ -0,0 +1,196 @@ >> +Qualcomm Camera Subsystem >> + >> +* Properties >> + >> +- compatible: >> +Usage: required >> +Value type: >> +Definition: Should contain: >> +- "qcom,8x16-camss" > > Don't use wildcards in compatible strings. One string per SoC. Ok, I'll fix this. > >> +- reg: >> +Usage: required >> +Value type: >> +Definition: Register ranges as listed in the reg-names property. >> +- reg-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "csiphy0" >> +- "csiphy0_clk_mux" >> +- "csiphy1" >> +- "csiphy1_clk_mux" >> +- "csid0" >> +- "csid1" >> +- "ispif" >> +- "csi_clk_mux" >> +- "vfe0" > > Kind of looks like the phy's should be separate nodes since each phy has > its own register range, irq, clocks, etc. Yes, there are a lot of hardware resources here. I have decided to keep everything into a single platform device as this represents it better from system point of view. > >> +- interrupts: >> +Usage: required >> +Value type: >> +Definition: Interrupts as listed in the interrupt-names property. >> +- interrupt-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "csiphy0" >> +- "csiphy1" >> +- "csid0" >> +- "csid1" >> +- "ispif" >> +- "vfe0" >> +- power-domains: >> +Usage: required >> +Value type: >> +Definition: A phandle and power domain specifier pairs to the >> +power domain which is responsible for collapsing >> +and restoring power to the peripheral. >> +- clocks: >> +Usage: required >> +Value type: >> +Definition: A list of phandle and clock specifier pairs as listed >> +in clock-names property. >> +- clock-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "camss_top_ahb_clk" >> +- "ispif_ahb_clk" >> +- "csiphy0_timer_clk" >> +- "csiphy1_timer_clk" >> +- "csi0_ahb_clk" >> +- "csi0_clk" >> +- "csi0_phy_clk" >> +- "csi0_pix_clk" >> +- "csi0_rdi_clk" >> +- "csi1_ahb_clk" >> +- "csi1_clk" >> +- "csi1_phy_clk" >> +- "csi1_pix_clk" >> +- "csi1_rdi_clk" >> +- "camss_ahb_clk" >> +- "camss_vfe_vfe_clk" >> +- "camss_csi_vfe_clk" >> +- "iface_clk" >> +- "bus_clk" >> +- vdda-supply: >> +Usage: required >> +Value type: >> +Definition: A phandle to voltage supply for CSI2. >> +- iommus: >> +Usage: required >> +Value type: >> +Definition: A list of phandle and IOMMU specifier pairs. >> + >> +* Nodes >> + >> +- ports: >> +Usage: required >> +Definition: As described in video-interfaces.txt in same directory. >> +Properties: >> +- reg: >> +Usage: required >> +
Re: [PATCH 08/10] media: camss: Add files which handle the video device nodes
Hi Hans, Thank you for the extensive review. On 12/05/2016 03:44 PM, Hans Verkuil wrote: > A few comments below: > > On 11/25/2016 03:57 PM, Todor Tomov wrote: >> These files handle the video device nodes of the camss driver. >> >> Signed-off-by: Todor Tomov >> --- >> drivers/media/platform/qcom/camss-8x16/video.c | 597 >> + >> drivers/media/platform/qcom/camss-8x16/video.h | 67 +++ >> 2 files changed, 664 insertions(+) >> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.c >> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.h >> >> diff --git a/drivers/media/platform/qcom/camss-8x16/video.c >> b/drivers/media/platform/qcom/camss-8x16/video.c >> new file mode 100644 >> index 000..0bf8ea9 >> --- /dev/null >> +++ b/drivers/media/platform/qcom/camss-8x16/video.c >> @@ -0,0 +1,597 @@ > > > >> +static int video_start_streaming(struct vb2_queue *q, unsigned int count) >> +{ >> +struct camss_video *video = vb2_get_drv_priv(q); >> +struct video_device *vdev = video->vdev; >> +struct media_entity *entity; >> +struct media_pad *pad; >> +struct v4l2_subdev *subdev; >> +int ret; >> + >> +ret = media_entity_pipeline_start(&vdev->entity, &video->pipe); >> +if (ret < 0) >> +return ret; >> + >> +ret = video_check_format(video); >> +if (ret < 0) >> +goto error; >> + >> +entity = &vdev->entity; >> +while (1) { >> +pad = &entity->pads[0]; >> +if (!(pad->flags & MEDIA_PAD_FL_SINK)) >> +break; >> + >> +pad = media_entity_remote_pad(pad); >> +if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) >> +break; >> + >> +entity = pad->entity; >> +subdev = media_entity_to_v4l2_subdev(entity); >> + >> +ret = v4l2_subdev_call(subdev, video, s_stream, 1); >> +if (ret < 0 && ret != -ENOIOCTLCMD) >> +goto error; >> +} >> + >> +return 0; >> + >> +error: >> +media_entity_pipeline_stop(&vdev->entity); >> + > > On error all queued buffers must be returned with state VB2_STATE_QUEUED. > > Basically the same as 'camss_video_call(video, flush_buffers);', just with > a different state. Ok, I'll add this. > >> +return ret; >> +} > > > >> +static int video_querycap(struct file *file, void *fh, >> + struct v4l2_capability *cap) >> +{ >> +strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver)); >> +strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); >> +strlcpy(cap->bus_info, "platform:qcom-camss", sizeof(cap->bus_info)); >> +cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | >> +V4L2_CAP_DEVICE_CAPS; >> +cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; > > Don't set capabilities and device_caps here. Instead fill in the struct > video_device > device_caps field and the v4l2 core will take care of cap->capabilities and > cap->device_caps. Ok. > >> + >> +return 0; >> +} >> + >> +static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc >> *f) >> +{ >> +struct camss_video *video = video_drvdata(file); >> +struct v4l2_format format; >> +int ret; >> + >> +if (f->type != video->type) >> +return -EINVAL; >> + >> +if (f->index) >> +return -EINVAL; >> + >> +ret = video_get_subdev_format(video, &format); >> +if (ret < 0) >> +return ret; >> + >> +f->pixelformat = format.fmt.pix.pixelformat; >> + >> +return 0; >> +} >> + >> +static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f) >> +{ >> +struct camss_video *video = video_drvdata(file); >> + >> +if (f->type != video->type) >> +return -EINVAL; >> + >> +*f = video->active_fmt; >> + >> +return 0; >> +} >> + >> +static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f) >> +{ >> +struct camss_
Re: [PATCH 08/10] media: camss: Add files which handle the video device nodes
Hi Laurent, Hans, On 12/05/2016 05:25 PM, Laurent Pinchart wrote: > Hi Hans, > > On Monday 05 Dec 2016 16:02:55 Hans Verkuil wrote: >> On 12/05/2016 03:45 PM, Laurent Pinchart wrote: >>> On Monday 05 Dec 2016 14:44:55 Hans Verkuil wrote: >>>> On 11/25/2016 03:57 PM, Todor Tomov wrote: >>>>> These files handle the video device nodes of the camss driver. >>>>> >>>>> Signed-off-by: Todor Tomov >>>>> --- >>>>> >>>>> drivers/media/platform/qcom/camss-8x16/video.c | 597 + >>>>> drivers/media/platform/qcom/camss-8x16/video.h | 67 +++ >>>>> 2 files changed, 664 insertions(+) >>>>> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.c >>>>> create mode 100644 drivers/media/platform/qcom/camss-8x16/video.h >>> >>> [snip] >>> >>>>> +int msm_video_register(struct camss_video *video, struct v4l2_device >>>>> *v4l2_dev, >>>>> +const char *name) >>>>> +{ >>>>> + struct media_pad *pad = &video->pad; >>>>> + struct video_device *vdev; >>>>> + struct vb2_queue *q; >>>>> + int ret; >>>>> + >>>>> + vdev = video_device_alloc(); >>>>> + if (vdev == NULL) { >>>>> + dev_err(v4l2_dev->dev, "Failed to allocate video >>>>> device\n"); >>>>> + return -ENOMEM; >>>>> + } >>>>> + >>>>> + video->vdev = vdev; >>>>> + >>>>> + q = &video->vb2_q; >>>>> + q->drv_priv = video; >>>>> + q->mem_ops = &vb2_dma_contig_memops; >>>>> + q->ops = &msm_video_vb2_q_ops; >>>>> + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; >>>>> + q->io_modes = VB2_MMAP; >>>> >>>> Add modes VB2_DMABUF and VB2_READ. These are for free, so why not? >>>> Especially DMABUF is of course very desirable to have. >>> >>> I certainly agree with VB2_DMABUF, but I wouldn't expose VB2_READ. read() >>> for this kind of device is inefficient and we should encourage userspace >>> application to move away from it (and certainly make it very clear that >>> new applications should not use read() with this device). >> >> VB2_READ is very nice when debugging (no need to program a stream I/O >> application first) > > There's at least v4l2-ctl and yavta that can (and should) be used for > debugging ;-) > >> and useful when you want to pipe the video. > > Except that you lose frame boundaries. It's really a poor man's solution that > should never be used in any "real" application. I'd rather add an option to > v4l2-ctl to output the video stream to stdout (and/or stderr). > >> Nobody uses read() in 'regular' applications since it is obviously >> inefficient, but I don't see that as a reason not to offer VB2_READ. >> >> I don't think this is something anyone will ever abuse, > > Famous last words ;-) > >> and it is a nice feature to have (and for free as well). > Thank you for the discussion over this. Both of you have reasonable arguments about the read i/o. I'd say that you cannot always save a person from himself. I'll add VB2_READ. -- Best regards, Todor Tomov
[PATCH 00/10] Qualcomm 8x16 Camera Subsystem driver
This patchset adds basic support for the Qualcomm Camera Subsystem found on Qualcomm MSM8916 and APQ8016 processors. The driver implements V4L2, Media controller and V4L2 subdev interfaces. Camera sensor using V4L2 subdev interface in the kernel is supported. The driver is implemented using as a reference the Qualcomm Camera Subsystem driver for Android as found in Code Aurora [1]. The driver supports raw dump of the input data to memory. ISP processing is not supported. The driver is tested on Dragonboard 410C (APQ8016) with one and two OV5645 camera sensors. media-ctl [2] and yavta [3] applications were used for testing. Also Gstreamer 1.4.4 with v4l2src plugin is supported. More information is present in the document added by the third patch. The patchset depends on: v4l: Add packed Bayer raw12 pixel formats [4] media: venus: enable building of Venus video codec driver [5] V4L2 compliance test result: root@linaro-alip:~/v4l-utils/utils/v4l2-compliance# ./v4l2-compliance -s -d /dev/video0 v4l2-compliance SHA : 6a760145f1a6809591a1cb17ee1b06913e4fddd1 Driver Info: Driver name : qcom-camss Card type : Qualcomm Camera Subsystem Bus info : platform:qcom-camss Driver version: 4.9.0 Capabilities : 0x8421 Video Capture Streaming Extended Pix Format Device Capabilities Device Caps : 0x0421 Video Capture Streaming Extended Pix Format Compliance test for device /dev/video0 (not using libv4l2): Required ioctls: test VIDIOC_QUERYCAP: OK Allow for multiple opens: test second video open: OK test VIDIOC_QUERYCAP: OK test VIDIOC_G/S_PRIORITY: OK test for unlimited opens: OK Debug ioctls: test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported) test VIDIOC_LOG_STATUS: OK (Not Supported) Input ioctls: test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported) test VIDIOC_G/S_FREQUENCY: OK (Not Supported) test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported) test VIDIOC_ENUMAUDIO: OK (Not Supported) test VIDIOC_G/S/ENUMINPUT: OK test VIDIOC_G/S_AUDIO: OK (Not Supported) Inputs: 1 Audio Inputs: 0 Tuners: 0 Output ioctls: test VIDIOC_G/S_MODULATOR: OK (Not Supported) test VIDIOC_G/S_FREQUENCY: OK (Not Supported) test VIDIOC_ENUMAUDOUT: OK (Not Supported) test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported) test VIDIOC_G/S_AUDOUT: OK (Not Supported) Outputs: 0 Audio Outputs: 0 Modulators: 0 Input/Output configuration ioctls: test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported) test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported) test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported) test VIDIOC_G/S_EDID: OK (Not Supported) Test input 0: Control ioctls: test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported) test VIDIOC_QUERYCTRL: OK (Not Supported) test VIDIOC_G/S_CTRL: OK (Not Supported) test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported) test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported) test VIDIOC_G/S_JPEGCOMP: OK (Not Supported) Standard Controls: 0 Private Controls: 0 Format ioctls: test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK test VIDIOC_G/S_PARM: OK (Not Supported) test VIDIOC_G_FBUF: OK (Not Supported) test VIDIOC_G_FMT: OK test VIDIOC_TRY_FMT: OK test VIDIOC_S_FMT: OK test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported) test Cropping: OK (Not Supported) test Composing: OK (Not Supported) test Scaling: OK (Not Supported) Codec ioctls: test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported) test VIDIOC_G_ENC_INDEX: OK (Not Supported) test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported) Buffer ioctls: test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK test VIDIOC_EXPBUF: OK (Not Supported) Test input 0: Streaming ioctls: test read/write: OK (Not Supported) test MMAP: OK test USERPTR: OK (Not Supported) test DMABUF: OK (Not Supported) Total: 47, Succeeded: 47, Failed: 0, Warnings: 0 [1] https://source.codeaurora.org/quic/la/kernel/msm-3.10/ [2] https://git.linuxtv.org//v4l-utils.git [3] http://git.ideasonboard.org/yavta.git [4] http://www.spinics.net/lists/linux-media/msg107494.html [5] http://www.spinics.net/lists/linux-media/msg104013.html Todor Tomov (10): doc: DT: camss: Binding document for Qualcomm Camera subsystem driver MAINTAINERS: Add Qualcomm Camera subsystem driver doc: media/v4l-drivers
[PATCH 01/10] doc: DT: camss: Binding document for Qualcomm Camera subsystem driver
Add DT binding document for Qualcomm Camera subsystem driver. Signed-off-by: Todor Tomov --- .../devicetree/bindings/media/qcom,camss.txt | 196 + 1 file changed, 196 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,camss.txt diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt new file mode 100644 index 000..76ad89a --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -0,0 +1,196 @@ +Qualcomm Camera Subsystem + +* Properties + +- compatible: + Usage: required + Value type: + Definition: Should contain: + - "qcom,8x16-camss" +- reg: + Usage: required + Value type: + Definition: Register ranges as listed in the reg-names property. +- reg-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy0_clk_mux" + - "csiphy1" + - "csiphy1_clk_mux" + - "csid0" + - "csid1" + - "ispif" + - "csi_clk_mux" + - "vfe0" +- interrupts: + Usage: required + Value type: + Definition: Interrupts as listed in the interrupt-names property. +- interrupt-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy1" + - "csid0" + - "csid1" + - "ispif" + - "vfe0" +- power-domains: + Usage: required + Value type: + Definition: A phandle and power domain specifier pairs to the + power domain which is responsible for collapsing + and restoring power to the peripheral. +- clocks: + Usage: required + Value type: + Definition: A list of phandle and clock specifier pairs as listed + in clock-names property. +- clock-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "camss_top_ahb_clk" + - "ispif_ahb_clk" + - "csiphy0_timer_clk" + - "csiphy1_timer_clk" + - "csi0_ahb_clk" + - "csi0_clk" + - "csi0_phy_clk" + - "csi0_pix_clk" + - "csi0_rdi_clk" + - "csi1_ahb_clk" + - "csi1_clk" + - "csi1_phy_clk" + - "csi1_pix_clk" + - "csi1_rdi_clk" + - "camss_ahb_clk" + - "camss_vfe_vfe_clk" + - "camss_csi_vfe_clk" + - "iface_clk" + - "bus_clk" +- vdda-supply: + Usage: required + Value type: + Definition: A phandle to voltage supply for CSI2. +- iommus: + Usage: required + Value type: + Definition: A list of phandle and IOMMU specifier pairs. + +* Nodes + +- ports: + Usage: required + Definition: As described in video-interfaces.txt in same directory. + Properties: + - reg: + Usage: required + Value type: + Definition: Selects CSI2 PHY interface - PHY0 or PHY1. + Endpoint node properties: + - clock-lanes: + Usage: required + Value type: + Definition: The clock lane. + - data-lanes: + Usage: required + Value type: + Definition: An array of data lanes. + - qcom,settle-cnt: + Usage: required + Value type: + Definition: The settle count parameter for CSI PHY. + +* An Example + + camss: camss@1b0 { + compatible = "qcom,8x16-camss"; + reg = <0x1b0ac00 0x200>, + <0x1b00030 0x4>, + <0x1b0b000 0x200>, + <0x1b00038 0x4>, + <0x1b08000 0x100>, + <0x1b08400 0x100>, + <0x1b0a000 0x500>, + <0x1b00020 0x10>, + <0x1b1 0x1000>; + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", +
[PATCH 02/10] MAINTAINERS: Add Qualcomm Camera subsystem driver
Add an entry for Qualcomm Camera subsystem driver. Signed-off-by: Todor Tomov --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 411e3b8..0740aee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9971,6 +9971,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git S: Supported F: drivers/net/wireless/ath/ath10k/ +QUALCOMM CAMERA SUBSYSTEM DRIVER +M: Todor Tomov +L: linux-me...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/qcom,camss.txt +F: Documentation/media/v4l-drivers/qcom_camss.rst +F: drivers/media/platform/qcom/camss/ + QUALCOMM EMAC GIGABIT ETHERNET DRIVER M: Timur Tabi L: net...@vger.kernel.org -- 1.9.1
[PATCH 04/10] media: camss: Add CSIPHY files
These files control the CSIPHY modules which are responsible for the physical layer of the CSI2 receivers. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/csiphy.c | 685 drivers/media/platform/qcom/camss-8x16/csiphy.h | 77 +++ 2 files changed, 762 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/csiphy.c create mode 100644 drivers/media/platform/qcom/camss-8x16/csiphy.h diff --git a/drivers/media/platform/qcom/camss-8x16/csiphy.c b/drivers/media/platform/qcom/camss-8x16/csiphy.c new file mode 100644 index 000..42ec7da --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/csiphy.c @@ -0,0 +1,685 @@ +/* + * csiphy.c + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csiphy.h" +#include "camss.h" + +#define MSM_CSIPHY_NAME "msm_csiphy" + +#define CAMSS_CSI_PHY_LNn_CFG2(n) (0x004 + 0x40 * (n)) +#define CAMSS_CSI_PHY_LNn_CFG3(n) (0x008 + 0x40 * (n)) +#define CAMSS_CSI_PHY_GLBL_RESET 0x140 +#define CAMSS_CSI_PHY_GLBL_PWR_CFG 0x144 +#define CAMSS_CSI_PHY_GLBL_IRQ_CMD 0x164 +#define CAMSS_CSI_PHY_HW_VERSION 0x188 +#define CAMSS_CSI_PHY_INTERRUPT_STATUSn(n) (0x18c + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_MASKn(n) (0x1ac + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_CLEARn(n) (0x1cc + 0x4 * (n)) +#define CAMSS_CSI_PHY_GLBL_T_INIT_CFG0 0x1ec +#define CAMSS_CSI_PHY_T_WAKEUP_CFG00x1f4 + +static const u32 csiphy_formats[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, +}; + +/* + * csiphy_isr - CSIPHY module interrupt handler + * @irq: Interrupt line + * @dev: CSIPHY device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t csiphy_isr(int irq, void *dev) +{ + struct csiphy_device *csiphy = dev; + u8 i; + + for (i = 0; i < 8; i++) { + u8 val = readl_relaxed(csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_STATUSn(i)); + writel_relaxed(val, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); + writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_IRQ_CMD); + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_IRQ_CMD); + writel_relaxed(0x0, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); + } + + return IRQ_HANDLED; +} + +/* + * csiphy_reset - Perform software reset on CSIPHY module + * @csiphy: CSIPHY device + */ +static void csiphy_reset(struct csiphy_device *csiphy) +{ + writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); + usleep_range(5000, 8000); + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); +} + +/* + * csiphy_set_power - Power on/off CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @on: Requested power state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_power(struct v4l2_subdev *sd, int on) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct device *dev = to_device_index(csiphy, csiphy->id); + int ret; + + if (on) { + u8 hw_version; + + ret = camss_enable_clocks(csiphy->nclocks, csiphy->clock, dev); + if (ret < 0) + return ret; + + enable_irq(csiphy->irq); + + csiphy_reset(csiphy); + + hw_version = readl_relaxed(csiphy->base + + CAMSS_CSI_PHY_HW_VERSION); + dev_dbg(dev, "CSIPHY HW Version = 0x%02x\n", hw_version); + } else { +
[PATCH 03/10] doc: media/v4l-drivers: Add Qualcomm Camera Subsystem driver document
Add a document to describe Qualcomm Camera Subsystem driver. Signed-off-by: Todor Tomov --- Documentation/media/v4l-drivers/index.rst | 1 + Documentation/media/v4l-drivers/qcom_camss.rst | 124 + 2 files changed, 125 insertions(+) create mode 100644 Documentation/media/v4l-drivers/qcom_camss.rst diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index aac566f..ba2aaeb 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -45,6 +45,7 @@ For more details see the file COPYING in the source distribution of Linux. omap4_camera pvrusb2 pxa_camera + qcom_camss radiotrack saa7134 sh_mobile_ceu_camera diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst new file mode 100644 index 000..4707ea7 --- /dev/null +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -0,0 +1,124 @@ +.. include:: + +Qualcomm Camera Subsystem driver + + +Introduction + + +This file documents the Qualcomm Camera Subsystem driver located under +drivers/media/platform/qcom/camss-8x16. + +The current version of the driver supports the Camera Subsystem found on +Qualcomm MSM8916 and APQ8016 processors. + +The driver implements V4L2, Media controller and V4L2 subdev interfaces. +Camera sensor using V4L2 subdev interface in the kernel is supported. + +The driver is implemented using as a reference the Qualcomm Camera Subsystem +driver for Android as found in Code Aurora [#f1]_. + + +Qualcomm Camera Subsystem hardware +-- + +The Camera Subsystem hardware found on 8x16 processors and supported by the +driver consists of: + +- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. + A separate camera sensor can be connected to each of the CSIPHY module; +- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application layer + of the CSI2 receivers. A CSID can decode data stream from any of the CSIPHY. + Each CSID also contains a TG (Test Generator) block which can generate + artificial input data for test purposes; +- ISPIF (ISP Interface) module. Handles the routing of the data streams from + the CSIDs to the inputs of the VFE; +- VFE (Video Front End) module. Contains a pipeline of image processing hardware + blocks. The VFE has different input interfaces. The PIX input interface feeds + the input data to the image processing pipeline. Three RDI input interfaces + bypass the image processing pipeline. The VFE also contains the AXI bus + interface which writes the output data to memory. + + +Supported functionality +--- + +The current version of the driver supports: + +- input from camera sensor via CSIPHY; +- generation of test input data by the TG in CSID; +- raw dump of the input data to memory. RDI interface of VFE is supported. + PIX interface (ISP processing, statistics engines, resize/crop, format + conversion) is not supported in the current version; +- concurrent and independent usage of two data inputs - could be camera sensors + and/or TG. + + +Driver Architecture and Design +-- + +The driver implements the V4L2 subdev interface. With the goal to model the +hardware links between the modules and to expose a clean, logical and usable +interface, the driver is split into V4L2 sub-devices as follows: + +- 2 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device; +- 2 CSID sub-devices - each CSID is represented by a single sub-device; +- 2 ISPIF sub-devices - ISPIF is represented by a number of sub-devices equal + to the number of CSID sub-devices; +- 3 VFE sub-devices - VFE is represented by a number of sub-devices equal to + the number of RDI input interfaces. + +The considerations to split the driver in this particular way are as follows: + +- representing CSIPHY and CSID modules by a separate sub-device for each module + allows to model the hardware links between these modules; +- representing VFE by a separate sub-devices for each RDI input interface allows + to use the three RDI interfaces concurently and independently as this is + supported by the hardware; +- representing ISPIF by a number of sub-devices equal to the number of CSID + sub-devices allows to create linear media controller pipelines when using two + cameras simultaneously. This avoids branches in the pipelines which otherwise + will require a) userspace and b) media framework (e.g. power on/off + operations) to make assumptions about the data flow from a sink pad to a + source pad on a single media entity. + +Each VFE sub-device is linked to a separate video device node. + +The complete list of the media entities (V4L2 sub-devices and video device +nodes) is as follows: + +- msm_csiphy0 +- msm_csiphy1 +- msm_csid0 +- msm_csid1
[PATCH 07/10] media: camss: Add VFE files
These files control the VFE module. The VFE has different input interfaces. The PIX input interface feeds the input data to an image processing pipeline. Three RDI input interfaces bypass the image processing pipeline. The VFE also contains the AXI bus interface which writes the output data to memory. RDI interfaces are supported in this version. PIX interface is not supported. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/vfe.c | 1877 ++ drivers/media/platform/qcom/camss-8x16/vfe.h | 112 ++ 2 files changed, 1989 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/vfe.c create mode 100644 drivers/media/platform/qcom/camss-8x16/vfe.h diff --git a/drivers/media/platform/qcom/camss-8x16/vfe.c b/drivers/media/platform/qcom/camss-8x16/vfe.c new file mode 100644 index 000..86fdf47 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/vfe.c @@ -0,0 +1,1877 @@ +/* + * vfe.c + * + * Qualcomm MSM Camera Subsystem - VFE Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vfe.h" +#include "camss.h" + +#define MSM_VFE_NAME "msm_vfe" + +#define vfe_line_array(ptr_line) \ + ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)])) + +#define to_vfe(ptr_line) \ + container_of(vfe_line_array(ptr_line), struct vfe_device, ptr_line) + +#define VFE_0_HW_VERSION 0x000 + +#define VFE_0_GLOBAL_RESET_CMD 0x00c +#define VFE_0_GLOBAL_RESET_CMD_CORE(1 << 0) +#define VFE_0_GLOBAL_RESET_CMD_CAMIF (1 << 1) +#define VFE_0_GLOBAL_RESET_CMD_BUS (1 << 2) +#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG (1 << 3) +#define VFE_0_GLOBAL_RESET_CMD_REGISTER(1 << 4) +#define VFE_0_GLOBAL_RESET_CMD_TIMER (1 << 5) +#define VFE_0_GLOBAL_RESET_CMD_PM (1 << 6) +#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR(1 << 7) +#define VFE_0_GLOBAL_RESET_CMD_TESTGEN (1 << 8) + +#define VFE_0_IRQ_CMD 0x024 +#define VFE_0_IRQ_CMD_GLOBAL_CLEAR (1 << 0) + +#define VFE_0_IRQ_MASK_0 0x028 +#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)(1 << ((n) + 5)) +#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_MASK_0_RESET_ACK (1 << 31) +#define VFE_0_IRQ_MASK_1 0x02c +#define VFE_0_IRQ_MASK_1_VIOLATION (1 << 7) +#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK (1 << 8) +#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)(1 << ((n) + 9)) + +#define VFE_0_IRQ_CLEAR_0 0x030 +#define VFE_0_IRQ_CLEAR_1 0x034 + +#define VFE_0_IRQ_STATUS_0 0x038 +#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5)) +#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_STATUS_0_RESET_ACK (1 << 31) +#define VFE_0_IRQ_STATUS_1 0x03c +#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK(1 << 8) + +#define VFE_0_BUS_CMD 0x4c +#define VFE_0_BUS_CMD_Mx_RLD_CMD(x)(1 << (x)) + +#define VFE_0_BUS_CFG 0x050 + +#define VFE_0_BUS_XBAR_CFG_x(x)(0x58 + 0x4 * ((x) / 2)) +#define VFE_0_BUS_XBAR_CFG_x_M0_SINGLE_STREAM_SEL_SHIFT8 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 5 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 6 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 7 + +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x06c + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT1 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x070 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x074 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)(0x078 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT2 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1F << 2) + +#define VFE_0_BUS_IMAGE_MASTER
[PATCH 06/10] media: camss: Add ISPIF files
These files control the ISPIF module which handles the routing of the data streams from the CSIDs to the inputs of the VFE. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/ispif.c | 1105 drivers/media/platform/qcom/camss-8x16/ispif.h | 85 ++ 2 files changed, 1190 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/ispif.c create mode 100644 drivers/media/platform/qcom/camss-8x16/ispif.h diff --git a/drivers/media/platform/qcom/camss-8x16/ispif.c b/drivers/media/platform/qcom/camss-8x16/ispif.c new file mode 100644 index 000..7d56b7d --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/ispif.c @@ -0,0 +1,1105 @@ +/* + * ispif.c + * + * Qualcomm MSM Camera Subsystem - ISPIF Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ispif.h" +#include "camss.h" + +#define MSM_ISPIF_NAME "msm_ispif" + +#define ispif_line_array(ptr_line) \ + ((const struct ispif_line (*)[]) &(ptr_line[-(ptr_line->id)])) + +#define to_ispif(ptr_line) \ + container_of(ispif_line_array(ptr_line), struct ispif_device, ptr_line) + +#define ISPIF_RST_CMD_00x008 +#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x01c +#define ISPIF_VFE_m_CTRL_0(m) (0x200 + 0x200 * (m)) +#define ISPIF_VFE_m_CTRL_0_PIX0_LINE_BUF_EN(1 << 6) +#define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE 0x1249 +#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK 0x1fff +#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE 0x02492000 +#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK 0x03ffe000 +#define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20c + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE 0x1249 +#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK 0x1fff +#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE 0x02492000 +#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK 0x03ffe000 +#define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE 0x1249 +#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK 0x1fff +#define ISPIF_VFE_m_IRQ_STATUS_0(m)(0x21c + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_STATUS_1(m)(0x220 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_STATUS_2(m)(0x224 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_CLEAR_0(m) (0x230 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_CLEAR_1(m) (0x234 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_CLEAR_2(m) (0x238 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_INPUT_SEL(m) (0x244 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_CMD_0(m) (0x248 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_CMD_1(m) (0x24c + 0x200 * (m)) +#define ISPIF_VFE_m_PIX_INTF_n_CID_MASK(m, n) \ + (0x254 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_CID_MASK(m, n) \ + (0x264 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_PIX_INTF_n_STATUS(m, n)\ + (0x2c0 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_STATUS(m, n)\ + (0x2d0 + 0x200 * (m) + 0x4 * (n)) + +#define CSI_PIX_CLK_MUX_SEL0x000 +#define CSI_RDI_CLK_MUX_SEL0x008 + +#define ISPIF_TIMEOUT_SLEEP_US 1000 +#define ISPIF_TIMEOUT_ALL_US 100 +#define ISPIF_RESET_TIMEOUT_MS 500 + +enum ispif_intf_cmd { + CMD_DISABLE_FRAME_BOUNDARY = 0x0, + CMD_ENABLE_FRAME_BOUNDARY = 0x1, + CMD_DISABLE_IMMEDIATELY = 0x2, + CMD_ALL_DISABLE_IMMEDIATELY = 0x, + CMD_ALL_NO_CHANGE = 0x, +}; + +static const u32 ispif_formats[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, +}; + +/* + * ispif_isr - ISPIF module interrup
[PATCH 09/10] media: camms: Add core files
These files implement the platform driver code. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/camss.c | 603 + drivers/media/platform/qcom/camss-8x16/camss.h | 93 2 files changed, 696 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss.h diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c new file mode 100644 index 000..6d9ef1f --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss.c @@ -0,0 +1,603 @@ +/* + * camss.c + * + * Qualcomm MSM Camera Subsystem - Core + * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "camss.h" + +static struct resources csiphy_res[] = { + /* CSIPHY0 */ + { + .regulator = { NULL }, + .clock = { "camss_top_ahb_clk", "ispif_ahb_clk", + "camss_ahb_clk", "csiphy0_timer_clk" }, + .clock_rate = { 0, 0, 0, 2 }, + .reg = { "csiphy0", "csiphy0_clk_mux" }, + .interrupt = { "csiphy0" } + }, + + /* CSIPHY1 */ + { + .regulator = { NULL }, + .clock = { "camss_top_ahb_clk", "ispif_ahb_clk", + "camss_ahb_clk", "csiphy1_timer_clk" }, + .clock_rate = { 0, 0, 0, 2 }, + .reg = { "csiphy1", "csiphy1_clk_mux" }, + .interrupt = { "csiphy1" } + } +}; + +static struct resources csid_res[] = { + /* CSID0 */ + { + .regulator = { "vdda" }, + .clock = { "camss_top_ahb_clk", "ispif_ahb_clk", + "csi0_ahb_clk", "camss_ahb_clk", + "csi0_clk", "csi0_phy_clk", + "csi0_pix_clk", "csi0_rdi_clk" }, + .clock_rate = { 0, 0, 0, 0, 2, 0, 0, 0 }, + .reg = { "csid0" }, + .interrupt = { "csid0" } + }, + + /* CSID1 */ + { + .regulator = { "vdda" }, + .clock = { "camss_top_ahb_clk", "ispif_ahb_clk", + "csi1_ahb_clk", "camss_ahb_clk", + "csi1_clk", "csi1_phy_clk", + "csi1_pix_clk", "csi1_rdi_clk" }, + .clock_rate = { 0, 0, 0, 0, 2, 0, 0, 0 }, + .reg = { "csid1" }, + .interrupt = { "csid1" } + }, +}; + +static struct resources_ispif ispif_res = { + /* ISPIF */ + .clock = { "camss_top_ahb_clk", "camss_ahb_clk", "ispif_ahb_clk", + "csi0_clk", "csi0_pix_clk", "csi0_rdi_clk", + "csi1_clk", "csi1_pix_clk", "csi1_rdi_clk" }, + .clock_for_reset = { "camss_vfe_vfe_clk", "camss_csi_vfe_clk" }, + .reg = { "ispif", "csi_clk_mux" }, + .interrupt = "ispif" + +}; + +static struct resources vfe_res = { + /* VFE0 */ + .regulator = { NULL }, + .clock = { "camss_top_ahb_clk", "camss_vfe_vfe_clk", + "camss_csi_vfe_clk", "iface_clk", + "bus_clk", "camss_ahb_clk" }, + .clock_rate = { 0, 32000, 0, 0, 0, 0, 0, 0 }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" } +}; + +/* + * camss_enable_clocks - Enable multiple clocks + * @nclocks: Number of clocks in clock array + * @clock: Clock array + * @dev: Device + * + * Return 0 on success or a negative error code otherwise + */ +int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev) +{ + int ret; + int i; + + for (i = 0; i < nclocks; i++) { + ret = clk_prepare_enable(clock[i
[PATCH 08/10] media: camss: Add files which handle the video device nodes
These files handle the video device nodes of the camss driver. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/video.c | 597 + drivers/media/platform/qcom/camss-8x16/video.h | 67 +++ 2 files changed, 664 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/video.c create mode 100644 drivers/media/platform/qcom/camss-8x16/video.h diff --git a/drivers/media/platform/qcom/camss-8x16/video.c b/drivers/media/platform/qcom/camss-8x16/video.c new file mode 100644 index 000..0bf8ea9 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/video.c @@ -0,0 +1,597 @@ +/* + * video.c + * + * Qualcomm MSM Camera Subsystem - V4L2 device node + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "video.h" +#include "camss.h" + +/* + * struct format_info - ISP media bus format information + * @code: V4L2 media bus format code + * @pixelformat: V4L2 pixel format FCC identifier + * @bpp: Bits per pixel when stored in memory + */ +static const struct format_info { + u32 code; + u32 pixelformat; + unsigned int bpp; +} formats[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 16 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 16 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 16 }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 16 }, + { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8 }, + { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8 }, + { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8 }, + { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8 }, + { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 10 }, + { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 10 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 10 }, + { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 10 }, + { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 }, + { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 }, + { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 } +}; + +/* - + * Helper functions + */ + +/* + * video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format + * @mbus: v4l2_mbus_framefmt format (input) + * @pix: v4l2_pix_format format (output) + * + * Fill the output pix structure with information from the input mbus format. + * + * Return 0 on success or a negative error code otherwise + */ +static unsigned int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus, + struct v4l2_pix_format *pix) +{ + unsigned int i; + + memset(pix, 0, sizeof(*pix)); + pix->width = mbus->width; + pix->height = mbus->height; + + for (i = 0; i < ARRAY_SIZE(formats); ++i) { + if (formats[i].code == mbus->code) + break; + } + + if (WARN_ON(i == ARRAY_SIZE(formats))) + return -EINVAL; + + pix->pixelformat = formats[i].pixelformat; + pix->bytesperline = pix->width * formats[i].bpp / 8; + pix->bytesperline = ALIGN(pix->bytesperline, 8); + pix->sizeimage = pix->bytesperline * pix->height; + pix->colorspace = mbus->colorspace; + pix->field = mbus->field; + + return 0; +} + +static struct v4l2_subdev *video_remote_subdev(struct camss_video *video, + u32 *pad) +{ + struct media_pad *remote; + + remote = media_entity_remote_pad(&video->pad); + + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) + return NULL; + + if (pad) + *pad = remote->index; + + return media_entity_to_v4l2_subdev(remote->entity); +} + +static int video_get_subdev_format(struct camss_video *video, + struct v4l2_format *format) +{ + struct v4l2_subdev_format fmt; + struct v4l2_subdev *subdev; + u32 pad; + int ret; + + subdev = video_remote_subdev(video, &pad); + if (subdev == NULL) + return -EINVAL; + + fmt.pad = pad; + fmt.which = V4L2_SUBDEV
[PATCH 05/10] media: camss: Add CSID files
These files control the CSID modules which handle the protocol and application layer of the CSI2 receivers. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/camss-8x16/csid.c | 1071 + drivers/media/platform/qcom/camss-8x16/csid.h | 82 ++ 2 files changed, 1153 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/csid.c create mode 100644 drivers/media/platform/qcom/camss-8x16/csid.h diff --git a/drivers/media/platform/qcom/camss-8x16/csid.c b/drivers/media/platform/qcom/camss-8x16/csid.c new file mode 100644 index 000..c7b8b88 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/csid.c @@ -0,0 +1,1071 @@ +/* + * csid.c + * + * Qualcomm MSM Camera Subsystem - CSID Module + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2016 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csid.h" +#include "camss.h" + +#define MSM_CSID_NAME "msm_csid" + +#define CAMSS_CSID_HW_VERSION 0x0 +#define CAMSS_CSID_CORE_CTRL_0 0x004 +#define CAMSS_CSID_CORE_CTRL_1 0x008 +#define CAMSS_CSID_RST_CMD 0x00c +#define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG(n)(0x020 + 0x4 * (n)) +#define CAMSS_CSID_IRQ_CLEAR_CMD 0x060 +#define CAMSS_CSID_IRQ_MASK0x064 +#define CAMSS_CSID_IRQ_STATUS 0x068 +#define CAMSS_CSID_TG_CTRL 0x0a0 +#define CAMSS_CSID_TG_VC_CFG 0x0a4 +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING0x3ff +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING0x7f +#define CAMSS_CSID_TG_DT_n_CGG_0(n)(0x0ac + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_1(n)(0x0b0 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_2(n)(0x0b4 + 0xc * (n)) + +#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 +#define DATA_TYPE_YUV422_8BIT 0x1e +#define DATA_TYPE_RAW_6BIT 0x28 +#define DATA_TYPE_RAW_8BIT 0x2a +#define DATA_TYPE_RAW_10BIT0x2b +#define DATA_TYPE_RAW_12BIT0x2c + +#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 +#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 +#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 +#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 + +#define CSID_RESET_TIMEOUT_MS 500 + +static const struct { + u32 code; + u32 uncompressed; + u8 data_type; + u8 decode_format; + u8 uncompr_bpp; +} csid_input_fmts[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16 + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16 + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16 + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16 + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8 + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8 + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8 + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8 + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRES
[PATCH 10/10] media: camss: Add Makefiles and Kconfig files
Add Makefiles and Kconfig files to build the camss driver. Signed-off-by: Todor Tomov --- drivers/media/platform/qcom/Kconfig | 5 + drivers/media/platform/qcom/Makefile| 1 + drivers/media/platform/qcom/camss-8x16/Makefile | 12 3 files changed, 18 insertions(+) create mode 100644 drivers/media/platform/qcom/Kconfig create mode 100644 drivers/media/platform/qcom/Makefile create mode 100644 drivers/media/platform/qcom/camss-8x16/Makefile diff --git a/drivers/media/platform/qcom/Kconfig b/drivers/media/platform/qcom/Kconfig new file mode 100644 index 000..743ab88 --- /dev/null +++ b/drivers/media/platform/qcom/Kconfig @@ -0,0 +1,5 @@ + +menuconfig VIDEO_QCOM_CAMSS + tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver" + depends on ARCH_QCOM && VIDEO_V4L2 + select VIDEOBUF2_DMA_CONTIG diff --git a/drivers/media/platform/qcom/Makefile b/drivers/media/platform/qcom/Makefile new file mode 100644 index 000..2d73819 --- /dev/null +++ b/drivers/media/platform/qcom/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= camss-8x16/ diff --git a/drivers/media/platform/qcom/camss-8x16/Makefile b/drivers/media/platform/qcom/camss-8x16/Makefile new file mode 100644 index 000..839e5f6 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/Makefile @@ -0,0 +1,12 @@ +# Makefile for Qualcomm CAMSS driver + +ccflags-y += -Idrivers/media/platform/qcom/camss +qcom-camss-objs += \ + camss.o \ + csid.o \ + csiphy.o \ + ispif.o \ + vfe.o \ + video.o \ + +obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom-camss.o -- 1.9.1
[PATCH v8 1/2] media: i2c/ov5645: add the device tree binding document
Add the document for ov5645 device tree binding. Signed-off-by: Todor Tomov Reviewed-by: Laurent Pinchart --- .../devicetree/bindings/media/i2c/ov5645.txt | 54 ++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5645.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov5645.txt b/Documentation/devicetree/bindings/media/i2c/ov5645.txt new file mode 100644 index 000..fd7aec9 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov5645.txt @@ -0,0 +1,54 @@ +* Omnivision 1/4-Inch 5Mp CMOS Digital Image Sensor + +The Omnivision OV5645 is a 1/4-Inch CMOS active pixel digital image sensor with +an active array size of 2592H x 1944V. It is programmable through a serial I2C +interface. + +Required Properties: +- compatible: Value should be "ovti,ov5645". +- clocks: Reference to the xclk clock. +- clock-names: Should be "xclk". +- clock-frequency: Frequency of the xclk clock. +- enable-gpios: Chip enable GPIO. Polarity is GPIO_ACTIVE_HIGH. This corresponds + to the hardware pin PWDNB which is physically active low. +- reset-gpios: Chip reset GPIO. Polarity is GPIO_ACTIVE_LOW. This corresponds to + the hardware pin RESETB. +- vdddo-supply: Chip digital IO regulator. +- vdda-supply: Chip analog regulator. +- vddd-supply: Chip digital core regulator. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + &i2c1 { + ... + + ov5645: ov5645@78 { + compatible = "ovti,ov5645"; + reg = <0x78>; + + enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_rear_default>; + + clocks = <&clks 200>; + clock-names = "xclk"; + clock-frequency = <2388>; + + vdddo-supply = <&camera_dovdd_1v8>; + vdda-supply = <&camera_avdd_2v8>; + vddd-supply = <&camera_dvdd_1v2>; + + port { + ov5645_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0 2>; + remote-endpoint = <&csi0_ep>; + }; + }; + }; + }; -- 1.9.1
[PATCH v8 2/2] media: Add a driver for the ov5645 camera sensor.
The ov5645 sensor from Omnivision supports up to 2592x1944 and CSI2 interface. The driver adds support for the following modes: - 1280x960 - 1920x1080 - 2592x1944 Output format is packed 8bit UYVY. Signed-off-by: Todor Tomov Reviewed-by: Laurent Pinchart --- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov5645.c | 1351 3 files changed, 1364 insertions(+) create mode 100644 drivers/media/i2c/ov5645.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index cee1dae..be4ded8 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -531,6 +531,18 @@ config VIDEO_OV2659 To compile this driver as a module, choose M here: the module will be called ov2659. +config VIDEO_OV5645 + tristate "OmniVision OV5645 sensor support" + depends on OF + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV5645 camera. + + To compile this driver as a module, choose M here: the + module will be called ov5645. + config VIDEO_OV7640 tristate "OmniVision OV7640 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 5bc7bbe..8b0b8ca 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o +obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV9650) += ov9650.o diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c new file mode 100644 index 000..5d2af33 --- /dev/null +++ b/drivers/media/i2c/ov5645.c @@ -0,0 +1,1351 @@ +/* + * Driver for the OV5645 camera sensor. + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015 By Tech Design S.L. All Rights Reserved. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Based on: + * - the OV5645 driver from QC msm-3.10 kernel on codeaurora.org: + * https://us.codeaurora.org/cgit/quic/la/kernel/msm-3.10/tree/drivers/ + * media/platform/msm/camera_v2/sensor/ov5645.c?h=LA.BR.1.2.4_rb1.41 + * - the OV5640 driver posted on linux-media: + * https://www.mail-archive.com/linux-media%40vger.kernel.org/msg92671.html + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OV5645_VOLTAGE_ANALOG 280 +#define OV5645_VOLTAGE_DIGITAL_CORE 150 +#define OV5645_VOLTAGE_DIGITAL_IO 180 + +#define OV5645_SYSTEM_CTRL00x3008 +#defineOV5645_SYSTEM_CTRL0_START 0x02 +#defineOV5645_SYSTEM_CTRL0_STOP0x42 +#define OV5645_CHIP_ID_HIGH0x300a +#defineOV5645_CHIP_ID_HIGH_BYTE0x56 +#define OV5645_CHIP_ID_LOW 0x300b +#defineOV5645_CHIP_ID_LOW_BYTE 0x45 +#define OV5645_AWB_MANUAL_CONTROL 0x3406 +#defineOV5645_AWB_MANUAL_ENABLEBIT(0) +#define OV5645_AEC_PK_MANUAL 0x3503 +#defineOV5645_AEC_MANUAL_ENABLEBIT(0) +#defineOV5645_AGC_MANUAL_ENABLEBIT(1) +#define OV5645_TIMING_TC_REG20 0x3820 +#defineOV5645_SENSOR_VFLIP BIT(1) +#defineOV5645_ISP_VFLIPBIT(2) +#define OV5645_TIMING_TC_REG21 0x3821 +#defineOV5645_SENSOR_MIRRORBIT(1) +#define OV5645_PRE_ISP_TEST_SETTING_1 0x503d +#defineOV5645_TEST_PATTERN_MASK0x3 +#defineOV5645_SET_TEST_PATTERN(x) ((x) & OV5645_TEST_PATTERN_MASK) +#defineOV5645_TEST_PATTERN_ENABLE BIT(7) +#define OV5645_SDE_SAT_U 0x5583 +#define OV5645_SDE_SAT_V 0x5584 + +struct reg_value { + u16 reg; + u8 val; +}; + +struct ov5645_mode_info { + u32