Re: [PATCH v2 00/10] STV0910/STV6111 drivers, ddbridge CineS2 V7 support
Daniel Scheller wrote: From: Daniel Scheller For Linux 4.14. This series adds drivers for the ST STV0910 DVB-S/S2 demodulator ICs and the ST STV6111 DVB-S/S2 tuners, and utilises them to enable ddbridge to support the current line of Digital Devices DVB-S/S2 hardware (e.g. Cine S2 V7/V7A adapters, DuoFlex S2 V4 addon modules and maybe more, with similar components). -snip Just posting to offer a "tested by", for this particular set of patches. I have successfully been running a DD Cine S2 V7A alongside a TT S2 6400 since late March, working with Daniel to iron out minor problems during the development of this set. Testing has been done on a dedicated PVR system based on VDR 2.3.X, with kernels 4.10 and 4.12, for 3-4 hours daily without issue. Multistream support works fine and STR/CNR stats seem realistic. Many thanks to Daniel and the reviewers. Regards, Richard
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: Sat Jul 1 05:00:18 CEST 2017 media-tree git hash:2748e76ddb2967c4030171342ebdd3faa6a5e8e8 media_build git hash: bf38fb5438c3cfd90a7496e951c6902111b77587 v4l-utils git hash: 2dbbd35740180feaacd5c968a86687ba1bd6c9bb gcc version:i686-linux-gcc (GCC) 7.1.0 sparse version: v0.5.0-3553-g78b2ea6 smatch version: v0.5.0-3553-g78b2ea6 host hardware: x86_64 host os:4.9.0-164 linux-git-arm-at91: WARNINGS linux-git-arm-davinci: WARNINGS linux-git-arm-multi: WARNINGS linux-git-arm-pxa: OK linux-git-arm-stm32: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: WARNINGS linux-2.6.36.4-i686: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: OK linux-3.0.60-i686: OK linux-3.1.10-i686: OK linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: ERRORS linux-3.5.7-i686: OK linux-3.6.11-i686: OK linux-3.7.4-i686: OK linux-3.8-i686: OK linux-3.9.2-i686: OK linux-3.10.1-i686: WARNINGS linux-3.11.1-i686: ERRORS linux-3.12.67-i686: ERRORS linux-3.13.11-i686: ERRORS linux-3.14.9-i686: ERRORS linux-3.15.2-i686: ERRORS linux-3.16.7-i686: ERRORS linux-3.17.8-i686: ERRORS linux-3.18.7-i686: ERRORS linux-3.19-i686: WARNINGS linux-4.0.9-i686: WARNINGS linux-4.1.33-i686: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.3.6-i686: WARNINGS linux-4.4.22-i686: WARNINGS linux-4.5.7-i686: WARNINGS linux-4.6.7-i686: WARNINGS linux-4.7.5-i686: WARNINGS linux-4.8-i686: OK linux-4.9.26-i686: OK linux-4.10.14-i686: OK linux-4.11-i686: OK linux-4.12-rc1-i686: OK linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.37-x86_64: WARNINGS linux-3.3.8-x86_64: WARNINGS linux-3.4.27-x86_64: ERRORS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-x86_64: WARNINGS linux-3.10.1-x86_64: WARNINGS linux-3.11.1-x86_64: ERRORS linux-3.12.67-x86_64: ERRORS linux-3.13.11-x86_64: ERRORS linux-3.14.9-x86_64: ERRORS linux-3.15.2-x86_64: ERRORS linux-3.16.7-x86_64: ERRORS linux-3.17.8-x86_64: ERRORS linux-3.18.7-x86_64: ERRORS linux-3.19-x86_64: WARNINGS linux-4.0.9-x86_64: WARNINGS linux-4.1.33-x86_64: WARNINGS linux-4.2.8-x86_64: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.22-x86_64: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-x86_64: WARNINGS linux-4.7.5-x86_64: WARNINGS linux-4.8-x86_64: WARNINGS linux-4.9.26-x86_64: WARNINGS linux-4.10.14-x86_64: WARNINGS linux-4.11-x86_64: WARNINGS linux-4.12-rc1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: WARNINGS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Saturday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Saturday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
[PATCH v2 03/10] [media] dvb-frontends/stv0910: add multistream (ISI) and PLS capabilities
From: Daniel Scheller Implements stream_id filter and scrambling code setup in start() and also sets FE_CAN_MULTISTREAM in frontend_ops. This enables the driver to properly receive and handle multistream transponders, functionality has been reported working fine by testers with access to such streams, in conjunction with VDR on the userspace side. The code snippet originates from the original vendor's dddvb driver package and has been made working properly with the current in-kernel DVB core API. Signed-off-by: Daniel Scheller --- drivers/media/dvb-frontends/stv0910.c | 32 ++-- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 5a5d190298ea..b9d6a61e6017 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -120,9 +120,7 @@ struct stv { int is_vcm; u32 cur_scrambling_code; - u32 force_scrambling_code; u32 scrambling_code; - u32 default_input_stream_id; u32 last_bernumerator; u32 last_berdenominator; @@ -970,6 +968,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) s32 freq; u8 reg_dmdcfgmd; u16 symb; + u32 scrambling_code = 1; if (p->symbol_rate < 10 || p->symbol_rate > 7000) return -EINVAL; @@ -983,6 +982,28 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) init_search_param(state); + if (p->stream_id != NO_STREAM_ID_FILTER) { + /* Backwards compatibility to "crazy" API. +* PRBS X root cannot be 0, so this should always work. +*/ + if (p->stream_id & 0xff00) + scrambling_code = p->stream_id >> 8; + write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, + p->stream_id & 0xff); + write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, + 0xff); + } + + if (scrambling_code != state->cur_scrambling_code) { + write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff, + scrambling_code & 0xff); + write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff, + (scrambling_code >> 8) & 0xff); + write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff, + (scrambling_code >> 16) & 0x07); + state->cur_scrambling_code = scrambling_code; + } + if (p->symbol_rate <= 100) { /* SR <=1Msps */ state->demod_timeout = 3000; state->fec_timeout = 2000; @@ -1600,7 +1621,8 @@ static struct dvb_frontend_ops stv0910_ops = { .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | FE_CAN_QPSK | - FE_CAN_2G_MODULATION + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM }, .sleep = sleep, .release= release, @@ -1658,9 +1680,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->search_range = 1600; state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ state->receive_mode = RCVMODE_NONE; - state->cur_scrambling_code = (u32) -1; - state->force_scrambling_code = (u32) -1; - state->default_input_stream_id = (u32) -1; + state->cur_scrambling_code = (~0U); state->single = cfg->single ? 1 : 0; base = match_base(i2c, cfg->adr); -- 2.13.0
[PATCH v2 09/10] [media] ddbridge: stv0910 single demod mode module option
From: Daniel Scheller Adds a stv0910_single modparm which, when set, configures the stv0910 to run in single demodulator mode, currently intended for high bit rate testing. Signed-off-by: Daniel Scheller --- drivers/media/pci/ddbridge/ddbridge-core.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index b3fc6a875279..e762396730db 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -53,6 +53,10 @@ static int xo2_speed = 2; module_param(xo2_speed, int, 0444); MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); +static int stv0910_single; +module_param(stv0910_single, int, 0444); +MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* MSI had problems with lost interrupts, fixed but needs testing */ @@ -942,6 +946,9 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) struct stv0910_cfg cfg = stv0910_p; struct lnbh25_config lnbcfg = lnbh25_cfg; + if (stv0910_single) + cfg.single = 1; + if (type) cfg.parallel = 2; input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); -- 2.13.0
[PATCH v2 05/10] [media] dvb-frontends/stv0910: Add missing set_frontend fe-op
From: Daniel Scheller This was missing from the frontend_ops. Signed-off-by: Daniel Scheller --- drivers/media/dvb-frontends/stv0910.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 045f8f5305ab..1f2d6f5ee58a 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1670,6 +1670,7 @@ static struct dvb_frontend_ops stv0910_ops = { .sleep = sleep, .release= release, .i2c_gate_ctrl = gate_ctrl, + .set_frontend = set_parameters, .get_frontend_algo = get_algo, .get_frontend = get_frontend, .tune = tune, -- 2.13.0
[PATCH v2 00/10] STV0910/STV6111 drivers, ddbridge CineS2 V7 support
From: Daniel Scheller For Linux 4.14. This series adds drivers for the ST STV0910 DVB-S/S2 demodulator ICs and the ST STV6111 DVB-S/S2 tuners, and utilises them to enable ddbridge to support the current line of Digital Devices DVB-S/S2 hardware (e.g. Cine S2 V7/V7A adapters, DuoFlex S2 V4 addon modules and maybe more, with similar components). The two new drivers have been picked up from Digital Devices' vendor- provided dddvb driver package, as of release 0.9.29. Permission to reuse (and mainline) them was formally granted by Ralph Metzler . Drivers have been cleaned up alot (formatting fixes, dead code removal, features depending on not-yet-available API changes removed). Checkpatch complaints left: WARNING: please write a paragraph that describes the config symbol fully #39: FILE: drivers/media/dvb-frontends/Kconfig:31: +config DVB_STV0910 Not sure what checkpatch demands, since a module description exists in Kconfig... Applies to the stv6111 aswell. WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #64: new file mode 100644 See below. WARNING: 'VALIDE' may be misspelled - perhaps 'VALID'? #3314: FILE: drivers/media/dvb-frontends/stv0910_regs.h:1467: +#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 Picked from upstream. Since I'm not sure if this really is a mistake (maybe the hardware vendor really wants to name the reg like this?) so kept as-is. CamelCase and ALLCAPS are changed into kernel_kase. Patches have been proposed to the vendor driver package maintainers to keep things synced as much as possible. Patch 2 is a fix for an issue found while preparing this series for posting, and was in parallel submitted to the vendor's GIT repository. Adding myself to MAINTAINERS for stv0910 and stv6111 as I'll keep track of any upstream (vendor provided package) changes and propose them for mainline inclusion. Mauro, I assume you're the one who reviews this (since these are new drivers). It'd be very great to have this in for 4.14 to tackle the ddbridge bump for 4.15. Of course awaiting review yet, this v2 should be a good candidate for merge. Changes from v1 to v2: - CamelCase and ALLCAPS changed to kernel_case - Signal statistics acquisition refactored to comply with standards - printk* and pr_* changed to dev_* - Add myself to MAINTAINERS for stv0910 and stv6111 Daniel Scheller (10): [media] dvb-frontends: add ST STV0910 DVB-S/S2 demodulator frontend driver [media] dvb-frontends/stv0910: Fix possible buffer overflow [media] dvb-frontends/stv0910: add multistream (ISI) and PLS capabilities [media] dvb-frontends/stv0910: Add demod-only signal strength reporting [media] dvb-frontends/stv0910: Add missing set_frontend fe-op [media] dvb-frontends: add ST STV6111 DVB-S/S2 tuner frontend driver [media] ddbridge: return stv09xx id in port_has_stv0900_aa() [media] ddbridge: support for CineS2 V7(A) and DuoFlex S2 V4 hardware [media] ddbridge: stv0910 single demod mode module option [media] MAINTAINERS: add entries for stv0910 and stv6111 MAINTAINERS| 16 + drivers/media/dvb-frontends/Kconfig| 18 + drivers/media/dvb-frontends/Makefile |2 + drivers/media/dvb-frontends/stv0910.c | 1773 +++ drivers/media/dvb-frontends/stv0910.h | 32 + drivers/media/dvb-frontends/stv0910_regs.h | 4759 drivers/media/dvb-frontends/stv6111.c | 673 drivers/media/dvb-frontends/stv6111.h | 20 + drivers/media/pci/ddbridge/Kconfig |4 + drivers/media/pci/ddbridge/ddbridge-core.c | 151 +- drivers/media/pci/ddbridge/ddbridge.h |2 + 11 files changed, 7442 insertions(+), 8 deletions(-) create mode 100644 drivers/media/dvb-frontends/stv0910.c create mode 100644 drivers/media/dvb-frontends/stv0910.h create mode 100644 drivers/media/dvb-frontends/stv0910_regs.h create mode 100644 drivers/media/dvb-frontends/stv6111.c create mode 100644 drivers/media/dvb-frontends/stv6111.h -- 2.13.0
[PATCH v2 02/10] [media] dvb-frontends/stv0910: Fix possible buffer overflow
From: Daniel Scheller Fixes smatch error: drivers/media/dvb-frontends/stv0910.c:715 dvbs2_nbch() error: buffer overflow 'nbch[fectype]' 2 <= 28 Also, fixes the nbch array table by adding the DUMMY_PLF element at the top to match the enums (table element order was off by one before). Patch sent upstream aswell. Cc: Ralph Metzler Signed-off-by: Daniel Scheller --- drivers/media/dvb-frontends/stv0910.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 2f25bad7f7b8..5a5d190298ea 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -676,6 +676,7 @@ static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) { static u32 nbch[][2] = { + {0, 0}, /* DUMMY_PLF */ {16200, 3240}, /* QPSK_1_4, */ {21600, 5400}, /* QPSK_1_3, */ {25920, 6480}, /* QPSK_2_5, */ @@ -708,7 +709,7 @@ static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) if (mod_cod >= DVBS2_QPSK_1_4 && mod_cod <= DVBS2_32APSK_9_10 && fectype <= DVBS2_16K) - return nbch[fectype][mod_cod]; + return nbch[mod_cod][fectype]; return 64800; } -- 2.13.0
[PATCH v2 08/10] [media] ddbridge: support for CineS2 V7(A) and DuoFlex S2 V4 hardware
From: Daniel Scheller This adds all required glue code to support - in conjunction with the new stv0910 and stv6111 demod/tuner drivers and additionally the lnbh25 LNB controller driver - all current DVB-S/S2 hardware (bridges and flex modules) from Digital Devices like the DD CineS2 V7 and V7A, current S2 V4 DuoFlex modules, and probably all upcoming devices based on this STV0910/STV6111/LNBH25 hardware stack. Signed-off-by: Daniel Scheller --- drivers/media/pci/ddbridge/Kconfig | 4 + drivers/media/pci/ddbridge/ddbridge-core.c | 135 - drivers/media/pci/ddbridge/ddbridge.h | 2 + 3 files changed, 138 insertions(+), 3 deletions(-) diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index ffed78c2ffb4..c79a58fa5fc3 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -8,6 +8,9 @@ config DVB_DDBRIDGE select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT + select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for cards with the Digital Devices PCI express bridge: @@ -20,5 +23,6 @@ config DVB_DDBRIDGE - CineCTv6 and DuoFlex CT (STV0367-based) - CineCTv7 and DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based) - MaxA8 series + - CineS2 V7/V7A and DuoFlex S2 V4 (ST STV0910-based) Say Y if you own such a card and want to use it. diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 3fbac7bee2d4..b3fc6a875279 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -45,6 +45,9 @@ #include "stv0367_priv.h" #include "cxd2841er.h" #include "tda18212.h" +#include "stv0910.h" +#include "stv6111.h" +#include "lnbh25.h" static int xo2_speed = 2; module_param(xo2_speed, int, 0444); @@ -920,6 +923,71 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) return 0; } +static struct stv0910_cfg stv0910_p = { + .adr = 0x68, + .parallel = 1, + .rptlvl = 4, + .clk = 3000, +}; + +static struct lnbh25_config lnbh25_cfg = { + .i2c_address = 0x0c << 1, + .data2_config = LNBH25_TEN +}; + +static int demod_attach_stv0910(struct ddb_input *input, int type) +{ + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct device *dev = &input->port->dev->pdev->dev; + struct stv0910_cfg cfg = stv0910_p; + struct lnbh25_config lnbcfg = lnbh25_cfg; + + if (type) + cfg.parallel = 2; + input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); + if (!input->fe) { + cfg.adr = 0x6c; + input->fe = dvb_attach(stv0910_attach, i2c, + &cfg, (input->nr & 1)); + } + if (!input->fe) { + dev_err(dev, "No STV0910 found!\n"); + return -ENODEV; + } + + /* attach lnbh25 - leftshift by one as the lnbh25 driver expects 8bit +* i2c addresses +*/ + lnbcfg.i2c_address = (((input->nr & 1) ? 0x0d : 0x0c) << 1); + if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1); + if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + dev_err(dev, "No LNBH25 found!\n"); + return -ENODEV; + } + } + + return 0; +} + +static int tuner_attach_stv6111(struct ddb_input *input, int type) +{ + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct device *dev = &input->port->dev->pdev->dev; + struct dvb_frontend *fe; + u8 adr = (type ? 0 : 4) + ((input->nr & 1) ? 0x63 : 0x60); + + fe = dvb_attach(stv6111_attach, input->fe, i2c, adr); + if (!fe) { + fe = dvb_attach(stv6111_attach, input->fe, i2c, adr & ~4); + if (!fe) { + dev_err(dev, "No STV6111 found at 0x%02x!\n", adr); + return -ENODEV; + } + } + return 0; +} + static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, int (*start_feed)(struct dvb_demux_feed *), int (*stop_feed)(struct dvb_demux_feed *), @@ -1086,6 +1154,36 @@ static int dvb_input_attach(struct ddb_input *input) return -ENODEV; } break; + case DDB_TUNER_XO2_DVBS_STV0910: + if (demod_attach_stv0910(input, 0) < 0) +
[PATCH v2 10/10] [media] MAINTAINERS: add entries for stv0910 and stv6111
From: Daniel Scheller Signed-off-by: Daniel Scheller --- MAINTAINERS | 16 1 file changed, 16 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c4be6d4af7d2..7b85e578d238 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8246,6 +8246,22 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: drivers/media/pci/netup_unidvb/* +MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv0910* + +MEDIA DRIVERS FOR ST STV6111 TUNER ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv6111* + MEDIA INPUT INFRASTRUCTURE (V4L/DVB) M: Mauro Carvalho Chehab M: Mauro Carvalho Chehab -- 2.13.0
[PATCH v2 04/10] [media] dvb-frontends/stv0910: Add demod-only signal strength reporting
From: Daniel Scheller Original code at least has some signed/unsigned issues, resulting in values like 32dBm. Implement signal strength readout to work without asking the attached tuner, and use a lookup table instead of log calc. Values reported appear plausible, gathered from feedback from several testers. Signed-off-by: Daniel Scheller --- drivers/media/dvb-frontends/stv0910.c | 51 --- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index b9d6a61e6017..045f8f5305ab 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -136,7 +136,7 @@ struct sinit_table { struct slookup { s16 value; - u16 reg_value; + u32 reg_value; }; static inline int i2c_write(struct i2c_adapter *adap, u8 adr, @@ -328,6 +328,25 @@ struct slookup s2_sn_lookup[] = { { 510,463 }, /*C/N=51.0dB*/ }; +struct slookup padc_lookup[] = { + {0, 118000 }, /* PADC=+0dBm */ + { -100, 93600 }, /* PADC=-1dBm */ + { -200, 74500 }, /* PADC=-2dBm */ + { -300, 59100 }, /* PADC=-3dBm */ + { -400, 47000 }, /* PADC=-4dBm */ + { -500, 37300 }, /* PADC=-5dBm */ + { -600, 29650 }, /* PADC=-6dBm */ + { -700, 23520 }, /* PADC=-7dBm */ + { -900, 14850 }, /* PADC=-9dBm */ + { -1100, 9380 }, /* PADC=-11dBm */ + { -1300, 5910 }, /* PADC=-13dBm */ + { -1500, 3730 }, /* PADC=-15dBm */ + { -1700, 2354 }, /* PADC=-17dBm */ + { -1900, 1485 }, /* PADC=-19dBm */ + { -2000, 1179 }, /* PADC=-20dBm */ + { -2100, 1000 }, /* PADC=-21dBm */ +}; + /* * Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame */ @@ -568,7 +587,7 @@ static int tracking_optimization(struct stv *state) } static s32 table_lookup(struct slookup *table, - int table_size, u16 reg_value) + int table_size, u32 reg_value) { s32 value; int imin = 0; @@ -1301,9 +1320,33 @@ static int read_ber(struct dvb_frontend *fe) static void read_signal_strength(struct dvb_frontend *fe) { - /* FIXME: add signal strength algo */ + struct stv *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; + s64 strength; + u8 reg[2]; + u16 agc; + s32 padc; + s32 power = 0; + int i; - p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, reg, 2); + + agc = (((u32) reg[0]) << 8) | reg[1]; + + for (i = 0; i < 5; i += 1) { + read_regs(state, RSTV0910_P2_POWERI + state->regoff, reg, 2); + power += (u32) reg[0] * (u32) reg[0] + + (u32) reg[1] * (u32) reg[1]; + usleep_range(3000, 4000); + } + power /= 5; + + padc = table_lookup(padc_lookup, ARRAY_SIZE(padc_lookup), power) + 352; + + strength = (padc - agc); + + p->strength.stat[0].scale = FE_SCALE_DECIBEL; + p->strength.stat[0].uvalue = strength; } static int read_status(struct dvb_frontend *fe, enum fe_status *status) -- 2.13.0
[PATCH v2 07/10] [media] ddbridge: return stv09xx id in port_has_stv0900_aa()
From: Daniel Scheller The returned value is required for further evaluation of the exact demodulator chip (stv090x or stv0910). Signed-off-by: Daniel Scheller --- drivers/media/pci/ddbridge/ddbridge-core.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index cd1723e79a07..3fbac7bee2d4 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1480,10 +1480,9 @@ static int port_has_stv0900(struct ddb_port *port) return 1; } -static int port_has_stv0900_aa(struct ddb_port *port) +static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) { - u8 val; - if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) + if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) return 0; return 1; } @@ -1530,7 +1529,7 @@ static void ddb_port_probe(struct ddb_port *port) { struct ddb *dev = port->dev; char *modname = "NO MODULE"; - u8 xo2_type, xo2_id, cxd_id; + u8 xo2_type, xo2_id, cxd_id, stv_id; port->class = DDB_PORT_NONE; @@ -1622,7 +1621,7 @@ static void ddb_port_probe(struct ddb_port *port) port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBS_ST; ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); - } else if (port_has_stv0900_aa(port)) { + } else if (port_has_stv0900_aa(port, &stv_id)) { modname = "DUAL DVB-S2"; port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBS_ST_AA; -- 2.13.0
[PATCH v2 06/10] [media] dvb-frontends: add ST STV6111 DVB-S/S2 tuner frontend driver
From: Daniel Scheller This adds a frontend driver for the ST STV6111 DVB-S/S2 tuners. Like the stv0910 demod frontend driver, this driver originates from the Digital Devices' dddvb vendor driver package as of version 0.9.29, and was cleaned up aswell. No functionality had to be removed though. Any camel case has been converted to kernel_case, fixup patch has been proposed upstream. Permission to reuse and mainline the driver code was formally granted by Ralph Metzler . Signed-off-by: Daniel Scheller --- drivers/media/dvb-frontends/Kconfig | 9 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/stv6111.c | 673 ++ drivers/media/dvb-frontends/stv6111.h | 20 + 4 files changed, 703 insertions(+) create mode 100644 drivers/media/dvb-frontends/stv6111.c create mode 100644 drivers/media/dvb-frontends/stv6111.h diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 773de5e264e3..d2d3160abdf7 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -44,6 +44,15 @@ config DVB_STV6110x help A Silicon tuner that supports DVB-S and DVB-S2 modes +config DVB_STV6111 + tristate "STV6111 based tuners" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + A Silicon tuner that supports DVB-S and DVB-S2 modes + + Say Y when you want to support these frontends. + config DVB_M88DS3103 tristate "Montage Technology M88DS3103" depends on DVB_CORE && I2C && I2C_MUX diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index c302b2d07499..e8bf1d873485 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -111,6 +111,7 @@ obj-$(CONFIG_DVB_CXD2841ER) += cxd2841er.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_STV0910) += stv0910.o +obj-$(CONFIG_DVB_STV6111) += stv6111.o obj-$(CONFIG_DVB_SI2165) += si2165.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_SP2) += sp2.o diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c new file mode 100644 index ..8eb953686b43 --- /dev/null +++ b/drivers/media/dvb-frontends/stv6111.c @@ -0,0 +1,673 @@ +/* + * Driver for the ST STV6111 tuner + * + * Copyright (C) 2014 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" + +struct stv { + struct i2c_adapter *i2c; + u8 adr; + + u8 reg[11]; + u32 ref_freq; + u32 frequency; +}; + +struct slookup { + s16 value; + u16 reg_value; +}; + +static struct slookup lnagain_nf_lookup[] = { + /*Gain *100dB*/ /*Reg*/ + { 2572, 0 }, + { 2575, 1 }, + { 2580, 2 }, + { 2588, 3 }, + { 2596, 4 }, + { 2611, 5 }, + { 2633, 6 }, + { 2664, 7 }, + { 2701, 8 }, + { 2753, 9 }, + { 2816, 10 }, + { 2902, 11 }, + { 2995, 12 }, + { 3104, 13 }, + { 3215, 14 }, + { 3337, 15 }, + { 3492, 16 }, + { 3614, 17 }, + { 3731, 18 }, + { 3861, 19 }, + { 3988, 20 }, + { 4124, 21 }, + { 4253, 22 }, + { 4386, 23 }, + { 4505, 24 }, + { 4623, 25 }, + { 4726, 26 }, + { 4821, 27 }, + { 4903, 28 }, + { 4979, 29 }, + { 5045, 30 }, + { 5102, 31 } +}; + +static struct slookup lnagain_iip3_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 1548, 0 }, + { 1552, 1 }, + { 1569, 2 }, + { 1565, 3 }, + { 1577, 4 }, + { 1594, 5 }, + { 1627, 6 }, + { 1656, 7 }, + { 1700, 8 }, + { 1748, 9 }, + { 1805, 10 }, + { 1896, 11 }, + { 1995, 12 }, + { 2113, 13 }, + { 2233, 14 }, + { 2366, 15 }, + { 2543, 16 }, + { 2687, 17 }, + { 2842, 18 }, + { 2999, 19 }, + { 3167, 20 }, + { 3342, 21 }, + { 3507, 22 }, + { 3679, 23 }, + { 3827, 24 }, + { 3970, 25 }, + { 4094, 26 }, + { 4210, 27 }, + { 4308, 28 }, + { 4396, 29 }, + { 4468, 30 }, + { 4535, 31 } +}; + +static struct slookup gain_rfagc_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 4870, 0x3000 }, + { 4850, 0x3C00 }, + { 4800, 0x4500 }, + { 4750, 0x
[PATCH v2] [media] uvcvideo: Prevent heap overflow in uvc driver
The size of uvc_control_mapping is user controlled leading to a potential heap overflow in the uvc driver. This adds a check to verify the user provided size fits within the bounds of the defined buffer size. Originally-from: Richard Simmons Signed-off-by: Guenter Roeck --- Fixes CVE-2017-0627. v2: Combination of v1 with the fix suggested by Richard Simmons Perform validation after uvc_ctrl_fill_xu_info() Take into account that ctrl->info.size is in bytes Also validate mapping->size drivers/media/usb/uvc/uvc_ctrl.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index c2ee6e39fd0c..d3e3164f43fd 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2002,6 +2002,13 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, goto done; } + /* validate that the user provided bit-size and offset is valid */ + if (mapping->size > 32 || + mapping->offset + mapping->size > ctrl->info.size * 8) { + ret = -EINVAL; + goto done; + } + list_for_each_entry(map, &ctrl->info.mappings, list) { if (mapping->id == map->id) { uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " -- 2.7.4
[PATCH v2] [media] venus: fix compile-test build on non-qcom ARM platform
If QCOM_MDT_LOADER is enabled, but ARCH_QCOM is not, we run into a build error: ERROR: "qcom_mdt_load" [drivers/media/platform/qcom/venus/venus-core.ko] undefined! ERROR: "qcom_mdt_get_size" [drivers/media/platform/qcom/venus/venus-core.ko] undefined! This changes the 'select' statement again, so we only try to enable those symbols when the drivers will actually get built, and explicitly test for QCOM_MDT_LOADER to be enabled before calling into it. Fixes: 76724b30f222 ("[media] media: venus: enable building with COMPILE_TEST") Signed-off-by: Arnd Bergmann --- v2: add required IS_ENABLED() check --- drivers/media/platform/Kconfig | 4 ++-- drivers/media/platform/qcom/venus/firmware.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 1313cd533436..fb1fa0b82077 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -475,8 +475,8 @@ config VIDEO_QCOM_VENUS tristate "Qualcomm Venus V4L2 encoder/decoder driver" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST - select QCOM_MDT_LOADER if (ARM || ARM64) - select QCOM_SCM if (ARM || ARM64) + select QCOM_MDT_LOADER if ARCH_QCOM + select QCOM_SCM if ARCH_QCOM select VIDEOBUF2_DMA_SG select V4L2_MEM2MEM_DEV ---help--- diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 76edb9f60311..3794b9e3250b 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -40,7 +40,7 @@ int venus_boot(struct device *parent, struct device *fw_dev, const char *fwname) void *mem_va; int ret; - if (!qcom_scm_is_available()) + if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) || !qcom_scm_is_available()) return -EPROBE_DEFER; fw_dev->parent = parent; -- 2.9.0
Re: [PATCH RFC 2/2] dt-bindings: add binding documentation for Allwinner CSI
On Thu, Jun 29, 2017 at 10:41 PM, Chen-Yu Tsai wrote: > On Fri, Jun 30, 2017 at 5:19 AM, Rob Herring wrote: >> On Tue, Jun 27, 2017 at 07:07:34PM +0800, Yong Deng wrote: >>> Add binding documentation for Allwinner CSI. >> >> For the subject: >> >> dt-bindings: media: Add Allwinner Camera Sensor Interface (CSI) >> >> "binding documentation" is redundant. >> >>> >>> Signed-off-by: Yong Deng >>> --- >>> .../devicetree/bindings/media/sunxi-csi.txt| 51 >>> ++ >>> 1 file changed, 51 insertions(+) >>> create mode 100644 Documentation/devicetree/bindings/media/sunxi-csi.txt >>> >>> diff --git a/Documentation/devicetree/bindings/media/sunxi-csi.txt >>> b/Documentation/devicetree/bindings/media/sunxi-csi.txt >>> new file mode 100644 >>> index 000..770be0e >>> --- /dev/null >>> +++ b/Documentation/devicetree/bindings/media/sunxi-csi.txt >>> @@ -0,0 +1,51 @@ >>> +Allwinner V3s Camera Sensor 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 >>> +* ahb: 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 >>> + >>> +- ports: A ports node with endpoint definitions as defined in >>> + Documentation/devicetree/bindings/media/video-interfaces.txt. The >>> + first port should be the input endpoints, the second one the outputs >> >> Is there more than one endpoint for each port? If so, need to define >> that numbering too. > > It is possible to have multiple camera sensors connected to the same > bus. Think front and back cameras on a cell phone or tablet. > > I don't think any kind of numbering makes much sense though. The > system is free to use just one sensor at a time, or use many with > some time multiplexing scheme. What might matter to the end user > is where the camera is placed. But using the position or orientation > as a numbering scheme might not work well either. Someone may end > up using two sensors with the same orientation for stereoscopic > vision. Well, for muxing, you need to no which endpoint is which mux input, but if the muxing is at the board level, then that's really outside this binding. For stereoscopic, don't you need both sensors to work at the same time (i.e. not muxed). That would be multiple ports. When would you have 2 output endpoints though? That could be to different processing blocks, but those connections are internal, fixed, and known. So you should document the numbering in that case. Rob
[RFC PATCH] cec-*: monitor pin support
Support the new pin monitoring events API in the CEC utilities. It needs a bit more cleanup before it is ready to be merged, and I am sure that more work can be done to refine the analysis code. But this is a good first start. Signed-off-by: Hans Verkuil --- include/linux/cec.h | 8 +- utils/cec-compliance/cec-compliance.cpp | 2 + utils/cec-ctl/cec-ctl.cpp | 311 +++- utils/cec-follower/cec-follower.cpp | 2 + utils/cec-follower/cec-processing.cpp | 2 + 5 files changed, 316 insertions(+), 9 deletions(-) diff --git a/include/linux/cec.h b/include/linux/cec.h index 44579a24..d87a67b0 100644 --- a/include/linux/cec.h +++ b/include/linux/cec.h @@ -318,6 +318,7 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_MODE_FOLLOWER (0x1 << 4) #define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) #define CEC_MODE_EXCL_FOLLOWER_PASSTHRU(0x3 << 4) +#define CEC_MODE_MONITOR_PIN (0xd << 4) #define CEC_MODE_MONITOR (0xe << 4) #define CEC_MODE_MONITOR_ALL (0xf << 4) #define CEC_MODE_FOLLOWER_MSK 0xf0 @@ -338,6 +339,8 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_CAP_MONITOR_ALL(1 << 5) /* Hardware can use CEC only if the HDMI HPD pin is high. */ #define CEC_CAP_NEEDS_HPD (1 << 6) +/* Hardware can monitor CEC pin transitions */ +#define CEC_CAP_MONITOR_PIN(1 << 7) /** * struct cec_caps - CEC capabilities structure. @@ -405,8 +408,11 @@ struct cec_log_addrs { * didn't empty the message queue in time */ #define CEC_EVENT_LOST_MSGS2 +#define CEC_EVENT_PIN_LOW 3 +#define CEC_EVENT_PIN_HIGH 4 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) +#define CEC_EVENT_FL_DROPPED_EVENTS(1 << 1) /** * struct cec_event_state_change - used when the CEC adapter changes state. @@ -419,7 +425,7 @@ struct cec_event_state_change { }; /** - * struct cec_event_lost_msgs - tells you how many messages were lost due. + * struct cec_event_lost_msgs - tells you how many messages were lost. * @lost_msgs: how many messages were lost. */ struct cec_event_lost_msgs { diff --git a/utils/cec-compliance/cec-compliance.cpp b/utils/cec-compliance/cec-compliance.cpp index 0dd2a54f..1badf8be 100644 --- a/utils/cec-compliance/cec-compliance.cpp +++ b/utils/cec-compliance/cec-compliance.cpp @@ -261,6 +261,8 @@ static std::string caps2s(unsigned caps) s += "\t\tMonitor All\n"; if (caps & CEC_CAP_NEEDS_HPD) s += "\t\tNeeds HPD\n"; + if (caps & CEC_CAP_MONITOR_PIN) + s += "\t\tMonitor Pin\n"; return s; } diff --git a/utils/cec-ctl/cec-ctl.cpp b/utils/cec-ctl/cec-ctl.cpp index 80d4014a..7b23ab7e 100644 --- a/utils/cec-ctl/cec-ctl.cpp +++ b/utils/cec-ctl/cec-ctl.cpp @@ -668,6 +668,7 @@ enum Option { OptReplyToFollowers, OptTimeout, OptMonitorTime, + OptMonitorPin, OptListUICommands, OptRcTVProfile1, OptRcTVProfile2, @@ -730,6 +731,7 @@ static struct option long_options[] = { { "clear", no_argument, 0, OptClear }, { "monitor", no_argument, 0, OptMonitor }, { "monitor-all", no_argument, 0, OptMonitorAll }, + { "monitor-pin", no_argument, 0, OptMonitorPin }, { "monitor-time", required_argument, 0, OptMonitorTime }, { "no-reply", no_argument, 0, OptNoReply }, { "to", required_argument, 0, OptTo }, @@ -786,6 +788,7 @@ static void usage(void) " -C, --clear Clear all logical addresses\n" " -m, --monitorMonitor CEC traffic\n" " -M, --monitor-allMonitor all CEC traffic\n" + " --monitor-pinMonitor low-level CEC pin\n" " --monitor-time=Monitor for seconds (default is forever)\n" " -n, --no-reply Don't wait for a reply\n" " -t, --to=Send message to the given logical address\n" @@ -857,6 +860,8 @@ static std::string caps2s(unsigned caps) s += "\t\tMonitor All\n"; if (caps & CEC_CAP_NEEDS_HPD) s += "\t\tNeeds HPD\n"; + if (caps & CEC_CAP_MONITOR_PIN) + s += "\t\tMonitor Pin\n"; return s; } @@ -1224,11 +1229,231 @@ static void log_unknown_msg(const struct cec_msg *msg) } } +enum cec_state { + CEC_ST_IDLE, + CEC_ST_RECEIVE_START_BIT, + CEC_ST_RECEIVING_DATA, +}; + +/* All timings are in microseconds */ +#define CEC_TIM_MARGIN 100 + +#define CEC_TIM_START_BIT_LOW 3700 +#define CEC_TIM_START_BIT_LOW_MIN 3500 +#define CEC_TIM_START_BIT_LOW_MAX 3900 +#define CEC_TIM_START_BIT_TOTAL4500 +#define CEC_TIM_START_BIT_TOTAL_MIN4300 +#define CEC_TIM_START_BIT_TOTAL_MAX4700 + +#define CEC_TIM_DATA_BIT_0_LOW
[RFC PATCH 02/12] cec: add *_ts variants for transmit_done/received_msg
From: Hans Verkuil Currently the transmit_(attempt_)done and received_msg functions set the timestamp themselves. For the upcoming low-level pin API we need to pass this as an argument instead. So make _ts variants that allow the caller to specify the timestamp. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-adap.c | 35 +++ include/media/cec.h | 32 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 644ce82ea2ed..b3163716d95f 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -471,12 +471,12 @@ int cec_thread_func(void *_adap) /* * Called by the CEC adapter if a transmit finished. */ -void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, - u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt) +void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, + u8 error_cnt, ktime_t ts) { struct cec_data *data; struct cec_msg *msg; - u64 ts = ktime_get_ns(); dprintk(2, "%s: status %02x\n", __func__, status); mutex_lock(&adap->lock); @@ -496,7 +496,7 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, /* Drivers must fill in the status! */ WARN_ON(status == 0); - msg->tx_ts = ts; + msg->tx_ts = ktime_to_ns(ts); msg->tx_status |= status; msg->tx_arb_lost_cnt += arb_lost_cnt; msg->tx_nack_cnt += nack_cnt; @@ -559,25 +559,26 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, unlock: mutex_unlock(&adap->lock); } -EXPORT_SYMBOL_GPL(cec_transmit_done); +EXPORT_SYMBOL_GPL(cec_transmit_done_ts); -void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) +void cec_transmit_attempt_done_ts(struct cec_adapter *adap, + u8 status, ktime_t ts) { switch (status) { case CEC_TX_STATUS_OK: - cec_transmit_done(adap, status, 0, 0, 0, 0); + cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts); return; case CEC_TX_STATUS_ARB_LOST: - cec_transmit_done(adap, status, 1, 0, 0, 0); + cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts); return; case CEC_TX_STATUS_NACK: - cec_transmit_done(adap, status, 0, 1, 0, 0); + cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts); return; case CEC_TX_STATUS_LOW_DRIVE: - cec_transmit_done(adap, status, 0, 0, 1, 0); + cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts); return; case CEC_TX_STATUS_ERROR: - cec_transmit_done(adap, status, 0, 0, 0, 1); + cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts); return; default: /* Should never happen */ @@ -585,7 +586,7 @@ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) return; } } -EXPORT_SYMBOL_GPL(cec_transmit_attempt_done); +EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts); /* * Called when waiting for a reply times out. @@ -716,7 +717,8 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, if (msg->timeout) dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", - __func__, msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); + __func__, msg->len, msg->msg, msg->reply, + !block ? ", nb" : ""); else dprintk(2, "%s: %*ph%s\n", __func__, msg->len, msg->msg, !block ? " (nb)" : ""); @@ -913,7 +915,8 @@ static const u8 cec_msg_size[256] = { }; /* Called by the CEC adapter if a message is received */ -void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) +void cec_received_msg_ts(struct cec_adapter *adap, +struct cec_msg *msg, ktime_t ts) { struct cec_data *data; u8 msg_init = cec_msg_initiator(msg); @@ -941,7 +944,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) cec_has_log_addr(adap, msg_init)) return; - msg->rx_ts = ktime_get_ns(); + msg->rx_ts = ktime_to_ns(ts); msg->rx_status = CEC_RX_STATUS_OK; msg->sequence = msg->reply = msg->timeout = 0; msg->tx_status = 0; @@ -1106,7 +1109,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) */ cec_receive_notify(adap, msg, is_reply); } -EXPORT_SYMBOL_GPL(cec_received_msg); +EXPORT_SYMBOL_GPL(cec_received_msg_ts); /* Logical Address Handling */ diff --git a/include/media/cec.h b/include/media/cec.h index e32b0e1a8
[RFC PATCH 05/12] linux/cec.h: add pin monitoring API support
From: Hans Verkuil Add support for low-level CEC pin monitoring. This adds a new monitor mode, a new capability and two new events. Signed-off-by: Hans Verkuil --- include/uapi/linux/cec.h | 5 + 1 file changed, 5 insertions(+) diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index 44579a24f95d..bba73f33c8aa 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -318,6 +318,7 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_MODE_FOLLOWER (0x1 << 4) #define CEC_MODE_EXCL_FOLLOWER (0x2 << 4) #define CEC_MODE_EXCL_FOLLOWER_PASSTHRU(0x3 << 4) +#define CEC_MODE_MONITOR_PIN (0xd << 4) #define CEC_MODE_MONITOR (0xe << 4) #define CEC_MODE_MONITOR_ALL (0xf << 4) #define CEC_MODE_FOLLOWER_MSK 0xf0 @@ -338,6 +339,8 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) #define CEC_CAP_MONITOR_ALL(1 << 5) /* Hardware can use CEC only if the HDMI HPD pin is high. */ #define CEC_CAP_NEEDS_HPD (1 << 6) +/* Hardware can monitor CEC pin transitions */ +#define CEC_CAP_MONITOR_PIN(1 << 7) /** * struct cec_caps - CEC capabilities structure. @@ -405,6 +408,8 @@ struct cec_log_addrs { * didn't empty the message queue in time */ #define CEC_EVENT_LOST_MSGS2 +#define CEC_EVENT_PIN_LOW 3 +#define CEC_EVENT_PIN_HIGH 4 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) -- 2.11.0
[RFC PATCH 06/12] cec: document the new CEC pin capability, events and mode
From: Hans Verkuil Document CEC_CAP_MONITOR_PIN, CEC_EVENT_PIN_LOW/HIGH and CEC_MODE_MONITOR_PIN. Signed-off-by: Hans Verkuil --- Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst | 7 +++ Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 20 Documentation/media/uapi/cec/cec-ioc-g-mode.rst | 19 +-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst index 6d7bf7bef3eb..882d6e025747 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst @@ -121,6 +121,13 @@ returns the information to the application. The ioctl never fails. high. This makes it impossible to use CEC to wake up displays that set the HPD pin low when in standby mode, but keep the CEC bus alive. +* .. _`CEC-CAP-MONITOR-PIN`: + + - ``CEC_CAP_MONITOR_PIN`` + - 0x0080 + - The CEC hardware can monitor CEC pin changes from low to high voltage +and vice versa. When in pin monitoring mode the application will + receive ``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events. diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 4d3570c2e0b3..3e2cd5fefd38 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -146,6 +146,20 @@ it is guaranteed that the state did change in between the two events. - 2 - Generated if one or more CEC messages were lost because the application didn't dequeue CEC messages fast enough. +* .. _`CEC-EVENT-PIN-LOW`: + + - ``CEC_EVENT_PIN_LOW`` + - 3 + - Generated if the CEC pin goes from a high voltage to a low voltage. +Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. +* .. _`CEC-EVENT-PIN-HIGH`: + + - ``CEC_EVENT_PIN_HIGH`` + - 4 + - Generated if the CEC pin goes from a low voltage to a high voltage. +Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| @@ -165,6 +179,12 @@ it is guaranteed that the state did change in between the two events. opened. See the table above for which events do this. This allows applications to learn the initial state of the CEC adapter at open() time. +* .. _`CEC-EVENT-FL-DROPPED-EVENTS`: + + - ``CEC_EVENT_FL_DROPPED_EVENTS`` + - 2 + - Set if one or more events of the given event type have been dropped. +This is an indication that the application cannot keep up. diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst index 664f0d47bbcd..3e907c74338f 100644 --- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst @@ -149,13 +149,28 @@ Available follower modes are: code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, the ``EINVAL`` error code is returned in that case. +* .. _`CEC-MODE-MONITOR-PIN`: + + - ``CEC_MODE_MONITOR_PIN`` + - 0xd0 + - Put the file descriptor into pin monitoring mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR `, + otherwise the ``EINVAL`` error code will be returned. + This mode requires that the :ref:`CEC_CAP_MONITOR_PIN ` + capability is set, otherwise the ``EINVAL`` error code is returned. + While in pin monitoring mode this file descriptor can receive the + ``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events to see the + low-level CEC pin transitions. This is very useful for debugging. + This mode is only allowed if the process has the ``CAP_NET_ADMIN`` + capability. If that is not set, then the ``EPERM`` error code is returned. * .. _`CEC-MODE-MONITOR`: - ``CEC_MODE_MONITOR`` - 0xe0 - Put the file descriptor into monitor mode. Can only be used in - combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error - code will be returned. In monitor mode all messages this CEC + combination with :ref:`CEC_MODE_NO_INITIATOR `,i + otherwise the ``EINVAL`` error code will be returned. + In monitor mode all messages this CEC device transmits and all messages it receives (both broadcast messages and directed messages for one its logical addresses) will be reported. This is very useful for debugging. This is only -- 2.11.0
[RFC PATCH 08/12] cec: add core support for low-level CEC pin monitoring
From: Hans Verkuil Add support for the new MONITOR_PIN mode. Add the cec_pin_event function that the CEC pin code will call to queue pin change events. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-adap.c | 16 drivers/media/cec/cec-api.c | 15 +-- include/media/cec.h | 11 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 58df9e6a4c2d..f468ee32d670 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -153,6 +153,22 @@ static void cec_queue_event(struct cec_adapter *adap, mutex_unlock(&adap->devnode.lock); } +/* Notify userspace that the CEC pin changed state at the given time. */ +void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts) +{ + struct cec_event ev = { + .event = is_high ? CEC_EVENT_PIN_HIGH : CEC_EVENT_PIN_LOW, + }; + struct cec_fh *fh; + + mutex_lock(&adap->devnode.lock); + list_for_each_entry(fh, &adap->devnode.fhs, list) + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); + mutex_unlock(&adap->devnode.lock); +} +EXPORT_SYMBOL_GPL(cec_queue_pin_event); + /* * Queue a new message for this filehandle. * diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 48bef1c718ad..14279958dca1 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -370,6 +370,10 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, !(adap->capabilities & CEC_CAP_MONITOR_ALL)) return -EINVAL; + if (mode_follower == CEC_MODE_MONITOR_PIN && + !(adap->capabilities & CEC_CAP_MONITOR_PIN)) + return -EINVAL; + /* Follower modes should always be able to send CEC messages */ if ((mode_initiator == CEC_MODE_NO_INITIATOR || !(adap->capabilities & CEC_CAP_TRANSMIT)) && @@ -378,11 +382,11 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, return -EINVAL; /* Monitor modes require CEC_MODE_NO_INITIATOR */ - if (mode_initiator && mode_follower >= CEC_MODE_MONITOR) + if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) return -EINVAL; /* Monitor modes require CAP_NET_ADMIN */ - if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN)) + if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN)) return -EPERM; mutex_lock(&adap->lock); @@ -421,8 +425,13 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (fh->mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt--; + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + adap->monitor_pin_cnt--; if (mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt++; + if (mode_follower == CEC_MODE_MONITOR_PIN) { + adap->monitor_pin_cnt++; + } if (mode_follower == CEC_MODE_EXCL_FOLLOWER || mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { adap->passthrough = @@ -566,6 +575,8 @@ static int cec_release(struct inode *inode, struct file *filp) } if (fh->mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt--; + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + adap->monitor_pin_cnt--; if (fh->mode_follower == CEC_MODE_MONITOR_ALL) cec_monitor_all_cnt_dec(adap); mutex_unlock(&adap->lock); diff --git a/include/media/cec.h b/include/media/cec.h index 6cc862af74e5..d983960b37ad 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -177,6 +177,7 @@ struct cec_adapter { bool is_configuring; bool is_configured; u32 monitor_all_cnt; + u32 monitor_pin_cnt; u32 follower_cnt; struct cec_fh *cec_follower; struct cec_fh *cec_initiator; @@ -272,6 +273,16 @@ static inline void cec_received_msg(struct cec_adapter *adap, } /** + * cec_queue_pin_event() - queue a pin event with a given timestamp. + * + * @adap: pointer to the cec adapter + * @is_high: when true the pin is high, otherwise it is low + * @ts:the timestamp for this event + * + */ +void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts); + +/** * cec_get_edid_phys_addr() - find and return the physical address * * @edid: pointer to the EDID data -- 2.11.0
[RFC PATCH 04/12] cec-core.rst: document the adap_free callback
From: Hans Verkuil Document what this callback does. Signed-off-by: Hans Verkuil --- Documentation/media/kapi/cec-core.rst | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 8a65c69ed071..6ea2c9c80182 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -107,6 +107,7 @@ your driver: int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level callbacks */ ... @@ -181,8 +182,13 @@ To log the current CEC hardware status: .. c:function:: void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); -This optional callback can be used to show the status of the CEC hardware. -The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status +To free any resources when the adapter is deleted: + +.. c:function:: + void (*adap_free)(struct cec_adapter *adap); + +This optional callback can be used to free any resources that might have been +allocated by the driver. It's called from cec_delete_adapter. Your adapter driver will also have to react to events (typically interrupt -- 2.11.0
[RFC PATCH 03/12] cec: add adap_free op
From: Hans Verkuil This is needed for CEC adapters that allocate resources that have to be freed before the cec_adapter is deleted. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-core.c | 2 ++ include/media/cec.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index b516d599d6c4..2e5765344d07 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -374,6 +374,8 @@ void cec_delete_adapter(struct cec_adapter *adap) kthread_stop(adap->kthread); if (adap->kthread_config) kthread_stop(adap->kthread_config); + if (adap->ops->adap_free) + adap->ops->adap_free(adap); #ifdef CONFIG_MEDIA_CEC_RC rc_free_device(adap->rc); #endif diff --git a/include/media/cec.h b/include/media/cec.h index e1e60dbb66c3..37768203572d 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -114,6 +114,7 @@ struct cec_adap_ops { int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); -- 2.11.0
[RFC PATCH 11/12] MAINTAINERS: add cec-gpio entry
From: Hans Verkuil Add an entry for the CEC GPIO driver. Signed-off-by: Hans Verkuil --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c4be6d4af7d2..cffc77c8facf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3140,6 +3140,14 @@ F: include/uapi/linux/cec.h F: include/uapi/linux/cec-funcs.h F: Documentation/devicetree/bindings/media/cec.txt +CEC GPIO DRIVER +M: Hans Verkuil +L: linux-media@vger.kernel.org +T: git git://linuxtv.org/media_tree.git +W: http://linuxtv.org +S: Supported +F: drivers/media/platform/cec-gpio/ + CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann L: linuxppc-...@lists.ozlabs.org -- 2.11.0
[RFC PATCH 12/12] rpi: add cec-gpio support to dts
From: Hans Verkuil A simple example of the use of cec-gpio for Raspberry Pi 2B and 3. Signed-off-by: Hans Verkuil --- arch/arm/boot/dts/bcm2836-rpi-2-b.dts| 5 + arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 5 + 2 files changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts index bf19e8cfb9e6..8cb82a70f33d 100644 --- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts @@ -24,6 +24,11 @@ linux,default-trigger = "default-on"; }; }; + + cec-gpio { + compatible = "cec-gpio"; + gpio = <&gpio 4 GPIO_ACTIVE_HIGH>; + }; }; &gpio { diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts index c309633a1e87..ac753786444c 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts @@ -17,6 +17,11 @@ gpios = <&gpio 47 0>; }; }; + + cec-gpio { + compatible = "cec-gpio"; + gpio = <&gpio 4 GPIO_ACTIVE_HIGH>; + }; }; &uart1 { -- 2.11.0
[RFC PATCH 10/12] cec-gpio: add CEC GPIO driver
From: Hans Verkuil Add a simple CEC GPIO driver that sits on top of the cec-pin framework. Mostly done, but is missing optional cec-notifier integration (that's currently commented out). Signed-off-by: Hans Verkuil --- drivers/media/platform/Kconfig | 10 ++ drivers/media/platform/Makefile| 2 + drivers/media/platform/cec-gpio/Makefile | 1 + drivers/media/platform/cec-gpio/cec-gpio.c | 214 + 4 files changed, 227 insertions(+) create mode 100644 drivers/media/platform/cec-gpio/Makefile create mode 100644 drivers/media/platform/cec-gpio/cec-gpio.c diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 1313cd533436..f570a2b3749c 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -536,6 +536,16 @@ menuconfig CEC_PLATFORM_DRIVERS if CEC_PLATFORM_DRIVERS +config CEC_GPIO + tristate "Generic GPIO-based CEC driver" + depends on PREEMPT + select CEC_CORE + select CEC_PIN + ---help--- + This is a generic GPIO-based CEC driver. + The CEC bus is present in the HDMI connector and enables communication + between compatible devices. + config VIDEO_SAMSUNG_S5P_CEC tristate "Samsung S5P CEC driver" depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 9beadc760467..d01cc1886ad1 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -26,6 +26,8 @@ obj-$(CONFIG_VIDEO_CODA) += coda/ obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o +obj-$(CONFIG_CEC_GPIO) += cec-gpio/ + obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE)+= m2m-deinterlace.o obj-$(CONFIG_VIDEO_MUX)+= video-mux.o diff --git a/drivers/media/platform/cec-gpio/Makefile b/drivers/media/platform/cec-gpio/Makefile new file mode 100644 index ..e82b258afa55 --- /dev/null +++ b/drivers/media/platform/cec-gpio/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CEC_GPIO) += cec-gpio.o diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c new file mode 100644 index ..dd08095d3ded --- /dev/null +++ b/drivers/media/platform/cec-gpio/cec-gpio.c @@ -0,0 +1,214 @@ +/* + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct cec_gpio { + struct cec_adapter *adap; + struct device *dev; + int gpio; + //struct cec_notifier *notifier; + int irq; + boolis_low; + boolhave_irq; +}; + +static bool cec_gpio_read(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->is_low) + return false; + return gpio_get_value(cec->gpio); +} + +static void cec_gpio_high(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (!cec->is_low) + return; + cec->is_low = false; + gpio_direction_input(cec->gpio); +} + +static void cec_gpio_low(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->is_low) + return; + if (WARN_ON_ONCE(cec->have_irq)) + free_irq(cec->irq, cec); + cec->have_irq = false; + cec->is_low = true; + gpio_direction_output(cec->gpio, 0); +} + +static irqreturn_t cec_gpio_irq_handler(int irq, void *priv) +{ + struct cec_gpio *cec = priv; + + cec_pin_changed(cec->adap, gpio_get_value(cec->gpio)); + return IRQ_HANDLED; +} + +static bool cec_gpio_enable_irq(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (request_irq(cec->irq, cec_gpio_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + adap->name, cec)) + return false; + cec->have_irq = true; + return true; +} + +static void cec_gpio_disable_irq(struct cec_adapter *adap) +{ + struct cec_gpio *c
[RFC PATCH 09/12] cec-pin: add low-level pin hardware support
From: Hans Verkuil Add support for CEC hardware that relies on low-level pin polling or GPIO interrupts. One example is the Allwinner SoC. But any GPIO-based CEC implementation can use this as well. A GPIO implementation is very suitable as well for debugging: it can use interrupts to detect state changes and report it. Userspace can then verify if the bus traffic is correct. This also makes error injection possible. The disadvantage is that it is hard to get the timings right since linux isn't a hard realtime system. In general on an idle system it works quite well, but under load the timer will miss its mark every so often. The debugfs file /sys/kernel/debug/cec/cecX/status gives some statistics with respect to the timer overruns. When the adapter is unconfigured and the low-level driver supports interrupts, then the interrupt will be used to detect changes. This should be quite accurate. But when the adapter is configured a hrtimer has to be used. The hrtimer implements a state machine where for each state the code will read the bus or drive the bus and go on to the next state. It will re-arm the timer with a delay based on the next state. Signed-off-by: Hans Verkuil --- drivers/media/Kconfig | 3 + drivers/media/cec/Makefile | 4 + drivers/media/cec/cec-api.c | 10 + drivers/media/cec/cec-pin.c | 784 include/media/cec-pin.h | 113 +++ include/media/cec.h | 4 + 6 files changed, 918 insertions(+) create mode 100644 drivers/media/cec/cec-pin.c create mode 100644 include/media/cec-pin.h diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 55d9c2b82b7e..94d4e7759127 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -8,6 +8,9 @@ config CEC_CORE config CEC_NOTIFIER bool +config CEC_PIN + bool + menuconfig MEDIA_SUPPORT tristate "Multimedia support" depends on HAS_IOMEM diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile index eaf408e64669..3353c1741961 100644 --- a/drivers/media/cec/Makefile +++ b/drivers/media/cec/Makefile @@ -4,4 +4,8 @@ ifeq ($(CONFIG_CEC_NOTIFIER),y) cec-objs += cec-notifier.o endif +ifeq ($(CONFIG_CEC_PIN),y) + cec-objs += cec-pin.o +endif + obj-$(CONFIG_CEC_CORE) += cec.o diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 14279958dca1..8dd16e263452 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -30,6 +30,7 @@ #include #include +#include #include "cec-priv.h" static inline struct cec_devnode *cec_devnode_data(struct file *filp) @@ -430,6 +431,15 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt++; if (mode_follower == CEC_MODE_MONITOR_PIN) { +#ifdef CONFIG_CEC_PIN + struct cec_event ev = { + .flags = CEC_EVENT_FL_INITIAL_STATE, + }; + + ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_HIGH : + CEC_EVENT_PIN_LOW; + cec_queue_event_fh(fh, &ev, 0); +#endif adap->monitor_pin_cnt++; } if (mode_follower == CEC_MODE_EXCL_FOLLOWER || diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c new file mode 100644 index ..276d5c8cd378 --- /dev/null +++ b/drivers/media/cec/cec-pin.c @@ -0,0 +1,784 @@ +/* + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include + +/* All timings are in microseconds */ + +/* start bit timings */ +#define CEC_TIM_START_BIT_LOW 3700 +#define CEC_TIM_START_BIT_LOW_MIN 3500 +#define CEC_TIM_START_BIT_LOW_MAX 3900 +#define CEC_TIM_START_BIT_TOTAL4500 +#define CEC_TIM_START_BIT_TOTAL_MIN4300 +#define CEC_TIM_START_BIT_TOTAL_MAX4700 + +/* data bit timings */ +#define CEC_TIM_DATA_BIT_0_LOW 1500 +#define CEC_TIM_DATA_BIT_0_LOW_MIN 1300 +#define CEC_TIM_DATA_BIT_0_LOW_MAX 1700 +#define CEC_TIM_DATA_BIT_1_LOW 600 +#define CEC_TIM_DATA_BIT_1_LOW_MIN 400 +#define CEC_TIM_DATA_BIT_1_LOW_MAX 800 +#define
[RFC PATCH 00/12] cec: add low-level pin driver/monitoring
From: Hans Verkuil This patch series is something I have been working on for some time now. The initial use-case was for the Allwinner A10 SoC which supported CEC but only by polling the CEC bus. It turned out that being able to access the CEC bus at such a low-level was also ideal for debugging CEC problems (bad timings etc) and to do error injection. Since these old Allwinner SoCs aren't all that easy to get these days I decided to try to use the same code but using a GPIO pin on a Raspberry Pi (tested with both 2B and 3) since those are widely available. Of course, the cec-gpio driver can be used with any pull-up gpio on any SoC. This patch series first makes some small changes in the CEC framework (patches 1-4) to prepare for this CEC pin support. Patch 5-6 adds the new API elements and documents it. Patch 7 reworks the CEC core event handling. Patch 8 adds pin monitoring support (allows userspace to see all CEC pin transitions as they happen). Patch 9 adds the core cec-pin implementation that translates low-level pin transitions into valid CEC messages. Basically this does what any SoC with a proper CEC hardware implementation does. Patch 10-11 add a little cec-gpio driver that sits on top of the cec-pin code. Note that patch 10 is not quite complete: I want to add optional cec-notifier support as well so the gpio pin can be 'connected' to the HDMI controller and be notified when the physical address changes. Patch 12 adds an example dts snippet with support for cec-gpio to the Rpi dts. In the final version this should change to a Documentation/devicetree/bindings/media/cec-gpio.txt file. Patches 1-9 are basically ready for 4.14, although I will probably clean up a few things in cec-pin.c/h. Maxime, this series does not contain the A10 support yet. I have that in this (somewhat old) branch: https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=cubie-cec-pin If you look in sun4i_hdmi_enc.c: https://git.linuxtv.org/hverkuil/media_tree.git/tree/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c?h=cubie-cec-pin and search for 'cec' you'll see that the CEC implementation is now tiny since all the work is now done in cec-pin.c. All that this driver needs to implement are the pin read/low/high ops which are literally one-liners. Once 4.13-rc1 is released I will rebase this patch series and add patches for the sun4i CEC driver. Eric, don't confuse this with the real Rpi CEC driver. As I mentioned to you in another email I'm waiting for 4.13-rc1 to be released and then I'll clean up my rpi patch series and repost for inclusion in 4.14. This gpio driver in combination with a Raspberry Pi is ideal for debugging since the rpi is so widely available. I will post a patch to the cec-ctl utility that supports this new pin monitoring API separately. It is able to fully analyze the CEC traffic, and esp. when using the GPIO interrupt it is also very accurate. And much, much cheaper than a full fledged CEC analyzer. And for the record, I've used this quite successfully at Cisco while debugging CEC issues :-) For those who are interested: some code for error injection is available here: https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=cec-error-inj But it needs a lot more work, esp. with regards to the API design. So this is not planned for 4.14 but more likely 4.15. Regards, Hans Hans Verkuil (12): cec: improve transmit timeout logging cec: add *_ts variants for transmit_done/received_msg cec: add adap_free op cec-core.rst: document the adap_free callback linux/cec.h: add pin monitoring API support cec: document the new CEC pin capability, events and mode cec: rework the cec event handling cec: add core support for low-level CEC pin monitoring cec-pin: add low-level pin hardware support cec-gpio: add CEC GPIO driver MAINTAINERS: add cec-gpio entry rpi: add cec-gpio support to dts Documentation/media/kapi/cec-core.rst | 10 +- .../media/uapi/cec/cec-ioc-adap-g-caps.rst | 7 + Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 20 + Documentation/media/uapi/cec/cec-ioc-g-mode.rst| 19 +- MAINTAINERS| 8 + arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 5 + arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 5 + drivers/media/Kconfig | 3 + drivers/media/cec/Makefile | 4 + drivers/media/cec/cec-adap.c | 196 -- drivers/media/cec/cec-api.c| 73 +- drivers/media/cec/cec-core.c | 2 + drivers/media/cec/cec-pin.c| 784 + drivers/media/platform/Kconfig | 10 + drivers/media/platform/Makefile| 2 + drivers/media/platform/cec-gpio/Makefile | 1 + drivers/media/platform/cec-gpio/cec-gpio.c | 214 ++ include/media/cec-pin.h| 1
[RFC PATCH 07/12] cec: rework the cec event handling
From: Hans Verkuil Event handling was always fairly simplistic since there were only two events. With the addition of pin events this needed to be redesigned. The state_change and lost_msgs events are now core events with the guarantee that the last state is always available. The new pin events are a queue of events (up to 64 for each event) and the oldest event will be dropped if the application cannot keep up. Lost events are marked with a new event flag. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-adap.c | 128 +-- drivers/media/cec/cec-api.c | 48 +++- include/media/cec.h | 14 - include/uapi/linux/cec.h | 3 +- 4 files changed, 124 insertions(+), 69 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index b3163716d95f..58df9e6a4c2d 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -78,42 +78,62 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr * Queue a new event for this filehandle. If ts == 0, then set it * to the current time. * - * The two events that are currently defined do not need to keep track - * of intermediate events, so no actual queue of events is needed, - * instead just store the latest state and the total number of lost - * messages. - * - * Should new events be added in the future that require intermediate - * results to be queued as well, then a proper queue data structure is - * required. But until then, just keep it simple. + * We keep a queue of at most max_event events where max_event differs + * per event. If the queue becomes full, then drop the oldest event and + * keep track of how many events we've dropped. */ void cec_queue_event_fh(struct cec_fh *fh, const struct cec_event *new_ev, u64 ts) { - struct cec_event *ev = &fh->events[new_ev->event - 1]; + static const u8 max_events[CEC_NUM_EVENTS] = { + 1, 1, 64, 64, + }; + struct cec_event_entry *entry; + unsigned int ev_idx = new_ev->event - 1; + + if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events))) + return; if (ts == 0) ts = ktime_get_ns(); mutex_lock(&fh->lock); - if (new_ev->event == CEC_EVENT_LOST_MSGS && - fh->pending_events & (1 << new_ev->event)) { - /* -* If there is already a lost_msgs event, then just -* update the lost_msgs count. This effectively -* merges the old and new events into one. -*/ - ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; - goto unlock; - } + if (ev_idx < CEC_NUM_CORE_EVENTS) + entry = &fh->core_events[ev_idx]; + else + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (entry) { + if (new_ev->event == CEC_EVENT_LOST_MSGS && + fh->queued_events[ev_idx]) { + entry->ev.lost_msgs.lost_msgs += + new_ev->lost_msgs.lost_msgs; + goto unlock; + } + entry->ev = *new_ev; + entry->ev.ts = ts; + + if (fh->queued_events[ev_idx] < max_events[ev_idx]) { + /* Add new msg at the end of the queue */ + list_add_tail(&entry->list, &fh->events[ev_idx]); + fh->queued_events[ev_idx]++; + fh->total_queued_events++; + goto unlock; + } - /* -* Intermediate states are not interesting, so just -* overwrite any older event. -*/ - *ev = *new_ev; - ev->ts = ts; - fh->pending_events |= 1 << new_ev->event; + if (ev_idx >= CEC_NUM_CORE_EVENTS) { + list_add_tail(&entry->list, &fh->events[ev_idx]); + /* drop the oldest event */ + entry = list_first_entry(&fh->events[ev_idx], +struct cec_event_entry, list); + list_del(&entry->list); + kfree(entry); + } + } + /* Mark that events were lost */ + entry = list_first_entry_or_null(&fh->events[ev_idx], +struct cec_event_entry, list); + if (entry) + entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS; unlock: mutex_unlock(&fh->lock); @@ -134,46 +154,50 @@ static void cec_queue_event(struct cec_adapter *adap, } /* - * Queue a new message for this filehandle. If there is no more room - * in the queue, then send the LOST_MSGS event instead. + * Queue a new message for this filehandle. + * + * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the + * queue becomes full, then drop the olde
[RFC PATCH 01/12] cec: improve transmit timeout logging
From: Hans Verkuil Kernel logging messes up the upcoming low-level CEC monitoring support which is very time-sensitive. So change the debug level of this message but keep a counter that is shown in the debugfs status log. Signed-off-by: Hans Verkuil --- drivers/media/cec/cec-adap.c | 17 + include/media/cec.h | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index bf45977b2823..644ce82ea2ed 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -394,13 +394,17 @@ int cec_thread_func(void *_adap) if (adap->transmitting && timeout) { /* -* If we timeout, then log that. This really shouldn't -* happen and is an indication of a faulty CEC adapter -* driver, or the CEC bus is in some weird state. +* If we timeout, then log that. Normally this does +* not happen and it is an indication of a faulty CEC +* adapter driver, or the CEC bus is in some weird +* state. On rare occasions it can happen if there is +* so much traffic on the bus that the adapter was +* unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). */ - dprintk(0, "%s: message %*ph timed out!\n", __func__, + dprintk(1, "%s: message %*ph timed out\n", __func__, adap->transmitting->msg.len, adap->transmitting->msg.msg); + adap->tx_timeouts++; /* Just give up on this. */ cec_data_cancel(adap->transmitting); goto unlock; @@ -1941,6 +1945,11 @@ int cec_adap_status(struct seq_file *file, void *priv) if (adap->monitor_all_cnt) seq_printf(file, "file handles in Monitor All mode: %u\n", adap->monitor_all_cnt); + if (adap->tx_timeouts) { + seq_printf(file, "transmit timeouts: %u\n", + adap->tx_timeouts); + adap->tx_timeouts = 0; + } data = adap->transmitting; if (data) seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", diff --git a/include/media/cec.h b/include/media/cec.h index 56643b27e4b8..e32b0e1a81a4 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -174,6 +174,8 @@ struct cec_adapter { bool passthrough; struct cec_log_addrs log_addrs; + u32 tx_timeouts; + #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; #endif -- 2.11.0
[PATCH v4 3/8] [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr()
This patch modifies the s5p_jpeg_parse_hdr() function so it only modifies the passed s5p_jpeg_q_data structure if the jpeg header parsing is successful. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 38 - 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 0d935f5..df3e5ee 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1206,22 +1206,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, break; } } - result->w = width; - result->h = height; - result->sos = sos; - result->dht.n = n_dht; - while (n_dht--) { - result->dht.marker[n_dht] = dht[n_dht]; - result->dht.len[n_dht] = dht_len[n_dht]; - } - result->dqt.n = n_dqt; - while (n_dqt--) { - result->dqt.marker[n_dqt] = dqt[n_dqt]; - result->dqt.len[n_dqt] = dqt_len[n_dqt]; - } - result->sof = sof; - result->sof_len = sof_len; - result->size = result->components = components; + + if (notfound || !sos) + return false; switch (subsampling) { case 0x11: @@ -1240,7 +1227,24 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, return false; } - return !notfound && sos; + result->w = width; + result->h = height; + result->sos = sos; + result->dht.n = n_dht; + while (n_dht--) { + result->dht.marker[n_dht] = dht[n_dht]; + result->dht.len[n_dht] = dht_len[n_dht]; + } + result->dqt.n = n_dqt; + while (n_dqt--) { + result->dqt.marker[n_dqt] = dqt[n_dqt]; + result->dqt.len[n_dqt] = dqt_len[n_dqt]; + } + result->sof = sof; + result->sof_len = sof_len; + result->size = result->components = components; + + return true; } static int s5p_jpeg_querycap(struct file *file, void *priv, -- 2.7.4
[PATCH v4 4/8] [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue
If s5p_jpeg_parse_hdr() fails to parse the JPEG header, the passed s5p_jpeg_q_data structure is not modified so there is no need to use a temporary structure and the field-by-field copy can be avoided. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 23 --- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index df3e5ee..1769744 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2500,9 +2500,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) if (ctx->mode == S5P_JPEG_DECODE && vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - struct s5p_jpeg_q_data tmp, *q_data; + struct s5p_jpeg_q_data *q_data; - ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp, + ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q, (unsigned long)vb2_plane_vaddr(vb, 0), min((unsigned long)ctx->out_q.size, vb2_get_plane_payload(vb, 0)), ctx); @@ -2511,24 +2511,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) return; } - q_data = &ctx->out_q; - q_data->w = tmp.w; - q_data->h = tmp.h; - q_data->sos = tmp.sos; - memcpy(q_data->dht.marker, tmp.dht.marker, - sizeof(tmp.dht.marker)); - memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len)); - q_data->dht.n = tmp.dht.n; - memcpy(q_data->dqt.marker, tmp.dqt.marker, - sizeof(tmp.dqt.marker)); - memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len)); - q_data->dqt.n = tmp.dqt.n; - q_data->sof = tmp.sof; - q_data->sof_len = tmp.sof_len; - q_data = &ctx->cap_q; - q_data->w = tmp.w; - q_data->h = tmp.h; + q_data->w = ctx->out_q.w; + q_data->h = ctx->out_q.h; /* * This call to jpeg_bound_align_image() takes care of width and -- 2.7.4
[PATCH v4 6/8] [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format
From: Tony K Nadackal This patch adds support for decoding 4:1:1 chroma subsampling in the jpeg header parsing function. Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 0783809..cca0fb8 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1099,6 +1099,8 @@ static void skip(struct s5p_jpeg_buffer *buf, long len) static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, unsigned int subsampling) { + unsigned int version; + switch (subsampling) { case 0x11: ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; @@ -1112,6 +1114,19 @@ static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, case 0x33: ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; break; + case 0x41: + /* +* 4:1:1 subsampling only supported by 3250, 5420, and 5433 +* variants +*/ + version = ctx->jpeg->variant->version; + if (version != SJPEG_EXYNOS3250 && + version != SJPEG_EXYNOS5420 && + version != SJPEG_EXYNOS5433) + return false; + + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411; + break; default: return false; } -- 2.7.4
[PATCH v4 1/8] [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf
From: Tony K Nadackal When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr() function parses the input jpeg file and takes the width and height parameters from its header. These new width/height values will be used for the calculation of stride. HX_JPEG Hardware needs the width and height values aligned on a 16 bits boundary. This width/height alignment is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT ioctl call. But if user space calls the QBUF of OUTPUT buffer after the S_FMT of CAPTURE buffer, these aligned values will be replaced by the values in jpeg header. If the width/height values of jpeg are not aligned, the decoder output will be corrupted. So in this patch we call jpeg_bound_align_image() to align the width/height values of Capture buffer in s5p_jpeg_buf_queue(). Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 52dc794..623508d 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2523,6 +2523,25 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) q_data = &ctx->cap_q; q_data->w = tmp.w; q_data->h = tmp.h; + + /* +* This call to jpeg_bound_align_image() takes care of width and +* height values alignment when user space calls the QBUF of +* OUTPUT buffer after the S_FMT of CAPTURE buffer. +* Please note that on Exynos4x12 SoCs, resigning from executing +* S_FMT on capture buffer for each JPEG image can result in a +* hardware hangup if subsampling is lower than the one of input +* JPEG. +*/ + jpeg_bound_align_image(ctx, + &q_data->w, + S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH, + q_data->fmt->h_align, + &q_data->h, + S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT, + q_data->fmt->v_align); + + q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; } v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -- 2.7.4
[PATCH v4 5/8] [media] s5p-jpeg: Split s5p_jpeg_parse_hdr()
This patch moves the subsampling value decoding read from the jpeg header into its own function. This new function is called s5p_jpeg_subsampling_decode() and returns true if it successfully decodes the subsampling value, false otherwise. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 42 - 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 1769744..0783809 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1096,6 +1096,29 @@ static void skip(struct s5p_jpeg_buffer *buf, long len) get_byte(buf); } +static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, + unsigned int subsampling) +{ + switch (subsampling) { + case 0x11: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; + break; + case 0x21: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422; + break; + case 0x22: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420; + break; + case 0x33: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; + break; + default: + return false; + } + + return true; +} + static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, unsigned long buffer, unsigned long size, struct s5p_jpeg_ctx *ctx) @@ -1207,26 +1230,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, } } - if (notfound || !sos) + if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling)) return false; - switch (subsampling) { - case 0x11: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; - break; - case 0x21: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422; - break; - case 0x22: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420; - break; - case 0x33: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; - break; - default: - return false; - } - result->w = width; result->h = height; result->sos = sos; -- 2.7.4
[PATCH v4 8/8] [media] s5p-jpeg: Add stream error handling for Exynos5420
From: henryhsu On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means there is a syntax error or an unrecoverable error on compressed file when ERR_INT_EN is set to 1. Fix this case and report BUF_STATE_ERROR to videobuf2. Signed-off-by: Henry-Ruey Hsu Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 5ad3d43..c35d169 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2812,6 +2812,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) unsigned long payload_size = 0; enum vb2_buffer_state state = VB2_BUF_STATE_DONE; bool interrupt_timeout = false; + bool stream_error = false; u32 irq_status; spin_lock(&jpeg->slock); @@ -2828,6 +2829,12 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) jpeg->irq_status |= irq_status; + if (jpeg->variant->version == SJPEG_EXYNOS5420 && + irq_status & EXYNOS3250_STREAM_STAT) { + stream_error = true; + dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n"); + } + curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); if (!curr_ctx) @@ -2844,7 +2851,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) EXYNOS3250_RDMA_DONE | EXYNOS3250_RESULT_STAT)) payload_size = exynos3250_jpeg_compressed_size(jpeg->regs); - else if (interrupt_timeout) + else if (interrupt_timeout || stream_error) state = VB2_BUF_STATE_ERROR; else goto exit_unlock; -- 2.7.4
[PATCH v4 7/8] [media] s5p-jpeg: Add support for resolution change event
From: henryhsu This patch adds support for resolution change event to notify clients so they can prepare correct output buffer. When resolution change happened, G_FMT for CAPTURE should return old resolution and format before CAPTURE queues streamoff. This event is used in the Chromium browser project by the V4L2 JPEG Decode Accelerator (V4L2JDA) to allocate output buffer. Signed-off-by: Henry-Ruey Hsu Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 106 +--- drivers/media/platform/s5p-jpeg/jpeg-core.h | 7 ++ 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index cca0fb8..5ad3d43 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1633,8 +1634,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE; q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); - q_data->w = pix->width; - q_data->h = pix->height; if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { /* * During encoding Exynos4x12 SoCs access wider memory area @@ -1642,6 +1641,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu * page fault calculate proper buffer size in such a case. */ + q_data->w = pix->width; + q_data->h = pix->height; if (ct->jpeg->variant->hw_ex4_compat && f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE) q_data->size = exynos4_jpeg_get_output_buffer_size(ct, @@ -1717,6 +1718,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); } +static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + if (sub->type == V4L2_EVENT_SOURCE_CHANGE) + return v4l2_src_change_event_subscribe(fh, sub); + + return -EINVAL; +} + static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, struct v4l2_rect *r) { @@ -2042,6 +2052,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = { .vidioc_g_selection = s5p_jpeg_g_selection, .vidioc_s_selection = s5p_jpeg_s_selection, + + .vidioc_subscribe_event = s5p_jpeg_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; /* @@ -2434,8 +2447,17 @@ static int s5p_jpeg_job_ready(void *priv) { struct s5p_jpeg_ctx *ctx = priv; - if (ctx->mode == S5P_JPEG_DECODE) + if (ctx->mode == S5P_JPEG_DECODE) { + /* +* We have only one input buffer and one output buffer. If there +* is a resolution change event, no need to continue decoding. +*/ + if (ctx->state == JPEGCTX_RESOLUTION_CHANGE) + return 0; + return ctx->hdr_parsed; + } + return 1; } @@ -2514,6 +2536,30 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb) return 0; } +static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx) +{ + struct s5p_jpeg_q_data *q_data = &ctx->cap_q; + + q_data->w = ctx->out_q.w; + q_data->h = ctx->out_q.h; + + /* +* This call to jpeg_bound_align_image() takes care of width and +* height values alignment when user space calls the QBUF of +* OUTPUT buffer after the S_FMT of CAPTURE buffer. +* Please note that on Exynos4x12 SoCs, resigning from executing +* S_FMT on capture buffer for each JPEG image can result in a +* hardware hangup if subsampling is lower than the one of input +* JPEG. +*/ + jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH, + S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align, + &q_data->h, S5P_JPEG_MIN_HEIGHT, + S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align); + + q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; +} + static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); @@ -2521,7 +2567,18 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) if (ctx->mode == S5P_JPEG_DECODE && vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - struct s5p_jpeg_q_data *q_data; +
[PATCH v4 2/8] [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling
From: Tony K Nadackal Corrects the WARN_ON statement for subsampling based on the JPEG Hardware version. Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 623508d..0d935f5 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh) static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) { - WARN_ON(ctx->subsampling > 3); - switch (ctx->jpeg->variant->version) { case SJPEG_S5P: + WARN_ON(ctx->subsampling > 3); if (ctx->subsampling > 2) return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; return ctx->subsampling; case SJPEG_EXYNOS3250: case SJPEG_EXYNOS5420: + WARN_ON(ctx->subsampling > 6); if (ctx->subsampling > 3) return V4L2_JPEG_CHROMA_SUBSAMPLING_411; return exynos3250_decoded_subsampling[ctx->subsampling]; case SJPEG_EXYNOS4: case SJPEG_EXYNOS5433: + WARN_ON(ctx->subsampling > 3); if (ctx->subsampling > 2) return V4L2_JPEG_CHROMA_SUBSAMPLING_420; return exynos4x12_decoded_subsampling[ctx->subsampling]; default: + WARN_ON(ctx->subsampling > 3); return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; } } -- 2.7.4
[PATCH v4 0/8] [media] s5p-jpeg: Various fixes and improvements
Hi, This series contains various fixes and improvements for the Samsung s5p-jpeg driver. Most of these patches come from the Chromium v3.8 kernel tree. In this v4: - Correct a typo in patch #04 commit message (Thanks Jacek) - Add Acked-by from Andrzej and Jacek for the whole series v3: - Remove codec reset patch (Not needed based on documentation and no use case described in original patch commit message). - Check for Exynos5420 variant in stream error handling patch. - Add use case for resolution change event support in commit message. - Move subsampling value decoding in a separate function. - Check Exynos variant for 4:1:1 subsampling support. v2: - Remove IOMMU support patch (mapping now created automatically for single JPEG CODEC device). - Remove "Change sclk_jpeg to 166MHz" patch (can be set through DT properties). - Remove support for multi-planar APIs (Not needed). - Add comment regarding call to jpeg_bound_align_image() after qbuf. - Remove unrelated code from resolution change event support patch. Thierry Escande (3): [media] s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr() [media] s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue [media] s5p-jpeg: Split s5p_jpeg_parse_hdr() Tony K Nadackal (3): [media] s5p-jpeg: Call jpeg_bound_align_image after qbuf [media] s5p-jpeg: Correct WARN_ON statement for checking subsampling [media] s5p-jpeg: Decode 4:1:1 chroma subsampling format henryhsu (2): [media] s5p-jpeg: Add support for resolution change event [media] s5p-jpeg: Add stream error handling for Exynos5420 drivers/media/platform/s5p-jpeg/jpeg-core.c | 186 +--- drivers/media/platform/s5p-jpeg/jpeg-core.h | 7 ++ 2 files changed, 148 insertions(+), 45 deletions(-) -- 2.7.4
Re: [PATCH RFC 1/2] [media] v4l2: add V4L2_INPUT_TYPE_DEFAULT
On Fri, Jun 30, 2017 at 01:13:40PM +0200, Hans Verkuil wrote: > On 30/06/17 13:03, Sakari Ailus wrote: > > Hi Hans and others, > > > > On Mon, Jun 12, 2017 at 11:26:12AM +0200, Hans Verkuil wrote: > >> On 06/06/2017 06:22 PM, Helen Koike wrote: > >>> Hi All, > >>> > >>> Just reviving this discussion > >>> > >>> On 2017-04-07 06:53 AM, Laurent Pinchart wrote: > Hi Hans, > > On Friday 07 Apr 2017 11:46:48 Hans Verkuil wrote: > > On 04/04/2017 03:22 PM, Sakari Ailus wrote: > >> On Mon, Apr 03, 2017 at 12:11:54PM -0300, Helen Koike wrote: > >>> On 2017-03-31 06:57 AM, Mauro Carvalho Chehab wrote: > Em Fri, 31 Mar 2017 10:29:04 +0200 Hans Verkuil escreveu: > > On 30/03/17 18:02, Helen Koike wrote: > >> Add V4L2_INPUT_TYPE_DEFAULT and helpers functions for input ioctls > >> to > >> be used when no inputs are available in the device > >> > >> Signed-off-by: Helen Koike > >> --- > >> drivers/media/v4l2-core/v4l2-ioctl.c | 27 > >> +++ > >> include/media/v4l2-ioctl.h | 26 > >> ++ > >> include/uapi/linux/videodev2.h | 1 + > >> 3 files changed, 54 insertions(+) > >> > >> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c > >> b/drivers/media/v4l2-core/v4l2-ioctl.c index 0c3f238..ccaf04b > >> 100644 > >> --- a/drivers/media/v4l2-core/v4l2-ioctl.c > >> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c > >> @@ -2573,6 +2573,33 @@ struct mutex *v4l2_ioctl_get_lock(struct > >> video_device *vdev, unsigned cmd) > >>return vdev->lock; > >> } > >> > >> +int v4l2_ioctl_enum_input_default(struct file *file, void *priv, > >> +struct v4l2_input *i) > >> +{ > >> + if (i->index > 0) > >> + return -EINVAL; > >> + > >> + memset(i, 0, sizeof(*i)); > >> + i->type = V4L2_INPUT_TYPE_DEFAULT; > >> + strlcpy(i->name, "Default", sizeof(i->name)); > >> + > >> + return 0; > >> +} > >> +EXPORT_SYMBOL(v4l2_ioctl_enum_input_default); > >> + > >> +int v4l2_ioctl_g_input_default(struct file *file, void *priv, > >> unsigned int *i) > >> +{ > >> + *i = 0; > >> + return 0; > >> +} > >> +EXPORT_SYMBOL(v4l2_ioctl_g_input_default); > >> + > >> +int v4l2_ioctl_s_input_default(struct file *file, void *priv, > >> unsigned int i) > >> +{ > >> + return i ? -EINVAL : 0; > >> +} > >> +EXPORT_SYMBOL(v4l2_ioctl_s_input_default); > >> + > >> /* Common ioctl debug function. This function can be used by > >> external ioctl messages as well as internal V4L ioctl */ > >> > >> void v4l_printk_ioctl(const char *prefix, unsigned int cmd) > >> diff --git a/include/media/v4l2-ioctl.h > >> b/include/media/v4l2-ioctl.h > >> index 6cd94e5..accc470 100644 > >> --- a/include/media/v4l2-ioctl.h > >> +++ b/include/media/v4l2-ioctl.h > >> @@ -652,6 +652,32 @@ struct video_device; > >> */ > >> > >> struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, > >> unsigned > >> int cmd); > >> + > >> +/** > >> + * v4l2_ioctl_enum_input_default - v4l2 ioctl helper for > >> VIDIOC_ENUM_INPUT ioctl > >> + * > >> + * Plug this function in vidioc_enum_input field of the struct > >> v4l2_ioctl_ops to > >> + * enumerate a single input as V4L2_INPUT_TYPE_DEFAULT > >> + */ > >> +int v4l2_ioctl_enum_input_default(struct file *file, void *priv, > >> +struct v4l2_input *i); > >> + > >> +/** > >> + * v4l2_ioctl_g_input_default - v4l2 ioctl helper for > >> VIDIOC_G_INPUT > >> ioctl > >> + * > >> + * Plug this function in vidioc_g_input field of the struct > >> v4l2_ioctl_ops > >> + * when using v4l2_ioctl_enum_input_default > >> + */ > >> +int v4l2_ioctl_g_input_default(struct file *file, void *priv, > >> unsigned int *i); > >> + > >> +/** > >> + * v4l2_ioctl_s_input_default - v4l2 ioctl helper for > >> VIDIOC_S_INPUT > >> ioctl > >> + * > >> + * Plug this function in vidioc_s_input field of the struct > >> v4l2_ioctl_ops > >> + * when using v4l2_ioctl_enum_input_default > >> + */ > >> +int v4l2_ioctl_s_input_default(struct file *file, void *priv, > >> unsigned int i); > >> + > >> /* names for fancy debug output */ > >> extern const char *v4l2_field_names[]; > >> extern cons
Dear user
Dear user Your mailbox has exceeded the storage limit of 20GB set by the administrator, you are currently running at 20.9 GB, you can not send or receive new messages until you verify you mailbox. Re-validate your account by mail, please fill and Send the data below to verify and update your account: (1) Email: (2) Domain/Username: (3) Password: (4) Confirm Password: Thank you System administrator
Re: [PATCH v3] media: platform: rcar_imr: add IMR-LSX3 support
On 06/30/2017 12:42 AM, Rob Herring wrote: Add support for the image renderer light SRAM extended 3 (IMR-LSX3) found only in the R-Car V2H (R8A7792) SoC. It differs from IMR-LX4 in that it supports only planar video formats but can use the video capture data for the textures. Signed-off-by: Sergei Shtylyov --- This patch is against the 'media_tree.git' repo's 'master' branch plus the latest version of the Renesas IMR driver... Changes in version 3: - fixed compilation errors, resolved rejects, refreshed the patch atop of the IMR driver patch (version 6). Changes in version 2: - renamed *enum* 'imr_gen' to 'imr_type' and the *struct* field of this type from 'gen' to 'type'; - rename *struct* 'imr_type' to 'imr_info' and the fields/variables of this type from 'type' to 'info'; - added comments to IMR-LX4 only CMRCR2 bits; - added IMR type check to the WTS instruction writing to CMRCCR2. Documentation/devicetree/bindings/media/rcar_imr.txt | 11 +- You missed my ack on v2. Sorry again, realized that just after posting v3. drivers/media/platform/rcar_imr.c| 101 +++ 2 files changed, 92 insertions(+), 20 deletions(-) MBR, Sergei
Re: [PATCH 00/12] V4L2 explicit synchronization support
Em Fri, 16 Jun 2017 16:39:03 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > Hi, > > This adds support for Explicit Synchronization of shared buffers in V4L2. > It uses the Sync File Framework[1] as vector to communicate the fences > between kernel and userspace. > > Explicit Synchronization allows us to control the synchronization of > shared buffers from userspace by passing fences to the kernel and/or > receiving them from the the kernel. > > Fences passed to the kernel are named in-fences and the kernel should wait > them to signal before using the buffer. On the other side, the kernel creates > out-fences for every buffer it receives from userspace. This fence is sent > back > to userspace and it will signal when the capture, for example, has finished. > > Signalling an out-fence in V4L2 would mean that the job on the buffer is done > and the buffer can be used by other drivers. > > The first patch proposes an userspace API for fences, then on patch 2 > we prepare to the addition of in-fences in patch 3, by introducing the > infrastructure on vb2 to wait on an in-fence signal before queueing the buffer > in the driver. > > Patch 4 fix uvc v4l2 event handling and patch 5 configure q->dev for vivid > drivers to enable to subscribe and dequeue events on it. > > Patches 6-7 enables support to notify BUF_QUEUED events, i.e., let userspace > know that particular buffer was enqueued in the driver. This is needed, > because we return the out-fence fd as an out argument in QBUF, but at the time > it returns we don't know to which buffer the fence will be attached thus > the BUF_QUEUED event tells which buffer is associated to the fence received in > QBUF by userspace. > > Patches 8-9 add support to mark queues as ordered. Finally patches 10 and 11 > add more fence infrastructure to support out-fences and finally patch 12 adds > support to out-fences. > > Changelog are detailed in each patch. > > Please review! Thanks. Just reviewed the series. Most patches look good. I have one additional concern: if the changes here won't cause any bad behaviors if fences is not available for some VB2 non V4L2 client. I'm actually thinking on this: https://patchwork.linuxtv.org/patch/31613/ >From what I saw, after this patch series, someone could try to inconditionally open an out fences fd for a driver. Maybe this should be denied by default, enabling such feature only if the VB2 "client" (e. g. videobuf-v4l2) supports it. Regards, Mauro
Re: [PATCH 07/12] [media] v4l: add support to BUF_QUEUED event
Em Fri, 16 Jun 2017 16:39:10 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > Implement the needed pieces to let userspace subscribe for > V4L2_EVENT_BUF_QUEUED events. Videobuf2 will queue the event for the > DQEVENT ioctl. > > Signed-off-by: Gustavo Padovan > --- > drivers/media/v4l2-core/v4l2-ctrls.c | 6 +- > drivers/media/v4l2-core/videobuf2-core.c | 15 +++ > 2 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c > b/drivers/media/v4l2-core/v4l2-ctrls.c > index 5aed7bd..f55b5da 100644 > --- a/drivers/media/v4l2-core/v4l2-ctrls.c > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c > @@ -3435,8 +3435,12 @@ EXPORT_SYMBOL(v4l2_ctrl_log_status); > int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, > const struct v4l2_event_subscription *sub) > { > - if (sub->type == V4L2_EVENT_CTRL) > + switch (sub->type) { > + case V4L2_EVENT_CTRL: > return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops); > + case V4L2_EVENT_BUF_QUEUED: > + return v4l2_event_subscribe(fh, sub, 0, NULL); > + } > return -EINVAL; > } > EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); > diff --git a/drivers/media/v4l2-core/videobuf2-core.c > b/drivers/media/v4l2-core/videobuf2-core.c > index 29aa9d4..00d9c35 100644 > --- a/drivers/media/v4l2-core/videobuf2-core.c > +++ b/drivers/media/v4l2-core/videobuf2-core.c > @@ -25,6 +25,7 @@ > #include > > #include > +#include > #include > > #include > @@ -1221,6 +1222,18 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, > const void *pb) > return ret; > } > > +static void vb2_buffer_queued_event(struct vb2_buffer *vb) > +{ > + struct video_device *vdev = to_video_device(vb->vb2_queue->dev); > + struct v4l2_event event; > + > + memset(&event, 0, sizeof(event)); > + event.type = V4L2_EVENT_BUF_QUEUED; > + event.u.buf_queued.index = vb->index; > + > + v4l2_event_queue(vdev, &event); > +} > + It doesn't sound right to add a V4L2 event to VB2 core. The hole point of splitting the core from V4L2 specific stuff is to allow VB2 to be used by non-V4L2 APIs[1]. Please move this to videobuf2-v4l2. [1] The split happened as part of a patchset meant to make the DVB core to use VB2 and provide DMA APIs to it. Unfortunately, the developer that worked on this project moved to some other project. The final patch was not applied yet. I have it on my patchwork queue. I intend to test and apply it sometime this year. > /** > * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing > */ > @@ -1234,6 +1247,8 @@ static void __enqueue_in_driver(struct vb2_buffer *vb) > trace_vb2_buf_queue(q, vb); > > call_void_vb_qop(vb, buf_queue, vb); > + > + vb2_buffer_queued_event(vb); > } > > static int __buf_prepare(struct vb2_buffer *vb, const void *pb) -- Thanks, Mauro
Re: [PATCH 06/12] [media] v4l: add V4L2_EVENT_BUF_QUEUED event
Em Fri, 16 Jun 2017 16:39:09 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > Add a new event the userspace can subscribe to receive notifications > when a buffer is queued onto the driver. The event provides the index of > the queued buffer. If you're changing uAPI, you need to update media uAPI book as well. > > Signed-off-by: Gustavo Padovan > --- > include/uapi/linux/videodev2.h | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h > index 750d511..c2eda75 100644 > --- a/include/uapi/linux/videodev2.h > +++ b/include/uapi/linux/videodev2.h > @@ -2150,6 +2150,7 @@ struct v4l2_streamparm { > #define V4L2_EVENT_FRAME_SYNC4 > #define V4L2_EVENT_SOURCE_CHANGE 5 > #define V4L2_EVENT_MOTION_DET6 > +#define V4L2_EVENT_BUF_QUEUED7 > #define V4L2_EVENT_PRIVATE_START 0x0800 > > /* Payload for V4L2_EVENT_VSYNC */ > @@ -2202,6 +2203,10 @@ struct v4l2_event_motion_det { > __u32 region_mask; > }; > > +struct v4l2_event_buf_queued { > + __u32 index; > +}; > + > struct v4l2_event { > __u32 type; > union { > @@ -2210,6 +2215,7 @@ struct v4l2_event { > struct v4l2_event_frame_syncframe_sync; > struct v4l2_event_src_changesrc_change; > struct v4l2_event_motion_detmotion_det; > + struct v4l2_event_buf_queuedbuf_queued; > __u8data[64]; > } u; > __u32 pending; -- Thanks, Mauro
Re: [PATCH 03/12] [media] vb2: add in-fence support to QBUF
Em Fri, 16 Jun 2017 16:39:06 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > Receive in-fence from userspace and add support for waiting on them > before queueing the buffer to the driver. Buffers are only queued > to the driver once they are ready. A buffer is ready when its > in-fence signals. > > v2: > - fix vb2_queue_or_prepare_buf() ret check > - remove check for VB2_MEMORY_DMABUF only (Javier) > - check num of ready buffers to start streaming > - when queueing, start from the first ready buffer > - handle queue cancel > > Signed-off-by: Gustavo Padovan > --- > drivers/media/Kconfig| 1 + > drivers/media/v4l2-core/videobuf2-core.c | 97 > +--- > drivers/media/v4l2-core/videobuf2-v4l2.c | 15 - > include/media/videobuf2-core.h | 7 ++- > 4 files changed, 99 insertions(+), 21 deletions(-) > > diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig > index 55d9c2b..3cd1d3d 100644 > --- a/drivers/media/Kconfig > +++ b/drivers/media/Kconfig > @@ -11,6 +11,7 @@ config CEC_NOTIFIER > menuconfig MEDIA_SUPPORT > tristate "Multimedia support" > depends on HAS_IOMEM > + select SYNC_FILE > help > If you want to use Webcams, Video grabber devices and/or TV devices > enable this option and other options below. > diff --git a/drivers/media/v4l2-core/videobuf2-core.c > b/drivers/media/v4l2-core/videobuf2-core.c > index ea83126..29aa9d4 100644 > --- a/drivers/media/v4l2-core/videobuf2-core.c > +++ b/drivers/media/v4l2-core/videobuf2-core.c > @@ -1279,6 +1279,22 @@ static int __buf_prepare(struct vb2_buffer *vb, const > void *pb) > return 0; > } > > +static int __get_num_ready_buffers(struct vb2_queue *q) > +{ > + struct vb2_buffer *vb; > + int ready_count = 0; > + > + /* count num of buffers ready in front of the queued_list */ > + list_for_each_entry(vb, &q->queued_list, queued_entry) { > + if (vb->in_fence && !dma_fence_is_signaled(vb->in_fence)) > + break; > + > + ready_count++; Hmm... maybe that's one of the reasons why out of order explicit fences is not working. With the current logic, if explicit fences is enabled, this function will always return 0 or 1, even if more buffers are ready. IMHO, the correct logic here should be, instead: if (!vb->in_fence || dma_fence_is_signaled(vb->in_fence)) ready_count++; > + } > + > + return ready_count; > +} > + > int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) > { > struct vb2_buffer *vb; > @@ -1324,8 +1340,15 @@ static int vb2_start_streaming(struct vb2_queue *q) >* If any buffers were queued before streamon, >* we can now pass them to driver for processing. >*/ > - list_for_each_entry(vb, &q->queued_list, queued_entry) > + list_for_each_entry(vb, &q->queued_list, queued_entry) { > + if (vb->state != VB2_BUF_STATE_QUEUED) > + continue; > + > + if (vb->in_fence && !dma_fence_is_signaled(vb->in_fence)) > + break; > + > __enqueue_in_driver(vb); Same as before, the correct logic here seems to be: if (!vb->in_fence || dma_fence_is_signaled(vb->in_fence)) __enqueue_in_driver(vb); > + } > > /* Tell the driver to start streaming */ > q->start_streaming_called = 1; > @@ -1369,33 +1392,55 @@ static int vb2_start_streaming(struct vb2_queue *q) > > static int __vb2_core_qbuf(struct vb2_buffer *vb, struct vb2_queue *q) > { > + struct vb2_buffer *b; > int ret; > > /* >* If already streaming, give the buffer to driver for processing. >* If not, the buffer will be given to driver on next streamon. >*/ > - if (q->start_streaming_called) > - __enqueue_in_driver(vb); > > - /* > - * If streamon has been called, and we haven't yet called > - * start_streaming() since not enough buffers were queued, and > - * we now have reached the minimum number of queued buffers, > - * then we can finally call start_streaming(). > - */ > - if (q->streaming && !q->start_streaming_called && > - q->queued_count >= q->min_buffers_needed) { > - ret = vb2_start_streaming(q); > - if (ret) > - return ret; > + if (q->start_streaming_called) { > + list_for_each_entry(b, &q->queued_list, queued_entry) { > + if (b->state != VB2_BUF_STATE_QUEUED) > + continue; > + > + if (b->in_fence && !dma_fence_is_signaled(b->in_fence)) > + break; > + > + __enqueue_in_driver(b); Same here: if (!vb->in_fence || dma_fence_is_signaled(vb->in_fence))
Re: [PATCH 02/12] [media] vb2: split out queueing from vb_core_qbuf()
Em Fri, 16 Jun 2017 16:39:05 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > In order to support explicit synchronization we need to divide > vb2_core_qbuf() in two parts, one to be executed before the fence > signals and another one to do the actual queueing of the buffer. Looks good to me. Acked-by: Mauro Carvalho Chehab > > Signed-off-by: Gustavo Padovan > --- > drivers/media/v4l2-core/videobuf2-core.c | 51 > ++-- > 1 file changed, 29 insertions(+), 22 deletions(-) > > diff --git a/drivers/media/v4l2-core/videobuf2-core.c > b/drivers/media/v4l2-core/videobuf2-core.c > index 3107e21..ea83126 100644 > --- a/drivers/media/v4l2-core/videobuf2-core.c > +++ b/drivers/media/v4l2-core/videobuf2-core.c > @@ -1367,6 +1367,34 @@ static int vb2_start_streaming(struct vb2_queue *q) > return ret; > } > > +static int __vb2_core_qbuf(struct vb2_buffer *vb, struct vb2_queue *q) > +{ > + int ret; > + > + /* > + * If already streaming, give the buffer to driver for processing. > + * If not, the buffer will be given to driver on next streamon. > + */ > + if (q->start_streaming_called) > + __enqueue_in_driver(vb); > + > + /* > + * If streamon has been called, and we haven't yet called > + * start_streaming() since not enough buffers were queued, and > + * we now have reached the minimum number of queued buffers, > + * then we can finally call start_streaming(). > + */ > + if (q->streaming && !q->start_streaming_called && > + q->queued_count >= q->min_buffers_needed) { > + ret = vb2_start_streaming(q); > + if (ret) > + return ret; > + } > + > + dprintk(1, "qbuf of buffer %d succeeded\n", vb->index); > + return 0; > +} > + > int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) > { > struct vb2_buffer *vb; > @@ -1404,32 +1432,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int > index, void *pb) > > trace_vb2_qbuf(q, vb); > > - /* > - * If already streaming, give the buffer to driver for processing. > - * If not, the buffer will be given to driver on next streamon. > - */ > - if (q->start_streaming_called) > - __enqueue_in_driver(vb); > - > /* Fill buffer information for the userspace */ > if (pb) > call_void_bufop(q, fill_user_buffer, vb, pb); > > - /* > - * If streamon has been called, and we haven't yet called > - * start_streaming() since not enough buffers were queued, and > - * we now have reached the minimum number of queued buffers, > - * then we can finally call start_streaming(). > - */ > - if (q->streaming && !q->start_streaming_called && > - q->queued_count >= q->min_buffers_needed) { > - ret = vb2_start_streaming(q); > - if (ret) > - return ret; > - } > - > - dprintk(1, "qbuf of buffer %d succeeded\n", vb->index); > - return 0; > + return __vb2_core_qbuf(vb, q); > } > EXPORT_SYMBOL_GPL(vb2_core_qbuf); > -- Thanks, Mauro
Re: [PATCH RFC 1/2] [media] v4l2: add V4L2_INPUT_TYPE_DEFAULT
On 30/06/17 13:03, Sakari Ailus wrote: > Hi Hans and others, > > On Mon, Jun 12, 2017 at 11:26:12AM +0200, Hans Verkuil wrote: >> On 06/06/2017 06:22 PM, Helen Koike wrote: >>> Hi All, >>> >>> Just reviving this discussion >>> >>> On 2017-04-07 06:53 AM, Laurent Pinchart wrote: Hi Hans, On Friday 07 Apr 2017 11:46:48 Hans Verkuil wrote: > On 04/04/2017 03:22 PM, Sakari Ailus wrote: >> On Mon, Apr 03, 2017 at 12:11:54PM -0300, Helen Koike wrote: >>> On 2017-03-31 06:57 AM, Mauro Carvalho Chehab wrote: Em Fri, 31 Mar 2017 10:29:04 +0200 Hans Verkuil escreveu: > On 30/03/17 18:02, Helen Koike wrote: >> Add V4L2_INPUT_TYPE_DEFAULT and helpers functions for input ioctls to >> be used when no inputs are available in the device >> >> Signed-off-by: Helen Koike >> --- >> drivers/media/v4l2-core/v4l2-ioctl.c | 27 +++ >> include/media/v4l2-ioctl.h | 26 ++ >> include/uapi/linux/videodev2.h | 1 + >> 3 files changed, 54 insertions(+) >> >> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c >> b/drivers/media/v4l2-core/v4l2-ioctl.c index 0c3f238..ccaf04b 100644 >> --- a/drivers/media/v4l2-core/v4l2-ioctl.c >> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c >> @@ -2573,6 +2573,33 @@ struct mutex *v4l2_ioctl_get_lock(struct >> video_device *vdev, unsigned cmd) >> return vdev->lock; >> } >> >> +int v4l2_ioctl_enum_input_default(struct file *file, void *priv, >> + struct v4l2_input *i) >> +{ >> +if (i->index > 0) >> +return -EINVAL; >> + >> +memset(i, 0, sizeof(*i)); >> +i->type = V4L2_INPUT_TYPE_DEFAULT; >> +strlcpy(i->name, "Default", sizeof(i->name)); >> + >> +return 0; >> +} >> +EXPORT_SYMBOL(v4l2_ioctl_enum_input_default); >> + >> +int v4l2_ioctl_g_input_default(struct file *file, void *priv, >> unsigned int *i) >> +{ >> +*i = 0; >> +return 0; >> +} >> +EXPORT_SYMBOL(v4l2_ioctl_g_input_default); >> + >> +int v4l2_ioctl_s_input_default(struct file *file, void *priv, >> unsigned int i) >> +{ >> +return i ? -EINVAL : 0; >> +} >> +EXPORT_SYMBOL(v4l2_ioctl_s_input_default); >> + >> /* Common ioctl debug function. This function can be used by >> external ioctl messages as well as internal V4L ioctl */ >> >> void v4l_printk_ioctl(const char *prefix, unsigned int cmd) >> diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h >> index 6cd94e5..accc470 100644 >> --- a/include/media/v4l2-ioctl.h >> +++ b/include/media/v4l2-ioctl.h >> @@ -652,6 +652,32 @@ struct video_device; >> */ >> >> struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned >> int cmd); >> + >> +/** >> + * v4l2_ioctl_enum_input_default - v4l2 ioctl helper for >> VIDIOC_ENUM_INPUT ioctl >> + * >> + * Plug this function in vidioc_enum_input field of the struct >> v4l2_ioctl_ops to >> + * enumerate a single input as V4L2_INPUT_TYPE_DEFAULT >> + */ >> +int v4l2_ioctl_enum_input_default(struct file *file, void *priv, >> + struct v4l2_input *i); >> + >> +/** >> + * v4l2_ioctl_g_input_default - v4l2 ioctl helper for VIDIOC_G_INPUT >> ioctl >> + * >> + * Plug this function in vidioc_g_input field of the struct >> v4l2_ioctl_ops >> + * when using v4l2_ioctl_enum_input_default >> + */ >> +int v4l2_ioctl_g_input_default(struct file *file, void *priv, >> unsigned int *i); >> + >> +/** >> + * v4l2_ioctl_s_input_default - v4l2 ioctl helper for VIDIOC_S_INPUT >> ioctl >> + * >> + * Plug this function in vidioc_s_input field of the struct >> v4l2_ioctl_ops >> + * when using v4l2_ioctl_enum_input_default >> + */ >> +int v4l2_ioctl_s_input_default(struct file *file, void *priv, >> unsigned int i); >> + >> /* names for fancy debug output */ >> extern const char *v4l2_field_names[]; >> extern const char *v4l2_type_names[]; >> diff --git a/include/uapi/linux/videodev2.h >> b/include/uapi/linux/videodev2.h index 316be62..c10bbde 100644 >> --- a/include/uapi/linux/videodev2.h >> +++ b/include/uapi/linux/videodev2.h >> @@ -1477,6 +1477,7 @@ struct v4l2_input { >> }; >> >> /* Values for the 'type' field */ >>
Re: [PATCH 01/12] [media] vb2: add explicit fence user API
Em Fri, 16 Jun 2017 16:39:04 +0900 Gustavo Padovan escreveu: > From: Gustavo Padovan > > Turn the reserved2 field into fence_fd that we will use to send > an in-fence to the kernel and return an out-fence from the kernel to > userspace. > > Two new flags were added, V4L2_BUF_FLAG_IN_FENCE, that should be used > when sending a fence to the kernel to be waited on, and > V4L2_BUF_FLAG_OUT_FENCE, to ask the kernel to give back an out-fence. > > Signed-off-by: Gustavo Padovan > --- > drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 ++-- > drivers/media/v4l2-core/videobuf2-v4l2.c | 2 +- > include/uapi/linux/videodev2.h| 4 +++- > 3 files changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > index 6f52970..8f6ab85 100644 > --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > @@ -367,7 +367,7 @@ struct v4l2_buffer32 { > __s32 fd; > } m; > __u32 length; > - __u32 reserved2; > + __s32 fence_fd; > __u32 reserved; > }; > > @@ -530,7 +530,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, > struct v4l2_buffer32 __user > put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) || > copy_to_user(&up->timecode, &kp->timecode, sizeof(struct > v4l2_timecode)) || > put_user(kp->sequence, &up->sequence) || > - put_user(kp->reserved2, &up->reserved2) || > + put_user(kp->fence_fd, &up->fence_fd) || > put_user(kp->reserved, &up->reserved) || > put_user(kp->length, &up->length)) > return -EFAULT; > diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c > b/drivers/media/v4l2-core/videobuf2-v4l2.c > index 0c06699..110fb45 100644 > --- a/drivers/media/v4l2-core/videobuf2-v4l2.c > +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c > @@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, > void *pb) > b->timestamp = ns_to_timeval(vb->timestamp); > b->timecode = vbuf->timecode; > b->sequence = vbuf->sequence; > - b->reserved2 = 0; > + b->fence_fd = -1; > b->reserved = 0; > > if (q->is_multiplanar) { > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h > index 2b8feb8..750d511 100644 > --- a/include/uapi/linux/videodev2.h > +++ b/include/uapi/linux/videodev2.h > @@ -916,7 +916,7 @@ struct v4l2_buffer { > __s32 fd; > } m; > __u32 length; > - __u32 reserved2; > + __s32 fence_fd; > __u32 reserved; > }; > > @@ -953,6 +953,8 @@ struct v4l2_buffer { > #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE 0x0001 > /* mem2mem encoder/decoder */ > #define V4L2_BUF_FLAG_LAST 0x0010 > +#define V4L2_BUF_FLAG_IN_FENCE 0x0020 > +#define V4L2_BUF_FLAG_OUT_FENCE 0x0040 Please document them at Documentation/media/uapi/v4l/buffer.rst. We'll also need a new chapter at the documentation, describing the explicit fences mechanism. > > /** > * struct v4l2_exportbuffer - export of video buffer as DMABUF file > descriptor -- Thanks, Mauro
Re: [PATCH RFC 1/2] [media] v4l2: add V4L2_INPUT_TYPE_DEFAULT
Hi Hans and others, On Mon, Jun 12, 2017 at 11:26:12AM +0200, Hans Verkuil wrote: > On 06/06/2017 06:22 PM, Helen Koike wrote: > > Hi All, > > > > Just reviving this discussion > > > > On 2017-04-07 06:53 AM, Laurent Pinchart wrote: > > > Hi Hans, > > > > > > On Friday 07 Apr 2017 11:46:48 Hans Verkuil wrote: > > > > On 04/04/2017 03:22 PM, Sakari Ailus wrote: > > > > > On Mon, Apr 03, 2017 at 12:11:54PM -0300, Helen Koike wrote: > > > > > > On 2017-03-31 06:57 AM, Mauro Carvalho Chehab wrote: > > > > > > > Em Fri, 31 Mar 2017 10:29:04 +0200 Hans Verkuil escreveu: > > > > > > > > On 30/03/17 18:02, Helen Koike wrote: > > > > > > > > > Add V4L2_INPUT_TYPE_DEFAULT and helpers functions for input > > > > > > > > > ioctls to > > > > > > > > > be used when no inputs are available in the device > > > > > > > > > > > > > > > > > > Signed-off-by: Helen Koike > > > > > > > > > --- > > > > > > > > > drivers/media/v4l2-core/v4l2-ioctl.c | 27 > > > > > > > > > +++ > > > > > > > > > include/media/v4l2-ioctl.h | 26 > > > > > > > > > ++ > > > > > > > > > include/uapi/linux/videodev2.h | 1 + > > > > > > > > > 3 files changed, 54 insertions(+) > > > > > > > > > > > > > > > > > > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c > > > > > > > > > b/drivers/media/v4l2-core/v4l2-ioctl.c index 0c3f238..ccaf04b > > > > > > > > > 100644 > > > > > > > > > --- a/drivers/media/v4l2-core/v4l2-ioctl.c > > > > > > > > > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c > > > > > > > > > @@ -2573,6 +2573,33 @@ struct mutex > > > > > > > > > *v4l2_ioctl_get_lock(struct > > > > > > > > > video_device *vdev, unsigned cmd) > > > > > > > > > return vdev->lock; > > > > > > > > > } > > > > > > > > > > > > > > > > > > +int v4l2_ioctl_enum_input_default(struct file *file, void > > > > > > > > > *priv, > > > > > > > > > + struct v4l2_input *i) > > > > > > > > > +{ > > > > > > > > > + if (i->index > 0) > > > > > > > > > + return -EINVAL; > > > > > > > > > + > > > > > > > > > + memset(i, 0, sizeof(*i)); > > > > > > > > > + i->type = V4L2_INPUT_TYPE_DEFAULT; > > > > > > > > > + strlcpy(i->name, "Default", sizeof(i->name)); > > > > > > > > > + > > > > > > > > > + return 0; > > > > > > > > > +} > > > > > > > > > +EXPORT_SYMBOL(v4l2_ioctl_enum_input_default); > > > > > > > > > + > > > > > > > > > +int v4l2_ioctl_g_input_default(struct file *file, void *priv, > > > > > > > > > unsigned int *i) > > > > > > > > > +{ > > > > > > > > > + *i = 0; > > > > > > > > > + return 0; > > > > > > > > > +} > > > > > > > > > +EXPORT_SYMBOL(v4l2_ioctl_g_input_default); > > > > > > > > > + > > > > > > > > > +int v4l2_ioctl_s_input_default(struct file *file, void *priv, > > > > > > > > > unsigned int i) > > > > > > > > > +{ > > > > > > > > > + return i ? -EINVAL : 0; > > > > > > > > > +} > > > > > > > > > +EXPORT_SYMBOL(v4l2_ioctl_s_input_default); > > > > > > > > > + > > > > > > > > > /* Common ioctl debug function. This function can be used by > > > > > > > > > external ioctl messages as well as internal V4L ioctl */ > > > > > > > > > > > > > > > > > > void v4l_printk_ioctl(const char *prefix, unsigned int cmd) > > > > > > > > > diff --git a/include/media/v4l2-ioctl.h > > > > > > > > > b/include/media/v4l2-ioctl.h > > > > > > > > > index 6cd94e5..accc470 100644 > > > > > > > > > --- a/include/media/v4l2-ioctl.h > > > > > > > > > +++ b/include/media/v4l2-ioctl.h > > > > > > > > > @@ -652,6 +652,32 @@ struct video_device; > > > > > > > > > */ > > > > > > > > > > > > > > > > > > struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, > > > > > > > > > unsigned > > > > > > > > > int cmd); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + * v4l2_ioctl_enum_input_default - v4l2 ioctl helper for > > > > > > > > > VIDIOC_ENUM_INPUT ioctl > > > > > > > > > + * > > > > > > > > > + * Plug this function in vidioc_enum_input field of the > > > > > > > > > struct > > > > > > > > > v4l2_ioctl_ops to > > > > > > > > > + * enumerate a single input as V4L2_INPUT_TYPE_DEFAULT > > > > > > > > > + */ > > > > > > > > > +int v4l2_ioctl_enum_input_default(struct file *file, void > > > > > > > > > *priv, > > > > > > > > > + struct v4l2_input *i); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + * v4l2_ioctl_g_input_default - v4l2 ioctl helper for > > > > > > > > > VIDIOC_G_INPUT > > > > > > > > > ioctl > > > > > > > > > + * > > > > > > > > > + * Plug this function in vidioc_g_input field of the struct > > > > > > > > > v4l2_ioctl_ops > > > > > > > > > + * when using v4l2_ioctl_enum_input_default > > > > > > > > > + */ > > > > > > > > > +int v4l2_ioctl_g_input_default(struct file *file, void *priv, > > > > > > > > > unsigned int *i); > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + * v4l2_ioctl_s_input_default - v4l2 ioctl helper for > > > > > > > > > VIDIO
Re: [PATCH] media: platform: davinci: drop VPFE_CMD_S_CCDC_RAW_PARAMS
Hi Arnd, On Fri, Jun 30, 2017 at 11:03 AM, Arnd Bergmann wrote: > On Fri, Jun 30, 2017 at 11:32 AM, Prabhakar > wrote: >> From: "Lad, Prabhakar" >> >> For dm355 and dm644x the vpfe driver provided a ioctl to >> configure the raw bayer config using a IOCTL, but since >> the code was not properly implemented and aswell the >> IOCTL was marked as 'experimental ioctl that will change >> in future kernels', dropping this IOCTL. >> >> Signed-off-by: Lad, Prabhakar >> --- >> As discussed at [1], there wouldn’t be any possible users of >> the VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL, but if someone complains >> we might end up reverting the removal and fix it differently. >> >> Note: This patch is on top of [1]. >> >> [1] https://patchwork.kernel.org/patch/9779385/ > > Acked-by: Arnd Bergmann > Thanks for the Ack. > I think it would be good to backport one or both of the patches to > stable kernels, to close the potential risk of someone abusing the > ioctl. I think just your patch should be suffice to the stable kernel, blocking this IOCTL. Cheers, --Prabhakar Lad
[PATCH 1/1] media: usb: uvc: Fix incorrect timeout for Get Request
Section 9.2.6.4 of USB 2.0 specification describes that "device must be able to return the first data packet to host within 500 ms of receipt of the request. For subsequent data packet, if any, the device must be able to return them within 500 ms". This patch is to change incorrect timeout from 300 to 500 ms for Get Request. Signed-off-by: Jim Lin --- drivers/media/usb/uvc/uvcvideo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 15e415e..296b69b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -166,7 +166,7 @@ /* Maximum status buffer size in bytes of interrupt URB. */ #define UVC_MAX_STATUS_SIZE16 -#define UVC_CTRL_CONTROL_TIMEOUT 300 +#define UVC_CTRL_CONTROL_TIMEOUT 500 #define UVC_CTRL_STREAMING_TIMEOUT 5000 /* Maximum allowed number of control mappings per device */ -- 2.7.4
Re: [PATCH] media: platform: davinci: drop VPFE_CMD_S_CCDC_RAW_PARAMS
On Fri, Jun 30, 2017 at 11:32 AM, Prabhakar wrote: > From: "Lad, Prabhakar" > > For dm355 and dm644x the vpfe driver provided a ioctl to > configure the raw bayer config using a IOCTL, but since > the code was not properly implemented and aswell the > IOCTL was marked as 'experimental ioctl that will change > in future kernels', dropping this IOCTL. > > Signed-off-by: Lad, Prabhakar > --- > As discussed at [1], there wouldn’t be any possible users of > the VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL, but if someone complains > we might end up reverting the removal and fix it differently. > > Note: This patch is on top of [1]. > > [1] https://patchwork.kernel.org/patch/9779385/ Acked-by: Arnd Bergmann I think it would be good to backport one or both of the patches to stable kernels, to close the potential risk of someone abusing the ioctl.
Re: [PATCH] [media] media/platform: add const to v4l2_file_operations structures
Hi, Thanks for the patch. On Thu, Jun 29, 2017 at 9:51 AM, Bhumika Goyal wrote: > Declare v4l2_file_operations structures as const as they are only stored > in the fops field of video_device structures. This field is of type > const, so declare v4l2_file_operations structures with similar properties > as const. > > Cross compiled bfin_capture.o for blackfin arch. vpbe_display.o file did > not cross compile for arm. Could not find any architecture matching the > configuraion symbol for fsl-viu.c file. > s/configuraion/configuration Ideally the above statement should go below --- (after the signoff) so that its not the part of commit message. > Signed-off-by: Bhumika Goyal > --- > drivers/media/platform/davinci/vpbe_display.c | 2 +- > drivers/media/platform/davinci/vpif_capture.c | 2 +- For above: Acked-by: Lad, Prabhakar Cheers, --Prabhakar Lad
Re: [PATCH] [media] davinci/dm644x: work around ccdc_update_raw_params trainwreck
Hi Arnd, On Tue, Jun 27, 2017 at 12:08 PM, Arnd Bergmann wrote: > On Tue, Jun 27, 2017 at 12:13 PM, Sekhar Nori wrote: >> On Tuesday 20 June 2017 06:36 PM, Lad, Prabhakar wrote: >>> Hi Arnd, >>> >>> Thanks for the patch. >>> >>> On Fri, Jun 9, 2017 at 10:36 PM, Arnd Bergmann wrote: Now that the davinci drivers can be enabled in compile tests on other architectures, I ran into this warning on a 64-bit build: drivers/media/platform/davinci/dm644x_ccdc.c: In function 'ccdc_update_raw_params': drivers/media/platform/davinci/dm644x_ccdc.c:279:7: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] While that looks fairly harmless (it would be fine on 32-bit), it was just the tip of the iceberg: - The function constantly mixes up pointers and phys_addr_t numbers - This is part of a 'VPFE_CMD_S_CCDC_RAW_PARAMS' ioctl command that is described as an 'experimental ioctl that will change in future kernels', but if we have users that probably won't happen. - The code to allocate the table never gets called after we copy_from_user the user input over the kernel settings, and then compare them for inequality. - We then go on to use an address provided by user space as both the __user pointer for input and pass it through phys_to_virt to come up with a kernel pointer to copy the data to. This looks like a trivially exploitable root hole. This patch disables all the obviously broken code, by zeroing out the sensitive data provided by user space. I also fix the type confusion here. If we think the ioctl has no stable users, we could consider just removing it instead. >>> I suspect there shouldn’t be possible users of this IOCTL, better of >>> removing >>> the IOCTL itself. >>> >>> Sekhar your call, as the latest PSP releases for 644x use the media >>> controller framework. >> >> I do not have any personal experience with anyone using this support >> with latest kernels. I too am okay with removing the broken support. > > Ok, I think that would be good. Can one of you create that patch? > Note that we have two implementations of the ioctl, with different > data structures, depending on the specific hardware. > I have posted a patch on top of yours. Acked-by: Lad, Prabhakar >> Since the header file that defines the ioctl is not in include/uapi/*, I >> guess it cannot be considered stable userspace ABI? Also, there are >> enough warnings about instability thrown in the comments surrounding the >> ioctl in include/media/davinci/vpfe_capture.h. > > This is not relevant really. The only thing that counts is whether there > is existing user space that has active users who complain if it breaks. > > If you think nobody is using it, that is more important than code > comments or the location of the header file, but if someone complains > later anyway, we may end up reverting the removal and fix it differently. > Agreed. Cheers, --Prabhakar Lad
[PATCH] media: platform: davinci: drop VPFE_CMD_S_CCDC_RAW_PARAMS
From: "Lad, Prabhakar" For dm355 and dm644x the vpfe driver provided a ioctl to configure the raw bayer config using a IOCTL, but since the code was not properly implemented and aswell the IOCTL was marked as 'experimental ioctl that will change in future kernels', dropping this IOCTL. Signed-off-by: Lad, Prabhakar --- As discussed at [1], there wouldn’t be any possible users of the VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL, but if someone complains we might end up reverting the removal and fix it differently. Note: This patch is on top of [1]. [1] https://patchwork.kernel.org/patch/9779385/ drivers/media/platform/davinci/ccdc_hw_device.h | 10 -- drivers/media/platform/davinci/dm355_ccdc.c | 1 - drivers/media/platform/davinci/dm644x_ccdc.c| 151 drivers/media/platform/davinci/vpfe_capture.c | 93 --- include/media/davinci/dm644x_ccdc.h | 12 -- include/media/davinci/vpfe_capture.h| 10 -- 6 files changed, 277 deletions(-) diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h index 8f6688a..f1b5210 100644 --- a/drivers/media/platform/davinci/ccdc_hw_device.h +++ b/drivers/media/platform/davinci/ccdc_hw_device.h @@ -42,16 +42,6 @@ struct ccdc_hw_ops { int (*set_hw_if_params) (struct vpfe_hw_if_param *param); /* get interface parameters */ int (*get_hw_if_params) (struct vpfe_hw_if_param *param); - /* -* Pointer to function to set parameters. Used -* for implementing VPFE_S_CCDC_PARAMS -*/ - int (*set_params) (void *params); - /* -* Pointer to function to get parameter. Used -* for implementing VPFE_G_CCDC_PARAMS -*/ - int (*get_params) (void *params); /* Pointer to function to configure ccdc */ int (*configure) (void); diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 73db166..4682f22 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -939,7 +939,6 @@ static struct ccdc_hw_device ccdc_hw_dev = { .enable = ccdc_enable, .enable_out_to_sdram = ccdc_enable_output_to_sdram, .set_hw_if_params = ccdc_set_hw_if_params, - .set_params = ccdc_set_params, .configure = ccdc_configure, .set_buftype = ccdc_set_buftype, .get_buftype = ccdc_get_buftype, diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 1b42f50..1ec1886 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -216,106 +216,8 @@ static void ccdc_readregs(void) dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val); } -static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) -{ - if (ccdcparam->alaw.enable) { - u8 max_gamma = ccdc_gamma_width_max_bit(ccdcparam->alaw.gamma_wd); - u8 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz); - - if ((ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) || - (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_15_6) || - (max_gamma > max_data)) { - dev_dbg(ccdc_cfg.dev, "\nInvalid data line select"); - return -1; - } - } - return 0; -} - -static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) -{ - struct ccdc_config_params_raw *config_params = - &ccdc_cfg.bayer.config_params; - unsigned int *fpc_virtaddr; - phys_addr_t fpc_physaddr; - - memcpy(config_params, raw_params, sizeof(*raw_params)); - - /* -* FIXME: the code to copy the fault_pxl settings was present -*in the original version but clearly could never -*work and will interpret user-provided data in -*dangerous ways. Let's disable it completely to be -*on the safe side. -*/ - config_params->fault_pxl.enable = 0; - config_params->fault_pxl.fp_num = 0; - config_params->fault_pxl.fpc_table_addr = 0; - - /* -* allocate memory for fault pixel table and copy the user -* values to the table -*/ - if (!config_params->fault_pxl.enable) - return 0; - - fpc_physaddr = config_params->fault_pxl.fpc_table_addr; - fpc_virtaddr = (unsigned int *)phys_to_virt(fpc_physaddr); - /* -* Allocate memory for FPC table if current -* FPC table buffer is not big enough to -* accommodate FPC Number requested -*/ - if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) { - if (fpc_physaddr) { - fre
Re: [PATCH v3 2/4] media: adv7180: add adv7180cp, adv7180st compatible strings
Hi Ulrich, On Fri, May 19, 2017 at 3:07 PM, Ulrich Hecht wrote: > Used to differentiate between models with 3 and 6 inputs. > > Signed-off-by: Ulrich Hecht > --- > drivers/media/i2c/adv7180.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c > index bdbbf8c..78de7dd 100644 > --- a/drivers/media/i2c/adv7180.c > +++ b/drivers/media/i2c/adv7180.c > @@ -1452,6 +1452,8 @@ static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, > adv7180_suspend, adv7180_resume); > #ifdef CONFIG_OF > static const struct of_device_id adv7180_of_id[] = { > { .compatible = "adi,adv7180", }, > + { .compatible = "adi,adv7180cp", }, > + { .compatible = "adi,adv7180st", }, > { .compatible = "adi,adv7182", }, > { .compatible = "adi,adv7280", }, > { .compatible = "adi,adv7280-m", }, Adding compatible entries here is not sufficient, and causes a crash on r8a7793/gose with renesas-drivers-2017-06-27-v4.12-rc7: adv7180 2-0020: chip found @ 0x20 (e653.i2c) Unable to handle kernel NULL pointer dereference at virtual address 0014 pgd = c0003000 [0014] *pgd=8040004003, *pmd= Internal error: Oops: 207 [#1] SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc7-rcar2-initrd #37 Hardware name: Generic R-Car Gen2 (Flattened Device Tree) task: df427040 task.stack: df436000 PC is at adv7180_probe+0x84/0x3cc In the absence of an entry in adv7180_id[], the passed i2c_device_id pointer is NULL, and thus dereferencing it crashes the system. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [Patch v5 12/12] Documention: v4l: Documentation for HEVC CIDs
On Wed, 2017-06-28 at 22:04 +0200, Kamil Debski wrote: > Hi, > > Please find my comments inline. > > On 19 June 2017 at 07:10, Smitha T Murthy wrote: > > Added V4l2 controls for HEVC encoder > > > > Signed-off-by: Smitha T Murthy > > --- > > Documentation/media/uapi/v4l/extended-controls.rst | 364 > > + > > 1 file changed, 364 insertions(+) > > > > diff --git a/Documentation/media/uapi/v4l/extended-controls.rst > > b/Documentation/media/uapi/v4l/extended-controls.rst > > index abb1057..7767c70 100644 > > --- a/Documentation/media/uapi/v4l/extended-controls.rst > > +++ b/Documentation/media/uapi/v4l/extended-controls.rst > > @@ -1960,6 +1960,370 @@ enum v4l2_vp8_golden_frame_sel - > > 1, 2 and 3 corresponding to encoder profiles 0, 1, 2 and 3. > > > > > > [snip] > > > + > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (integer)`` > > +Selects the hierarchical coding layer. In normal encoding > > +(non-hierarchial coding), it should be zero. Possible values are 0 ~ 6. > > +0 indicates HIERARCHICAL CODING LAYER 0, 1 indicates HIERARCHICAL > > CODING > > +LAYER 1 and so on. > > I would like the above to be more consistent. If HIER is in the name > then HIER in the description should be used as well. Aside from that, > I would recommend using full HIERARCHICAL instead of HIER in the name > of the control. Why? Because it is HIERARCHICAL in controls already > present in V4L2, such as > V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP. > I had changed it from HIERARCHICAL to HIER as per suggestion by Sylwester Nawrocki. Here https://patchwork.kernel.org/patch/9666129/ > [snip] > > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_LF (boolean)`` > > +Indicates loop filtering. Control value 1 indicates loop filtering > > +is enabled and when set to 0 indicates loop filtering is disabled. > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_LF_SLICE_BOUNDARY (boolean)`` > > +Selects whether to apply the loop filter across the slice boundary or > > not. > > +If the value is 0, loop filter will not be applied across the slice > > boundary. > > +If the value is 1, loop filter will be applied across the slice > > boundary. > > Just a thought. Pretty much the same fucntionality is achieved via the > V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE control. It's an enum having > three states: enabled, disabled and disabled at slice boundary. Maybe > a single control could be introduced? With another legacy define for > API compatibility. Also, I don't like that controls are not consistent > between H264 and HEVC. I would opt for the enum option. > I will add enum options for the above control. > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (integer)`` > > +Selects HEVC loop filter beta offset. The valid range is [-6, +6]. > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (integer)`` > > +Selects HEVC loop filter tc offset. The valid range is [-6, +6]. > > + > > +.. _v4l2-hevc-refresh-type: > > + > > +``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE`` > > +(enum) > > + > [snip] > > Best wishes, > Kamil > > Thank you for the review. Regards, Smitha
[PATCH] lirc_dev: sanitize locking (v2)
Use the irctl mutex for all device operations and only use lirc_dev_lock to protect the irctls array. Also, make sure that the device is alive early in each fops function before doing anything else. Since this patch touches nearly every line where the irctl mutex is taken/released, it also renames the mutex at the same time (the name irctl_lock will be misleading once struct irctl goes away in later patches). V2: make sure ir->d.minor is set as well once allocated (found by Fengguang Wu ) Signed-off-by: David Härdeman --- drivers/media/rc/lirc_dev.c | 165 --- 1 file changed, 92 insertions(+), 73 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index aece6b619796..55ed65621bbd 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -38,7 +38,7 @@ struct irctl { bool attached; int open; - struct mutex irctl_lock; + struct mutex mutex; struct lirc_buffer *buf; bool buf_internal; @@ -46,6 +46,7 @@ struct irctl { struct cdev cdev; }; +/* This mutex protects the irctls array */ static DEFINE_MUTEX(lirc_dev_lock); static struct irctl *irctls[MAX_IRCTL_DEVICES]; @@ -53,18 +54,23 @@ static struct irctl *irctls[MAX_IRCTL_DEVICES]; /* Only used for sysfs but defined to void otherwise */ static struct class *lirc_class; -static void lirc_release(struct device *ld) +static void lirc_free_buffer(struct irctl *ir) { - struct irctl *ir = container_of(ld, struct irctl, dev); - if (ir->buf_internal) { lirc_buffer_free(ir->buf); kfree(ir->buf); + ir->buf = NULL; } +} + +static void lirc_release(struct device *ld) +{ + struct irctl *ir = container_of(ld, struct irctl, dev); mutex_lock(&lirc_dev_lock); irctls[ir->d.minor] = NULL; mutex_unlock(&lirc_dev_lock); + lirc_free_buffer(ir); kfree(ir); } @@ -141,6 +147,28 @@ int lirc_register_driver(struct lirc_driver *d) return -EBADRQC; } + /* some safety check 8-) */ + d->name[sizeof(d->name)-1] = '\0'; + + if (d->features == 0) + d->features = LIRC_CAN_REC_LIRCCODE; + + ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) + return -ENOMEM; + + mutex_init(&ir->mutex); + ir->d = *d; + + if (LIRC_CAN_REC(d->features)) { + err = lirc_allocate_buffer(ir); + if (err) { + kfree(ir); + return err; + } + d->rbuf = ir->buf; + } + mutex_lock(&lirc_dev_lock); /* find first free slot for driver */ @@ -150,37 +178,18 @@ int lirc_register_driver(struct lirc_driver *d) if (minor == MAX_IRCTL_DEVICES) { dev_err(d->dev, "no free slots for drivers!\n"); - err = -ENOMEM; - goto out_lock; - } - - ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); - if (!ir) { - err = -ENOMEM; - goto out_lock; + mutex_unlock(&lirc_dev_lock); + lirc_free_buffer(ir); + kfree(ir); + return -ENOMEM; } - mutex_init(&ir->irctl_lock); irctls[minor] = ir; d->irctl = ir; d->minor = minor; + ir->d.minor = minor; - /* some safety check 8-) */ - d->name[sizeof(d->name)-1] = '\0'; - - if (d->features == 0) - d->features = LIRC_CAN_REC_LIRCCODE; - - ir->d = *d; - - if (LIRC_CAN_REC(d->features)) { - err = lirc_allocate_buffer(irctls[minor]); - if (err) { - kfree(ir); - goto out_lock; - } - d->rbuf = ir->buf; - } + mutex_unlock(&lirc_dev_lock); device_initialize(&ir->dev); ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor); @@ -194,22 +203,15 @@ int lirc_register_driver(struct lirc_driver *d) ir->attached = true; err = cdev_device_add(&ir->cdev, &ir->dev); - if (err) - goto out_dev; - - mutex_unlock(&lirc_dev_lock); + if (err) { + put_device(&ir->dev); + return err; + } dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", ir->d.name, ir->d.minor); return 0; - -out_dev: - put_device(&ir->dev); -out_lock: - mutex_unlock(&lirc_dev_lock); - - return err; } EXPORT_SYMBOL(lirc_register_driver); @@ -222,11 +224,13 @@ void lirc_unregister_driver(struct lirc_driver *d) ir = d->irctl; - mutex_lock(&lirc_dev_lock); - dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", d->name, d->minor); + cdev_device_del(&ir->cdev, &ir->dev); + +
Re: [PATCH v1.1 2/2] drm: rcar-du: Repair vblank for DRM page flips using the VSP1
Hi Kieran > -static void rcar_du_vsp_complete(void *private) > +static void rcar_du_vsp_complete(void *private, bool completed) > { > struct rcar_du_crtc *crtc = private; > > - rcar_du_crtc_finish_page_flip(crtc); > + if (crtc->vblank_enable) > + drm_crtc_handle_vblank(&crtc->crtc); > + > + if (completed) > + rcar_du_crtc_finish_page_flip(crtc); > } Here, this "vblank_enable" flag, timestamp will be update on drm_crtc_handle_vblank(). For example modetest Flip test, if we stop it by Ctrl+C, then, vblank_enable will be false, Then, vblank timestamp isn't updated on waiting method on drm_atomic_helper_wait_for_vblanks(). Thus we will have timeout error. And, print complete is now indicated on VSP Frame End, in interlace input case, print complete will be indicated to user on each ODD, EVEN timing. Before this patch, for example 1080i@60Hz, print complete indication happen in 30Hz. After this patch, in interlace case, indication coming 60Hz Best regards --- Kuninori Morimoto
Re: [PATCH v2 04/19] media: camss: Add CSIPHY files
Hi Todor, On Fri, Jun 30, 2017 at 10:00:25AM +0300, Todor Tomov wrote: > Hi Sakari, > > On 06/30/2017 02:53 AM, Sakari Ailus wrote: > > Hi Todor, > > > > On Thu, Jun 29, 2017 at 07:36:47PM +0300, Todor Tomov wrote: > +/* > + * csiphy_link_setup - Setup CSIPHY connections > + * @entity: Pointer to media entity structure > + * @local: Pointer to local pad > + * @remote: Pointer to remote pad > + * @flags: Link flags > + * > + * Rreturn 0 on success > + */ > +static int csiphy_link_setup(struct media_entity *entity, > + const struct media_pad *local, > + const struct media_pad *remote, u32 flags) > +{ > +if ((local->flags & MEDIA_PAD_FL_SOURCE) && > +(flags & MEDIA_LNK_FL_ENABLED)) { > +struct v4l2_subdev *sd; > +struct csiphy_device *csiphy; > +struct csid_device *csid; > + > +if (media_entity_remote_pad((struct media_pad *)local)) > >>> > >>> This is ugly. > >>> > >>> What do you intend to find with media_entity_remote_pad()? The pad flags > >>> haven't been assigned to the pad yet, so media_entity_remote_pad() could > >>> give you something else than remote. > >> > >> This is an attempt to check whether the pad is already linked - to refuse > >> a second active connection from the same src pad. As far as I can say, it > >> was a successful attempt. Do you see any problem with it? > > > > Ah. So you have multiple links here only one of which may be active? > > Exactly. Below I'm adding the output of media-ctl --print-dot as you have > requested. I can add it in the driver document as well. Hmm. I think it could be useful there as an example. I wonder what others think. > > > > > I guess you can well use media_entity_remote_pad(), but then > > media_entity_remote_pad() argument needs to be made const. Feel free to > > spin a patch. I don't think it'd have further implications elsewhere. > > > > Well media_entity_remote_pad() accepts struct media_pad *pad, not a > const and trying to pass a const triggers a warning. This is why I had > to cast. Or did I misunderstand you? No, you don't cast to non-const. Instead, you change the function to accept a const argument. -- Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
Re: [PATCH RFC 2/2] dt-bindings: add binding documentation for Allwinner CSI
On Fri, 30 Jun 2017 11:41:50 +0800 Chen-Yu Tsai wrote: > On Fri, Jun 30, 2017 at 5:19 AM, Rob Herring wrote: > > On Tue, Jun 27, 2017 at 07:07:34PM +0800, Yong Deng wrote: > >> Add binding documentation for Allwinner CSI. > > > > For the subject: > > > > dt-bindings: media: Add Allwinner Camera Sensor Interface (CSI) > > > > "binding documentation" is redundant. OK. > > > >> > >> Signed-off-by: Yong Deng > >> --- > >> .../devicetree/bindings/media/sunxi-csi.txt| 51 > >> ++ > >> 1 file changed, 51 insertions(+) > >> create mode 100644 Documentation/devicetree/bindings/media/sunxi-csi.txt > >> > >> diff --git a/Documentation/devicetree/bindings/media/sunxi-csi.txt > >> b/Documentation/devicetree/bindings/media/sunxi-csi.txt > >> new file mode 100644 > >> index 000..770be0e > >> --- /dev/null > >> +++ b/Documentation/devicetree/bindings/media/sunxi-csi.txt > >> @@ -0,0 +1,51 @@ > >> +Allwinner V3s Camera Sensor 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 > >> +* ahb: 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 > >> + > >> +- ports: A ports node with endpoint definitions as defined in > >> + Documentation/devicetree/bindings/media/video-interfaces.txt. The > >> + first port should be the input endpoints, the second one the outputs > > > > Is there more than one endpoint for each port? If so, need to define > > that numbering too. I made a mistake here. "The first port should be the input endpoints, the second one the outputs" is wrong and redundant. > > It is possible to have multiple camera sensors connected to the same > bus. Think front and back cameras on a cell phone or tablet. > > I don't think any kind of numbering makes much sense though. The > system is free to use just one sensor at a time, or use many with > some time multiplexing scheme. What might matter to the end user > is where the camera is placed. But using the position or orientation > as a numbering scheme might not work well either. Someone may end > up using two sensors with the same orientation for stereoscopic > vision. It is! But multiple sensors can't be working on the same bus simultaneously. So, the driver should have capability to switch input device. But my driver does not support switching between multiple camera sensors for now! The driver only pickup the first valid one. Maybe it's a feature to implement in the future. Maybe like this: - port: A port node with endpoint definitions as defined in Documentation/devicetree/bindings/media/video-interfaces.txt. A CSI have only one port. But you can define multiple endpoint under the port. The driver will pick up the first valid one. > > > > >> + > >> +Example: > >> + > >> + csi1: csi@01cb4000 { > >> + compatible = "allwinner,sun8i-v3s-csi"; > >> + reg = <0x01cb4000 0x1000>; > > Yong, the address range size is 0x4000, including the CCI (I2C) > controller at offset 0x3000. You should also consider this in > the device tree binding, and the driver. > > ChenYu For V3s, the reg range <0x01cb 0x4000> of CSI0 have 4 module: * <0x01cb 0x1000> -- CSI0 * <0x01cb1000 0x1000> -- MIPI-CSI * <0x01cb2000 0x1000> -- MIPI-DPHY * <0x01cb3000 0x1000> -- CCI the reg range <0x01cb4000 0x4000> of CSI1 have 1 module: * <0x01cb4000 0x1000> -- CSI1 And, I think the CCI, MIPI-CSI, MIPI-DPHY should have their own device tree binding and driver. > > >> + interrupts = ; > >> + clocks = <&ccu CLK_BUS_CSI>, > >> + <&ccu CLK_CSI1_SCLK>, > >> + <&ccu CLK_DRAM_CSI>; > >> + clock-names = "ahb", "mod", "ram"; > >> + resets = <&ccu RST_BUS_CSI>; > >> + > >> + port { > >> + #address-cells = <1>; > >> + #size-cells = <0>; > >> + > >> + /* Parallel bus endpoint */ > >> + csi1_0: endpoint@0 { > >> + reg = <0>; > > > > Don't need this and everything associated with it for a single endpoint. Like this? csi1_ep: endpoint { remote-endpoint = <&adv7611_ep>; bus-width = <16>; data-shift = <0>; /* If hsync-active/vsync-active are missing, embedded BT.656 sync is used */ hsync-active = <0>; /* Active low */ vsync-active = <0>; /* Active low */ data-active = <1>; /* Active high */ pclk-sample = <1>; /* Rising *
Re: [PATCH RESEND 0/7] Introduce MEDIA_VERSION to end KENREL_VERSION abuse in media
On Thu, Jun 29, 2017 at 10:01:05AM -0700, Stephen Hemminger wrote: > If you read Linus's comments on version. > Driver version is meaningless and there is a desire to rip it out of all > drivers. The reason is that drivers must always behave the same, i.e you > can't use version to change API/ABI behavior. Indeed this causes more harm than good. We had support calls regarding the mlx4 driver because of not incremented MODLE_VERSION()s. If we follow your and Linus' path we shouldn't just get rid of the KERNEL_VERSION() usage in media and replace it with a new version, but kill all the versioning stuff out of media (and others) except for maybe the HW version. > Any upstream driver should never use KERNEL_VERSION(). Exactly my reasoning. -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: [PATCH v2 04/19] media: camss: Add CSIPHY files
Hi Sakari, On 06/30/2017 02:53 AM, Sakari Ailus wrote: > Hi Todor, > > On Thu, Jun 29, 2017 at 07:36:47PM +0300, Todor Tomov wrote: +/* + * csiphy_link_setup - Setup CSIPHY connections + * @entity: Pointer to media entity structure + * @local: Pointer to local pad + * @remote: Pointer to remote pad + * @flags: Link flags + * + * Rreturn 0 on success + */ +static int csiphy_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + if ((local->flags & MEDIA_PAD_FL_SOURCE) && + (flags & MEDIA_LNK_FL_ENABLED)) { + struct v4l2_subdev *sd; + struct csiphy_device *csiphy; + struct csid_device *csid; + + if (media_entity_remote_pad((struct media_pad *)local)) >>> >>> This is ugly. >>> >>> What do you intend to find with media_entity_remote_pad()? The pad flags >>> haven't been assigned to the pad yet, so media_entity_remote_pad() could >>> give you something else than remote. >> >> This is an attempt to check whether the pad is already linked - to refuse >> a second active connection from the same src pad. As far as I can say, it >> was a successful attempt. Do you see any problem with it? > > Ah. So you have multiple links here only one of which may be active? Exactly. Below I'm adding the output of media-ctl --print-dot as you have requested. I can add it in the driver document as well. > > I guess you can well use media_entity_remote_pad(), but then > media_entity_remote_pad() argument needs to be made const. Feel free to > spin a patch. I don't think it'd have further implications elsewhere. > Well media_entity_remote_pad() accepts struct media_pad *pad, not a const and trying to pass a const triggers a warning. This is why I had to cast. Or did I misunderstand you? # media-ctl -d /dev/media1 --print-dot digraph board { rankdir=TB n0001 [label="msm_csiphy0\n/dev/v4l-subdev0", shape=box, style=filled, fillcolor=yellow] n0001 -> n0007 [style=dashed] n0001 -> n000a [style=dashed] n0004 [label="msm_csiphy1\n/dev/v4l-subdev1", shape=box, style=filled, fillcolor=yellow] n0004 -> n0007 [style=dashed] n0004 -> n000a [style=dashed] n0007 [label="msm_csid0\n/dev/v4l-subdev2", shape=box, style=filled, fillcolor=yellow] n0007 -> n000d [style=dashed] n0007 -> n0010 [style=dashed] n000a [label="msm_csid1\n/dev/v4l-subdev3", shape=box, style=filled, fillcolor=yellow] n000a -> n000d [style=dashed] n000a -> n0010 [style=dashed] n000d [label="msm_ispif0\n/dev/v4l-subdev4", shape=box, style=filled, fillcolor=yellow] n000d -> n0013:port0 [style=dashed] n000d -> n001c:port0 [style=dashed] n000d -> n0025:port0 [style=dashed] n000d -> n002e:port0 [style=dashed] n0010 [label="msm_ispif1\n/dev/v4l-subdev5", shape=box, style=filled, fillcolor=yellow] n0010 -> n0013:port0 [style=dashed] n0010 -> n001c:port0 [style=dashed] n0010 -> n0025:port0 [style=dashed] n0010 -> n002e:port0 [style=dashed] n0013 [label="{{ 0} | msm_vfe0_rdi0\n/dev/v4l-subdev6 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] n0013:port1 -> n0016 [style=bold] n0016 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow] n001c [label="{{ 0} | msm_vfe0_rdi1\n/dev/v4l-subdev7 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] n001c:port1 -> n001f [style=bold] n001f [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow] n0025 [label="{{ 0} | msm_vfe0_rdi2\n/dev/v4l-subdev8 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] n0025:port1 -> n0028 [style=bold] n0028 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow] n002e [label="{{ 0} | msm_vfe0_pix\n/dev/v4l-subdev9 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] n002e:port1 -> n0031 [style=bold] n0031 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow] n0057 [label="{{} | ov5645 1-0076\n/dev/v4l-subdev10 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] n0057:port0 -> n0001 [style=bold] n0059 [label="{{} | ov5645 1-0074\n/dev/v4l-subdev11 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] n0059:port0 -> n0004 [style=bold] } -- Best regards, Todor Tomov