cron job: media_tree daily build: ERRORS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Fri Mar 2 05:00:18 CET 2018 media-tree git hash:e3e389f931a14ddf43089c7db92fc5d74edf93a4 media_build git hash: c3a4fa1a633e24b4a607a78ad11a61598ee177b6 v4l-utils git hash: ff14bf4192d28408afefb968b36850dc5ee19f53 gcc version:i686-linux-gcc (GCC) 7.3.0 sparse version: v0.5.0-3994-g45eb2282 smatch version: v0.5.0-3994-g45eb2282 host hardware: x86_64 host os:4.14.0-3-amd64 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-multi: OK linux-git-arm-pxa: OK linux-git-arm-stm32: OK linux-git-arm64: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.36.4-i686: ERRORS linux-2.6.36.4-x86_64: ERRORS linux-2.6.37.6-i686: ERRORS linux-2.6.37.6-x86_64: ERRORS linux-2.6.38.8-i686: ERRORS linux-2.6.38.8-x86_64: ERRORS linux-2.6.39.4-i686: ERRORS linux-2.6.39.4-x86_64: ERRORS linux-3.0.60-i686: ERRORS linux-3.0.60-x86_64: ERRORS linux-3.1.10-i686: ERRORS linux-3.1.10-x86_64: ERRORS linux-3.2.98-i686: ERRORS linux-3.2.98-x86_64: ERRORS linux-3.3.8-i686: ERRORS linux-3.3.8-x86_64: ERRORS linux-3.4.27-i686: ERRORS linux-3.4.27-x86_64: ERRORS linux-3.5.7-i686: ERRORS linux-3.5.7-x86_64: ERRORS linux-3.6.11-i686: ERRORS linux-3.6.11-x86_64: ERRORS linux-3.7.4-i686: ERRORS linux-3.7.4-x86_64: ERRORS linux-3.8-i686: ERRORS linux-3.8-x86_64: ERRORS linux-3.9.2-i686: ERRORS linux-3.9.2-x86_64: ERRORS linux-3.10.1-i686: ERRORS linux-3.10.1-x86_64: ERRORS linux-3.11.1-i686: ERRORS linux-3.11.1-x86_64: ERRORS linux-3.12.67-i686: ERRORS linux-3.12.67-x86_64: ERRORS linux-3.13.11-i686: ERRORS linux-3.13.11-x86_64: ERRORS linux-3.14.9-i686: ERRORS linux-3.14.9-x86_64: ERRORS linux-3.15.2-i686: ERRORS linux-3.15.2-x86_64: ERRORS linux-3.16.53-i686: ERRORS linux-3.16.53-x86_64: ERRORS linux-3.17.8-i686: ERRORS linux-3.17.8-x86_64: ERRORS linux-3.18.93-i686: ERRORS linux-3.18.93-x86_64: ERRORS linux-3.19-i686: ERRORS linux-3.19-x86_64: ERRORS linux-4.0.9-i686: ERRORS linux-4.0.9-x86_64: ERRORS linux-4.1.49-i686: ERRORS linux-4.1.49-x86_64: ERRORS linux-4.2.8-i686: ERRORS linux-4.2.8-x86_64: ERRORS linux-4.3.6-i686: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.115-i686: OK linux-4.4.115-x86_64: OK linux-4.5.7-i686: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-i686: OK linux-4.6.7-x86_64: WARNINGS linux-4.7.5-i686: OK linux-4.7.5-x86_64: WARNINGS linux-4.8-i686: OK linux-4.8-x86_64: WARNINGS linux-4.9.80-i686: OK linux-4.9.80-x86_64: OK linux-4.10.14-i686: OK linux-4.10.14-x86_64: WARNINGS linux-4.11-i686: OK linux-4.11-x86_64: WARNINGS linux-4.12.1-i686: OK linux-4.12.1-x86_64: WARNINGS linux-4.13-i686: OK linux-4.13-x86_64: OK linux-4.14.17-i686: OK linux-4.14.17-x86_64: OK linux-4.15.2-i686: OK linux-4.15.2-x86_64: OK linux-4.16-rc1-i686: OK linux-4.16-rc1-x86_64: OK apps: WARNINGS spec-git: OK sparse: WARNINGS smatch: OK Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
[PATCH v11 03/32] rcar-vin: add Gen3 devicetree bindings documentation
Document the devicetree bindings for the CSI-2 inputs available on Gen3. There is a need to add a custom property 'renesas,id' and to define which CSI-2 input is described in which endpoint under the port@1 node. This information is needed since there are a set of predefined routes between each VIN and CSI-2 block. This routing table will be kept inside the driver but in order for it to act on it it must know which VIN and CSI-2 is which. Signed-off-by: Niklas SöderlundAcked-by: Rob Herring Reviewed-by: Laurent Pinchart --- .../devicetree/bindings/media/rcar_vin.txt | 118 ++--- 1 file changed, 106 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index c60e6b0a89b67a8c..90d92836284b7f68 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -2,8 +2,12 @@ Renesas R-Car Video Input driver (rcar_vin) --- The rcar_vin device provides video input capabilities for the Renesas R-Car -family of devices. The current blocks are always slaves and suppot one input -channel which can be either RGB, YUYV or BT656. +family of devices. + +Each VIN instance has a single parallel input that supports RGB and YUV video, +with both external synchronization and BT.656 synchronization for the latter. +Depending on the instance the VIN input is connected to external SoC pins, or +on Gen3 platforms to a CSI-2 receiver. - compatible: Must be one or more of the following - "renesas,vin-r8a7743" for the R8A7743 device @@ -16,6 +20,8 @@ channel which can be either RGB, YUYV or BT656. - "renesas,vin-r8a7793" for the R8A7793 device - "renesas,vin-r8a7794" for the R8A7794 device - "renesas,vin-r8a7795" for the R8A7795 device + - "renesas,vin-r8a7796" for the R8A7796 device + - "renesas,vin-r8a77970" for the R8A77970 device - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible device. - "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device. @@ -31,21 +37,38 @@ channel which can be either RGB, YUYV or BT656. Additionally, an alias named vinX will need to be created to specify which video input device this is. -The per-board settings: +The per-board settings Gen2 platforms: - port sub-node describing a single endpoint connected to the vin as described in video-interfaces.txt[1]. Only the first one will be considered as each vin interface has one input port. - These settings are used to work out video input format and widths - into the system. +The per-board settings Gen3 platforms: +Gen3 platforms can support both a single connected parallel input source +from external SoC pins (port0) and/or multiple parallel input sources +from local SoC CSI-2 receivers (port1) depending on SoC. -Device node example +- renesas,id - ID number of the VIN, VINx in the documentation. +- ports +- port 0 - sub-node describing a single endpoint connected to the VIN + from external SoC pins described in video-interfaces.txt[1]. + Describing more then one endpoint in port 0 is invalid. Only VIN + instances that are connected to external pins should have port 0. +- port 1 - sub-nodes describing one or more endpoints connected to + the VIN from local SoC CSI-2 receivers. The endpoint numbers must + use the following schema. - aliases { - vin0 = - }; +- Endpoint 0 - sub-node describing the endpoint connected to CSI20 +- Endpoint 1 - sub-node describing the endpoint connected to CSI21 +- Endpoint 2 - sub-node describing the endpoint connected to CSI40 +- Endpoint 3 - sub-node describing the endpoint connected to CSI41 + +Device node example for Gen2 platforms +-- + +aliases { +vin0 = +}; vin0: vin@e6ef { compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; @@ -55,8 +78,8 @@ Device node example status = "disabled"; }; -Board setup example (vin1 composite video input) - +Board setup example for Gen2 platforms (vin1 composite video input) +--- { status = "ok"; @@ -95,6 +118,77 @@ Board setup example (vin1 composite video input) }; }; +Device node example for Gen3 platforms +-- +vin0: video@e6ef { +compatible = "renesas,vin-r8a7795"; +reg = <0 0xe6ef 0 0x1000>; +interrupts = ; +clocks = < CPG_MOD 811>; +power-domains = <
[PATCH v11 15/32] rcar-vin: break out format alignment and checking
Part of the format alignment and checking can be shared with the Gen3 format handling. Break that part out to a separate function. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 96 - 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index b94ca9ffb1d3b323..3290e603b44cdf3a 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -87,6 +87,59 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) return pix->bytesperline * pix->height; } +static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) +{ + u32 walign; + + if (!rvin_format_from_pixel(pix->pixelformat) || + (vin->info->model == RCAR_M1 && +pix->pixelformat == V4L2_PIX_FMT_XBGR32)) + pix->pixelformat = RVIN_DEFAULT_FORMAT; + + switch (pix->field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + break; + case V4L2_FIELD_ALTERNATE: + /* +* Driver do not (yet) support outputting ALTERNATE to a +* userspace. It does support outputting INTERLACED so use +* the VIN hardware to combine the two fields. +*/ + pix->field = V4L2_FIELD_INTERLACED; + pix->height *= 2; + break; + default: + pix->field = RVIN_DEFAULT_FIELD; + break; + } + + /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ + walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; + + /* Limit to VIN capabilities */ + v4l_bound_align_image(>width, 2, vin->info->max_width, walign, + >height, 4, vin->info->max_height, 2, 0); + + pix->bytesperline = rvin_format_bytesperline(pix); + pix->sizeimage = rvin_format_sizeimage(pix); + + if (vin->info->model == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + vin_err(vin, "pixel format XBGR32 not supported on M1\n"); + return -EINVAL; + } + + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); + + return 0; +} + /* - * V4L2 */ @@ -184,55 +237,14 @@ static int __rvin_try_format(struct rvin_dev *vin, struct v4l2_pix_format *pix, struct rvin_source_fmt *source) { - u32 walign; int ret; - if (!rvin_format_from_pixel(pix->pixelformat) || - (vin->info->model == RCAR_M1 && -pix->pixelformat == V4L2_PIX_FMT_XBGR32)) - pix->pixelformat = RVIN_DEFAULT_FORMAT; - /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix, source); if (ret) return ret; - switch (pix->field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_NONE: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - case V4L2_FIELD_INTERLACED: - break; - case V4L2_FIELD_ALTERNATE: - /* -* Driver do not (yet) support outputting ALTERNATE to a -* userspace. It does support outputting INTERLACED so use -* the VIN hardware to combine the two fields. -*/ - pix->field = V4L2_FIELD_INTERLACED; - pix->height *= 2; - break; - default: - pix->field = RVIN_DEFAULT_FIELD; - break; - } - - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ - walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; - - /* Limit to VIN capabilities */ - v4l_bound_align_image(>width, 2, vin->info->max_width, walign, - >height, 4, vin->info->max_height, 2, 0); - - pix->bytesperline = rvin_format_bytesperline(pix); - pix->sizeimage = rvin_format_sizeimage(pix); - - vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", - pix->width, pix->height, pix->bytesperline, pix->sizeimage); - - return 0; + return rvin_format_align(vin, pix); } static int rvin_querycap(struct file *file, void *priv, -- 2.16.2
[PATCH v11 12/32] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)
There was never proper support in the VIN driver to deliver ALTERNATING field format to user-space, remove this field option. The problem is that ALTERNATING filed order requires the sequence numbers of buffers returned to userspace to reflect if fields where dropped or not, something which is not possible with the VIN drivers capture logic. The VIN driver can still capture from a video source which delivers frames in ALTERNATING field order, but needs to combine them using the VIN hardware into INTERLACED field order. Before this change if a source was delivering fields using ALTERNATE the driver would default to combining them using this hardware feature. Only if the user explicitly requested ALTERNATE filed order would incorrect frames be delivered. The height should not be cut in half for the format for TOP or BOTTOM fields settings. This was a mistake and it was made visible by the scaling refactoring. Correct behavior is that the user should request a frame size that fits the half height frame reflected in the field setting. If not the VIN will do its best to scale the top or bottom to the requested format and cropping and scaling do not work as expected. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-dma.c | 15 +-- drivers/media/platform/rcar-vin/rcar-v4l2.c | 40 +++-- 2 files changed, 10 insertions(+), 45 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index fd14be20a6604d7a..c8831e189d362c8b 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -617,7 +617,6 @@ static int rvin_setup(struct rvin_dev *vin) case V4L2_FIELD_INTERLACED_BT: vnmc = VNMC_IM_FULL | VNMC_FOC; break; - case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_NONE: if (vin->continuous) { vnmc = VNMC_IM_ODD_EVEN; @@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) return 0; } -static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) -{ - if (vin->format.field == V4L2_FIELD_ALTERNATE) { - /* If FS is set it's a Even field */ - if (vnms & VNMS_FS) - return V4L2_FIELD_BOTTOM; - return V4L2_FIELD_TOP; - } - - return vin->format.field; -} - static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) { const struct rvin_video_format *fmt; @@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data) goto done; /* Capture frame */ - vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); + vin->queue_buf[slot]->field = vin->format.field; vin->queue_buf[slot]->sequence = sequence; vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); vb2_buffer_done(>queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index ebcd78b1bb6e8cb6..cef9070884d93ba6 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -121,33 +121,6 @@ static int rvin_reset_format(struct rvin_dev *vin) vin->format.colorspace = mf->colorspace; vin->format.field = mf->field; - /* -* If the subdevice uses ALTERNATE field mode and G_STD is -* implemented use the VIN HW to combine the two fields to -* one INTERLACED frame. The ALTERNATE field mode can still -* be requested in S_FMT and be respected, this is just the -* default which is applied at probing or when S_STD is called. -*/ - if (vin->format.field == V4L2_FIELD_ALTERNATE && - v4l2_subdev_has_op(vin_to_source(vin), video, g_std)) - vin->format.field = V4L2_FIELD_INTERLACED; - - switch (vin->format.field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - vin->format.height /= 2; - break; - case V4L2_FIELD_NONE: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - case V4L2_FIELD_INTERLACED: - break; - default: - vin->format.field = RVIN_DEFAULT_FIELD; - break; - } - rvin_reset_crop_compose(vin); vin->format.bytesperline = rvin_format_bytesperline(>format); @@ -233,15 +206,20 @@ static int __rvin_try_format(struct rvin_dev *vin, switch (pix->field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - pix->height /= 2; - source->height /= 2; - break; case V4L2_FIELD_NONE: case V4L2_FIELD_INTERLACED_TB:
[PATCH v11 13/32] rcar-vin: update bytesperline and sizeimage calculation
Remove over complicated logic to calculate the value for bytesperline and sizeimage that was carried over from the soc_camera port. There is no need to find the max value of bytesperline and sizeimage from user-space as they are set to 0 before the max_t() operation. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index cef9070884d93ba6..652b85300b4ef9db 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -194,10 +194,6 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->pixelformat = RVIN_DEFAULT_FORMAT; } - /* Always recalculate */ - pix->bytesperline = 0; - pix->sizeimage = 0; - /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix, source); if (ret) @@ -232,10 +228,8 @@ static int __rvin_try_format(struct rvin_dev *vin, v4l_bound_align_image(>width, 2, vin->info->max_width, walign, >height, 4, vin->info->max_height, 2, 0); - pix->bytesperline = max_t(u32, pix->bytesperline, - rvin_format_bytesperline(pix)); - pix->sizeimage = max_t(u32, pix->sizeimage, - rvin_format_sizeimage(pix)); + pix->bytesperline = rvin_format_bytesperline(pix); + pix->sizeimage = rvin_format_sizeimage(pix); if (vin->info->model == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { -- 2.16.2
[PATCH v11 11/32] rcar-vin: set a default field to fallback on
If the field is not supported by the driver it should not try to keep the current field. Instead it should set it to a default fallback. Since trying a format should always result in the same state regardless of the current state of the device. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index c2265324c7c96308..ebcd78b1bb6e8cb6 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,6 +23,7 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE /* - * Format Conversions @@ -143,7 +144,7 @@ static int rvin_reset_format(struct rvin_dev *vin) case V4L2_FIELD_INTERLACED: break; default: - vin->format.field = V4L2_FIELD_NONE; + vin->format.field = RVIN_DEFAULT_FIELD; break; } @@ -213,10 +214,6 @@ static int __rvin_try_format(struct rvin_dev *vin, u32 walign; int ret; - /* Keep current field if no specific one is asked for */ - if (pix->field == V4L2_FIELD_ANY) - pix->field = vin->format.field; - /* If requested format is not supported fallback to the default */ if (!rvin_format_from_pixel(pix->pixelformat)) { vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", @@ -246,7 +243,7 @@ static int __rvin_try_format(struct rvin_dev *vin, case V4L2_FIELD_INTERLACED: break; default: - pix->field = V4L2_FIELD_NONE; + pix->field = RVIN_DEFAULT_FIELD; break; } -- 2.16.2
[PATCH v11 07/32] rcar-vin: move model information to own struct
When Gen3 support is added to the driver more than model ID will be different for the different SoCs. To avoid a lot of if statements in the code create a struct rvin_info to store this information. While we are at it rename the poorly chosen enum which contains the different model IDs from chip_id to model_id. Also sort the compatible string entries and make use of of_device_get_match_data() which will always work as the driver is DT only, so there's always a valid match. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 56 + drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +- drivers/media/platform/rcar-vin/rcar-vin.h | 14 ++-- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 663309ca9c04f208..d2b27ccff690cede 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -241,21 +241,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) * Platform Device Driver */ +static const struct rvin_info rcar_info_h1 = { + .model = RCAR_H1, +}; + +static const struct rvin_info rcar_info_m1 = { + .model = RCAR_M1, +}; + +static const struct rvin_info rcar_info_gen2 = { + .model = RCAR_GEN2, +}; + static const struct of_device_id rvin_of_id_table[] = { - { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 }, - { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 }, - { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 }, - { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 }, - { }, + { + .compatible = "renesas,vin-r8a7778", + .data = _info_m1, + }, + { + .compatible = "renesas,vin-r8a7779", + .data = _info_h1, + }, + { + .compatible = "renesas,vin-r8a7790", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7791", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7793", + .data = _info_gen2, + }, + { + .compatible = "renesas,vin-r8a7794", + .data = _info_gen2, + }, + { + .compatible = "renesas,rcar-gen2-vin", + .data = _info_gen2, + }, + { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); static int rcar_vin_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct rvin_dev *vin; struct resource *mem; int irq, ret; @@ -264,12 +296,8 @@ static int rcar_vin_probe(struct platform_device *pdev) if (!vin) return -ENOMEM; - match = of_match_device(of_match_ptr(rvin_of_id_table), >dev); - if (!match) - return -ENODEV; - vin->dev = >dev; - vin->chip = (enum chip_id)match->data; + vin->info = of_device_get_match_data(>dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (mem == NULL) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 4a0610a6b4503501..0a035667c0b0e93f 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -266,7 +266,8 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->sizeimage = max_t(u32, pix->sizeimage, rvin_format_sizeimage(pix)); - if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { + if (vin->info->model == RCAR_M1 && + pix->pixelformat == V4L2_PIX_FMT_XBGR32) { vin_err(vin, "pixel format XBGR32 not supported on M1\n"); return -EINVAL; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 85cb7ec53d2b08b5..3f49d2f2d6b88471 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -29,7 +29,7 @@ /* Address alignment mask for HW buffers */ #define HW_BUFFER_MASK 0x7f -enum chip_id { +enum model_id { RCAR_H1, RCAR_M1, RCAR_GEN2, @@ -88,11 +88,19 @@ struct rvin_graph_entity { unsigned int sink_pad; }; +/** + * struct rvin_info - Information about the particular
[PATCH v11 19/32] rcar-vin: add function to manipulate Gen3 chsel value
On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One feature of this register is that it's only present in the VIN0 and VIN4 instances. The register in VIN0 controls the routing for VIN0-3 and the register in VIN4 controls routing for VIN4-7. To be able to control routing from a media device this function is need to control runtime PM for the subgroup master (VIN0 and VIN4). The subgroup master must be switched on before the register is manipulated, once the operation is complete it's safe to switch the master off and the new routing will still be in effect. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-dma.c | 38 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 57bb288b3ca67a60..3fb9c325285c5a5a 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -16,6 +16,7 @@ #include #include +#include #include @@ -1228,3 +1229,40 @@ int rvin_dma_register(struct rvin_dev *vin, int irq) return ret; } + +/* - + * Gen3 CHSEL manipulation + */ + +/* + * There is no need to have locking around changing the routing + * as it's only possible to do so when no VIN in the group is + * streaming so nothing can race with the VNMC register. + */ +int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) +{ + u32 ifmd, vnmc; + int ret; + + ret = pm_runtime_get_sync(vin->dev); + if (ret < 0) + return ret; + + /* Make register writes take effect immediately. */ + vnmc = rvin_read(vin, VNMC_REG); + rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG); + + ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | + VNCSI_IFMD_CSI_CHSEL(chsel); + + rvin_write(vin, ifmd, VNCSI_IFMD_REG); + + vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); + + /* Restore VNMC. */ + rvin_write(vin, vnmc, VNMC_REG); + + pm_runtime_put(vin->dev); + + return ret; +} diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index b3802651eaa78ea9..666308946eb4994d 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -165,4 +165,6 @@ const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); /* Cropping, composing and scaling */ void rvin_crop_scale_comp(struct rvin_dev *vin); +int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel); + #endif -- 2.16.2
[PATCH v11 08/32] rcar-vin: move max width and height information to chip information
On Gen3 the max supported width and height will be different from Gen2. Move the limits to the struct rvin_info to prepare for Gen3 support. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 6 ++ drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 5 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index d2b27ccff690cede..cc863e4ec9a4d4b3 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -243,14 +243,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .model = RCAR_H1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .model = RCAR_M1, + .max_width = 2048, + .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .model = RCAR_GEN2, + .max_width = 2048, + .max_height = 2048, }; static const struct of_device_id rvin_of_id_table[] = { diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 0a035667c0b0e93f..8805d7911a761019 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -23,8 +23,6 @@ #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV -#define RVIN_MAX_WIDTH 2048 -#define RVIN_MAX_HEIGHT2048 /* - * Format Conversions @@ -258,8 +256,8 @@ static int __rvin_try_format(struct rvin_dev *vin, walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; /* Limit to VIN capabilities */ - v4l_bound_align_image(>width, 2, RVIN_MAX_WIDTH, walign, - >height, 4, RVIN_MAX_HEIGHT, 2, 0); + v4l_bound_align_image(>width, 2, vin->info->max_width, walign, + >height, 4, vin->info->max_height, 2, 0); pix->bytesperline = max_t(u32, pix->bytesperline, rvin_format_bytesperline(pix)); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 3f49d2f2d6b88471..f195d174eeacda10 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -91,9 +91,14 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model + * @max_width: max input width the VIN supports + * @max_height:max input height the VIN supports */ struct rvin_info { enum model_id model; + + unsigned int max_width; + unsigned int max_height; }; /** -- 2.16.2
[PATCH v11 05/32] rcar-vin: unregister video device on driver removal
If the video device was registered by the complete() callback it should be unregistered when a device is unbound from the driver. Protect from printing an uninitialized video device node name by adding a check in rvin_v4l2_unregister() to identify that the video device is registered. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Acked-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 2 ++ drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 2bedf20abcf3ca07..47f06acde2e698f2 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -272,6 +272,8 @@ static int rcar_vin_remove(struct platform_device *pdev) pm_runtime_disable(>dev); + rvin_v4l2_unregister(vin); + v4l2_async_notifier_unregister(>notifier); v4l2_async_notifier_cleanup(>notifier); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 178aecc94962abe2..32a658214f48fa49 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -841,6 +841,9 @@ static const struct v4l2_file_operations rvin_fops = { void rvin_v4l2_unregister(struct rvin_dev *vin) { + if (!video_is_registered(>vdev)) + return; + v4l2_info(>v4l2_dev, "Removing %s\n", video_device_node_name(>vdev)); -- 2.16.2
[PATCH v11 06/32] rcar-vin: move subdevice handling to async callbacks
In preparation for Gen3 support move the subdevice initialization and clean up from rvin_v4l2_{register,unregister}() directly to the async callbacks. This simplifies the addition of Gen3 support as the rvin_v4l2_register() can be shared for both Gen2 and Gen3 while direct subdevice control are only used on Gen2. While moving this code drop a large comment which is copied from the framework documentation and fold rvin_mbus_supported() into its only caller. Also move the initialization and cleanup code to separate functions to increase readability. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 108 +++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 35 - 2 files changed, 74 insertions(+), 69 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 47f06acde2e698f2..663309ca9c04f208 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,46 +46,88 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } -static bool rvin_mbus_supported(struct rvin_graph_entity *entity) +/* The vin lock shuld be held when calling the subdevice attach and detach */ +static int rvin_digital_subdevice_attach(struct rvin_dev *vin, +struct v4l2_subdev *subdev) { - struct v4l2_subdev *sd = entity->subdev; struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; + int ret; + /* Find source and sink pad of remote subdevice */ + ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); + if (ret < 0) + return ret; + vin->digital->source_pad = ret; + + ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK); + vin->digital->sink_pad = ret < 0 ? 0 : ret; + + /* Find compatible subdevices mbus format */ + vin->digital->code = 0; code.index = 0; - code.pad = entity->source_pad; - while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, )) { + code.pad = vin->digital->source_pad; + while (!vin->digital->code && + !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) { code.index++; switch (code.code) { case MEDIA_BUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: - entity->code = code.code; - return true; + vin->digital->code = code.code; + vin_dbg(vin, "Found media bus format for %s: %d\n", + subdev->name, vin->digital->code); + break; default: break; } } - return false; -} - -static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) -{ - struct rvin_dev *vin = notifier_to_vin(notifier); - int ret; - - /* Verify subdevices mbus format */ - if (!rvin_mbus_supported(vin->digital)) { + if (!vin->digital->code) { vin_err(vin, "Unsupported media bus format for %s\n", - vin->digital->subdev->name); + subdev->name); return -EINVAL; } - vin_dbg(vin, "Found media bus format for %s: %d\n", - vin->digital->subdev->name, vin->digital->code); + /* Read tvnorms */ + ret = v4l2_subdev_call(subdev, video, g_tvnorms, >vdev.tvnorms); + if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) + return ret; + + /* Add the controls */ + ret = v4l2_ctrl_handler_init(>ctrl_handler, 16); + if (ret < 0) + return ret; + + ret = v4l2_ctrl_add_handler(>ctrl_handler, subdev->ctrl_handler, + NULL); + if (ret < 0) { + v4l2_ctrl_handler_free(>ctrl_handler); + return ret; + } + + vin->vdev.ctrl_handler = >ctrl_handler; + + vin->digital->subdev = subdev; + + return 0; +} + +static void rvin_digital_subdevice_detach(struct rvin_dev *vin) +{ + rvin_v4l2_unregister(vin); + v4l2_ctrl_handler_free(>ctrl_handler); + + vin->vdev.ctrl_handler = NULL; + vin->digital->subdev = NULL; +} + +static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + int ret; ret = v4l2_device_register_subdev_nodes(>v4l2_dev); if (ret < 0) { @@ -103,8 +145,10 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, struct rvin_dev
[PATCH v11 24/32] rcar-vin: add group allocator functions
In media controller mode all VIN instances needs to be part of the same media graph. There is also a need for each VIN instance to know about and in some cases be able to communicate with other VIN instances. Add an allocator framework where the first VIN instance to be probed creates a shared data structure and registers a media device. Consecutive VINs insert themself into the global group. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 174 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 31 + 2 files changed, 203 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index eb67ad5e2633064b..01132b9966509c1f 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -20,12 +20,174 @@ #include #include #include +#include #include #include #include "rcar-vin.h" +/* - + * Gen3 CSI2 Group Allocator + */ + +/* FIXME: This should if we find a system that supports more + * than one group for the whole system be replaced with a linked + * list of groups. And eventually all of this should be replaced + * with a global device allocator API. + * + * But for now this works as on all supported systems there will + * be only one group for all instances. + */ + +static DEFINE_MUTEX(rvin_group_lock); +static struct rvin_group *rvin_group_data; + +static void rvin_group_cleanup(struct rvin_group *group) +{ + media_device_unregister(>mdev); + media_device_cleanup(>mdev); + mutex_destroy(>lock); +} + +static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin) +{ + struct media_device *mdev = >mdev; + const struct of_device_id *match; + struct device_node *np; + int ret; + + mutex_init(>lock); + + /* Count number of VINs in the system */ + group->count = 0; + for_each_matching_node(np, vin->dev->driver->of_match_table) + if (of_device_is_available(np)) + group->count++; + + vin_dbg(vin, "found %u enabled VIN's in DT", group->count); + + mdev->dev = vin->dev; + + match = of_match_node(vin->dev->driver->of_match_table, + vin->dev->of_node); + + strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); + strlcpy(mdev->model, match->compatible, sizeof(mdev->model)); + snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", +dev_name(mdev->dev)); + + media_device_init(mdev); + + ret = media_device_register(>mdev); + if (ret) + rvin_group_cleanup(group); + + return ret; +} + +static void rvin_group_release(struct kref *kref) +{ + struct rvin_group *group = + container_of(kref, struct rvin_group, refcount); + + mutex_lock(_group_lock); + + rvin_group_data = NULL; + + rvin_group_cleanup(group); + + kfree(group); + + mutex_unlock(_group_lock); +} + +static int rvin_group_get(struct rvin_dev *vin) +{ + struct rvin_group *group; + u32 id; + int ret; + + /* Make sure VIN id is present and sane */ + ret = of_property_read_u32(vin->dev->of_node, "renesas,id", ); + if (ret) { + vin_err(vin, "%pOF: No renesas,id property found\n", + vin->dev->of_node); + return -EINVAL; + } + + if (id >= RCAR_VIN_NUM) { + vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", + vin->dev->of_node, id); + return -EINVAL; + } + + /* Join or create a VIN group */ + mutex_lock(_group_lock); + if (rvin_group_data) { + group = rvin_group_data; + kref_get(>refcount); + } else { + group = kzalloc(sizeof(*group), GFP_KERNEL); + if (!group) { + ret = -ENOMEM; + goto err_group; + } + + ret = rvin_group_init(group, vin); + if (ret) { + kfree(group); + vin_err(vin, "Failed to initialize group\n"); + goto err_group; + } + + kref_init(>refcount); + + rvin_group_data = group; + } + mutex_unlock(_group_lock); + + /* Add VIN to group */ + mutex_lock(>lock); + + if (group->vin[id]) { + vin_err(vin, "Duplicate renesas,id property value %u\n", id); + mutex_unlock(>lock); + kref_put(>refcount, rvin_group_release); + return -EINVAL; + } + + group->vin[id] = vin; + +
[PATCH v11 18/32] rcar-vin: enable Gen3 hardware configuration
Add the register needed to work with Gen3 hardware. This patch adds the logic for how to work with the Gen3 hardware. More work is required to enable the subdevice structure needed to configure capturing. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 94 -- drivers/media/platform/rcar-vin/rcar-vin.h | 1 + 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 4ebf76c30a3e9117..57bb288b3ca67a60 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -33,21 +33,23 @@ #define VNELPRC_REG0x10/* Video n End Line Pre-Clip Register */ #define VNSPPRC_REG0x14/* Video n Start Pixel Pre-Clip Register */ #define VNEPPRC_REG0x18/* Video n End Pixel Pre-Clip Register */ -#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ -#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ -#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ -#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ #define VNIS_REG 0x2C/* Video n Image Stride Register */ #define VNMB_REG(m)(0x30 + ((m) << 2)) /* Video n Memory Base m Register */ #define VNIE_REG 0x40/* Video n Interrupt Enable Register */ #define VNINTS_REG 0x44/* Video n Interrupt Status Register */ #define VNSI_REG 0x48/* Video n Scanline Interrupt Register */ #define VNMTC_REG 0x4C/* Video n Memory Transfer Control Register */ -#define VNYS_REG 0x50/* Video n Y Scale Register */ -#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNDMR_REG 0x58/* Video n Data Mode Register */ #define VNDMR2_REG 0x5C/* Video n Data Mode Register 2 */ #define VNUVAOF_REG0x60/* Video n UV Address Offset Register */ + +/* Register offsets specific for Gen2 */ +#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */ +#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */ +#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */ +#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */ +#define VNYS_REG 0x50/* Video n Y Scale Register */ +#define VNXS_REG 0x54/* Video n X Scale Register */ #define VNC1A_REG 0x80/* Video n Coefficient Set C1A Register */ #define VNC1B_REG 0x84/* Video n Coefficient Set C1B Register */ #define VNC1C_REG 0x88/* Video n Coefficient Set C1C Register */ @@ -73,9 +75,13 @@ #define VNC8B_REG 0xF4/* Video n Coefficient Set C8B Register */ #define VNC8C_REG 0xF8/* Video n Coefficient Set C8C Register */ +/* Register offsets specific for Gen3 */ +#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */ /* Register bit fields for R-Car VIN */ /* Video n Main Control Register bits */ +#define VNMC_DPINE (1 << 27) /* Gen3 specific */ +#define VNMC_SCLE (1 << 26) /* Gen3 specific */ #define VNMC_FOC (1 << 21) #define VNMC_YCAL (1 << 19) #define VNMC_INF_YUV8_BT656(0 << 16) @@ -119,6 +125,13 @@ #define VNDMR2_FTEV(1 << 17) #define VNDMR2_VLV(n) ((n & 0xf) << 12) +/* Video n CSI2 Interface Mode Register (Gen3) */ +#define VNCSI_IFMD_DES2(1 << 27) +#define VNCSI_IFMD_DES1(1 << 26) +#define VNCSI_IFMD_DES0(1 << 25) +#define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0) +#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf + struct rvin_buffer { struct vb2_v4l2_buffer vb; struct list_head list; @@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) rvin_write(vin, p_set->coeff_set[23], VNC8C_REG); } -void rvin_crop_scale_comp(struct rvin_dev *vin) +static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) { u32 xs, ys; - /* Set Start/End Pixel/Line Pre-Clip */ - rvin_write(vin, vin->crop.left, VNSPPRC_REG); - rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); - switch (vin->format.field) { - case V4L2_FIELD_INTERLACED: - case V4L2_FIELD_INTERLACED_TB: - case V4L2_FIELD_INTERLACED_BT: - rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG); - rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1, - VNELPRC_REG); - break; - default: - rvin_write(vin, vin->crop.top, VNSLPRC_REG); - rvin_write(vin, vin->crop.top + vin->crop.height - 1, - VNELPRC_REG); -
[PATCH v11 14/32] rcar-vin: align pixelformat check
If the pixelformat is not supported it should not fail but be set to something that works. While we are at it move the two different checks of the pixelformat to the same statement. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 652b85300b4ef9db..b94ca9ffb1d3b323 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -187,12 +187,10 @@ static int __rvin_try_format(struct rvin_dev *vin, u32 walign; int ret; - /* If requested format is not supported fallback to the default */ - if (!rvin_format_from_pixel(pix->pixelformat)) { - vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n", - pix->pixelformat, RVIN_DEFAULT_FORMAT); + if (!rvin_format_from_pixel(pix->pixelformat) || + (vin->info->model == RCAR_M1 && +pix->pixelformat == V4L2_PIX_FMT_XBGR32)) pix->pixelformat = RVIN_DEFAULT_FORMAT; - } /* Limit to source capabilities */ ret = __rvin_try_format_source(vin, which, pix, source); @@ -231,12 +229,6 @@ static int __rvin_try_format(struct rvin_dev *vin, pix->bytesperline = rvin_format_bytesperline(pix); pix->sizeimage = rvin_format_sizeimage(pix); - if (vin->info->model == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32) { - vin_err(vin, "pixel format XBGR32 not supported on M1\n"); - return -EINVAL; - } - vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", pix->width, pix->height, pix->bytesperline, pix->sizeimage); -- 2.16.2
[PATCH v11 25/32] rcar-vin: change name of video device
The rcar-vin driver needs to be part of a media controller to support Gen3. Give each VIN instance a unique name so it can be referenced from userspace. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 02f3100ed30db63c..7ca60e8289675b88 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -999,7 +999,7 @@ int rvin_v4l2_register(struct rvin_dev *vin) /* video node */ vdev->v4l2_dev = >v4l2_dev; vdev->queue = >queue; - strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); + snprintf(vdev->name, sizeof(vdev->name), "VIN%u output", vin->id); vdev->release = video_device_release_empty; vdev->lock = >lock; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -- 2.16.2
[PATCH v11 23/32] rcar-vin: prepare for media controller mode initialization
Prepare for media controller by calling a different initialization then when running in device centric mode. Add trivial configuration of the mbus and creation of the media pad for the video device entity. While we are at it clearly mark the digital device centric notifier functions with a comment. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 20 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 4 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index ca22903c375d2018..eb67ad5e2633064b 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -46,6 +46,10 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int direction) return -EINVAL; } +/* - + * Digital async notifier + */ + /* The vin lock shuld be held when calling the subdevice attach and detach */ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, struct v4l2_subdev *subdev) @@ -237,6 +241,16 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) return 0; } +static int rvin_mc_init(struct rvin_dev *vin) +{ + /* All our sources are CSI-2 */ + vin->mbus_cfg.type = V4L2_MBUS_CSI2; + vin->mbus_cfg.flags = 0; + + vin->pad.flags = MEDIA_PAD_FL_SINK; + return media_entity_pads_init(>vdev.entity, 1, >pad); +} + /* - * Platform Device Driver */ @@ -325,8 +339,10 @@ static int rcar_vin_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, vin); - - ret = rvin_digital_graph_init(vin); + if (vin->info->use_mc) + ret = rvin_mc_init(vin); + else + ret = rvin_digital_graph_init(vin); if (ret < 0) goto error; diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 7bae9270c6216c3e..849f428871af113f 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -101,6 +101,8 @@ struct rvin_info { * @notifier: V4L2 asynchronous subdevs notifier * @digital: entity in the DT for local digital subdevice * + * @pad: media pad for the video device entity + * * @lock: protects @queue * @queue: vb2 buffers queue * @@ -130,6 +132,8 @@ struct rvin_dev { struct v4l2_async_notifier notifier; struct rvin_graph_entity *digital; + struct media_pad pad; + struct mutex lock; struct vb2_queue queue; -- 2.16.2
[PATCH v11 26/32] rcar-vin: add chsel information to rvin_info
Each Gen3 SoC has a limited set of predefined routing possibilities for which CSI-2 device and channel can be routed to which VIN instance. Prepare to store this information in the struct rvin_info. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-vin.h | 42 ++ 1 file changed, 42 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 07cde9e1ab01ca51..6150a883e17f8479 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -43,6 +43,14 @@ enum model_id { RCAR_GEN3, }; +enum rvin_csi_id { + RVIN_CSI20, + RVIN_CSI21, + RVIN_CSI40, + RVIN_CSI41, + RVIN_CSI_MAX, +}; + /** * STOPPED - No operation in progress * RUNNING - Operation in progress have buffers @@ -81,12 +89,45 @@ struct rvin_graph_entity { unsigned int sink_pad; }; +/** + * struct rvin_group_route - describes a route from a channel of a + * CSI-2 receiver to a VIN + * + * @vin: VIN ID. + * @csi: CSI-2 receiver ID. + * @chan: Output channel of the CSI-2 receiver. + * @mask: Bitmask of the different CHSEL register values that + * allows for a route from @csi + @chan to @vin. + * + * .. note:: + * Each R-Car CSI-2 receiver has four output channels facing the VIN + * devices, each channel can carry one CSI-2 Virtual Channel (VC). + * There are no correlation between channel number and CSI-2 VC. It's + * up to the CSI-2 receiver driver to configure which VC is output + * on which channel, the VIN devices only care about output channels. + * + * There are in some cases multiple CHSEL register settings which would + * allow for the same route from @csi + @chan to @vin. For example + * on R-Car H3 both the CHSEL values 0 and 3 allows for a route from + * CSI40/VC0 to VIN0. All possible CHSEL values for a route need to be + * recorded as a bitmask in @mask, in this example bit 0 and 3 should + * be set. + */ +struct rvin_group_route { + unsigned int vin; + enum rvin_csi_id csi; + unsigned char chan; + unsigned int mask; +}; + /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model * @use_mc:use media controller instead of controlling subdevice * @max_width: max input width the VIN supports * @max_height:max input height the VIN supports + * @routes:list of possible routes from the CSI-2 recivers to + * all VINs. The list mush be NULL terminated. */ struct rvin_info { enum model_id model; @@ -94,6 +135,7 @@ struct rvin_info { unsigned int max_width; unsigned int max_height; + const struct rvin_group_route *routes; }; /** -- 2.16.2
[PATCH v11 09/32] rcar-vin: move functions regarding scaling
In preparation of refactoring the scaling code move the code regarding scaling to to the top of the file to avoid the need to add forward declarations. No code is changed in this commit only whole functions moved inside the same file. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 602 +++-- 1 file changed, 303 insertions(+), 299 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index d701b52d198243b5..a7cda3922cb74baa 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -138,305 +138,6 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset) return ioread32(vin->base + offset); } -static int rvin_setup(struct rvin_dev *vin) -{ - u32 vnmc, dmr, dmr2, interrupts; - v4l2_std_id std; - bool progressive = false, output_is_yuv = false, input_is_yuv = false; - - switch (vin->format.field) { - case V4L2_FIELD_TOP: - vnmc = VNMC_IM_ODD; - break; - case V4L2_FIELD_BOTTOM: - vnmc = VNMC_IM_EVEN; - break; - case V4L2_FIELD_INTERLACED: - /* Default to TB */ - vnmc = VNMC_IM_FULL; - /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { - if (std & V4L2_STD_525_60) - vnmc = VNMC_IM_FULL | VNMC_FOC; - } - break; - case V4L2_FIELD_INTERLACED_TB: - vnmc = VNMC_IM_FULL; - break; - case V4L2_FIELD_INTERLACED_BT: - vnmc = VNMC_IM_FULL | VNMC_FOC; - break; - case V4L2_FIELD_ALTERNATE: - case V4L2_FIELD_NONE: - if (vin->continuous) { - vnmc = VNMC_IM_ODD_EVEN; - progressive = true; - } else { - vnmc = VNMC_IM_ODD; - } - break; - default: - vnmc = VNMC_IM_ODD; - break; - } - - /* -* Input interface -*/ - switch (vin->digital->code) { - case MEDIA_BUS_FMT_YUYV8_1X16: - /* BT.601/BT.1358 16bit YCbCr422 */ - vnmc |= VNMC_INF_YUV16; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_UYVY8_2X8: - /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; - input_is_yuv = true; - break; - case MEDIA_BUS_FMT_RGB888_1X24: - vnmc |= VNMC_INF_RGB888; - break; - case MEDIA_BUS_FMT_UYVY10_2X10: - /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? - VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; - input_is_yuv = true; - break; - default: - break; - } - - /* Enable VSYNC Field Toogle mode after one VSYNC input */ - dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); - - /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_HPS; - - /* Vsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) - dmr2 |= VNDMR2_VPS; - - /* -* Output format -*/ - switch (vin->format.pixelformat) { - case V4L2_PIX_FMT_NV16: - rvin_write(vin, - ALIGN(vin->format.width * vin->format.height, 0x80), - VNUVAOF_REG); - dmr = VNDMR_DTMD_YCSEP; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_YUYV: - dmr = VNDMR_BPSM; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_UYVY: - dmr = 0; - output_is_yuv = true; - break; - case V4L2_PIX_FMT_XRGB555: - dmr = VNDMR_DTMD_ARGB1555; - break; - case V4L2_PIX_FMT_RGB565: - dmr = 0; - break; - case V4L2_PIX_FMT_XBGR32: - /* Note: not supported on M1 */ - dmr = VNDMR_EXRGB; - break; - default: - vin_err(vin, "Invalid pixelformat (0x%x)\n", - vin->format.pixelformat); - return -EINVAL; - } - - /* Always update on
[PATCH v11 30/32] rcar-vin: enable support for r8a7795
Add the SoC specific information for Renesas r8a7795 ES1.x and ES2.0. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/Kconfig | 2 +- drivers/media/platform/rcar-vin/rcar-core.c | 120 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index af4c98b44d2e22cb..8fa7ee468c63afb9 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig @@ -6,7 +6,7 @@ config VIDEO_RCAR_VIN select V4L2_FWNODE ---help--- Support for Renesas R-Car Video Input (VIN) driver. - Supports R-Car Gen2 SoCs. + Supports R-Car Gen2 and Gen3 SoCs. To compile this driver as a module, choose M here: the module will be called rcar-vin. diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index c015f3c284439285..8017d386fc9bc545 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -832,6 +833,104 @@ static const struct rvin_info rcar_info_gen2 = { .max_height = 2048, }; +static const struct rvin_group_route rcar_info_r8a7795_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 0, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(1) | BIT(3) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(0) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) | BIT(2) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { .vin = 4, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 4, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 4, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 5, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(1) | BIT(3) }, + { .vin = 5, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(0) }, + { .vin = 6, .csi = RVIN_CSI41, .chan = 0, .mask = BIT(1) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 6, .csi = RVIN_CSI41, .chan = 2, .mask = BIT(3) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 7, .csi = RVIN_CSI41, .chan = 1, .mask = BIT(0) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) | BIT(2) }, + { .vin = 7, .csi = RVIN_CSI41, .chan = 3, .mask = BIT(3) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a7795 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a7795_routes, +}; + +static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 0, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(2) | BIT(5) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(1) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 1, .csi = RVIN_CSI21, .chan = 1, .mask = BIT(5) }, + { .vin = 2, .csi = RVIN_CSI21, .chan = 0, .mask = BIT(0) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20,
[PATCH v11 27/32] rcar-vin: parse Gen3 OF and setup media graph
The parsing and registering CSI-2 subdevices with the v4l2 async framework is a collaborative effort shared between the VIN instances which are part of the group. When the last VIN in the group is probed it asks all other VINs to parse its share of OF and record the async subdevices it finds in the notifier belonging to the last probed VIN. Once all CSI-2 subdevices in this notifier are bound proceed to register all VIN video devices of the group and crate media device links between all CSI-2 and VIN entities according to the SoC specific routing configuration. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 246 +++- drivers/media/platform/rcar-vin/rcar-vin.h | 12 +- 2 files changed, 254 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 01132b9966509c1f..3ddd7d8fecd52909 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -27,6 +27,23 @@ #include "rcar-vin.h" +/* + * The companion CSI-2 receiver driver (rcar-csi2) is known + * and we know it has one source pad (pad 0) and four sink + * pads (pad 1-4). So to translate a pad on the remote + * CSI-2 receiver to/from the VIN internal channel number simply + * subtract/add one from the pad/channel number. + */ +#define rvin_group_csi_pad_to_chan(pad) ((pad) - 1) +#define rvin_group_csi_chan_to_pad(chan) ((chan) + 1) + +/* + * Not all VINs are created equal, master VINs control the + * routing for other VIN's. We can figure out which VIN is + * master by looking at a VINs id. + */ +#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4) + /* - * Gen3 CSI2 Group Allocator */ @@ -403,6 +420,216 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) return 0; } +/* - + * Group async notifier + */ + +static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + const struct rvin_group_route *route; + unsigned int i; + int ret; + + ret = v4l2_device_register_subdev_nodes(>v4l2_dev); + if (ret) { + vin_err(vin, "Failed to register subdev nodes\n"); + return ret; + } + + /* Register all video nodes for the group. */ + for (i = 0; i < RCAR_VIN_NUM; i++) { + if (vin->group->vin[i]) { + ret = rvin_v4l2_register(vin->group->vin[i]); + if (ret) + return ret; + } + } + + /* Create all media device links between VINs and CSI-2's. */ + mutex_lock(>group->lock); + for (route = vin->info->routes; route->mask; route++) { + struct media_pad *source_pad, *sink_pad; + struct media_entity *source, *sink; + unsigned int source_idx; + + /* Check that VIN is part of the group. */ + if (!vin->group->vin[route->vin]) + continue; + + /* Check that VIN' master is part of the group. */ + if (!vin->group->vin[rvin_group_id_to_master(route->vin)]) + continue; + + /* Check that CSI-2 is part of the group. */ + if (!vin->group->csi[route->csi].subdev) + continue; + + source = >group->csi[route->csi].subdev->entity; + source_idx = rvin_group_csi_chan_to_pad(route->chan); + source_pad = >pads[source_idx]; + + sink = >group->vin[route->vin]->vdev.entity; + sink_pad = >pads[0]; + + /* Skip if link already exists. */ + if (media_entity_find_link(source_pad, sink_pad)) + continue; + + ret = media_create_pad_link(source, source_idx, sink, 0, 0); + if (ret) { + vin_err(vin, "Error adding link from %s to %s\n", + source->name, sink->name); + break; + } + } + mutex_unlock(>group->lock); + + return ret; +} + +static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, +struct v4l2_subdev *subdev, +struct v4l2_async_subdev *asd) +{ + struct rvin_dev *vin = notifier_to_vin(notifier); + unsigned int i; + + for (i = 0; i < RCAR_VIN_NUM; i++) + if (vin->group->vin[i]) + rvin_v4l2_unregister(vin->group->vin[i]); + + mutex_lock(>group->lock); + + for (i = 0; i
[PATCH v11 32/32] rcar-vin: enable support for r8a77970
Add the SoC specific information for Renesas r8a77970. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index f631a66e9cb69265..29b1ad793deefabc 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -971,6 +971,25 @@ static const struct rvin_info rcar_info_r8a7796 = { .routes = rcar_info_r8a7796_routes, }; +static const struct rvin_group_route _rcar_info_r8a77970_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a77970 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = _rcar_info_r8a77970_routes, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a7778", @@ -1008,6 +1027,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7796", .data = _info_r8a7796, }, + { + .compatible = "renesas,vin-r8a77970", + .data = _info_r8a77970, + }, { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); -- 2.16.2
[PATCH v11 28/32] rcar-vin: add link notify for Gen3
Add the ability to process media device link change request. Link enabling is a bit complicated on Gen3, whether or not it's possible to enable a link depends on what other links already are enabled. On Gen3 the 8 VINs are split into two subgroup's (VIN0-3 and VIN4-7) and from a routing perspective these two groups are independent of each other. Each subgroup's routing is controlled by the subgroup VIN master instance (VIN0 and VIN4). There are a limited number of possible route setups available for each subgroup and the configuration of each setup is dictated by the hardware. On H3 for example there are 6 possible route setups for each subgroup to choose from. This leads to the media device link notification code being rather large since it will find the best routing configuration to try and accommodate as many links as possible. When it's not possible to enable a new link due to hardware constrains the link_notifier callback will return -EMLINK. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-core.c | 153 1 file changed, 153 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 3ddd7d8fecd52909..c015f3c284439285 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -24,6 +24,7 @@ #include #include +#include #include "rcar-vin.h" @@ -44,6 +45,157 @@ */ #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4) +/* - + * Media Controller link notification + */ + +/* group lock should be held when calling this function. */ +static int rvin_group_entity_to_csi_id(struct rvin_group *group, + struct media_entity *entity) +{ + struct v4l2_subdev *sd; + unsigned int i; + + sd = media_entity_to_v4l2_subdev(entity); + + for (i = 0; i < RVIN_CSI_MAX; i++) + if (group->csi[i].subdev == sd) + return i; + + return -ENODEV; +} + +static unsigned int rvin_group_get_mask(struct rvin_dev *vin, + enum rvin_csi_id csi_id, + unsigned char chan) +{ + const struct rvin_group_route *route; + unsigned int mask = 0; + + for (route = vin->info->routes; route->mask; route++) { + if (route->vin == vin->id && + route->csi == csi_id && + route->chan == chan) { + vin_dbg(vin, "Adding route: vin: %d csi: %d chan: %d\n", + route->vin, route->csi, route->chan); + mask |= route->mask; + } + } + + return mask; +} + +/* + * Link setup for the links between a VIN and a CSI-2 receiver is a bit + * complex. The reason for this is that the register controlling routing + * are not present in each VIN instance. There are special VINs which + * control routing for itself and other VINs. There are not many + * different possible links combinations that can be enabled at the same + * time, therefor all already enabled links which are controlled by a + * master VIN needs to be taken into account when making the decision + * if a new link can be enabled or not. + * + * 1. Find out which VIN the link the user tries to enable is connected to. + * 2. Lookup which master VIN controls the links for this VIN. + * 3. Start with a bitmask with all bits set. + * 4. For each previously enabled link from the master VIN bitwise AND its + *route mask (see documentation for mask in struct rvin_group_route) + *with the bitmask. + * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask. + * 6. If the bitmask is not empty at this point the new link can be enabled + *while keeping all previous links enabled. Update the CHSEL value of the + *master VIN and inform the user that the link could be enabled. + * + * Please note that no link can be enabled if any VIN in the group is + * currently streaming. + */ +static int rvin_group_link_notify(struct media_link *link, u32 flags, + unsigned int notification) +{ + struct rvin_group *group = container_of(link->graph_obj.mdev, + struct rvin_group, mdev); + unsigned int master_id, chan, mask_new, i; + unsigned int mask = ~0; + struct media_entity *entity; + struct video_device *vdev; + struct media_pad *csi_pad; + struct rvin_dev *vin = NULL; + int csi_id, ret; + + ret = v4l2_pipeline_link_notify(link, flags, notification); + if (ret) + return ret; + + /* Only care about link enablement for VIN nodes. */ + if (!(flags & MEDIA_LNK_FL_ENABLED) || +
[PATCH v11 29/32] rcar-vin: extend {start,stop}_streaming to work with media controller
The procedure to start or stop streaming using the non-MC single subdevice and the MC graph and multiple subdevices are quite different. Create a new function to abstract which method is used based on which mode the driver is running in and add logic to start the MC graph. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 133 +++-- 1 file changed, 126 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 27d0c098f1da40f9..dd70d12ff693e500 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1087,15 +1087,136 @@ static void rvin_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(>qlock, flags); } +static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd, + struct media_pad *pad) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + fmt.pad = pad->index; + if (v4l2_subdev_call(sd, pad, get_fmt, NULL, )) + return -EPIPE; + + switch (fmt.format.code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY10_2X10: + case MEDIA_BUS_FMT_RGB888_1X24: + vin->mbus_code = fmt.format.code; + break; + default: + return -EPIPE; + } + + switch (fmt.format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Supported natively */ + break; + case V4L2_FIELD_ALTERNATE: + switch (vin->format.field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_NONE: + break; + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_TB: + case V4L2_FIELD_SEQ_BT: + /* Use VIN hardware to combine the two fields */ + fmt.format.height *= 2; + break; + default: + return -EPIPE; + } + break; + default: + return -EPIPE; + } + + if (fmt.format.width != vin->format.width || + fmt.format.height != vin->format.height || + fmt.format.code != vin->mbus_code) + return -EPIPE; + + return 0; +} + +static int rvin_set_stream(struct rvin_dev *vin, int on) +{ + struct media_pipeline *pipe; + struct media_device *mdev; + struct v4l2_subdev *sd; + struct media_pad *pad; + int ret; + + /* No media controller used, simply pass operation to subdevice. */ + if (!vin->info->use_mc) { + ret = v4l2_subdev_call(vin->digital->subdev, video, s_stream, + on); + + return ret == -ENOIOCTLCMD ? 0 : ret; + } + + pad = media_entity_remote_pad(>pad); + if (!pad) + return -EPIPE; + + sd = media_entity_to_v4l2_subdev(pad->entity); + + if (!on) { + media_pipeline_stop(>vdev.entity); + return v4l2_subdev_call(sd, video, s_stream, 0); + } + + ret = rvin_mc_validate_format(vin, sd, pad); + if (ret) + return ret; + + /* +* The graph lock needs to be taken to protect concurrent +* starts of multiple VIN instances as they might share +* a common subdevice down the line and then should use +* the same pipe. +*/ + mdev = vin->vdev.entity.graph_obj.mdev; + mutex_lock(>graph_mutex); + pipe = sd->entity.pipe ? sd->entity.pipe : >vdev.pipe; + ret = __media_pipeline_start(>vdev.entity, pipe); + mutex_unlock(>graph_mutex); + if (ret) + return ret; + + ret = v4l2_subdev_call(sd, video, s_stream, 1); + if (ret == -ENOIOCTLCMD) + ret = 0; + if (ret) + media_pipeline_stop(>vdev.entity); + + return ret; +} + static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) { struct rvin_dev *vin = vb2_get_drv_priv(vq); - struct v4l2_subdev *sd; unsigned long flags; int ret; - sd = vin_to_source(vin); - v4l2_subdev_call(sd, video, s_stream, 1); + ret = rvin_set_stream(vin, 1); + if (ret) { +
[PATCH v11 21/32] rcar-vin: use different v4l2 operations in media controller mode
When the driver runs in media controller mode it should not directly control the subdevice instead userspace will be responsible for configuring the pipeline. To be able to run in this mode a different set of v4l2 operations needs to be used. Add a new set of v4l2 operations to support operation without directly interacting with the source subdevice. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-dma.c | 3 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 161 +++- 2 files changed, 160 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 3fb9c325285c5a5a..27d0c098f1da40f9 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -628,7 +628,8 @@ static int rvin_setup(struct rvin_dev *vin) /* Default to TB */ vnmc = VNMC_IM_FULL; /* Use BT if video standard can be read and is 60 Hz format */ - if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { + if (!vin->info->use_mc && + !v4l2_subdev_call(vin_to_source(vin), video, g_std, )) { if (std & V4L2_STD_525_60) vnmc = VNMC_IM_FULL | VNMC_FOC; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 20be21cb1cf521e5..8d92710efffa7276 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -18,12 +18,16 @@ #include #include +#include #include #include "rcar-vin.h" #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV +#define RVIN_DEFAULT_WIDTH 800 +#define RVIN_DEFAULT_HEIGHT600 #define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE +#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB /* - * Format Conversions @@ -667,6 +671,74 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; +/* - + * V4L2 Media Controller + */ + +static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + + return rvin_format_align(vin, >fmt.pix); +} + +static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv, +struct v4l2_format *f) +{ + struct rvin_dev *vin = video_drvdata(file); + int ret; + + if (vb2_is_busy(>queue)) + return -EBUSY; + + ret = rvin_format_align(vin, >fmt.pix); + if (ret) + return ret; + + vin->format = f->fmt.pix; + + return 0; +} + +static int rvin_mc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_CAMERA; + strlcpy(i->name, "Camera", sizeof(i->name)); + + return 0; +} + +static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = { + .vidioc_querycap= rvin_querycap, + .vidioc_try_fmt_vid_cap = rvin_mc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = rvin_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = rvin_mc_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap= rvin_enum_fmt_vid_cap, + + .vidioc_enum_input = rvin_mc_enum_input, + .vidioc_g_input = rvin_g_input, + .vidioc_s_input = rvin_s_input, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf= vb2_ioctl_querybuf, + .vidioc_qbuf= vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon= vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = rvin_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + /* - * File Operations */ @@ -810,6 +882,74 @@ static const struct v4l2_file_operations rvin_fops = { .read = vb2_fop_read, }; +/* - + * Media
[PATCH v11 31/32] rcar-vin: enable support for r8a7796
Add the SoC specific information for Renesas r8a7796. Signed-off-by: Niklas SöderlundReviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 44 + 1 file changed, 44 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 8017d386fc9bc545..f631a66e9cb69265 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -931,6 +931,46 @@ static const struct rvin_info rcar_info_r8a7795es1 = { .routes = rcar_info_r8a7795es1_routes, }; +static const struct rvin_group_route rcar_info_r8a7796_routes[] = { + { .vin = 0, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 0, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 1, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 1, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 2, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 2, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) }, + { .vin = 3, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 3, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { .vin = 4, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(0) | BIT(3) }, + { .vin = 4, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(1) | BIT(4) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(0) }, + { .vin = 5, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(2) }, + { .vin = 5, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(3) }, + { .vin = 5, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(4) }, + { .vin = 6, .csi = RVIN_CSI40, .chan = 0, .mask = BIT(1) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 0, .mask = BIT(2) }, + { .vin = 6, .csi = RVIN_CSI40, .chan = 2, .mask = BIT(3) }, + { .vin = 6, .csi = RVIN_CSI20, .chan = 2, .mask = BIT(4) }, + { .vin = 7, .csi = RVIN_CSI40, .chan = 1, .mask = BIT(0) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 1, .mask = BIT(1) }, + { .vin = 7, .csi = RVIN_CSI40, .chan = 3, .mask = BIT(3) }, + { .vin = 7, .csi = RVIN_CSI20, .chan = 3, .mask = BIT(4) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a7796 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a7796_routes, +}; + static const struct of_device_id rvin_of_id_table[] = { { .compatible = "renesas,vin-r8a7778", @@ -964,6 +1004,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7795", .data = _info_r8a7795, }, + { + .compatible = "renesas,vin-r8a7796", + .data = _info_r8a7796, + }, { /* Sentinel */ }, }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); -- 2.16.2
[PATCH v11 16/32] rcar-vin: read subdevice format for crop only when needed
Instead of caching the subdevice format each time the video device format is set read it directly when it's needed. As it turns out the format is only needed when figuring out the max rectangle for cropping. This simplifies the code and makes it clearer what the source format is used for. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 158 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 12 --- 2 files changed, 80 insertions(+), 90 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 3290e603b44cdf3a..55640c6b2a1200ca 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -144,67 +144,62 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) * V4L2 */ -static void rvin_reset_crop_compose(struct rvin_dev *vin) +static int rvin_get_vin_format_from_source(struct rvin_dev *vin, + struct v4l2_pix_format *pix) { + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = vin->digital->source_pad, + }; + int ret; + + ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, ); + if (ret) + return ret; + + v4l2_fill_pix_format(pix, ); + + return rvin_format_align(vin, pix); +} + +static int rvin_reset_format(struct rvin_dev *vin) +{ + int ret; + + ret = rvin_get_vin_format_from_source(vin, >format); + if (ret) + return ret; + vin->crop.top = vin->crop.left = 0; - vin->crop.width = vin->source.width; - vin->crop.height = vin->source.height; + vin->crop.width = vin->format.width; + vin->crop.height = vin->format.height; vin->compose.top = vin->compose.left = 0; vin->compose.width = vin->format.width; vin->compose.height = vin->format.height; -} - -static int rvin_reset_format(struct rvin_dev *vin) -{ - struct v4l2_subdev_format fmt = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; - struct v4l2_mbus_framefmt *mf = - int ret; - - fmt.pad = vin->digital->source_pad; - - ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, ); - if (ret) - return ret; - - vin->format.width = mf->width; - vin->format.height = mf->height; - vin->format.colorspace = mf->colorspace; - vin->format.field = mf->field; - - rvin_reset_crop_compose(vin); - - vin->format.bytesperline = rvin_format_bytesperline(>format); - vin->format.sizeimage = rvin_format_sizeimage(>format); return 0; } -static int __rvin_try_format_source(struct rvin_dev *vin, - u32 which, - struct v4l2_pix_format *pix, - struct rvin_source_fmt *source) +static int rvin_try_format(struct rvin_dev *vin, u32 which, + struct v4l2_pix_format *pix, + struct v4l2_rect *crop, struct v4l2_rect *compose) { - struct v4l2_subdev *sd; + struct v4l2_subdev *sd = vin_to_source(vin); struct v4l2_subdev_pad_config *pad_cfg; struct v4l2_subdev_format format = { .which = which, + .pad = vin->digital->source_pad, }; enum v4l2_field field; u32 width, height; int ret; - sd = vin_to_source(vin); - - v4l2_fill_mbus_format(, pix, vin->digital->code); - pad_cfg = v4l2_subdev_alloc_pad_config(sd); if (pad_cfg == NULL) return -ENOMEM; - format.pad = vin->digital->source_pad; + v4l2_fill_mbus_format(, pix, vin->digital->code); /* Allow the video device to override field and to scale */ field = pix->field; @@ -217,34 +212,34 @@ static int __rvin_try_format_source(struct rvin_dev *vin, v4l2_fill_pix_format(pix, ); - source->width = pix->width; - source->height = pix->height; + crop->top = crop->left = 0; + crop->width = pix->width; + crop->height = pix->height; + + /* +* If source is ALTERNATE the driver will use the VIN hardware +* to INTERLACE it. The crop height then needs to be doubled. +*/ + if (pix->field == V4L2_FIELD_ALTERNATE) + crop->height *= 2; + + if (field != V4L2_FIELD_ANY) + pix->field = field; - pix->field = field; pix->width = width; pix->height = height; - vin_dbg(vin, "Source resolution: %ux%u\n", source->width, - source->height); + ret = rvin_format_align(vin, pix); + if (ret) + return ret; + compose->top = compose->left = 0; +
[PATCH v11 20/32] rcar-vin: add flag to switch to media controller mode
On Gen3 a media controller API needs to be used to allow userspace to configure the subdevices in the pipeline instead of directly controlling a single source subdevice, which is and will continue to be the mode of operation on Gen2. Prepare for these two modes of operation by adding a flag to struct rvin_info which will control which mode to use. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 6 +- drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 449175c3133e42c6..ca22903c375d2018 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -243,18 +243,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) static const struct rvin_info rcar_info_h1 = { .model = RCAR_H1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_m1 = { .model = RCAR_M1, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; static const struct rvin_info rcar_info_gen2 = { .model = RCAR_GEN2, + .use_mc = false, .max_width = 2048, .max_height = 2048, }; @@ -349,7 +352,8 @@ static int rcar_vin_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(>notifier); v4l2_async_notifier_cleanup(>notifier); - v4l2_ctrl_handler_free(>ctrl_handler); + if (!vin->info->use_mc) + v4l2_ctrl_handler_free(>ctrl_handler); rvin_dma_unregister(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 666308946eb4994d..7bae9270c6216c3e 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -77,11 +77,13 @@ struct rvin_graph_entity { /** * struct rvin_info - Information about the particular VIN implementation * @model: VIN model + * @use_mc:use media controller instead of controlling subdevice * @max_width: max input width the VIN supports * @max_height:max input height the VIN supports */ struct rvin_info { enum model_id model; + bool use_mc; unsigned int max_width; unsigned int max_height; -- 2.16.2
[PATCH v11 22/32] rcar-vin: force default colorspace for media centric mode
When the VIN driver is running in media centric mode (on Gen3) the colorspace is not retrieved from the video source instead the user is expected to set it as part of the format. There is no way for the VIN driver to validated the colorspace requested by user-space, this creates a problem where validation tools fail. Until the user requested colorspace can be validated lets force it to the driver default. Signed-off-by: Niklas Söderlund--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 8d92710efffa7276..02f3100ed30db63c 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -675,12 +675,24 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { * V4L2 Media Controller */ +static int rvin_mc_try_format(struct rvin_dev *vin, struct v4l2_pix_format *pix) +{ + /* +* There is no way to validate the colorspace provided by the +* user. Until it can be validated force colorspace to the +* driver default. +*/ + pix->colorspace = RVIN_DEFAULT_COLORSPACE; + + return rvin_format_align(vin, pix); +} + static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct rvin_dev *vin = video_drvdata(file); - return rvin_format_align(vin, >fmt.pix); + return rvin_mc_try_format(vin, >fmt.pix); } static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv, @@ -692,7 +704,7 @@ static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv, if (vb2_is_busy(>queue)) return -EBUSY; - ret = rvin_format_align(vin, >fmt.pix); + ret = rvin_mc_try_format(vin, >fmt.pix); if (ret) return ret; -- 2.16.2
[PATCH v11 17/32] rcar-vin: move media bus configuration to struct rvin_info
Bus configuration will once the driver is extended to support Gen3 contain information not specific to only the directly connected parallel subdevice. Move it to struct rvin_dev to show it's not always coupled to the parallel subdevice. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil --- drivers/media/platform/rcar-vin/rcar-core.c | 18 +- drivers/media/platform/rcar-vin/rcar-dma.c | 11 ++- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- drivers/media/platform/rcar-vin/rcar-vin.h | 9 - 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index cc863e4ec9a4d4b3..449175c3133e42c6 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -65,10 +65,10 @@ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, vin->digital->sink_pad = ret < 0 ? 0 : ret; /* Find compatible subdevices mbus format */ - vin->digital->code = 0; + vin->mbus_code = 0; code.index = 0; code.pad = vin->digital->source_pad; - while (!vin->digital->code && + while (!vin->mbus_code && !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) { code.index++; switch (code.code) { @@ -76,16 +76,16 @@ static int rvin_digital_subdevice_attach(struct rvin_dev *vin, case MEDIA_BUS_FMT_UYVY8_2X8: case MEDIA_BUS_FMT_UYVY10_2X10: case MEDIA_BUS_FMT_RGB888_1X24: - vin->digital->code = code.code; + vin->mbus_code = code.code; vin_dbg(vin, "Found media bus format for %s: %d\n", - subdev->name, vin->digital->code); + subdev->name, vin->mbus_code); break; default: break; } } - if (!vin->digital->code) { + if (!vin->mbus_code) { vin_err(vin, "Unsupported media bus format for %s\n", subdev->name); return -EINVAL; @@ -190,16 +190,16 @@ static int rvin_digital_parse_v4l2(struct device *dev, if (vep->base.port || vep->base.id) return -ENOTCONN; - rvge->mbus_cfg.type = vep->bus_type; + vin->mbus_cfg.type = vep->bus_type; - switch (rvge->mbus_cfg.type) { + switch (vin->mbus_cfg.type) { case V4L2_MBUS_PARALLEL: vin_dbg(vin, "Found PARALLEL media bus\n"); - rvge->mbus_cfg.flags = vep->bus.parallel.flags; + vin->mbus_cfg.flags = vep->bus.parallel.flags; break; case V4L2_MBUS_BT656: vin_dbg(vin, "Found BT656 media bus\n"); - rvge->mbus_cfg.flags = 0; + vin->mbus_cfg.flags = 0; break; default: vin_err(vin, "Unknown media bus type\n"); diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index c8831e189d362c8b..4ebf76c30a3e9117 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin) /* * Input interface */ - switch (vin->digital->code) { + switch (vin->mbus_code) { case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; @@ -641,7 +641,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; input_is_yuv = true; break; @@ -650,7 +650,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; input_is_yuv = true; break; @@ -662,11 +662,11 @@ static int rvin_setup(struct rvin_dev *vin) dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); /* Hsync Signal Polarity Select */ - if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) + if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) dmr2 |= VNDMR2_HPS; /* Vsync Signal Polarity
[PATCH v11 01/32] dt-bindings: media: rcar_vin: Reverse SoC part number list
From: Fabrizio CastroChange the sorting of the part numbers from descending to ascending to match with other documentation. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Acked-by: Rob Herring Reviewed-by: Geert Uytterhoeven Acked-by: Niklas Söderlund --- Documentation/devicetree/bindings/media/rcar_vin.txt | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 19357d0bbe6539b3..0ac715a5c331bc26 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -6,14 +6,14 @@ family of devices. The current blocks are always slaves and suppot one input channel which can be either RGB, YUYV or BT656. - compatible: Must be one or more of the following - - "renesas,vin-r8a7795" for the R8A7795 device - - "renesas,vin-r8a7794" for the R8A7794 device - - "renesas,vin-r8a7793" for the R8A7793 device - - "renesas,vin-r8a7792" for the R8A7792 device - - "renesas,vin-r8a7791" for the R8A7791 device - - "renesas,vin-r8a7790" for the R8A7790 device - - "renesas,vin-r8a7779" for the R8A7779 device - "renesas,vin-r8a7778" for the R8A7778 device + - "renesas,vin-r8a7779" for the R8A7779 device + - "renesas,vin-r8a7790" for the R8A7790 device + - "renesas,vin-r8a7791" for the R8A7791 device + - "renesas,vin-r8a7792" for the R8A7792 device + - "renesas,vin-r8a7793" for the R8A7793 device + - "renesas,vin-r8a7794" for the R8A7794 device + - "renesas,vin-r8a7795" for the R8A7795 device - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 compatible device. - "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device. -- 2.16.2
[PATCH v11 00/32] rcar-vin: Add Gen3 with media controller
Hi, This series adds Gen3 VIN support to rcar-vin driver for Renesas r8a7795, r8a7796 and r8a77970. It is based on the media-tree and depends on Fabrizio Castro patches as they touches the order of the compatible strings in the documentation to reduce merge conflicts. The dependencies are included in this series. The driver is tested on Renesas H3 (r8a7795, ES2.0), M3-W (r8a7796) together with the rcar-csi2 driver (posted separately and not yet upstream) and the Salvator-X onboard ADV7482. It is also tested on the V3M (r8a77970) on the Eagle board together with its expansion board with a ADV7482 and out of tree patches for GMSL capture using the max9286 and rdacm20 drivers. It is possible to capture both CVBS and HDMI video streams, v4l2-compliance passes with no errors and media-ctl can be used to change the routing and formats for the different entities in the media graph. Gen2 compatibility is verified on Koelsch and no problems where found, video can be captured just like before and v4l2-compliance passes without errors or warnings just like before this series. I have started on a very basic test suite for the VIN driver at: https://git.ragnatech.se/vin-tests And as before the state of the driver and information about how to test it can be found on the elinux wiki: http://elinux.org/R-Car/Tests:rcar-vin * Changes since v10 - Corrected spelling in comments and commit messages. - Reworked 'rcar-vin: read subdevice format for crop only when needed' to only get the source format once per operation. - Moved some patches around to make it easier to review, moved: - rcar-vin: set a default field to fallback on - rcar-vin: fix handling of single field frames (top, bottom and alternate fields) - rcar-vin: update bytesperline and sizeimage calculation - rcar-vin: break out format alignment and checking - rcar-vin: update pixelformat check for M1 Before: - rcar-vin: read subdevice format for crop only when needed - Rename variable 'code' to 'mbus_code' in struct rvin_dev. - Add comment describing no locking is needed in rvin_set_channel_routing(). - Check return value of pm_runtime_get_sync() in rvin_set_channel_routing(). - Rework 'rcar-vin: add check for colorspace' to not try to check the format, instead force a default format. This should be revisited once either v4l2-compliance or v4l2 framework changes are worked out to allow for MC centric drivers to validate user supplied colorspace. - Add error checking for pm_runtime_get_sync() and v4l2_pipeline_pm_use(). - Change mutex_lock() to mutex_lock_interruptible() in rvin_mc_open(). - Rewrote documentation for struct rvin_group_route. - Rename rvin_mc_parse_v4l2() to rvin_mc_parse_of_endpoint(). - Reword error messages in rvin_mc_parse_of_endpoint(). - Removed unneeded loop in rvin_mc_parse_of_endpoint(). - Remove check !is_media_entity_v4l2_subdev() in rvin_group_entity_to_csi_id(). - Add documentation for the algorithm used to figure out if a link can be enabled or not in rvin_group_link_notify(). - Break out format validation to rvin_mc_validate_format(). - Include two DT documentation patches from Fabrizio Castro which previously where mentioned as the only dependency for this series. - Added reviewed tags from Laurent, Thanks! * Changes since v9 - Fixed mistakes in the device tree description pointed out by Laurent. - GenX -> GenX platforms - portX -> port X - Explicitly state the on Gen3 platforms port 0 can only describe one endpoint and that only VIN instances connected to external pins should have a port 0 node. - s/which is/connected to/ in he endpoint description for Gen3 platforms. - Update some poorly written commit messages. - Moved the digital subdevice attach and detach code to two separate functions to increase readability. - Rename the struct rvin_info member chip to model to better describe its purpose. - Change the video name from "rcar_vin e6ef.video" to "VINx output" where x is the VIN id. - Dropped patch 'rcar-vin: do not allow changing scaling and composing while streaming' as it removed Gen2 functionality which is valid as pointed out by Laurent. - Rename rvin_get_sd_format() to rvin_get_source_format() and change its parameter from struct v4l2_pix_format* to struct v4l2_mbus_framefmt*. - Clarified commit message and add a few move comments to 'rcar-vin: fix handling of single field frames (top, bottom and alternate fields'. - Update documentation for struct rvin_dev fields mbus_cfg and code. - Fix argument in VNCSI_IFMD_CSI_CHSEL macro. - Renamed rvin_set_chsel() to rvin_set_channel_routing(). - Restore the VNMC register after changing CHSEL setting. - Broke patch 'rcar-vin: break out format alignment and checking' into three parts to ease review. - Add new patch to introduce a default field. - Only include media/v4l2-mc.h in the .c files that needs it and not in rcar-vin.h. - Rename rvin_group_allocate()
[PATCH v11 10/32] rcar-vin: all Gen2 boards can scale simplify logic
The logic to preserve the requested format width and height are too complex and come from a premature optimization for Gen3. All Gen2 SoC can scale and the Gen3 implementation will not use these functions at all so simply preserve the width and height when interacting with the subdevice much like the field is preserved simplifies the logic quite a bit. Signed-off-by: Niklas SöderlundReviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-dma.c | 8 drivers/media/platform/rcar-vin/rcar-v4l2.c | 25 +++-- drivers/media/platform/rcar-vin/rcar-vin.h | 2 -- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index a7cda3922cb74baa..fd14be20a6604d7a 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -585,14 +585,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) 0, 0); } -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height) -{ - /* All VIN channels on Gen2 have scalers */ - pix->width = width; - pix->height = height; -} - /* - * Hardware setup */ diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 8805d7911a761019..c2265324c7c96308 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -166,6 +166,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin, .which = which, }; enum v4l2_field field; + u32 width, height; int ret; sd = vin_to_source(vin); @@ -178,7 +179,10 @@ static int __rvin_try_format_source(struct rvin_dev *vin, format.pad = vin->digital->source_pad; + /* Allow the video device to override field and to scale */ field = pix->field; + width = pix->width; + height = pix->height; ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, ); if (ret < 0 && ret != -ENOIOCTLCMD) @@ -186,11 +190,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin, v4l2_fill_pix_format(pix, ); - pix->field = field; - source->width = pix->width; source->height = pix->height; + pix->field = field; + pix->width = width; + pix->height = height; + vin_dbg(vin, "Source resolution: %ux%u\n", source->width, source->height); @@ -204,13 +210,9 @@ static int __rvin_try_format(struct rvin_dev *vin, struct v4l2_pix_format *pix, struct rvin_source_fmt *source) { - u32 rwidth, rheight, walign; + u32 walign; int ret; - /* Requested */ - rwidth = pix->width; - rheight = pix->height; - /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; @@ -248,10 +250,6 @@ static int __rvin_try_format(struct rvin_dev *vin, break; } - /* If source can't match format try if VIN can scale */ - if (source->width != rwidth || source->height != rheight) - rvin_scale_try(vin, pix, rwidth, rheight); - /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; @@ -270,9 +268,8 @@ static int __rvin_try_format(struct rvin_dev *vin, return -EINVAL; } - vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n", - rwidth, rheight, pix->width, pix->height, - pix->bytesperline, pix->sizeimage); + vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n", + pix->width, pix->height, pix->bytesperline, pix->sizeimage); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index f195d174eeacda10..8daba9db0e927a49 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -175,8 +175,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); /* Cropping, composing and scaling */ -void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix, - u32 width, u32 height); void rvin_crop_scale_comp(struct rvin_dev *vin); #endif -- 2.16.2
[PATCH v11 02/32] dt-bindings: media: rcar_vin: add device tree support for r8a774[35]
From: Fabrizio CastroAdd compatible strings for r8a7743 and r8a7745. No driver change is needed as "renesas,rcar-gen2-vin" will activate the right code. However, it is good practice to document compatible strings for the specific SoC as this allows SoC specific changes to the driver if needed, in addition to document SoC support and therefore allow checkpatch.pl to validate compatible string values. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Acked-by: Rob Herring Reviewed-by: Geert Uytterhoeven Acked-by: Niklas Söderlund --- Documentation/devicetree/bindings/media/rcar_vin.txt | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 0ac715a5c331bc26..c60e6b0a89b67a8c 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt @@ -6,6 +6,8 @@ family of devices. The current blocks are always slaves and suppot one input channel which can be either RGB, YUYV or BT656. - compatible: Must be one or more of the following + - "renesas,vin-r8a7743" for the R8A7743 device + - "renesas,vin-r8a7745" for the R8A7745 device - "renesas,vin-r8a7778" for the R8A7778 device - "renesas,vin-r8a7779" for the R8A7779 device - "renesas,vin-r8a7790" for the R8A7790 device @@ -14,7 +16,8 @@ channel which can be either RGB, YUYV or BT656. - "renesas,vin-r8a7793" for the R8A7793 device - "renesas,vin-r8a7794" for the R8A7794 device - "renesas,vin-r8a7795" for the R8A7795 device - - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 compatible device. + - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible + device. - "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device. When compatible with the generic version nodes must list the -- 2.16.2
[PATCH v11 04/32] rcar-vin: rename poorly named initialize and cleanup functions
The functions to register and unregister the hardware and video device where poorly named from the start. Rename them to better describe their intended function. Signed-off-by: Niklas SöderlundReviewed-by: Kieran Bingham Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-core.c | 10 +- drivers/media/platform/rcar-vin/rcar-dma.c | 6 +++--- drivers/media/platform/rcar-vin/rcar-v4l2.c | 4 ++-- drivers/media/platform/rcar-vin/rcar-vin.h | 8 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index f1fc7978d6d1523d..2bedf20abcf3ca07 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -93,7 +93,7 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) return ret; } - return rvin_v4l2_probe(vin); + return rvin_v4l2_register(vin); } static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, @@ -103,7 +103,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, struct rvin_dev *vin = notifier_to_vin(notifier); vin_dbg(vin, "unbind digital subdev %s\n", subdev->name); - rvin_v4l2_remove(vin); + rvin_v4l2_unregister(vin); vin->digital->subdev = NULL; } @@ -245,7 +245,7 @@ static int rcar_vin_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = rvin_dma_probe(vin, irq); + ret = rvin_dma_register(vin, irq); if (ret) return ret; @@ -260,7 +260,7 @@ static int rcar_vin_probe(struct platform_device *pdev) return 0; error: - rvin_dma_remove(vin); + rvin_dma_unregister(vin); v4l2_async_notifier_cleanup(>notifier); return ret; @@ -275,7 +275,7 @@ static int rcar_vin_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(>notifier); v4l2_async_notifier_cleanup(>notifier); - rvin_dma_remove(vin); + rvin_dma_unregister(vin); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 23fdff7a7370842e..d701b52d198243b5 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1153,14 +1153,14 @@ static const struct vb2_ops rvin_qops = { .wait_finish= vb2_ops_wait_finish, }; -void rvin_dma_remove(struct rvin_dev *vin) +void rvin_dma_unregister(struct rvin_dev *vin) { mutex_destroy(>lock); v4l2_device_unregister(>v4l2_dev); } -int rvin_dma_probe(struct rvin_dev *vin, int irq) +int rvin_dma_register(struct rvin_dev *vin, int irq) { struct vb2_queue *q = >queue; int i, ret; @@ -1208,7 +1208,7 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) return 0; error: - rvin_dma_remove(vin); + rvin_dma_unregister(vin); return ret; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index b479b882da12f62d..178aecc94962abe2 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -839,7 +839,7 @@ static const struct v4l2_file_operations rvin_fops = { .read = vb2_fop_read, }; -void rvin_v4l2_remove(struct rvin_dev *vin) +void rvin_v4l2_unregister(struct rvin_dev *vin) { v4l2_info(>v4l2_dev, "Removing %s\n", video_device_node_name(>vdev)); @@ -866,7 +866,7 @@ static void rvin_notify(struct v4l2_subdev *sd, } } -int rvin_v4l2_probe(struct rvin_dev *vin) +int rvin_v4l2_register(struct rvin_dev *vin) { struct video_device *vdev = >vdev; struct v4l2_subdev *sd = vin_to_source(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 5382078143fb3869..85cb7ec53d2b08b5 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -153,11 +153,11 @@ struct rvin_dev { #define vin_warn(d, fmt, arg...) dev_warn(d->dev, fmt, ##arg) #define vin_err(d, fmt, arg...)dev_err(d->dev, fmt, ##arg) -int rvin_dma_probe(struct rvin_dev *vin, int irq); -void rvin_dma_remove(struct rvin_dev *vin); +int rvin_dma_register(struct rvin_dev *vin, int irq); +void rvin_dma_unregister(struct rvin_dev *vin); -int rvin_v4l2_probe(struct rvin_dev *vin); -void rvin_v4l2_remove(struct rvin_dev *vin); +int rvin_v4l2_register(struct rvin_dev *vin); +void rvin_v4l2_unregister(struct rvin_dev *vin); const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
Re: [PATCH v5 2/2] v4l: cadence: Add Cadence MIPI-CSI2 TX driver
Maxime, Thanks you for the patch, Maxime Ripardwrote on Thu [2018-Mar-01 12:30:49 +0100]: > The Cadence MIPI-CSI2 TX controller is an hardware block meant to be used > as a bridge between pixel interfaces and a CSI-2 bus. > > It supports operating with an internal or external D-PHY, with up to 4 > lanes, or without any D-PHY. The current code only supports the latter > case. > > While the virtual channel input on the pixel interface can be directly > mapped to CSI2, the datatype input is actually a selection signal (3-bits) > mapping to a table of up to 8 preconfigured datatypes/formats (programmed > at start-up) > > The block supports up to 8 input datatypes. > > Signed-off-by: Maxime Ripard > --- > drivers/media/platform/cadence/Kconfig | 11 + > drivers/media/platform/cadence/Makefile | 1 + > drivers/media/platform/cadence/cdns-csi2tx.c | 527 > +++ > 3 files changed, 539 insertions(+) > create mode 100644 drivers/media/platform/cadence/cdns-csi2tx.c > > diff --git a/drivers/media/platform/cadence/Kconfig > b/drivers/media/platform/cadence/Kconfig > index 18f061e5cbd1..83dcf2b1814b 100644 > --- a/drivers/media/platform/cadence/Kconfig > +++ b/drivers/media/platform/cadence/Kconfig > @@ -14,4 +14,15 @@ config VIDEO_CADENCE_CSI2RX > To compile this driver as a module, choose M here: the module will be > called cdns-csi2rx. > > +config VIDEO_CADENCE_CSI2TX > + tristate "Cadence MIPI-CSI2 TX Controller" > + depends on MEDIA_CONTROLLER > + depends on VIDEO_V4L2_SUBDEV_API > + select V4L2_FWNODE > + help > + Support for the Cadence MIPI CSI2 Transceiver controller. > + > + To compile this driver as a module, choose M here: the module will be > + called cdns-csi2tx. > + > endif > diff --git a/drivers/media/platform/cadence/Makefile > b/drivers/media/platform/cadence/Makefile > index 99a4086b7448..7fe992273162 100644 > --- a/drivers/media/platform/cadence/Makefile > +++ b/drivers/media/platform/cadence/Makefile > @@ -1 +1,2 @@ > obj-$(CONFIG_VIDEO_CADENCE_CSI2RX) += cdns-csi2rx.o > +obj-$(CONFIG_VIDEO_CADENCE_CSI2TX) += cdns-csi2tx.o > diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c > b/drivers/media/platform/cadence/cdns-csi2tx.c > new file mode 100644 > index ..8de277e6aec1 > --- /dev/null > +++ b/drivers/media/platform/cadence/cdns-csi2tx.c > @@ -0,0 +1,527 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Driver for Cadence MIPI-CSI2 TX Controller > + * > + * Copyright (C) 2017 Cadence Design Systems Inc. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#define CSI2TX_DEVICE_CONFIG_REG 0x00 > + > +#define CSI2TX_CONFIG_REG0x20 > +#define CSI2TX_CONFIG_CFG_REQBIT(2) > +#define CSI2TX_CONFIG_SRST_REQ BIT(1) > + > +#define CSI2TX_DPHY_CFG_REG 0x28 > +#define CSI2TX_DPHY_CFG_CLK_RESETBIT(16) > +#define CSI2TX_DPHY_CFG_LANE_RESET(n)BIT((n) + 12) > +#define CSI2TX_DPHY_CFG_MODE_MASKGENMASK(9, 8) > +#define CSI2TX_DPHY_CFG_MODE_LPDT(2 << 8) > +#define CSI2TX_DPHY_CFG_MODE_HS (1 << 8) > +#define CSI2TX_DPHY_CFG_MODE_ULPS(0 << 8) > +#define CSI2TX_DPHY_CFG_CLK_ENABLE BIT(4) > +#define CSI2TX_DPHY_CFG_LANE_ENABLE(n) BIT(n) > + > +#define CSI2TX_DPHY_CLK_WAKEUP_REG 0x2c > +#define CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(n)((n) & 0x) > + > +#define CSI2TX_DT_CFG_REG(n) (0x80 + (n) * 8) > +#define CSI2TX_DT_CFG_DT(n) (((n) & 0x3f) << 2) > + > +#define CSI2TX_DT_FORMAT_REG(n) (0x84 + (n) * 8) > +#define CSI2TX_DT_FORMAT_BYTES_PER_LINE(n) (((n) & 0x) << 16) > +#define CSI2TX_DT_FORMAT_MAX_LINE_NUM(n) ((n) & 0x) > + > +#define CSI2TX_STREAM_IF_CFG_REG(n) (0x100 + (n) * 4) > +#define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n) ((n) & 0x1f) > + > +#define CSI2TX_LANES_MAX 4 > +#define CSI2TX_STREAMS_MAX 4 > + > +enum csi2tx_pads { > + CSI2TX_PAD_SOURCE, > + CSI2TX_PAD_SINK_STREAM0, > + CSI2TX_PAD_SINK_STREAM1, > + CSI2TX_PAD_SINK_STREAM2, > + CSI2TX_PAD_SINK_STREAM3, > + CSI2TX_PAD_MAX, > +}; > + > +struct csi2tx_fmt { > + u32 mbus; > + u32 dt; > + u32 bpp; > +}; > + > +struct csi2tx_priv { > + struct device *dev; > + unsigned intcount; > + > + /* > + * Used to prevent race conditions between multiple, > + * concurrent calls to start and stop. > + */ > + struct mutexlock; > + > + void __iomem*base; > + > + struct clk *esc_clk; > + struct clk
Re: [PATCH v8 2/2] v4l: cadence: Add Cadence MIPI-CSI2 RX driver
Maxime, Thank you for the patch. Maxime Ripardwrote on Thu [2018-Feb-15 14:33:35 +0100]: > The Cadence CSI-2 RX Controller is an hardware block meant to be used as a > bridge between a CSI-2 bus and pixel grabbers. > > It supports operating with internal or external D-PHY, with up to 4 lanes, > or without any D-PHY. The current code only supports the latter case. > > It also support dynamic mapping of the CSI-2 virtual channels to the > associated pixel grabbers, but that isn't allowed at the moment either. > > Acked-by: Sakari Ailus > Signed-off-by: Maxime Ripard > --- > drivers/media/platform/Kconfig | 1 + > drivers/media/platform/Makefile | 2 + > drivers/media/platform/cadence/Kconfig | 17 + > drivers/media/platform/cadence/Makefile | 1 + > drivers/media/platform/cadence/cdns-csi2rx.c | 499 > +++ > 5 files changed, 520 insertions(+) > create mode 100644 drivers/media/platform/cadence/Kconfig > create mode 100644 drivers/media/platform/cadence/Makefile > create mode 100644 drivers/media/platform/cadence/cdns-csi2rx.c > > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig > index 614fbef08ddc..c001b646d441 100644 > --- a/drivers/media/platform/Kconfig > +++ b/drivers/media/platform/Kconfig > @@ -26,6 +26,7 @@ config VIDEO_VIA_CAMERA > # > # Platform multimedia device configuration > # > +source "drivers/media/platform/cadence/Kconfig" > > source "drivers/media/platform/davinci/Kconfig" > > diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile > index 7f3080437be6..3d29082fcf72 100644 > --- a/drivers/media/platform/Makefile > +++ b/drivers/media/platform/Makefile > @@ -3,6 +3,8 @@ > # Makefile for the video capture/playback device drivers. > # > > +obj-$(CONFIG_VIDEO_CADENCE) += cadence/ > + > obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o > > obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o > diff --git a/drivers/media/platform/cadence/Kconfig > b/drivers/media/platform/cadence/Kconfig > new file mode 100644 > index ..18f061e5cbd1 > --- /dev/null > +++ b/drivers/media/platform/cadence/Kconfig > @@ -0,0 +1,17 @@ > +config VIDEO_CADENCE > + bool "Cadence Video Devices" > + > +if VIDEO_CADENCE > + > +config VIDEO_CADENCE_CSI2RX > + tristate "Cadence MIPI-CSI2 RX Controller" > + depends on MEDIA_CONTROLLER > + depends on VIDEO_V4L2_SUBDEV_API > + select V4L2_FWNODE > + help > + Support for the Cadence MIPI CSI2 Receiver controller. > + > + To compile this driver as a module, choose M here: the module will be > + called cdns-csi2rx. > + > +endif > diff --git a/drivers/media/platform/cadence/Makefile > b/drivers/media/platform/cadence/Makefile > new file mode 100644 > index ..99a4086b7448 > --- /dev/null > +++ b/drivers/media/platform/cadence/Makefile > @@ -0,0 +1 @@ > +obj-$(CONFIG_VIDEO_CADENCE_CSI2RX) += cdns-csi2rx.o > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c > b/drivers/media/platform/cadence/cdns-csi2rx.c > new file mode 100644 > index ..99662e1a536b > --- /dev/null > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c > @@ -0,0 +1,499 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Driver for Cadence MIPI-CSI2 RX Controller v1.3 > + * > + * Copyright (C) 2017 Cadence Design Systems Inc. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#define CSI2RX_DEVICE_CFG_REG0x000 > + > +#define CSI2RX_SOFT_RESET_REG0x004 > +#define CSI2RX_SOFT_RESET_PROTOCOL BIT(1) > +#define CSI2RX_SOFT_RESET_FRONT BIT(0) > + > +#define CSI2RX_STATIC_CFG_REG0x008 > +#define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)((plane) << (16 + > (llane) * 4)) > +#define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8) > + > +#define CSI2RX_STREAM_BASE(n)(((n) + 1) * 0x100) > + > +#define CSI2RX_STREAM_CTRL_REG(n)(CSI2RX_STREAM_BASE(n) + 0x000) > +#define CSI2RX_STREAM_CTRL_START BIT(0) > + > +#define CSI2RX_STREAM_DATA_CFG_REG(n)(CSI2RX_STREAM_BASE(n) > + 0x008) > +#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT BIT(31) > +#define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n) BIT((n) + 16) > + > +#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c) > +#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF(1 << 8) > + > +#define CSI2RX_LANES_MAX 4 > +#define CSI2RX_STREAMS_MAX 4 > + > +enum csi2rx_pads { > + CSI2RX_PAD_SINK, > + CSI2RX_PAD_SOURCE_STREAM0, > + CSI2RX_PAD_SOURCE_STREAM1, > +
Re: [PATCH] media: tw9910: Whitespace alignment
On Thu, 2018-03-01 at 20:02 +0100, jacopo mondi wrote: > Hi Joe, Hello Jacopo > On Thu, Mar 01, 2018 at 03:50:22AM -0800, Joe Perches wrote: > > Update multiline statements to open parenthesis. > > Update a ?: to a single line. > > Thanks for the cleanup. > You may want to rebase this on my series from a few days ago > > https://patchwork.linuxtv.org/patch/47475/ My patch is completely trivial. I didn't see your patch but presumably Mauro, if he cares to apply this patch, can handle whatever conflicts that might exist. cheers, Joe
Re: [PATCH] media: tw9910: Whitespace alignment
Hi Joe, On Thu, Mar 01, 2018 at 03:50:22AM -0800, Joe Perches wrote: > Update multiline statements to open parenthesis. > Update a ?: to a single line. Thanks for the cleanup. You may want to rebase this on my series from a few days ago https://patchwork.linuxtv.org/patch/47475/ which includes some of the changes you made here and in patch [PATCH] media: tw9910: Miscellaneous neatening or the other way around and I should rebase mine on these two patches. Thanks j > > Signed-off-by: Joe Perches> --- > drivers/media/i2c/tw9910.c | 19 +-- > 1 file changed, 9 insertions(+), 10 deletions(-) > > diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c > index cc5d383fc6b8..ab32cd81ebd0 100644 > --- a/drivers/media/i2c/tw9910.c > +++ b/drivers/media/i2c/tw9910.c > @@ -445,7 +445,7 @@ static const struct tw9910_scale_ctrl > *tw9910_select_norm(v4l2_std_id norm, > > for (i = 0; i < size; i++) { > tmp = abs(width - scale[i].width) + > - abs(height - scale[i].height); > + abs(height - scale[i].height); > if (tmp < diff) { > diff = tmp; > ret = scale + i; > @@ -534,9 +534,9 @@ static int tw9910_s_std(struct v4l2_subdev *sd, > v4l2_std_id norm) > if (!ret) > ret = i2c_smbus_write_byte_data(client, CROP_HI, > ((vdelay >> 2) & 0xc0) | > - ((vact >> 4) & 0x30) | > - ((hdelay >> 6) & 0x0c) | > - ((hact >> 8) & 0x03)); > + ((vact >> 4) & 0x30) | > + ((hdelay >> 6) & 0x0c) | > + ((hact >> 8) & 0x03)); > if (!ret) > ret = i2c_smbus_write_byte_data(client, VDELAY_LO, > vdelay & 0xff); > @@ -642,8 +642,7 @@ static int tw9910_s_power(struct v4l2_subdev *sd, int on) > struct i2c_client *client = v4l2_get_subdevdata(sd); > struct tw9910_priv *priv = to_tw9910(client); > > - return on ? tw9910_power_on(priv) : > - tw9910_power_off(priv); > + return on ? tw9910_power_on(priv) : tw9910_power_off(priv); > } > > static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) > @@ -733,7 +732,7 @@ static int tw9910_set_frame(struct v4l2_subdev *sd, u32 > *width, u32 *height) > > static int tw9910_get_selection(struct v4l2_subdev *sd, > struct v4l2_subdev_pad_config *cfg, > - struct v4l2_subdev_selection *sel) > + struct v4l2_subdev_selection *sel) > { > struct i2c_client *client = v4l2_get_subdevdata(sd); > struct tw9910_priv *priv = to_tw9910(client); > @@ -758,7 +757,7 @@ static int tw9910_get_selection(struct v4l2_subdev *sd, > > static int tw9910_get_fmt(struct v4l2_subdev *sd, > struct v4l2_subdev_pad_config *cfg, > - struct v4l2_subdev_format *format) > + struct v4l2_subdev_format *format) > { > struct v4l2_mbus_framefmt *mf = >format; > struct i2c_client *client = v4l2_get_subdevdata(sd); > @@ -809,7 +808,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, > > static int tw9910_set_fmt(struct v4l2_subdev *sd, > struct v4l2_subdev_pad_config *cfg, > - struct v4l2_subdev_format *format) > + struct v4l2_subdev_format *format) > { > struct v4l2_mbus_framefmt *mf = >format; > struct i2c_client *client = v4l2_get_subdevdata(sd); > @@ -900,7 +899,7 @@ static const struct v4l2_subdev_core_ops > tw9910_subdev_core_ops = { > > static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, >struct v4l2_subdev_pad_config *cfg, > - struct v4l2_subdev_mbus_code_enum *code) > + struct v4l2_subdev_mbus_code_enum *code) > { > if (code->pad || code->index) > return -EINVAL; > -- > 2.15.0 >
Re: [PATCH] staging/imx: Fix inconsistent IS_ERR and PTR_ERR
On Thu, Mar 1, 2018 at 1:27 PM, Philipp Zabelwrote: > Oh, this only works for csi ports that have pinctrl in their csi port > node, like: > > _csi0 { > pinctrl-names = "default"; > pinctrl-0 = <_ipu1_csi0>; > }; This is the case for imx6qdl-sabresd.dtsi and even in this case devm_pinctrl_get_select_default() fails > pinctrl would have to be moved out of the csi port nodes, for example > into their parent ipu nodes, or maybe more correctly, into the video mux > nodes in each device tree. Tried it like this: --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -154,12 +154,9 @@ }; _csi0_mux_from_parallel_sensor { - remote-endpoint = <_to_ipu1_csi0_mux>; -}; - -_csi0 { pinctrl-names = "default"; pinctrl-0 = <_ipu1_csi0>; + remote-endpoint = <_to_ipu1_csi0_mux>; }; _csi { but still get the devm_pinctrl_get_select_default() failure. I was not able to change the dts so that devm_pinctrl_get_select_default() succeeds. If you agree I can send the following change: diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f8..c40f786 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1797,11 +1797,8 @@ static int imx_csi_probe(struct platform_device *pdev) */ priv->dev->of_node = pdata->of_node; pinctrl = devm_pinctrl_get_select_default(priv->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(priv->vdev); - goto free; - } - + if (IS_ERR(pinctrl)) + dev_dbg(priv->dev, "pintrl_get_select_default() failed\n"); ret = v4l2_async_register_subdev(>sd); if (ret) goto free; So that the error is ignored and we still can change the pinctrl values via dts. What do you think?
Re: [PATCH] staging/imx: Fix inconsistent IS_ERR and PTR_ERR
Steve, Phiipp, On Thu, Mar 1, 2018 at 1:02 PM, Fabio Estevamwrote: > So imx_csi_probe() does not succeed anymore since > devm_pinctrl_get_select_default() always fails. > > Not sure I understand the comments that explain the need for pinctrl > handling inside the driver. > > Can't we just get rid of it like this? Just tested and if devm_pinctrl_get_select_default() is removed, I am not able to change the ipu csi pinctrl settings anymore. I had to ignore devm_pinctrl_get_select_default() error value so that the driver can probe again: diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f8..c40f786 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1797,11 +1797,8 @@ static int imx_csi_probe(struct platform_device *pdev) */ priv->dev->of_node = pdata->of_node; pinctrl = devm_pinctrl_get_select_default(priv->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(priv->vdev); - goto free; - } - + if (IS_ERR(pinctrl)) + dev_dbg(priv->dev, "pintrl_get_select_default() failed\n"); ret = v4l2_async_register_subdev(>sd); if (ret) goto free; Is there a better solution for this issue?
Re: [PATCH] staging/imx: Fix inconsistent IS_ERR and PTR_ERR
On Thu, 2018-03-01 at 13:02 -0300, Fabio Estevam wrote: > On Thu, Mar 1, 2018 at 1:09 AM, Gustavo A. R. Silva >wrote: > > Fix inconsistent IS_ERR and PTR_ERR in imx_csi_probe. > > The proper pointer to be passed as argument is pinctrl > > instead of priv->vdev. > > > > This issue was detected with the help of Coccinelle. > > > > Fixes: 52e17089d185 ("media: imx: Don't initialize vars that won't be used") > > Signed-off-by: Gustavo A. R. Silva > > --- > > drivers/staging/media/imx/imx-media-csi.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/staging/media/imx/imx-media-csi.c > > b/drivers/staging/media/imx/imx-media-csi.c > > index 5a195f8..4f290a0 100644 > > --- a/drivers/staging/media/imx/imx-media-csi.c > > +++ b/drivers/staging/media/imx/imx-media-csi.c > > @@ -1798,7 +1798,7 @@ static int imx_csi_probe(struct platform_device *pdev) > > priv->dev->of_node = pdata->of_node; > > pinctrl = devm_pinctrl_get_select_default(priv->dev); > > if (IS_ERR(pinctrl)) { > > - ret = PTR_ERR(priv->vdev); > > + ret = PTR_ERR(pinctrl); > > goto free; > > This patch is correct, but now I am seeing that > devm_pinctrl_get_select_default() always fails. > > I added this debug line: > > --- a/drivers/staging/media/imx/imx-media-csi.c > +++ b/drivers/staging/media/imx/imx-media-csi.c > @@ -1799,6 +1799,7 @@ static int imx_csi_probe(struct platform_device *pdev) > pinctrl = devm_pinctrl_get_select_default(priv->dev); > if (IS_ERR(pinctrl)) { > ret = PTR_ERR(pinctrl); > + pr_err(" pinctrl failed\n"); > goto free; > } > > and this is what I get in imx6q-sabresd: > > [3.453905] imx-media: subdev ipu1_vdic bound > [3.458601] imx-media: subdev ipu2_vdic bound > [3.463341] imx-media: subdev ipu1_ic_prp bound > [3.468924] ipu1_ic_prpenc: Registered ipu1_ic_prpenc capture as > /dev/video0 > [3.476237] imx-media: subdev ipu1_ic_prpenc bound > [3.481621] ipu1_ic_prpvf: Registered ipu1_ic_prpvf capture as /dev/video1 > [3.488805] imx-media: subdev ipu1_ic_prpvf bound > [3.493659] imx-media: subdev ipu2_ic_prp bound > [3.498839] ipu2_ic_prpenc: Registered ipu2_ic_prpenc capture as > /dev/video2 > [3.505958] imx-media: subdev ipu2_ic_prpenc bound > [3.511318] ipu2_ic_prpvf: Registered ipu2_ic_prpvf capture as /dev/video3 > [3.518335] imx-media: subdev ipu2_ic_prpvf bound > [3.524622] ipu1_csi0: Registered ipu1_csi0 capture as /dev/video4 > [3.530902] imx-media: subdev ipu1_csi0 bound > [3.535453] pinctrl failed > [3.539684] pinctrl failed > [3.543677] pinctrl failed > [3.548278] imx-media: subdev imx6-mipi-csi2 bound > > So imx_csi_probe() does not succeed anymore since > devm_pinctrl_get_select_default() always fails. > > Not sure I understand the comments that explain the need for pinctrl > handling inside the driver. Oh, this only works for csi ports that have pinctrl in their csi port node, like: _csi0 { pinctrl-names = "default"; pinctrl-0 = <_ipu1_csi0>; }; For all other ports it fails. So we indeed have to silently continue if there is no pinctrl in the port node. > Can't we just get rid of it like this? pinctrl would have to be moved out of the csi port nodes, for example into their parent ipu nodes, or maybe more correctly, into the video mux nodes in each device tree. regards Philipp >
Re: [PATCH v5 2/2] v4l: cadence: Add Cadence MIPI-CSI2 TX driver
Hi Maxime, Thanks for your patch, I did not do a full review on this series, I only browsed it to check how you handled some CSI-2 related problems. While doing so I noticed a few small issues. On 2018-03-01 12:30:49 +0100, Maxime Ripard wrote: > The Cadence MIPI-CSI2 TX controller is an hardware block meant to be used > as a bridge between pixel interfaces and a CSI-2 bus. > > It supports operating with an internal or external D-PHY, with up to 4 > lanes, or without any D-PHY. The current code only supports the latter > case. > > While the virtual channel input on the pixel interface can be directly > mapped to CSI2, the datatype input is actually a selection signal (3-bits) > mapping to a table of up to 8 preconfigured datatypes/formats (programmed > at start-up) > > The block supports up to 8 input datatypes. > > Signed-off-by: Maxime Ripard> --- > drivers/media/platform/cadence/Kconfig | 11 + > drivers/media/platform/cadence/Makefile | 1 + > drivers/media/platform/cadence/cdns-csi2tx.c | 527 > +++ > 3 files changed, 539 insertions(+) > create mode 100644 drivers/media/platform/cadence/cdns-csi2tx.c > > diff --git a/drivers/media/platform/cadence/Kconfig > b/drivers/media/platform/cadence/Kconfig > index 18f061e5cbd1..83dcf2b1814b 100644 > --- a/drivers/media/platform/cadence/Kconfig > +++ b/drivers/media/platform/cadence/Kconfig > @@ -14,4 +14,15 @@ config VIDEO_CADENCE_CSI2RX > To compile this driver as a module, choose M here: the module will be > called cdns-csi2rx. > > +config VIDEO_CADENCE_CSI2TX > + tristate "Cadence MIPI-CSI2 TX Controller" > + depends on MEDIA_CONTROLLER > + depends on VIDEO_V4L2_SUBDEV_API > + select V4L2_FWNODE > + help > + Support for the Cadence MIPI CSI2 Transceiver controller. > + > + To compile this driver as a module, choose M here: the module will be > + called cdns-csi2tx. > + > endif > diff --git a/drivers/media/platform/cadence/Makefile > b/drivers/media/platform/cadence/Makefile > index 99a4086b7448..7fe992273162 100644 > --- a/drivers/media/platform/cadence/Makefile > +++ b/drivers/media/platform/cadence/Makefile > @@ -1 +1,2 @@ > obj-$(CONFIG_VIDEO_CADENCE_CSI2RX) += cdns-csi2rx.o > +obj-$(CONFIG_VIDEO_CADENCE_CSI2TX) += cdns-csi2tx.o > diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c > b/drivers/media/platform/cadence/cdns-csi2tx.c > new file mode 100644 > index ..8de277e6aec1 > --- /dev/null > +++ b/drivers/media/platform/cadence/cdns-csi2tx.c > @@ -0,0 +1,527 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Driver for Cadence MIPI-CSI2 TX Controller > + * > + * Copyright (C) 2017 Cadence Design Systems Inc. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#define CSI2TX_DEVICE_CONFIG_REG 0x00 > + > +#define CSI2TX_CONFIG_REG0x20 > +#define CSI2TX_CONFIG_CFG_REQBIT(2) > +#define CSI2TX_CONFIG_SRST_REQ BIT(1) > + > +#define CSI2TX_DPHY_CFG_REG 0x28 > +#define CSI2TX_DPHY_CFG_CLK_RESETBIT(16) > +#define CSI2TX_DPHY_CFG_LANE_RESET(n)BIT((n) + 12) > +#define CSI2TX_DPHY_CFG_MODE_MASKGENMASK(9, 8) > +#define CSI2TX_DPHY_CFG_MODE_LPDT(2 << 8) > +#define CSI2TX_DPHY_CFG_MODE_HS (1 << 8) > +#define CSI2TX_DPHY_CFG_MODE_ULPS(0 << 8) > +#define CSI2TX_DPHY_CFG_CLK_ENABLE BIT(4) > +#define CSI2TX_DPHY_CFG_LANE_ENABLE(n) BIT(n) > + > +#define CSI2TX_DPHY_CLK_WAKEUP_REG 0x2c > +#define CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(n)((n) & 0x) > + > +#define CSI2TX_DT_CFG_REG(n) (0x80 + (n) * 8) > +#define CSI2TX_DT_CFG_DT(n) (((n) & 0x3f) << 2) > + > +#define CSI2TX_DT_FORMAT_REG(n) (0x84 + (n) * 8) > +#define CSI2TX_DT_FORMAT_BYTES_PER_LINE(n) (((n) & 0x) << 16) > +#define CSI2TX_DT_FORMAT_MAX_LINE_NUM(n) ((n) & 0x) > + > +#define CSI2TX_STREAM_IF_CFG_REG(n) (0x100 + (n) * 4) > +#define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n) ((n) & 0x1f) > + > +#define CSI2TX_LANES_MAX 4 > +#define CSI2TX_STREAMS_MAX 4 > + > +enum csi2tx_pads { > + CSI2TX_PAD_SOURCE, > + CSI2TX_PAD_SINK_STREAM0, > + CSI2TX_PAD_SINK_STREAM1, > + CSI2TX_PAD_SINK_STREAM2, > + CSI2TX_PAD_SINK_STREAM3, > + CSI2TX_PAD_MAX, > +}; > + > +struct csi2tx_fmt { > + u32 mbus; > + u32 dt; > + u32 bpp; > +}; > + > +struct csi2tx_priv { > + struct device *dev; > + unsigned intcount; > + > + /* > + * Used to prevent race conditions between multiple, > + * concurrent calls to start and stop. > + */ > + struct mutexlock; > + > +
Re: [PATCH v5 0/2] media: v4l: Add support for the Cadence MIPI-CSI2 TX controller
Hi Maxime, Thanks for your patch-set, On 2018-03-01 12:30:47 +0100, Maxime Ripard wrote: > Hi, > > Here is an attempt at supporting the MIPI-CSI2 TX block from Cadence. > > This IP block is able to receive 4 video streams and stream them over > a MIPI-CSI2 link using up to 4 lanes. Those streams are basically the > interfaces to controllers generating some video signals, like a camera > or a pattern generator. > > It is able to map input streams to CSI2 virtual channels and datatypes > dynamically. The streaming devices choose their virtual channels > through an additional signal that is transparent to the CSI2-TX. The > datatypes however are yet another additional input signal, and can be > mapped to any CSI2 datatypes. > > Since v4l2 doesn't really allow for that setup at the moment, this > preliminary version is a rather dumb one in order to start the > discussion on how to address this properly. I'm sure you already are aware of this but in case you are not. Sakari have a branch [1] which addresses much of the CSI-2 virtual channel problems. It handles data types, virtual channels and format validation for pipelines in IMHO good way. I have used it for my base when implementing the R-Car CSI-2 receiver which adds a proposed way on how to start and stop streams using Sakaris work [2]. Would it be possible for you to try this series on-top of Sakaris branch and see if it fits your needs? I would be happy if it did and we can start the process of trying to get his work upstream so we can clear that dependency for our hopefully shared problem :-) 1. https://git.linuxtv.org/sailus/media_tree.git vc 2. https://git.ragnatech.se/linux v4l2/mux > > Let me know what you think! > Maxime > > Changes from v4: > - After playing a bit with the pad multiplexing patches, found that it > was making much more sense to have the subdev notifiers for the source > subdev rather for the sink that might even be outside of Linux control. > Removed the notifier for now. > > Changes from v3: > - Added a comment about entity links walk concurrency > - Changed the default resolution to 1280x720 > - Changed usleep_range calls to udelay > - Reworked the reference counting mechanism to remove a race > condition by adding a mutex instead of an atomic count > - Changed the entity function to MEDIA_ENT_F_VID_IF_BRIDGE > - Changed the name of the reg variable in _get_resources to dev_cfg > - Removed the redundant error message in the devm_ioremap_resource > error path > - Moved the subdev s_stream call before enabling the TX bridge > - Changed some int types to unsigned > - Init'd the pad formats properly > - Fixed typo in the CSI2TX_LANES_MAX define name > - Added Sakari Acked-by > > Changes from v2: > - Use SPDX license header > - Use the lane mapping from DT > > Changes from v1: > - Add a subdev notifier and start our downstream subdevice in > s_stream > - Based the decision to enable the stream or not on the link state > instead of whether a format was being set on the pad > - Put the controller back in reset when stopping the pipeline > - Clarified the enpoints number in the DT binding > - Added a default format for the pads > - Added some missing const > - Added more explicit comments > - Rebased on 4.15 > > Maxime Ripard (2): > dt-bindings: media: Add Cadence MIPI-CSI2 TX Device Tree bindings > v4l: cadence: Add Cadence MIPI-CSI2 TX driver > > .../devicetree/bindings/media/cdns,csi2tx.txt | 98 > drivers/media/platform/cadence/Kconfig | 11 + > drivers/media/platform/cadence/Makefile| 1 + > drivers/media/platform/cadence/cdns-csi2tx.c | 527 > + > 4 files changed, 637 insertions(+) > create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2tx.txt > create mode 100644 drivers/media/platform/cadence/cdns-csi2tx.c > > -- > 2.14.3 > -- Regards, Niklas Söderlund
Re: [PATCH] staging/imx: Fix inconsistent IS_ERR and PTR_ERR
On Thu, Mar 1, 2018 at 1:09 AM, Gustavo A. R. Silvawrote: > Fix inconsistent IS_ERR and PTR_ERR in imx_csi_probe. > The proper pointer to be passed as argument is pinctrl > instead of priv->vdev. > > This issue was detected with the help of Coccinelle. > > Fixes: 52e17089d185 ("media: imx: Don't initialize vars that won't be used") > Signed-off-by: Gustavo A. R. Silva > --- > drivers/staging/media/imx/imx-media-csi.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/media/imx/imx-media-csi.c > b/drivers/staging/media/imx/imx-media-csi.c > index 5a195f8..4f290a0 100644 > --- a/drivers/staging/media/imx/imx-media-csi.c > +++ b/drivers/staging/media/imx/imx-media-csi.c > @@ -1798,7 +1798,7 @@ static int imx_csi_probe(struct platform_device *pdev) > priv->dev->of_node = pdata->of_node; > pinctrl = devm_pinctrl_get_select_default(priv->dev); > if (IS_ERR(pinctrl)) { > - ret = PTR_ERR(priv->vdev); > + ret = PTR_ERR(pinctrl); > goto free; This patch is correct, but now I am seeing that devm_pinctrl_get_select_default() always fails. I added this debug line: --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1799,6 +1799,7 @@ static int imx_csi_probe(struct platform_device *pdev) pinctrl = devm_pinctrl_get_select_default(priv->dev); if (IS_ERR(pinctrl)) { ret = PTR_ERR(pinctrl); + pr_err(" pinctrl failed\n"); goto free; } and this is what I get in imx6q-sabresd: [3.453905] imx-media: subdev ipu1_vdic bound [3.458601] imx-media: subdev ipu2_vdic bound [3.463341] imx-media: subdev ipu1_ic_prp bound [3.468924] ipu1_ic_prpenc: Registered ipu1_ic_prpenc capture as /dev/video0 [3.476237] imx-media: subdev ipu1_ic_prpenc bound [3.481621] ipu1_ic_prpvf: Registered ipu1_ic_prpvf capture as /dev/video1 [3.488805] imx-media: subdev ipu1_ic_prpvf bound [3.493659] imx-media: subdev ipu2_ic_prp bound [3.498839] ipu2_ic_prpenc: Registered ipu2_ic_prpenc capture as /dev/video2 [3.505958] imx-media: subdev ipu2_ic_prpenc bound [3.511318] ipu2_ic_prpvf: Registered ipu2_ic_prpvf capture as /dev/video3 [3.518335] imx-media: subdev ipu2_ic_prpvf bound [3.524622] ipu1_csi0: Registered ipu1_csi0 capture as /dev/video4 [3.530902] imx-media: subdev ipu1_csi0 bound [3.535453] pinctrl failed [3.539684] pinctrl failed [3.543677] pinctrl failed [3.548278] imx-media: subdev imx6-mipi-csi2 bound So imx_csi_probe() does not succeed anymore since devm_pinctrl_get_select_default() always fails. Not sure I understand the comments that explain the need for pinctrl handling inside the driver. Can't we just get rid of it like this? --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -1739,7 +1738,6 @@ static const struct v4l2_subdev_internal_ops csi_internal_ops = { static int imx_csi_probe(struct platform_device *pdev) { struct ipu_client_platformdata *pdata; - struct pinctrl *pinctrl; struct csi_priv *priv; int ret; @@ -1789,19 +1787,7 @@ static int imx_csi_probe(struct platform_device *pdev) v4l2_ctrl_handler_init(>ctrl_hdlr, 0); priv->sd.ctrl_handler = >ctrl_hdlr; - /* -* The IPUv3 driver did not assign an of_node to this -* device. As a result, pinctrl does not automatically -* configure our pin groups, so we need to do that manually -* here, after setting this device's of_node. -*/ priv->dev->of_node = pdata->of_node; - pinctrl = devm_pinctrl_get_select_default(priv->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); - goto free; - } - ret = v4l2_async_register_subdev(>sd); if (ret) goto free;
Re: [PATCH v2 3/3] media: i2c: adv748x: Add support for i2c_new_secondary_device
Hi Kieran, I like this change :-) On 2018-02-27 15:05:50 +, Kieran Bingham wrote: > From: Kieran Bingham> > The ADV748x has twelve 256-byte maps that can be accessed via the main > I2C ports. Each map has it own I2C address and acts as a standard slave > device on the I2C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Kieran Bingham Reviewed-by: Niklas Söderlund > --- > drivers/media/i2c/adv748x/adv748x-core.c | 77 > +++- > drivers/media/i2c/adv748x/adv748x.h | 14 -- > 2 files changed, 36 insertions(+), 55 deletions(-) > > diff --git a/drivers/media/i2c/adv748x/adv748x-core.c > b/drivers/media/i2c/adv748x/adv748x-core.c > index 9dcaadaca217..911ccf6eb68c 100644 > --- a/drivers/media/i2c/adv748x/adv748x-core.c > +++ b/drivers/media/i2c/adv748x/adv748x-core.c > @@ -80,21 +80,24 @@ static int adv748x_configure_regmap(struct adv748x_state > *state, int region) > > return 0; > } > +struct adv748x_register_map { > + const char *name; > + u8 default_addr; > +}; > > -/* Default addresses for the I2C pages */ > -static int adv748x_i2c_addresses[ADV748X_PAGE_MAX] = { > - ADV748X_I2C_IO, > - ADV748X_I2C_DPLL, > - ADV748X_I2C_CP, > - ADV748X_I2C_HDMI, > - ADV748X_I2C_EDID, > - ADV748X_I2C_REPEATER, > - ADV748X_I2C_INFOFRAME, > - ADV748X_I2C_CBUS, > - ADV748X_I2C_CEC, > - ADV748X_I2C_SDP, > - ADV748X_I2C_TXB, > - ADV748X_I2C_TXA, > +static const struct adv748x_register_map adv748x_default_addresses[] = { > + [ADV748X_PAGE_IO] = { "main", 0x70 }, > + [ADV748X_PAGE_DPLL] = { "dpll", 0x26 }, > + [ADV748X_PAGE_CP] = { "cp", 0x22 }, > + [ADV748X_PAGE_HDMI] = { "hdmi", 0x34 }, > + [ADV748X_PAGE_EDID] = { "edid", 0x36 }, > + [ADV748X_PAGE_REPEATER] = { "repeater", 0x32 }, > + [ADV748X_PAGE_INFOFRAME] = { "infoframe", 0x31 }, > + [ADV748X_PAGE_CBUS] = { "cbus", 0x30 }, > + [ADV748X_PAGE_CEC] = { "cec", 0x41 }, > + [ADV748X_PAGE_SDP] = { "sdp", 0x79 }, > + [ADV748X_PAGE_TXB] = { "txb", 0x48 }, > + [ADV748X_PAGE_TXA] = { "txa", 0x4a }, > }; > > static int adv748x_read_check(struct adv748x_state *state, > @@ -143,15 +146,20 @@ int adv748x_write_block(struct adv748x_state *state, > int client_page, > return regmap_raw_write(regmap, init_reg, val, val_len); > } > > -static struct i2c_client *adv748x_dummy_client(struct adv748x_state *state, > -u8 addr, u8 io_reg) > +static int adv748x_set_slave_addresses(struct adv748x_state *state) > { > - struct i2c_client *client = state->client; > + struct i2c_client *client; > + unsigned int i; > + u8 io_reg; > + > + for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { > + io_reg = ADV748X_IO_SLAVE_ADDR_BASE + i; > + client = state->i2c_clients[i]; > > - if (addr) > - io_write(state, io_reg, addr << 1); > + io_write(state, io_reg, client->addr << 1); > + } > > - return i2c_new_dummy(client->adapter, io_read(state, io_reg) >> 1); > + return 0; > } > > static void adv748x_unregister_clients(struct adv748x_state *state) > @@ -164,13 +172,15 @@ static void adv748x_unregister_clients(struct > adv748x_state *state) > > static int adv748x_initialise_clients(struct adv748x_state *state) > { > - int i; > + unsigned int i; > int ret; > > for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { > - state->i2c_clients[i] = > - adv748x_dummy_client(state, adv748x_i2c_addresses[i], > - ADV748X_IO_SLAVE_ADDR_BASE + i); > + state->i2c_clients[i] = i2c_new_secondary_device( > + state->client, > + adv748x_default_addresses[i].name, > + adv748x_default_addresses[i].default_addr); > + > if (state->i2c_clients[i] == NULL) { > adv_err(state, "failed to create i2c client %u\n", i); > return -ENOMEM; > @@ -181,7 +191,7 @@ static int adv748x_initialise_clients(struct > adv748x_state *state) > return ret; > } > > - return 0; > + return adv748x_set_slave_addresses(state); > } > > /** > @@ -347,21 +357,6 @@ static const struct adv748x_reg_value adv748x_sw_reset[] > = { > {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ > }; > > -static const struct adv748x_reg_value adv748x_set_slave_address[] = { > - {ADV748X_PAGE_IO, 0xf3, ADV748X_I2C_DPLL << 1}, > - {ADV748X_PAGE_IO, 0xf4, ADV748X_I2C_CP << 1}, > - {ADV748X_PAGE_IO,
Re: [PATCH v2 1/3] media: i2c: adv748x: Simplify regmap configuration
Hi Kieran, Thanks for your patch, On 2018-02-27 15:05:48 +, Kieran Bingham wrote: > From: Kieran Bingham> > The ADV748x has identical map configurations for each register map. The > duplication of each map can be simplified using a helper macro such that > each map is represented on a single line. > > Define ADV748X_REGMAP_CONF for this purpose use it to create the tables. > > Signed-off-by: Kieran Bingham Reviewed-by: Niklas Söderlund > > --- > v2: > - Remove unnecessary #undef > > drivers/media/i2c/adv748x/adv748x-core.c | 109 > ++- > 1 file changed, 20 insertions(+), 89 deletions(-) > > diff --git a/drivers/media/i2c/adv748x/adv748x-core.c > b/drivers/media/i2c/adv748x/adv748x-core.c > index fd92c9e4b519..faf73949962b 100644 > --- a/drivers/media/i2c/adv748x/adv748x-core.c > +++ b/drivers/media/i2c/adv748x/adv748x-core.c > @@ -35,96 +35,27 @@ > * Register manipulation > */ > > -static const struct regmap_config adv748x_regmap_cnf[] = { > - { > - .name = "io", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "dpll", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "cp", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "hdmi", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "edid", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "repeater", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "infoframe", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "cec", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "sdp", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - > - { > - .name = "txb", > - .reg_bits = 8, > - .val_bits = 8, > - > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > - { > - .name = "txa", > - .reg_bits = 8, > - .val_bits = 8, > +#define ADV748X_REGMAP_CONF(n) \ > +{ \ > + .name = n, \ > + .reg_bits = 8, \ > + .val_bits = 8, \ > + .max_register = 0xff, \ > + .cache_type = REGCACHE_NONE, \ > +} > > - .max_register = 0xff, > - .cache_type = REGCACHE_NONE, > - }, > +static const struct regmap_config adv748x_regmap_cnf[] = { > + ADV748X_REGMAP_CONF("io"), > + ADV748X_REGMAP_CONF("dpll"), > + ADV748X_REGMAP_CONF("cp"), > + ADV748X_REGMAP_CONF("hdmi"), > + ADV748X_REGMAP_CONF("edid"), > + ADV748X_REGMAP_CONF("repeater"), > + ADV748X_REGMAP_CONF("infoframe"), > + ADV748X_REGMAP_CONF("cec"), > + ADV748X_REGMAP_CONF("sdp"), > + ADV748X_REGMAP_CONF("txa"), > + ADV748X_REGMAP_CONF("txb"), > }; > > static int adv748x_configure_regmap(struct adv748x_state *state, int region) > -- > 2.7.4 > -- Regards, Niklas Söderlund
[PATCH v6] media: imx258: Add imx258 camera sensor driver
Add a V4L2 sub-device driver for the Sony IMX258 image sensor. This is a camera sensor using the I2C bus for control and the CSI-2 bus for data. Signed-off-by: Andy YehSigned-off-by: Jason Chen Signed-off-by: Alan Chiang --- since v2: -- Update the streaming function to remove SW_STANDBY in the beginning. -- Adjust the delay time from 1ms to 12ms before set stream-on register. since v3: -- fix the sd.entity to make code be compiled on the mainline kernel. since v4: -- Enabled AG, DG, and Exposure time control correctly. since v5: -- Sensor vendor provided a new setting to fix different CLK issue -- Add i2c seq write function for writing 2 registers in 1 write command. MAINTAINERS|7 + drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/imx258.c | 1214 4 files changed, 1233 insertions(+) create mode 100644 drivers/media/i2c/imx258.c diff --git a/MAINTAINERS b/MAINTAINERS index a339bb5..9f75510 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12646,6 +12646,13 @@ S: Maintained F: drivers/ssb/ F: include/linux/ssb/ +SONY IMX258 SENSOR DRIVER +M: Sakari Ailus +L: linux-media@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/i2c/imx258.c + SONY IMX274 SENSOR DRIVER M: Leon Luo L: linux-media@vger.kernel.org diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index fd01842..bcd4bf1 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -565,6 +565,17 @@ config VIDEO_APTINA_PLL config VIDEO_SMIAPP_PLL tristate +config VIDEO_IMX258 + tristate "Sony IMX258 sensor support" + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + ---help--- + This is a Video4Linux2 sensor-level driver for the Sony + IMX258 camera. + + To compile this driver as a module, choose M here: the + module will be called imx258. + config VIDEO_IMX274 tristate "Sony IMX274 sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 1b62639..4bf7d00 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -94,6 +94,7 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o obj-$(CONFIG_VIDEO_OV2659) += ov2659.o obj-$(CONFIG_VIDEO_TC358743) += tc358743.o +obj-$(CONFIG_VIDEO_IMX258) += imx258.o obj-$(CONFIG_VIDEO_IMX274) += imx274.o obj-$(CONFIG_SDR_MAX2175) += max2175.o diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c new file mode 100644 index 000..0d0830d --- /dev/null +++ b/drivers/media/i2c/imx258.c @@ -0,0 +1,1214 @@ +// Copyright (C) 2018 Intel Corporation +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include + +#define IMX258_REG_VALUE_08BIT 1 +#define IMX258_REG_VALUE_16BIT 2 +#define IMX258_REG_VALUE_24BIT 3 + +#define IMX258_REG_MODE_SELECT 0x0100 +#define IMX258_MODE_STANDBY0x00 +#define IMX258_MODE_STREAMING 0x01 + +/* Chip ID */ +#define IMX258_REG_CHIP_ID 0x0016 +#define IMX258_CHIP_ID 0x0258 + +/* V_TIMING internal */ +#define IMX258_REG_VTS 0x0340 +#define IMX258_VTS_30FPS 0x0c98 +#define IMX258_VTS_MAX 0x + +/*Frame Length Line*/ +#define IMX258_FLL_MIN 0x08a6 +#define IMX258_FLL_MAX 0x +#define IMX258_FLL_STEP1 +#define IMX258_FLL_DEFAULT 0x0c98 + +/* HBLANK control - read only */ +#define IMX258_PPL_650MHZ 5352 +#define IMX258_PPL_325MHZ 2676 + +/* Exposure control */ +#define IMX258_REG_EXPOSURE0x0202 +#define IMX258_EXPOSURE_MIN4 +#define IMX258_EXPOSURE_STEP 1 +#define IMX258_EXPOSURE_DEFAULT0x640 +#define IMX258_EXPOSURE_MAX65535 + +/* Analog gain control */ +#define IMX258_REG_ANALOG_GAIN 0x0204 +#define IMX258_ANA_GAIN_MIN0 +#define IMX258_ANA_GAIN_MAX0x1fff +#define IMX258_ANA_GAIN_STEP 1 +#define IMX258_ANA_GAIN_DEFAULT0x0 + +/* Digital gain control */ +#define IMX258_REG_GR_DIGITAL_GAIN 0x020e +#define IMX258_REG_R_DIGITAL_GAIN 0x0210 +#define IMX258_REG_B_DIGITAL_GAIN 0x0212 +#define IMX258_REG_GB_DIGITAL_GAIN 0x0214 +#define IMX258_DGTL_GAIN_MIN 0 +#define IMX258_DGTL_GAIN_MAX 4096 /* Max = 0xFFF */ +#define IMX258_DGTL_GAIN_DEFAULT 1024 +#define IMX258_DGTL_GAIN_STEP 1 + +/* Orientation */ +#define
Re: [PULL] DVB-mmap Kconfig typo fix
On Thu, Mar 1, 2018 at 7:55 AM, Michael Ira Krufkywrote: > Please pull the following typo fix in the Kconfig for dvb-mmap: > > The following changes since commit 4df7ac5f42087dc9bcbed04b5cada0f025fbf9ef: > > drivers/media/Kconfig: typo: replace `with` with `which` (2018-02-15 > 08:01:22 -0500) > > are available in the git repository at: > > git://linuxtv.org/mkrufky/dvb.git dvb-mmap-v3 > > for you to fetch changes up to 4df7ac5f42087dc9bcbed04b5cada0f025fbf9ef: > > drivers/media/Kconfig: typo: replace `with` with `which` (2018-02-15 > 08:01:22 -0500) I realize I never sent the actual patch to the list. inline below: Author: Michael Ira Krufky Date: Tue Jan 16 22:16:12 2018 -0500 drivers/media/Kconfig: typo: replace `with` with `which` Signed-off-by: Michael Ira Krufky diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 372c074bb1b9..86c1a190d946 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -151,7 +151,7 @@ config DVB_MMAP select VIDEOBUF2_VMALLOC default n help - This option enables DVB experimental memory-mapped API, with + This option enables DVB experimental memory-mapped API, which reduces the number of context switches to read DVB buffers, as the buffers can use mmap() syscalls.
Re: [PATCH] vimc: use correct subdev functions
Hi Hans, On 02/07/2018 03:06 PM, Hans Verkuil wrote: Instead of calling everything a MEDIA_ENT_F_ATV_DECODER, pick the correct functions for these blocks. Nice, thanks for the patch Signed-off-by: Hans VerkuilAcked-by: Helen Koike --- diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 4d663e89d33f..6e10b63ba9ec 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -533,7 +533,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(>ved, >sd, v4l2_dev, pdata->entity_name, - MEDIA_ENT_F_ATV_DECODER, 2, + MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, (const unsigned long[2]) {MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE}, _deb_ops); diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index e1602e0bc230..e583ec7a91da 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -395,7 +395,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(>ved, >sd, v4l2_dev, pdata->entity_name, - MEDIA_ENT_F_ATV_DECODER, 2, + MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, (const unsigned long[2]) {MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE}, _sca_ops); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 457e211514c6..7d9fa9ccdb0e 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -378,7 +378,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, /* Initialize ved and sd */ ret = vimc_ent_sd_register(>ved, >sd, v4l2_dev, pdata->entity_name, - MEDIA_ENT_F_ATV_DECODER, 1, + MEDIA_ENT_F_CAM_SENSOR, 1, (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, _sen_ops); if (ret)
Re: [PATCH] v4l2-subdev: without controls return -ENOTTY
Hi Hans On 02/02/2018 11:05 AM, Hans Verkuil wrote: If the subdev did not define any controls, then return -ENOTTY if userspace attempts to call these ioctls. The control framework functions will return -EINVAL, not -ENOTTY if vfh->ctrl_handler is NULL. Several of these framework functions are also called directly from drivers, so I don't want to change the error code there. Right, I see, thanks for the patch Found with vimc and v4l2-compliance. Signed-off-by: Hans VerkuilAcked-by: Helen Koike --- diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 43fefa73e0a3..be7a19272614 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -187,27 +187,43 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) switch (cmd) { case VIDIOC_QUERYCTRL: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_queryctrl(vfh->ctrl_handler, arg); case VIDIOC_QUERY_EXT_CTRL: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); case VIDIOC_QUERYMENU: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_querymenu(vfh->ctrl_handler, arg); case VIDIOC_G_CTRL: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_g_ctrl(vfh->ctrl_handler, arg); case VIDIOC_S_CTRL: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg); case VIDIOC_G_EXT_CTRLS: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg); case VIDIOC_S_EXT_CTRLS: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg); case VIDIOC_TRY_EXT_CTRLS: + if (!vfh->ctrl_handler) + return -ENOTTY; return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg); case VIDIOC_DQEVENT:
Re: [PATCH] vimc: fix control event handling
Hi Hans, Thanks for the patch On 02/02/2018 11:00 AM, Hans Verkuil wrote: The sensor subdev didn't handle control events. Add support for this. Found with v4l2-compliance. Signed-off-by: Hans VerkuilAcked-by: Helen Koike --- diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 9d63c84a9876..617415c224fe 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -434,7 +434,9 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, v4l2_set_subdevdata(sd, ved); /* Expose this subdev to user space */ - sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + if (sd->ctrl_handler) + sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS; /* Initialize the media entity */ ret = media_entity_pads_init(>entity, num_pads, ved->pads); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 457e211514c6..54184cd9e0ff 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -284,11 +285,18 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) return 0; } +static struct v4l2_subdev_core_ops vimc_sen_core_ops = { + .log_status = v4l2_ctrl_subdev_log_status, + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + static const struct v4l2_subdev_video_ops vimc_sen_video_ops = { .s_stream = vimc_sen_s_stream, }; static const struct v4l2_subdev_ops vimc_sen_ops = { + .core = _sen_core_ops, .pad = _sen_pad_ops, .video = _sen_video_ops, };
[PULL] DVB-mmap Kconfig typo fix
Mauro, Please pull the following typo fix in the Kconfig for dvb-mmap: The following changes since commit 4df7ac5f42087dc9bcbed04b5cada0f025fbf9ef: drivers/media/Kconfig: typo: replace `with` with `which` (2018-02-15 08:01:22 -0500) are available in the git repository at: git://linuxtv.org/mkrufky/dvb.git dvb-mmap-v3 for you to fetch changes up to 4df7ac5f42087dc9bcbed04b5cada0f025fbf9ef: drivers/media/Kconfig: typo: replace `with` with `which` (2018-02-15 08:01:22 -0500) Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Cheers, Michael Ira Krufky
[PATCH] media: tw9910: Miscellaneous neatening
Yet more whitespace and style neatening o Add blank lines before returns o Reverse a logic test and return early on error o Move formats to same line as dev_ calls o Remove an unnecessary period from a logging message Signed-off-by: Joe Perches--- drivers/media/i2c/tw9910.c | 27 +-- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c index ab32cd81ebd0..cc648deb8123 100644 --- a/drivers/media/i2c/tw9910.c +++ b/drivers/media/i2c/tw9910.c @@ -752,6 +752,7 @@ static int tw9910_get_selection(struct v4l2_subdev *sd, sel->r.width= 768; sel->r.height = 576; } + return 0; } @@ -799,11 +800,13 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, mf->colorspace = V4L2_COLORSPACE_SMPTE170M; ret = tw9910_set_frame(sd, , ); - if (!ret) { - mf->width = width; - mf->height = height; - } - return ret; + if (ret) + return ret; + + mf->width = width; + mf->height = height; + + return 0; } static int tw9910_set_fmt(struct v4l2_subdev *sd, @@ -821,7 +824,7 @@ static int tw9910_set_fmt(struct v4l2_subdev *sd, if (mf->field == V4L2_FIELD_ANY) { mf->field = V4L2_FIELD_INTERLACED_BT; } else if (mf->field != V4L2_FIELD_INTERLACED_BT) { - dev_err(>dev, "Field type %d invalid.\n", mf->field); + dev_err(>dev, "Field type %d invalid\n", mf->field); return -EINVAL; } @@ -840,7 +843,9 @@ static int tw9910_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) return tw9910_s_fmt(sd, mf); + cfg->try_fmt = *mf; + return 0; } @@ -871,21 +876,21 @@ static int tw9910_video_probe(struct i2c_client *client) id = GET_ID(id); if (id != 0x0b || priv->revision > 0x01) { - dev_err(>dev, - "Product ID error %x:%x\n", + dev_err(>dev, "Product ID error %x:%x\n", id, priv->revision); ret = -ENODEV; goto done; } - dev_info(>dev, -"tw9910 Product ID %0x:%0x\n", id, priv->revision); + dev_info(>dev, "tw9910 Product ID %0x:%0x\n", +id, priv->revision); priv->norm = V4L2_STD_NTSC; priv->scale = _ntsc_scales[0]; done: tw9910_s_power(>subdev, 0); + return ret; } @@ -905,12 +910,14 @@ static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, return -EINVAL; code->code = MEDIA_BUS_FMT_UYVY8_2X8; + return 0; } static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) { *norm = V4L2_STD_NTSC | V4L2_STD_PAL; + return 0; } -- 2.15.0
[PATCH] media: tw9910: Whitespace alignment
Update multiline statements to open parenthesis. Update a ?: to a single line. Signed-off-by: Joe Perches--- drivers/media/i2c/tw9910.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c index cc5d383fc6b8..ab32cd81ebd0 100644 --- a/drivers/media/i2c/tw9910.c +++ b/drivers/media/i2c/tw9910.c @@ -445,7 +445,7 @@ static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm, for (i = 0; i < size; i++) { tmp = abs(width - scale[i].width) + - abs(height - scale[i].height); + abs(height - scale[i].height); if (tmp < diff) { diff = tmp; ret = scale + i; @@ -534,9 +534,9 @@ static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) if (!ret) ret = i2c_smbus_write_byte_data(client, CROP_HI, ((vdelay >> 2) & 0xc0) | - ((vact >> 4) & 0x30) | - ((hdelay >> 6) & 0x0c) | - ((hact >> 8) & 0x03)); + ((vact >> 4) & 0x30) | + ((hdelay >> 6) & 0x0c) | + ((hact >> 8) & 0x03)); if (!ret) ret = i2c_smbus_write_byte_data(client, VDELAY_LO, vdelay & 0xff); @@ -642,8 +642,7 @@ static int tw9910_s_power(struct v4l2_subdev *sd, int on) struct i2c_client *client = v4l2_get_subdevdata(sd); struct tw9910_priv *priv = to_tw9910(client); - return on ? tw9910_power_on(priv) : - tw9910_power_off(priv); + return on ? tw9910_power_on(priv) : tw9910_power_off(priv); } static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) @@ -733,7 +732,7 @@ static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) static int tw9910_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_selection *sel) + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct tw9910_priv *priv = to_tw9910(client); @@ -758,7 +757,7 @@ static int tw9910_get_selection(struct v4l2_subdev *sd, static int tw9910_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) + struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = >format; struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -809,7 +808,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, static int tw9910_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) + struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = >format; struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -900,7 +899,7 @@ static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) +struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index) return -EINVAL; -- 2.15.0
[PATCH v5 1/2] dt-bindings: media: Add Cadence MIPI-CSI2 TX Device Tree bindings
The Cadence MIPI-CSI2 TX controller is a CSI2 bridge that supports up to 4 video streams and can output on up to 4 CSI-2 lanes, depending on the hardware implementation. It can operate with an external D-PHY, an internal one or no D-PHY at all in some configurations. Acked-by: Rob HerringAcked-by: Sakari Ailus Signed-off-by: Maxime Ripard --- .../devicetree/bindings/media/cdns,csi2tx.txt | 98 ++ 1 file changed, 98 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2tx.txt diff --git a/Documentation/devicetree/bindings/media/cdns,csi2tx.txt b/Documentation/devicetree/bindings/media/cdns,csi2tx.txt new file mode 100644 index ..459c6e332f52 --- /dev/null +++ b/Documentation/devicetree/bindings/media/cdns,csi2tx.txt @@ -0,0 +1,98 @@ +Cadence MIPI-CSI2 TX controller +=== + +The Cadence MIPI-CSI2 TX controller is a CSI-2 bridge supporting up to +4 CSI lanes in output, and up to 4 different pixel streams in input. + +Required properties: + - compatible: must be set to "cdns,csi2tx" + - reg: base address and size of the memory mapped region + - clocks: phandles to the clocks driving the controller + - clock-names: must contain: +* esc_clk: escape mode clock +* p_clk: register bank clock +* pixel_if[0-3]_clk: pixel stream output clock, one for each stream + implemented in hardware, between 0 and 3 + +Optional properties + - phys: phandle to the D-PHY. If it is set, phy-names need to be set + - phy-names: must contain "dphy" + +Required subnodes: + - ports: A ports node with one port child node per device input and output + port, in accordance with the video interface bindings defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. The + port nodes are numbered as follows. + + Port Description + - + 0CSI-2 output + 1Stream 0 input + 2Stream 1 input + 3Stream 2 input + 4Stream 3 input + + The stream input port nodes are optional if they are not + connected to anything at the hardware level or implemented + in the design. Since there is only one endpoint per port, + the endpoints are not numbered. + +Example: + +csi2tx: csi-bridge@0d0e1000 { + compatible = "cdns,csi2tx"; + reg = <0x0d0e1000 0x1000>; + clocks = <>, <>, +<>, <>, +<>, <>; + clock-names = "p_clk", "esc_clk", + "pixel_if0_clk", "pixel_if1_clk", + "pixel_if2_clk", "pixel_if3_clk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi2tx_out: endpoint { + remote-endpoint = <_in>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + + csi2tx_in_stream0: endpoint { + remote-endpoint = <_out>; + }; + }; + + port@2 { + reg = <2>; + + csi2tx_in_stream1: endpoint { + remote-endpoint = <_out>; + }; + }; + + port@3 { + reg = <3>; + + csi2tx_in_stream2: endpoint { + remote-endpoint = <_out>; + }; + }; + + port@4 { + reg = <4>; + + csi2tx_in_stream3: endpoint { + remote-endpoint = <_out>; + }; + }; + }; +}; -- 2.14.3
[PATCH v5 2/2] v4l: cadence: Add Cadence MIPI-CSI2 TX driver
The Cadence MIPI-CSI2 TX controller is an hardware block meant to be used as a bridge between pixel interfaces and a CSI-2 bus. It supports operating with an internal or external D-PHY, with up to 4 lanes, or without any D-PHY. The current code only supports the latter case. While the virtual channel input on the pixel interface can be directly mapped to CSI2, the datatype input is actually a selection signal (3-bits) mapping to a table of up to 8 preconfigured datatypes/formats (programmed at start-up) The block supports up to 8 input datatypes. Signed-off-by: Maxime Ripard--- drivers/media/platform/cadence/Kconfig | 11 + drivers/media/platform/cadence/Makefile | 1 + drivers/media/platform/cadence/cdns-csi2tx.c | 527 +++ 3 files changed, 539 insertions(+) create mode 100644 drivers/media/platform/cadence/cdns-csi2tx.c diff --git a/drivers/media/platform/cadence/Kconfig b/drivers/media/platform/cadence/Kconfig index 18f061e5cbd1..83dcf2b1814b 100644 --- a/drivers/media/platform/cadence/Kconfig +++ b/drivers/media/platform/cadence/Kconfig @@ -14,4 +14,15 @@ config VIDEO_CADENCE_CSI2RX To compile this driver as a module, choose M here: the module will be called cdns-csi2rx. +config VIDEO_CADENCE_CSI2TX + tristate "Cadence MIPI-CSI2 TX Controller" + depends on MEDIA_CONTROLLER + depends on VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + Support for the Cadence MIPI CSI2 Transceiver controller. + + To compile this driver as a module, choose M here: the module will be + called cdns-csi2tx. + endif diff --git a/drivers/media/platform/cadence/Makefile b/drivers/media/platform/cadence/Makefile index 99a4086b7448..7fe992273162 100644 --- a/drivers/media/platform/cadence/Makefile +++ b/drivers/media/platform/cadence/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_VIDEO_CADENCE_CSI2RX) += cdns-csi2rx.o +obj-$(CONFIG_VIDEO_CADENCE_CSI2TX) += cdns-csi2tx.o diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c new file mode 100644 index ..8de277e6aec1 --- /dev/null +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -0,0 +1,527 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for Cadence MIPI-CSI2 TX Controller + * + * Copyright (C) 2017 Cadence Design Systems Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CSI2TX_DEVICE_CONFIG_REG 0x00 + +#define CSI2TX_CONFIG_REG 0x20 +#define CSI2TX_CONFIG_CFG_REQ BIT(2) +#define CSI2TX_CONFIG_SRST_REQ BIT(1) + +#define CSI2TX_DPHY_CFG_REG0x28 +#define CSI2TX_DPHY_CFG_CLK_RESET BIT(16) +#define CSI2TX_DPHY_CFG_LANE_RESET(n) BIT((n) + 12) +#define CSI2TX_DPHY_CFG_MODE_MASK GENMASK(9, 8) +#define CSI2TX_DPHY_CFG_MODE_LPDT (2 << 8) +#define CSI2TX_DPHY_CFG_MODE_HS(1 << 8) +#define CSI2TX_DPHY_CFG_MODE_ULPS (0 << 8) +#define CSI2TX_DPHY_CFG_CLK_ENABLE BIT(4) +#define CSI2TX_DPHY_CFG_LANE_ENABLE(n) BIT(n) + +#define CSI2TX_DPHY_CLK_WAKEUP_REG 0x2c +#define CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(n) ((n) & 0x) + +#define CSI2TX_DT_CFG_REG(n) (0x80 + (n) * 8) +#define CSI2TX_DT_CFG_DT(n)(((n) & 0x3f) << 2) + +#define CSI2TX_DT_FORMAT_REG(n)(0x84 + (n) * 8) +#define CSI2TX_DT_FORMAT_BYTES_PER_LINE(n) (((n) & 0x) << 16) +#define CSI2TX_DT_FORMAT_MAX_LINE_NUM(n) ((n) & 0x) + +#define CSI2TX_STREAM_IF_CFG_REG(n)(0x100 + (n) * 4) +#define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n) ((n) & 0x1f) + +#define CSI2TX_LANES_MAX 4 +#define CSI2TX_STREAMS_MAX 4 + +enum csi2tx_pads { + CSI2TX_PAD_SOURCE, + CSI2TX_PAD_SINK_STREAM0, + CSI2TX_PAD_SINK_STREAM1, + CSI2TX_PAD_SINK_STREAM2, + CSI2TX_PAD_SINK_STREAM3, + CSI2TX_PAD_MAX, +}; + +struct csi2tx_fmt { + u32 mbus; + u32 dt; + u32 bpp; +}; + +struct csi2tx_priv { + struct device *dev; + unsigned intcount; + + /* +* Used to prevent race conditions between multiple, +* concurrent calls to start and stop. +*/ + struct mutexlock; + + void __iomem*base; + + struct clk *esc_clk; + struct clk *p_clk; + struct clk *pixel_clk[CSI2TX_STREAMS_MAX]; + + struct v4l2_subdev subdev; + struct media_padpads[CSI2TX_PAD_MAX]; + struct v4l2_mbus_framefmt pad_fmts[CSI2TX_PAD_MAX]; + + boolhas_internal_dphy; + u8
[PATCH v5 0/2] media: v4l: Add support for the Cadence MIPI-CSI2 TX controller
Hi, Here is an attempt at supporting the MIPI-CSI2 TX block from Cadence. This IP block is able to receive 4 video streams and stream them over a MIPI-CSI2 link using up to 4 lanes. Those streams are basically the interfaces to controllers generating some video signals, like a camera or a pattern generator. It is able to map input streams to CSI2 virtual channels and datatypes dynamically. The streaming devices choose their virtual channels through an additional signal that is transparent to the CSI2-TX. The datatypes however are yet another additional input signal, and can be mapped to any CSI2 datatypes. Since v4l2 doesn't really allow for that setup at the moment, this preliminary version is a rather dumb one in order to start the discussion on how to address this properly. Let me know what you think! Maxime Changes from v4: - After playing a bit with the pad multiplexing patches, found that it was making much more sense to have the subdev notifiers for the source subdev rather for the sink that might even be outside of Linux control. Removed the notifier for now. Changes from v3: - Added a comment about entity links walk concurrency - Changed the default resolution to 1280x720 - Changed usleep_range calls to udelay - Reworked the reference counting mechanism to remove a race condition by adding a mutex instead of an atomic count - Changed the entity function to MEDIA_ENT_F_VID_IF_BRIDGE - Changed the name of the reg variable in _get_resources to dev_cfg - Removed the redundant error message in the devm_ioremap_resource error path - Moved the subdev s_stream call before enabling the TX bridge - Changed some int types to unsigned - Init'd the pad formats properly - Fixed typo in the CSI2TX_LANES_MAX define name - Added Sakari Acked-by Changes from v2: - Use SPDX license header - Use the lane mapping from DT Changes from v1: - Add a subdev notifier and start our downstream subdevice in s_stream - Based the decision to enable the stream or not on the link state instead of whether a format was being set on the pad - Put the controller back in reset when stopping the pipeline - Clarified the enpoints number in the DT binding - Added a default format for the pads - Added some missing const - Added more explicit comments - Rebased on 4.15 Maxime Ripard (2): dt-bindings: media: Add Cadence MIPI-CSI2 TX Device Tree bindings v4l: cadence: Add Cadence MIPI-CSI2 TX driver .../devicetree/bindings/media/cdns,csi2tx.txt | 98 drivers/media/platform/cadence/Kconfig | 11 + drivers/media/platform/cadence/Makefile| 1 + drivers/media/platform/cadence/cdns-csi2tx.c | 527 + 4 files changed, 637 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2tx.txt create mode 100644 drivers/media/platform/cadence/cdns-csi2tx.c -- 2.14.3
Re: [PATCH] media: ov2685: Not delay latch for gain
Hi Tomasz, On 2018年03月01日 16:53, Tomasz Figa wrote: Hi Shunqian, On Thu, Mar 1, 2018 at 5:44 PM, Shunqian Zhengwrote: Update the register 0x3503 to use 'no delay latch' for gain. This makes sensor to output the first frame as normal rather than a very dark one. I'm not 100% sure on how this setting works, but wouldn't it mean that setting the gain mid-frame would result in half of the frame having old gain and another half new? Depending how this works, perhaps we should set this during initial register settings, but reset after streaming starts? Thank you. I'm not quite sure too. Then I try to change gain during capture by: capture_10_frames.sh & while sleep .01; do v4l2-ctl -d /dev/video4 --set-ctrl=analogue_gain=54; sleep .01; v4l2-ctl -d /dev/video4 --set-ctrl=analogue_gain=1024; done The gain setting takes effect for every single frame, not in mid-frame from my test. Best wishes, - Shunqian Best regards, Tomasz
[PATCH] media: ov5695: Off by one in ov5695_enum_frame_sizes()
The ">" should be ">=" so that we don't read one element beyond the end of the array. Fixes: 8a77009be4be ("media: ov5695: add support for OV5695 sensor") Signed-off-by: Dan Carpenterdiff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index a4985a4715f5..9be38a0a2046 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -884,7 +884,7 @@ static int ov5695_enum_frame_sizes(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index > ARRAY_SIZE(supported_modes)) + if (fse->index >= ARRAY_SIZE(supported_modes)) return -EINVAL; if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
[bug report] media: i2c: Copy tw9910 soc_camera sensor driver
[ I know you're just copying files, but you might have a fix for these since you're looking at the code. - dan ] Hello Jacopo Mondi, The patch e0d76c3842ee: "media: i2c: Copy tw9910 soc_camera sensor driver" from Feb 21, 2018, leads to the following static checker warning: drivers/media/i2c/tw9910.c:395 tw9910_set_hsync() warn: odd binop '0x260 & 0x7' drivers/media/i2c/tw9910.c:396 tw9910_set_hsync() warn: odd binop '0x300 & 0x7' drivers/media/i2c/tw9910.c:538 tw9910_s_std() warn: odd binop '0x0 & 0xc' drivers/media/i2c/tw9910.c 374 static int tw9910_set_hsync(struct i2c_client *client) 375 { 376 struct tw9910_priv *priv = to_tw9910(client); 377 int ret; 378 379 /* bit 10 - 3 */ 380 ret = i2c_smbus_write_byte_data(client, HSBEGIN, 381 (HSYNC_START & 0x07F8) >> 3); 382 if (ret < 0) 383 return ret; 384 385 /* bit 10 - 3 */ 386 ret = i2c_smbus_write_byte_data(client, HSEND, 387 (HSYNC_END & 0x07F8) >> 3); 388 if (ret < 0) 389 return ret; 390 391 /* So far only revisions 0 and 1 have been seen */ 392 /* bit 2 - 0 */ 393 if (priv->revision == 1) 394 ret = tw9910_mask_set(client, HSLOWCTL, 0x77, 395(HSYNC_START & 0x0007) << 4 | 396(HSYNC_END & 0x0007)); These always mask to zero. 397 398 return ret; 399 } [ snip ] 511 static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 512 { 513 struct i2c_client *client = v4l2_get_subdevdata(sd); 514 struct tw9910_priv *priv = to_tw9910(client); 515 const unsigned int hact = 720; 516 const unsigned int hdelay = 15; ^^^ 517 unsigned int vact; 518 unsigned int vdelay; 519 int ret; 520 521 if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL))) 522 return -EINVAL; 523 524 priv->norm = norm; 525 if (norm & V4L2_STD_525_60) { 526 vact = 240; 527 vdelay = 18; 528 ret = tw9910_mask_set(client, VVBI, 0x10, 0x10); 529 } else { 530 vact = 288; 531 vdelay = 24; 532 ret = tw9910_mask_set(client, VVBI, 0x10, 0x00); 533 } 534 if (!ret) 535 ret = i2c_smbus_write_byte_data(client, CROP_HI, 536 ((vdelay >> 2) & 0xc0) | 537 ((vact >> 4) & 0x30) | 538 ((hdelay >> 6) & 0x0c) | ^^^ 15 >> 6 is zero. 539 ((hact >> 8) & 0x03)); 540 if (!ret) 541 ret = i2c_smbus_write_byte_data(client, VDELAY_LO, 542 vdelay & 0xff); 543 if (!ret) 544 ret = i2c_smbus_write_byte_data(client, VACTIVE_LO, 545 vact & 0xff); 546 547 return ret; 548 } regards, dan carpenter
Re: [PATCH] media: renesas-ceu: mark PM functions as __maybe_unused
On Thu, Mar 01, 2018 at 12:19:37AM +0100, Arnd Bergmann wrote: > The PM runtime operations are unused when CONFIG_PM is disabled, > leading to a harmless warning: > > drivers/media/platform/renesas-ceu.c:1003:12: error: 'ceu_runtime_suspend' > defined but not used [-Werror=unused-function] > static int ceu_runtime_suspend(struct device *dev) > ^~~ > drivers/media/platform/renesas-ceu.c:987:12: error: 'ceu_runtime_resume' > defined but not used [-Werror=unused-function] > static int ceu_runtime_resume(struct device *dev) > ^~ > > This adds a __maybe_unused annotation to shut up the warning. > > Fixes: 32e5a70dc8f4 ("media: platform: Add Renesas CEU driver") > Signed-off-by: Arnd BergmannReviewed-by: Simon Horman
Re: [PATCH RFC] media: em28xx: don't use coherent buffer for DMA transfers
Em Wed, 28 Feb 2018 09:49:12 -0500 Devin Heitmuellerescreveu: > On Tue, Feb 27, 2018 at 12:42 PM, Mauro Carvalho Chehab > wrote: > > While coherent memory is cheap on x86, it has problems on > > arm. So, stop using it. > > > > Signed-off-by: Mauro Carvalho Chehab > > --- > > > > I wrote this patch in order to check if this would make things better > > for ISOCH transfers on Raspberry Pi3. It didn't. Yet, keep using > > coherent memory at USB drivers seem an overkill. > > > > So, I'm actually not sure if we should either go ahead and merge it > > or not. > > > > Comments? Tests? > > For what it's worth, while I haven't tested this patch you're > proposing, I've been running what is essentially the same change in a > private tree for several years in order for the device to work better > with several TI Davinci SOC platforms. Good to know! I guess then it is worth applying it. Btw, while here, I'm wandering if it should keep using URB_ISO_ASAP flag or not. On my tests, for DVB, it seems to be working both ways. Didn't test analog TV yet. Thanks, Mauro
[PATCH v4l-utils] v4l2-compliance/v4l2-test-formats: fix typo
When using planar formats, we want to check pix_mp, not pix. Signed-off-by: Alexandre Courbot--- utils/v4l2-compliance/v4l2-test-formats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp index a336afdd..e9170688 100644 --- a/utils/v4l2-compliance/v4l2-test-formats.cpp +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp @@ -452,7 +452,7 @@ static int testFormatsType(struct node *node, int ret, unsigned type, struct v4 if (!node->is_m2m) fail_on_test(testColorspace(pix_mp.pixelformat, pix_mp.colorspace, pix_mp.ycbcr_enc, pix_mp.quantization)); - fail_on_test(pix.field == V4L2_FIELD_ANY); + fail_on_test(pix_mp.field == V4L2_FIELD_ANY); ret = check_0(pix_mp.reserved, sizeof(pix_mp.reserved)); if (ret) return fail("pix_mp.reserved not zeroed\n"); -- 2.16.2.395.g2e18187dfd-goog
Re: [PATCH] media: ov2685: Not delay latch for gain
Hi Shunqian, On Thu, Mar 1, 2018 at 5:44 PM, Shunqian Zhengwrote: > Update the register 0x3503 to use 'no delay latch' for gain. > This makes sensor to output the first frame as normal rather > than a very dark one. I'm not 100% sure on how this setting works, but wouldn't it mean that setting the gain mid-frame would result in half of the frame having old gain and another half new? Depending how this works, perhaps we should set this during initial register settings, but reset after streaming starts? Best regards, Tomasz
[PATCH] media: ov2685: Not delay latch for gain
Update the register 0x3503 to use 'no delay latch' for gain. This makes sensor to output the first frame as normal rather than a very dark one. Signed-off-by: Shunqian Zheng--- drivers/media/i2c/ov2685.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c index 9ac702e..83c55e8 100644 --- a/drivers/media/i2c/ov2685.c +++ b/drivers/media/i2c/ov2685.c @@ -119,7 +119,7 @@ struct ov2685 { {0x3087, 0x00}, {0x3501, 0x4e}, {0x3502, 0xe0}, - {0x3503, 0x07}, + {0x3503, 0x27}, {0x350b, 0x36}, {0x3600, 0xb4}, {0x3603, 0x35}, -- 1.9.1
Re: [PATCH] staging/imx: Fix inconsistent IS_ERR and PTR_ERR
On Wed, 2018-02-28 at 22:09 -0600, Gustavo A. R. Silva wrote: > Fix inconsistent IS_ERR and PTR_ERR in imx_csi_probe. > The proper pointer to be passed as argument is pinctrl > instead of priv->vdev. > > This issue was detected with the help of Coccinelle. > > Fixes: 52e17089d185 ("media: imx: Don't initialize vars that won't be used") > Signed-off-by: Gustavo A. R. Silva> --- > drivers/staging/media/imx/imx-media-csi.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/media/imx/imx-media-csi.c > b/drivers/staging/media/imx/imx-media-csi.c > index 5a195f8..4f290a0 100644 > --- a/drivers/staging/media/imx/imx-media-csi.c > +++ b/drivers/staging/media/imx/imx-media-csi.c > @@ -1798,7 +1798,7 @@ static int imx_csi_probe(struct platform_device *pdev) > priv->dev->of_node = pdata->of_node; > pinctrl = devm_pinctrl_get_select_default(priv->dev); > if (IS_ERR(pinctrl)) { > - ret = PTR_ERR(priv->vdev); > + ret = PTR_ERR(pinctrl); > goto free; > } Thanks, Acked-by: Philipp Zabel regards Philipp