Re: [PATCH 5/6 v5] uvcvideo: send a control event when a Control Change interrupt arrives
Hi Guennadi, [auto build test WARNING on linuxtv-media/master] [also build test WARNING on v4.13-rc2 next-20170728] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Guennadi-Liakhovetski/UVC-fix-queue_setup-to-check-the-number-of-planes/20170730-123108 base: git://linuxtv.org/media_tree.git master coccinelle warnings: (new ones prefixed by >>) >> drivers/media/usb/uvc/uvc_ctrl.c:1327:2-7: WARNING: NULL check before >> freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or >> usb_free_urb is not needed. Maybe consider reorganizing relevant code to >> avoid passing NULL values. Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
[PATCH] uvcvideo: fix ifnullfree.cocci warnings
drivers/media/usb/uvc/uvc_ctrl.c:1327:2-7: WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values. NULL check before some freeing functions is not needed. Based on checkpatch warning "kfree(NULL) is safe this check is probably not required" and kfreeaddr.cocci by Julia Lawall. Generated by: scripts/coccinelle/free/ifnullfree.cocci Fixes: c698cbbd35da ("uvcvideo: send a control event when a Control Change interrupt arrives") CC: Guennadi Liakhovetski Signed-off-by: Fengguang Wu --- uvc_ctrl.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1322,9 +1322,8 @@ void uvc_ctrl_status_event(struct uvc_de return; spin_lock(&w->lock); - if (w->data) /* A previous event work hasn't run yet, we lose 1 event */ - kfree(w->data); + kfree(w->data); w->data = kmalloc(len, GFP_ATOMIC); if (w->data) {
Re: [PATCH v2 1/3] media: V3s: Add support for Allwinner CSI.
Hi Maxime, Yong, On Fri, Jul 28, 2017 at 06:02:33PM +0200, Maxime Ripard wrote: > Hi, > > Thanks for the second iteration! > > On Thu, Jul 27, 2017 at 01:01:35PM +0800, Yong Deng wrote: > > Allwinner V3s SoC have two CSI module. CSI0 is used for MIPI interface > > and CSI1 is used for parallel interface. This is not documented in > > datasheet but by testing and guess. > > > > This patch implement a v4l2 framework driver for it. > > > > Currently, the driver only support the parallel interface. MIPI-CSI2, > > ISP's support are not included in this patch. > > > > Signed-off-by: Yong Deng [...] > > +#ifdef DEBUG > > +static void sun6i_csi_dump_regs(struct sun6i_csi_dev *sdev) > > +{ > > + struct regmap *regmap = sdev->regmap; > > + u32 val; > > + > > + regmap_read(regmap, CSI_EN_REG, &val); > > + printk("CSI_EN_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_IF_CFG_REG, &val); > > + printk("CSI_IF_CFG_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CAP_REG, &val); > > + printk("CSI_CAP_REG=0x%x\n",val); > > + regmap_read(regmap, CSI_SYNC_CNT_REG, &val); > > + printk("CSI_SYNC_CNT_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_FIFO_THRS_REG, &val); > > + printk("CSI_FIFO_THRS_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_PTN_LEN_REG, &val); > > + printk("CSI_PTN_LEN_REG=0x%x\n",val); > > + regmap_read(regmap, CSI_PTN_ADDR_REG, &val); > > + printk("CSI_PTN_ADDR_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_VER_REG, &val); > > + printk("CSI_VER_REG=0x%x\n",val); > > + regmap_read(regmap, CSI_CH_CFG_REG, &val); > > + printk("CSI_CH_CFG_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_SCALE_REG, &val); > > + printk("CSI_CH_SCALE_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_F0_BUFA_REG, &val); > > + printk("CSI_CH_F0_BUFA_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_F1_BUFA_REG, &val); > > + printk("CSI_CH_F1_BUFA_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_F2_BUFA_REG, &val); > > + printk("CSI_CH_F2_BUFA_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_STA_REG, &val); > > + printk("CSI_CH_STA_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_INT_EN_REG, &val); > > + printk("CSI_CH_INT_EN_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_INT_STA_REG, &val); > > + printk("CSI_CH_INT_STA_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_FLD1_VSIZE_REG, &val); > > + printk("CSI_CH_FLD1_VSIZE_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_HSIZE_REG, &val); > > + printk("CSI_CH_HSIZE_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_VSIZE_REG, &val); > > + printk("CSI_CH_VSIZE_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_BUF_LEN_REG, &val); > > + printk("CSI_CH_BUF_LEN_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_FLIP_SIZE_REG, &val); > > + printk("CSI_CH_FLIP_SIZE_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_FRM_CLK_CNT_REG, &val); > > + printk("CSI_CH_FRM_CLK_CNT_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_ACC_ITNL_CLK_CNT_REG, &val); > > + printk("CSI_CH_ACC_ITNL_CLK_CNT_REG=0x%x\n",val); > > + regmap_read(regmap, CSI_CH_FIFO_STAT_REG, &val); > > + printk("CSI_CH_FIFO_STAT_REG=0x%x\n", val); > > + regmap_read(regmap, CSI_CH_PCLK_STAT_REG, &val); > > + printk("CSI_CH_PCLK_STAT_REG=0x%x\n", val); > > +} > > +#endif > > You can already dump a regmap through debugfs, that's redundant. The advantage of in-code registers dump routine is the ability to synchronize the snapshot with the driver code execution. This is particularly important for the capture statistics registers. I have found it useful here. [...] > > +static int update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr) > > +{ > > + struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); > > + /* transform physical address to bus address */ > > + dma_addr_t bus_addr = addr - 0x4000; > > Like Baruch noticed, you should use PHYS_OFFSET here. The A80 for > example has a different RAM base address. > > > + > > + regmap_write(sdev->regmap, CSI_CH_F0_BUFA_REG, > > +(bus_addr + sdev->planar_offset[0]) >> 2); Why do you need the bit shift? Does that work for you? The User Manuals of both the V3s and the and the A33 (AKA R16) state that the BUFA field size in this register is 31:00, that is 32bit. I have found no indication of this bit shift in the Olimex provided sunxi-vfe[1] driver. On the A33 I have found that only after removing the bit-shift, (some sort of) data started to appear in the buffer. [1] https://github.com/hehopmajieh/a33_linux/tree/master/drivers/media/video/sunxi-vfe [...] > > +static irqreturn_t sun6i_csi_isr(int irq, void *dev_id) > > +{ > > + struct sun6i_csi_dev *sdev = (struct sun6i_csi_dev *)dev_id; > > + struct regmap *regmap = sdev->regmap; > > + u32 status; > > + > > +
Re: [PATCH v1 5/5] [media] stm32-dcmi: g_/s_selection crop support
Hi Hugues, [auto build test WARNING on linuxtv-media/master] [also build test WARNING on v4.13-rc2 next-20170728] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Hugues-Fruchet/STM32-DCMI-camera-interface-crop-support/20170730-114803 base: git://linuxtv.org/media_tree.git master config: powerpc-allmodconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings (new ones prefixed by >>): drivers/media//platform/stm32/stm32-dcmi.c: In function 'dcmi_graph_notify_complete': >> drivers/media//platform/stm32/stm32-dcmi.c:1445:5: warning: 'ret' may be >> used uninitialized in this function [-Wmaybe-uninitialized] if (ret) { ^ vim +/ret +1445 drivers/media//platform/stm32/stm32-dcmi.c 1431 1432 static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) 1433 { 1434 struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); 1435 int ret; 1436 1437 dcmi->vdev->ctrl_handler = dcmi->entity.subdev->ctrl_handler; 1438 ret = dcmi_formats_init(dcmi); 1439 if (ret) { 1440 dev_err(dcmi->dev, "No supported mediabus format found\n"); 1441 return ret; 1442 } 1443 1444 ret = dcmi_framesizes_init(dcmi); > 1445 if (ret) { 1446 dev_err(dcmi->dev, "Could not initialize framesizes\n"); 1447 return ret; 1448 } 1449 1450 ret = dcmi_get_sensor_bounds(dcmi, &dcmi->sd_bounds); 1451 if (ret) { 1452 dev_err(dcmi->dev, "Could not get sensor bounds\n"); 1453 return ret; 1454 } 1455 1456 ret = dcmi_set_default_fmt(dcmi); 1457 if (ret) { 1458 dev_err(dcmi->dev, "Could not set default format\n"); 1459 return ret; 1460 } 1461 1462 ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1); 1463 if (ret) { 1464 dev_err(dcmi->dev, "Failed to register video device\n"); 1465 return ret; 1466 } 1467 1468 dev_dbg(dcmi->dev, "Device registered as %s\n", 1469 video_device_node_name(dcmi->vdev)); 1470 return 0; 1471 } 1472 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
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: Sun Jul 30 05:00:14 CEST 2017 media-tree git hash:da48c948c263c9d87dfc64566b3373a858cc8aa2 media_build git hash: 1abc6be7b313cb92ff9128cea3d69df7f63e725f v4l-utils git hash: 6b5204abea527469012d3c40b1909b199b532614 gcc version:i686-linux-gcc (GCC) 7.1.0 sparse version: v0.5.0 smatch version: v0.5.0-3553-g78b2ea6 host hardware: x86_64 host os:4.11.0-164 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-multi: WARNINGS linux-git-arm-pxa: OK linux-git-arm-stm32: 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: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-3.0.60-i686: WARNINGS linux-3.1.10-i686: WARNINGS linux-3.2.37-i686: WARNINGS linux-3.3.8-i686: WARNINGS linux-3.4.27-i686: ERRORS linux-3.5.7-i686: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.8-i686: WARNINGS linux-3.9.2-i686: WARNINGS linux-3.10.1-i686: WARNINGS linux-3.11.1-i686: WARNINGS linux-3.12.67-i686: WARNINGS linux-3.13.11-i686: WARNINGS linux-3.14.9-i686: ERRORS linux-3.15.2-i686: ERRORS linux-3.16.7-i686: ERRORS linux-3.17.8-i686: ERRORS linux-3.18.7-i686: ERRORS linux-3.19-i686: WARNINGS linux-4.0.9-i686: WARNINGS linux-4.1.33-i686: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.3.6-i686: WARNINGS linux-4.4.22-i686: WARNINGS linux-4.5.7-i686: WARNINGS linux-4.6.7-i686: WARNINGS linux-4.7.5-i686: WARNINGS linux-4.8-i686: OK linux-4.9.26-i686: OK linux-4.10.14-i686: ERRORS linux-4.11-i686: OK linux-4.12.1-i686: OK linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.37-x86_64: WARNINGS linux-3.3.8-x86_64: WARNINGS linux-3.4.27-x86_64: ERRORS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-x86_64: WARNINGS linux-3.10.1-x86_64: WARNINGS linux-3.11.1-x86_64: WARNINGS linux-3.12.67-x86_64: WARNINGS linux-3.13.11-x86_64: WARNINGS linux-3.14.9-x86_64: ERRORS linux-3.15.2-x86_64: ERRORS linux-3.16.7-x86_64: ERRORS linux-3.17.8-x86_64: WARNINGS linux-3.18.7-x86_64: WARNINGS linux-3.19-x86_64: WARNINGS linux-4.0.9-x86_64: WARNINGS linux-4.1.33-x86_64: WARNINGS linux-4.2.8-x86_64: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.22-x86_64: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-x86_64: WARNINGS linux-4.7.5-x86_64: WARNINGS linux-4.8-x86_64: WARNINGS linux-4.9.26-x86_64: WARNINGS linux-4.10.14-x86_64: ERRORS linux-4.11-x86_64: WARNINGS linux-4.12.1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Sunday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Sunday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
[PATCH v3 4/4] drm: rcar-du: Repair vblank for DRM page flips using the VSP
From: Kieran Bingham The driver recently switched from handling page flip completion in the DU vertical blanking handler to the VSP frame end handler to fix a race condition. This unfortunately resulted in incorrect timestamps in the vertical blanking events sent to userspace as vertical blanking is now handled after sending the event. To fix this we must reverse the order of the two operations. The easiest way is to handle vertical blanking in the VSP frame end handler before sending the event. The VSP frame end interrupt occurs approximately 50µs earlier than the DU frame end interrupt, but this should not cause any undue harm. As we need to handle vertical blanking even when page flip completion is delayed, the VSP driver now needs to call the frame end completion callback unconditionally, with a new argument to report whether page flip has completed. With this new scheme the DU vertical blanking interrupt isn't needed anymore, so we can stop enabling it. Fixes: d503a43ac06a ("drm: rcar-du: Register a completion callback with VSP1") Signed-off-by: Kieran Bingham Signed-off-by: Laurent Pinchart Acked-by: Mauro Carvalho Chehab --- Changes compared to v2: - Enable the VBK interrupt when using the VSP as patch 3/4 now needs it Changes compared to v1: - Don't enable the VBK interrupt when using the VSP --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 8 +--- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c| 8 ++-- drivers/media/platform/vsp1/vsp1_drm.c | 5 +++-- drivers/media/platform/vsp1/vsp1_drm.h | 2 +- drivers/media/platform/vsp1/vsp1_pipe.c | 20 ++-- drivers/media/platform/vsp1/vsp1_pipe.h | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 6 +- include/media/vsp1.h | 2 +- 9 files changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 6e5bd0b92dfa..301ea1a8018e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -690,6 +690,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc) rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL); rcar_du_crtc_set(rcrtc, DIER, DIER_VBE); + rcrtc->vblank_enable = true; return 0; } @@ -699,6 +700,7 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc) struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE); + rcrtc->vblank_enable = false; } static const struct drm_crtc_funcs crtc_funcs = { @@ -743,10 +745,10 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) spin_unlock(&rcrtc->vblank_lock); if (status & DSSR_VBK) { - drm_crtc_handle_vblank(&rcrtc->crtc); - - if (rcdu->info->gen < 3) + if (rcdu->info->gen < 3) { + drm_crtc_handle_vblank(&rcrtc->crtc); rcar_du_crtc_finish_page_flip(rcrtc); + } ret = IRQ_HANDLED; } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 065b91f5b1d9..fdc2bf99bda1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -32,6 +32,7 @@ struct rcar_du_vsp; * @mmio_offset: offset of the CRTC registers in the DU MMIO block * @index: CRTC software and hardware index * @initialized: whether the CRTC has been initialized and clocks enabled + * @vblank_enable: whether vblank events are enabled on this CRTC * @event: event to post when the pending page flip completes * @flip_wait: wait queue used to signal page flip completion * @vblank_lock: protects vblank_wait and vblank_count @@ -51,6 +52,7 @@ struct rcar_du_crtc { unsigned int index; bool initialized; + bool vblank_enable; struct drm_pending_vblank_event *event; wait_queue_head_t flip_wait; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index e43b065e141a..6de6be3d9090 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -31,11 +31,15 @@ #include "rcar_du_kms.h" #include "rcar_du_vsp.h" -static void rcar_du_vsp_complete(void *private) +static void rcar_du_vsp_complete(void *private, bool completed) { struct rcar_du_crtc *crtc = private; - rcar_du_crtc_finish_page_flip(crtc); + if (crtc->vblank_enable) + drm_crtc_handle_vblank(&crtc->crtc); + + if (completed) + rcar_du_crtc_finish_page_flip(crtc); } void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 7791d7b5a743..4dfbeac8f42c 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -32,12 +32,13 @@ *
[PATCH v3 1/4] drm: rcar-du: Use the VBK interrupt for vblank events
When implementing support for interlaced modes, the driver switched from reporting vblank events on the vertical blanking (VBK) interrupt to the frame end interrupt (FRM). This incorrectly divided the reported refresh rate by two. Fix it by moving back to the VBK interrupt. Fixes: 906eff7fcada ("drm: rcar-du: Implement support for interlaced modes") Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 98cf446391dc..17fd1cd5212c 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -698,7 +698,7 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) status = rcar_du_crtc_read(rcrtc, DSSR); rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK); - if (status & DSSR_FRM) { + if (status & DSSR_VBK) { drm_crtc_handle_vblank(&rcrtc->crtc); if (rcdu->info->gen < 3) -- Regards, Laurent Pinchart
[PATCH v3 0/4] drm: rcar-du: Repair vblank event handling
Hello, The recent changes to the rcar-du driver to fix a page flip handling race condition changed the order of which vblanks and page flips are handled, resulting in incorrect timestamps being reported in the vblan events. Correct this by handling vblank events in the same completion handler as page flips. Compared to v2 patch 3/4 is completely rewritten with a new approach, as the previous one caused flip timeouts for a currently unknown reason. This version now uses the vertical blanking interrupt to handle the CRTC stop race regardless of the generation of the SoC. As a result drm_atomic_helper_wait_for_vblanks() can't be used anymore to wait for completion of a page flip or CRTC disable. I've thus included the previously posted patch "drm: rcar-du: Wait for flip completion instead of vblank in commit tail" in this series. I still plan to investigate why the original version caused issues, as I believe it went in the right direction. For now this series should do, as it doesn't introduce any hack and passes all tests properly. Kieran Bingham (1): drm: rcar-du: Repair vblank for DRM page flips using the VSP Laurent Pinchart (3): drm: rcar-du: Use the VBK interrupt for vblank events drm: rcar-du: Wait for flip completion instead of vblank in commit tail drm: rcar-du: Fix race condition when disabling planes at CRTC stop drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 66 +++- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 10 + drivers/gpu/drm/rcar-du/rcar_du_kms.c| 2 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c| 8 +++- drivers/media/platform/vsp1/vsp1_drm.c | 5 ++- drivers/media/platform/vsp1/vsp1_drm.h | 2 +- drivers/media/platform/vsp1/vsp1_pipe.c | 20 +- drivers/media/platform/vsp1/vsp1_pipe.h | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 6 ++- include/media/vsp1.h | 2 +- 10 files changed, 95 insertions(+), 28 deletions(-) -- Regards, Laurent Pinchart
[PATCH v3 3/4] drm: rcar-du: Fix race condition when disabling planes at CRTC stop
When stopping the CRTC the driver must disable all planes and wait for the change to take effect at the next vblank. Merely calling drm_crtc_wait_one_vblank() is not enough, as the function doesn't include any mechanism to handle the race with vblank interrupts. Replace the drm_crtc_wait_one_vblank() call with a manual mechanism that handles the vblank interrupt race. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 58 ++ drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 8 + 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 17fd1cd5212c..6e5bd0b92dfa 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -490,23 +490,51 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) rcar_du_group_start_stop(rcrtc->group, true); } +static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc) +{ + struct rcar_du_device *rcdu = rcrtc->group->dev; + struct drm_crtc *crtc = &rcrtc->crtc; + u32 status; + + /* Make sure vblank interrupts are enabled. */ + drm_crtc_vblank_get(crtc); + + /* +* Disable planes and calculate how many vertical blanking interrupts we +* have to wait for. If a vertical blanking interrupt has been triggered +* but not processed yet, we don't know whether it occurred before or +* after the planes got disabled. We thus have to wait for two vblank +* interrupts in that case. +*/ + spin_lock_irq(&rcrtc->vblank_lock); + rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0); + status = rcar_du_crtc_read(rcrtc, DSSR); + rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1; + spin_unlock_irq(&rcrtc->vblank_lock); + + if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0, + msecs_to_jiffies(100))) + dev_warn(rcdu->dev, "vertical blanking timeout\n"); + + drm_crtc_vblank_put(crtc); +} + static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc) { struct drm_crtc *crtc = &rcrtc->crtc; /* * Disable all planes and wait for the change to take effect. This is -* required as the DSnPR registers are updated on vblank, and no vblank -* will occur once the CRTC is stopped. Disabling planes when starting -* the CRTC thus wouldn't be enough as it would start scanning out -* immediately from old frame buffers until the next vblank. +* required as the plane enable registers are updated on vblank, and no +* vblank will occur once the CRTC is stopped. Disabling planes when +* starting the CRTC thus wouldn't be enough as it would start scanning +* out immediately from old frame buffers until the next vblank. * * This increases the CRTC stop delay, especially when multiple CRTCs * are stopped in one operation as we now wait for one vblank per CRTC. * Whether this can be improved needs to be researched. */ - rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0); - drm_crtc_wait_one_vblank(crtc); + rcar_du_crtc_disable_planes(rcrtc); /* * Disable vertical blanking interrupt reporting. We first need to wait @@ -695,10 +723,26 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) irqreturn_t ret = IRQ_NONE; u32 status; + spin_lock(&rcrtc->vblank_lock); + status = rcar_du_crtc_read(rcrtc, DSSR); rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK); if (status & DSSR_VBK) { + /* +* Wake up the vblank wait if the counter reaches 0. This must +* be protected by the vblank_lock to avoid races in +* rcar_du_crtc_disable_planes(). +*/ + if (rcrtc->vblank_count) { + if (--rcrtc->vblank_count == 0) + wake_up(&rcrtc->vblank_wait); + } + } + + spin_unlock(&rcrtc->vblank_lock); + + if (status & DSSR_VBK) { drm_crtc_handle_vblank(&rcrtc->crtc); if (rcdu->info->gen < 3) @@ -756,6 +800,8 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) } init_waitqueue_head(&rcrtc->flip_wait); + init_waitqueue_head(&rcrtc->vblank_wait); + spin_lock_init(&rcrtc->vblank_lock); rcrtc->group = rgrp; rcrtc->mmio_offset = mmio_offsets[index]; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 3cc376826592..065b91f5b1d9 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -15,6 +15,7 @@ #define __RCAR_DU_CRTC_H__ #include +
[PATCH v3 2/4] drm: rcar-du: Wait for flip completion instead of vblank in commit tail
Page flips can take more than one vertical blanking to complete if arming the page flips races with the vertical blanking interrupt. Waiting for one vblank to complete the atomic commit in the commit tail handler is thus incorrect, and can lead to framebuffers being released while still being scanned out. Fix this by waiting for flip completion instead, using the drm_atomic_helper_wait_for_flip_done() helper. Fixes: 0d230422d256 ("drm: rcar-du: Register a completion callback with VSP1") Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index b91257dee98f..221e22922396 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -262,7 +262,7 @@ static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_commit_modeset_enables(dev, old_state); drm_atomic_helper_commit_hw_done(old_state); - drm_atomic_helper_wait_for_vblanks(dev, old_state); + drm_atomic_helper_wait_for_flip_done(dev, old_state); drm_atomic_helper_cleanup_planes(dev, old_state); } -- Regards, Laurent Pinchart
Re: Kworld 340U (1b80:a340) kernel 4.8.0 ERROR: i2c_transfer returned: -6
On Fri, Jul 28, 2017 at 11:54 PM, Kumar Vivek wrote: > Thank you Frank! I appreciate your time. > This is what I have done so far - > > On Wed, Jul 19, 2017 at 2:44 PM, Frank Schäfer > wrote: >> >> Hi Kumar, >> >> I don't have time for the em28xx driver at the moment (and I also do not >> have access to a device with tda18271 tuner). >> But... >> >> Am 08.07.2017 um 22:29 schrieb Kumar Vivek: >>> New subscriber and first time poster. I have tried to read most of the >>> instructions and etiquettes regarding the mailing list but there might >>> still be some noob mistakes on my part. >>> >>> I have had this tuner for a while and I used it successfully in 2009 >>> (with help from Markus Rechberger - who provided me with the >>> appropriate patch). I saw that the patches were included in the kernel >>> drivers and this was fully supported. I tried to use it again recently >>> and ran into problems and hence this mail. I have spent days trying to >>> figure out the problem and have been unsuccessful. >>> >>> I am using kernel 4.8.0 >>> >>> The variant of this USB ATSC device I have has vid:pid = 1b80:a340 , >>> EM2870 USB bridge, lgdt3304 demodulator/Frontend, TDA18271HDC2 tuner. >>> >>> I loaded the em28xx module with debugging on - including i2c bus scan >>> and i2c transfer. >>> >>> [ 320.139648] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=0: >>> [ 320.139652] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 >>> [ 320.140008] <<< cf >>> [ 320.140038] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.140732] em2870 #0: found i2c device @ 0x1c on bus 0 [lgdt330x] >>> >>> . >>> [ 320.177163] (pipe 0x8280): IN: c0 02 00 00 a0 00 01 00 >>> [ 320.177541] <<< 1a >>> [ 320.177547] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.177663] em2870 #0: found i2c device @ 0xa0 on bus 0 [eeprom] >>> . >>> >>> [ 320.186289] (pipe 0x8280): IN: c0 02 00 00 c4 00 01 00 >>> [ 320.186659] <<< 84 >>> [ 320.186665] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.186945] em2870 #0: found i2c device @ 0xc4 on bus 0 [tuner (analog)] >>> >>> This is a bit strange since the tuner TDA18271HDC2 is at 0x60 (7 bit) >>> or 0xC0 (8 bit) i2c address and usually - i2cbus scan doesn't reveal >>> the tuner's address. >>> >>> And then this happens : >>> [ 320.203404] em2870 #0: Identified as KWorld PlusTV 340U or UB435-Q >>> (ATSC) (card=76) >>> [ 320.203406] em28xx: Currently, V4L2 is not supported on this model >>> [ 320.203407] em2870 #0: dvb set to isoc mode. >>> [ 320.260270] em2870 #0: Binding DVB extension >>> [ 320.260274] em2870 #0 em28xx_alloc_urbs :em28xx: called >>> em28xx_alloc_isoc in mode 2 >>> [ 320.260276] em2870 #0 em28xx_uninit_usb_xfer :em28xx: called >>> em28xx_uninit_usb_xfer in mode 2 >>> [ 320.260279] (pipe 0x8280): IN: c0 00 00 00 0c 00 01 00 <<< 00 >>> [ 320.260536] (pipe 0x8200): OUT: 40 00 00 00 0c 00 01 00 >>> 00 >>> [ 320.260631] (pipe 0x8200): OUT: 40 00 00 00 12 00 01 00 >>> 27 >>> [ 320.260833] (pipe 0x8200): OUT: 40 00 00 00 48 00 01 00 >>> 00 >>> [ 320.260987] (pipe 0x8200): OUT: 40 00 00 00 12 00 01 00 >>> 37 >>> [ 320.275990] (pipe 0x8280): IN: c0 00 00 00 08 00 01 00 <<< ff >>> [ 320.278154] (pipe 0x8200): OUT: 40 00 00 00 08 00 01 00 >>> 7d >>> [ 320.337050] em2870 #0 at em28xx_i2c_xfer: write nonstop addr=1c len=2: >>> 00 01 >>> [ 320.337056] (pipe 0x8200): OUT: 40 03 00 00 1c 00 02 00 >>> >>> [ 320.337057] 00 01 >>> [ 320.337502] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.337618] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=1: >>> [ 320.337620] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 >>> [ 320.337860] <<< 30 >>> [ 320.337867] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> [ 320.337979] 30 >>> [ 320.337984] em2870 #0 at em28xx_i2c_xfer: write stop addr=1c len=3: 08 >>> 08 80 >>> [ 320.337987] (pipe 0x8200): OUT: 40 02 00 00 1c 00 03 00 >>> >>> [ 320.337988] 08 08 80 >>> [ 320.338518] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.338618] em2870 #0 at em28xx_i2c_xfer: write nonstop addr=1c len=2: >>> 08 08 >>> [ 320.338622] (pipe 0x8200): OUT: 40 03 00 00 1c 00 02 00 >>> >>> [ 320.338623] 08 08 >>> [ 320.339018] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.339110] em2870 #0 at em28xx_i2c_xfer: read stop addr=1c len=1: >>> [ 320.339113] (pipe 0x8280): IN: c0 02 00 00 1c 00 01 00 >>> [ 320.339391] <<< 80 >>> [ 320.339397] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> [ 320.339490] 80 >>> [ 320.339496] em2870 #0 at em28xx_i2c_xfer: write stop addr=1c len=3: 08 >>> 08 00 >>> [ 320.339499] (pipe 0x8200): OUT: 40 02 00 00 1c 00 03 00 >>> >>> [ 320.339499] 08 08 00 >>> [ 320.340768] (pipe 0x8280): IN: c0 00 00 00 05 00 01 00 <<< 00 >>> >>> [ 320.341276] tda18271 12-0060: creating new instance >>> [ 32
Re: ir-keytable question [Ubuntu 17.04]
On Sat, Jul 29, 2017 at 11:23:22AM +0100, Sean Young wrote: > Hi, > > On Sun, Jul 16, 2017 at 10:26:14PM -0700, Szabolcs Andrasi wrote: > > Hi, > > > > I'm using Ubuntu 17.04 and I installed the ir-keytable tool. The > > output of the ir-keytable command is as follows: > > > > > > > > Found /sys/class/rc/rc0/ (/dev/input/event5) with: > > Driver ite-cir, table rc-rc6-mce > > Supported protocols: unknown other lirc rc-5 rc-5-sz jvc sony nec > > sanyo mce_kbd rc-6 sharp xmp > > Enabled protocols: lirc rc-6 > > Name: ITE8708 CIR transceiver > > bus: 25, vendor/product: 1283:, version: 0x > > Repeat delay = 500 ms, repeat period = 125 ms > > > > > > > > I'm trying to enable the supported mce_kbd protocol in addition to the > > lirc and rc-6 protocols with the > > > > $ sudo ir-keytable -p lirc -p rc-6 -p mce_kbd > > > > command which works as expected. If, however, I reboot my computer, > > ir-keytable forgets this change and only the lirc and rc-6 protocols > > are enabled. Is there a configuration file I can edit so that after > > the boot my IR remote still works? Or is that so that the only way to > > make it work is to write a start-up script that runs the above command > > to enable the needed protocol? > > So what we have today is /etc/rc_maps.cfg, where you can select the default > keymap for a particular driver; unfortunately, you can only select one > keymap and one keymap can only have one protocol. > > Ideally we could either have more than one protocol per keymap, which > would be helpful for the MCE Keyboard, or we could allow multiple keymaps > which would be great for supporting different remotes at the same time. Having more than one protocol in the keymap file works fine here, we have been using that feature in LibreELEC for a long time now. Maybe it was just forgotten to document it? $ git show 42511eb505 commit 42511eb505b46b125652d37e764e5c8d1eb99e6b Author: Mauro Carvalho Chehab Date: Sat Apr 10 21:55:28 2010 -0300 ir-keytable: add support for more than one protocol in a table Signed-off-by: Mauro Carvalho Chehab Quick test with ir-keytable 1.12.3 from Debian Stretch: $ sudo ir-keytable -c -p lirc,rc-6 -s rc1 Old keytable cleared Protocols changed to lirc rc-6 $ sudo ir-keytable -r -s rc1 Enabled protocols: lirc rc-6 $ cat /etc/rc_keymaps/rc6_mce_kbd_test # table test, type:rc-6,mce_kbd 0x01KEY_1 $ cat test-map.cfg * * rc6_mce_kbd_test $ sudo ir-keytable -a test-map.cfg -s rc1 Old keytable cleared Wrote 1 keycode(s) to driver Protocols changed to mce_kbd rc-6 $ sudo ir-keytable -r -s rc1 scancode 0x0001 = KEY_1 (0x02) Enabled protocols: lirc mce_kbd rc-6 so long, Hias > > For now, you could add a udev rule to also enable the mce_kbd protocol. > > > Sean
[PATCH v2 13/14] [media] ddbridge: Kconfig option to control the MSI modparam default
From: Daniel Scheller It is known that MSI interrupts - while working quite well so far - can still cause issues on some hardware platforms (causing I2C timeouts due to unhandled interrupts). The msi variable/option is set to 1 by default. So, add a Kconfig option prefixed with "EXPERIMENTAL" that will control the default value of that modparam, defaulting to off for a better user experience and (guaranteed) stable operation "per default". Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/Kconfig | 15 +++ drivers/media/pci/ddbridge/ddbridge-main.c | 11 +-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index c79a58fa5fc3..1330b2ecc72a 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -26,3 +26,18 @@ config DVB_DDBRIDGE - CineS2 V7/V7A and DuoFlex S2 V4 (ST STV0910-based) Say Y if you own such a card and want to use it. + +config DVB_DDBRIDGE_MSIENABLE + bool "Enable Message Signaled Interrupts (MSI) per default (EXPERIMENTAL)" + depends on DVB_DDBRIDGE + depends on PCI_MSI + default n + ---help--- + Use PCI MSI (Message Signaled Interrupts) per default. Enabling this + might lead to I2C errors originating from the bridge in conjunction + with certain SATA controllers, requiring a reload of the ddbridge + module. MSI can still be disabled by passing msi=0 as option, as + this will just change the msi option default value. + + If you're unsure, concerned about stability and don't want to pass + module options in case of troubles, say N. diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 5094d2ef79d6..5a930a6e9fb2 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -47,10 +47,17 @@ MODULE_PARM_DESC(adapter_alloc, "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); #ifdef CONFIG_PCI_MSI +#ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE int msi = 1; +#else +int msi; +#endif module_param(msi, int, 0444); -MODULE_PARM_DESC(msi, -" Control MSI interrupts: 0-disable, 1-enable (default)"); +#ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE +MODULE_PARM_DESC(msi, "Control MSI interrupts: 0-disable, 1-enable (default)"); +#else +MODULE_PARM_DESC(msi, "Control MSI interrupts: 0-disable (default), 1-enable"); +#endif #endif int ci_bitrate = 7; -- 2.13.0
[PATCH v2 06/14] [media] ddbridge: split off hardware definitions and mappings
From: Daniel Scheller Further cleanup of ddbridge-core and ddbridge-main, and moves all such hw definitions into one single place, making things easier to maintain. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/Makefile| 4 +- drivers/media/pci/ddbridge/ddbridge-core.c | 68 --- drivers/media/pci/ddbridge/ddbridge-hw.c | 299 + drivers/media/pci/ddbridge/ddbridge-hw.h | 52 + drivers/media/pci/ddbridge/ddbridge-main.c | 217 + drivers/media/pci/ddbridge/ddbridge.h | 1 - 6 files changed, 354 insertions(+), 287 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-hw.c create mode 100644 drivers/media/pci/ddbridge/ddbridge-hw.h diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index 0a7caa95a3b6..c4d8d6261243 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -2,8 +2,8 @@ # Makefile for the ddbridge device driver # -ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o \ - ddbridge-irq.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \ + ddbridge-i2c.o ddbridge-irq.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index d2f6713539d4..758073b716a2 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -67,74 +67,6 @@ static struct ddb *ddbs[DDB_MAX_ADAPTER]; // // -static struct ddb_regset octopus_input = { - .base = 0x200, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_output = { - .base = 0x280, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_idma = { - .base = 0x300, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_idma_buf = { - .base = 0x2000, - .num = 0x08, - .size = 0x100, -}; - -static struct ddb_regset octopus_odma = { - .base = 0x380, - .num = 0x04, - .size = 0x10, -}; - -static struct ddb_regset octopus_odma_buf = { - .base = 0x2800, - .num = 0x04, - .size = 0x100, -}; - -static struct ddb_regset octopus_i2c = { - .base = 0x80, - .num = 0x04, - .size = 0x20, -}; - -static struct ddb_regset octopus_i2c_buf = { - .base = 0x1000, - .num = 0x04, - .size = 0x200, -}; - -// - -struct ddb_regmap octopus_map = { - .irq_base_i2c = 0, - .irq_base_idma = 8, - .irq_base_odma = 16, - .i2c = &octopus_i2c, - .i2c_buf = &octopus_i2c_buf, - .idma = &octopus_idma, - .idma_buf = &octopus_idma_buf, - .odma = &octopus_odma, - .odma_buf = &octopus_odma_buf, - .input = &octopus_input, - .output = &octopus_output, -}; - -// -// -// - static void ddb_set_dma_table(struct ddb_io *io) { struct ddb *dev = io->port->dev; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c new file mode 100644 index ..e35b41e8d860 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -0,0 +1,299 @@ +/* + * ddbridge-hw.c: Digital Devices bridge hardware maps + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "ddbridge.h" + +/**/ + +static struct ddb_regset octopus_input = { + .base = 0x200, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_output = { + .base = 0x280, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_idma = { + .base = 0x300, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regse
[PATCH v2 10/14] [media] ddbridge: remove unreachable code
From: Daniel Scheller >From smatch: drivers/media/pci/ddbridge/ddbridge-core.c:3490 snr_store() info: ignoring unreachable code. In fact, the function immediately returns zero, so remove it and update ddb_attrs_snr[] to not reference it anymore. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 27 --- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 06bd37f8b95d..1ffcf23c63ed 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -3236,25 +3236,6 @@ static ssize_t snr_show(struct device *device, return sprintf(buf, "%s\n", snr); } - -static ssize_t snr_store(struct device *device, struct device_attribute *attr, -const char *buf, size_t count) -{ - struct ddb *dev = dev_get_drvdata(device); - int num = attr->attr.name[3] - 0x30; - u8 snr[34] = { 0x01, 0x00 }; - - return 0; /* NOE: remove completely? */ - if (count > 31) - return -EINVAL; - if (dev->port[num].type >= DDB_TUNER_XO2) - return -EINVAL; - memcpy(snr + 2, buf, count); - i2c_write(&dev->i2c[num].adap, 0x57, snr, 34); - i2c_write(&dev->i2c[num].adap, 0x50, snr, 34); - return count; -} - static ssize_t bsnr_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -3394,10 +3375,10 @@ static struct device_attribute ddb_attrs_fan[] = { }; static struct device_attribute ddb_attrs_snr[] = { - __ATTR(snr0, 0664, snr_show, snr_store), - __ATTR(snr1, 0664, snr_show, snr_store), - __ATTR(snr2, 0664, snr_show, snr_store), - __ATTR(snr3, 0664, snr_show, snr_store), + __ATTR_MRO(snr0, snr_show), + __ATTR_MRO(snr1, snr_show), + __ATTR_MRO(snr2, snr_show), + __ATTR_MRO(snr3, snr_show), }; static struct device_attribute ddb_attrs_ctemp[] = { -- 2.13.0
[PATCH v2 08/14] [media] ddbridge: only register frontends in fe2 if fe is not NULL
From: Daniel Scheller Smatch reported: drivers/media/pci/ddbridge/ddbridge-core.c:1602 dvb_input_attach() error: we previously assumed 'dvb->fe' could be null (see line 1595) dvb->fe2 will ever only be populated when dvb->fe is set. So only handle registration of dvb->fe2 when dvb->fe got set beforehand by moving the registration into the "if (dvb->fe)" conditional. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 0002b6a8ec85..9aee112c0d88 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1506,23 +1506,25 @@ static int dvb_input_attach(struct ddb_input *input) return 0; } dvb->attached = 0x30; + if (dvb->fe) { if (dvb_register_frontend(adap, dvb->fe) < 0) return -ENODEV; + + if (dvb->fe2) { + if (dvb_register_frontend(adap, dvb->fe2) < 0) + return -ENODEV; + dvb->fe2->tuner_priv = dvb->fe->tuner_priv; + memcpy(&dvb->fe2->ops.tuner_ops, + &dvb->fe->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } } - if (dvb->fe2) { - if (dvb_register_frontend(adap, dvb->fe2) < 0) - return -ENODEV; - dvb->fe2->tuner_priv = dvb->fe->tuner_priv; - memcpy(&dvb->fe2->ops.tuner_ops, - &dvb->fe->ops.tuner_ops, - sizeof(struct dvb_tuner_ops)); - } + dvb->attached = 0x31; return 0; } - static int port_has_encti(struct ddb_port *port) { struct device *dev = port->dev->dev; -- 2.13.0
[PATCH v2 09/14] [media] ddbridge: fix possible buffer overflow in ddb_ports_init()
From: Daniel Scheller Report from smatch: drivers/media/pci/ddbridge/ddbridge-core.c:2659 ddb_ports_init() error: buffer overflow 'dev->port' 32 <= u32max Fix by making sure "p" is greater than zero before checking for "dev->port[].type == DDB_CI_EXTERNAL_XO2". Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 9aee112c0d88..06bd37f8b95d 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2551,7 +2551,7 @@ void ddb_ports_init(struct ddb *dev) port->dvb[0].adap = &dev->adap[2 * p]; port->dvb[1].adap = &dev->adap[2 * p + 1]; - if ((port->class == DDB_PORT_NONE) && i && + if ((port->class == DDB_PORT_NONE) && i && p && dev->port[p - 1].type == DDB_CI_EXTERNAL_XO2) { port->class = DDB_PORT_CI; port->type = DDB_CI_EXTERNAL_XO2_B; -- 2.13.0
[PATCH v2 12/14] [media] ddbridge: fix dereference before check
From: Daniel Scheller Both ts_release() and ts_open() can use "output" before check (smatch): drivers/media/pci/ddbridge/ddbridge-core.c:816 ts_release() warn: variable dereferenced before check 'output' (see line 809) drivers/media/pci/ddbridge/ddbridge-core.c:836 ts_open() warn: variable dereferenced before check 'output' (see line 828) Fix by performing checks on those pointers. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index ace06fcdd0cf..ed75c1c6734a 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -738,8 +738,13 @@ static unsigned int ts_poll(struct file *file, poll_table *wait) static int ts_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; + struct ddb_output *output = NULL; + struct ddb_input *input = NULL; + + if (dvbdev) { + output = dvbdev->priv; + input = output->port->input[0]; + } if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (!input) @@ -757,8 +762,13 @@ static int ts_open(struct inode *inode, struct file *file) { int err; struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; + struct ddb_output *output = NULL; + struct ddb_input *input = NULL; + + if (dvbdev) { + output = dvbdev->priv; + input = output->port->input[0]; + } if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (!input) -- 2.13.0
[PATCH v2 14/14] [media] MAINTAINERS: add entry for ddbridge
From: Daniel Scheller Signed-off-by: Daniel Scheller --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9826a918d37a..f25f26b5d9f6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8428,6 +8428,14 @@ T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/dvb-frontends/stv6111* +MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/pci/ddbridge/* + MEDIA INPUT INFRASTRUCTURE (V4L/DVB) M: Mauro Carvalho Chehab M: Mauro Carvalho Chehab -- 2.13.0
[PATCH v2 07/14] [media] ddbridge: check pointers before dereferencing
From: Daniel Scheller Fixes two warnings reported by smatch: drivers/media/pci/ddbridge/ddbridge-core.c:240 ddb_redirect() warn: variable dereferenced before check 'idev' (see line 238) drivers/media/pci/ddbridge/ddbridge-core.c:240 ddb_redirect() warn: variable dereferenced before check 'pdev' (see line 238) Fixed by moving the existing checks up before accessing members. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 758073b716a2..0002b6a8ec85 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -170,10 +170,10 @@ static int ddb_redirect(u32 i, u32 p) struct ddb *pdev = ddbs[(p >> 4) & 0x3f]; struct ddb_port *port; - if (!idev->has_dma || !pdev->has_dma) - return -EINVAL; if (!idev || !pdev) return -EINVAL; + if (!idev->has_dma || !pdev->has_dma) + return -EINVAL; port = &pdev->port[p & 0x0f]; if (!port->output) -- 2.13.0
[PATCH v2 11/14] [media] ddbridge: fix impossible condition warning
From: Daniel Scheller Smatch and gcc complained: drivers/media/pci/ddbridge/ddbridge-core.c:3491 bpsnr_show() warn: impossible condition '(snr[0] == 255) => ((-128)-127 == 255)' drivers/media/pci/ddbridge/ddbridge-core.c: In function ‘bpsnr_show’: drivers/media/pci/ddbridge/ddbridge-core.c:3491:13: warning: comparison is always false due to limited range of data type [-Wtype-limits] Fix this by changing the type of snr to unsigned char. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 1ffcf23c63ed..ace06fcdd0cf 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -3251,7 +3251,7 @@ static ssize_t bpsnr_show(struct device *device, struct device_attribute *attr, char *buf) { struct ddb *dev = dev_get_drvdata(device); - char snr[32]; + unsigned char snr[32]; if (!dev->i2c_num) return 0; -- 2.13.0
[PATCH v2 05/14] [media] ddbridge: split off IRQ handling
From: Daniel Scheller This not only helps keep the ddbridge-core tidy, but also gets rid of defined-but-unused-function warnings which might be triggered depending of CONFIG_PCI_MSI, without having to clutter the code with #ifdef'ery. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/Makefile| 3 +- drivers/media/pci/ddbridge/ddbridge-core.c | 117 --- drivers/media/pci/ddbridge/ddbridge-irq.c | 148 + drivers/media/pci/ddbridge/ddbridge.h | 12 +-- 4 files changed, 155 insertions(+), 125 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-irq.c diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index fe8ff0c681ad..0a7caa95a3b6 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -2,7 +2,8 @@ # Makefile for the ddbridge device driver # -ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o \ + ddbridge-irq.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 658f8e0f6163..d2f6713539d4 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2691,123 +2691,6 @@ void ddb_ports_release(struct ddb *dev) // // -#define IRQ_HANDLE(_nr) \ - do { if ((s & (1UL << ((_nr) & 0x1f))) && dev->handler[0][_nr]) \ - dev->handler[0][_nr](dev->handler_data[0][_nr]); } \ - while (0) - -static void irq_handle_msg(struct ddb *dev, u32 s) -{ - dev->i2c_irq++; - IRQ_HANDLE(0); - IRQ_HANDLE(1); - IRQ_HANDLE(2); - IRQ_HANDLE(3); -} - -static void irq_handle_io(struct ddb *dev, u32 s) -{ - dev->ts_irq++; - if ((s & 0x00f0)) { - IRQ_HANDLE(4); - IRQ_HANDLE(5); - IRQ_HANDLE(6); - IRQ_HANDLE(7); - } - if ((s & 0xff00)) { - IRQ_HANDLE(8); - IRQ_HANDLE(9); - IRQ_HANDLE(10); - IRQ_HANDLE(11); - IRQ_HANDLE(12); - IRQ_HANDLE(13); - IRQ_HANDLE(14); - IRQ_HANDLE(15); - } - if ((s & 0x00ff)) { - IRQ_HANDLE(16); - IRQ_HANDLE(17); - IRQ_HANDLE(18); - IRQ_HANDLE(19); - IRQ_HANDLE(20); - IRQ_HANDLE(21); - IRQ_HANDLE(22); - IRQ_HANDLE(23); - } - if ((s & 0xff00)) { - IRQ_HANDLE(24); - IRQ_HANDLE(25); - IRQ_HANDLE(26); - IRQ_HANDLE(27); - IRQ_HANDLE(28); - IRQ_HANDLE(29); - IRQ_HANDLE(30); - IRQ_HANDLE(31); - } -} - -#ifdef DDB_USE_MSI_IRQHANDLERS -irqreturn_t irq_handler0(int irq, void *dev_id) -{ - struct ddb *dev = (struct ddb *) dev_id; - u32 s = ddbreadl(dev, INTERRUPT_STATUS); - - do { - if (s & 0x8000) - return IRQ_NONE; - if (!(s & 0xf00)) - return IRQ_NONE; - ddbwritel(dev, s & 0xf00, INTERRUPT_ACK); - irq_handle_io(dev, s); - } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); - - return IRQ_HANDLED; -} - -irqreturn_t irq_handler1(int irq, void *dev_id) -{ - struct ddb *dev = (struct ddb *) dev_id; - u32 s = ddbreadl(dev, INTERRUPT_STATUS); - - do { - if (s & 0x8000) - return IRQ_NONE; - if (!(s & 0xf)) - return IRQ_NONE; - ddbwritel(dev, s & 0xf, INTERRUPT_ACK); - irq_handle_msg(dev, s); - } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); - - return IRQ_HANDLED; -} -#endif - -irqreturn_t irq_handler(int irq, void *dev_id) -{ - struct ddb *dev = (struct ddb *) dev_id; - u32 s = ddbreadl(dev, INTERRUPT_STATUS); - int ret = IRQ_HANDLED; - - if (!s) - return IRQ_NONE; - do { - if (s & 0x8000) - return IRQ_NONE; - ddbwritel(dev, s, INTERRUPT_ACK); - - if (s & 0x000f) - irq_handle_msg(dev, s); - if (s & 0x0f00) - irq_handle_io(dev, s); - } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); - - return ret; -} - -// -/**
[PATCH v2 02/14] [media] ddbridge: split code into multiple files
From: Daniel Scheller As of 0.9.9b, the ddbridge code has been split from one single file (ddbridge-core.c) into multiple files, with the purpose of taking care of different topics, and to be able to reuse code in different kernel modules (ddbridge.ko and octonet.ko). This applies the same code split, with a notable difference: In the vendor package, the split was done by moving all code parts into separate files, and in the "main" code files (ddbridge.c and octonet.c), a simple "#include ddbridge-core.c" was done. In this patch, the same split (codewise) is done, but all resulting .c/.o files will be handled by the makefile, with proper prototyping of all shared functions done in ddbridge.h. To avoid conflicts wrt the global space, the I2C functions and neccessary prototypes for ddbridge-i2c.c are moved into ddbridge-i2c.h, which is to be included wherever required. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/Makefile| 2 +- drivers/media/pci/ddbridge/ddbridge-core.c | 589 + drivers/media/pci/ddbridge/ddbridge-i2c.c | 173 + drivers/media/pci/ddbridge/ddbridge-i2c.h | 99 + drivers/media/pci/ddbridge/ddbridge-main.c | 389 +++ drivers/media/pci/ddbridge/ddbridge.h | 35 ++ 6 files changed, 710 insertions(+), 577 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.c create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.h create mode 100644 drivers/media/pci/ddbridge/ddbridge-main.c diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index 7446c8b677b5..fe8ff0c681ad 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -2,7 +2,7 @@ # Makefile for the ddbridge device driver # -ddbridge-objs := ddbridge-core.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index d6dcc42ff222..7e164a370273 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -32,8 +32,9 @@ #include #include #include -#include "ddbridge.h" +#include "ddbridge.h" +#include "ddbridge-i2c.h" #include "ddbridge-regs.h" #include "tda18271c2dd.h" @@ -49,227 +50,8 @@ #include "stv6111.h" #include "lnbh25.h" -static int xo2_speed = 2; -module_param(xo2_speed, int, 0444); -MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); - -static int stv0910_single; -module_param(stv0910_single, int, 0444); -MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -/* MSI had problems with lost interrupts, fixed but needs testing */ -#undef CONFIG_PCI_MSI - -/**/ - -static int i2c_io(struct i2c_adapter *adapter, u8 adr, - u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) -{ - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = wbuf, .len = wlen }, - {.addr = adr, .flags = I2C_M_RD, - .buf = rbuf, .len = rlen } }; - return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -} - -static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) -{ - struct i2c_msg msg = {.addr = adr, .flags = 0, - .buf = data, .len = len}; - - return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; -} - -static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) -{ - struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = 1 } }; - return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; -} - -static int i2c_read_regs(struct i2c_adapter *adapter, -u8 adr, u8 reg, u8 *val, u8 len) -{ - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = ®, .len = 1 }, - {.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = len } }; - return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -} - -static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) -{ - return i2c_read_regs(adapter, adr, reg, val, 1); -} - -static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, - u16 reg, u8 *val) -{ - u8 msg[2] = {reg>>8, reg&0xff}; - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = msg, .len = 2}, -
[PATCH v2 04/14] [media] ddbridge: split I/O related functions off from ddbridge.h
From: Daniel Scheller While it seems valid that headers can carry simple oneline static inline annotated functions, move them into their own header file to have the overall code more readable. Also, keep them as header (and don't put in a separate object) and static inline to help the compiler avoid generating function calls. (Thanks to Jasmin J. for valuable input on this!) Cc: Jasmin J. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 1 + drivers/media/pci/ddbridge/ddbridge-i2c.c | 1 + drivers/media/pci/ddbridge/ddbridge-io.h | 71 ++ drivers/media/pci/ddbridge/ddbridge-main.c | 1 + drivers/media/pci/ddbridge/ddbridge.h | 43 -- 5 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-io.h diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 5045ad6c36fe..658f8e0f6163 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -37,6 +37,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" #include "tda18271c2dd.h" #include "stv6110x.h" diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c index 376d8a7ca0b9..3d4fafb5db27 100644 --- a/drivers/media/pci/ddbridge/ddbridge-i2c.c +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -33,6 +33,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" /**/ diff --git a/drivers/media/pci/ddbridge/ddbridge-io.h b/drivers/media/pci/ddbridge/ddbridge-io.h new file mode 100644 index ..ce92e9484075 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-io.h @@ -0,0 +1,71 @@ +/* + * ddbridge-io.h: Digital Devices bridge I/O inline functions + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __DDBRIDGE_IO_H__ +#define __DDBRIDGE_IO_H__ + +#include + +#include "ddbridge.h" + +/**/ + +static inline u32 ddblreadl(struct ddb_link *link, u32 adr) +{ + return readl((char *) (link->dev->regs + (adr))); +} + +static inline void ddblwritel(struct ddb_link *link, u32 val, u32 adr) +{ + writel(val, (char *) (link->dev->regs + (adr))); +} + +static inline u32 ddbreadl(struct ddb *dev, u32 adr) +{ + return readl((char *) (dev->regs + (adr))); +} + +static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) +{ + writel(val, (char *) (dev->regs + (adr))); +} + +static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) +{ + return memcpy_toio((char *) (dev->regs + adr), src, count); +} + +static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) +{ + return memcpy_fromio(dst, (char *) (dev->regs + adr), count); +} + +static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) +{ + u32 val = ddbreadl(dev, adr); + + /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ + if (val == ~0) { + dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); + return 0; + } + + return val; +} + +#endif /* __DDBRIDGE_IO_H__ */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index dde938ad1247..5332fd89f359 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -35,6 +35,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" // /* module parameters */ diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index ab6364ae0711..3790fd8465a4 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -353,49 +353,6 @@ struct ddb { u8 tsbuf[TS_CAPTURE_LEN]; }; -static inline u32 ddblreadl(struct ddb_link *link, u32 adr) -{ - return readl((char *) (link->dev->regs + (adr))); -}
[PATCH v2 00/14] ddbridge: bump to ddbridge-0.9.29
From: Daniel Scheller Still prefered for and made for Linux 4.14. Changes from v1 to v2: * I2C access functions (ie. i2c_read() et al) refactored from ddbridge-i2c.c into ddbridge-i2c.h and declared static, and needed include added to all .c files making use of them. This fixes symbol conflicts in the global namespace with other drivers (kbuild test robot reported a conflict with an infiniband driver) when compiling into the kernel blob. While at it, code style has been made proper (in ddbridge-i2c.h) and the 0.9.29 code bump patch was updated to re-use the "plural" functions from their "singular" equivalents. * The IRQ_HANDLE_BYTE() macro was removed. It is used nowhere, even in the unmodified/unstripped upstream driver. * Shortened the buffer overflow fix in ddb_ports_init() from checking "p > 0" to only check "p". Changes from original series to the resend: * rebased on latest mediatree-master wrt commit 618e8aac3d7c ("media: ddbridge: constify i2c_algorithm structure") * build error in ddbridge-core.c fixed wrt commit dcda9b04713c ("mm, tree wide: replace __GFP_REPEAT by __GFP_RETRY_MAYFAIL with more useful semantic") * useless return removed from void calc_con() * UTF8 in ddbridge-regs.h removed * Tested-by's added to commit messages Since the STV0910 patches are merged, the dependency is resolved. Previous Tested-by testimonials still apply. Mauro/Media maintainers, this updates drivers/media/pci/ddbridge to the very latest code that DD carry in their vendor driver package as of version 0.9.29, in the "once, the big-bang-way is ok" way as discussed at [2] (compared to the incremental, awkward to do variant since that involves dissecting all available release archives and having to - try to - build proper commits out of this, which will always be inaccurate; a start was done at [3], however - and please understand - I definitely don't want to continue doing that...) In patch 14, I add myself to MAINTAINERS. This means I will care about getting driver updates as they're released by DD into mainline, starting from this (0.9.29) version, which is definitely doable in an incremental way. So, I'll make sure the in-kernel driver won't bit-rot again, and it will receive new hardware support as it becomes available in a timely manner. While the driver code bump looks massive, judging from the diff, there's mostly a whole lot of refactoring and restructuring of variables, port/ link management and all such stuff in it. Feature-wise, this is most notable: - Support for all (PCIe) CI (single/duo) cards and Flex addons - Support for MSI (Message Signaled Interrupts), though disabled by default since there were still reports of problems with this - TS Loopback support (set up ports to behave as if a CI is connected, without decryption of course) - As mentioned: Heavy code reordering, and split up into multiple files Stripped functionality compared to dddvb: - DVB-C modulator card support removed (requires DVB core API) - OctoNET SAT>IP server/box support removed (requires API aswell) - with this, GT link support was removed (only on OctoNET hardware) - MaxS8 4/8 DVB-S/S2 card support (temporarily) removed (requires an additional Demod driver; subject for another, later, series) A note on the patches: The bump starts by aligning the code "order-wise" to the updated driver, to keep the diff a bit cleaner. Next, the code split is applied, without actually changing any functionality. Compared to upstream, this isn't done by moving functions into different C files and then do an include on them, but we're handling them with the Makefile, building separate objects, and having proper prototypes in ddbridge.h. After the code bump, further split up is applied to increase readability and maintainability (also, for the MaxS8 support, there will be another object with another ~400 LoC, which originally lives in ddbridge-core aswell). Then, all issues found by W=1 and smatch are resolved, one by one. This is kept separate since those fixes will be proposed for upstream inclusion. The last thing is the addition of the MSI default Kconfig options which will mainly inform users that there's something that might(!) cause issues but is still being worked on - the default is "off" to provide a proper OotB experience. To distinguish from the original unchanged vendor driver, "-integrated" is suffixed to the version code. Note on checkpatch: First two patches are solely code-moving, so checkpatch will complain on them. With the ddbridge code bump, all non-strict style issues are resolved. "--strict" checking will receive another round of patches afterwards. Yes, you will hate me for this large code drop, but at least we sort-of discussed this beforehand, and we have to start *somewhere*. Thanks in advance for reviewing and (optimally) getting this merged and getting the DD driver dilemma solved hopefully once and for all. [1] http://www.spinics.net/lists/linux-media/msg1
[PATCH v2 01/14] [media] ddbridge: move/reorder functions
From: Daniel Scheller The functions in ddbridge-core.c have been moved to different positions in newer versions of the dddvb vendor driver package (most notably in version 0.9.9b). Perform the same code move to keep the diff of the upcoming code bump simpler. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick --- drivers/media/pci/ddbridge/ddbridge-core.c | 660 ++--- 1 file changed, 327 insertions(+), 333 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index ec41804d78c7..d6dcc42ff222 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -404,43 +404,6 @@ static void ddb_buffers_free(struct ddb *dev) } } -static void ddb_input_start(struct ddb_input *input) -{ - struct ddb *dev = input->port->dev; - - spin_lock_irq(&input->lock); - input->cbuf = 0; - input->coff = 0; - - /* reset */ - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(2, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - - ddbwritel((1 << 16) | - (input->dma_buf_num << 11) | - (input->dma_buf_size >> 7), - DMA_BUFFER_SIZE(input->nr)); - ddbwritel(0, DMA_BUFFER_ACK(input->nr)); - - ddbwritel(1, DMA_BASE_WRITE); - ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); - ddbwritel(9, TS_INPUT_CONTROL(input->nr)); - input->running = 1; - spin_unlock_irq(&input->lock); -} - -static void ddb_input_stop(struct ddb_input *input) -{ - struct ddb *dev = input->port->dev; - - spin_lock_irq(&input->lock); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); - input->running = 0; - spin_unlock_irq(&input->lock); -} - static void ddb_output_start(struct ddb_output *output) { struct ddb *dev = output->port->dev; @@ -477,6 +440,43 @@ static void ddb_output_stop(struct ddb_output *output) spin_unlock_irq(&output->lock); } +static void ddb_input_stop(struct ddb_input *input) +{ + struct ddb *dev = input->port->dev; + + spin_lock_irq(&input->lock); + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); + input->running = 0; + spin_unlock_irq(&input->lock); +} + +static void ddb_input_start(struct ddb_input *input) +{ + struct ddb *dev = input->port->dev; + + spin_lock_irq(&input->lock); + input->cbuf = 0; + input->coff = 0; + + /* reset */ + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + ddbwritel(2, TS_INPUT_CONTROL(input->nr)); + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + + ddbwritel((1 << 16) | + (input->dma_buf_num << 11) | + (input->dma_buf_size >> 7), + DMA_BUFFER_SIZE(input->nr)); + ddbwritel(0, DMA_BUFFER_ACK(input->nr)); + + ddbwritel(1, DMA_BASE_WRITE); + ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); + ddbwritel(9, TS_INPUT_CONTROL(input->nr)); + input->running = 1; + spin_unlock_irq(&input->lock); +} + static u32 ddb_output_free(struct ddb_output *output) { u32 idx, off, stat = output->stat; @@ -595,7 +595,98 @@ static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t co return count; } -/**/ +// +// + +static ssize_t ts_write(struct file *file, const __user char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + size_t left = count; + int stat; + + while (left) { + if (ddb_output_free(output) < 188) { + if (file->f_flags & O_NONBLOCK) + break; + if (wait_event_interruptible( + output->wq, ddb_output_free(output) >= 188) < 0) + break; + } + stat = ddb_output_write(output, buf, left); + if (stat < 0) + break; + buf += stat; + left -= stat; + } + return (left == count) ? -EAGAIN : (count - left); +} + +static ssize_t ts_read(struct file *file, __user char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + struct ddb_input *input = output->port->input[0]; + int left, rea
Re: ir-keytable question [Ubuntu 17.04]
Hi, On Sun, Jul 16, 2017 at 10:26:14PM -0700, Szabolcs Andrasi wrote: > Hi, > > I'm using Ubuntu 17.04 and I installed the ir-keytable tool. The > output of the ir-keytable command is as follows: > > > > Found /sys/class/rc/rc0/ (/dev/input/event5) with: > Driver ite-cir, table rc-rc6-mce > Supported protocols: unknown other lirc rc-5 rc-5-sz jvc sony nec > sanyo mce_kbd rc-6 sharp xmp > Enabled protocols: lirc rc-6 > Name: ITE8708 CIR transceiver > bus: 25, vendor/product: 1283:, version: 0x > Repeat delay = 500 ms, repeat period = 125 ms > > > > I'm trying to enable the supported mce_kbd protocol in addition to the > lirc and rc-6 protocols with the > > $ sudo ir-keytable -p lirc -p rc-6 -p mce_kbd > > command which works as expected. If, however, I reboot my computer, > ir-keytable forgets this change and only the lirc and rc-6 protocols > are enabled. Is there a configuration file I can edit so that after > the boot my IR remote still works? Or is that so that the only way to > make it work is to write a start-up script that runs the above command > to enable the needed protocol? So what we have today is /etc/rc_maps.cfg, where you can select the default keymap for a particular driver; unfortunately, you can only select one keymap and one keymap can only have one protocol. Ideally we could either have more than one protocol per keymap, which would be helpful for the MCE Keyboard, or we could allow multiple keymaps which would be great for supporting different remotes at the same time. For now, you could add a udev rule to also enable the mce_kbd protocol. Sean
Re: [PATCH 2/2] rc: add zx-irdec remote control driver
Hi Shawn, The driver looks great! Just a minor point, see below. On Sat, Jul 29, 2017 at 02:31:42PM +0800, Shawn Guo wrote: > From: Shawn Guo > > It adds the remote control driver and corresponding keymap file for > IRDEC block found on ZTE ZX family SoCs. > > Signed-off-by: Shawn Guo > --- > drivers/media/rc/Kconfig | 11 ++ > drivers/media/rc/Makefile | 1 + > drivers/media/rc/keymaps/Makefile | 3 +- > drivers/media/rc/keymaps/rc-zx-irdec.c | 79 + > drivers/media/rc/zx-irdec.c| 198 > + > include/media/rc-map.h | 1 + > 6 files changed, 292 insertions(+), 1 deletion(-) > create mode 100644 drivers/media/rc/keymaps/rc-zx-irdec.c > create mode 100644 drivers/media/rc/zx-irdec.c > > diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig > index 5e83b76495f7..c572d5da4b5f 100644 > --- a/drivers/media/rc/Kconfig > +++ b/drivers/media/rc/Kconfig > @@ -435,4 +435,15 @@ config IR_SIR > To compile this driver as a module, choose M here: the module will > be called sir-ir. > > +config IR_ZX > + tristate "ZTE ZX IR remote control" > + depends on RC_CORE > + depends on ARCH_ZX || COMPILE_TEST > + ---help--- > +Say Y if you want to use the IR remote control available > +on ZTE ZX family SoCs. > + > +To compile this driver as a module, choose M here: the > +module will be called zx-irdec. > + > endif #RC_DEVICES > diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile > index 245e2c2d0b22..922c1a5620e9 100644 > --- a/drivers/media/rc/Makefile > +++ b/drivers/media/rc/Makefile > @@ -41,3 +41,4 @@ obj-$(CONFIG_IR_IMG) += img-ir/ > obj-$(CONFIG_IR_SERIAL) += serial_ir.o > obj-$(CONFIG_IR_SIR) += sir_ir.o > obj-$(CONFIG_IR_MTK) += mtk-cir.o > +obj-$(CONFIG_IR_ZX) += zx-irdec.o > diff --git a/drivers/media/rc/keymaps/Makefile > b/drivers/media/rc/keymaps/Makefile > index 2945f99907b5..af6496d709fb 100644 > --- a/drivers/media/rc/keymaps/Makefile > +++ b/drivers/media/rc/keymaps/Makefile > @@ -109,4 +109,5 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ > rc-videomate-tv-pvr.o \ > rc-winfast.o \ > rc-winfast-usbii-deluxe.o \ > - rc-su3000.o > + rc-su3000.o \ > + rc-zx-irdec.o > diff --git a/drivers/media/rc/keymaps/rc-zx-irdec.c > b/drivers/media/rc/keymaps/rc-zx-irdec.c > new file mode 100644 > index ..cc889df47eb8 > --- /dev/null > +++ b/drivers/media/rc/keymaps/rc-zx-irdec.c > @@ -0,0 +1,79 @@ > +/* > + * Copyright (C) 2017 Sanechips Technology Co., Ltd. > + * Copyright 2017 Linaro Ltd. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include > +#include > + > +static struct rc_map_table zx_irdec_table[] = { > + { 0x01, KEY_1 }, > + { 0x02, KEY_2 }, > + { 0x03, KEY_3 }, > + { 0x04, KEY_4 }, > + { 0x05, KEY_5 }, > + { 0x06, KEY_6 }, > + { 0x07, KEY_7 }, > + { 0x08, KEY_8 }, > + { 0x09, KEY_9 }, > + { 0x31, KEY_0 }, > + { 0x16, KEY_DELETE }, > + { 0x0a, KEY_MODE }, /* Input method */ > + { 0x0c, KEY_VOLUMEUP }, > + { 0x18, KEY_VOLUMEDOWN }, > + { 0x0b, KEY_CHANNELUP }, > + { 0x15, KEY_CHANNELDOWN }, > + { 0x0d, KEY_PAGEUP }, > + { 0x13, KEY_PAGEDOWN }, > + { 0x46, KEY_FASTFORWARD }, > + { 0x43, KEY_REWIND }, > + { 0x44, KEY_PLAYPAUSE }, > + { 0x45, KEY_STOP }, > + { 0x49, KEY_OK }, > + { 0x47, KEY_UP }, > + { 0x4b, KEY_DOWN }, > + { 0x48, KEY_LEFT }, > + { 0x4a, KEY_RIGHT }, > + { 0x4d, KEY_MENU }, > + { 0x56, KEY_APPSELECT },/* Application */ > + { 0x4c, KEY_BACK }, > + { 0x1e, KEY_INFO }, > + { 0x4e, KEY_F1 }, > + { 0x4f, KEY_F2 }, > + { 0x50, KEY_F3 }, > + { 0x51, KEY_F4 }, > + { 0x1c, KEY_AUDIO }, > + { 0x12, KEY_MUTE }, > + { 0x11, KEY_DOT }, /* Location */ > + { 0x1d, KEY_SETUP }, > + { 0x40, KEY_POWER }, > +}; > + > +static struct rc_map_list zx_irdec_map = { > + .map = { > + .scan = zx_irdec_table, > + .size = ARRAY_SIZE(zx_irdec_table), > + .rc_type = RC_TYPE_NEC, > + .name = RC_MAP_ZX_IRDEC, > + } > +}; > + > +static int __init init_rc_map_zx_irdec(void) > +{ > + return rc_map_register(&zx_irdec_map); > +} > + > +static void __exit exit_rc_map_zx_irdec(void) > +{ > + rc_map_unregister(&zx_irdec_map); > +} > + > +module_init(init_rc_map_zx_irdec) > +module_exit(exit_rc_map_zx_irdec) > + > +MODULE_AUTHOR("Shawn Guo "); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/media/rc/zx-irdec.c b/drivers/media/rc/zx-irdec.c > new file mode 10064
[PATCH v2] media: ov13858: Correct link-frequency and pixel-rate
Previously both link-frequency and pixel-rate reported by the sensor was incorrect, resulting in incorrect FPS. Report link-frequency in Hz rather than link data rate in bps. Calculate pixel-rate from link-frequency. Signed-off-by: Chiranjeevi Rapolu --- Changes in v2: - Fix typo, from PLL to PPL. - Suffixed ULL instead of typecasting to uint64_t drivers/media/i2c/ov13858.c | 28 +++- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 86550d8..9b87820 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -60,8 +60,8 @@ #define OV13858_VBLANK_MIN 56 /* HBLANK control - read only */ -#define OV13858_PPL_540MHZ 2244 -#define OV13858_PPL_1080MHZ4488 +#define OV13858_PPL_270MHZ 2244 +#define OV13858_PPL_540MHZ 4488 /* Exposure control */ #define OV13858_REG_EXPOSURE 0x3500 @@ -944,31 +944,33 @@ struct ov13858_mode { /* Configurations for supported link frequencies */ #define OV13858_NUM_OF_LINK_FREQS 2 -#define OV13858_LINK_FREQ_1080MBPS 108000 -#define OV13858_LINK_FREQ_540MBPS 54000 +#define OV13858_LINK_FREQ_540MHZ 54000ULL +#define OV13858_LINK_FREQ_270MHZ 27000ULL #define OV13858_LINK_FREQ_INDEX_0 0 #define OV13858_LINK_FREQ_INDEX_1 1 /* Menu items for LINK_FREQ V4L2 control */ static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = { - OV13858_LINK_FREQ_1080MBPS, - OV13858_LINK_FREQ_540MBPS + OV13858_LINK_FREQ_540MHZ, + OV13858_LINK_FREQ_270MHZ }; /* Link frequency configs */ static const struct ov13858_link_freq_config link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = { { - .pixel_rate = 86400, - .pixels_per_line = OV13858_PPL_1080MHZ, + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + .pixel_rate = (OV13858_LINK_FREQ_540MHZ * 2 * 4) / 10, + .pixels_per_line = OV13858_PPL_540MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps), .regs = mipi_data_rate_1080mbps, } }, { - .pixel_rate = 43200, - .pixels_per_line = OV13858_PPL_540MHZ, + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + .pixel_rate = (OV13858_LINK_FREQ_270MHZ * 2 * 4) / 10, + .pixels_per_line = OV13858_PPL_270MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps), .regs = mipi_data_rate_540mbps, @@ -1634,10 +1636,10 @@ static int ov13858_init_controls(struct ov13858 *ov13858) ov13858->hblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width, + OV13858_PPL_540MHZ - ov13858->cur_mode->width, + OV13858_PPL_540MHZ - ov13858->cur_mode->width, 1, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width); + OV13858_PPL_540MHZ - ov13858->cur_mode->width); ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; ov13858->exposure = v4l2_ctrl_new_std( -- 1.9.1