[PATCH v2] media: ir-spi: update Andi's e-mail
From: Andi Shyti <andi.sh...@samsung.com> Because I will be leaving Samsung soon, update my e-mail to the etezian.org mail. CC: Mauro Carvalho Chehab <mche...@kernel.org> CC: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- Hi Sean, thanks for the review and sorry for the late reply. Here is the patch with my mail changed also in the MODULE_AUTHOR macro. Thanks, Andi v1 - v2 changed the mail also in the MODULE_AUTHOR macro drivers/media/rc/ir-spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 7163d5ce2e64..66334e8d63ba 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -2,7 +2,7 @@ // SPI driven IR LED device driver // // Copyright (c) 2016 Samsung Electronics Co., Ltd. -// Copyright (c) Andi Shyti <andi.sh...@samsung.com> +// Copyright (c) Andi Shyti <a...@etezian.org> #include #include @@ -173,6 +173,6 @@ static struct spi_driver ir_spi_driver = { module_spi_driver(ir_spi_driver); -MODULE_AUTHOR("Andi Shyti <andi.sh...@samsung.com>"); +MODULE_AUTHOR("Andi Shyti <a...@etezian.org>"); MODULE_DESCRIPTION("SPI IR LED"); MODULE_LICENSE("GPL v2"); -- 2.17.0
[PATCH] media: ir-spi: update Andi's e-mail
Because I will be leaving Samsung soon, update my e-mail to the etezian.org mail. CC: Mauro Carvalho Chehab <mche...@kernel.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/ir-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index a32a84ae2d0b..26f6ec856297 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -2,7 +2,7 @@ // SPI driven IR LED device driver // // Copyright (c) 2016 Samsung Electronics Co., Ltd. -// Copyright (c) Andi Shyti <andi.sh...@samsung.com> +// Copyright (c) Andi Shyti <a...@etezian.org> #include #include -- 2.16.2
Re: [PATCH] media: rc: ir-spi: fix duty cycle
Hi Sean, On Sat, Jan 27, 2018 at 02:05:37PM +, Sean Young wrote: > Calculate the pulse rather than having a few preset values. > > Cc: Andi Shyti <andi.sh...@samsung.com> > Signed-off-by: Sean Young <s...@mess.org> Looks good to me. Acked-by: Andi Shyti <andi.sh...@samsung.com> Thanks, Andi
Re: [PATCH v3 1/6] media: rc: update sunxi-ir driver to get base clock frequency from devicetree
Hi Philipp, On Tue, Dec 19, 2017 at 09:07:42AM +0100, Philipp Rossak wrote: > This patch updates the sunxi-ir driver to set the base clock frequency from > devicetree. > > This is necessary since there are different ir receivers on the > market, that operate with different frequencies. So this value could be > set if the attached ir receiver needs a different base clock frequency, > than the default 8 MHz. > > Signed-off-by: Philipp Rossak <embe...@gmail.com> feel free to add Reviewed-by: Andi Shyti <andi.sh...@samsung.com> Andi
Re: [PATCH 1/5] media: rc: update sunxi-ir driver to get base clock frequency from devicetree
Hi Philipp, just a couple of small nitpicks. > + u32 b_clk_freq; [...] > + /* Base clock frequency (optional) */ > + if (of_property_read_u32(dn, "clock-frequency", _clk_freq)) { > + b_clk_freq = SUNXI_IR_BASE_CLK; > + } > + how about you intialize 'b_clk_freq' to 'SUNXI_IR_BASE_CLK' and just call 'of_property_read_u32' without if statement. 'b_clk_freq' value should not be changed if "clock-frequency" is not present in the DTS. This might avoid misinterpretation from static analyzers that might think that 'b_clk_freq' is used uninitialized. > + dev_info(dev, "set base clock frequency to %d Hz.\n", b_clk_freq); Please use dev_dbg(). Andi
[PATCH] [media] ir-spi: add SPDX identifier
Replace the original license statement with the SPDX identifier. Update also the copyright owner adding myself as co-owner of the copyright. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/ir-spi.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 29ed0638cb74..a32a84ae2d0b 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -1,13 +1,8 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * Author: Andi Shyti <andi.sh...@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * SPI driven IR LED device driver - */ +// SPDX-License-Identifier: GPL-2.0 +// SPI driven IR LED device driver +// +// Copyright (c) 2016 Samsung Electronics Co., Ltd. +// Copyright (c) Andi Shyti <andi.sh...@samsung.com> #include #include -- 2.15.1
Re: [PATCH v2 4/7] media: usb: add SPDX identifiers to some code I wrote
Hi Mauro, > diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h > b/drivers/media/usb/tm6000/tm6000-usb-isoc.h > index 6a13a27c55d7..e69f5cf8fe9f 100644 > --- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h > +++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h > @@ -1,17 +1,7 @@ > -/* > - * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices > - * > - * Copyright (C) 2006-2007 Mauro Carvalho Chehab> - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation version 2 > - * > - * 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. > - */ > +// SPDX-License-Identifier: GPL-2.0 > +// tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices > +// > +// Copyright (c) 2006-2007 Mauro Carvalho Chehab shouldn't this and all the header files be of the type: /* SPDX-License-Identifier: GPL-2.0 ... */ as stated here: https://lwn.net/Articles/739183/ Andi
Re: [PATCH] media: rc: ir-spi needs OF
On Mon, Oct 09, 2017 at 09:46:50AM +0100, Sean Young wrote: > Without device tree, there is no way to use this driver. > > Signed-off-by: Sean Young <s...@mess.org> Thanks, Sean! Acked-by: Andi Shyti <andi.sh...@samsung.com> Andi > --- > drivers/media/rc/Kconfig | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig > index bde3c271fb88..afb3456d4e20 100644 > --- a/drivers/media/rc/Kconfig > +++ b/drivers/media/rc/Kconfig > @@ -286,6 +286,7 @@ config IR_REDRAT3 > config IR_SPI > tristate "SPI connected IR LED" > depends on SPI && LIRC > + depends on OF || COMPILE_TEST > ---help--- > Say Y if you want to use an IR LED connected through SPI bus. > > -- > 2.13.6 > >
Re: [PATCH v2 00/10] media: rc: gpio-ir-recv: driver update
Hi Ladislav, > > > Serie was rebased on top of current linux.git, but something > > > happened there and my userspace decoder no longer works: driver > > > reports completely bogus timing such as (rc-5): > > > ^427, _1342, ^945, _183, ^1128, _671, ^1586, _91, ^1189, _1525, > > > ^1738, _1433, ^915, _1159, ^1464, _1525, ^213, _1067, ^793, _0 > > > (^ used for pulse and _ for space) > > > As it has nothing to do with my changes, I'm sending it anyway > > > for review, which I do not expect to happen until merge window > > > ends. > > > > This means that your patch is anyway untested. > > Previous version is pretty well tested. GPIO IR stopped working > after pulling other changes from linux.git yesterday. And does not > work even without this patch set. I'll try to bisect later as omiting > linux-media merge did not fix it either. OK > > In any case I don't see much use if patch 1/10 as it doesn't > > simplify much, but the rest (from 2 to 10) looks good to me. > > Just look at patch 9 and imagine how it would look without this > change. If you are still unconvinced I'll drop this change. You don't need to, that's just my personal taste and I'm not strong with it. Patch 1 is quite common and not a big deal anyway. If you like it you like you can leave it :) > > P.S. I don't see in this V2 the changelog from V1. Next time, > > please add the changelog. > > It was just a rebase with conflicts resolved. I do not see how > to describe it better than I did. You could write the above (i.e. V2 fixed rebase conflicts :) ). The reason is that as no change is stated, I have to anyway, as reviewer, compare side by side all patches to figure out if there is any difference (even if small) that is not expected. Thanks, Andi
Re: [PATCH v2 00/10] media: rc: gpio-ir-recv: driver update
Hi Ladislav, > Serie was rebased on top of current linux.git, but something > happened there and my userspace decoder no longer works: driver > reports completely bogus timing such as (rc-5): > ^427, _1342, ^945, _183, ^1128, _671, ^1586, _91, ^1189, _1525, > ^1738, _1433, ^915, _1159, ^1464, _1525, ^213, _1067, ^793, _0 > (^ used for pulse and _ for space) > As it has nothing to do with my changes, I'm sending it anyway > for review, which I do not expect to happen until merge window > ends. This means that your patch is anyway untested. In any case I don't see much use if patch 1/10 as it doesn't simplify much, but the rest (from 2 to 10) looks good to me. Once it's tested you can add Acked-by: Andi Shyti <andi.sh...@samsung.com> Andi P.S. I don't see in this V2 the changelog from V1. Next time, please add the changelog.
Re: [PATCH v1 0/4] media: rc: add support for IR receiver on MT7622 SoC
Hi Sean, > This patchset introduces Consumer IR (CIR) support for MT7622 SoC > implements raw mode for more compatibility with different protocols > as previously SoC did. Before adding support to MT7622 SoC, extra > code refactor is done since there're major differences in register and > field definition from the previous SoC. > > Sean Wang (4): > dt-bindings: media: mtk-cir: Add support for MT7622 SoC > media: rc: mtk-cir: add platform data to adapt into various hardware > media: rc: mtk-cir: add support for MediaTek MT7622 SoC > MAINTAINERS: add entry for MediaTek CIR driver for the whole patchset: Reviewed-by: Andi Shyti <andi.sh...@samsung.com> Andi
Re: [PATCH] [media] ir-spi: Fix issues with lirc API
Hi Anton, On Sun, May 07, 2017 at 11:00:11AM +1000, Anton Blanchard wrote: > From: Anton Blanchard <an...@samba.org> > > The ir-spi driver has 2 issues which prevents it from working with > lirc: > > 1. The ir-spi driver uses 16 bits of SPI data to create one cycle of > the waveform. As such our SPI clock needs to be 16x faster than the > carrier frequency. > > The driver is inconsistent in how it currently handles this. It > initializes it to the carrier frequency: > > But the commit message has some example code which initialises it > to 16x the carrier frequency: > > val = 608000; > ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); > > To maintain compatibility with lirc, always do the frequency adjustment > in the driver. > > 2. lirc presents pulses in microseconds, but the ir-spi driver treats > them as cycles of the carrier. Similar to other lirc drivers, do the > conversion with DIV_ROUND_CLOSEST(). > > Fixes: fe052da49201 ("[media] rc: add support for IR LEDs driven through SPI") > Cc: sta...@vger.kernel.org > Signed-off-by: Anton Blanchard <an...@samba.org> Thanks for fixing it. Reviewed-by: Andi Shyti <andi.sh...@samsung.com> Andi
Re: [PATCH] [media] lirc_dev: fix regression in feature check logic in ioctl
Hi Alexey, this has been already fixed in commit bd291208d7f5 ("[media] lirc_dev: LIRC_{G,S}ET_REC_MODE do not work") by Sean. You need to update your kernel or cherry-pick this patch. In any case, for future patches of this kind, some notes through the lines: On Tue, Apr 04, 2017 at 02:19:16AM +0300, Alexey Ignatov wrote: > Commit 273b902a5b1bfd6977a73c4de3eb96db3cb103cb removed inversion in References to commit should be of the kind: Commit 273b902a5b1b ("[media] lirc_dev: use LIRC_CAN_REC() define to check if the device can receive") Please run checkpatch.pl before sending the patch. > features check conditionals (by accident, perhaps). That change resulted > in erroneous reporting that device can't receive while actually it can. > Fix this. > > Signed-off-by: Alexey IgnatovHere goes: Fixes: 273b902a5b1b ("[media] lirc_dev: use LIRC_CAN_REC() define to check if the device can receive") Cc: because it fixes a bug (check Sean's patch). Thanks, Andi
[PATCH] [media] rc: ir-spi: remove unnecessary initialization
Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/ir-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index c8863f36686a..4ca43383a8e8 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -58,7 +58,7 @@ static int ir_spi_tx(struct rc_dev *dev, /* convert the pulse/space signal to raw binary signal */ for (i = 0; i < count; i++) { int j; - u16 val = ((i + 1) % 2) ? idata->pulse : idata->space; + u16 val; if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE) return -EINVAL; -- 2.11.0
Re: [PATCH v2 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
Hi Sean, >include/linux/compiler.h:253:8: sparse: attribute 'no_sanitize_address': > unknown attribute > >> drivers/media/rc/mtk-cir.c:215:41: sparse: too many arguments for function > >> devm_rc_allocate_device >drivers/media/rc/mtk-cir.c: In function 'mtk_ir_probe': >drivers/media/rc/mtk-cir.c:215:11: error: too many arguments to function > 'devm_rc_allocate_device' > ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW); > ^~~ >In file included from drivers/media/rc/mtk-cir.c:22:0: >include/media/rc-core.h:213:16: note: declared here > struct rc_dev *devm_rc_allocate_device(struct device *dev); >^~~ > > vim +/devm_rc_allocate_device +215 drivers/media/rc/mtk-cir.c > >209ir->base = devm_ioremap_resource(dev, res); >210if (IS_ERR(ir->base)) { >211dev_err(dev, "failed to map registers\n"); >212return PTR_ERR(ir->base); >213} >214 > > 215ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW); this error comes because the patches I pointed out have not been applied yet. I guess you can ignore them as long as you tested yours on top those patches. Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
Hi Sean, > + ir->rc = rc_allocate_device(); Yes, you should use devm_rc_allocate_device(...) Besides, standing to this patch which is not in yet: https://lkml.org/lkml/2016/12/18/39 rc_allocate_device should provide the driver type during allocation, so it should be: ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW); and this line can be removed: > + ir->rc->driver_type = RC_DRIVER_IR_RAW; I don't know when Mauro will take the patch above. Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 0/6] Add support for IR transmitters
Hi, The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. The patchset is based on next-20161218, while the media directory is a bit more outdated. Thanks, Andi Changelog from version 5: - patch 1: fixed rebase conflict on drivers/media/cec/cec-core.c patch 2: fixed checkpatch error patch 3: restored a Kbuild Test Robot error fix which was lost in v5 Changelog from version 4: - patch 2: fixed a slip on a copy/paste which caused the breakage of the input interface for receivers. Thanks again Sean! Changelog from version 3: - Added the patches Sean's review. patch 1: commit ddbf7d5a has introduced the devm_* managed version of rc_allocate_device and rc_register_device, this patch has been rebased on top of it and adds the driver type as a parameter of the devm_rc_allocate_device. patch 3: fixes a warning from the kbuild test robot patch 5: after a discussion with Rob, despite mine, Jacek's and Mauro's objections [*] the binding has been placed under leds/irled/spi-ir-led.txt patch 6: uses the new devm_* allocation and registration rc functions [*] https://www.spinics.net/lists/linux-leds/msg07062.html https://www.spinics.net/lists/linux-leds/msg07164.html https://www.spinics.net/lists/linux-leds/msg07167.html Changelog from version 2: - The original patch number 5 has been abandoned because it was not bringing much benenfit. patch 1: rebased on the new kernel. patch 3: removed the sysfs attribute protocol for transmitters patch 5: the binding has been moved to the leds section instead of the media. Fixed all the comments from Rob patch 6: fixed all the comments from Sean added also Sean's review. Changelog from version 1: - The RFC is now PATCH. The main difference is that this version doesn't try to add the any bit streaming protocol and doesn't modify any LIRC interface specification. patch 1: updates all the drivers using rc_allocate_device patch 2: fixed errors and warning reported from the kbuild test robot patch 5: this patch has been dropped and replaced with a new one which avoids waiting for transmitters. patch 6: added new properties to the dts specification patch 7: the driver uses the pulse/space input and converts it to a bit stream. Andi Shyti (6): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 +++ drivers/hid/hid-picolcd_cir.c | 3 +- drivers/media/cec/cec-core.c | 3 +- drivers/media/common/siano/smsir.c | 3 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +- drivers/media/pci/cx88/cx88-input.c| 3 +- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_input.c| 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 9 + drivers/media/rc/Makefile | 1 + drivers/media/rc/ati_remote.c | 3 +- drivers/media/rc/ene_ir.c | 3 +- drivers/media/rc/fintek-cir.c | 3 +- drivers/media/rc/gpio-ir-recv.c| 3 +- drivers/media/rc/igorplugusb.c | 3 +- drivers/media/rc/iguanair.c| 3 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 3 +- drivers/media/rc/imon.c| 3 +- drivers/media/rc/ir-hix5hd2.c | 3 +- drivers/media/rc/ir-spi.c | 199 + drivers/media/rc/ite-cir.c | 3 +- drivers/media/rc/mceusb.c
[PATCH v6 1/6] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/cec/cec-core.c| 3 +-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 9 ++--- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/serial_ir.c| 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- include/media/rc-core.h | 6 -- 42 files changed, 50 insertions(+), 85 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 96286510f42e..38b0ea8d89e0 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index aca3ab83a8a1..37217e205040 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -239,7 +239,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, #if IS_REACHABLE(CONFIG_RC_CORE) /* Prepare the RC input device */ - adap->rc = rc_allocate_device(); + adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!adap->rc) { pr_err("cec-%s: failed to allocate memory for rc_dev\n", name); @@ -259,7 +259,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.vendor = 0; adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; - adap->rc->driver_type = RC_DRIVER_SCANCODE; adap->rc->driver_name = CEC_NAME; adap->rc->allowed_protocols = RC_BIT_CEC; adap->rc->priv = adap; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 41f2a3939979..ee30c7b8fb15 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/si
[PATCH v6 2/6] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. This patch fixes the following checkpatch error as well: ERROR: do not initialise statics to false #1438: FILE: drivers/media/rc/rc-main.c:1438: + static bool raw_init = false; /* raw decoders loaded? */ Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 143 + 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a6bbceb7147f..7c8411a40305 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1436,16 +1436,12 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev, } EXPORT_SYMBOL_GPL(devm_rc_allocate_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1454,6 +1450,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1463,6 +1472,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init; /* 'false' default value, raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1486,39 +1550,15 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -*
[PATCH v6 5/6] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt diff --git a/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt new file mode 100644 index ..896b6997cf30 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt @@ -0,0 +1,29 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi-led". + +Optional properties: + - duty-cycle: 8 bit balue that represents the percentage of one period + in which the signal is active. It can be 50, 60, 70, 75, 80 or 90. + - led-active-low: boolean value that specifies whether the output is + negated with a NOT gate. + - power-supply: specifies the power source. It can either be a regulator + or a gpio which enables a regulator, i.e. a regulator-fixed as + described in + Documentation/devicetree/bindings/regulator/fixed-regulator.txt + +Example: + + irled@0 { + compatible = "ir-spi-led"; + reg = <0x0>; + spi-max-frequency = <500>; + power-supply = <_led>; + led-active-low; + duty-cycle = /bits/ 8 <60>; + }; -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 3/6] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 42 +- include/media/rc-core.h| 9 ++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7c8411a40305..f527fe1f50ba 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1365,20 +1365,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1507,7 +1511,7 @@ static int rc_setup_rx_device(struct rc_dev *dev) static void rc_free_rx_device(struct rc_dev *dev) { - if (!dev) + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) return; ir_free_table(>rc_map); @@ -1537,7 +1541,8 @@ int rc_register_device(struct rc_dev *dev) atomic_set(>initialized, 0); dev->dev.groups = dev->sysfs_groups; - dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; if (dev->s_filter) dev->sysfs_groups[attr++] = _dev_filter_attr_grp; if (dev->s_wakeup_filter) @@ -1555,11 +1560,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - rc = rc_setup_rx_device(dev); - if (rc) - goto out_dev; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index ba92c86c47ff..e6cb336b4668 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,13 +32,16 @@ do { \ /** * enum rc_driver_type - type of the RC output * - * @RC_DRIVER_SCANCODE:Driver or hardware generates a scancode - * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. - * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode + * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. + * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_IR_RAW_TX: Device transmitter only, + * driver requires pulse/space data sequence. */ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, RC_DRIVER_IR_RAW, + RC_DRIVER_IR_RAW_TX, }; /** -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 4/6] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 1c42a9f2f290..9938e42e0c0b 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -270,12 +270,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 6/6] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through an rc character device. The chardev is handled by the LIRC framework and its functionality basically provides: - write: the driver gets a pulse/space signal and translates it to a binary signal that will be streamed to the IR led through the SPI framework. - set frequency: sets the frequency whith which the data should be sent. This is handle with ioctl with the LIRC_SET_SEND_CARRIER flag (as per lirc documentation) - set duty cycle: this is also handled with ioctl with the LIRC_SET_SEND_DUTY_CYCLE flag. The driver handles duty cycles of 50%, 60%, 70%, 75%, 80% and 90%, calculated on 16bit data. The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; val = 60; ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/Kconfig | 9 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 199 ++ 3 files changed, 209 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 629e8ca15ab3..3351e25d6176 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 3a984ee301e2..938c98b82b22 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index ..d45c60352093 --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +/* pulse value for different duty cycles */ +#define IR_SPI_PULSE_DC_50 0xff00 +#define IR_SPI_PULSE_DC_60 0xfc00 +#define IR_SPI_PULSE_DC_70 0xf800 +#define IR_SPI_PULSE_DC_75 0xf000 +#define IR_SPI_PULSE_DC_80 0xc000 +#define IR_SPI_PULSE_DC_90 0x8000 + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 +#define IR_SPI_MAX_BUFSIZE 4096 + +struct ir_spi_data { + u32 freq; + u8 duty_cycle; + bool negated; + + u16 tx_buf[IR_SPI_MAX_BUFSIZE]; + u16 pulse; + u16 space; + + struct rc_dev *rc; + struct spi_device *spi; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, + unsigned int *buffer, unsigned int count) +{ + int i; + int ret; + unsigned int len = 0; + struct ir_spi_data *idata = dev->priv; + struct spi_transfer xfer; + + /* convert the pulse/space signal to raw binary signal */ + for (i = 0; i < count; i++) { + int j; + u16 val = ((i+1) % 2) ? idata->pulse : idata->space; + + if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE) +
Re: [PATCH v5 2/6] [media] rc-main: split setup and unregister functions
Hi Sean, > On Fri, Dec 16, 2016 at 12:10:26PM +, Sean Young wrote: > > Sorry to add to your woes, but there are some checkpatch warnings and > > errors. Please can you correct these. One is below. > > Actually, the changes are pretty minor, I can fix them up before sending > them to Mauro. Sorry for bothering you. yes, it's an error on the previous code: ERROR: do not initialise statics to false #109: FILE: drivers/media/rc/rc-main.c:1521: + static bool raw_init = false; /* raw decoders loaded? */ total: 1 errors, 0 warnings, 196 lines checked I noticed this already before, but I preferred to leave it in its original status. No worries, if you want I will send the fix, it's indeed quite an easy fix. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 1/6] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- Hi, Sorry for further spamming, but these drivers change so fast and I'm taking too long to finalize this patch series. This is the correct patch which fixes the compile error from the kbuild test robot. The whole patch series, anyway, is rebased on next-161216 and all the files compile. Thanks, Andi drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/cec/cec-core.c| 3 +-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 9 ++--- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/serial_ir.c| 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- include/media/rc-core.h | 6 -- 42 files changed, 50 insertions(+), 85 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 9628651..38b0ea8 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index aca3ab8..37217e2 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -239,7 +239,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, #if IS_REACHABLE(CONFIG_RC_CORE) /* Prepare the RC input device */ - adap->rc = rc_allocate_device(); + adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!adap->rc) { pr_err("cec-%s: failed to allocate memory for rc_dev\n", name); @@ -259,7 +259,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.vendor = 0; adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; - adap->rc->driver_type = RC_DRIVER_SCANCODE; adap->rc->driver_name = CEC_NAME;
[PATCH v5 4/6] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 1c42a9f..9938e42 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -270,12 +270,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 5/6] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt diff --git a/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt new file mode 100644 index 000..896b699 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt @@ -0,0 +1,29 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi-led". + +Optional properties: + - duty-cycle: 8 bit balue that represents the percentage of one period + in which the signal is active. It can be 50, 60, 70, 75, 80 or 90. + - led-active-low: boolean value that specifies whether the output is + negated with a NOT gate. + - power-supply: specifies the power source. It can either be a regulator + or a gpio which enables a regulator, i.e. a regulator-fixed as + described in + Documentation/devicetree/bindings/regulator/fixed-regulator.txt + +Example: + + irled@0 { + compatible = "ir-spi-led"; + reg = <0x0>; + spi-max-frequency = <500>; + power-supply = <_led>; + led-active-low; + duty-cycle = /bits/ 8 <60>; + }; -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 6/6] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through an rc character device. The chardev is handled by the LIRC framework and its functionality basically provides: - write: the driver gets a pulse/space signal and translates it to a binary signal that will be streamed to the IR led through the SPI framework. - set frequency: sets the frequency whith which the data should be sent. This is handle with ioctl with the LIRC_SET_SEND_CARRIER flag (as per lirc documentation) - set duty cycle: this is also handled with ioctl with the LIRC_SET_SEND_DUTY_CYCLE flag. The driver handles duty cycles of 50%, 60%, 70%, 75%, 80% and 90%, calculated on 16bit data. The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; val = 60; ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/Kconfig | 9 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 199 ++ 3 files changed, 209 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 629e8ca..3351e25 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 3a984ee..938c98b 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index 000..d45c603 --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +/* pulse value for different duty cycles */ +#define IR_SPI_PULSE_DC_50 0xff00 +#define IR_SPI_PULSE_DC_60 0xfc00 +#define IR_SPI_PULSE_DC_70 0xf800 +#define IR_SPI_PULSE_DC_75 0xf000 +#define IR_SPI_PULSE_DC_80 0xc000 +#define IR_SPI_PULSE_DC_90 0x8000 + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 +#define IR_SPI_MAX_BUFSIZE 4096 + +struct ir_spi_data { + u32 freq; + u8 duty_cycle; + bool negated; + + u16 tx_buf[IR_SPI_MAX_BUFSIZE]; + u16 pulse; + u16 space; + + struct rc_dev *rc; + struct spi_device *spi; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, + unsigned int *buffer, unsigned int count) +{ + int i; + int ret; + unsigned int len = 0; + struct ir_spi_data *idata = dev->priv; + struct spi_transfer xfer; + + /* convert the pulse/space signal to raw binary signal */ + for (i = 0; i < count; i++) { + int j; + u16 val = ((i+1) % 2) ? idata->pulse : idata->space; + + if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE) + return -EINVAL;
[PATCH v5 2/6] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 143 + 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a6bbceb..7cc700d 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1436,16 +1436,12 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev, } EXPORT_SYMBOL_GPL(devm_rc_allocate_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1454,6 +1450,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1463,6 +1472,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1486,39 +1550,15 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -* to do. -*/ - dev->input_dev->rep[REP_PERIOD] = 125; - path = kobject_get_path(>dev.kobj, GFP_KERNEL); dev_info(>dev, "%s as %s\n", dev->input_name ?: "Unspe
[PATCH v5 0/6] Add support for IR transmitters
Hi, The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. Thanks, Andi Changelog from version 4: - patch 2: fixed a slip on a copy/paste. Thanks again Sean! Changelog from version 3: - Added the patches Sean's review. patch 1: commit ddbf7d5a has introduced the devm_* managed version of rc_allocate_device and rc_register_device, this patch has been rebased on top of it and adds the driver type as a parameter of the devm_rc_allocate_device. patch 3: fixes a warning from the kbuild test robot patch 5: after a discussion with Rob, despite mine, Jacek's and Mauro's objections [*] the binding has been placed under leds/irled/spi-ir-led.txt patch 6: uses the new devm_* allocation and registration rc functions [*] https://www.spinics.net/lists/linux-leds/msg07062.html https://www.spinics.net/lists/linux-leds/msg07164.html https://www.spinics.net/lists/linux-leds/msg07167.html Changelog from version 2: - The original patch number 5 has been abandoned because it was not bringing much benenfit. patch 1: rebased on the new kernel. patch 3: removed the sysfs attribute protocol for transmitters patch 5: the binding has been moved to the leds section instead of the media. Fixed all the comments from Rob patch 6: fixed all the comments from Sean added also Sean's review. Changelog from version 1: - The RFC is now PATCH. The main difference is that this version doesn't try to add the any bit streaming protocol and doesn't modify any LIRC interface specification. patch 1: updates all the drivers using rc_allocate_device patch 2: fixed errors and warning reported from the kbuild test robot patch 5: this patch has been dropped and replaced with a new one which avoids waiting for transmitters. patch 6: added new properties to the dts specification patch 7: the driver uses the pulse/space input and converts it to a bit stream. Andi Shyti (6): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 +++ drivers/hid/hid-picolcd_cir.c | 3 +- drivers/media/cec/cec-core.c | 4 +- drivers/media/common/siano/smsir.c | 3 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +- drivers/media/pci/cx88/cx88-input.c| 3 +- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_input.c| 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 9 + drivers/media/rc/Makefile | 1 + drivers/media/rc/ati_remote.c | 3 +- drivers/media/rc/ene_ir.c | 3 +- drivers/media/rc/fintek-cir.c | 3 +- drivers/media/rc/gpio-ir-recv.c| 3 +- drivers/media/rc/igorplugusb.c | 3 +- drivers/media/rc/iguanair.c| 3 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 3 +- drivers/media/rc/imon.c| 3 +- drivers/media/rc/ir-hix5hd2.c | 3 +- drivers/media/rc/ir-spi.c | 199 + drivers/media/rc/ite-cir.c | 3 +- drivers/media/rc/mceusb.c | 3 +- drivers/media/rc/meson-ir.c| 3 +- drivers/media/rc/nuvoton-cir.c | 3 +- drivers/media/rc/rc-ir-raw.c | 17 +- drivers/media/rc/rc-loopback.c | 3 +- drivers/media/rc/rc-main.c | 186 +++ drivers/media/rc/redrat3.c | 3
[PATCH v5 1/6] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/cec/cec-core.c| 4 ++-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 9 ++--- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/serial_ir.c| 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- include/media/rc-core.h | 6 -- 42 files changed, 51 insertions(+), 85 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 9628651..38b0ea8 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index aca3ab8..2fee148 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -239,7 +239,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, #if IS_REACHABLE(CONFIG_RC_CORE) /* Prepare the RC input device */ - adap->rc = rc_allocate_device(); + adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!adap->rc) { pr_err("cec-%s: failed to allocate memory for rc_dev\n", name); @@ -259,7 +259,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.vendor = 0; adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; - adap->rc->driver_type = RC_DRIVER_SCANCODE; + adap->rc->dev.parent = parent; adap->rc->driver_name = CEC_NAME; adap->rc->allowed_protocols = RC_BIT_CEC; adap->rc->priv = adap; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 41f2a39..ee30c7b 100644 --- a/drivers/media/common/siano/smsir.c +++ b/d
[PATCH v5 3/6] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 42 +- include/media/rc-core.h| 9 ++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7cc700d..19cf15c 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1365,20 +1365,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1507,7 +1511,7 @@ static int rc_setup_rx_device(struct rc_dev *dev) static void rc_free_rx_device(struct rc_dev *dev) { - if (!dev) + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) return; ir_free_table(>rc_map); @@ -1537,7 +1541,8 @@ int rc_register_device(struct rc_dev *dev) atomic_set(>initialized, 0); dev->dev.groups = dev->sysfs_groups; - dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; if (dev->s_filter) dev->sysfs_groups[attr++] = _dev_filter_attr_grp; if (dev->s_wakeup_filter) @@ -1555,11 +1560,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - rc = rc_setup_rx_device(dev); - if (rc) - goto out_dev; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index ba92c86..98d28d5 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,13 +32,16 @@ do { \ /** * enum rc_driver_type - type of the RC output * - * @RC_DRIVER_SCANCODE:Driver or hardware generates a scancode - * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. - * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode + * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. + * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_IR_RAW_TX: Device transmitter only, +driver requires pulse/space data sequence. */ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, RC_DRIVER_IR_RAW, + RC_DRIVER_IR_RAW_TX, }; /** -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/6] [media] rc-main: split setup and unregister functions
> > + /* rc_open will be called here */ > > + rc = input_register_device(dev->input_dev); > > + if (rc) > > + goto out_table; > > + > > + dev->input_dev->dev.parent = >dev; > > + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); > > + dev->input_dev->phys = dev->input_phys; > > + dev->input_dev->name = dev->input_name; > > I was testing your changes, and with this patch none of my rc devices > have input devices associated with them. The problem is that you've changed > the order: input_register_device() should happen AFTER the preceding > 4 lines. This must have been a copy paste error and I don't have transmitters to test it. Thanks for testing it. I will send it again. Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 4/6] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 1c42a9f..9938e42 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -270,12 +270,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/6] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/cec/cec-core.c| 3 +-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 9 ++--- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/serial_ir.c| 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- include/media/rc-core.h | 6 -- 42 files changed, 50 insertions(+), 85 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 9628651..38b0ea8 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index b0137e2..09bc0ba 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -244,7 +244,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, #if IS_REACHABLE(CONFIG_RC_CORE) /* Prepare the RC input device */ - adap->rc = rc_allocate_device(); + adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!adap->rc) { pr_err("cec-%s: failed to allocate memory for rc_dev\n", name); @@ -265,7 +265,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; adap->rc->dev.parent = parent; - adap->rc->driver_type = RC_DRIVER_SCANCODE; adap->rc->driver_name = CEC_NAME; adap->rc->allowed_protocols = RC_BIT_CEC; adap->rc->priv = adap; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 41f2a39..ee30c7b 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -58,7 +58,7 @@ in
[PATCH v4 2/6] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 143 + 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a6bbceb..59fac96 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1436,16 +1436,12 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev, } EXPORT_SYMBOL_GPL(devm_rc_allocate_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1454,6 +1450,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1463,6 +1472,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1486,39 +1550,15 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -* to do. -*/ - dev->input_dev->rep[REP_PERIOD] = 125; - path = kobject_get_path(>dev.kobj, GFP_KERNEL); dev_info(>dev, "%s as %s\n", dev->input_name ?: "Unspe
[PATCH v4 0/6] Add support for IR transmitters
Hi, The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. Thanks, Andi Changelog from version 1: - The RFC is now PATCH. The main difference is that this version doesn't try to add the any bit streaming protocol and doesn't modify any LIRC interface specification. patch 1: updates all the drivers using rc_allocate_device patch 2: fixed errors and warning reported from the kbuild test robot patch 5: this patch has been dropped and replaced with a new one which avoids waiting for transmitters. patch 6: added new properties to the dts specification patch 7: the driver uses the pulse/space input and converts it to a bit stream. Changelog from version 2: - The original patch number 5 has been abandoned because it was not bringing much benenfit. patch 1: rebased on the new kernel. patch 3: removed the sysfs attribute protocol for transmitters patch 5: the binding has been moved to the leds section instead of the media. Fixed all the comments from Rob patch 6: fixed all the comments from Sean added also Sean's review. Changelog from version 3: - Added the patches Sean's review. patch 1: commit ddbf7d5a has introduced the devm_* managed version of rc_allocate_device and rc_register_device, this patch has been rebased on top of it and adds the driver type as a parameter of the devm_rc_allocate_device. patch 3: fixes a warning from the kbuild test robot patch 5: after a discussion with Rob, despite mine, Jacek's and Mauro's objections [*] the binding has been placed under leds/irled/spi-ir-led.txt patch 6: uses the new devm_* allocation and registration rc functions [*] https://www.spinics.net/lists/linux-leds/msg07062.html https://www.spinics.net/lists/linux-leds/msg07164.html https://www.spinics.net/lists/linux-leds/msg07167.html Andi Shyti (6): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 +++ drivers/hid/hid-picolcd_cir.c | 3 +- drivers/media/cec/cec-core.c | 3 +- drivers/media/common/siano/smsir.c | 3 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +- drivers/media/pci/cx88/cx88-input.c| 3 +- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_input.c| 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 9 + drivers/media/rc/Makefile | 1 + drivers/media/rc/ati_remote.c | 3 +- drivers/media/rc/ene_ir.c | 3 +- drivers/media/rc/fintek-cir.c | 3 +- drivers/media/rc/gpio-ir-recv.c| 3 +- drivers/media/rc/igorplugusb.c | 3 +- drivers/media/rc/iguanair.c| 3 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 3 +- drivers/media/rc/imon.c| 3 +- drivers/media/rc/ir-hix5hd2.c | 3 +- drivers/media/rc/ir-spi.c | 199 + drivers/media/rc/ite-cir.c | 3 +- drivers/media/rc/mceusb.c | 3 +- drivers/media/rc/meson-ir.c| 3 +- drivers/media/rc/nuvoton-cir.c | 3 +- drivers/media/rc/rc-ir-raw.c | 17 +- drivers/media/rc/rc-loopback.c | 3 +- drivers/media/rc/rc-main.c | 186 +++ drivers/media/rc/redrat3.c | 3 +- drivers/media/rc/serial_ir.c | 3 +- drivers/media/rc/st_rc.c
[PATCH v4 3/6] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/rc-main.c | 42 +- include/media/rc-core.h| 9 ++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 59fac96..1ddecca 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1365,20 +1365,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1507,7 +1511,7 @@ static int rc_setup_rx_device(struct rc_dev *dev) static void rc_free_rx_device(struct rc_dev *dev) { - if (!dev) + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) return; ir_free_table(>rc_map); @@ -1537,7 +1541,8 @@ int rc_register_device(struct rc_dev *dev) atomic_set(>initialized, 0); dev->dev.groups = dev->sysfs_groups; - dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; if (dev->s_filter) dev->sysfs_groups[attr++] = _dev_filter_attr_grp; if (dev->s_wakeup_filter) @@ -1555,11 +1560,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - rc = rc_setup_rx_device(dev); - if (rc) - goto out_dev; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index ba92c86..e6cb336 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,13 +32,16 @@ do { \ /** * enum rc_driver_type - type of the RC output * - * @RC_DRIVER_SCANCODE:Driver or hardware generates a scancode - * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. - * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode + * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. + * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_IR_RAW_TX: Device transmitter only, + * driver requires pulse/space data sequence. */ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, RC_DRIVER_IR_RAW, + RC_DRIVER_IR_RAW_TX, }; /** -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/6] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- .../devicetree/bindings/leds/irled/spi-ir-led.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt diff --git a/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt new file mode 100644 index 000..896b699 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt @@ -0,0 +1,29 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi-led". + +Optional properties: + - duty-cycle: 8 bit balue that represents the percentage of one period + in which the signal is active. It can be 50, 60, 70, 75, 80 or 90. + - led-active-low: boolean value that specifies whether the output is + negated with a NOT gate. + - power-supply: specifies the power source. It can either be a regulator + or a gpio which enables a regulator, i.e. a regulator-fixed as + described in + Documentation/devicetree/bindings/regulator/fixed-regulator.txt + +Example: + + irled@0 { + compatible = "ir-spi-led"; + reg = <0x0>; + spi-max-frequency = <500>; + power-supply = <_led>; + led-active-low; + duty-cycle = /bits/ 8 <60>; + }; -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 6/6] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through an rc character device. The chardev is handled by the LIRC framework and its functionality basically provides: - write: the driver gets a pulse/space signal and translates it to a binary signal that will be streamed to the IR led through the SPI framework. - set frequency: sets the frequency whith which the data should be sent. This is handle with ioctl with the LIRC_SET_SEND_CARRIER flag (as per lirc documentation) - set duty cycle: this is also handled with ioctl with the LIRC_SET_SEND_DUTY_CYCLE flag. The driver handles duty cycles of 50%, 60%, 70%, 75%, 80% and 90%, calculated on 16bit data. The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; val = 60; ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/Kconfig | 9 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 199 ++ 3 files changed, 209 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 629e8ca..3351e25 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 3a984ee..938c98b 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index 000..d45c603 --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +/* pulse value for different duty cycles */ +#define IR_SPI_PULSE_DC_50 0xff00 +#define IR_SPI_PULSE_DC_60 0xfc00 +#define IR_SPI_PULSE_DC_70 0xf800 +#define IR_SPI_PULSE_DC_75 0xf000 +#define IR_SPI_PULSE_DC_80 0xc000 +#define IR_SPI_PULSE_DC_90 0x8000 + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 +#define IR_SPI_MAX_BUFSIZE 4096 + +struct ir_spi_data { + u32 freq; + u8 duty_cycle; + bool negated; + + u16 tx_buf[IR_SPI_MAX_BUFSIZE]; + u16 pulse; + u16 space; + + struct rc_dev *rc; + struct spi_device *spi; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, + unsigned int *buffer, unsigned int count) +{ + int i; + int ret; + unsigned int len = 0; + struct ir_spi_data *idata = dev->priv; + struct spi_transfer xfer; + + /* convert the pulse/space signal to raw binary signal */ + for (i = 0; i < count; i++) { + int j; + u16 val = ((i+1) % 2) ? idata->pulse : idata->space; + + if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE) + return -EINVAL;
Re: [PATCH 3/8] [media] lirc: LIRC_{G,S}ET_SEND_MODE fail if device cannot transmit
Reviewed-by: Andi Shyti <andi.sh...@samsung.com> On Fri, Dec 02, 2016 at 05:16:09PM +, Sean Young wrote: > These ioctls should not succeed if the device cannot send. Also make it > clear that these ioctls should return the lirc mode, although the actual > value does not change. > > Signed-off-by: Sean Young <s...@mess.org> > --- > drivers/media/rc/ir-lirc-codec.c | 10 -- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/rc/ir-lirc-codec.c > b/drivers/media/rc/ir-lirc-codec.c > index c327730..9e41305 100644 > --- a/drivers/media/rc/ir-lirc-codec.c > +++ b/drivers/media/rc/ir-lirc-codec.c > @@ -204,11 +204,17 @@ static long ir_lirc_ioctl(struct file *filep, unsigned > int cmd, > > /* legacy support */ > case LIRC_GET_SEND_MODE: > - val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; > + if (!dev->tx_ir) > + return -ENOTTY; > + > + val = LIRC_MODE_PULSE; > break; > > case LIRC_SET_SEND_MODE: > - if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) > + if (!dev->tx_ir) > + return -ENOTTY; > + > + if (val != LIRC_MODE_PULSE) > return -EINVAL; > return 0; > > -- > 2.9.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/8] [media] mceusb: LIRC_SET_SEND_CARRIER returns 0 on success
Reviewed-by: Andi Shyti <andi.sh...@samsung.com> On Fri, Dec 02, 2016 at 05:16:07PM +, Sean Young wrote: > LIRC_SET_SEND_CARRIER ioctl should not return the carrier used, it > should return 0. > > Signed-off-by: Sean Young <s...@mess.org> > --- > drivers/media/rc/mceusb.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c > index 9bf6917..96b0ade 100644 > --- a/drivers/media/rc/mceusb.c > +++ b/drivers/media/rc/mceusb.c > @@ -890,7 +890,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 > carrier) > cmdbuf[3] = MCE_IRDATA_TRAILER; > dev_dbg(ir->dev, "disabling carrier modulation"); > mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); > - return carrier; > + return 0; > } > > for (prescaler = 0; prescaler < 4; ++prescaler) { > @@ -904,7 +904,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 > carrier) > > /* Transmit new carrier to mce device */ > mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); > - return carrier; > + return 0; > } > } > > -- > 2.9.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/8] [media] lirc_dev: LIRC_{G,S}ET_REC_MODE do not work
> Since "273b902 [media] lirc_dev: use LIRC_CAN_REC() define" these > ioctls no longer work. > > Signed-off-by: Sean Young <s...@mess.org> > Cc: Andi Shyti <andi.sh...@samsung.com> > Cc: <sta...@vger.kernel.org> # v4.8+ mmhhh... yes, right! :) Reviewed-by: Andi Shyti <andi.sh...@samsung.com> Thanks, Andi > --- > drivers/media/rc/lirc_dev.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c > index 3854809..7f5d109 100644 > --- a/drivers/media/rc/lirc_dev.c > +++ b/drivers/media/rc/lirc_dev.c > @@ -582,7 +582,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int > cmd, unsigned long arg) > result = put_user(ir->d.features, (__u32 __user *)arg); > break; > case LIRC_GET_REC_MODE: > - if (LIRC_CAN_REC(ir->d.features)) { > + if (!LIRC_CAN_REC(ir->d.features)) { > result = -ENOTTY; > break; > } > @@ -592,7 +592,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int > cmd, unsigned long arg) > (__u32 __user *)arg); > break; > case LIRC_SET_REC_MODE: > - if (LIRC_CAN_REC(ir->d.features)) { > + if (!LIRC_CAN_REC(ir->d.features)) { > result = -ENOTTY; > break; > } > -- > 2.9.3 > > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Documentation: media, leds: move IR LED remote controllers from media to LED
Hi Mauro, > > this is purely a request for comments after a discussion had with > > Rob and Jacek [*] about where to place the ir leds binding. Rob wants > > the binding to be under led, while Jacek wants it in media... > > "Ubi maior minor cessat": it goes to LED and they can be organized > > in a subdirectory. > > > > Standing to Rob "Bindings are grouped by types of h/w and IR LEDs > > are a type of LED": all remote controllers have an IR LED as core > > device, even though the framework is under drivers/media/rc/, thus > > they naturally belong to the LED binding group. > > > > Please, let me know if this is the right approach. > > IMHO, this is wrong. > > Ok, if you look at just the diode, the physics of an IR Light-emitting Diode > (LED) is identical to the one for a visible light LED, just like the physics > of the LED diodes inside a display. Btw, the physics of an IR detector > diode is almost identical to the physics of a LED. > > Yet, the hardware where those diodes are connected are very different, > and so their purpose. > > The same way I don't think it would make sense to represent a LED > display using the same approach as a flash light, I don't think we > should to it for IR LEDs. > > A visible light LED is used either to work as a flash light for a camera > or as a way to indicate a status. No machine2machine protocol there. > The circuitry for them is usually just a gatway that will turn it on > or off. > > With regards to the IR hardware, an IR LED is used for machine2machine > signaling. It is part of a modulator circuit that uses a carrier of about > 40kHz to modulate 16 or 32 bits words. > > The IR device hardware usually also have another diode (the IR detector) > that receives IR rays. Visually, they look identical. > > IMHO, it makes much more sense to keep both IR detector and light-emitting > diodes described together, as they are part of the same circuitry and > have a way more similarities than a flash light or a LED display. thanks for the reply, I agree with you, that's why I first put the ir-spi of tm2 in the media directory where all the ir leds devices are. That's what Jacek recommended and what you are recommending (that's also why this is an RFC and not a patch). Rob, if I place the tm2 ir-spi in the led bindings in a sub-directory it will be the only device there for the time being. But the ir-spi it's not unique in its kind, there are many others and they are all under the media directory. My opinion is that all the ir-leds devices should be in the same place. Would, then, make sense to split the ir-leds devices in two different locations? Would it be a valid alternative to create instead an 'rc' directory for the ir-leds bindings that can either be under media or in the higher directory? Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC] Documentation: media, leds: move IR LED remote controllers from media to LED
Hi, this is purely a request for comments after a discussion had with Rob and Jacek [*] about where to place the ir leds binding. Rob wants the binding to be under led, while Jacek wants it in media... "Ubi maior minor cessat": it goes to LED and they can be organized in a subdirectory. Standing to Rob "Bindings are grouped by types of h/w and IR LEDs are a type of LED": all remote controllers have an IR LED as core device, even though the framework is under drivers/media/rc/, thus they naturally belong to the LED binding group. Please, let me know if this is the right approach. Thanks, Andi [*] https://lkml.org/lkml/2016/9/12/380 https://lkml.org/lkml/2016/11/9/622 --- .../devicetree/bindings/{media => leds/ir-leds}/gpio-ir-receiver.txt | 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/hix5hd2-ir.txt | 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/img-ir-rev1.txt | 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/meson-ir.txt| 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/nokia,n900-ir | 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/st-rc.txt | 0 Documentation/devicetree/bindings/{media => leds/ir-leds}/sunxi-ir.txt| 0 7 files changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/gpio-ir-receiver.txt (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/hix5hd2-ir.txt (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/img-ir-rev1.txt (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/meson-ir.txt (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/nokia,n900-ir (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/st-rc.txt (100%) rename Documentation/devicetree/bindings/{media => leds/ir-leds}/sunxi-ir.txt (100%) diff --git a/Documentation/devicetree/bindings/media/gpio-ir-receiver.txt b/Documentation/devicetree/bindings/leds/ir-leds/gpio-ir-receiver.txt similarity index 100% rename from Documentation/devicetree/bindings/media/gpio-ir-receiver.txt rename to Documentation/devicetree/bindings/leds/ir-leds/gpio-ir-receiver.txt diff --git a/Documentation/devicetree/bindings/media/hix5hd2-ir.txt b/Documentation/devicetree/bindings/leds/ir-leds/hix5hd2-ir.txt similarity index 100% rename from Documentation/devicetree/bindings/media/hix5hd2-ir.txt rename to Documentation/devicetree/bindings/leds/ir-leds/hix5hd2-ir.txt diff --git a/Documentation/devicetree/bindings/media/img-ir-rev1.txt b/Documentation/devicetree/bindings/leds/ir-leds/img-ir-rev1.txt similarity index 100% rename from Documentation/devicetree/bindings/media/img-ir-rev1.txt rename to Documentation/devicetree/bindings/leds/ir-leds/img-ir-rev1.txt diff --git a/Documentation/devicetree/bindings/media/meson-ir.txt b/Documentation/devicetree/bindings/leds/ir-leds/meson-ir.txt similarity index 100% rename from Documentation/devicetree/bindings/media/meson-ir.txt rename to Documentation/devicetree/bindings/leds/ir-leds/meson-ir.txt diff --git a/Documentation/devicetree/bindings/media/nokia,n900-ir b/Documentation/devicetree/bindings/leds/ir-leds/nokia,n900-ir similarity index 100% rename from Documentation/devicetree/bindings/media/nokia,n900-ir rename to Documentation/devicetree/bindings/leds/ir-leds/nokia,n900-ir diff --git a/Documentation/devicetree/bindings/media/st-rc.txt b/Documentation/devicetree/bindings/leds/ir-leds/st-rc.txt similarity index 100% rename from Documentation/devicetree/bindings/media/st-rc.txt rename to Documentation/devicetree/bindings/leds/ir-leds/st-rc.txt diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/leds/ir-leds/sunxi-ir.txt similarity index 100% rename from Documentation/devicetree/bindings/media/sunxi-ir.txt rename to Documentation/devicetree/bindings/leds/ir-leds/sunxi-ir.txt -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver
Hi Jacek, > > > > > Only DT bindings of LED class drivers should be placed in > > > > > Documentation/devicetree/bindings/leds. Please move it to the > > > > > media bindings. > > > > > > > > that's where I placed it first, but Rob asked me to put it in the > > > > LED directory and Cc the LED mailining list. > > > > > > > > That's the discussion of the version 2: > > > > > > > > https://lkml.org/lkml/2016/9/12/380 > > > > > > > > Rob, Jacek, could you please agree where I can put the binding? > > > > > > I'm not sure if this is a good approach. I've noticed also that > > > backlight bindings have been moved to leds, whereas they don't look > > > similarly. > > > > > > We have common.txt LED bindings, that all LED class drivers' bindings > > > have to follow. Neither backlight bindings nor these ones do that, > > > which introduces some mess. > > > > And there are probably LED bindings that don't follow common.txt either. > > > > > Eventually adding a sub-directory, e.g. remote_control could make it > > > somehow logically justified, but still - shouldn't bindings be > > > placed in the documentation directory related to the subsystem of the > > > driver they are predestined to? > > > > No. While binding directories often mirror the driver directories, they > > are not the same. Bindings are grouped by types of h/w and IR LEDs are a > > type of LED. > > > > If you prefer a sub-dir, that is fine with me. > > Fine. So how about sub-dir "ir" ? would we put here all the remote control bindings that currently are under media? Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver
Hi Jacek, > > > Only DT bindings of LED class drivers should be placed in > > > Documentation/devicetree/bindings/leds. Please move it to the > > > media bindings. > > > > that's where I placed it first, but Rob asked me to put it in the > > LED directory and Cc the LED mailining list. > > > > That's the discussion of the version 2: > > > > https://lkml.org/lkml/2016/9/12/380 > > > > Rob, Jacek, could you please agree where I can put the binding? > > I'm not sure if this is a good approach. I've noticed also that > backlight bindings have been moved to leds, whereas they don't look > similarly. > > We have common.txt LED bindings, that all LED class drivers' bindings > have to follow. Neither backlight bindings nor these ones do that, > which introduces some mess. > > Eventually adding a sub-directory, e.g. remote_control could make it > somehow logically justified, but still - shouldn't bindings be > placed in the documentation directory related to the subsystem of the > driver they are predestined to? In principle I agree with you, also because I understood that the led kind of bindings are for those LEDs which main function is to emit light. There is no need for a remote control directory, because there is one already under bindings/media, where all the remote controllers are placed. Now this is a matter of interpretation, is this an IR LED used by the driver as remote controller or is this a remote controller with just an IR LED? In any case, I will wait for you and Rob to agree where is best to place the binding, then I will send a new version. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver
Hi Jacek, > Only DT bindings of LED class drivers should be placed in > Documentation/devicetree/bindings/leds. Please move it to the > media bindings. that's where I placed it first, but Rob asked me to put it in the LED directory and Cc the LED mailining list. That's the discussion of the version 2: https://lkml.org/lkml/2016/9/12/380 Rob, Jacek, could you please agree where I can put the binding? Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/6] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 143 + 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 9e19b73e..7ab1b32 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1405,16 +1405,12 @@ void rc_free_device(struct rc_dev *dev) } EXPORT_SYMBOL_GPL(rc_free_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1423,6 +1419,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1432,6 +1441,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1455,39 +1519,15 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -* to do. -*/ - dev->input_dev->rep[REP_PERIOD] = 125; - path = kobject_get_path(>dev.kobj, GFP_KERNEL); dev_info(>dev, "%s as %s\n", dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); + rc = rc_setup_rx
[PATCH v3 4/6] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 205ecc6..db3701f 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -275,12 +275,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.10.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- .../devicetree/bindings/leds/spi-ir-led.txt| 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/spi-ir-led.txt diff --git a/Documentation/devicetree/bindings/leds/spi-ir-led.txt b/Documentation/devicetree/bindings/leds/spi-ir-led.txt new file mode 100644 index 000..896b699 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/spi-ir-led.txt @@ -0,0 +1,29 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi-led". + +Optional properties: + - duty-cycle: 8 bit balue that represents the percentage of one period + in which the signal is active. It can be 50, 60, 70, 75, 80 or 90. + - led-active-low: boolean value that specifies whether the output is + negated with a NOT gate. + - power-supply: specifies the power source. It can either be a regulator + or a gpio which enables a regulator, i.e. a regulator-fixed as + described in + Documentation/devicetree/bindings/regulator/fixed-regulator.txt + +Example: + + irled@0 { + compatible = "ir-spi-led"; + reg = <0x0>; + spi-max-frequency = <500>; + power-supply = <_led>; + led-active-low; + duty-cycle = /bits/ 8 <60>; + }; -- 2.10.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/6] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 4 +++- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- drivers/staging/media/cec/cec-core.c| 3 +-- include/media/rc-core.h | 4 +++- 41 files changed, 45 insertions(+), 80 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 9628651..38b0ea8 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 41f2a39..ee30c7b 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -58,7 +58,7 @@ int sms_ir_init(struct smscore_device_t *coredev) struct rc_dev *dev; pr_debug("Allocating rc device\n"); - dev = rc_allocate_device(); + dev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!dev) return -ENOMEM; @@ -86,7 +86,6 @@ int sms_ir_init(struct smscore_device_t *coredev) #endif dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; dev->allowed_protocols = RC_BIT_ALL; dev->map_name = sms_get_board(board_id)->rc_codes; dev->driver_name = MODULE_NAME; diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index f95a6bc..2848a3e 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -428,7 +428,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) * If platform_data doesn't specify rc_dev, initialize it * internally */ - rc = rc_allocate_device(); + rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!rc)
[PATCH v3 6/6] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through an rc character device. The chardev is handled by the LIRC framework and its functionality basically provides: - write: the driver gets a pulse/space signal and translates it to a binary signal that will be streamed to the IR led through the SPI framework. - set frequency: sets the frequency whith which the data should be sent. This is handle with ioctl with the LIRC_SET_SEND_CARRIER flag (as per lirc documentation) - set duty cycle: this is also handled with ioctl with the LIRC_SET_SEND_DUTY_CYCLE flag. The driver handles duty cycles of 50%, 60%, 70%, 75%, 80% and 90%, calculated on 16bit data. The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; val = 60; ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> Reviewed-by: Sean Young <s...@mess.org> --- drivers/media/rc/Kconfig | 9 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 205 ++ 3 files changed, 215 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 370e16e..207dfcc 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 379a5c0..1417c8d 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index 000..fcda1e4 --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +/* pulse value for different duty cycles */ +#define IR_SPI_PULSE_DC_50 0xff00 +#define IR_SPI_PULSE_DC_60 0xfc00 +#define IR_SPI_PULSE_DC_70 0xf800 +#define IR_SPI_PULSE_DC_75 0xf000 +#define IR_SPI_PULSE_DC_80 0xc000 +#define IR_SPI_PULSE_DC_90 0x8000 + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 +#define IR_SPI_MAX_BUFSIZE 4096 + +struct ir_spi_data { + u32 freq; + u8 duty_cycle; + bool negated; + + u16 tx_buf[IR_SPI_MAX_BUFSIZE]; + u16 pulse; + u16 space; + + struct rc_dev *rc; + struct spi_device *spi; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, + unsigned int *buffer, unsigned int count) +{ + int i; + int ret; + unsigned int len = 0; + struct ir_spi_data *idata = dev->priv; + struct spi_transfer xfer; + + /* convert the pulse/space signal to raw binary signal */ + for (i = 0; i < count; i++) { + int j; + u16 val = ((i+1) % 2) ? idata->pulse : idata->space; + + if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE) + return -EINVAL;
[PATCH v3 0/6] Add support for IR transmitters
Hi, The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. Thanks Sean for your prompt reviews. Andi Changelog from version 1: The RFC is now PATCH. The main difference is that this version doesn't try to add the any bit streaming protocol and doesn't modify any LIRC interface specification. patch 1: updates all the drivers using rc_allocate_device patch 2: fixed errors and warning reported from the kbuild test robot patch 5: this patch has been dropped and replaced with a new one which avoids waiting for transmitters. patch 6: added new properties to the dts specification patch 7: the driver uses the pulse/space input and converts it to a bit stream. Changelog from version 2: The original patch number 5 has been abandoned because it was not bringing much benenfit. patch 1: rebased on the new kernel. patch 3: removed the sysfs attribute protocol for transmitters patch 5: the binding has been moved to the leds section instead of the media. Fixed all the comments from Rob patch 6: fixed all the comments from Sean added also Sean's review. Andi Shyti (6): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI .../devicetree/bindings/leds/spi-ir-led.txt| 29 +++ drivers/hid/hid-picolcd_cir.c | 3 +- drivers/media/common/siano/smsir.c | 3 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +- drivers/media/pci/cx88/cx88-input.c| 3 +- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_input.c| 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 9 + drivers/media/rc/Makefile | 1 + drivers/media/rc/ati_remote.c | 3 +- drivers/media/rc/ene_ir.c | 3 +- drivers/media/rc/fintek-cir.c | 3 +- drivers/media/rc/gpio-ir-recv.c| 3 +- drivers/media/rc/igorplugusb.c | 3 +- drivers/media/rc/iguanair.c| 3 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 3 +- drivers/media/rc/imon.c| 3 +- drivers/media/rc/ir-hix5hd2.c | 3 +- drivers/media/rc/ir-spi.c | 205 + drivers/media/rc/ite-cir.c | 3 +- drivers/media/rc/mceusb.c | 3 +- drivers/media/rc/meson-ir.c| 3 +- drivers/media/rc/nuvoton-cir.c | 3 +- drivers/media/rc/rc-ir-raw.c | 17 +- drivers/media/rc/rc-loopback.c | 3 +- drivers/media/rc/rc-main.c | 181 ++ drivers/media/rc/redrat3.c | 3 +- drivers/media/rc/st_rc.c | 3 +- drivers/media/rc/streamzap.c | 3 +- drivers/media/rc/sunxi-cir.c | 3 +- drivers/media/rc/ttusbir.c | 3 +- drivers/media/rc/winbond-cir.c | 3 +- drivers/media/usb/au0828/au0828-input.c| 3 +- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c| 3 +- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +- drivers/media/usb/em28xx/em28xx-input.c| 2 +- drivers/media/usb/tm6000/tm6000-input.c| 3 +- drivers/staging/media/cec/cec-core.c | 3 +- include/media/rc-core.h| 13 +- 46 files changed, 409 insertions(+), 163 deletions(-) create mode 100644 Documentation/devicetree/bindings/leds/spi-ir-led.txt create mode 100644 drivers/media/rc/ir-spi.c -- 2.10.1 -- To unsubscribe from
[PATCH v3 3/6] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 42 +- include/media/rc-core.h| 9 ++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7ab1b32..0d2f440 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1363,20 +1363,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1476,7 +1480,7 @@ static int rc_setup_rx_device(struct rc_dev *dev) static void rc_free_rx_device(struct rc_dev *dev) { - if (!dev) + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) return; ir_free_table(>rc_map); @@ -1506,7 +1510,8 @@ int rc_register_device(struct rc_dev *dev) atomic_set(>initialized, 0); dev->dev.groups = dev->sysfs_groups; - dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + dev->sysfs_groups[attr++] = _dev_protocol_attr_grp; if (dev->s_filter) dev->sysfs_groups[attr++] = _dev_filter_attr_grp; if (dev->s_wakeup_filter) @@ -1524,11 +1529,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - rc = rc_setup_rx_device(dev); - if (rc) - goto out_dev; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index f8ca557..b6f7419 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,13 +32,16 @@ do { \ /** * enum rc_driver_type - type of the RC output * - * @RC_DRIVER_SCANCODE:Driver or hardware generates a scancode - * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. - * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode + * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. + * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_IR_RAW_TX: Device transmitter only, +driver requires pulse/space data sequence. */ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, RC_DRIVER_IR_RAW, + RC_DRIVER_IR_RAW_TX, }; /** -- 2.10.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] [media] ir-lirc-codec: don't wait any transmitting time for tx only devices
Hi Sean, > > > Andi, it would be good to know what the use-case for the original change > > > is. > > > > the use case is the ir-spi itself which doesn't need the lirc to > > perform any waiting on its behalf. > > Here is the crux of the problem: in the ir-spi case no wait will actually > happen here, and certainly no "over-wait". The patch below will not change > behaviour at all. > > In the ir-spi case, "towait" will be 0 and no wait happens. > > I think the code is already in good shape but somehow there is a > misunderstanding. Did I miss something? We can just drop this patch, it's just something small that is bothering me. I will send a new patchset without this one. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] [media] ir-lirc-codec: don't wait any transmitting time for tx only devices
Hi Sean, > Andi, it would be good to know what the use-case for the original change is. the use case is the ir-spi itself which doesn't need the lirc to perform any waiting on its behalf. To me it just doesn't look right to simulate a fake transmission period and wait unnecessary time. Of course, the "over-wait" is not a big deal and at the end we can decide to drop it. Otherwise, an alternative could be to add the boolean 'tx_no_wait' in the rc_dev structure. It could be set by the device driver during the initialization and the we can follow your approach. Something like this: diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index c327730..4553d04 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -161,15 +161,19 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, ret *= sizeof(unsigned int); - /* -* The lircd gap calculation expects the write function to -* wait for the actual IR signal to be transmitted before -* returning. -*/ - towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); - if (towait > 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(towait)); + if (!dev->tx_no_wait) { + /* +* The lircd gap calculation expects the write function to +* wait for the actual IR signal to be transmitted before +* returning. +*/ + towait = ktime_us_delta(ktime_add_us(start, duration), + ktime_get()); + if (towait > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(towait)); + } + } out: diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index fcda1e4..e44abfa 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -149,6 +149,7 @@ static int ir_spi_probe(struct spi_device *spi) if (!idata->rc) return -ENOMEM; + idata->rc->tx_no_wait = true; idata->rc->tx_ir = ir_spi_tx; idata->rc->s_tx_carrier= ir_spi_set_tx_carrier; idata->rc->s_tx_duty_cycle = ir_spi_set_duty_cycle; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index fe0c9c4..c3ced9b 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -85,6 +85,9 @@ enum rc_filter_type { * @input_dev: the input child device used to communicate events to userspace * @driver_type: specifies if protocol decoding is done in hardware or software * @idle: used to keep track of RX state + * @tx_no_wait: decides whether to perform or not a sync write or not. The + * device driver setting it to true must make sure to not break the ABI + * which requires a sync transfer. * @allowed_protocols: bitmask with the supported RC_BIT_* protocols * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols * @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols @@ -147,6 +150,7 @@ struct rc_dev { struct input_dev*input_dev; enum rc_driver_type driver_type; boolidle; + booltx_no_wait; u64 allowed_protocols; u64 enabled_protocols; u64 allowed_wakeup_protocols; Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] [media] lirc: introduce LIRC_SET_TRANSMITTER_WAIT ioctl
Hi Sean. > > > ret *= sizeof(unsigned int); > > > > > > - /* > > > - * The lircd gap calculation expects the write function to > > > - * wait for the actual IR signal to be transmitted before > > > - * returning. > > > - */ > > > - towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); > > > - if (towait > 0) { > > > - set_current_state(TASK_INTERRUPTIBLE); > > > - schedule_timeout(usecs_to_jiffies(towait)); > > > + if (!lirc->tx_no_wait) { > > > + /* > > > + * The lircd gap calculation expects the write function to > > > + * wait for the actual IR signal to be transmitted before > > > + * returning. > > > + */ > > > + towait = ktime_us_delta(ktime_add_us(start, duration), > > > + ktime_get()); > > > + if (towait > 0) { > > > + set_current_state(TASK_INTERRUPTIBLE); > > > + schedule_timeout(usecs_to_jiffies(towait)); > > > + } > > > } > > > - > > > > this doesn't fix my problem, though. > > > > This approach gives the userspace the possibility to choose to > > either sync or not. In my case the sync happens, but in a > > different level and it's not up to the userspace to make the > > decision. > > What problem are you trying to solve? > > I wrote this patch as a response to this patch: > > https://lkml.org/lkml/2016/9/1/653 Actually no big problem here but what I wrote below. If the user sets LIRC_SET_TRANSMITTER_WAIT to 0 and the driver waits anyway, this patch wouldn't be of any use and it would do exactly what it whas doing before. > In the spi case, the driver already waits for the IR to complete so the > wait in ir_lirc_transmit_ir() is unnecessary. However it does not end up > waiting. There are other drivers like yours that wait for the IR to > complete (ene_ir, ite-cir). Since towait in ir_lirc_transmit_ir is the > delta between before and after the driver transmits, it will be 0 and > will never goto into schedule_timeout(), barring some very minor rounding > differences. > > > Besides, I see here a security issue: what happens if userspace > > does something like > > > > fd = open("/dev/lirc0", O_RDWR); > > > > ioctl(fd, LIRC_SET_TRANSMITTER_WAIT, 0); > > > > while(1) > > write(fd, buffer, ENORMOUS_BUFFER_SIZE); > > I don't understand what problem this would introduce. > > You can't write more than 512 pulse/spaces and each write cannot > have more than 500ms in IR (so adding up the pulses and spaces). The driver > should only send once the previous send completed. OK. > > > + case LIRC_SET_TRANSMITTER_WAIT: > > > + if (!dev->tx_ir) > > > + return -ENOTTY; > > > + > > > + lirc->tx_no_wait = !val; > > > + break; > > > + > > > > Here I see an innocuous bug. Depending on the hardware (for > > example ir-spi) it might happen that the device waits in any > > case (in ir-spi the sync is done by the spi). This means that if > > userspace sets 'tx_no_wait = true', the device/driver doesn't > > care and waits anyway, doing the opposite from what is described > > in the ABI. > > > > Here we could call a dev->tx_set_transmitter_wait(...) function > > that sets the value or returns error in case the wait is not > > feasable, something like: > > > > case LIRC_SET_TRANSMITTER_WAIT: > > if (!dev->tx_ir) > > return -ENOTTY; > > > > if (dev->tx_set_transmitter_wait) > > return dev->tx_set_transmitter_wait(lirc, val); > > > > lirc->tx_no_wait = !val; > > break; > > That is true. Do you want the ir-spi driver to be able to send without > waiting? I think there should be some meccanism to keep it coherent with the ABI, mine was a suggestion. > > > --- a/drivers/media/rc/rc-core-priv.h > > > +++ b/drivers/media/rc/rc-core-priv.h > > > @@ -112,7 +112,7 @@ struct ir_raw_event_ctrl { > > > u64 gap_duration; > > > bool gap; > > > bool send_timeout_reports; > > > - > > > + bool tx_no_wait; > > > } lirc; > > > > this to me looks confusing, it has a negative meaning in kernel > > space and a positive meaning in userspace. Can't we call it > > lirc->tx_wait instead of lirc->tx_no_wait, so that we keep the > > same meaning and we don't need to negate val? > > This was just done to avoid having to initialise to true (non-zero). OK, this was just a nitpick anyway :) Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] [media] lirc: introduce LIRC_SET_TRANSMITTER_WAIT ioctl
Hi Sean, > ret *= sizeof(unsigned int); > > - /* > - * The lircd gap calculation expects the write function to > - * wait for the actual IR signal to be transmitted before > - * returning. > - */ > - towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); > - if (towait > 0) { > - set_current_state(TASK_INTERRUPTIBLE); > - schedule_timeout(usecs_to_jiffies(towait)); > + if (!lirc->tx_no_wait) { > + /* > + * The lircd gap calculation expects the write function to > + * wait for the actual IR signal to be transmitted before > + * returning. > + */ > + towait = ktime_us_delta(ktime_add_us(start, duration), > + ktime_get()); > + if (towait > 0) { > + set_current_state(TASK_INTERRUPTIBLE); > + schedule_timeout(usecs_to_jiffies(towait)); > + } > } > - this doesn't fix my problem, though. This approach gives the userspace the possibility to choose to either sync or not. In my case the sync happens, but in a different level and it's not up to the userspace to make the decision. Besides, I see here a security issue: what happens if userspace does something like fd = open("/dev/lirc0", O_RDWR); ioctl(fd, LIRC_SET_TRANSMITTER_WAIT, 0); while(1) write(fd, buffer, ENORMOUS_BUFFER_SIZE); > > + case LIRC_SET_TRANSMITTER_WAIT: > + if (!dev->tx_ir) > + return -ENOTTY; > + > + lirc->tx_no_wait = !val; > + break; > + Here I see an innocuous bug. Depending on the hardware (for example ir-spi) it might happen that the device waits in any case (in ir-spi the sync is done by the spi). This means that if userspace sets 'tx_no_wait = true', the device/driver doesn't care and waits anyway, doing the opposite from what is described in the ABI. Here we could call a dev->tx_set_transmitter_wait(...) function that sets the value or returns error in case the wait is not feasable, something like: case LIRC_SET_TRANSMITTER_WAIT: if (!dev->tx_ir) return -ENOTTY; if (dev->tx_set_transmitter_wait) return dev->tx_set_transmitter_wait(lirc, val); lirc->tx_no_wait = !val; break; > --- a/drivers/media/rc/rc-core-priv.h > +++ b/drivers/media/rc/rc-core-priv.h > @@ -112,7 +112,7 @@ struct ir_raw_event_ctrl { > u64 gap_duration; > bool gap; > bool send_timeout_reports; > - > + bool tx_no_wait; > } lirc; this to me looks confusing, it has a negative meaning in kernel space and a positive meaning in userspace. Can't we call it lirc->tx_wait instead of lirc->tx_no_wait, so that we keep the same meaning and we don't need to negate val? Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/7] [media] ir-lirc-codec: don't wait any transmitting time for tx only devices
Hi Sean, it's been a while :) I was going through your review fixing what needs to be fixed, but... > > @@ -153,7 +153,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, > > const char __user *buf, > > } > > > > ret = dev->tx_ir(dev, txbuf, count); > > - if (ret < 0) > > + if (ret < 0 || dev->driver_type == RC_DRIVER_IR_RAW_TX) > > Just because a driver only does transmit doesn't mean its transmit ABI > should change. > > Now this bit of code is pretty horrible. It ensures that the call to write() > takes at least as long as the length of the transmit IR by sleeping. That's > not much of a guarantee that the IR has been sent. > > Note that in the case of ir-spi, since your spi transfer is sync no sleep > should be introduced here. > > The gap calculation in lirc checks that if the call to write() took _longer_ > than expected wait before sending the next IR code (when either multiple > IR codes or repeats are specified). Introducing the sleep in the kernel > here does not help at all, lirc already ensures that it waits as long as > the IR is long (see schedule_repeat_timer in lirc). > > This change was introduced in 3.10, commit f8e00d5. ... I'm not sure what can be done here. I get your point and I understand that this indeed is a kind of fake sync point and by doing this I How about creating two different functions: - ir_lirc_transmit_ir where we actually do what the function already does - ir_lirc_transmit_no_sync where the function we don't wait because the the sync is done on a different level (for example in the SPI case). SPI does approximately the same thing. Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/7] Documentation: bindings: add documentation for ir-spi device driver
Hi Rob, > > Document the ir-spi driver's binding which is a IR led driven > > through the SPI line. > > > > Signed-off-by: Andi Shyti <andi.sh...@samsung.com> > > --- > > Documentation/devicetree/bindings/media/spi-ir.txt | 26 > > ++ > > 1 file changed, 26 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/media/spi-ir.txt > > > > diff --git a/Documentation/devicetree/bindings/media/spi-ir.txt > > b/Documentation/devicetree/bindings/media/spi-ir.txt > > new file mode 100644 > > index 000..85cb21b > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/media/spi-ir.txt > > Move this to bindings/leds, and CC the leds maintainers. More than an LED this is the driver of a remote controller, the driver itself is under drivers/media/rc/. Besides all the transmitters have an LED but still they are media devices. This is a bit special because it's so simple that the only hardware left is the LED itself, but still it's a media remote controller. > > @@ -0,0 +1,26 @@ > > +Device tree bindings for IR LED connected through SPI bus which is used as > > +remote controller. > > + > > +The IR LED switch is connected to the MOSI line of the SPI device and the > > data > > +are delivered thourgh that. > > + > > +Required properties: > > + - compatible: should be "ir-spi". > > Really this is just an LED connected to a SPI, so maybe this should > just be "spi-led". If being more specific is helpful, then I'm all for > that, but perhaps spi-ir-led. (Trying to be consistent in naming with > gpio-leds). As I mentioned above, all transmitters have an LED, but they do not have the 'led' name. "ir-spi" is coherent with the device driver name and the driver name is coherent with the media/rc driver's naming. > > + > > +Optional properties: > > + - irled,switch: specifies the gpio switch which enables the irled/ > > As I said previously, "switch-gpios" as gpio lines should have a > '-gpios' suffix. Or better yet, "enable-gpios" as that is a standard > name for an enable line. OK, thanks! > > + - negated: boolean value that specifies whether the output is > > negated > > + with a NOT gate. > > Negated or inverted assumes I know what normal is. Define this in > terms of what is the on state. If on is normally active low, then this > should be led-active-high. There may already be an LED property for > this. Yes, thanks! > > + - duty-cycle: 8 bit value that stores the percentage of the duty > > cycle. > > + it can be 50, 60, 70, 75, 80 or 90. > > This is percent time on or off? Will add more details, thanks. If it's OK for you, I would keep the name and documentation path and fix the rest. Please let me know if I'm missing something :) Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 7/7] [media] rc: add support for IR LEDs driven through SPI
> Thanks Andi, this is looking great! Thanks Sean! With your reviews the whole thing looks much better now :) I agree with all your points here, I will fix them. Can I add your reviewd-by? Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/7] [media] rc-main: assign driver type during allocation
Hi Sean, > > ir = kzalloc(sizeof(*ir), GFP_KERNEL); > > - dev = rc_allocate_device(); > > + dev = rc_allocate_device(RC_DRIVER_IR_RAW); > > if (!ir || !dev) > > goto err_out_free; > > > > If ir->sampling = 0 then it should be RC_DRIVER_SCANCODE. > > > > @@ -481,7 +481,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev > > *pci) > > dev->scancode_mask = hardware_mask; > > > > if (ir->sampling) { > > - dev->driver_type = RC_DRIVER_IR_RAW; > > dev->timeout = 10 * 1000 * 1000; /* 10 ms */ > > } else { > > dev->driver_type = RC_DRIVER_SCANCODE; > > That assignment shouldn't really be there any more. I think this doesn't change the driver's behavior, because I either do like: - dev = rc_allocate_device(); + dev = rc_allocate_device(RC_DRIVER_SCANCODE); [ ... ] if (ir->sampling) { dev->driver_type = RC_DRIVER_IR_RAW; dev->timeout = 10 * 1000 * 1000; /* 10 ms */ } else { - dev->driver_type = RC_DRIVER_SCANCODE; Or I would need to do aftr the long switch...case statement + if (ir->sampling) { + dev = rc_allocate_device(RC_DRIVER_IR_RAW); + ... + } else { + dev = rc_allocate_device(RC_DRIVER_SCANCODE); + ... I prefered the first way because it doesn't alter much the driver. > > ir = kzalloc(sizeof(*ir), GFP_KERNEL); > > - rc = rc_allocate_device(); > > + rc = rc_allocate_device(RC_DRIVER_SCANCODE); > > if (!ir || !rc) { > > err = -ENOMEM; > > goto err_out_free; > > This is not correct, I'm afraid. If you look at the code you can see that > if raw_decode is true, then it should be RC_DRIVER_IR_RAW. Same here, the driver doesn't change the behavior. raw_decode can be both 'true' or 'false' it's set as default RC_DRIVER_SCANCODE and depending on value of raw_decode it's chaged to RC_DRIVER_IR_RAW. also in this case I can do + if (raw_decode) { + rc = rc_allocate_device(RC_DRIVER_IR_RAW); + ... + } else { + rc = rc_allocate_device(RC_DRIVER_SCANCODE); + ... but also in this case my original approach doesn't add much changes. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/7] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 39 +++ include/media/rc-core.h| 9 ++--- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7961083..c3c1f68 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1361,20 +1361,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1474,7 +1478,7 @@ out_table: static void rc_free_rx_device(struct rc_dev *dev) { - if (!dev) + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) return; ir_free_table(>rc_map); @@ -1522,11 +1526,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - rc = rc_setup_rx_device(dev); - if (rc) - goto out_dev; + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 4fc60dd..56e33c1 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,13 +32,16 @@ do { \ /** * enum rc_driver_type - type of the RC output * - * @RC_DRIVER_SCANCODE:Driver or hardware generates a scancode - * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. - * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode + * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. + * It needs a Infra-Red pulse/space decoder + * @RC_DRIVER_IR_RAW_TX: Device transmitter only, +driver requires pulce/spce data sequence. */ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, RC_DRIVER_IR_RAW, + RC_DRIVER_IR_RAW_TX, }; /** -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/7] Add support for IR transmitters
Hi, The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. The last patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is currently ongoing. Changelog from version 1: The RFC is now PATCH. The main difference is that this version doesn't try to add the any bit streaming protocol and doesn't modify any LIRC interface specification. patch 1: updates all the drivers using rc_allocate_device patch 2: fixed errors and warning reported from the kbuild test robot patch 5: this patch has been dropped and replaced with a new one which avoids waiting for transmitters. patch 6: added new properties to the dts specification patch 7: the driver uses the pulse/space input and converts it to a bit stream. Thanks, Andi Andi Shyti (7): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters [media] ir-lirc-codec: don't wait any transmitting time for tx only devices Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI Documentation/devicetree/bindings/media/spi-ir.txt | 26 +++ drivers/hid/hid-picolcd_cir.c | 3 +- drivers/media/common/siano/smsir.c | 3 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +- drivers/media/pci/cx88/cx88-input.c| 3 +- drivers/media/pci/dm1105/dm1105.c | 3 +- drivers/media/pci/mantis/mantis_input.c| 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 9 + drivers/media/rc/Makefile | 1 + drivers/media/rc/ati_remote.c | 3 +- drivers/media/rc/ene_ir.c | 3 +- drivers/media/rc/fintek-cir.c | 3 +- drivers/media/rc/gpio-ir-recv.c| 3 +- drivers/media/rc/igorplugusb.c | 3 +- drivers/media/rc/iguanair.c| 3 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 3 +- drivers/media/rc/imon.c| 3 +- drivers/media/rc/ir-hix5hd2.c | 3 +- drivers/media/rc/ir-lirc-codec.c | 2 +- drivers/media/rc/ir-spi.c | 221 + drivers/media/rc/ite-cir.c | 3 +- drivers/media/rc/mceusb.c | 3 +- drivers/media/rc/meson-ir.c| 3 +- drivers/media/rc/nuvoton-cir.c | 3 +- drivers/media/rc/rc-ir-raw.c | 17 +- drivers/media/rc/rc-loopback.c | 3 +- drivers/media/rc/rc-main.c | 179 ++--- drivers/media/rc/redrat3.c | 3 +- drivers/media/rc/st_rc.c | 3 +- drivers/media/rc/streamzap.c | 3 +- drivers/media/rc/sunxi-cir.c | 3 +- drivers/media/rc/ttusbir.c | 3 +- drivers/media/rc/winbond-cir.c | 3 +- drivers/media/usb/au0828/au0828-input.c| 3 +- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c| 3 +- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +- drivers/media/usb/em28xx/em28xx-input.c| 2 +- drivers/media/usb/tm6000/tm6000-input.c| 3 +- drivers/staging/media/cec/cec-core.c | 3 +- include/media/rc-core.h| 13 +- 47 files changed, 421 insertions(+), 164 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/spi-ir.txt create mode 100644 drivers/media/rc/ir-spi.c -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 6/7] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- Documentation/devicetree/bindings/media/spi-ir.txt | 26 ++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/spi-ir.txt diff --git a/Documentation/devicetree/bindings/media/spi-ir.txt b/Documentation/devicetree/bindings/media/spi-ir.txt new file mode 100644 index 000..85cb21b --- /dev/null +++ b/Documentation/devicetree/bindings/media/spi-ir.txt @@ -0,0 +1,26 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi". + +Optional properties: + - irled,switch: specifies the gpio switch which enables the irled/ + - negated: boolean value that specifies whether the output is negated + with a NOT gate. + - duty-cycle: 8 bit value that stores the percentage of the duty cycle. + it can be 50, 60, 70, 75, 80 or 90. + +Example: + +irled@0 { +compatible = "ir-spi"; +reg = <0x0>; +spi-max-frequency = <500>; +irled,switch = < 3 0>; + negated; + duty-cycle = /bits/ 8 <60>; +}; -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/7] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 144304c..64ddc3d 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -274,12 +274,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 7/7] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through an rc character device. The chardev is handled by the LIRC framework and its functionality basically provides: - write: the driver gets a pulse/space signal and translates it to a binary signal that will be streamed to the IR led through the SPI framework. - set frequency: sets the frequency whith which the data should be sent. This is handle with ioctl with the LIRC_SET_SEND_CARRIER flag (as per lirc documentation) - set duty cycle: this is also handled with ioctl with the LIRC_SET_SEND_DUTY_CYCLE flag. The driver handles duty cycles of 50%, 60%, 70%, 75%, 80% and 90%, calculated on 16bit data. The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; val = 60; ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/Kconfig | 9 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 221 ++ 3 files changed, 231 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 370e16e..207dfcc 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 379a5c0..1417c8d 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index 000..34d5a0c --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +/* pulse value for different duty cycles */ +#define IR_SPI_PULSE_DC_50 0xff00 +#define IR_SPI_PULSE_DC_60 0xfc00 +#define IR_SPI_PULSE_DC_70 0xf800 +#define IR_SPI_PULSE_DC_75 0xf000 +#define IR_SPI_PULSE_DC_80 0xc000 +#define IR_SPI_PULSE_DC_90 0x8000 + +/* duty cycles values */ +#define IR_SPI_DUTY_CYCLE_50 50 +#define IR_SPI_DUTY_CYCLE_60 60 +#define IR_SPI_DUTY_CYCLE_70 70 +#define IR_SPI_DUTY_CYCLE_75 75 +#define IR_SPI_DUTY_CYCLE_80 80 +#define IR_SPI_DUTY_CYCLE_90 90 + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 +#define IR_SPI_MAX_BUFSIZE 4096 + +struct ir_spi_data { + u32 freq; + u8 duty_cycle; + bool negated; + + u16 tx_buf[IR_SPI_MAX_BUFSIZE]; + u16 pulse; + u16 space; + + struct rc_dev *rc; + struct spi_device *spi; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int count) +{ + int i; + int ret; + unsigned int len = 0; + struct ir_spi_data *idata = dev->priv; + struct spi_transfer xfer; + + /* convert the pulse/space signal to raw binary signal */ + for (i = 0; i
[PATCH v2 1/7] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Change accordingly all the drivers calling rc_allocate_device() so that the device type is specified during the rc device allocation. Whenever the device type is not specified, it will be set as RC_DRIVER_SCANCODE which was the default '0' value. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/hid/hid-picolcd_cir.c | 3 +-- drivers/media/common/siano/smsir.c | 3 +-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c| 2 +- drivers/media/pci/cx23885/cx23885-input.c | 11 +-- drivers/media/pci/cx88/cx88-input.c | 3 +-- drivers/media/pci/dm1105/dm1105.c | 3 +-- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 3 +-- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 3 +-- drivers/media/rc/ene_ir.c | 3 +-- drivers/media/rc/fintek-cir.c | 3 +-- drivers/media/rc/gpio-ir-recv.c | 3 +-- drivers/media/rc/igorplugusb.c | 3 +-- drivers/media/rc/iguanair.c | 3 +-- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c| 3 +-- drivers/media/rc/imon.c | 3 +-- drivers/media/rc/ir-hix5hd2.c | 3 +-- drivers/media/rc/ite-cir.c | 3 +-- drivers/media/rc/mceusb.c | 3 +-- drivers/media/rc/meson-ir.c | 3 +-- drivers/media/rc/nuvoton-cir.c | 3 +-- drivers/media/rc/rc-loopback.c | 3 +-- drivers/media/rc/rc-main.c | 4 +++- drivers/media/rc/redrat3.c | 3 +-- drivers/media/rc/st_rc.c| 3 +-- drivers/media/rc/streamzap.c| 3 +-- drivers/media/rc/sunxi-cir.c| 3 +-- drivers/media/rc/ttusbir.c | 3 +-- drivers/media/rc/winbond-cir.c | 3 +-- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/cx231xx/cx231xx-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 3 +-- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 3 +-- drivers/staging/media/cec/cec-core.c| 3 +-- include/media/rc-core.h | 4 +++- 41 files changed, 45 insertions(+), 80 deletions(-) diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 9628651..38b0ea8 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -108,12 +108,11 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) struct rc_dev *rdev; int ret = 0; - rdev = rc_allocate_device(); + rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rdev) return -ENOMEM; rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close= picolcd_cir_close; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 41f2a39..ee30c7b 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -58,7 +58,7 @@ int sms_ir_init(struct smscore_device_t *coredev) struct rc_dev *dev; pr_debug("Allocating rc device\n"); - dev = rc_allocate_device(); + dev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!dev) return -ENOMEM; @@ -86,7 +86,6 @@ int sms_ir_init(struct smscore_device_t *coredev) #endif dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; dev->allowed_protocols = RC_BIT_ALL; dev->map_name = sms_get_board(board_id)->rc_codes; dev->driver_name = MODULE_NAME; diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index bf82726..918fd7d 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -398,7 +398,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) * If platform_data doesn't specify rc_dev, initialize it * internally */ - rc = rc_allocate_device(); + rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!rc)
[PATCH v2 5/7] [media] ir-lirc-codec: don't wait any transmitting time for tx only devices
Transmitters do not need to wait until the data has been sent (and of course received). Return before waiting. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/ir-lirc-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index c327730..d8953fb 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -153,7 +153,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, } ret = dev->tx_ir(dev, txbuf, count); - if (ret < 0) + if (ret < 0 || dev->driver_type == RC_DRIVER_IR_RAW_TX) goto out; for (duration = i = 0; i < ret; i++) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/7] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 144 + 1 file changed, 81 insertions(+), 63 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b28a8d1..7961083 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1403,16 +1403,12 @@ void rc_free_device(struct rc_dev *dev) } EXPORT_SYMBOL_GPL(rc_free_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1421,6 +1417,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1430,6 +1439,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1453,40 +1517,15 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -* to do. -*/ - dev->input_dev->rep[REP_PERIOD] = 125; - - /* rc_open will be called here */ - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - path = kobject_get_path(>dev.kobj, GFP_KERNEL); dev_info(>dev, "%s as %s\n", dev->input_name ?: "Unspecified
Re: [RFC 7/7] [media] rc: add support for IR LEDs driven through SPI
Hi Sean, > > > > + ret = regulator_enable(idata->regulator); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + mutex_lock(>mutex); > > > > + idata->xfer.len = n; > > > > + idata->xfer.tx_buf = buffer; > > > > + mutex_unlock(>mutex); > > > > > > I'm not convinced the locking works here. You want to guard against > > > someone modifying xfer while you are sending (so in spi_sync_transfer), > > > which this locking is not doing. You could declare a > > > local "struct spi_transfer xfer" and avoid the mutex altogether. > > > > I cannot declare xfer locally because the spi framework needs > > a statically allocated xfer, so that either I dynamically > > allocate it in the function or I declare it global in idata. > > It can be stack allocated for sync transfers. You might want to lock > the spi bus. no, actually it's just dirty data and laziness, a memset to 0 fixes it :) > > With the mutex I would like to prevent different tasks to change > > the value at the same time, it's an easy case, it shouldn't make > > much difference. > > That's cargo-cult locking. It does not achieve anything. yes, as I said, it's not a big thing, I can remove the mutex. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 7/7] [media] rc: add support for IR LEDs driven through SPI
Hi Sean, > > + int ret; > > + struct ir_spi_data *idata = (struct ir_spi_data *) dev->priv; > > No cast needed. yes, thanks. > > + ret = regulator_enable(idata->regulator); > > + if (ret) > > + return ret; > > + > > + mutex_lock(>mutex); > > + idata->xfer.len = n; > > + idata->xfer.tx_buf = buffer; > > + mutex_unlock(>mutex); > > I'm not convinced the locking works here. You want to guard against > someone modifying xfer while you are sending (so in spi_sync_transfer), > which this locking is not doing. You could declare a > local "struct spi_transfer xfer" and avoid the mutex altogether. I cannot declare xfer locally because the spi framework needs a statically allocated xfer, so that either I dynamically allocate it in the function or I declare it global in idata. With the mutex I would like to prevent different tasks to change the value at the same time, it's an easy case, it shouldn't make much difference. There are checkpatch issues, in the next patchset I will fix them. Thanks a lot for your review, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 5/7] [media] ir-lirc-codec: do not handle any buffer for raw transmitters
Hi Sean, > > Raw transmitters receive the data which need to be sent to > > receivers from userspace as stream of bits, they don't require > > any handling from the lirc framework. > > No drivers of type RC_DRIVER_IR_RAW_TX should handle tx just like any > other device, so data should be provided as an array of u32 alternating > pulse-space. If your device does not handle input like that then convert > it into that format in the driver. Every other driver has to do some > sort of conversion of that kind. I don't see anything wrong here, that's how it works for example in Tizen or in Android for the boards I'm on: userspace sends a stream of bits that are then submitted to the IR as they are. If I change it to only pulse-space domain, then I wouldn't provide support for those platforms. Eventually I can add a new protocol. Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 3/7] [media] rc-core: add support for IR raw transmitters
Hi Sean, > > + if (dev->driver_type == RC_DRIVER_IR_RAW || > > + dev->driver_type == RC_DRIVER_IR_RAW_TX) { > > Here the if is wrong. It should be > "if (dev->driver_type != RC_DRIVER_IR_RAW_TX)". Note that as result > the decoder thread is not started, so patch 4 won't be needed either. but I need the ir-lirc-codec as it handles the interface with userspace and it calls the tx_ir and s_tx_carrier. if I do "if (dev->driver_type != RC_DRIVER_IR_RAW_TX)" the lirc-codec is not called and I would need to handle it on my driver, but then we fall in the first version of the driver. Thanks, Andi > > if (!raw_init) { > > request_module_nowait("ir-lirc-codec"); > > raw_init = true; -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 1/7] [media] rc-main: assign driver type during allocation
Hi Sean, > > The driver type can be assigned immediately when an RC device > > requests to the framework to allocate the device. > > > > This is an 'enum rc_driver_type' data type and specifies whether > > the device is a raw receiver or scancode receiver. The type will > > be given as parameter to the rc_allocate_device device. > > This patch is good, but it does unfortunately break all the other > rc-core drivers, as now rc_allocate_device() needs argument. All > drivers will need a simple change in this patch. Yes, but for being an RFC I didn't took care of fixing everything. > Also note that there lots of issues that checkpatch.pl would pick > in these series. Some of the issues are coming from the code as it was and I preferred to not change it. The last patch has some that need to be fixed in the patchset. Thanks, Andi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 5/7] [media] ir-lirc-codec: do not handle any buffer for raw transmitters
Raw transmitters receive the data which need to be sent to receivers from userspace as stream of bits, they don't require any handling from the lirc framework. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/ir-lirc-codec.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 5effc65..80e94b6 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -121,17 +121,6 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, if (!lirc) return -EFAULT; - if (n < sizeof(unsigned) || n % sizeof(unsigned)) - return -EINVAL; - - count = n / sizeof(unsigned); - if (count > LIRCBUF_SIZE || count % 2 == 0) - return -EINVAL; - - txbuf = memdup_user(buf, n); - if (IS_ERR(txbuf)) - return PTR_ERR(txbuf); - dev = lirc->dev; if (!dev) { ret = -EFAULT; @@ -143,6 +132,25 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, goto out; } + if (dev->driver_type == RC_DRIVER_IR_RAW_TX) { + txbuf = memdup_user(buf, n); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + + return dev->tx_ir(dev, txbuf, n); + } + + if (n < sizeof(unsigned) || n % sizeof(unsigned)) + return -EINVAL; + + count = n / sizeof(unsigned); + if (count > LIRCBUF_SIZE || count % 2 == 0) + return -EINVAL; + + txbuf = memdup_user(buf, n); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + for (i = 0; i < count; i++) { if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) { ret = -EINVAL; -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 2/7] [media] rc-main: split setup and unregister functions
Move the input device allocation, map and protocol handling to different functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 140 + 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 6403674..ac91157 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1396,16 +1396,12 @@ void rc_free_device(struct rc_dev *dev) } EXPORT_SYMBOL_GPL(rc_free_device); -int rc_register_device(struct rc_dev *dev) +static int rc_setup_rx_device(struct rc_dev *dev) { - static bool raw_init = false; /* raw decoders loaded? */ - struct rc_map *rc_map; - const char *path; - int attr = 0; - int minor; int rc; + struct rc_map *rc_map; - if (!dev || !dev->map_name) + if (!dev->map_name) return -EINVAL; rc_map = rc_map_get(dev->map_name); @@ -1414,6 +1410,19 @@ int rc_register_device(struct rc_dev *dev) if (!rc_map || !rc_map->scan || rc_map->size == 0) return -EINVAL; + rc = ir_setkeytable(dev, rc_map); + if (rc) + return rc; + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + + rc = dev->change_protocol(dev, _type); + if (rc < 0) + goto out_table; + dev->enabled_protocols = rc_type; + } + set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); set_bit(EV_MSC, dev->input_dev->evbit); @@ -1423,6 +1432,61 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; + /* +* Default delay of 250ms is too short for some protocols, especially +* since the timeout is currently set to 250ms. Increase it to 500ms, +* to avoid wrong repetition of the keycodes. Note that this must be +* set after the call to input_register_device(). +*/ + dev->input_dev->rep[REP_DELAY] = 500; + + /* +* As a repeat event on protocols like RC-5 and NEC take as long as +* 110/114ms, using 33ms as a repeat period is not the right thing +* to do. +*/ + dev->input_dev->rep[REP_PERIOD] = 125; + + /* rc_open will be called here */ + rc = input_register_device(dev->input_dev); + if (rc) + goto out_table; + + dev->input_dev->dev.parent = >dev; + memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + return 0; + +out_table: + ir_free_table(>rc_map); + + return rc; +} + +static void rc_free_rx_device(struct rc_dev *dev) +{ + if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX) + return; + + ir_free_table(>rc_map); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +} + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev) + return -EINVAL; + minor = ida_simple_get(_ida, 0, RC_DEV_MAX, GFP_KERNEL); if (minor < 0) return minor; @@ -1446,35 +1510,6 @@ int rc_register_device(struct rc_dev *dev) if (rc) goto out_unlock; - rc = ir_setkeytable(dev, rc_map); - if (rc) - goto out_dev; - - dev->input_dev->dev.parent = >dev; - memcpy(>input_dev->id, >input_id, sizeof(dev->input_id)); - dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; - - /* -* Default delay of 250ms is too short for some protocols, especially -* since the timeout is currently set to 250ms. Increase it to 500ms, -* to avoid wrong repetition of the keycodes. Note that this must be -* set after the call to input_register_device(). -*/ - dev->input_dev->rep[REP_DELAY] = 500; - - /* -* As a repeat event on protocols like RC-5 and NEC take as long as -* 110/114ms, using 33ms as a repeat period is not the right thing -* to do. -*/ - dev->input_dev->rep[REP_PERIOD] = 125; - - /* rc_open will be called here */ - rc = input_register_device(dev->input_dev); - if (rc) - goto out_table; - path = kobject_get_path(>dev.kobj, GFP_KERNEL); dev_info(>dev, "%s as %s\n", dev->input_name ?: "Unspecif
[RFC 7/7] [media] rc: add support for IR LEDs driven through SPI
The ir-spi is a simple device driver which supports the connection between an IR LED and the MOSI line of an SPI device. The driver, indeed, uses the SPI framework to stream the raw data provided by userspace through a character device. The chardev is handled by the LIRC framework and its functionality basically provides: - raw write: data to be sent to the SPI and then streamed to the MOSI line; - set frequency: sets the frequency whith which the data should be sent; The character device is created under /dev/lircX name, where X is and ID assigned by the LIRC framework. Example of usage: fd = open("/dev/lirc0", O_RDWR); if (fd < 0) return -1; val = 608000; ret = ioctl(fd, LIRC_SET_SEND_CARRIER, ); if (ret < 0) return -1; n = write(fd, buffer, BUF_LEN); if (n < 0 || n != BUF_LEN) ret = -1; close(fd); Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/Kconfig | 9 drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-spi.c | 133 ++ 3 files changed, 143 insertions(+) create mode 100644 drivers/media/rc/ir-spi.c diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index bd4d685..dacaa29 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -261,6 +261,15 @@ config IR_REDRAT3 To compile this driver as a module, choose M here: the module will be called redrat3. +config IR_SPI + tristate "SPI connected IR LED" + depends on SPI && LIRC + ---help--- + Say Y if you want to use an IR LED connected through SPI bus. + + To compile this driver as a module, choose M here: the module will be + called ir-spi. + config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 379a5c0..1417c8d 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o obj-$(CONFIG_IR_RX51) += ir-rx51.o +obj-$(CONFIG_IR_SPI) += ir-spi.o obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c new file mode 100644 index 000..7b6f344 --- /dev/null +++ b/drivers/media/rc/ir-spi.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Author: Andi Shyti <andi.sh...@samsung.it> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * SPI driven IR LED device driver + */ + +#include +#include +#include +#include +#include +#include +#include + +#define IR_SPI_DRIVER_NAME "ir-spi" + +#define IR_SPI_DEFAULT_FREQUENCY 38000 +#define IR_SPI_BIT_PER_WORD8 + +struct ir_spi_data { + struct rc_dev *rc; + struct spi_device *spi; + struct spi_transfer xfer; + struct mutex mutex; + struct regulator *regulator; +}; + +static int ir_spi_tx(struct rc_dev *dev, unsigned *buffer, unsigned n) +{ + int ret; + struct ir_spi_data *idata = (struct ir_spi_data *) dev->priv; + + ret = regulator_enable(idata->regulator); + if (ret) + return ret; + + mutex_lock(>mutex); + idata->xfer.len = n; + idata->xfer.tx_buf = buffer; + mutex_unlock(>mutex); + + ret = spi_sync_transfer(idata->spi, >xfer, 1); + if (ret) + dev_err(>spi->dev, "unable to deliver the signal\n"); + + regulator_disable(idata->regulator); + + return ret; +} + +static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier) +{ + struct ir_spi_data *idata = (struct ir_spi_data *) dev->priv; + + if (!carrier) + return -EINVAL; + + mutex_lock(>mutex); + idata->xfer.speed_hz = carrier; + mutex_unlock(>mutex); + + return 0; +} + +static int ir_spi_probe(struct spi_device *spi) +{ + int ret; + struct ir_spi_data *idata; + + idata = devm_kzalloc(>dev, sizeof(*idata), GFP_KERNEL); + if (!idata) + return -ENOMEM; + + idata->regulator = devm_regulator_get(>dev, "irda_regulator"); + if (IS_ERR(idata->regulator)) + return PTR_ERR(idata->regulator); + + idata->rc = rc_allocate_device(RC_DRIVER_IR_RAW_TX); + if (!idata->rc) + return -ENOMEM; + + idata->rc->s_tx_carrier =
[RFC 1/7] [media] rc-main: assign driver type during allocation
The driver type can be assigned immediately when an RC device requests to the framework to allocate the device. This is an 'enum rc_driver_type' data type and specifies whether the device is a raw receiver or scancode receiver. The type will be given as parameter to the rc_allocate_device device. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 4 +++- include/media/rc-core.h| 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7dfc7c2..6403674 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1346,7 +1346,7 @@ static struct device_type rc_dev_type = { .uevent = rc_dev_uevent, }; -struct rc_dev *rc_allocate_device(void) +struct rc_dev *rc_allocate_device(enum rc_driver_type type) { struct rc_dev *dev; @@ -1373,6 +1373,8 @@ struct rc_dev *rc_allocate_device(void) dev->dev.class = _class; device_initialize(>dev); + dev->driver_type = type; + __module_get(THIS_MODULE); return dev; } diff --git a/include/media/rc-core.h b/include/media/rc-core.h index b6586a9..c6bf1ef 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -185,7 +185,7 @@ struct rc_dev { * Remote Controller, at sys/class/rc. */ -struct rc_dev *rc_allocate_device(void); +struct rc_dev *rc_allocate_device(enum rc_driver_type); void rc_free_device(struct rc_dev *dev); int rc_register_device(struct rc_dev *dev); void rc_unregister_device(struct rc_dev *dev); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 6/7] Documentation: bindings: add documentation for ir-spi device driver
Document the ir-spi driver's binding which is a IR led driven through the SPI line. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- Documentation/devicetree/bindings/media/spi-ir.txt | 20 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/spi-ir.txt diff --git a/Documentation/devicetree/bindings/media/spi-ir.txt b/Documentation/devicetree/bindings/media/spi-ir.txt new file mode 100644 index 000..532da68 --- /dev/null +++ b/Documentation/devicetree/bindings/media/spi-ir.txt @@ -0,0 +1,20 @@ +Device tree bindings for IR LED connected through SPI bus which is used as +remote controller. + +The IR LED switch is connected to the MOSI line of the SPI device and the data +are delivered thourgh that. + +Required properties: + - compatible: should be "ir-spi" + +Optional properties: + - irled,switch: specifies the gpio switch which enables the irled + +Example: + +irled@0 { +compatible = "ir-spi"; +reg = <0x0>; +spi-max-frequency = <500>; +irled,switch = < 3 0>; +}; -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 3/7] [media] rc-core: add support for IR raw transmitters
IR raw transmitter driver type is specified in the enum rc_driver_type as RC_DRIVER_IR_RAW_TX which includes all those devices that transmit raw stream of bit to a receiver. The data are provided by userspace applications, therefore they don't need any input device allocation, but still they need to be registered as raw devices. Suggested-by: Sean Young <s...@mess.org> Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-main.c | 35 +++ include/media/rc-core.h| 1 + 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index ac91157..f555f38 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1354,20 +1354,24 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) if (!dev) return NULL; - dev->input_dev = input_allocate_device(); - if (!dev->input_dev) { - kfree(dev); - return NULL; - } + if (type != RC_DRIVER_IR_RAW_TX) { + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } - dev->input_dev->getkeycode = ir_getkeycode; - dev->input_dev->setkeycode = ir_setkeycode; - input_set_drvdata(dev->input_dev, dev); + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); - spin_lock_init(>rc_map.lock); - spin_lock_init(>keylock); + setup_timer(>timer_keyup, ir_timer_keyup, + (unsigned long)dev); + + spin_lock_init(>rc_map.lock); + spin_lock_init(>keylock); + } mutex_init(>lock); - setup_timer(>timer_keyup, ir_timer_keyup, (unsigned long)dev); dev->dev.type = _dev_type; dev->dev.class = _class; @@ -1515,7 +1519,14 @@ int rc_register_device(struct rc_dev *dev) dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - if (dev->driver_type == RC_DRIVER_IR_RAW) { + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + rc = rc_setup_rx_device(dev); + if (rc) + goto out_dev; + } + + if (dev->driver_type == RC_DRIVER_IR_RAW || + dev->driver_type == RC_DRIVER_IR_RAW_TX) { if (!raw_init) { request_module_nowait("ir-lirc-codec"); raw_init = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index c6bf1ef..77b0893 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -32,6 +32,7 @@ do { \ enum rc_driver_type { RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */ RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */ + RC_DRIVER_IR_RAW_TX,/* Device is transmitter, driver handles raw */ }; /** -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 4/7] [media] rc-ir-raw: do not generate any receiving thread for raw transmitters
Raw IR transmitters do not need any thread listening for occurring events. Check the driver type before running the thread. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/rc-ir-raw.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 144304c..64ddc3d 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -274,12 +274,19 @@ int ir_raw_event_register(struct rc_dev *dev) INIT_KFIFO(dev->raw->kfifo); spin_lock_init(>raw->lock); - dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, - "rc%u", dev->minor); - if (IS_ERR(dev->raw->thread)) { - rc = PTR_ERR(dev->raw->thread); - goto out; + /* +* raw transmitters do not need any event registration +* because the event is coming from userspace +*/ + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } } mutex_lock(_raw_handler_lock); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 0/7] Add support for IR transmitters
Hi, this is an RFCset that follows this patch: http://marc.info/?l=linux-kernel=146736225606125=2 and after Sean's review and recommendations: http://marc.info/?l=linux-kernel=146737935611128=2 The main goal is to add support in the rc framework for IR transmitters, which currently is only supported by lirc but that is not the preferred way. with this RFCset I'm trying to gather some opinions as I'm not really aware of other use cases other than the simple ir transmitter in the last patch. As it is, the code to me looks quite forced in order to achieve "my" goal by abusing on the driver type check. The last rfc-patch adds support for an IR transmitter driven by the MOSI line of an SPI controller, it's the case of the Samsung TM2(e) board which support is going to come soon. Please let me know if there is anything to improve. Thanks, Andi Andi Shyti (7): [media] rc-main: assign driver type during allocation [media] rc-main: split setup and unregister functions [media] rc-core: add support for IR raw transmitters [media] rc-ir-raw: do not generate any receiving thread for raw transmitters [media] ir-lirc-codec: do not handle any buffer for raw transmitters Documentation: bindings: add documentation for ir-spi device driver [media] rc: add support for IR LEDs driven through SPI Documentation/devicetree/bindings/media/spi-ir.txt | 20 +++ drivers/media/rc/Kconfig | 9 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/ir-lirc-codec.c | 30 ++-- drivers/media/rc/ir-spi.c | 133 +++ drivers/media/rc/rc-ir-raw.c | 17 +- drivers/media/rc/rc-main.c | 179 - include/media/rc-core.h| 3 +- 8 files changed, 299 insertions(+), 93 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/spi-ir.txt create mode 100644 drivers/media/rc/ir-spi.c -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 10/15] [media] lirc_dev: remove compat_ioctl assignment
There is no need to check for CONFIG_COMPAT and consequently assign the compat_ioctl. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 71ff820..09bdd69 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -150,9 +150,6 @@ static const struct file_operations lirc_dev_fops = { .write = lirc_dev_fop_write, .poll = lirc_dev_fop_poll, .unlocked_ioctl = lirc_dev_fop_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = lirc_dev_fop_ioctl, -#endif .open = lirc_dev_fop_open, .release= lirc_dev_fop_close, .llseek = noop_llseek, -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 03/15] [media] lirc_dev: remove unnecessary debug prints
Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 25 - 1 file changed, 25 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 154e553..9f20f94 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -80,8 +80,6 @@ static void lirc_irctl_init(struct irctl *ir) static void lirc_irctl_cleanup(struct irctl *ir) { - dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); - device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); if (ir->buf != ir->d.rbuf) { @@ -127,9 +125,6 @@ static int lirc_thread(void *irctl) { struct irctl *ir = irctl; - dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n", - ir->d.name, ir->d.minor); - do { if (ir->open) { if (ir->jiffies_to_wait) { @@ -146,9 +141,6 @@ static int lirc_thread(void *irctl) } } while (!kthread_should_stop()); - dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n", - ir->d.name, ir->d.minor); - return 0; } @@ -277,8 +269,6 @@ static int lirc_allocate_driver(struct lirc_driver *d) goto out; } - dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n", - d->sample_rate); if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { dev_err(d->dev, "lirc_dev: lirc_register_driver: " @@ -521,10 +511,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) } error: - if (ir) - dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n", - ir->d.name, ir->d.minor, retval); - mutex_unlock(_dev_lock); nonseekable_open(inode, file); @@ -546,8 +532,6 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) cdev = ir->cdev; - dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); - ret = mutex_lock_killable(_dev_lock); WARN_ON(ret); @@ -582,8 +566,6 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) return POLLERR; } - dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); - if (!ir->attached) return POLLERR; @@ -679,9 +661,6 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) result = -EINVAL; } - dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n", - ir->d.name, ir->d.minor, result); - mutex_unlock(>irctl_lock); return result; @@ -786,8 +765,6 @@ out_locked: out_unlocked: kfree(buf); - dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", - ir->d.name, ir->d.minor, ret ? "" : "", ret); return ret ? ret : written; } @@ -810,8 +787,6 @@ ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer, return -ENODEV; } - dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); - if (!ir->attached) return -ENODEV; -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/15] [media] lirc_dev: place buffer allocation on separate function
During the driver registration, move the buffer allocation on a separate function. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 57 +++-- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 92ae190..5716978 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -203,13 +203,41 @@ err_out: return retval; } -int lirc_register_driver(struct lirc_driver *d) +static int lirc_allocate_buffer(struct irctl *ir) { - struct irctl *ir; - int minor; + int err; int bytes_in_key; unsigned int chunk_size; unsigned int buffer_size; + struct lirc_driver *d = >d; + + bytes_in_key = BITS_TO_LONGS(d->code_length) + + (d->code_length % 8 ? 1 : 0); + buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; + chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; + + if (d->rbuf) { + ir->buf = d->rbuf; + } else { + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!ir->buf) + return -ENOMEM; + + err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); + if (err) { + kfree(ir->buf); + return err; + } + } + ir->chunk_size = ir->buf->chunk_size; + + return 0; +} + +int lirc_register_driver(struct lirc_driver *d) +{ + struct irctl *ir; + int minor; int err; if (!d) { @@ -314,26 +342,9 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - bytes_in_key = BITS_TO_LONGS(d->code_length) + - (d->code_length % 8 ? 1 : 0); - buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; - chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; - - if (d->rbuf) { - ir->buf = d->rbuf; - } else { - ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) { - err = -ENOMEM; - goto out_lock; - } - err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); - if (err) { - kfree(ir->buf); - goto out_lock; - } - } - ir->chunk_size = ir->buf->chunk_size; + err = lirc_allocate_buffer(ir); + if (err) + goto out_lock; if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 15/15] [media] lirc_dev: use LIRC_CAN_REC() define to check if the device can receive
The LIRC_CAN_REC() returns a boolean "flag & LIRC_CAN_REC_MASK" to check whether the device can receive data. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 8cf5e6b..809a867 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -586,7 +586,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) result = put_user(ir->d.features, (__u32 __user *)arg); break; case LIRC_GET_REC_MODE: - if (!(ir->d.features & LIRC_CAN_REC_MASK)) { + if (LIRC_CAN_REC(ir->d.features)) { result = -ENOTTY; break; } @@ -596,7 +596,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) (__u32 __user *)arg); break; case LIRC_SET_REC_MODE: - if (!(ir->d.features & LIRC_CAN_REC_MASK)) { + if (LIRC_CAN_REC(ir->d.features)) { result = -ENOTTY; break; } -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/15] [media] lirc_dev: allow bufferless driver registration
Transmitters don't necessarily need to have a FIFO managed buffer for their transfers. When registering the driver, before allocating the buffer, check whether the device is a transmitter or receiver. Allocate the buffer only for receivers. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 40 ++-- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 5716978..154e553 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -205,12 +205,14 @@ err_out: static int lirc_allocate_buffer(struct irctl *ir) { - int err; + int err = 0; int bytes_in_key; unsigned int chunk_size; unsigned int buffer_size; struct lirc_driver *d = >d; + mutex_lock(_dev_lock); + bytes_in_key = BITS_TO_LONGS(d->code_length) + (d->code_length % 8 ? 1 : 0); buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; @@ -220,21 +222,26 @@ static int lirc_allocate_buffer(struct irctl *ir) ir->buf = d->rbuf; } else { ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) - return -ENOMEM; + if (!ir->buf) { + err = -ENOMEM; + goto out; + } err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); if (err) { kfree(ir->buf); - return err; + goto out; } } ir->chunk_size = ir->buf->chunk_size; - return 0; +out: + mutex_unlock(_dev_lock); + + return err; } -int lirc_register_driver(struct lirc_driver *d) +static int lirc_allocate_driver(struct lirc_driver *d) { struct irctl *ir; int minor; @@ -342,10 +349,6 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - err = lirc_allocate_buffer(ir); - if (err) - goto out_lock; - if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; @@ -385,6 +388,23 @@ out_lock: out: return err; } + +int lirc_register_driver(struct lirc_driver *d) +{ + int minor, err = 0; + + minor = lirc_allocate_driver(d); + if (minor < 0) + return minor; + + if (LIRC_CAN_REC(d->features)) { + err = lirc_allocate_buffer(irctls[minor]); + if (err) + lirc_unregister_driver(minor); + } + + return err ? err : minor; +} EXPORT_SYMBOL(lirc_register_driver); int lirc_unregister_driver(int minor) -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 00/15] lirc_dev fixes and beautification
Hi, This is a collection of fixes, added functionality, coding rework and trivial coding style fixes. The first patch is preparatory to the second, which allows the user to create a lirc driver without receiver buffer, which is obvious for transmitters. The rest of the patches is a series of coding style and code rework, as I said, some of them are very trivial, but I sent them anyway because I was on fire. Patch 14 is a segfault fix, while the last patch adds the possibility to send to ioctl the set frequency, get frequency and set length command. Changelog: V1 -> V2 - patch 4: added the pr_fmt definition and removed all the hardcoded prefixes from the pr_* functions (from Joe Perches). - patch 15: removed the definitions of the GET/SET_FREQUENCY, I will use GET/SET_SEND_CARRIER instead, even though I find the name a bit confusing (from Sean Young). - In patch 6 I did a better refactoring V2 -> V3 - patch 2: do not create a specific function for bufferless allocation, but check whether the device is a transmitter, in that case do not allocate any buffer (from Sean Young). - patch 10: remove completely compat ioctl (from Hans Verkuil). - patch 12: ioctl fails and returns -ENOTTY instead of -EPERM (from Hans Verkuil). - patch 15: removed the original patch which adds the LIRC_GET_LENTGH command to the ioctl (from Sean Young). - patch 15: new patch which uses LIRC_CAN_REC() define to check if the device is a receiver. Thanks, Andi Andi Shyti (15): [media] lirc_dev: place buffer allocation on separate function [media] lirc_dev: allow bufferless driver registration [media] lirc_dev: remove unnecessary debug prints [media] lirc_dev: replace printk with pr_* or dev_* [media] lirc_dev: simplify goto paths [media] lirc_dev: do not use goto to create loops [media] lirc_dev: simplify if statement in lirc_add_to_buf [media] lirc_dev: remove double if ... else statement [media] lirc_dev: merge three if statements in only one [media] lirc_dev: remove compat_ioctl assignment [media] lirc_dev: fix variable constant comparisons [media] lirc_dev: fix error return value [media] lirc_dev: extremely trivial comment style fix [media] lirc_dev: fix potential segfault [media] lirc_dev: use LIRC_CAN_REC() define to check if the device can receive drivers/media/rc/lirc_dev.c | 302 1 file changed, 140 insertions(+), 162 deletions(-) -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 08/15] [media] lirc_dev: remove double if ... else statement
There are two if ... else which check the same thing in different part of the code, they can be merged in a single check. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index c2826a7..a8a5116 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -310,13 +310,6 @@ static int lirc_allocate_driver(struct lirc_driver *d) irctls[minor] = ir; d->minor = minor; - if (d->sample_rate) { - ir->jiffies_to_wait = HZ / d->sample_rate; - } else { - /* it means - wait for external event in task queue */ - ir->jiffies_to_wait = 0; - } - /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; @@ -330,6 +323,8 @@ static int lirc_allocate_driver(struct lirc_driver *d) "lirc%u", ir->d.minor); if (d->sample_rate) { + ir->jiffies_to_wait = HZ / d->sample_rate; + /* try to fire up polling thread */ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); if (IS_ERR(ir->task)) { @@ -338,6 +333,9 @@ static int lirc_allocate_driver(struct lirc_driver *d) err = -ECHILD; goto out_sysfs; } + } else { + /* it means - wait for external event in task queue */ + ir->jiffies_to_wait = 0; } err = lirc_cdev_add(ir); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 04/15] [media] lirc_dev: replace printk with pr_* or dev_*
This patch mutes also all the checkpatch warnings related to printk. Reword all the printouts so that the string doesn't need to be split, which fixes the following checkpatch warning: WARNING: quoted string split across lines Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 79 +++-- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 9f20f94..59f4c93 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -19,6 +19,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -240,59 +242,51 @@ static int lirc_allocate_driver(struct lirc_driver *d) int err; if (!d) { - printk(KERN_ERR "lirc_dev: lirc_register_driver: " - "driver pointer must be not NULL!\n"); + pr_err("driver pointer must be not NULL!\n"); err = -EBADRQC; goto out; } if (!d->dev) { - printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__); + pr_err("dev pointer not filled in!\n"); err = -EINVAL; goto out; } if (MAX_IRCTL_DEVICES <= d->minor) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "\"minor\" must be between 0 and %d (%d)!\n", - MAX_IRCTL_DEVICES - 1, d->minor); + dev_err(d->dev, "minor must be between 0 and %d!\n", + MAX_IRCTL_DEVICES - 1); err = -EBADRQC; goto out; } if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "code length in bits for minor (%d) " - "must be less than %d!\n", - d->minor, BUFLEN * 8); + dev_err(d->dev, "code length must be less than %d bits\n", + BUFLEN * 8); err = -EBADRQC; goto out; } if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "sample_rate must be between 2 and %d!\n", HZ); + dev_err(d->dev, "invalid %d sample rate\n", + d->sample_rate); err = -EBADRQC; goto out; } if (!d->add_to_buf) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "add_to_buf cannot be NULL when " - "sample_rate is set\n"); + dev_err(d->dev, "add_to_buf not set\n"); err = -EBADRQC; goto out; } } else if (!(d->fops && d->fops->read) && !d->rbuf) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "fops->read and rbuf cannot all be NULL!\n"); + dev_err(d->dev, "fops->read and rbuf are NULL!\n"); err = -EBADRQC; goto out; } else if (!d->rbuf) { if (!(d->fops && d->fops->read && d->fops->poll && d->fops->unlocked_ioctl)) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "neither read, poll nor unlocked_ioctl can be NULL!\n"); + dev_err(d->dev, "undefined read, poll, ioctl\n"); err = -EBADRQC; goto out; } @@ -308,14 +302,12 @@ static int lirc_allocate_driver(struct lirc_driver *d) if (!irctls[minor]) break; if (MAX_IRCTL_DEVICES == minor) { - dev_err(d->dev, "lirc_dev: lirc_register_driver: " - "no free slots for drivers!\n"); + dev_err(d->dev, "no free slots for drivers!\n"); err = -ENOMEM; goto out_lock; } } else if (irctls[minor])
[PATCH v3 12/15] [media] lirc_dev: fix error return value
If ioctl is called, it cannot be a case of invalid system call number (ENOSYS), that is a ENOTTY case which means that the device doesn't support that specific ioctl command. Replace ENOSYS with EPERM. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index c2b32e0..ac00433 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -582,7 +582,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case LIRC_GET_REC_MODE: if (!(ir->d.features & LIRC_CAN_REC_MASK)) { - result = -ENOSYS; + result = -ENOTTY; break; } @@ -592,7 +592,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case LIRC_SET_REC_MODE: if (!(ir->d.features & LIRC_CAN_REC_MASK)) { - result = -ENOSYS; + result = -ENOTTY; break; } @@ -610,7 +610,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LIRC_GET_MIN_TIMEOUT: if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ir->d.min_timeout == 0) { - result = -ENOSYS; + result = -ENOTTY; break; } @@ -619,7 +619,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LIRC_GET_MAX_TIMEOUT: if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ir->d.max_timeout == 0) { - result = -ENOSYS; + result = -ENOTTY; break; } -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 14/15] [media] lirc_dev: fix potential segfault
When opening or closing a lirc character device, the framework provides to the user the possibility to keep track of opening or closing of the device by calling two functions: - set_use_inc() when opening the device - set_use_dec() when closing the device if those are not set by the lirc user, the system segfaults. Check the pointer value before calling the above functions. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index c78fe2b..8cf5e6b 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -408,7 +408,10 @@ int lirc_unregister_driver(int minor) ir->d.name, ir->d.minor); wake_up_interruptible(>buf->wait_poll); mutex_lock(>irctl_lock); - ir->d.set_use_dec(ir->d.data); + + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); + module_put(cdev->owner); mutex_unlock(>irctl_lock); } else { @@ -466,7 +469,8 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) cdev = ir->cdev; if (try_module_get(cdev->owner)) { ir->open++; - retval = ir->d.set_use_inc(ir->d.data); + if (ir->d.set_use_inc) + retval = ir->d.set_use_inc(ir->d.data); if (retval) { module_put(cdev->owner); @@ -507,7 +511,8 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) ir->open--; if (ir->attached) { - ir->d.set_use_dec(ir->d.data); + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); module_put(cdev->owner); } else { lirc_irctl_cleanup(ir); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/15] [media] lirc_dev: fix variable constant comparisons
When comparing a variable with a constant, the comparison should start from the variable and not from the constant. It's also written in the human DNA. Swap the terms of comparisons whenever the constant comes first and fix the following checkpatch warning: WARNING: Comparisons should place the constant on the right side of the test Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 09bdd69..c2b32e0 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -245,13 +245,13 @@ static int lirc_allocate_driver(struct lirc_driver *d) return -EINVAL; } - if (MAX_IRCTL_DEVICES <= d->minor) { + if (d->minor >= MAX_IRCTL_DEVICES) { dev_err(d->dev, "minor must be between 0 and %d!\n", MAX_IRCTL_DEVICES - 1); return -EBADRQC; } - if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { + if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { dev_err(d->dev, "code length must be less than %d bits\n", BUFLEN * 8); return -EBADRQC; @@ -282,7 +282,7 @@ static int lirc_allocate_driver(struct lirc_driver *d) for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) if (!irctls[minor]) break; - if (MAX_IRCTL_DEVICES == minor) { + if (minor == MAX_IRCTL_DEVICES) { dev_err(d->dev, "no free slots for drivers!\n"); err = -ENOMEM; goto out_lock; -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 09/15] [media] lirc_dev: merge three if statements in only one
The three if statements check the same thing, merge them in only one statement. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index a8a5116..71ff820 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -270,15 +270,10 @@ static int lirc_allocate_driver(struct lirc_driver *d) dev_err(d->dev, "add_to_buf not set\n"); return -EBADRQC; } - } else if (!(d->fops && d->fops->read) && !d->rbuf) { - dev_err(d->dev, "fops->read and rbuf are NULL!\n"); + } else if (!d->rbuf && !(d->fops && d->fops->read && + d->fops->poll && d->fops->unlocked_ioctl)) { + dev_err(d->dev, "undefined read, poll, ioctl\n"); return -EBADRQC; - } else if (!d->rbuf) { - if (!(d->fops && d->fops->read && d->fops->poll && - d->fops->unlocked_ioctl)) { - dev_err(d->dev, "undefined read, poll, ioctl\n"); - return -EBADRQC; - } } mutex_lock(_dev_lock); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 05/15] [media] lirc_dev: simplify goto paths
The code can be rearranged so that some goto paths can be removed Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 34 -- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 59f4c93..b11d026 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -243,52 +243,44 @@ static int lirc_allocate_driver(struct lirc_driver *d) if (!d) { pr_err("driver pointer must be not NULL!\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (!d->dev) { pr_err("dev pointer not filled in!\n"); - err = -EINVAL; - goto out; + return -EINVAL; } if (MAX_IRCTL_DEVICES <= d->minor) { dev_err(d->dev, "minor must be between 0 and %d!\n", MAX_IRCTL_DEVICES - 1); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { dev_err(d->dev, "code length must be less than %d bits\n", BUFLEN * 8); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (d->sample_rate) { if (2 > d->sample_rate || HZ < d->sample_rate) { dev_err(d->dev, "invalid %d sample rate\n", d->sample_rate); - err = -EBADRQC; - goto out; + return -EBADRQC; } if (!d->add_to_buf) { dev_err(d->dev, "add_to_buf not set\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } } else if (!(d->fops && d->fops->read) && !d->rbuf) { dev_err(d->dev, "fops->read and rbuf are NULL!\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } else if (!d->rbuf) { if (!(d->fops && d->fops->read && d->fops->poll && d->fops->unlocked_ioctl)) { dev_err(d->dev, "undefined read, poll, ioctl\n"); - err = -EBADRQC; - goto out; + return -EBADRQC; } } @@ -366,7 +358,7 @@ out_sysfs: device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); out_lock: mutex_unlock(_dev_lock); -out: + return err; } @@ -790,9 +782,8 @@ static int __init lirc_dev_init(void) lirc_class = class_create(THIS_MODULE, "lirc"); if (IS_ERR(lirc_class)) { - retval = PTR_ERR(lirc_class); pr_err("class_create failed\n"); - goto error; + return PTR_ERR(lirc_class); } retval = alloc_chrdev_region(_base_dev, 0, MAX_IRCTL_DEVICES, @@ -800,15 +791,14 @@ static int __init lirc_dev_init(void) if (retval) { class_destroy(lirc_class); pr_err("alloc_chrdev_region failed\n"); - goto error; + return retval; } pr_info("IR Remote Control driver registered, major %d\n", MAJOR(lirc_base_dev)); -error: - return retval; + return 0; } -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/15] [media] lirc_dev: do not use goto to create loops
... use "do .. while" instead. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index b11d026..cfa6031 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -99,18 +99,16 @@ static int lirc_add_to_buf(struct irctl *ir) { if (ir->d.add_to_buf) { int res = -ENODATA; - int got_data = 0; + int got_data = -1; /* * service the device as long as it is returning * data and we have space */ -get_data: - res = ir->d.add_to_buf(ir->d.data, ir->buf); - if (res == 0) { + do { got_data++; - goto get_data; - } + res = ir->d.add_to_buf(ir->d.data, ir->buf); + } while (!res); if (res == -ENODEV) kthread_stop(ir->task); -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 13/15] [media] lirc_dev: extremely trivial comment style fix
Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index ac00433..c78fe2b 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -687,7 +687,8 @@ ssize_t lirc_dev_fop_read(struct file *file, /* According to the read(2) man page, 'written' can be * returned as less than 'length', instead of blocking * again, returning -EWOULDBLOCK, or returning -* -ERESTARTSYS */ +* -ERESTARTSYS +*/ if (written) break; if (file->f_flags & O_NONBLOCK) { -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/15] [media] lirc_dev: simplify if statement in lirc_add_to_buf
The whole function is inside an 'if' statement ("if (ir->d.add_to_buf)"). Check the opposite of that statement at the beginning and exit, this way we can have one level less of indentation. Signed-off-by: Andi Shyti <andi.sh...@samsung.com> --- drivers/media/rc/lirc_dev.c | 31 +++ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index cfa6031..c2826a7 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -97,26 +97,25 @@ static void lirc_irctl_cleanup(struct irctl *ir) */ static int lirc_add_to_buf(struct irctl *ir) { - if (ir->d.add_to_buf) { - int res = -ENODATA; - int got_data = -1; + int res; + int got_data = -1; - /* -* service the device as long as it is returning -* data and we have space -*/ - do { - got_data++; - res = ir->d.add_to_buf(ir->d.data, ir->buf); - } while (!res); + if (!ir->d.add_to_buf) + return 0; - if (res == -ENODEV) - kthread_stop(ir->task); + /* +* service the device as long as it is returning +* data and we have space +*/ + do { + got_data++; + res = ir->d.add_to_buf(ir->d.data, ir->buf); + } while (!res); - return got_data ? 0 : res; - } + if (res == -ENODEV) + kthread_stop(ir->task); - return 0; + return got_data ? 0 : res; } /* main function of the polling thread -- 2.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html