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: Tue Mar 6 05:00:13 CET 2018 media-tree git hash:76bf7087fb2118aee16370821975f8a58febf68a media_build git hash: 15e592e1abe9d29c9fd3b32302ac50716ef793d5 v4l-utils git hash: 5090c6cb0265c6847ff4b0e89b37c172eb0c1c62 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: WARNINGS linux-4.1.49-x86_64: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.2.8-x86_64: WARNINGS 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: WARNINGS linux-4.15.2-x86_64: WARNINGS linux-4.16-rc1-i686: WARNINGS linux-4.16-rc1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: WARNINGS smatch: OK Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Tuesday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Tuesday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
Donation For Charity Work
-- Good Day, My wife and I have awarded you with a donation of $ 1,000,000.00 Dollars from part of our Jackpot Lottery of 50 Million Dollars, respond with your details for claims. We await your earliest response and God Bless you. Friedrich And Ann Mayrhofer.
Re: [PATCH] media: ov2685: Not delay latch for gain
On Thu, Mar 1, 2018 at 7:14 PM, Shunqian Zhengwrote: > Hi Tomasz, > > > On 2018年03月01日 16:53, Tomasz Figa wrote: >> >> Hi Shunqian, >> >> On Thu, Mar 1, 2018 at 5:44 PM, Shunqian Zheng >> wrote: >>> >>> 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. Alright. I wasn't able to confirm the exact meaning of this bit myself unfortunately, but if that's the behavior you're seeing, we should be fine. Reviewed-by: Tomasz Figa Best regards, Tomasz
[PATCH v9 2/2] media: V3s: Add support for Allwinner CSI.
Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2 interface and CSI1 is used for parallel interface. This is not documented in datasheet but by test 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. Reviewed-by: Maxime RipardTested-by: Maxime Ripard Signed-off-by: Yong Deng --- MAINTAINERS| 8 + drivers/media/platform/Kconfig | 1 + drivers/media/platform/Makefile| 2 + drivers/media/platform/sunxi/sun6i-csi/Kconfig | 9 + drivers/media/platform/sunxi/sun6i-csi/Makefile| 3 + drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 936 + drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 145 .../media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h | 196 + .../media/platform/sunxi/sun6i-csi/sun6i_video.c | 759 + .../media/platform/sunxi/sun6i-csi/sun6i_video.h | 53 ++ 10 files changed, 2112 insertions(+) create mode 100644 drivers/media/platform/sunxi/sun6i-csi/Kconfig create mode 100644 drivers/media/platform/sunxi/sun6i-csi/Makefile create mode 100644 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c create mode 100644 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h create mode 100644 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_reg.h create mode 100644 drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c create mode 100644 drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h diff --git a/MAINTAINERS b/MAINTAINERS index 91ed6adfa4a6..b4a331ad35b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3793,6 +3793,14 @@ M: Jaya Kumar S: Maintained F: sound/pci/cs5535audio/ +CSI DRIVERS FOR ALLWINNER V3s +M: Yong Deng +L: linux-media@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/platform/sunxi/sun6i-csi/ +F: Documentation/devicetree/bindings/media/sun6i-csi.txt + CW1200 WLAN driver M: Solomon Peachy S: Maintained diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index f9cc0582c8a9..7f1ee46c3258 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -159,6 +159,7 @@ source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" source "drivers/media/platform/rcar-vin/Kconfig" source "drivers/media/platform/atmel/Kconfig" +source "drivers/media/platform/sunxi/sun6i-csi/Kconfig" config VIDEO_TI_CAL tristate "TI CAL (Camera Adaptation Layer) driver" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 85e112122f32..143d8a473b0a 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -96,3 +96,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)+= qcom/camss-8x16/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ obj-y += meson/ + +obj-$(CONFIG_VIDEO_SUN6I_CSI) += sunxi/sun6i-csi/ diff --git a/drivers/media/platform/sunxi/sun6i-csi/Kconfig b/drivers/media/platform/sunxi/sun6i-csi/Kconfig new file mode 100644 index ..314188aae2c2 --- /dev/null +++ b/drivers/media/platform/sunxi/sun6i-csi/Kconfig @@ -0,0 +1,9 @@ +config VIDEO_SUN6I_CSI + tristate "Allwinner V3s Camera Sensor Interface driver" + depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA + depends on ARCH_SUNXI || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select REGMAP_MMIO + select V4L2_FWNODE + ---help--- + Support for the Allwinner Camera Sensor Interface Controller on V3s. diff --git a/drivers/media/platform/sunxi/sun6i-csi/Makefile b/drivers/media/platform/sunxi/sun6i-csi/Makefile new file mode 100644 index ..213cb6be9e9c --- /dev/null +++ b/drivers/media/platform/sunxi/sun6i-csi/Makefile @@ -0,0 +1,3 @@ +sun6i-csi-y += sun6i_video.o sun6i_csi.o + +obj-$(CONFIG_VIDEO_SUN6I_CSI) += sun6i-csi.o diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c new file mode 100644 index ..26d57e6053df --- /dev/null +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -0,0 +1,936 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2018 Magewell Electronics Co., Ltd. (Nanjing) + * All rights reserved. + * Author: Yong Deng + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sun6i_csi.h" +#include "sun6i_csi_reg.h" + +#define MODULE_NAME
[PATCH v9 1/2] dt-bindings: media: Add Allwinner V3s Camera Sensor Interface (CSI)
Add binding documentation for Allwinner V3s CSI. Acked-by: Maxime RipardAcked-by: Sakari Ailus Reviewed-by: Rob Herring Signed-off-by: Yong Deng --- .../devicetree/bindings/media/sun6i-csi.txt| 59 ++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/sun6i-csi.txt diff --git a/Documentation/devicetree/bindings/media/sun6i-csi.txt b/Documentation/devicetree/bindings/media/sun6i-csi.txt new file mode 100644 index ..2ff47a9507a6 --- /dev/null +++ b/Documentation/devicetree/bindings/media/sun6i-csi.txt @@ -0,0 +1,59 @@ +Allwinner V3s Camera Sensor Interface +- + +Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2 +interface and CSI1 is used for parallel interface. + +Required properties: + - compatible: value must be "allwinner,sun8i-v3s-csi" + - reg: base address and size of the memory-mapped region. + - interrupts: interrupt associated to this IP + - clocks: phandles to the clocks feeding the CSI +* bus: the CSI interface clock +* mod: the CSI module clock +* ram: the CSI DRAM clock + - clock-names: the clock names mentioned above + - resets: phandles to the reset line driving the CSI + +Each CSI node should contain one 'port' child node with one child 'endpoint' +node, according to the bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. As mentioned +above, the endpoint's bus type should be MIPI CSI-2 for CSI0 and parallel or +Bt656 for CSI1. + +Endpoint node properties for CSI1 +- + +- remote-endpoint : (required) a phandle to the bus receiver's endpoint + node +- bus-width: : (required) must be 8, 10, 12 or 16 +- pclk-sample : (optional) (default: sample on falling edge) +- hsync-active : (only required for parallel) +- vsync-active : (only required for parallel) + +Example: + +csi1: csi@1cb4000 { + compatible = "allwinner,sun8i-v3s-csi"; + reg = <0x01cb4000 0x1000>; + interrupts = ; + clocks = < CLK_BUS_CSI>, +< CLK_CSI1_SCLK>, +< CLK_DRAM_CSI>; + clock-names = "bus", "mod", "ram"; + resets = < RST_BUS_CSI>; + + port { + /* Parallel bus endpoint */ + csi1_ep: endpoint { + remote-endpoint = <_ep>; + bus-width = <16>; + + /* If hsync-active/vsync-active are missing, + embedded BT.656 sync is used */ + hsync-active = <0>; /* Active low */ + vsync-active = <0>; /* Active low */ + pclk-sample = <1>; /* Rising */ + }; + }; +}; -- 1.8.3.1
[PATCH V3 0/2] Rockchip: Add RK1608 driver and DT-bindings
From: Leo WenYou can use the v4l2-ctl command to capture frames for RK1608. Add DT-bindings documentation for Rockchip RK1608. Add the information of the MAINTAINERS. Leo Wen (2): [media] Add Rockchip RK1608 driver dt-bindings: Document the Rockchip RK1608 bindings Documentation/devicetree/bindings/media/rk1608.txt | 87 ++ MAINTAINERS|7 + drivers/media/spi/Makefile |1 + drivers/media/spi/rk1608.c | 1409 drivers/media/spi/rk1608.h | 442 ++ 5 files changed, 1946 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/rk1608.txt create mode 100644 drivers/media/spi/rk1608.c create mode 100644 drivers/media/spi/rk1608.h -- 2.7.4
[PATCH V3 2/2] dt-bindings: Document the Rockchip RK1608 bindings
From: Leo WenAdd DT bindings documentation for Rockchip RK1608. Changes V3: - Instead use the *-gpios. - Delete the rockchip,powerdown0 and rockchip,powerdown1 GPIO. - Delete the rockchip,reset0 and rockchip,reset1 GPIO. Signed-off-by: Leo Wen --- Documentation/devicetree/bindings/media/rk1608.txt | 87 ++ MAINTAINERS| 1 + 2 files changed, 88 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/rk1608.txt diff --git a/Documentation/devicetree/bindings/media/rk1608.txt b/Documentation/devicetree/bindings/media/rk1608.txt new file mode 100644 index 000..72b01da --- /dev/null +++ b/Documentation/devicetree/bindings/media/rk1608.txt @@ -0,0 +1,87 @@ +Rockchip RK1608 as a PreISP to link on Soc +-- + +Required properties: + +- compatible : "rockchip,rk1608"; +- reg : SPI slave address of the rk1608; +- clocks : Must contain an entry for each entry in clock-names; +- clock-names : Must contain "mclk" for the device's master clock; +- reset-gpios : GPIO connected to reset pin; +- irq-gpios: GPIO connected to irq pin; +- sleepst-gpios: GPIO connected to sleepst pin; +- wakeup-gpios : GPIO connected to wakeup pin; +- powerdown-gpios : GPIO connected to powerdown pin; +- pinctrl-names: Should contain only one value - "default"; +- pinctrl-0: Pin control group to be used for this controller; + +Optional properties: + +- spi-max-frequency: Maximum SPI clocking speed of the device; + +The device node should contain one 'port' child node with one child 'endpoint' +node, according to the bindings defined in Documentation/devicetree/bindings/ +media/video-interfaces.txt. The following are properties specific to those +nodes. + +endpoint node +- + +- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in + video-interfaces.txt. If present it should be <1> - the device + supports only one data lane without re-mapping. + +Note1: Since no data is generated in RK1608,so this is meaningful that you need +a extra sensor (such as a camera) mounted on RK1608. You need to use endpoint@x +to match these sensors. + +Note2:You must set the current value of the spi pins to be 8mA, if they are not. + +Example: + { + status = "okay"; + spi_rk1608@00 { + compatible = "rockchip,rk1608"; + status = "okay"; + reg = <0>; + spi-max-frequency = <2400>; + link-freqs = /bits/ 64 ; + clocks = < SCLK_SPI0>, < SCLK_VIP_OUT>, + < DCLK_VOP0>, < ACLK_VIP>, < HCLK_VIP>, + < PCLK_ISP_IN>, < PCLK_ISP_IN>, + < PCLK_ISP_IN>, < SCLK_MIPIDSI_24M>, + < PCLK_MIPI_CSI>; + clock-names = "mclk", "mipi_clk", "pd_cif", "aclk_cif", + "hclk_cif", "cif0_in", "g_pclkin_cif", + "cif0_out", "clk_mipi_24m", "hclk_mipiphy"; + reset-gpios = < 0 GPIO_ACTIVE_HIGH>; + irq-gpios = < 2 GPIO_ACTIVE_HIGH>; + sleepst-gpios = < 1 GPIO_ACTIVE_HIGH>; + wakeup-gpios = < 4 GPIO_ACTIVE_HIGH>; + powerdown-gpios = < 0 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <_irq_gpios _wake_gpios +_sleep_gpios>; + + port@0 { + mipi_dphy_out: endpoint { + remote-endpoint = <_dphy_in>; + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + clock-noncontinuous; + link-frequencies = + /bits/ 64 ; + }; + }; + /* Example: we have two cameras */ + port@1 { + sensor_in0: endpoint@0 { + remote-endpoint = <_out0>; + }; + sensor_in1: endpoint@1 { + remote-endpoint = <_out1>; + }; + }; + }; +}; diff --git a/MAINTAINERS b/MAINTAINERS index b2a98e3..04d227b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -141,6 +141,7 @@ M: Leo Wen S: Maintained F: drivers/media/spi/rk1608.c F: drivers/media/spi/rk1608.h +F: Documentation/devicetree/bindings/media/rk1608.txt 3C59X NETWORK DRIVER M: Steffen Klassert -- 2.7.4
[PATCH V3 1/2] [media] Add Rockchip RK1608 driver
From: Leo WenRk1608 is used as a PreISP to link on Soc, which mainly has two functions. One is to download the firmware of RK1608, and the other is to match the extra sensor such as camera and enable sensor by calling sensor's s_power. use below v4l2-ctl command to capture frames. v4l2-ctl --verbose -d /dev/video1 --stream-mmap=2 --stream-to=/tmp/stream.out --stream-count=60 --stream-poll use below command to playback the video on your PC. mplayer ./stream.out -loop 0 -demuxer rawvideo -rawvideo w=640:h=480:size=$((640*480*3/2)):format=NV12 Changes V3: - Instead use the new GPIO API. - Add the 'static' for all non-static functions. - Use a proper error code. - Delete the soc-specific registers operation(ioremap and write etc.). - Use sizeof() instead of hardcoding to 32. - Delete the extra cast(void *). - Add free() for all the msg functions(allocate a struct msg). - Add a comment for the delay functions. - Instead use the v4l2_subdev_call() macro. - Use the 'entity.function' instead of 'entity.type'. - Use 'GPL v2' for the MODULE_LICENSE. - Redefine all struct msg. - Revise the comment of msg. - Delete a struct msg_rk1608_log_t. Signed-off-by: Leo Wen --- MAINTAINERS|6 + drivers/media/spi/Makefile |1 + drivers/media/spi/rk1608.c | 1409 drivers/media/spi/rk1608.h | 442 ++ 4 files changed, 1858 insertions(+) create mode 100644 drivers/media/spi/rk1608.c create mode 100644 drivers/media/spi/rk1608.h diff --git a/MAINTAINERS b/MAINTAINERS index 93a12af..b2a98e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -136,6 +136,12 @@ Maintainers List (try to look for most precise areas first) --- +ROCKCHIP RK1608 DRIVER +M: Leo Wen +S: Maintained +F: drivers/media/spi/rk1608.c +F: drivers/media/spi/rk1608.h + 3C59X NETWORK DRIVER M: Steffen Klassert L: net...@vger.kernel.org diff --git a/drivers/media/spi/Makefile b/drivers/media/spi/Makefile index ea64013..6d0e6ee 100644 --- a/drivers/media/spi/Makefile +++ b/drivers/media/spi/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_VIDEO_GS1662) += gs1662.o +obj-$(CONFIG_VIDEO_RK1608) += rk1608.o diff --git a/drivers/media/spi/rk1608.c b/drivers/media/spi/rk1608.c new file mode 100644 index 000..22f1aac --- /dev/null +++ b/drivers/media/spi/rk1608.c @@ -0,0 +1,1409 @@ +/** + * Rockchip rk1608 driver + * + * SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rk1608.h" + +/** + * Rk1608 is used as the Pre-ISP to link on Soc, which mainly has two + * functions. One is to download the firmware of RK1608, and the other + * is to match the extra sensor such as camera and enable sensor by + * calling sensor's s_power. + * |---| + * | Sensor Camera | + * |---| + * |---||--| + * |---||--| + * |---\/--| + * | Pre-ISP RK1608| + * |---| + * |---||--| + * |---||--| + * |---\/--| + * | Rockchip Soc | + * |---| + * Data Transfer As shown above. In RK1608, the data received from the + * extra sensor,and it is passed to the Soc through ISP. + */ + +static inline struct rk1608_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct rk1608_state, sd); +} + +/** + * rk1608_operation_query - RK1608 last operation state query + * + * @spi: device from which data will be read + * @state: last operation state [out] + * Context: can sleep + * + * It returns zero on success, else a negative error code. + */ +static int rk1608_operation_query(struct spi_device *spi, s32 *state) +{ + s32 query_cmd = RK1608_CMD_QUERY; + struct spi_transfer query_cmd_packet = { + .tx_buf = _cmd, + .len= sizeof(query_cmd), + }; + struct spi_transfer state_packet = { + .rx_buf = state, + .len= sizeof(*state), + }; + struct spi_message m; + + spi_message_init(); + spi_message_add_tail(_cmd_packet, ); + spi_message_add_tail(_packet, ); + spi_sync(spi, ); + + return ((*state & RK1608_STATE_ID_MASK) == RK1608_STATE_ID) ? 0 : -1; +} + +static int rk1608_write(struct spi_device *spi, + s32 addr, const s32 *data, size_t data_len) +{ + s32 write_cmd = RK1608_CMD_WRITE; + struct spi_transfer write_cmd_packet = { + .tx_buf = _cmd, + .len= sizeof(write_cmd), + }; + struct spi_transfer
[PATCH v9 0/2] Initial Allwinner V3s CSI Support
This patchset add initial support for Allwinner V3s CSI. Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2 interface and CSI1 is used for parallel interface. This is not documented in datasheet but by test and guess. This patchset implement a v4l2 framework driver and add a binding documentation for it. Currently, the driver only support the parallel interface. And has been tested with a BT1120 signal which generating from FPGA. The following fetures are not support with this patchset: - ISP - MIPI-CSI2 - Master clock for camera sensor - Power regulator for the front end IC Changes in v9: * Merge the patchs from Maxime: a. Fill dma_pfn_offset to accomodate for the RAM offset b. Reduce the error level c. Pass the sun6i_csi_dev pointer to our helpers d. Don't emit a warning when the configured format isn't found e. Support the YUYV format properly f. Invert the polaritie of all signals g. Expose controls on the v4l2_device Changes in v8: * Revert to v6 and add 'hack' for PHYS_OFFSET. Changes in v7: * Add 'depends on ARM' in Kconfig to avoid built with non-ARM arch. Changes in v6: * Add Rob Herring's review tag. * Fix a NULL pointer dereference by picking Maxime Ripard's patch. * Add Maxime Ripard's test tag. Changes in v5: * Using the new SPDX tags. * Fix MODULE_LICENSE. * Add many default cases and warning messages. * Detail the parallel bus properties * Fix some spelling and syntax mistakes. Changes in v4: * Deal with the CSI 'INNER QUEUE'. CSI will lookup the next dma buffer for next frame before the the current frame done IRQ triggered. This is not documented but reported by Ondřej Jirman. The BSP code has workaround for this too. It skip to mark the first buffer as frame done for VB2 and pass the second buffer to CSI in the first frame done ISR call. Then in second frame done ISR call, it mark the first buffer as frame done for VB2 and pass the third buffer to CSI. And so on. The bad thing is that the first buffer will be written twice and the first frame is dropped even the queued buffer is sufficient. So, I make some improvement here. Pass the next buffer to CSI just follow starting the CSI. In this case, the first frame will be stored in first buffer, second frame in second buffer. This mothed is used to avoid dropping the first frame, it would also drop frame when lacking of queued buffer. * Fix: using a wrong mbus_code when getting the supported formats * Change all fourcc to pixformat * Change some function names Changes in v3: * Get rid of struct sun6i_csi_ops * Move sun6i-csi to new directory drivers/media/platform/sunxi * Merge sun6i_csi.c and sun6i_csi_v3s.c into sun6i_csi.c * Use generic fwnode endpoints parser * Only support a single subdev to make things simple * Many complaintion fix Changes in v2: * Change sunxi-csi to sun6i-csi * Rebase to media_tree master branch Following is the 'v4l2-compliance -s -f' output, I have test this with both interlaced and progressive signal: # ./v4l2-compliance -s -f v4l2-compliance SHA : 6049ea8bd64f9d78ef87ef0c2b3dc9b5de1ca4a1 Driver Info: Driver name : sun6i-video Card type : sun6i-csi Bus info : platform:csi Driver version: 4.15.0 Capabilities : 0x8421 Video Capture Streaming Extended Pix Format Device Capabilities Device Caps : 0x0421 Video Capture Streaming Extended Pix Format Compliance test for device /dev/video0 (not using libv4l2): Required ioctls: test VIDIOC_QUERYCAP: OK Allow for multiple opens: test second video open: OK test VIDIOC_QUERYCAP: OK test VIDIOC_G/S_PRIORITY: OK test for unlimited opens: OK Debug ioctls: test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported) test VIDIOC_LOG_STATUS: OK (Not Supported) Input ioctls: test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported) test VIDIOC_G/S_FREQUENCY: OK (Not Supported) test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported) test VIDIOC_ENUMAUDIO: OK (Not Supported) test VIDIOC_G/S/ENUMINPUT: OK test VIDIOC_G/S_AUDIO: OK (Not Supported) Inputs: 1 Audio Inputs: 0 Tuners: 0 Output ioctls: test VIDIOC_G/S_MODULATOR: OK (Not Supported) test VIDIOC_G/S_FREQUENCY: OK (Not Supported) test VIDIOC_ENUMAUDOUT: OK (Not Supported) test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported) test VIDIOC_G/S_AUDOUT: OK (Not Supported) Outputs: 0 Audio Outputs: 0 Modulators: 0 Input/Output configuration ioctls: test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported) test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported) test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported) test
Re: [PATCH v2 1/2] media: ov2680: dt: Add bindings for OV2680
On Wed, Feb 28, 2018 at 03:27:22PM +, Rui Miguel Silva wrote: > Add device tree binding documentation for the OV2680 camera sensor. > > CC: devicet...@vger.kernel.org > Signed-off-by: Rui Miguel Silva> --- > .../devicetree/bindings/media/i2c/ov2680.txt | 40 > ++ > 1 file changed, 40 insertions(+) > create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2680.txt Reviewed-by: Rob Herring
Re: [PATCH v4 1/2] media: dt-bindings: Add bindings for panasonic,amg88xx
On Mon, Feb 26, 2018 at 10:11:35PM -0800, Matt Ranostay wrote: > Define the device tree bindings for the panasonic,amg88xx i2c > video driver. > > Cc: Rob Herring> Cc: devicet...@vger.kernel.org > Signed-off-by: Matt Ranostay > --- > .../bindings/media/i2c/panasonic,amg88xx.txt | 19 > +++ > 1 file changed, 19 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/media/i2c/panasonic,amg88xx.txt Reviewed-by: Rob Herring
Re: [PATCH V2 2/3] media: dvb-core: Added timers for dvb_ca_en50221_write_data
Em Wed, 14 Feb 2018 00:29:43 +0100 "Jasmin J."escreveu: > Hi! > > Please hold on in merging this series, because I have to investigate a hint > I got related to the buffer size handshake of the protocol driver: > https://www.linuxtv.org/pipermail/linux-dvb/2007-July/019116.html Ok. I'll mark this series as "Changes requested". Please resubmit it once you have a new patch series. > > BR, >Jasmin > > > On 12/21/2017 02:22 PM, Jasmin J. wrote: > > From: Jasmin Jessich > > > > Some (older) CAMs are really slow in accepting data. The CI interface > > specification doesn't define a handshake for accepted data. Thus, the > > en50221 protocol driver can't control if a data byte has been correctly > > written to the CAM. > > > > The current implementation writes the length and the data quick after > > each other. Thus, the slow CAMs may generate a WR error, which leads to > > the known error logging > >"CAM tried to send a buffer larger than the ecount size". > > > > To solve this issue the en50221 protocol driver needs to wait some CAM > > depending time between the different bytes to be written. Because the > > time is CAM dependent, an individual value per CAM needs to be set. For > > that SysFS is used in favor of ioctl's to allow the control of the timer > > values independent from any user space application. > > > > This patch adds the timers and the SysFS nodes to set/get the timeout > > values and the timer waiting between the different steps of the CAM write > > access. A timer value of 0 (default) means "no timeout". > > > > Signed-off-by: Jasmin Jessich > > Acked-by: Ralph Metzler > > --- > > drivers/media/dvb-core/dvb_ca_en50221.c | 132 > > +++- > > 1 file changed, 131 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c > > b/drivers/media/dvb-core/dvb_ca_en50221.c > > index a3b2754..9b45d6b 100644 > > --- a/drivers/media/dvb-core/dvb_ca_en50221.c > > +++ b/drivers/media/dvb-core/dvb_ca_en50221.c > > @@ -86,6 +86,13 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug > > messages"); > > #define DVB_CA_SLOTSTATE_WAITFR 6 > > #define DVB_CA_SLOTSTATE_LINKINIT 7 > > > > +enum dvb_ca_timers { > > + DVB_CA_TIM_WR_HIGH /* wait after writing length high */ > > +, DVB_CA_TIM_WR_LOW /* wait after writing length low */ > > +, DVB_CA_TIM_WR_DATA /* wait between data bytes */ > > +, DVB_CA_TIM_MAX > > +}; > > + > > /* Information on a CA slot */ > > struct dvb_ca_slot { > > /* current state of the CAM */ > > @@ -119,6 +126,11 @@ struct dvb_ca_slot { > > unsigned long timeout; > > }; > > > > +struct dvb_ca_timer { > > + unsigned long min; > > + unsigned long max; > > +}; > > + > > /* Private CA-interface information */ > > struct dvb_ca_private { > > struct kref refcount; > > @@ -161,6 +173,14 @@ struct dvb_ca_private { > > > > /* mutex serializing ioctls */ > > struct mutex ioctl_mutex; > > + > > + struct dvb_ca_timer timers[DVB_CA_TIM_MAX]; > > +}; > > + > > +static const char dvb_ca_tim_names[DVB_CA_TIM_MAX][15] = { > > + "tim_wr_high" > > +, "tim_wr_low" > > +, "tim_wr_data" > > }; > > > > static void dvb_ca_private_free(struct dvb_ca_private *ca) > > @@ -223,6 +243,14 @@ static char *findstr(char *haystack, int hlen, char > > *needle, int nlen) > > return NULL; > > } > > > > +static void dvb_ca_sleep(struct dvb_ca_private *ca, enum dvb_ca_timers tim) > > +{ > > + unsigned long min = ca->timers[tim].min; > > + > > + if (min) > > + usleep_range(min, ca->timers[tim].max); > > +} > > + > > /* > > ** > > */ > > /* EN50221 physical interface functions */ > > > > @@ -869,10 +897,13 @@ static int dvb_ca_en50221_write_data(struct > > dvb_ca_private *ca, int slot, > > bytes_write >> 8); > > if (status) > > goto exit; > > + dvb_ca_sleep(ca, DVB_CA_TIM_WR_HIGH); > > + > > status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW, > > bytes_write & 0xff); > > if (status) > > goto exit; > > + dvb_ca_sleep(ca, DVB_CA_TIM_WR_LOW); > > > > /* send the buffer */ > > for (i = 0; i < bytes_write; i++) { > > @@ -880,6 +911,7 @@ static int dvb_ca_en50221_write_data(struct > > dvb_ca_private *ca, int slot, > > buf[i]); > > if (status) > > goto exit; > > + dvb_ca_sleep(ca, DVB_CA_TIM_WR_DATA); > > } > > > > /* check for write error (WE should now be 0) */ > > @@ -1834,6 +1866,97 @@ static const struct dvb_device dvbdev_ca = { > > }; > > > > /* > > ** > > */ > > +/* EN50221 device
Re: [PATCHv2 0/7] cec: add error injection support
Hans, > Special thanks go to Wolfram Sang since his i2c error injection > presentation at the Embedded Linux Conference Europe 2017 inspired > me to switch to debugfs for this instead of using ioctls. You are very welcome! I am glad the presentation did inspire you. Happy hacking, Wolfram signature.asc Description: PGP signature
[PATCH 2/3] media: rc: add keymap for iMON RSC remote
Note that the stick on the remote is not supported yet. Signed-off-by: Sean Young--- drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-imon-rsc.c | 81 ++ include/media/rc-map.h | 1 + 3 files changed, 83 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-imon-rsc.c diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 50b319355edf..d6b913a3032d 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-hisi-tv-demo.o \ rc-imon-mce.o \ rc-imon-pad.o \ + rc-imon-rsc.o \ rc-iodata-bctv7e.o \ rc-it913x-v1.o \ rc-it913x-v2.o \ diff --git a/drivers/media/rc/keymaps/rc-imon-rsc.c b/drivers/media/rc/keymaps/rc-imon-rsc.c new file mode 100644 index ..83e4564aaa22 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-imon-rsc.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (C) 2018 Sean Young + +#include +#include + +// +// Note that this remote has a stick which its own IR protocol, +// with 16 directions. This is not supported yet. +// +static struct rc_map_table imon_rsc[] = { + { 0x801010, KEY_EXIT }, + { 0x80102f, KEY_POWER }, + { 0x80104a, KEY_SCREENSAVER }, /* Screensaver */ + { 0x801049, KEY_TIME }, /* Timer */ + { 0x801054, KEY_NUMERIC_1 }, + { 0x801055, KEY_NUMERIC_2 }, + { 0x801056, KEY_NUMERIC_3 }, + { 0x801057, KEY_NUMERIC_4 }, + { 0x801058, KEY_NUMERIC_5 }, + { 0x801059, KEY_NUMERIC_6 }, + { 0x80105a, KEY_NUMERIC_7 }, + { 0x80105b, KEY_NUMERIC_8 }, + { 0x80105c, KEY_NUMERIC_9 }, + { 0x801081, KEY_SCREEN }, /* Desktop */ + { 0x80105d, KEY_NUMERIC_0 }, + { 0x801082, KEY_MAX }, + { 0x801048, KEY_ESC }, + { 0x80104b, KEY_MEDIA },/* Windows key */ + { 0x801083, KEY_MENU }, + { 0x801045, KEY_APPSELECT },/* app launcher */ + { 0x801084, KEY_STOP }, + { 0x801046, KEY_CYCLEWINDOWS }, + { 0x801085, KEY_BACKSPACE }, + { 0x801086, KEY_KEYBOARD }, + { 0x801087, KEY_SPACE }, + { 0x80101e, KEY_RESERVED }, /* shift tab */ + { 0x801098, BTN_0 }, + { 0x80101f, KEY_TAB }, + { 0x80101b, BTN_LEFT }, + { 0x80101d, BTN_RIGHT }, + { 0x801016, BTN_MIDDLE }, /* drag and drop */ + { 0x801088, KEY_MUTE }, + { 0x80105e, KEY_VOLUMEDOWN }, + { 0x80105f, KEY_VOLUMEUP }, + { 0x80104c, KEY_PLAY }, + { 0x80104d, KEY_PAUSE }, + { 0x80104f, KEY_EJECTCD }, + { 0x801050, KEY_PREVIOUS }, + { 0x801051, KEY_NEXT }, + { 0x80104e, KEY_STOP }, + { 0x801052, KEY_REWIND }, + { 0x801053, KEY_FASTFORWARD }, + { 0x801089, KEY_ZOOM } /* full screen */ +}; + +static struct rc_map_list imon_rsc_map = { + .map = { + .scan = imon_rsc, + .size = ARRAY_SIZE(imon_rsc), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_IMON_RSC, + } +}; + +static int __init init_rc_map_imon_rsc(void) +{ + return rc_map_register(_rsc_map); +} + +static void __exit exit_rc_map_imon_rsc(void) +{ + rc_map_unregister(_rsc_map); +} + +module_init(init_rc_map_imon_rsc) +module_exit(exit_rc_map_imon_rsc) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sean Young "); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 7046734b3895..7fc84991bd12 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -211,6 +211,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_HISI_TV_DEMO "rc-hisi-tv-demo" #define RC_MAP_IMON_MCE "rc-imon-mce" #define RC_MAP_IMON_PAD "rc-imon-pad" +#define RC_MAP_IMON_RSC "rc-imon-rsc" #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" #define RC_MAP_IT913X_V1 "rc-it913x-v1" #define RC_MAP_IT913X_V2 "rc-it913x-v2" -- 2.14.3
[PATCH 3/3] media: rc: new driver for early iMon device
These devices were supported by the lirc_imon.c driver which was removed from staging in commit f41003a23a02 ("[media] staging: lirc_imon: port remaining usb ids to imon and remove"). Signed-off-by: Sean Young--- MAINTAINERS | 7 ++ drivers/media/rc/Kconfig| 12 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/imon_raw.c | 193 4 files changed, 213 insertions(+) create mode 100644 drivers/media/rc/imon_raw.c diff --git a/MAINTAINERS b/MAINTAINERS index 0eea2f0e9456..3e23fb9e3991 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6903,6 +6903,13 @@ M: James Hogan S: Maintained F: drivers/media/rc/img-ir/ +IMON SOUNDGRAPH USB IR RECEIVER +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/imon_raw.c +F: drivers/media/rc/imon.c + IMS TWINTURBO FRAMEBUFFER DRIVER L: linux-fb...@vger.kernel.org S: Orphan diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 447f82c1f65a..7ad05a6ef350 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -175,6 +175,18 @@ config IR_IMON To compile this driver as a module, choose M here: the module will be called imon. +config IR_IMON_RAW + tristate "SoundGraph iMON Receiver (early raw IR models)" + depends on USB_ARCH_HAS_HCD + depends on RC_CORE + select USB + ---help--- + Say Y here if you want to use a SoundGraph iMON IR Receiver, + early raw models. + + To compile this driver as a module, choose M here: the + module will be called imon_raw. + config IR_MCEUSB tristate "Windows Media Center Ed. eHome Infrared Transceiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 0e857816ac2d..e098e127b26a 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o obj-$(CONFIG_IR_HIX5HD2) += ir-hix5hd2.o obj-$(CONFIG_IR_IMON) += imon.o +obj-$(CONFIG_IR_IMON_RAW) += imon_raw.o obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o obj-$(CONFIG_IR_MCEUSB) += mceusb.o obj-$(CONFIG_IR_FINTEK) += fintek-cir.o diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c new file mode 100644 index ..92dfe972c4b8 --- /dev/null +++ b/drivers/media/rc/imon_raw.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (C) 2018 Sean Young + +#include +#include +#include +#include + +/* Each bit is 250us */ +#define BIT_DURATION 25 + +struct imon { + struct device *dev; + struct urb *ir_urb; + struct rc_dev *rcdev; + u8 ir_buf[8]; + char phys[64]; +}; + +/* + * ffs/find_next_bit() searches in the wrong direction, so open-code our own. + */ +static int is_bit_set(u8 *buf, int bit) +{ + return buf[bit / 8] & (0x80 >> (bit & 7)); +} + +static void imon_ir_data(struct imon *imon) +{ + DEFINE_IR_RAW_EVENT(rawir); + int offset = 0, size = 5 * 8; + int bit; + + dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); + + while (offset < size) { + bit = offset; + while (!is_bit_set(imon->ir_buf, bit) && bit < size) + bit++; + dev_dbg(imon->dev, "zero: %d", bit - offset); + if (bit > offset) { + rawir.pulse = true; + rawir.duration = (bit - offset) * BIT_DURATION; + ir_raw_event_store_with_filter(imon->rcdev, ); + } + + if (bit >= size) + break; + + offset = bit; + while (is_bit_set(imon->ir_buf, bit) && bit < size) + bit++; + dev_dbg(imon->dev, "set: %d", bit - offset); + + rawir.pulse = false; + rawir.duration = (bit - offset) * BIT_DURATION; + ir_raw_event_store_with_filter(imon->rcdev, ); + + offset = bit; + } + + if (imon->ir_buf[7] == 0x0a) { + ir_raw_event_set_idle(imon->rcdev, true); + ir_raw_event_handle(imon->rcdev); + } +} + +static void imon_ir_rx(struct urb *urb) +{ + struct imon *imon = urb->context; + int ret; + + switch (urb->status) { + case 0: + if (imon->ir_buf[7] != 0xff) + imon_ir_data(imon); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + usb_unlink_urb(urb); + return; + case -EPIPE: + default: + dev_dbg(imon->dev, "error: urb status = %d", urb->status); + break; + } + + ret = usb_submit_urb(urb,
[PATCH 1/3] Revert "[media] staging: lirc_imon: port remaining usb ids to imon and remove"
This code was ported without the necessary hardware to test. There are multiple problems which are more easily solved by writing a separate driver. This reverts commit f41003a23a02dc7299539300f74360c2a932714a. Signed-off-by: Sean Young--- drivers/media/rc/imon.c | 135 +++- 1 file changed, 7 insertions(+), 128 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 950d068ba806..527920a59d99 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -92,7 +92,6 @@ struct imon_usb_dev_descr { __u16 flags; #define IMON_NO_FLAGS 0 #define IMON_NEED_20MS_PKT_DELAY 1 -#define IMON_IR_RAW 2 struct imon_panel_key_table key_table[]; }; @@ -123,12 +122,6 @@ struct imon_context { unsigned char usb_tx_buf[8]; unsigned int send_packet_delay; - struct rx_data { - int count; /* length of 0 or 1 sequence */ - int prev_bit; /* logic level of sequence */ - int initial_space; /* initial space flag */ - } rx; - struct tx_t { unsigned char data_buf[35]; /* user data buffer */ struct completion finished; /* wait for write to finish */ @@ -331,10 +324,6 @@ static const struct imon_usb_dev_descr imon_DH102 = { } }; -static const struct imon_usb_dev_descr imon_ir_raw = { - .flags = IMON_IR_RAW, -}; - /* * USB Device ID for iMON USB Control Boards * @@ -418,18 +407,6 @@ static const struct usb_device_id imon_usb_id_table[] = { /* device specifics unknown */ { USB_DEVICE(0x15c2, 0x0046), .driver_info = (unsigned long)_default_table}, - /* TriGem iMON (IR only) -- TG_iMON.inf */ - { USB_DEVICE(0x0aa8, 0x8001), - .driver_info = (unsigned long)_ir_raw}, - /* SoundGraph iMON (IR only) -- sg_imon.inf */ - { USB_DEVICE(0x04e8, 0xff30), - .driver_info = (unsigned long)_ir_raw}, - /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */ - { USB_DEVICE(0x0aa8, 0xffda), - .driver_info = (unsigned long)_ir_raw}, - /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */ - { USB_DEVICE(0x15c2, 0xffda), - .driver_info = (unsigned long)_ir_raw}, {} }; @@ -1572,91 +1549,8 @@ static int imon_parse_press_type(struct imon_context *ictx, /* * Process the incoming packet */ -/* - * Convert bit count to time duration (in us) and submit - * the value to lirc_dev. - */ -static void submit_data(struct imon_context *context) -{ - DEFINE_IR_RAW_EVENT(ev); - - ev.pulse = context->rx.prev_bit; - ev.duration = US_TO_NS(context->rx.count * BIT_DURATION); - ir_raw_event_store_with_filter(context->rdev, ); -} - -/* - * Process the incoming packet - */ -static void imon_incoming_ir_raw(struct imon_context *context, +static void imon_incoming_packet(struct imon_context *ictx, struct urb *urb, int intf) -{ - int len = urb->actual_length; - unsigned char *buf = urb->transfer_buffer; - struct device *dev = context->dev; - int octet, bit; - unsigned char mask; - - if (len != 8) { - dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n", -__func__, len, intf); - return; - } - - if (debug) - dev_info(dev, "raw packet: %*ph\n", len, buf); - /* -* Translate received data to pulse and space lengths. -* Received data is active low, i.e. pulses are 0 and -* spaces are 1. -* -* My original algorithm was essentially similar to -* Changwoo Ryu's with the exception that he switched -* the incoming bits to active high and also fed an -* initial space to LIRC at the start of a new sequence -* if the previous bit was a pulse. -* -* I've decided to adopt his algorithm. -*/ - - if (buf[7] == 1 && context->rx.initial_space) { - /* LIRC requires a leading space */ - context->rx.prev_bit = 0; - context->rx.count = 4; - submit_data(context); - context->rx.count = 0; - } - - for (octet = 0; octet < 5; ++octet) { - mask = 0x80; - for (bit = 0; bit < 8; ++bit) { - int curr_bit = !(buf[octet] & mask); - - if (curr_bit != context->rx.prev_bit) { - if (context->rx.count) { - submit_data(context); - context->rx.count = 0; - } - context->rx.prev_bit = curr_bit; - } - ++context->rx.count; - mask >>= 1; - } -
[PATCHv2 5/7] cec-pin: add error injection support
From: Hans VerkuilImplement all the error injection commands. The state machine gets new states for the various error situations, helper functions are added to detect whether an error injection is active and the actual error injections are implemented. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-pin-priv.h | 38 ++- drivers/media/cec/cec-pin.c | 542 +++ 2 files changed, 521 insertions(+), 59 deletions(-) diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h index 779384f18689..c9349f68e554 100644 --- a/drivers/media/cec/cec-pin-priv.h +++ b/drivers/media/cec/cec-pin-priv.h @@ -28,14 +28,30 @@ enum cec_pin_state { CEC_ST_TX_START_BIT_LOW, /* Drive CEC high for the start bit */ CEC_ST_TX_START_BIT_HIGH, + /* Generate a start bit period that is too short */ + CEC_ST_TX_START_BIT_HIGH_SHORT, + /* Generate a start bit period that is too long */ + CEC_ST_TX_START_BIT_HIGH_LONG, + /* Drive CEC low for the start bit using the custom timing */ + CEC_ST_TX_START_BIT_LOW_CUSTOM, + /* Drive CEC high for the start bit using the custom timing */ + CEC_ST_TX_START_BIT_HIGH_CUSTOM, /* Drive CEC low for the 0 bit */ CEC_ST_TX_DATA_BIT_0_LOW, /* Drive CEC high for the 0 bit */ CEC_ST_TX_DATA_BIT_0_HIGH, + /* Generate a bit period that is too short */ + CEC_ST_TX_DATA_BIT_0_HIGH_SHORT, + /* Generate a bit period that is too long */ + CEC_ST_TX_DATA_BIT_0_HIGH_LONG, /* Drive CEC low for the 1 bit */ CEC_ST_TX_DATA_BIT_1_LOW, /* Drive CEC high for the 1 bit */ CEC_ST_TX_DATA_BIT_1_HIGH, + /* Generate a bit period that is too short */ + CEC_ST_TX_DATA_BIT_1_HIGH_SHORT, + /* Generate a bit period that is too long */ + CEC_ST_TX_DATA_BIT_1_HIGH_LONG, /* * Wait for start of sample time to check for Ack bit or first * four initiator bits to check for Arbitration Lost. @@ -43,6 +59,20 @@ enum cec_pin_state { CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE, /* Wait for end of bit period after sampling */ CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE, + /* Generate a bit period that is too short */ + CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT, + /* Generate a bit period that is too long */ + CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG, + /* Drive CEC low for a data bit using the custom timing */ + CEC_ST_TX_DATA_BIT_LOW_CUSTOM, + /* Drive CEC high for a data bit using the custom timing */ + CEC_ST_TX_DATA_BIT_HIGH_CUSTOM, + /* Drive CEC low for a standalone pulse using the custom timing */ + CEC_ST_TX_PULSE_LOW_CUSTOM, + /* Drive CEC high for a standalone pulse using the custom timing */ + CEC_ST_TX_PULSE_HIGH_CUSTOM, + /* Start low drive */ + CEC_ST_TX_LOW_DRIVE, /* Rx states */ @@ -54,8 +84,8 @@ enum cec_pin_state { CEC_ST_RX_DATA_SAMPLE, /* Wait for earliest end of bit period after sampling */ CEC_ST_RX_DATA_POST_SAMPLE, - /* Wait for CEC to go high (i.e. end of bit period */ - CEC_ST_RX_DATA_HIGH, + /* Wait for CEC to go low (i.e. end of bit period) */ + CEC_ST_RX_DATA_WAIT_FOR_LOW, /* Drive CEC low to send 0 Ack bit */ CEC_ST_RX_ACK_LOW, /* End of 0 Ack time, wait for earliest end of bit period */ @@ -64,9 +94,9 @@ enum cec_pin_state { CEC_ST_RX_ACK_HIGH_POST, /* Wait for earliest end of bit period and end of message */ CEC_ST_RX_ACK_FINISH, - /* Start low drive */ - CEC_ST_LOW_DRIVE, + CEC_ST_RX_LOW_DRIVE, + /* Monitor pin using interrupts */ CEC_ST_RX_IRQ, diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 7920ea1c940b..430a23392299 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -39,11 +39,29 @@ #define CEC_TIM_IDLE_SAMPLE1000 /* when processing the start bit, sample twice per millisecond */ #define CEC_TIM_START_BIT_SAMPLE 500 -/* when polling for a state change, sample once every 50 micoseconds */ +/* when polling for a state change, sample once every 50 microseconds */ #define CEC_TIM_SAMPLE 50 #define CEC_TIM_LOW_DRIVE_ERROR(1.5 * CEC_TIM_DATA_BIT_TOTAL) +/* + * Total data bit time that is too short/long for a valid bit, + * used for error injection. + */ +#define CEC_TIM_DATA_BIT_TOTAL_SHORT 1800 +#define CEC_TIM_DATA_BIT_TOTAL_LONG2900 + +/* + * Total start bit time that is too short/long for a valid bit, + * used for error injection. + */ +#define CEC_TIM_START_BIT_TOTAL_SHORT 4100 +#define CEC_TIM_START_BIT_TOTAL_LONG 5000 + +/* Data bits are 0-7, EOM is bit 8 and ACK is bit 9 */ +#define EOM_BIT
[PATCHv2 1/7] cec: add core error injection support
From: Hans VerkuilAdd two new ops (error_inj_show and error_inj_parse_line) to support error injection functionality for CEC adapters. If both are present, then the core will add a new error-inj debugfs file that can be used to see the current error injection commands and to set error injection commands. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-core.c | 58 include/media/cec.h | 5 2 files changed, 63 insertions(+) diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index e47ea22b3c23..ea3eccfdba15 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -195,6 +195,55 @@ void cec_register_cec_notifier(struct cec_adapter *adap, EXPORT_SYMBOL_GPL(cec_register_cec_notifier); #endif +#ifdef CONFIG_DEBUG_FS +static ssize_t cec_error_inj_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *sf = file->private_data; + struct cec_adapter *adap = sf->private; + char *buf; + char *line; + char *p; + + buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count)); + if (IS_ERR(buf)) + return PTR_ERR(buf); + p = buf; + while (p && *p && count >= 0) { + p = skip_spaces(p); + line = strsep(, "\n"); + if (!*line || *line == '#') + continue; + if (!adap->ops->error_inj_parse_line(adap, line)) { + count = -EINVAL; + break; + } + } + kfree(buf); + return count; +} + +static int cec_error_inj_show(struct seq_file *sf, void *unused) +{ + struct cec_adapter *adap = sf->private; + + return adap->ops->error_inj_show(adap, sf); +} + +static int cec_error_inj_open(struct inode *inode, struct file *file) +{ + return single_open(file, cec_error_inj_show, inode->i_private); +} + +static const struct file_operations cec_error_inj_fops = { + .open = cec_error_inj_open, + .write = cec_error_inj_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv, const char *name, u32 caps, u8 available_las) @@ -334,7 +383,16 @@ int cec_register_adapter(struct cec_adapter *adap, pr_warn("cec-%s: Failed to create status file\n", adap->name); debugfs_remove_recursive(adap->cec_dir); adap->cec_dir = NULL; + return 0; } + if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line) + return 0; + adap->error_inj_file = debugfs_create_file("error-inj", 0644, + adap->cec_dir, adap, + _error_inj_fops); + if (IS_ERR_OR_NULL(adap->error_inj_file)) + pr_warn("cec-%s: Failed to create error-inj file\n", + adap->name); #endif return 0; } diff --git a/include/media/cec.h b/include/media/cec.h index 9afba9b558df..41df048efc55 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -117,6 +117,10 @@ struct cec_adap_ops { void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); void (*adap_free)(struct cec_adapter *adap); + /* Error injection callbacks */ + int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); + bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); + /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); }; @@ -189,6 +193,7 @@ struct cec_adapter { struct dentry *cec_dir; struct dentry *status_file; + struct dentry *error_inj_file; u16 phys_addrs[15]; u32 sequence; -- 2.16.1
[PATCHv2 0/7] cec: add error injection support
From: Hans VerkuilThis patch series adds support for CEC error injection for drivers using the CEC Pin Framework (cec-pin.c). There are two CEC drivers currently using this framework: the sun4i Allwinner A10/A20 driver and the cec-gpio driver. This patch series was developed with the cec-gpio driver and a Raspberry Pi. The CEC Pin Framework is meant for hardware that has no high-level support but only direct low-level control of the bus (i.e. pull the CEC line down or read the CEC line). Low-level bus access like that is ideal to implement error injection since you have full control of the bus and you can do anything you want. This new error injection framework can create most if not all error conditions that I could think of. We (Cisco) used it to verify our own CEC implementation and in fact this error injection framework was developed together with the low-level CEC analysis code in the cec-ctl userspace utility to analyze what is happening on the bus. I have been working on creating scripts that can test a remote CEC adapter for low-level compliance with the CEC standard: https://git.linuxtv.org/hverkuil/v4l-utils.git/log/?h=cec-pin-tests (note: these scripts are for the v1 version of this patch series, they need to be updated for this v2) These scripts are not complete yet since it isn't smart enough to tell the difference between different (but valid) interpretations of the CEC specification and actual violations of the specification. I plan to continue working on that since I would like to have a test-suite that can check a CEC implementation automatically. Special thanks go to Wolfram Sang since his i2c error injection presentation at the Embedded Linux Conference Europe 2017 inspired me to switch to debugfs for this instead of using ioctls. Changes since v1: - added 'mode' support (off/once/always/toggle). - simplified the error injection data structures and logic. - added patch 7 to log various errors in the 'status' debugfs file. Regards, Hans Hans Verkuil (7): cec: add core error injection support cec-core.rst: document the error injection ops cec-pin: create cec_pin_start_timer() function cec-pin-error-inj: parse/show error injection cec-pin: add error injection support cec-pin-error-inj.rst: document CEC Pin Error Injection cec-pin: improve status log .../media/cec-drivers/cec-pin-error-inj.rst| 322 +++ Documentation/media/cec-drivers/index.rst | 1 + Documentation/media/kapi/cec-core.rst | 72 ++- MAINTAINERS| 1 + drivers/media/cec/Kconfig | 6 + drivers/media/cec/Makefile | 4 + drivers/media/cec/cec-core.c | 58 ++ drivers/media/cec/cec-pin-error-inj.c | 341 +++ drivers/media/cec/cec-pin-priv.h | 124 +++- drivers/media/cec/cec-pin.c| 627 ++--- include/media/cec.h| 5 + 11 files changed, 1490 insertions(+), 71 deletions(-) create mode 100644 Documentation/media/cec-drivers/cec-pin-error-inj.rst create mode 100644 drivers/media/cec/cec-pin-error-inj.c -- 2.16.1
[PATCHv2 6/7] cec-pin-error-inj.rst: document CEC Pin Error Injection
From: Hans VerkuilThe CEC Pin framework adds support for Error Injection. Document all the error injections commands and how to use it. Signed-off-by: Hans Verkuil --- .../media/cec-drivers/cec-pin-error-inj.rst| 322 + Documentation/media/cec-drivers/index.rst | 1 + MAINTAINERS| 1 + 3 files changed, 324 insertions(+) create mode 100644 Documentation/media/cec-drivers/cec-pin-error-inj.rst diff --git a/Documentation/media/cec-drivers/cec-pin-error-inj.rst b/Documentation/media/cec-drivers/cec-pin-error-inj.rst new file mode 100644 index ..21bda831d3fb --- /dev/null +++ b/Documentation/media/cec-drivers/cec-pin-error-inj.rst @@ -0,0 +1,322 @@ +CEC Pin Framework Error Injection += + +The CEC Pin Framework is a core CEC framework for CEC hardware that only +has low-level support for the CEC bus. Most hardware today will have +high-level CEC support where the hardware deals with driving the CEC bus, +but some older devices aren't that fancy. However, this framework also +allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and +you can become an instant CEC adapter. + +What makes doing this so interesting is that since we have full control +over the bus it is easy to support error injection. This is ideal to +test how well CEC adapters can handle error conditions. + +Currently only the cec-gpio driver (when the CEC line is directly +connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver +support this framework. + +If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available +through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is +now an ``error-inj`` file. + +With ``cat error-inj`` you can see both the possible commands and the current +error injection status: + +.. code-block:: none + + $ cat /sys/kernel/debug/cec/cec0/error-inj + # Clear error injections: + # clear clear all rx and tx error injections + # rx-clear clear all rx error injections + # tx-clear clear all tx error injections + #clear clear all rx and tx error injections for + #rx-clear clear all rx error injections for + #tx-clear clear all tx error injections for + # + # RX error injection: + # [,] rx-nack NACK the message instead of sending an ACK + # [,] rx-low-driveforce a low-drive condition at this bit position + # [,] rx-add-byte add a spurious byte to the received CEC message + # [,] rx-remove-byte remove the last byte from the received CEC message + # [,] rx-arb-lostgenerate a POLL message to trigger an arbitration lost + # + # TX error injection settings: + # tx-ignore-nack-until-eom ignore early NACKs until EOM + # tx-custom-low-usecs define the 'low' time for the custom pulse + # tx-custom-high-usecsdefine the 'high' time for the custom pulse + # tx-custom-pulsetransmit the custom pulse once the bus is idle + # + # TX error injection: + # [,] tx-no-eomdon't set the EOM bit + # [,] tx-early-eom set the EOM bit one byte too soon + # [,] tx-add-bytesappend (1-255) spurious bytes to the message + # [,] tx-remove-byte drop the last byte from the message + # [,] tx-short-bitmake this bit shorter than allowed + # [,] tx-long-bit make this bit longer than allowed + # [,] tx-custom-bit send the custom pulse instead of this bit + # [,] tx-short-start send a start pulse that's too short + # [,] tx-long-startsend a start pulse that's too long + # [,] tx-custom-start send the custom pulse instead of the start pulse + # [,] tx-last-bit stop sending after this bit + # [,] tx-low-driveforce a low-drive condition at this bit position + # + #CEC message opcode (0-255) or 'any' + # 'once' (default), 'always', 'toggle' or 'off' + # CEC message bit (0-159) + #10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK + # CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f) + # microseconds (0-1000, default 1000) + + clear + +You can write error injection commands to ``error-inj`` using ``echo 'cmd' >error-inj`` +or ``cat cmd.txt >error-inj``. The ``cat error-inj`` output contains the current +error commands. You can save the output to a file and use it as an input to +``error-inj`` later. + +Basic Syntax + + +Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the +line was reached, then the whole
[PATCHv2 2/7] cec-core.rst: document the error injection ops
From: Hans VerkuilDocument the new core error injection callbacks. Signed-off-by: Hans Verkuil --- Documentation/media/kapi/cec-core.rst | 72 ++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 62b9a1448177..a9f53f069a2d 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -110,11 +110,14 @@ your driver: void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); void (*adap_free)(struct cec_adapter *adap); + /* Error injection callbacks */ + ... + /* High-level callbacks */ ... }; -The five low-level ops deal with various aspects of controlling the CEC adapter +The seven low-level ops deal with various aspects of controlling the CEC adapter hardware: @@ -286,6 +289,70 @@ handling the receive interrupt. The framework expects to see the cec_transmit_do call before the cec_received_msg call, otherwise it can get confused if the received message was in reply to the transmitted message. +Optional: Implementing Error Injection Support +-- + +If the CEC adapter supports Error Injection functionality, then that can +be exposed through the Error Injection callbacks: + +.. code-block:: none + + struct cec_adap_ops { + /* Low-level callbacks */ + ... + + /* Error injection callbacks */ + int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); + bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); + + /* High-level CEC message callback */ + ... + }; + +If both callbacks are set, then an ``error-inj`` file will appear in debugfs. +The basic syntax is as follows: + +Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the +line was reached, then the whole line is ignored. Otherwise a command is expected. + +This basic parsing is done in the CEC Framework. It is up to the driver to decide +what commands to implement. The only requirement is that the command ``clear`` without +any arguments must be implemented and that it will remove all current error injection +commands. + +This ensures that you can always do ``echo clear >error-inj`` to clear any error +injections without having to know the details of the driver-specific commands. + +Note that the output of ``error-inj`` shall be valid as input to ``error-inj``. +So this must work: + +.. code-block:: none + + $ cat error-inj >einj.txt + $ cat einj.txt >error-inj + +The first callback is called when this file is read and it should show the +the current error injection state: + +.. c:function:: + int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); + +It is recommended that it starts with a comment block with basic usage +information. It returns 0 for success and an error otherwise. + +The second callback will parse commands written to the ``error-inj`` file: + +.. c:function:: + bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); + +The ``line`` argument points to the start of the command. Any leading +spaces or tabs have already been skipped. It is a single line only (so there +are no embedded newlines) and it is 0-terminated. The callback is free to +modify the contents of the buffer. It is only called for lines containing a +command, so this callback is never called for empty lines or comment lines. + +Return true if the command was valid or false if there were syntax errors. + Implementing the High-Level CEC Adapter --- @@ -298,6 +365,9 @@ CEC protocol driven. The following high-level callbacks are available: /* Low-level callbacks */ ... + /* Error injection callbacks */ + ... + /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); }; -- 2.16.1
[PATCHv2 7/7] cec-pin: improve status log
From: Hans VerkuilKeep track of the number of short or long start bits, the number of short or long data bits and the number of initiated or detected low drive conditions. Show this information in the status debugfs log. Helpful when debugging, particularly when doing error injection as well. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-pin-priv.h | 13 + drivers/media/cec/cec-pin.c | 58 +--- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h index c9349f68e554..dae8ba6f1037 100644 --- a/drivers/media/cec/cec-pin-priv.h +++ b/drivers/media/cec/cec-pin-priv.h @@ -181,6 +181,18 @@ struct cec_pin { struct cec_msg rx_msg; u32 rx_bit; boolrx_toggle; + u32 rx_start_bit_low_too_short_cnt; + u64 rx_start_bit_low_too_short_ts; + u32 rx_start_bit_low_too_short_delta; + u32 rx_start_bit_too_short_cnt; + u64 rx_start_bit_too_short_ts; + u32 rx_start_bit_too_short_delta; + u32 rx_start_bit_too_long_cnt; + u32 rx_data_bit_too_short_cnt; + u64 rx_data_bit_too_short_ts; + u32 rx_data_bit_too_short_delta; + u32 rx_data_bit_too_long_cnt; + u32 rx_low_drive_cnt; struct cec_msg work_rx_msg; u8 work_tx_status; @@ -205,6 +217,7 @@ struct cec_pin { booltx_generated_poll; booltx_post_eom; u8 tx_extra_bytes; + u32 tx_low_drive_cnt; #ifdef CONFIG_CEC_PIN_ERROR_INJ u64 error_inj[CEC_ERROR_INJ_OP_ANY + 1]; u8 error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS]; diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 430a23392299..b509df154ca1 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -429,6 +429,7 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) pin->state = CEC_ST_TX_WAIT_FOR_HIGH; pin->work_tx_ts = ts; pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; + pin->tx_low_drive_cnt++; wake_up_interruptible(>kthread_waitq); break; } @@ -460,6 +461,7 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) break; pin->work_tx_ts = ts; pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; + pin->tx_low_drive_cnt++; wake_up_interruptible(>kthread_waitq); break; } @@ -650,6 +652,10 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) delta = ktime_us_delta(ts, pin->ts); /* Start bit low is too short, go back to idle */ if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) { + if (!pin->rx_start_bit_low_too_short_cnt++) { + pin->rx_start_bit_low_too_short_ts = pin->ts; + pin->rx_start_bit_low_too_short_delta = delta; + } cec_pin_to_idle(pin); break; } @@ -670,6 +676,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) * and go to idle. We just pick TOTAL_LONG. */ if (v && delta > CEC_TIM_START_BIT_TOTAL_LONG) { + pin->rx_start_bit_too_long_cnt++; cec_pin_to_idle(pin); break; } @@ -677,6 +684,10 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) break; /* Start bit is too short, go back to idle */ if (delta < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_IDLE_SAMPLE) { + if (!pin->rx_start_bit_too_short_cnt++) { + pin->rx_start_bit_too_short_ts = pin->ts; + pin->rx_start_bit_too_short_delta = delta; + } cec_pin_to_idle(pin); break; } @@ -684,6 +695,7 @@ static void
[PATCHv2 4/7] cec-pin-error-inj: parse/show error injection
From: Hans VerkuilAdd support to the CEC Pin framework to parse error injection commands and to show them. The next patch will do the actual implementation of this. Signed-off-by: Hans Verkuil --- drivers/media/cec/Kconfig | 6 + drivers/media/cec/Makefile| 4 + drivers/media/cec/cec-pin-error-inj.c | 341 ++ drivers/media/cec/cec-pin-priv.h | 71 +++ drivers/media/cec/cec-pin.c | 6 + 5 files changed, 428 insertions(+) create mode 100644 drivers/media/cec/cec-pin-error-inj.c diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig index 43428cec3a01..9c2b108c613a 100644 --- a/drivers/media/cec/Kconfig +++ b/drivers/media/cec/Kconfig @@ -4,3 +4,9 @@ config MEDIA_CEC_RC depends on CEC_CORE=m || RC_CORE=y ---help--- Pass on CEC remote control messages to the RC framework. + +config CEC_PIN_ERROR_INJ + bool "Enable CEC error injection support" + depends on CEC_PIN && DEBUG_FS + ---help--- + This option enables CEC error injection using debugfs. diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile index 41ee3325e1ea..29a2ab9e77c5 100644 --- a/drivers/media/cec/Makefile +++ b/drivers/media/cec/Makefile @@ -9,4 +9,8 @@ ifeq ($(CONFIG_CEC_PIN),y) cec-objs += cec-pin.o endif +ifeq ($(CONFIG_CEC_PIN_ERROR_INJ),y) + cec-objs += cec-pin-error-inj.o +endif + obj-$(CONFIG_CEC_CORE) += cec.o diff --git a/drivers/media/cec/cec-pin-error-inj.c b/drivers/media/cec/cec-pin-error-inj.c new file mode 100644 index ..10f73def9df5 --- /dev/null +++ b/drivers/media/cec/cec-pin-error-inj.c @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + */ + +#include +#include +#include + +#include +#include "cec-pin-priv.h" + +struct cec_error_inj_cmd { + unsigned int mode_offset; + int arg_idx; + const char *cmd; +}; + +static const struct cec_error_inj_cmd cec_error_inj_cmds[] = { + { CEC_ERROR_INJ_RX_NACK_OFFSET, -1, "rx-nack" }, + { CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET, + CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, "rx-low-drive" }, + { CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, "rx-add-byte" }, + { CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, "rx-remove-byte" }, + { CEC_ERROR_INJ_RX_ARB_LOST_OFFSET, + CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, "rx-arb-lost" }, + + { CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, "tx-no-eom" }, + { CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, "tx-early-eom" }, + { CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET, + CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, "tx-add-bytes" }, + { CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, "tx-remove-byte" }, + { CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET, + CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, "tx-short-bit" }, + { CEC_ERROR_INJ_TX_LONG_BIT_OFFSET, + CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, "tx-long-bit" }, + { CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET, + CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, "tx-custom-bit" }, + { CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, "tx-short-start" }, + { CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, "tx-long-start" }, + { CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, -1, "tx-custom-start" }, + { CEC_ERROR_INJ_TX_LAST_BIT_OFFSET, + CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, "tx-last-bit" }, + { CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET, + CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, "tx-low-drive" }, + { 0, -1, NULL } +}; + +u16 cec_pin_rx_error_inj(struct cec_pin *pin) +{ + u16 cmd = CEC_ERROR_INJ_OP_ANY; + + /* Only when 18 bits have been received do we have a valid cmd */ + if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) && + pin->rx_bit >= 18) + cmd = pin->rx_msg.msg[1]; + return (pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) ? cmd : + CEC_ERROR_INJ_OP_ANY; +} + +u16 cec_pin_tx_error_inj(struct cec_pin *pin) +{ + u16 cmd = CEC_ERROR_INJ_OP_ANY; + + if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) && + pin->tx_msg.len > 1) + cmd = pin->tx_msg.msg[1]; + return (pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) ? cmd : + CEC_ERROR_INJ_OP_ANY; +} + +bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) +{ + static const char *delims = " \t\r"; + struct cec_pin *pin = adap->pin; + unsigned int i; + bool has_pos = false; + char *p = line; + char *token; + char *comma; + u64 *error; + u8 *args; + bool has_op; + u32 op; + u8 mode; + u8 pos; + u8 v; + + p = skip_spaces(p); + token = strsep(, delims); + if (!strcmp(token, "clear")) { + memset(pin->error_inj, 0, sizeof(pin->error_inj)); + pin->rx_toggle
[PATCHv2 3/7] cec-pin: create cec_pin_start_timer() function
From: Hans VerkuilThis function will be needed for injecting a custom pulse. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-pin-priv.h | 2 ++ drivers/media/cec/cec-pin.c | 21 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h index cf41c4236efd..4571a0001a9d 100644 --- a/drivers/media/cec/cec-pin-priv.h +++ b/drivers/media/cec/cec-pin-priv.h @@ -118,4 +118,6 @@ struct cec_pin { u32 timer_sum_overrun; }; +void cec_pin_start_timer(struct cec_pin *pin); + #endif diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 8e834b9f72c6..67d6ea9f56b6 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -680,6 +680,18 @@ static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr) return 0; } +void cec_pin_start_timer(struct cec_pin *pin) +{ + if (pin->state != CEC_ST_RX_IRQ) + return; + + atomic_set(>work_irq_change, CEC_PIN_IRQ_UNCHANGED); + pin->ops->disable_irq(pin->adap); + cec_pin_high(pin); + cec_pin_to_idle(pin); + hrtimer_start(>timer, ns_to_ktime(0), HRTIMER_MODE_REL); +} + static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { @@ -689,14 +701,7 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, pin->tx_msg = *msg; pin->work_tx_status = 0; pin->tx_bit = 0; - if (pin->state == CEC_ST_RX_IRQ) { - atomic_set(>work_irq_change, CEC_PIN_IRQ_UNCHANGED); - pin->ops->disable_irq(adap); - cec_pin_high(pin); - cec_pin_to_idle(pin); - hrtimer_start(>timer, ns_to_ktime(0), - HRTIMER_MODE_REL); - } + cec_pin_start_timer(pin); return 0; } -- 2.16.1
Re: [PULL] DVB-mmap Kconfig typo fix
Em Thu, 1 Mar 2018 07:55:20 -0500 Michael Ira Krufkyescreveu: > 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) There's something wrong with it: $ git pull git://linuxtv.org/mkrufky/dvb.git dvb-mmap-v3 >From git://linuxtv.org/mkrufky/dvb * branch dvb-mmap-v3 -> FETCH_HEAD fatal: Not possible to fast-forward, aborting. Anyway, I'll apply the patch from the one you sent via the ML. Regards, Mauro
Re: [PATCH 0/7] media: sun6i: Various fixes and improvements
Hi Maxime, On Mon, 5 Mar 2018 10:35:27 +0100 Maxime Ripardwrote: > Hi Yong, > > Here are a bunch of patches I came up with after testing your last > (v8) version of the CSI patches. > > There's some improvements (patches 1 and 7) and fixes for > regressions found in the v8 compared to the v7 (patches 2, 3, 4 and > 5), and one fix that we discussed for the signals polarity for the > parallel interface (patch 6). > > Feel free to squash them in your serie for the v9. OK. Thank you! I notice that your responses have not been listed in google group since February. > Thanks! > Maxime > > Maxime Ripard (7): > media: sun6i: Fill dma_pfn_offset to accomodate for the RAM offset > media: sun6i: Reduce the error level > media: sun6i: Pass the sun6i_csi_dev pointer to our helpers > media: sun6i: Don't emit a warning when the configured format isn't > found > media: sun6i: Support the YUYV format properly > media: sun6i: Invert the polarities > media: sun6i: Expose controls on the v4l2_device > > drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 85 > ++ > drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 2 + > .../media/platform/sunxi/sun6i-csi/sun6i_video.c | 6 ++ > 3 files changed, 63 insertions(+), 30 deletions(-) > > -- > 2.14.3 Thanks, Yong
[PATCH 0/4] media: sun6i: Add support for the H3 CSI controller
Hi, The H3 and H5 have a CSI controller based on the one previously found in the A31, that is currently supported by the sun6i-csi driver. Add the compatibles to the device tree bindings and to the driver to make it work properly. This obviously depends on the serie "Initial Allwinner V3s CSI Support" by Yong Deng. Let me know what you think, Maxime Maxime Ripard (2): dt-bindings: media: sun6i: Add A31 and H3 compatibles media: sun6i: Add A31 compatible Mylène Josserand (2): ARM: dts: sun8i: Add the H3/H5 CSI controller [DO NOT MERGE] ARM: dts: sun8i: Add CAM500B camera module to the Nano Pi M1+ .../devicetree/bindings/media/sun6i-csi.txt| 5 +- arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts | 85 ++ arch/arm/boot/dts/sunxi-h3-h5.dtsi | 22 ++ drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 1 + 4 files changed, 112 insertions(+), 1 deletion(-) -- 2.14.3
[PATCH 3/4] ARM: dts: sun8i: Add the H3/H5 CSI controller
From: Mylène JosserandThe H3 and H5 features the same CSI controller that was initially found on the A31. Add a DT node for it. Signed-off-by: Mylène Josserand Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sunxi-h3-h5.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 7a83b15225c7..fc538fd8282a 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -325,6 +325,13 @@ interrupt-controller; #interrupt-cells = <3>; + csi_pins: csi { + pins = "PE0", "PE1", "PE2", "PE3", "PE4", + "PE5", "PE6", "PE7", "PE8", "PE9", + "PE10", "PE11"; + function = "csi"; + }; + emac_rgmii_pins: emac0 { pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD7", "PD8", "PD9", "PD10", @@ -684,6 +691,21 @@ interrupts = ; }; + csi: camera@1cb { + compatible = "allwinner,sun8i-h3-csi", +"allwinner,sun6i-a31-csi"; + reg = <0x01cb 0x1000>; + interrupts = ; + clocks = < CLK_BUS_CSI>, +< CLK_CSI_SCLK>, +< CLK_DRAM_CSI>; + clock-names = "bus", "mod", "ram"; + resets = < RST_BUS_CSI>; + pinctrl-names = "default"; + pinctrl-0 = <_pins>; + status = "disabled"; + }; + rtc: rtc@1f0 { compatible = "allwinner,sun6i-a31-rtc"; reg = <0x01f0 0x54>; -- 2.14.3
[PATCH 4/4] [DO NOT MERGE] ARM: dts: sun8i: Add CAM500B camera module to the Nano Pi M1+
From: Mylène JosserandThe Nano Pi M1+ comes with an optional sensor based on the ov5640 from Omnivision. Enable the support for it in the DT. Signed-off-by: Mylène Josserand Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts | 85 +++ 1 file changed, 85 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts index d7b6e1ac541a..a2d1c6bb8406 100644 --- a/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-m1-plus.dts @@ -52,6 +52,37 @@ ethernet1 = _wifi; }; + cam_xclk: cam-xclk { +#clock-cells = <0>; +compatible = "fixed-clock"; +clock-frequency = <2400>; +clock-output-names = "cam-xclk"; +}; + +reg_cam_avdd: cam-avdd { +compatible = "regulator-fixed"; +regulator-name = "cam500b-avdd"; +regulator-min-microvolt = <280>; +regulator-max-microvolt = <280>; +vin-supply = <_vcc3v3>; +}; + +reg_cam_dovdd: cam-dovdd { +compatible = "regulator-fixed"; +regulator-name = "cam500b-dovdd"; +regulator-min-microvolt = <180>; +regulator-max-microvolt = <180>; +vin-supply = <_vcc3v3>; +}; + +reg_cam_dvdd: cam-dvdd { +compatible = "regulator-fixed"; +regulator-name = "cam500b-dvdd"; +regulator-min-microvolt = <150>; +regulator-max-microvolt = <150>; +vin-supply = <_vcc3v3>; +}; + reg_gmac_3v3: gmac-3v3 { compatible = "regulator-fixed"; regulator-name = "gmac-3v3"; @@ -69,6 +100,26 @@ }; }; + { +status = "okay"; + +port { +#address-cells = <1>; +#size-cells = <0>; + +/* Parallel bus endpoint */ +csi_from_ov5640: endpoint { +remote-endpoint = <_to_csi>; +bus-width = <8>; +data-shift = <2>; +hsync-active = <1>; /* Active high */ +vsync-active = <0>; /* Active low */ +data-active = <1>; /* Active high */ +pclk-sample = <1>; /* Rising */ +}; +}; +}; + { status = "okay"; }; @@ -94,6 +145,40 @@ }; }; + { + status = "okay"; + + ov5640: camera@3c { +compatible = "ovti,ov5640"; +reg = <0x3c>; +clocks = <_xclk>; +clock-names = "xclk"; + +reset-gpios = < 4 14 GPIO_ACTIVE_LOW>; +powerdown-gpios = < 4 15 GPIO_ACTIVE_HIGH>; +AVDD-supply = <_cam_avdd>; +DOVDD-supply = <_cam_dovdd>; +DVDD-supply = <_cam_dvdd>; + +port { +ov5640_to_csi: endpoint { +remote-endpoint = <_from_ov5640>; +bus-width = <8>; +data-shift = <2>; +hsync-active = <1>; /* Active high */ +vsync-active = <0>; /* Active low */ +data-active = <1>; /* Active high */ +pclk-sample = <1>; /* Rising */ +}; +}; +}; + +}; + +_pins { + bias-pull-up; +}; + { pinctrl-names = "default"; pinctrl-0 = <_pins_a>; -- 2.14.3
[PATCH 1/4] dt-bindings: media: sun6i: Add A31 and H3 compatibles
The H3 has a slightly different CSI controller (no BT656, no CCI) which looks a lot like the original A31 controller. Add a compatible for the A31, and more specific compatible the for the H3 to be used in combination for the A31. Signed-off-by: Maxime Ripard--- Documentation/devicetree/bindings/media/sun6i-csi.txt | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/sun6i-csi.txt b/Documentation/devicetree/bindings/media/sun6i-csi.txt index 2ff47a9507a6..18a5b3068b25 100644 --- a/Documentation/devicetree/bindings/media/sun6i-csi.txt +++ b/Documentation/devicetree/bindings/media/sun6i-csi.txt @@ -5,7 +5,10 @@ Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2 interface and CSI1 is used for parallel interface. Required properties: - - compatible: value must be "allwinner,sun8i-v3s-csi" + - compatible: value must be one of: +* "allwinner,sun6i-a31-csi", along with, optionally: + + "allwinner,sun8i-h3-csi" +* "allwinner,sun8i-v3s-csi" - reg: base address and size of the memory-mapped region. - interrupts: interrupt associated to this IP - clocks: phandles to the clocks feeding the CSI -- 2.14.3
[PATCH 2/4] media: sun6i: Add A31 compatible
The first device that used that IP was the A31. Add it to our list of compatibles. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 26d57e6053df..b05265f8edb5 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -916,6 +916,7 @@ static int sun6i_csi_remove(struct platform_device *pdev) } static const struct of_device_id sun6i_csi_of_match[] = { + { .compatible = "allwinner,sun6i-a31-csi", }, { .compatible = "allwinner,sun8i-v3s-csi", }, {}, }; -- 2.14.3
Re: [bug report] media: i2c: Copy tw9910 soc_camera sensor driver
On Mon, Mar 05, 2018 at 09:51:48AM +0100, jacopo mondi wrote: > In your suggested fix: > > > (((vdelay >> 8) & 0x3) << 6) | > > (((vact >> 8) & 0x3) << 4) | > > (((hedelay >> 8) & 0x3) << 2) | > > ((hact >> 8) & 0x03); > > > > Won't your analyzer in that case point out that > "15 >> 8 is zero" again? I may have been underestimating it though > It will complain, yes, but it's a pretty common false positive and I have it in the back of my head to teach the static checker to look for that situation. Eventually I will get around to it. regards, dan carpenter
Re: [PATCH 8/8] media: sun6i: Add g_parm/s_parm ioctl support
On Mon, Mar 05, 2018 at 10:35:35AM +0100, Maxime Ripard wrote: > Add a g_parm and s_parm callback in order to be able to control the sensor > framerate of the sensor. > > Signed-off-by: Maxime RipardHmmm, that patch shouldn't have been there. This is an outdated version based on Hans g_parm/s_parm rework that will not need this anymore. Maxime -- Maxime Ripard, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering https://bootlin.com signature.asc Description: PGP signature
[PATCH 7/7] media: sun6i: Expose controls on the v4l2_device
Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 8 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 2 ++ drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | 6 ++ 3 files changed, 16 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index a93bc25ff372..26d57e6053df 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -729,7 +729,15 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) media_device_init(>media_dev); + ret = v4l2_ctrl_handler_init(>ctrl_handler, 0); + if (ret) { + dev_err(csi->dev, "V4L2 controls handler init failed (%d)\n", + ret); + goto clean_media; + } + csi->v4l2_dev.mdev = >media_dev; + csi->v4l2_dev.ctrl_handler = >ctrl_handler; ret = v4l2_device_register(csi->dev, >v4l2_dev); if (ret) { dev_err(csi->dev, "V4L2 device registration failed (%d)\n", diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h index c1a1e3aefaa8..c0e8b14073d1 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h @@ -8,6 +8,7 @@ #ifndef __SUN6I_CSI_H__ #define __SUN6I_CSI_H__ +#include #include #include @@ -33,6 +34,7 @@ struct sun6i_csi_config { struct sun6i_csi { struct device *dev; + struct v4l2_ctrl_handlerctrl_handler; struct v4l2_device v4l2_dev; struct media_device media_dev; diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index c74565d15014..bf7c0d1d1d47 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -497,6 +498,11 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { .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 = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + }; /* - -- 2.14.3
[PATCH 8/8] media: sun6i: Add g_parm/s_parm ioctl support
Add a g_parm and s_parm callback in order to be able to control the sensor framerate of the sensor. Signed-off-by: Maxime Ripard--- .../media/platform/sunxi/sun6i-csi/sun6i_video.c | 29 ++ 1 file changed, 29 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index bf7c0d1d1d47..bac867004fa0 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -478,6 +478,32 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i) return 0; } +static int vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) +{ + struct sun6i_video *video = video_drvdata(file); + struct v4l2_subdev *subdev; + u32 pad; + + subdev = sun6i_video_remote_subdev(video, ); + if (subdev == NULL) + return -ENXIO; + + return v4l2_g_parm_cap(video_devdata(file), subdev, a); +} + +static int vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) +{ + struct sun6i_video *video = video_drvdata(file); + struct v4l2_subdev *subdev; + u32 pad; + + subdev = sun6i_video_remote_subdev(video, ); + if (subdev == NULL) + return -ENXIO; + + return v4l2_s_parm_cap(video_devdata(file), subdev, a); +} + static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { .vidioc_querycap= vidioc_querycap, .vidioc_enum_fmt_vid_cap= vidioc_enum_fmt_vid_cap, @@ -489,6 +515,9 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { .vidioc_s_input = vidioc_s_input, .vidioc_g_input = vidioc_g_input, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_s_parm = vidioc_s_parm, + .vidioc_reqbufs = vb2_ioctl_reqbufs, .vidioc_querybuf= vb2_ioctl_querybuf, .vidioc_qbuf= vb2_ioctl_qbuf, -- 2.14.3
[PATCH 3/7] media: sun6i: Pass the sun6i_csi_dev pointer to our helpers
Some helpers need to log some errors for example when we don't support the format passed as an argument. However, we don't currently have a dev pointer available in those functions, preventing us from using any dev_* logging function. Fix that by passing the sun6i_csi_dev structure as an argument, which itself contains a pointer to our struct device. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index b0ac8a188f92..f10c3bc2a6c5 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -225,7 +225,8 @@ int sun6i_csi_set_power(struct sun6i_csi *csi, bool enable) return 0; } -static enum csi_input_fmt get_csi_input_format(u32 mbus_code, u32 pixformat) +static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_dev *sdev, + u32 mbus_code, u32 pixformat) { /* bayer */ if ((mbus_code & 0xF000) == 0x3000) @@ -242,11 +243,12 @@ static enum csi_input_fmt get_csi_input_format(u32 mbus_code, u32 pixformat) } /* not support YUV420 input format yet */ - pr_debug("Select YUV422 as default input format of CSI.\n"); + dev_dbg(sdev->dev, "Select YUV422 as default input format of CSI.\n"); return CSI_INPUT_FORMAT_YUV422; } -static enum csi_output_fmt get_csi_output_format(u32 pixformat, u32 field) +static enum csi_output_fmt get_csi_output_format(struct sun6i_csi_dev *sdev, +u32 pixformat, u32 field) { bool buf_interlaced = false; @@ -304,7 +306,8 @@ static enum csi_output_fmt get_csi_output_format(u32 pixformat, u32 field) return CSI_FIELD_RAW_8; } -static enum csi_input_seq get_csi_input_seq(u32 mbus_code, u32 pixformat) +static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_dev *sdev, + u32 mbus_code, u32 pixformat) { switch (pixformat) { @@ -449,13 +452,16 @@ static void sun6i_csi_set_format(struct sun6i_csi_dev *sdev) CSI_CH_CFG_HFLIP_EN | CSI_CH_CFG_FIELD_SEL_MASK | CSI_CH_CFG_INPUT_SEQ_MASK); - val = get_csi_input_format(csi->config.code, csi->config.pixelformat); + val = get_csi_input_format(sdev, csi->config.code, + csi->config.pixelformat); cfg |= CSI_CH_CFG_INPUT_FMT(val); - val = get_csi_output_format(csi->config.pixelformat, csi->config.field); + val = get_csi_output_format(sdev, csi->config.pixelformat, + csi->config.field); cfg |= CSI_CH_CFG_OUTPUT_FMT(val); - val = get_csi_input_seq(csi->config.code, csi->config.pixelformat); + val = get_csi_input_seq(sdev, csi->config.code, + csi->config.pixelformat); cfg |= CSI_CH_CFG_INPUT_SEQ(val); if (csi->config.field == V4L2_FIELD_TOP) -- 2.14.3
[PATCH 1/7] media: sun6i: Fill dma_pfn_offset to accomodate for the RAM offset
The CSI controller does its DMA accesses through a DMA bus that has the RAM mapped at the address 0. The current code removes from the dma_addr_t PHYS_OFFSET, and while it works, this is an abuse of the DMA API. Instead, fill the dma_pfn_offset field in the struct device that should be used to express such an offset, and the use the dma_addr_t directly as we should. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 1e238d57..2ec33fb04632 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -563,20 +563,15 @@ int sun6i_csi_update_config(struct sun6i_csi *csi, void sun6i_csi_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 */ -#if defined(CONFIG_COMPILE_TEST) && !defined(PHYS_OFFSET) -#define PHYS_OFFSET 0 -#endif - dma_addr_t bus_addr = addr - PHYS_OFFSET; regmap_write(sdev->regmap, CSI_CH_F0_BUFA_REG, -(bus_addr + sdev->planar_offset[0]) >> 2); +(addr + sdev->planar_offset[0]) >> 2); if (sdev->planar_offset[1] != -1) regmap_write(sdev->regmap, CSI_CH_F1_BUFA_REG, -(bus_addr + sdev->planar_offset[1]) >> 2); +(addr + sdev->planar_offset[1]) >> 2); if (sdev->planar_offset[2] != -1) regmap_write(sdev->regmap, CSI_CH_F2_BUFA_REG, -(bus_addr + sdev->planar_offset[2]) >> 2); +(addr + sdev->planar_offset[2]) >> 2); } void sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable) @@ -856,6 +851,14 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, return 0; } +/* + * PHYS_OFFSET isn't available on all architectures. In order to + * accomodate for COMPILE_TEST, let's define it to something dumb. + */ +#ifndef PHYS_OFFSET +#define PHYS_OFFSET 0 +#endif + static int sun6i_csi_probe(struct platform_device *pdev) { struct sun6i_csi_dev *sdev; @@ -866,6 +869,8 @@ static int sun6i_csi_probe(struct platform_device *pdev) return -ENOMEM; sdev->dev = >dev; + /* The DMA bus has the memory mapped at 0 */ + sdev->dev->dma_pfn_offset = PHYS_OFFSET >> PAGE_SHIFT; ret = sun6i_csi_resource_request(sdev, pdev); if (ret) -- 2.14.3
[PATCH 5/7] media: sun6i: Support the YUYV format properly
Currently, if we ever start a capture using the YUYV format, the switch case in the get_csi_input_seq function will not catch it since it considers it the default case. However, that switch default also calls dev_warn to log an error, which is this case will be either an unsupported format, or the YUYV format. Obviously, the latter creates a spurious message. Make sure this isn't the case. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 9a25aad8b6b1..e0b39ea641aa 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -357,6 +357,10 @@ static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_dev *sdev, break; } break; + + case V4L2_PIX_FMT_YUYV: + return CSI_INPUT_SEQ_YUYV; + default: dev_warn(sdev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", pixformat); -- 2.14.3
[PATCH 6/7] media: sun6i: Invert the polarities
A good look at an oscilloscope and test with a camera have shown that the polarity of all signals are actually reversed compared to the polarity documented in the datasheet for the clock, HSYNC and VSYNC signals. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index e0b39ea641aa..a93bc25ff372 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -398,12 +398,12 @@ static void sun6i_csi_setup_bus(struct sun6i_csi_dev *sdev) if (flags & V4L2_MBUS_FIELD_EVEN_LOW) cfg |= CSI_IF_CFG_FIELD_POSITIVE; - if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) + if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) cfg |= CSI_IF_CFG_VREF_POL_POSITIVE; - if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) + if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) cfg |= CSI_IF_CFG_HREF_POL_POSITIVE; - if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) cfg |= CSI_IF_CFG_CLK_POL_FALLING_EDGE; break; case V4L2_MBUS_BT656: -- 2.14.3
[PATCH 4/7] media: sun6i: Don't emit a warning when the configured format isn't found
Currently the driver will call WARN when a format isn't available, resulting in a kernel backtrace in our logs. This makes it look much more serious than it should be. Replace the call to the WARN macro to a dev_warn, which will still allow us to log what happened without making it too dramatic. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index f10c3bc2a6c5..9a25aad8b6b1 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -299,7 +299,7 @@ static enum csi_output_fmt get_csi_output_format(struct sun6i_csi_dev *sdev, return buf_interlaced ? CSI_FRAME_PLANAR_YUV422 : CSI_FIELD_PLANAR_YUV422; default: - WARN(1, "Unsupported pixformat: 0x%x\n", pixformat); + dev_warn(sdev->dev, "Unsupported pixformat: 0x%x\n", pixformat); break; } @@ -330,7 +330,8 @@ static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_dev *sdev, case MEDIA_BUS_FMT_YVYU8_2X8: return CSI_INPUT_SEQ_YVYU; default: - WARN(1, "Unsupported mbus code: 0x%x\n", mbus_code); + dev_warn(sdev->dev, "Unsupported mbus code: 0x%x\n", +mbus_code); break; } break; @@ -351,12 +352,14 @@ static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_dev *sdev, case MEDIA_BUS_FMT_YVYU8_2X8: return CSI_INPUT_SEQ_YUYV; default: - WARN(1, "Unsupported mbus code: 0x%x\n", mbus_code); + dev_warn(sdev->dev, "Unsupported mbus code: 0x%x\n", +mbus_code); break; } break; default: - WARN(1, "Unsupported pixformat: 0x%x\n", pixformat); + dev_warn(sdev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", +pixformat); break; } -- 2.14.3
[PATCH 2/7] media: sun6i: Reduce the error level
The is_format_support function can be called in the standard format negociation path with a sensor, where it's expected to have not exactly the same set of formats available. Reduce the error logging level when we find a format not supported to not have a lot of spurious messages. Signed-off-by: Maxime Ripard--- drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 2ec33fb04632..b0ac8a188f92 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -111,15 +111,14 @@ bool sun6i_csi_is_format_support(struct sun6i_csi *csi, case MEDIA_BUS_FMT_YVYU8_1X16: return true; default: - dev_warn(sdev->dev, -"Unsupported mbus code: 0x%x\n", -mbus_code); + dev_dbg(sdev->dev, "Unsupported mbus code: 0x%x\n", + mbus_code); break; } break; default: - dev_warn(sdev->dev, "Unsupported pixformat: 0x%x\n", -pixformat); + dev_dbg(sdev->dev, "Unsupported pixformat: 0x%x\n", + pixformat); break; } return false; @@ -175,13 +174,13 @@ bool sun6i_csi_is_format_support(struct sun6i_csi *csi, case MEDIA_BUS_FMT_YVYU8_2X8: return true; default: - dev_warn(sdev->dev, "Unsupported mbus code: 0x%x\n", -mbus_code); + dev_dbg(sdev->dev, "Unsupported mbus code: 0x%x\n", + mbus_code); break; } break; default: - dev_warn(sdev->dev, "Unsupported pixformat: 0x%x\n", pixformat); + dev_dbg(sdev->dev, "Unsupported pixformat: 0x%x\n", pixformat); break; } -- 2.14.3
[PATCH 0/7] media: sun6i: Various fixes and improvements
Hi Yong, Here are a bunch of patches I came up with after testing your last (v8) version of the CSI patches. There's some improvements (patches 1 and 7) and fixes for regressions found in the v8 compared to the v7 (patches 2, 3, 4 and 5), and one fix that we discussed for the signals polarity for the parallel interface (patch 6). Feel free to squash them in your serie for the v9. Thanks! Maxime Maxime Ripard (7): media: sun6i: Fill dma_pfn_offset to accomodate for the RAM offset media: sun6i: Reduce the error level media: sun6i: Pass the sun6i_csi_dev pointer to our helpers media: sun6i: Don't emit a warning when the configured format isn't found media: sun6i: Support the YUYV format properly media: sun6i: Invert the polarities media: sun6i: Expose controls on the v4l2_device drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 85 ++ drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 2 + .../media/platform/sunxi/sun6i-csi/sun6i_video.c | 6 ++ 3 files changed, 63 insertions(+), 30 deletions(-) -- 2.14.3
Re: [bug report] media: i2c: Copy tw9910 soc_camera sensor driver
Hi Dan, On Mon, Mar 05, 2018 at 10:21:09AM +0300, Dan Carpenter wrote: > On Fri, Mar 02, 2018 at 03:20:16PM +0100, jacopo mondi wrote: > > Hi Dan, > > > > On Thu, Mar 01, 2018 at 12:59:54PM +0300, Dan Carpenter wrote: > > > [ I know you're just copying files, but you might have a fix for these > > > since you're looking at the code. - dan ] > > > > According to the static analyzer I should simply substitute all those > > expressions with 0s. > > I really try not to print warnings for stuff which is just white space > complaints like that. For example, Smatch ignores inconsistent NULL > checking if every caller passes non-NULL parameters or Smatch ignores > comparing unsigned with zero if it's just clamping to between zero and > max. > > > I would instead keep them for sake of readability > > and accordance with register description in the video decoder manual. > > Sorry, I did not make myself clear, see below! > > Thanks > >j > > > > [ 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)); > > I looked at the spec and it seems to me that we should doing something > like: > > (((vdelay >> 8) & 0x3) << 6) | > (((vact >> 8) & 0x3) << 4) | > (((hedelay >> 8) & 0x3) << 2) | > ((hact >> 8) & 0x03); > > > But this is the first time I've looked and it and I can't even be sure > I'm looking in the right place. That's correct. I admit I haven't looked at the register composition in detail, I just didn't want to substitute the whole expressions with 0s as it hides what values the register is composed of and that was the "accordance with register description" I mentioned... In your suggested fix: > (((vdelay >> 8) & 0x3) << 6) | > (((vact >> 8) & 0x3) << 4) | > (((hedelay >> 8) & 0x3) << 2) | > ((hact >> 8) & 0x03); > Won't your analyzer in that case point out that "15 >> 8 is zero" again? I may have been underestimating it though Thanks for noticing this! j > > regards, > dan carpenter >