2016-11-02 10:40:43

by Andi Shyti

[permalink] [raw]
Subject: [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


2016-11-02 10:40:48

by Andi Shyti

[permalink] [raw]
Subject: [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 <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
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)
return -ENOMEM;
}
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index a75c53d..6187b7b 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -424,7 +424,7 @@ int bttv_input_init(struct bttv *btv)
return -ENODEV;

ir = kzalloc(sizeof(*ir),GFP_KERNEL);
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!ir || !rc)
goto err_out_free;

diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 410c314..0c31666 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -267,7 +267,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
struct cx23885_kernel_ir *kernel_ir;
struct rc_dev *rc;
char *rc_map;
- enum rc_driver_type driver_type;
u64 allowed_protos;

int ret;
@@ -285,28 +284,24 @@ int cx23885_input_init(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1290:
case CX23885_BOARD_HAUPPAUGE_HVR1250:
/* Integrated CX2388[58] IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* The grey Hauppauge RC-5 remote */
rc_map = RC_MAP_HAUPPAUGE;
break;
case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* The grey Terratec remote with orange buttons */
rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
break;
case CX23885_BOARD_TEVII_S470:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TEVII_NEC;
break;
case CX23885_BOARD_MYGICA_X8507:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
@@ -314,7 +309,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
case CX23885_BOARD_TBS_6980:
case CX23885_BOARD_TBS_6981:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TBS_NEC;
@@ -326,13 +320,11 @@ int cx23885_input_init(struct cx23885_dev *dev)
case CX23885_BOARD_DVBSKY_S952:
case CX23885_BOARD_DVBSKY_T982:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
rc_map = RC_MAP_DVBSKY;
break;
case CX23885_BOARD_TT_CT2_4500_CI:
/* Integrated CX23885 IR controller */
- driver_type = RC_DRIVER_IR_RAW;
allowed_protos = RC_BIT_ALL;
rc_map = RC_MAP_TT_1500;
break;
@@ -352,7 +344,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
pci_name(dev->pci));

/* input device */
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc) {
ret = -ENOMEM;
goto err_out_free;
@@ -371,7 +363,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
rc->input_id.product = dev->pci->device;
}
rc->dev.parent = &dev->pci->dev;
- rc->driver_type = driver_type;
rc->allowed_protocols = allowed_protos;
rc->priv = kernel_ir;
rc->open = cx23885_input_ir_open;
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index cd76871..af32224 100644
--- a/drivers/media/pci/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
@@ -272,7 +272,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
*/

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;

@@ -482,7 +482,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;
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 5dd5047..5f9c6e6 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -744,7 +744,7 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)
struct rc_dev *dev;
int err = -ENOMEM;

- dev = rc_allocate_device();
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!dev)
return -ENOMEM;

@@ -753,7 +753,6 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)

dev->driver_name = MODULE_NAME;
dev->map_name = RC_MAP_DM1105_NEC;
- dev->driver_type = RC_DRIVER_SCANCODE;
dev->input_name = "DVB on-card IR receiver";
dev->input_phys = dm1105->ir.input_phys;
dev->input_id.bustype = BUS_PCI;
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
index 7f7f1d4..50d10cb 100644
--- a/drivers/media/pci/mantis/mantis_input.c
+++ b/drivers/media/pci/mantis/mantis_input.c
@@ -39,7 +39,7 @@ int mantis_input_init(struct mantis_pci *mantis)
struct rc_dev *dev;
int err;

- dev = rc_allocate_device();
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!dev) {
dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
err = -ENOMEM;
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index eff52bb..f4900e0 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -849,7 +849,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
}

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;
diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c
index 826c7c7..d2730c3 100644
--- a/drivers/media/pci/smipcie/smipcie-ir.c
+++ b/drivers/media/pci/smipcie/smipcie-ir.c
@@ -183,7 +183,7 @@ int smi_ir_init(struct smi_dev *dev)
struct rc_dev *rc_dev;
struct smi_rc *ir = &dev->ir;

- rc_dev = rc_allocate_device();
+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!rc_dev)
return -ENOMEM;

@@ -202,7 +202,6 @@ int smi_ir_init(struct smi_dev *dev)
rc_dev->input_id.product = dev->pci_dev->subsystem_device;
rc_dev->dev.parent = &dev->pci_dev->dev;

- rc_dev->driver_type = RC_DRIVER_SCANCODE;
rc_dev->map_name = dev->info->rc_map;

ir->rc_dev = rc_dev;
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 7b27af4..5ced8ee 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -177,7 +177,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
struct rc_dev *dev;
int error;

- dev = rc_allocate_device();
+ dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
return -ENOMEM;
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 9f5b597..0b4c7df 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -765,7 +765,6 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
struct rc_dev *rdev = ati_remote->rdev;

rdev->priv = ati_remote;
- rdev->driver_type = RC_DRIVER_SCANCODE;
rdev->allowed_protocols = RC_BIT_OTHER;
rdev->driver_name = "ati_remote";

@@ -852,7 +851,7 @@ static int ati_remote_probe(struct usb_interface *interface,
}

ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
- rc_dev = rc_allocate_device();
+ rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!ati_remote || !rc_dev)
goto exit_free_dev_rdev;

diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index d1c61cd..c62d097 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -1012,7 +1012,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)

/* allocate memory */
dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!dev || !rdev)
goto exit_free_dev_rdev;

@@ -1058,7 +1058,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (!dev->hw_learning_and_tx_capable)
learning_mode_force = false;

- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->priv = dev;
rdev->open = ene_open;
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index bd7b3bd..5bf572b 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -496,7 +496,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
return ret;

/* input device for IR remote (and tx) */
- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev)
goto exit_free_dev_rdev;

@@ -538,7 +538,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id

/* Set up the rc device */
rdev->priv = fintek;
- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = fintek_open;
rdev->close = fintek_close;
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 5b63b1f..d5d2152 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -143,14 +143,13 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
if (!gpio_dev)
return -ENOMEM;

- rcdev = rc_allocate_device();
+ rcdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rcdev) {
rc = -ENOMEM;
goto err_allocate_device;
}

rcdev->priv = gpio_dev;
- rcdev->driver_type = RC_DRIVER_IR_RAW;
rcdev->input_name = GPIO_IR_DEVICE_NAME;
rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
rcdev->input_id.bustype = BUS_HOST;
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index 5cf983b..d770a62 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -190,7 +190,7 @@ static int igorplugusb_probe(struct usb_interface *intf,

usb_make_path(udev, ir->phys, sizeof(ir->phys));

- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc)
goto fail;

@@ -198,7 +198,6 @@ static int igorplugusb_probe(struct usb_interface *intf,
rc->input_phys = ir->phys;
usb_to_input_id(udev, &rc->input_id);
rc->dev.parent = &intf->dev;
- rc->driver_type = RC_DRIVER_IR_RAW;
/*
* This device can only store 36 pulses + spaces, which is not enough
* for the NEC protocol and many others.
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 5f63454..4cd1e6b 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -431,7 +431,7 @@ static int iguanair_probe(struct usb_interface *intf,
struct usb_host_interface *idesc;

ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!ir || !rc) {
ret = -ENOMEM;
goto out;
@@ -494,7 +494,6 @@ static int iguanair_probe(struct usb_interface *intf,
rc->input_phys = ir->phys;
usb_to_input_id(ir->udev, &rc->input_id);
rc->dev.parent = &intf->dev;
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_ALL;
rc->priv = ir;
rc->open = iguanair_open;
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
index 7bb71bc..c87ae03 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -1071,7 +1071,7 @@ int img_ir_probe_hw(struct img_ir_priv *priv)
}

/* Allocate hardware decoder */
- hw->rdev = rdev = rc_allocate_device();
+ hw->rdev = rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!rdev) {
dev_err(priv->dev, "cannot allocate input device\n");
error = -ENOMEM;
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
index 33f37ed..8d2f8e2 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.c
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
@@ -110,7 +110,7 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);

/* Allocate raw decoder */
- raw->rdev = rdev = rc_allocate_device();
+ raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev) {
dev_err(priv->dev, "cannot allocate raw input device\n");
return -ENOMEM;
@@ -118,7 +118,6 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
rdev->priv = priv;
rdev->map_name = RC_MAP_EMPTY;
rdev->input_name = "IMG Infrared Decoder Raw";
- rdev->driver_type = RC_DRIVER_IR_RAW;

/* Register raw decoder */
error = rc_register_device(rdev);
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 86cc70fe25..d1295cb 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1951,7 +1951,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88 };

- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!rdev) {
dev_err(ictx->dev, "remote control dev allocation failed\n");
goto out;
@@ -1969,7 +1969,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
rdev->dev.parent = ictx->dev;

rdev->priv = ictx;
- rdev->driver_type = RC_DRIVER_SCANCODE;
rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
rdev->change_protocol = imon_ir_change_protocol;
rdev->driver_name = MOD_NAME;
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
index d0549fb..459bdbc 100644
--- a/drivers/media/rc/ir-hix5hd2.c
+++ b/drivers/media/rc/ir-hix5hd2.c
@@ -222,7 +222,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
return priv->irq;
}

- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev)
return -ENOMEM;

@@ -235,7 +235,6 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
clk_prepare_enable(priv->clock);
priv->rate = clk_get_rate(priv->clock);

- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->priv = priv;
rdev->open = hix5hd2_ir_open;
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 0f30190..f58bf7f 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1470,7 +1470,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
return ret;

/* input device for IR remote (and tx) */
- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev)
goto exit_free_dev_rdev;
itdev->rdev = rdev;
@@ -1562,7 +1562,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id

/* set up ir-core props */
rdev->priv = itdev;
- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = ite_open;
rdev->close = ite_close;
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 4f8c7ef..bac08f7 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1220,7 +1220,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
struct rc_dev *rc;
int ret;

- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc) {
dev_err(dev, "remote dev allocation failed");
goto out;
@@ -1240,7 +1240,6 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
usb_to_input_id(ir->usbdev, &rc->input_id);
rc->dev.parent = dev;
rc->priv = ir;
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_ALL;
rc->timeout = MS_TO_NS(100);
if (!ir->flags.no_tx) {
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 003fff0..2f43c3b 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -131,7 +131,7 @@ static int meson_ir_probe(struct platform_device *pdev)
return ir->irq;
}

- ir->rc = rc_allocate_device();
+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!ir->rc) {
dev_err(dev, "failed to allocate rc device\n");
return -ENOMEM;
@@ -144,7 +144,6 @@ static int meson_ir_probe(struct platform_device *pdev)
map_name = of_get_property(node, "linux,rc-map-name", NULL);
ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
ir->rc->dev.parent = dev;
- ir->rc->driver_type = RC_DRIVER_IR_RAW;
ir->rc->allowed_protocols = RC_BIT_ALL;
ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
ir->rc->timeout = MS_TO_NS(200);
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 04fedaa..57ef5a2 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1009,7 +1009,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
return ret;

/* input device for IR remote (and tx) */
- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev)
goto exit_free_dev_rdev;

@@ -1073,7 +1073,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)

/* Set up the rc device */
rdev->priv = nvt;
- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = nvt_open;
rdev->close = nvt_close;
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 63dace8..36192ac 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -181,7 +181,7 @@ static int __init loop_init(void)
struct rc_dev *rc;
int ret;

- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc) {
printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
return -ENOMEM;
@@ -194,7 +194,6 @@ static int __init loop_init(void)
rc->driver_name = DRIVER_NAME;
rc->map_name = RC_MAP_EMPTY;
rc->priv = &loopdev;
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_ALL;
rc->timeout = 100 * 1000 * 1000; /* 100 ms */
rc->min_timeout = 1;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index d9c1f2f..9e19b73e 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1355,7 +1355,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;

@@ -1382,6 +1382,8 @@ struct rc_dev *rc_allocate_device(void)
dev->dev.class = &rc_class;
device_initialize(&dev->dev);

+ dev->driver_type = type;
+
__module_get(THIS_MODULE);
return dev;
}
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 05ba47b..1f58321 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -911,7 +911,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
int ret = -ENODEV;
u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);

- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc) {
dev_err(dev, "remote input dev allocation failed\n");
goto out;
@@ -929,7 +929,6 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
usb_to_input_id(rr3->udev, &rc->input_id);
rc->dev.parent = dev;
rc->priv = rr3;
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_ALL;
rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index 1fa0c9d..e6f6735 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -235,7 +235,7 @@ static int st_rc_probe(struct platform_device *pdev)
if (!rc_dev)
return -ENOMEM;

- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);

if (!rdev)
return -ENOMEM;
@@ -290,7 +290,6 @@ static int st_rc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rc_dev);
st_rc_hardware_init(rc_dev);

- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
/* rx sampling rate is 10Mhz */
rdev->rx_resolution = 100;
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index 4004260..efd176c 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -291,7 +291,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
struct device *dev = sz->dev;
int ret;

- rdev = rc_allocate_device();
+ rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rdev) {
dev_err(dev, "remote dev allocation failed\n");
goto out;
@@ -309,7 +309,6 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
usb_to_input_id(sz->usbdev, &rdev->input_id);
rdev->dev.parent = dev;
rdev->priv = sz;
- rdev->driver_type = RC_DRIVER_IR_RAW;
rdev->allowed_protocols = RC_BIT_ALL;
rdev->driver_name = DRIVER_NAME;
rdev->map_name = RC_MAP_STREAMZAP;
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index eaadc08..5451f3d 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -212,7 +212,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
goto exit_clkdisable_clk;
}

- ir->rc = rc_allocate_device();
+ ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!ir->rc) {
dev_err(dev, "failed to allocate device\n");
ret = -ENOMEM;
@@ -229,7 +229,6 @@ static int sunxi_ir_probe(struct platform_device *pdev)
ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
ir->rc->dev.parent = dev;
- ir->rc->driver_type = RC_DRIVER_IR_RAW;
ir->rc->allowed_protocols = RC_BIT_ALL;
ir->rc->rx_resolution = SUNXI_IR_SAMPLE;
ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
index bc214e2..6ff2cef 100644
--- a/drivers/media/rc/ttusbir.c
+++ b/drivers/media/rc/ttusbir.c
@@ -205,7 +205,7 @@ static int ttusbir_probe(struct usb_interface *intf,
int altsetting = -1;

tt = kzalloc(sizeof(*tt), GFP_KERNEL);
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!tt || !rc) {
ret = -ENOMEM;
goto out;
@@ -317,7 +317,6 @@ static int ttusbir_probe(struct usb_interface *intf,
rc->input_phys = tt->phys;
usb_to_input_id(tt->udev, &rc->input_id);
rc->dev.parent = &intf->dev;
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_ALL;
rc->priv = tt;
rc->driver_name = DRIVER_NAME;
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 95ae60e..62d8225 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1062,13 +1062,12 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
if (err)
goto exit_free_data;

- data->dev = rc_allocate_device();
+ data->dev = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!data->dev) {
err = -ENOMEM;
goto exit_unregister_led;
}

- data->dev->driver_type = RC_DRIVER_IR_RAW;
data->dev->driver_name = DRVNAME;
data->dev->input_name = WBCIR_NAME;
data->dev->input_phys = "wbcir/cir0";
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 1e66e78..9ec919c 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -298,7 +298,7 @@ int au0828_rc_register(struct au0828_dev *dev)
return -ENODEV;

ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!ir || !rc)
goto error;

@@ -343,7 +343,6 @@ int au0828_rc_register(struct au0828_dev *dev)
rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
rc->dev.parent = &dev->usbdev->dev;
rc->driver_name = "au0828-input";
- rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 |
RC_BIT_RC5;

diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 15d8d1b..6e80f3c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
@@ -72,7 +72,7 @@ int cx231xx_ir_init(struct cx231xx *dev)

memset(&info, 0, sizeof(struct i2c_board_info));
memset(&dev->init_data, 0, sizeof(dev->init_data));
- dev->init_data.rc_dev = rc_allocate_device();
+ dev->init_data.rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!dev->init_data.rc_dev)
return -ENOMEM;

diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index a8e6624..298c91a 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -147,7 +147,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
if (!d->rc.map_name)
return 0;

- dev = rc_allocate_device();
+ dev = rc_allocate_device(d->rc.driver_type);
if (!dev) {
ret = -ENOMEM;
goto err;
@@ -162,7 +162,6 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
/* TODO: likely RC-core should took const char * */
dev->driver_name = (char *) d->props->driver_name;
dev->map_name = d->rc.map_name;
- dev->driver_type = d->rc.driver_type;
dev->allowed_protocols = d->rc.allowed_protos;
dev->change_protocol = d->rc.change_protocol;
dev->priv = d;
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
index c259f9e..059ded5 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
@@ -265,7 +265,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
int err, rc_interval;
struct rc_dev *dev;

- dev = rc_allocate_device();
+ dev = rc_allocate_device(d->props.rc.core.driver_type);
if (!dev)
return -ENOMEM;

@@ -273,7 +273,6 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
dev->map_name = d->props.rc.core.rc_codes;
dev->change_protocol = d->props.rc.core.change_protocol;
dev->allowed_protocols = d->props.rc.core.allowed_protos;
- dev->driver_type = d->props.rc.core.driver_type;
usb_to_input_id(d->udev, &dev->input_id);
dev->input_name = "IR-receiver inside an USB DVB receiver";
dev->input_phys = d->rc_phys;
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 4007356..ca526d1 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -713,7 +713,7 @@ static int em28xx_ir_init(struct em28xx *dev)
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
if (!ir)
return -ENOMEM;
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!rc)
goto error;

diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c
index 26b2ebb..377a69b 100644
--- a/drivers/media/usb/tm6000/tm6000-input.c
+++ b/drivers/media/usb/tm6000/tm6000-input.c
@@ -429,7 +429,7 @@ int tm6000_ir_init(struct tm6000_core *dev)
return 0;

ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
- rc = rc_allocate_device();
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!ir || !rc)
goto out;

@@ -456,7 +456,6 @@ int tm6000_ir_init(struct tm6000_core *dev)
ir->polling = 50;
INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
}
- rc->driver_type = RC_DRIVER_SCANCODE;

snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
dev->name);
diff --git a/drivers/staging/media/cec/cec-core.c b/drivers/staging/media/cec/cec-core.c
index b0137e2..09bc0ba 100644
--- a/drivers/staging/media/cec/cec-core.c
+++ b/drivers/staging/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/include/media/rc-core.h b/include/media/rc-core.h
index 40188d3..f8ca557 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -198,9 +198,11 @@ struct rc_dev {
/**
* rc_allocate_device - Allocates a RC device
*
+ * @rc_driver_type: specifies the type of the RC output to be allocated
+ *
* returns a pointer to struct rc_dev.
*/
-struct rc_dev *rc_allocate_device(void);
+struct rc_dev *rc_allocate_device(enum rc_driver_type);

/**
* rc_free_device - Frees a RC device
--
2.10.1

2016-11-02 10:40:56

by Andi Shyti

[permalink] [raw]
Subject: [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 <[email protected]>
Signed-off-by: Andi Shyti <[email protected]>
---
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(&dev->timer_keyup, ir_timer_keyup,
+ (unsigned long)dev);

- spin_lock_init(&dev->rc_map.lock);
- spin_lock_init(&dev->keylock);
+ spin_lock_init(&dev->rc_map.lock);
+ spin_lock_init(&dev->keylock);
+ }
mutex_init(&dev->lock);
- setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);

dev->dev.type = &rc_dev_type;
dev->dev.class = &rc_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(&dev->rc_map);
@@ -1506,7 +1510,8 @@ int rc_register_device(struct rc_dev *dev)
atomic_set(&dev->initialized, 0);

dev->dev.groups = dev->sysfs_groups;
- dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
+ if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+ dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
if (dev->s_filter)
dev->sysfs_groups[attr++] = &rc_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

2016-11-02 10:41:04

by Andi Shyti

[permalink] [raw]
Subject: [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, &val);
if (ret < 0)
return -1;

val = 60;
ret = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, &val);
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 <[email protected]>
Reviewed-by: Sean Young <[email protected]>
---
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 0000000..fcda1e4
--- /dev/null
+++ b/drivers/media/rc/ir-spi.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Author: Andi Shyti <[email protected]>
+ *
+ * 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 <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <media/rc-core.h>
+
+#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_WORD 8
+#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;
+
+ /*
+ * the first value in buffer is a pulse, so that 0, 2, 4, ...
+ * contain a pulse duration. On the contrary, 1, 3, 5, ...
+ * contain a space duration.
+ */
+ val = (i % 2) ? idata->space : idata->pulse;
+ for (j = 0; j < buffer[i]; j++)
+ idata->tx_buf[len++] = val;
+ }
+
+ memset(&xfer, 0, sizeof(xfer));
+
+ xfer.speed_hz = idata->freq;
+ xfer.len = len * sizeof(*idata->tx_buf);
+ xfer.tx_buf = idata->tx_buf;
+
+ ret = regulator_enable(idata->regulator);
+ if (ret)
+ return ret;
+
+ ret = spi_sync_transfer(idata->spi, &xfer, 1);
+ if (ret)
+ dev_err(&idata->spi->dev, "unable to deliver the signal\n");
+
+ regulator_disable(idata->regulator);
+
+ return ret ? ret : count;
+}
+
+static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+ struct ir_spi_data *idata = dev->priv;
+
+ if (!carrier)
+ return -EINVAL;
+
+ idata->freq = carrier;
+
+ return 0;
+}
+
+static int ir_spi_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+ struct ir_spi_data *idata = dev->priv;
+
+ if (duty_cycle >= 90)
+ idata->pulse = IR_SPI_PULSE_DC_90;
+ else if (duty_cycle >= 80)
+ idata->pulse = IR_SPI_PULSE_DC_80;
+ else if (duty_cycle >= 75)
+ idata->pulse = IR_SPI_PULSE_DC_75;
+ else if (duty_cycle >= 70)
+ idata->pulse = IR_SPI_PULSE_DC_70;
+ else if (duty_cycle >= 60)
+ idata->pulse = IR_SPI_PULSE_DC_60;
+ else
+ idata->pulse = IR_SPI_PULSE_DC_50;
+
+ if (idata->negated) {
+ idata->pulse = ~idata->pulse;
+ idata->space = 0xffff;
+ } else {
+ idata->space = 0;
+ }
+
+ return 0;
+}
+
+static int ir_spi_probe(struct spi_device *spi)
+{
+ int ret;
+ u8 dc;
+ struct ir_spi_data *idata;
+
+ idata = devm_kzalloc(&spi->dev, sizeof(*idata), GFP_KERNEL);
+ if (!idata)
+ return -ENOMEM;
+
+ idata->regulator = devm_regulator_get(&spi->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->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;
+ idata->rc->driver_name = IR_SPI_DRIVER_NAME;
+ idata->rc->priv = idata;
+ idata->spi = spi;
+
+ idata->negated = of_property_read_bool(spi->dev.of_node,
+ "led-active-low");
+ ret = of_property_read_u8(spi->dev.of_node, "duty-cycle", &dc);
+ if (ret)
+ dc = 50;
+
+ ret = ir_spi_set_duty_cycle(idata->rc, dc);
+ if (ret)
+ return ret;
+
+ idata->freq = IR_SPI_DEFAULT_FREQUENCY;
+
+ ret = rc_register_device(idata->rc);
+ if (ret)
+ rc_free_device(idata->rc);
+
+ return ret;
+}
+
+static int ir_spi_remove(struct spi_device *spi)
+{
+ struct ir_spi_data *idata = spi_get_drvdata(spi);
+
+ rc_unregister_device(idata->rc);
+
+ return 0;
+}
+
+static const struct of_device_id ir_spi_of_match[] = {
+ { .compatible = "ir-spi-led" },
+ {},
+};
+
+static struct spi_driver ir_spi_driver = {
+ .probe = ir_spi_probe,
+ .remove = ir_spi_remove,
+ .driver = {
+ .name = IR_SPI_DRIVER_NAME,
+ .of_match_table = ir_spi_of_match,
+ },
+};
+
+module_spi_driver(ir_spi_driver);
+
+MODULE_AUTHOR("Andi Shyti <[email protected]>");
+MODULE_DESCRIPTION("SPI IR LED");
+MODULE_LICENSE("GPL v2");
--
2.10.1

2016-11-02 10:41:00

by Andi Shyti

[permalink] [raw]
Subject: [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 <[email protected]>
---
.../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 0000000..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 = <5000000>;
+ power-supply = <&vdd_led>;
+ led-active-low;
+ duty-cycle = /bits/ 8 <60>;
+ };
--
2.10.1

2016-11-02 10:41:38

by Andi Shyti

[permalink] [raw]
Subject: [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 <[email protected]>
---
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(&dev->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(&ir_raw_handler_lock);
--
2.10.1

2016-11-02 10:42:01

by Andi Shyti

[permalink] [raw]
Subject: [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 <[email protected]>
---
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, &rc_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->dev;
+ memcpy(&dev->input_dev->id, &dev->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(&dev->rc_map);
+
+ return rc;
+}
+
+static void rc_free_rx_device(struct rc_dev *dev)
+{
+ if (!dev)
+ return;
+
+ ir_free_table(&dev->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(&rc_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->dev;
- memcpy(&dev->input_dev->id, &dev->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->dev.kobj, GFP_KERNEL);
dev_info(&dev->dev, "%s as %s\n",
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) {
if (!raw_init) {
request_module_nowait("ir-lirc-codec");
@@ -1495,36 +1535,20 @@ int rc_register_device(struct rc_dev *dev)
}
rc = ir_raw_event_register(dev);
if (rc < 0)
- goto out_input;
- }
-
- if (dev->change_protocol) {
- u64 rc_type = (1ll << rc_map->rc_type);
- rc = dev->change_protocol(dev, &rc_type);
- if (rc < 0)
- goto out_raw;
- dev->enabled_protocols = rc_type;
+ goto out_rx;
}

/* Allow the RC sysfs nodes to be accessible */
atomic_set(&dev->initialized, 1);

- IR_dprintk(1, "Registered rc%u (driver: %s, remote: %s, mode %s)\n",
+ IR_dprintk(1, "Registered rc%u (driver: %s)\n",
dev->minor,
- dev->driver_name ? dev->driver_name : "unknown",
- rc_map->name ? rc_map->name : "unknown",
- dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");
+ dev->driver_name ? dev->driver_name : "unknown");

return 0;

-out_raw:
- if (dev->driver_type == RC_DRIVER_IR_RAW)
- ir_raw_event_unregister(dev);
-out_input:
- input_unregister_device(dev->input_dev);
- dev->input_dev = NULL;
-out_table:
- ir_free_table(&dev->rc_map);
+out_rx:
+ rc_free_rx_device(dev);
out_dev:
device_del(&dev->dev);
out_unlock:
@@ -1543,12 +1567,7 @@ void rc_unregister_device(struct rc_dev *dev)
if (dev->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(dev);

- /* Freeing the table should also call the stop callback */
- ir_free_table(&dev->rc_map);
- IR_dprintk(1, "Freed keycode table\n");
-
- input_unregister_device(dev->input_dev);
- dev->input_dev = NULL;
+ rc_free_rx_device(dev);

device_del(&dev->dev);

--
2.10.1

2016-11-02 12:34:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 3/6] [media] rc-core: add support for IR raw transmitters

Hi Andi,

[auto build test WARNING on hid/for-next]
[also build test WARNING on v4.9-rc3]
[cannot apply to linuxtv-media/master next-20161028]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Andi-Shyti/Add-support-for-IR-transmitters/20161102-184657
base: https://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git for-next
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

make[3]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
include/linux/init.h:1: warning: no structured comments found
include/linux/workqueue.h:392: warning: No description found for parameter '...'
include/linux/workqueue.h:392: warning: Excess function parameter 'args' description in 'alloc_workqueue'
include/linux/workqueue.h:413: warning: No description found for parameter '...'
include/linux/workqueue.h:413: warning: Excess function parameter 'args' description in 'alloc_ordered_workqueue'
include/linux/kthread.h:26: warning: No description found for parameter '...'
kernel/sys.c:1: warning: no structured comments found
drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found
include/linux/fence-array.h:61: warning: No description found for parameter 'fence'
include/sound/core.h:324: warning: No description found for parameter '...'
include/sound/core.h:335: warning: No description found for parameter '...'
include/sound/core.h:388: warning: No description found for parameter '...'
include/media/media-entity.h:1054: warning: No description found for parameter '...'
>> include/media/rc-core.h:39: warning: bad line: driver requires pulse/space data sequence.
include/net/mac80211.h:2148: WARNING: Inline literal start-string without end-string.
include/net/mac80211.h:2153: WARNING: Inline literal start-string without end-string.
include/net/mac80211.h:3202: ERROR: Unexpected indentation.
include/net/mac80211.h:3205: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:3207: ERROR: Unexpected indentation.
include/net/mac80211.h:3208: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:1435: WARNING: Inline emphasis start-string without end-string.
include/net/mac80211.h:1172: WARNING: Inline literal start-string without end-string.
include/net/mac80211.h:1173: WARNING: Inline literal start-string without end-string.
include/net/mac80211.h:814: ERROR: Unexpected indentation.
include/net/mac80211.h:815: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:820: ERROR: Unexpected indentation.
include/net/mac80211.h:821: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:2489: ERROR: Unexpected indentation.
include/net/mac80211.h:1768: ERROR: Unexpected indentation.
include/net/mac80211.h:1772: WARNING: Block quote ends without a blank line; unexpected unindent.
include/net/mac80211.h:1746: WARNING: Inline emphasis start-string without end-string.
kernel/sched/fair.c:7252: WARNING: Inline emphasis start-string without end-string.
kernel/time/timer.c:1230: ERROR: Unexpected indentation.
kernel/time/timer.c:1232: ERROR: Unexpected indentation.
kernel/time/timer.c:1233: WARNING: Block quote ends without a blank line; unexpected unindent.
include/linux/wait.h:121: WARNING: Block quote ends without a blank line; unexpected unindent.
include/linux/wait.h:124: ERROR: Unexpected indentation.
include/linux/wait.h:126: WARNING: Block quote ends without a blank line; unexpected unindent.
kernel/time/hrtimer.c:1021: WARNING: Block quote ends without a blank line; unexpected unindent.
kernel/signal.c:317: WARNING: Inline literal start-string without end-string.
drivers/base/firmware_class.c:1348: WARNING: Bullet list ends without a blank line; unexpected unindent.
drivers/message/fusion/mptbase.c:5054: WARNING: Definition list ends without a blank line; unexpected unindent.
drivers/tty/serial/serial_core.c:1893: WARNING: Definition list ends without a blank line; unexpected unindent.
include/linux/spi/spi.h:369: ERROR: Unexpected indentation.
WARNING: dvipng command 'dvipng' cannot be run (needed for math display), check the imgmath_dvipng setting

vim +39 include/media/rc-core.h

23 #include <media/rc-map.h>
24
25 extern int rc_core_debug;
26 #define IR_dprintk(level, fmt, ...) \
27 do { \
28 if (rc_core_debug >= level) \
29 printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \
30 } while (0)
31
32 /**
33 * enum rc_driver_type - type of the RC output
34 *
35 * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode
36 * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences.
37 * It needs a Infra-Red pulse/space decoder
38 * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
> 39 driver requires pulse/space data sequence.
40 */
41 enum rc_driver_type {
42 RC_DRIVER_SCANCODE = 0,
43 RC_DRIVER_IR_RAW,
44 RC_DRIVER_IR_RAW_TX,
45 };
46
47 /**

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (5.32 kB)
.config.gz (6.28 kB)
Download all attachments

2016-11-02 17:29:16

by Sean Young

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] Add support for IR transmitters

On Wed, Nov 02, 2016 at 07:40:04PM +0900, Andi Shyti wrote:
> 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.

Looks great! For the whole series:

Reviewed-by: Sean Young <[email protected]>

Thanks,
Sean

2016-11-02 19:58:10

by Heiner Kallweit

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] Add support for IR transmitters

Am 02.11.2016 um 11:40 schrieb Andi Shyti:
> 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
>
Hi Andi,

at least patches 1 and 2 conflict with recent extensions. See commits
ddbf7d5a698c "rc: core: add managed versions of rc_allocate_device and
rc_register_device" and b6f3ece38733 "[media] rc: nuvoton: use managed
versions of rc_allocate_device and rc_register_device".

It would be good if you could rebase your patch set on top of the
latest master branch of media tree. Most likely you will have to make
changes to the recently introduced managed versions of
rc_allocate_device and rc_register_device.

Rgds, Heiner

2016-11-03 08:33:06

by Jacek Anaszewski

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver

Hi Andi,

Only DT bindings of LED class drivers should be placed in
Documentation/devicetree/bindings/leds. Please move it to the
media bindings.

Thanks,
Jacek Anaszewski

On 11/02/2016 11:40 AM, Andi Shyti wrote:
> Document the ir-spi driver's binding which is a IR led driven
> through the SPI line.
>
> Signed-off-by: Andi Shyti <[email protected]>
> ---
> .../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 0000000..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 = <5000000>;
> + power-supply = <&vdd_led>;
> + led-active-low;
> + duty-cycle = /bits/ 8 <60>;
> + };
>

2016-11-03 10:11:09

by Andi Shyti

[permalink] [raw]
Subject: 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

2016-11-03 10:39:32

by Jacek Anaszewski

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver

On 11/03/2016 11:10 AM, Andi Shyti wrote:
> 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?

--
Best regards,
Jacek Anaszewski

2016-11-04 04:28:43

by Andi Shyti

[permalink] [raw]
Subject: 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

2016-11-09 18:26:27

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver

On Thu, Nov 03, 2016 at 11:39:21AM +0100, Jacek Anaszewski wrote:
> On 11/03/2016 11:10 AM, Andi Shyti wrote:
> > 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.

Rob

2016-11-10 07:46:45

by Jacek Anaszewski

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver

On 11/09/2016 07:26 PM, Rob Herring wrote:
> On Thu, Nov 03, 2016 at 11:39:21AM +0100, Jacek Anaszewski wrote:
>> On 11/03/2016 11:10 AM, Andi Shyti wrote:
>>> 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" ?

--
Best regards,
Jacek Anaszewski

2016-11-10 10:02:09

by Andi Shyti

[permalink] [raw]
Subject: 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

2016-11-14 16:10:53

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v3 5/6] Documentation: bindings: add documentation for ir-spi device driver

On Thu, Nov 10, 2016 at 4:02 AM, Andi Shyti <[email protected]> wrote:
> 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?

No. Only if they are just an LED that happens to be IR.

Rob