diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
commit | 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 (patch) | |
tree | fa581f6dc1c0596391690d1f67eceef3af8246dc /drivers/media/rc | |
parent | d4e493caf788ef44982e131ff9c786546904d934 (diff) |
Linux-libre 4.5-gnu
Diffstat (limited to 'drivers/media/rc')
-rw-r--r-- | drivers/media/rc/Kconfig | 3 | ||||
-rw-r--r-- | drivers/media/rc/gpio-ir-recv.c | 24 | ||||
-rw-r--r-- | drivers/media/rc/ir-jvc-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/ir-lirc-codec.c | 1 | ||||
-rw-r--r-- | drivers/media/rc/ir-mce_kbd-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/ir-nec-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/ir-rc5-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/ir-rc6-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/rc/ir-rx51.c | 2 | ||||
-rw-r--r-- | drivers/media/rc/ir-sanyo-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/ir-sharp-decoder.c | 7 | ||||
-rw-r--r-- | drivers/media/rc/ir-sony-decoder.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/ir-xmp-decoder.c | 3 | ||||
-rw-r--r-- | drivers/media/rc/nuvoton-cir.c | 156 | ||||
-rw-r--r-- | drivers/media/rc/nuvoton-cir.h | 28 | ||||
-rw-r--r-- | drivers/media/rc/rc-core-priv.h | 71 | ||||
-rw-r--r-- | drivers/media/rc/rc-ir-raw.c | 41 | ||||
-rw-r--r-- | drivers/media/rc/rc-main.c | 88 | ||||
-rw-r--r-- | drivers/media/rc/st_rc.c | 14 | ||||
-rw-r--r-- | drivers/media/rc/streamzap.c | 19 |
20 files changed, 215 insertions, 266 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index b6e13116c..bd4d68500 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -101,7 +101,8 @@ config IR_SHARP_DECODER ---help--- Enable this option if you have an infrared remote control which - uses the Sharp protocol, and you need software decoding support. + uses the Sharp protocol (Sharp, Denon), and you need software + decoding support. config IR_MCE_KBD_DECODER tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 7dbc9ca6d..5b63b1f15 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -21,7 +21,7 @@ #include <linux/platform_device.h> #include <linux/irq.h> #include <media/rc-core.h> -#include <media/gpio-ir-recv.h> +#include <linux/platform_data/media/gpio-ir-recv.h> #define GPIO_IR_DRIVER_NAME "gpio-rc-recv" #define GPIO_IR_DEVICE_NAME "gpio_ir_recv" @@ -30,6 +30,7 @@ struct gpio_rc_dev { struct rc_dev *rcdev; int gpio_nr; bool active_low; + struct timer_list flush_timer; }; #ifdef CONFIG_OF @@ -93,12 +94,26 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) if (rc < 0) goto err_get_value; + mod_timer(&gpio_dev->flush_timer, + jiffies + nsecs_to_jiffies(gpio_dev->rcdev->timeout)); + ir_raw_event_handle(gpio_dev->rcdev); err_get_value: return IRQ_HANDLED; } +static void flush_timer(unsigned long arg) +{ + struct gpio_rc_dev *gpio_dev = (struct gpio_rc_dev *)arg; + DEFINE_IR_RAW_EVENT(ev); + + ev.timeout = true; + ev.duration = gpio_dev->rcdev->timeout; + ir_raw_event_store(gpio_dev->rcdev, &ev); + ir_raw_event_handle(gpio_dev->rcdev); +} + static int gpio_ir_recv_probe(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev; @@ -144,6 +159,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->input_id.version = 0x0100; rcdev->dev.parent = &pdev->dev; rcdev->driver_name = GPIO_IR_DRIVER_NAME; + rcdev->min_timeout = 0; + rcdev->timeout = IR_DEFAULT_TIMEOUT; + rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; if (pdata->allowed_protos) rcdev->allowed_protocols = pdata->allowed_protos; else @@ -154,6 +172,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) gpio_dev->gpio_nr = pdata->gpio_nr; gpio_dev->active_low = pdata->active_low; + setup_timer(&gpio_dev->flush_timer, flush_timer, + (unsigned long)gpio_dev); + rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); if (rc < 0) goto err_gpio_request; @@ -196,6 +217,7 @@ static int gpio_ir_recv_remove(struct platform_device *pdev) struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); + del_timer_sync(&gpio_dev->flush_timer); rc_unregister_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); kfree(gpio_dev); diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 30bcf188d..182402f7b 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -47,9 +47,6 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct jvc_dec *data = &dev->raw->jvc; - if (!(dev->enabled_protocols & RC_BIT_JVC)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index a32659fcd..5effc65d2 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -415,6 +415,7 @@ static int ir_lirc_unregister(struct rc_dev *dev) lirc_unregister_driver(lirc->drv->minor); lirc_buffer_free(lirc->drv->rbuf); + kfree(lirc->drv->rbuf); kfree(lirc->drv); return 0; diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 9f3c9b59f..d80986251 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -216,9 +216,6 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; unsigned long delay; - if (!(dev->enabled_protocols & RC_BIT_MCE_KBD)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 7b81fec08..bea0d1eed 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -52,9 +52,6 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 address, not_address, command, not_command; bool send_32bits = false; - if (!(dev->enabled_protocols & RC_BIT_NEC)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 84fa6e9b5..6ffe776ab 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -53,9 +53,6 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; enum rc_type protocol; - if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ))) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index d16bc67af..e0e2edefa 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -90,11 +90,6 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 toggle; enum rc_type protocol; - if (!(dev->enabled_protocols & - (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE))) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c index b1e19a262..4e1711a40 100644 --- a/drivers/media/rc/ir-rx51.c +++ b/drivers/media/rc/ir-rx51.c @@ -31,7 +31,7 @@ #include <media/lirc.h> #include <media/lirc_dev.h> -#include <media/ir-rx51.h> +#include <linux/platform_data/media/ir-rx51.h> #define LIRC_RX51_DRIVER_FEATURES (LIRC_CAN_SET_SEND_DUTY_CYCLE | \ LIRC_CAN_SET_SEND_CARRIER | \ diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index ad1dc6ae2..7331e5e7c 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -58,9 +58,6 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 address, command, not_command; - if (!(dev->enabled_protocols & RC_BIT_SANYO)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) { IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index b7acdbae8..317677f06 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -48,9 +48,6 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) struct sharp_dec *data = &dev->raw->sharp; u32 msg, echo, address, command, scancode; - if (!(dev->enabled_protocols & RC_BIT_SHARP)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; @@ -118,7 +115,9 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) if (data->count == SHARP_NBITS) { /* exp,chk bits should be 1,0 */ - if ((data->bits & 0x3) != 0x2) + if ((data->bits & 0x3) != 0x2 && + /* DENON variant, both chk bits 0 */ + (data->bits & 0x3) != 0x0) break; data->state = STATE_ECHO_SPACE; } else { diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 58ef06f35..baa972c76 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -46,10 +46,6 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 device, subdevice, function; - if (!(dev->enabled_protocols & - (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c index 1017d4816..18596190b 100644 --- a/drivers/media/rc/ir-xmp-decoder.c +++ b/drivers/media/rc/ir-xmp-decoder.c @@ -43,9 +43,6 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct xmp_dec *data = &dev->raw->xmp; - if (!(dev->enabled_protocols & RC_BIT_XMP)) - return 0; - if (!is_timing_event(ev)) { if (ev.reset) data->state = STATE_INACTIVE; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 85af7a869..18adf580f 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -39,6 +39,18 @@ #include "nuvoton-cir.h" +static const struct nvt_chip nvt_chips[] = { + { "w83667hg", NVT_W83667HG }, + { "NCT6775F", NVT_6775F }, + { "NCT6776F", NVT_6776F }, + { "NCT6779D", NVT_6779D }, +}; + +static inline bool is_w83667hg(struct nvt_dev *nvt) +{ + return nvt->chip_ver == NVT_W83667HG; +} + /* write val to config reg */ static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg) { @@ -224,74 +236,60 @@ static void cir_wake_dump_regs(struct nvt_dev *nvt) pr_cont("\n"); } +static inline const char *nvt_find_chip(struct nvt_dev *nvt, int id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nvt_chips); i++) + if ((id & SIO_ID_MASK) == nvt_chips[i].chip_ver) { + nvt->chip_ver = nvt_chips[i].chip_ver; + return nvt_chips[i].name; + } + + return NULL; +} + + /* detect hardware features */ -static int nvt_hw_detect(struct nvt_dev *nvt) +static void nvt_hw_detect(struct nvt_dev *nvt) { - unsigned long flags; - u8 chip_major, chip_minor; - char chip_id[12]; - bool chip_unknown = false; + const char *chip_name; + int chip_id; nvt_efm_enable(nvt); /* Check if we're wired for the alternate EFER setup */ - chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); - if (chip_major == 0xff) { + nvt->chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); + if (nvt->chip_major == 0xff) { nvt->cr_efir = CR_EFIR2; nvt->cr_efdr = CR_EFDR2; nvt_efm_enable(nvt); - chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); + nvt->chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI); } - chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); - - /* these are the known working chip revisions... */ - switch (chip_major) { - case CHIP_ID_HIGH_667: - strcpy(chip_id, "w83667hg\0"); - if (chip_minor != CHIP_ID_LOW_667) - chip_unknown = true; - break; - case CHIP_ID_HIGH_677B: - strcpy(chip_id, "w83677hg\0"); - if (chip_minor != CHIP_ID_LOW_677B2 && - chip_minor != CHIP_ID_LOW_677B3) - chip_unknown = true; - break; - case CHIP_ID_HIGH_677C: - strcpy(chip_id, "w83677hg-c\0"); - if (chip_minor != CHIP_ID_LOW_677C) - chip_unknown = true; - break; - default: - strcpy(chip_id, "w836x7hg\0"); - chip_unknown = true; - break; - } + nvt->chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); + + chip_id = nvt->chip_major << 8 | nvt->chip_minor; + chip_name = nvt_find_chip(nvt, chip_id); /* warn, but still let the driver load, if we don't know this chip */ - if (chip_unknown) - nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, " - "it may not work...", chip_id, chip_major, chip_minor); + if (!chip_name) + dev_warn(&nvt->pdev->dev, + "unknown chip, id: 0x%02x 0x%02x, it may not work...", + nvt->chip_major, nvt->chip_minor); else - nvt_dbg("%s: chip id: 0x%02x 0x%02x", - chip_id, chip_major, chip_minor); + dev_info(&nvt->pdev->dev, + "found %s or compatible: chip id: 0x%02x 0x%02x", + chip_name, nvt->chip_major, nvt->chip_minor); nvt_efm_disable(nvt); - - spin_lock_irqsave(&nvt->nvt_lock, flags); - nvt->chip_major = chip_major; - nvt->chip_minor = chip_minor; - spin_unlock_irqrestore(&nvt->nvt_lock, flags); - - return 0; } static void nvt_cir_ldev_init(struct nvt_dev *nvt) { u8 val, psreg, psmask, psval; - if (nvt->chip_major == CHIP_ID_HIGH_667) { + if (is_w83667hg(nvt)) { psreg = CR_MULTIFUNC_PIN_SEL; psmask = MULTIFUNC_PIN_SEL_MASK; psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB; @@ -485,8 +483,9 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) duration *= SAMPLE_PERIOD; if (!count || !duration) { - nvt_pr(KERN_NOTICE, "Unable to determine carrier! (c:%u, d:%u)", - count, duration); + dev_notice(&nvt->pdev->dev, + "Unable to determine carrier! (c:%u, d:%u)", + count, duration); return 0; } @@ -661,7 +660,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt) { - nvt_pr(KERN_WARNING, "RX FIFO overrun detected, flushing data!"); + dev_warn(&nvt->pdev->dev, "RX FIFO overrun detected, flushing data!"); nvt->pkts = 0; nvt_clear_cir_fifo(nvt); @@ -719,7 +718,7 @@ static void nvt_get_rx_ir_data(struct nvt_dev *nvt) static void nvt_cir_log_irqs(u8 status, u8 iren) { - nvt_pr(KERN_INFO, "IRQ 0x%02x (IREN 0x%02x) :%s%s%s%s%s%s%s%s%s", + nvt_dbg("IRQ 0x%02x (IREN 0x%02x) :%s%s%s%s%s%s%s%s%s", status, iren, status & CIR_IRSTS_RDR ? " RDR" : "", status & CIR_IRSTS_RTR ? " RTR" : "", @@ -779,7 +778,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) if (!status) { nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__); nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); - return IRQ_RETVAL(IRQ_NONE); + return IRQ_NONE; } /* ack/clear all irq flags we've got */ @@ -790,11 +789,10 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) iren = nvt_cir_reg_read(nvt, CIR_IREN); if (!iren) { nvt_dbg_verbose("%s exiting, CIR not enabled", __func__); - return IRQ_RETVAL(IRQ_NONE); + return IRQ_NONE; } - if (debug) - nvt_cir_log_irqs(status, iren); + nvt_cir_log_irqs(status, iren); if (status & CIR_IRSTS_RTR) { /* FIXME: add code for study/learn mode */ @@ -853,7 +851,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) } nvt_dbg_verbose("%s done", __func__); - return IRQ_RETVAL(IRQ_HANDLED); + return IRQ_HANDLED; } /* Interrupt service routine for CIR Wake */ @@ -867,7 +865,7 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data) status = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS); if (!status) - return IRQ_RETVAL(IRQ_NONE); + return IRQ_NONE; if (status & CIR_WAKE_IRSTS_IR_PENDING) nvt_clear_cir_wake_fifo(nvt); @@ -879,7 +877,7 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data) iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN); if (!iren) { nvt_dbg_wake("%s exiting, wake not enabled", __func__); - return IRQ_RETVAL(IRQ_HANDLED); + return IRQ_HANDLED; } if ((status & CIR_WAKE_IRSTS_PE) && @@ -896,7 +894,7 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data) } nvt_dbg_wake("%s done", __func__); - return IRQ_RETVAL(IRQ_HANDLED); + return IRQ_HANDLED; } static void nvt_enable_cir(struct nvt_dev *nvt) @@ -974,7 +972,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) struct rc_dev *rdev; int ret = -ENOMEM; - nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL); + nvt = devm_kzalloc(&pdev->dev, sizeof(struct nvt_dev), GFP_KERNEL); if (!nvt) return ret; @@ -1026,9 +1024,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) init_waitqueue_head(&nvt->tx.queue); - ret = nvt_hw_detect(nvt); - if (ret) - goto exit_free_dev_rdev; + nvt_hw_detect(nvt); /* Initialize CIR & CIR Wake Logical Devices */ nvt_efm_enable(nvt); @@ -1074,25 +1070,26 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) ret = -EBUSY; /* now claim resources */ - if (!request_region(nvt->cir_addr, + if (!devm_request_region(&pdev->dev, nvt->cir_addr, CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) goto exit_unregister_device; - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto exit_release_cir_addr; + if (devm_request_irq(&pdev->dev, nvt->cir_irq, nvt_cir_isr, + IRQF_SHARED, NVT_DRIVER_NAME, (void *)nvt)) + goto exit_unregister_device; - if (!request_region(nvt->cir_wake_addr, + if (!devm_request_region(&pdev->dev, nvt->cir_wake_addr, CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto exit_free_irq; + goto exit_unregister_device; - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto exit_release_cir_wake_addr; + if (devm_request_irq(&pdev->dev, nvt->cir_wake_irq, + nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto exit_unregister_device; device_init_wakeup(&pdev->dev, true); - nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); + dev_notice(&pdev->dev, "driver has been successfully loaded\n"); if (debug) { cir_dump_regs(nvt); cir_wake_dump_regs(nvt); @@ -1100,18 +1097,11 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) return 0; -exit_release_cir_wake_addr: - release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); -exit_free_irq: - free_irq(nvt->cir_irq, nvt); -exit_release_cir_addr: - release_region(nvt->cir_addr, CIR_IOREG_LENGTH); exit_unregister_device: rc_unregister_device(rdev); rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); - kfree(nvt); return ret; } @@ -1129,15 +1119,7 @@ static void nvt_remove(struct pnp_dev *pdev) nvt_enable_wake(nvt); spin_unlock_irqrestore(&nvt->nvt_lock, flags); - /* free resources */ - free_irq(nvt->cir_irq, nvt); - free_irq(nvt->cir_wake_irq, nvt); - release_region(nvt->cir_addr, CIR_IOREG_LENGTH); - release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); - rc_unregister_device(nvt->rdev); - - kfree(nvt); } static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index e1cf23c38..0ad15d34e 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -35,9 +35,6 @@ static int debug; -#define nvt_pr(level, text, ...) \ - printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__) - #define nvt_dbg(text, ...) \ if (debug) \ printk(KERN_DEBUG \ @@ -64,6 +61,21 @@ static int debug; #define TX_BUF_LEN 256 #define RX_BUF_LEN 32 +#define SIO_ID_MASK 0xfff0 + +enum nvt_chip_ver { + NVT_UNKNOWN = 0, + NVT_W83667HG = 0xa510, + NVT_6775F = 0xb470, + NVT_6776F = 0xc330, + NVT_6779D = 0xc560 +}; + +struct nvt_chip { + const char *name; + enum nvt_chip_ver chip_ver; +}; + struct nvt_dev { struct pnp_dev *pdev; struct rc_dev *rdev; @@ -93,6 +105,7 @@ struct nvt_dev { int cir_irq; int cir_wake_irq; + enum nvt_chip_ver chip_ver; /* hardware id */ u8 chip_major; u8 chip_minor; @@ -326,15 +339,6 @@ struct nvt_dev { #define EFER_EFM_ENABLE 0x87 #define EFER_EFM_DISABLE 0xaa -/* Chip IDs found in CR_CHIP_ID_{HI,LO} */ -#define CHIP_ID_HIGH_667 0xa5 -#define CHIP_ID_HIGH_677B 0xb4 -#define CHIP_ID_HIGH_677C 0xc3 -#define CHIP_ID_LOW_667 0x13 -#define CHIP_ID_LOW_677B2 0x72 -#define CHIP_ID_LOW_677B3 0x73 -#define CHIP_ID_LOW_677C 0x33 - /* Config regs we need to care about */ #define CR_SOFTWARE_RESET 0x02 #define CR_LOGICAL_DEV_SEL 0x07 diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index b68d4f762..7359f3d03 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -167,75 +167,4 @@ void ir_raw_init(void); * loads the compiled decoders for their usage with IR raw events */ -/* from ir-nec-decoder.c */ -#ifdef CONFIG_IR_NEC_DECODER_MODULE -#define load_nec_decode() request_module_nowait("ir-nec-decoder") -#else -static inline void load_nec_decode(void) { } -#endif - -/* from ir-rc5-decoder.c */ -#ifdef CONFIG_IR_RC5_DECODER_MODULE -#define load_rc5_decode() request_module_nowait("ir-rc5-decoder") -#else -static inline void load_rc5_decode(void) { } -#endif - -/* from ir-rc6-decoder.c */ -#ifdef CONFIG_IR_RC6_DECODER_MODULE -#define load_rc6_decode() request_module_nowait("ir-rc6-decoder") -#else -static inline void load_rc6_decode(void) { } -#endif - -/* from ir-jvc-decoder.c */ -#ifdef CONFIG_IR_JVC_DECODER_MODULE -#define load_jvc_decode() request_module_nowait("ir-jvc-decoder") -#else -static inline void load_jvc_decode(void) { } -#endif - -/* from ir-sony-decoder.c */ -#ifdef CONFIG_IR_SONY_DECODER_MODULE -#define load_sony_decode() request_module_nowait("ir-sony-decoder") -#else -static inline void load_sony_decode(void) { } -#endif - -/* from ir-sanyo-decoder.c */ -#ifdef CONFIG_IR_SANYO_DECODER_MODULE -#define load_sanyo_decode() request_module_nowait("ir-sanyo-decoder") -#else -static inline void load_sanyo_decode(void) { } -#endif - -/* from ir-sharp-decoder.c */ -#ifdef CONFIG_IR_SHARP_DECODER_MODULE -#define load_sharp_decode() request_module_nowait("ir-sharp-decoder") -#else -static inline void load_sharp_decode(void) { } -#endif - -/* from ir-mce_kbd-decoder.c */ -#ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE -#define load_mce_kbd_decode() request_module_nowait("ir-mce_kbd-decoder") -#else -static inline void load_mce_kbd_decode(void) { } -#endif - -/* from ir-lirc-codec.c */ -#ifdef CONFIG_IR_LIRC_CODEC_MODULE -#define load_lirc_codec() request_module_nowait("ir-lirc-codec") -#else -static inline void load_lirc_codec(void) { } -#endif - -/* from ir-xmp-decoder.c */ -#ifdef CONFIG_IR_XMP_DECODER_MODULE -#define load_xmp_decode() request_module_nowait("ir-xmp-decoder") -#else -static inline void load_xmp_decode(void) { } -#endif - - #endif /* _RC_CORE_PRIV */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index ad260520a..c69807fe2 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -59,7 +59,9 @@ static int ir_raw_event_thread(void *data) mutex_lock(&ir_raw_handler_lock); list_for_each_entry(handler, &ir_raw_handler_list, list) - handler->decode(raw->dev, ev); + if (raw->dev->enabled_protocols & handler->protocols || + !handler->protocols) + handler->decode(raw->dev, ev); raw->prev_ev = ev; mutex_unlock(&ir_raw_handler_lock); } @@ -246,6 +248,14 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_type) return 0; } +static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols) +{ + mutex_lock(&dev->lock); + dev->enabled_protocols &= ~protocols; + dev->enabled_wakeup_protocols &= ~protocols; + mutex_unlock(&dev->lock); +} + /* * Used to (un)register raw event clients */ @@ -337,33 +347,16 @@ EXPORT_SYMBOL(ir_raw_handler_register); void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) { struct ir_raw_event_ctrl *raw; + u64 protocols = ir_raw_handler->protocols; mutex_lock(&ir_raw_handler_lock); list_del(&ir_raw_handler->list); - if (ir_raw_handler->raw_unregister) - list_for_each_entry(raw, &ir_raw_client_list, list) + list_for_each_entry(raw, &ir_raw_client_list, list) { + ir_raw_disable_protocols(raw->dev, protocols); + if (ir_raw_handler->raw_unregister) ir_raw_handler->raw_unregister(raw->dev); - available_protocols &= ~ir_raw_handler->protocols; + } + available_protocols &= ~protocols; mutex_unlock(&ir_raw_handler_lock); } EXPORT_SYMBOL(ir_raw_handler_unregister); - -void ir_raw_init(void) -{ - /* Load the decoder modules */ - - load_nec_decode(); - load_rc5_decode(); - load_rc6_decode(); - load_jvc_decode(); - load_sony_decode(); - load_sanyo_decode(); - load_sharp_decode(); - load_mce_kbd_decode(); - load_lirc_codec(); - load_xmp_decode(); - - /* If needed, we may later add some init code. In this case, - it is needed to change the CONFIG_MODULE test at rc-core.h - */ -} diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 3f0f71ada..1042fa331 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -61,7 +61,7 @@ struct rc_map *rc_map_get(const char *name) struct rc_map_list *map; map = seek_rc_map(name); -#ifdef MODULE +#ifdef CONFIG_MODULES if (!map) { int rc = request_module("%s", name); if (rc < 0) { @@ -777,30 +777,31 @@ static struct class rc_class = { * used by the sysfs protocols file. Note that the order * of the entries is relevant. */ -static struct { +static const struct { u64 type; - char *name; + const char *name; + const char *module_name; } proto_names[] = { - { RC_BIT_NONE, "none" }, - { RC_BIT_OTHER, "other" }, - { RC_BIT_UNKNOWN, "unknown" }, + { RC_BIT_NONE, "none", NULL }, + { RC_BIT_OTHER, "other", NULL }, + { RC_BIT_UNKNOWN, "unknown", NULL }, { RC_BIT_RC5 | - RC_BIT_RC5X, "rc-5" }, - { RC_BIT_NEC, "nec" }, + RC_BIT_RC5X, "rc-5", "ir-rc5-decoder" }, + { RC_BIT_NEC, "nec", "ir-nec-decoder" }, { RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | - RC_BIT_RC6_MCE, "rc-6" }, - { RC_BIT_JVC, "jvc" }, + RC_BIT_RC6_MCE, "rc-6", "ir-rc6-decoder" }, + { RC_BIT_JVC, "jvc", "ir-jvc-decoder" }, { RC_BIT_SONY12 | RC_BIT_SONY15 | - RC_BIT_SONY20, "sony" }, - { RC_BIT_RC5_SZ, "rc-5-sz" }, - { RC_BIT_SANYO, "sanyo" }, - { RC_BIT_SHARP, "sharp" }, - { RC_BIT_MCE_KBD, "mce_kbd" }, - { RC_BIT_XMP, "xmp" }, + RC_BIT_SONY20, "sony", "ir-sony-decoder" }, + { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" }, + { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" }, + { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" }, + { RC_BIT_MCE_KBD, "mce_kbd", "ir-mce_kbd-decoder" }, + { RC_BIT_XMP, "xmp", "ir-xmp-decoder" }, }; /** @@ -979,6 +980,48 @@ static int parse_protocol_change(u64 *protocols, const char *buf) return count; } +static void ir_raw_load_modules(u64 *protocols) + +{ + u64 available; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (proto_names[i].type == RC_BIT_NONE || + proto_names[i].type & (RC_BIT_OTHER | RC_BIT_UNKNOWN)) + continue; + + available = ir_raw_get_allowed_protocols(); + if (!(*protocols & proto_names[i].type & ~available)) + continue; + + if (!proto_names[i].module_name) { + pr_err("Can't enable IR protocol %s\n", + proto_names[i].name); + *protocols &= ~proto_names[i].type; + continue; + } + + ret = request_module("%s", proto_names[i].module_name); + if (ret < 0) { + pr_err("Couldn't load IR protocol module %s\n", + proto_names[i].module_name); + *protocols &= ~proto_names[i].type; + continue; + } + msleep(20); + available = ir_raw_get_allowed_protocols(); + if (!(*protocols & proto_names[i].type & ~available)) + continue; + + pr_err("Loaded IR protocol module %s, \ + but protocol %s still not available\n", + proto_names[i].module_name, + proto_names[i].name); + *protocols &= ~proto_names[i].type; + } +} + /** * store_protocols() - changes the current/wakeup IR protocol(s) * @device: the device descriptor @@ -1045,6 +1088,9 @@ static ssize_t store_protocols(struct device *device, goto out; } + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_load_modules(&new_protocols); + if (new_protocols != old_protocols) { *current_protocols = new_protocols; IR_dprintk(1, "Protocols changed to 0x%llx\n", @@ -1420,17 +1466,13 @@ int rc_register_device(struct rc_dev *dev) dev->input_dev->rep[REP_PERIOD] = 125; path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); - printk(KERN_INFO "%s: %s as %s\n", - dev_name(&dev->dev), - dev->input_name ? dev->input_name : "Unspecified device", - path ? path : "N/A"); + dev_info(&dev->dev, "%s as %s\n", + dev->input_name ?: "Unspecified device", path ?: "N/A"); kfree(path); if (dev->driver_type == RC_DRIVER_IR_RAW) { - /* Load raw decoders, if they aren't already */ if (!raw_init) { - IR_dprintk(1, "Loading raw decoders\n"); - ir_raw_init(); + request_module_nowait("ir-lirc-codec"); raw_init = true; } /* calls ir_register_device so unlock mutex here*/ diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 37d040158..1fa0c9d1c 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -16,6 +16,7 @@ #include <linux/reset.h> #include <media/rc-core.h> #include <linux/pinctrl/consumer.h> +#include <linux/pm_wakeirq.h> struct st_rc_device { struct device *dev; @@ -190,6 +191,9 @@ static void st_rc_hardware_init(struct st_rc_device *dev) static int st_rc_remove(struct platform_device *pdev) { struct st_rc_device *rc_dev = platform_get_drvdata(pdev); + + dev_pm_clear_wake_irq(&pdev->dev); + device_init_wakeup(&pdev->dev, false); clk_disable_unprepare(rc_dev->sys_clock); rc_unregister_device(rc_dev->rdev); return 0; @@ -298,22 +302,22 @@ static int st_rc_probe(struct platform_device *pdev) rdev->map_name = RC_MAP_LIRC; rdev->input_name = "ST Remote Control Receiver"; - /* enable wake via this device */ - device_set_wakeup_capable(dev, true); - device_set_wakeup_enable(dev, true); - ret = rc_register_device(rdev); if (ret < 0) goto clkerr; rc_dev->rdev = rdev; if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt, - IRQF_NO_SUSPEND, IR_ST_NAME, rc_dev) < 0) { + 0, IR_ST_NAME, rc_dev) < 0) { dev_err(dev, "IRQ %d register failed\n", rc_dev->irq); ret = -EINVAL; goto rcerr; } + /* enable wake via this device */ + device_init_wakeup(dev, true); + dev_pm_set_wake_irq(dev, rc_dev->irq); + /** * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW * lircd expects a long space first before a signal train to sync. diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 5a17cb88f..815243c65 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -34,6 +34,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/ktime.h> #include <linux/usb.h> #include <linux/usb/input.h> #include <media/rc-core.h> @@ -96,8 +97,8 @@ struct streamzap_ir { /* sum of signal lengths received since signal start */ unsigned long sum; /* start time of signal; necessary for gap tracking */ - struct timeval signal_last; - struct timeval signal_start; + ktime_t signal_last; + ktime_t signal_start; bool timeout_enabled; char name[128]; @@ -136,20 +137,18 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, DEFINE_IR_RAW_EVENT(rawir); if (sz->idle) { - long deltv; + int delta; sz->signal_last = sz->signal_start; - do_gettimeofday(&sz->signal_start); + sz->signal_start = ktime_get_real(); - deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; + delta = ktime_us_delta(sz->signal_start, sz->signal_last); rawir.pulse = false; - if (deltv > 15) { + if (delta > (15 * USEC_PER_SEC)) { /* really long time */ rawir.duration = IR_MAX_DURATION; } else { - rawir.duration = (int)(deltv * 1000000 + - sz->signal_start.tv_usec - - sz->signal_last.tv_usec); + rawir.duration = delta; rawir.duration -= sz->sum; rawir.duration = US_TO_NS(rawir.duration); rawir.duration = (rawir.duration > IR_MAX_DURATION) ? @@ -428,7 +427,7 @@ static int streamzap_probe(struct usb_interface *intf, sz->max_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION); #endif - do_gettimeofday(&sz->signal_start); + sz->signal_start = ktime_get_real(); /* Complete final initialisations */ usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in, |