diff options
Diffstat (limited to 'drivers/media/rc/nuvoton-cir.c')
| -rw-r--r-- | drivers/media/rc/nuvoton-cir.c | 247 |
1 files changed, 124 insertions, 123 deletions
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 144f3f55d76..d244e1a83f4 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -25,6 +25,8 @@ * USA */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/pnp.h> @@ -123,43 +125,40 @@ static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset) return val; } -#define pr_reg(text, ...) \ - printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__) - /* dump current cir register contents */ static void cir_dump_regs(struct nvt_dev *nvt) { nvt_efm_enable(nvt); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); - pr_reg("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); - pr_reg(" * CR CIR ACTIVE : 0x%x\n", - nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); - pr_reg(" * CR CIR BASE ADDR: 0x%x\n", - (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + pr_info("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME); + pr_info(" * CR CIR ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_info(" * CR CIR BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); - pr_reg(" * CR CIR IRQ NUM: 0x%x\n", - nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + pr_info(" * CR CIR IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); nvt_efm_disable(nvt); - pr_reg("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); - pr_reg(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); - pr_reg(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); - pr_reg(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); - pr_reg(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); - pr_reg(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); - pr_reg(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); - pr_reg(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); - pr_reg(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); - pr_reg(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); - pr_reg(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); - pr_reg(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); - pr_reg(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); - pr_reg(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); - pr_reg(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); - pr_reg(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); - pr_reg(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); + pr_info("%s: Dump CIR registers:\n", NVT_DRIVER_NAME); + pr_info(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON)); + pr_info(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS)); + pr_info(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN)); + pr_info(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT)); + pr_info(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP)); + pr_info(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC)); + pr_info(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH)); + pr_info(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL)); + pr_info(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON)); + pr_info(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS)); + pr_info(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO)); + pr_info(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT)); + pr_info(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO)); + pr_info(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH)); + pr_info(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL)); + pr_info(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM)); } /* dump current cir wake register contents */ @@ -170,59 +169,59 @@ static void cir_wake_dump_regs(struct nvt_dev *nvt) nvt_efm_enable(nvt); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); - pr_reg("%s: Dump CIR WAKE logical device registers:\n", - NVT_DRIVER_NAME); - pr_reg(" * CR CIR WAKE ACTIVE : 0x%x\n", - nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); - pr_reg(" * CR CIR WAKE BASE ADDR: 0x%x\n", - (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | + pr_info("%s: Dump CIR WAKE logical device registers:\n", + NVT_DRIVER_NAME); + pr_info(" * CR CIR WAKE ACTIVE : 0x%x\n", + nvt_cr_read(nvt, CR_LOGICAL_DEV_EN)); + pr_info(" * CR CIR WAKE BASE ADDR: 0x%x\n", + (nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) | nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO)); - pr_reg(" * CR CIR WAKE IRQ NUM: 0x%x\n", - nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); + pr_info(" * CR CIR WAKE IRQ NUM: 0x%x\n", + nvt_cr_read(nvt, CR_CIR_IRQ_RSRC)); nvt_efm_disable(nvt); - pr_reg("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); - pr_reg(" * IRCON: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); - pr_reg(" * IRSTS: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); - pr_reg(" * IREN: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); - pr_reg(" * FIFO CMP DEEP: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); - pr_reg(" * FIFO CMP TOL: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); - pr_reg(" * FIFO COUNT: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); - pr_reg(" * SLCH: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); - pr_reg(" * SLCL: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); - pr_reg(" * FIFOCON: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); - pr_reg(" * SRXFSTS: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); - pr_reg(" * SAMPLE RX FIFO: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); - pr_reg(" * WR FIFO DATA: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); - pr_reg(" * RD FIFO ONLY: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); - pr_reg(" * RD FIFO ONLY IDX: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); - pr_reg(" * FIFO IGNORE: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); - pr_reg(" * IRFSM: 0x%x\n", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); + pr_info("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME); + pr_info(" * IRCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON)); + pr_info(" * IRSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS)); + pr_info(" * IREN: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN)); + pr_info(" * FIFO CMP DEEP: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP)); + pr_info(" * FIFO CMP TOL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL)); + pr_info(" * FIFO COUNT: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT)); + pr_info(" * SLCH: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH)); + pr_info(" * SLCL: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL)); + pr_info(" * FIFOCON: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON)); + pr_info(" * SRXFSTS: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS)); + pr_info(" * SAMPLE RX FIFO: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO)); + pr_info(" * WR FIFO DATA: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA)); + pr_info(" * RD FIFO ONLY: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + pr_info(" * RD FIFO ONLY IDX: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)); + pr_info(" * FIFO IGNORE: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE)); + pr_info(" * IRFSM: 0x%x\n", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM)); fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT); - pr_reg("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); - pr_reg("* Contents = "); + pr_info("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len); + pr_info("* Contents ="); for (i = 0; i < fifo_len; i++) - printk(KERN_CONT "%02x ", - nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); - printk(KERN_CONT "\n"); + pr_cont(" %02x", + nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY)); + pr_cont("\n"); } /* detect hardware features */ @@ -331,9 +330,6 @@ static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt) /* Enable CIR Wake via PSOUT# (Pin60) */ nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); - /* enable cir interrupt of mouse/keyboard IRQ event */ - nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); - /* enable pme interrupt of cir wakeup event */ nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); @@ -457,7 +453,6 @@ static void nvt_enable_wake(struct nvt_dev *nvt) nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); - nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); @@ -473,6 +468,7 @@ static void nvt_enable_wake(struct nvt_dev *nvt) nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN); } +#if 0 /* Currently unused */ /* rx carrier detect only works in learning mode, must be called w/nvt_lock */ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) { @@ -505,7 +501,7 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) return carrier; } - +#endif /* * set carrier frequency * @@ -518,6 +514,9 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier) struct nvt_dev *nvt = dev->priv; u16 val; + if (carrier == 0) + return -EINVAL; + nvt_cir_reg_write(nvt, 1, CIR_CP); val = 3000000 / (carrier) - 1; nvt_cir_reg_write(nvt, val & 0xff, CIR_CC); @@ -618,7 +617,6 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt) static void nvt_process_rx_ir_data(struct nvt_dev *nvt) { DEFINE_IR_RAW_EVENT(rawir); - u32 carrier; u8 sample; int i; @@ -627,9 +625,6 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) if (debug) nvt_dump_rx_buf(nvt); - if (nvt->carrier_detect_enabled) - carrier = nvt_rx_carrier_detect(nvt); - nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts); init_ir_raw_event(&rawir); @@ -987,25 +982,31 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* input device for IR remote (and tx) */ rdev = rc_allocate_device(); if (!rdev) - goto failure; + goto exit_free_dev_rdev; ret = -ENODEV; + /* activate pnp device */ + if (pnp_activate_dev(pdev) < 0) { + dev_err(&pdev->dev, "Could not activate PNP device!\n"); + goto exit_free_dev_rdev; + } + /* validate pnp resources */ if (!pnp_port_valid(pdev, 0) || pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) { dev_err(&pdev->dev, "IR PNP Port not valid!\n"); - goto failure; + goto exit_free_dev_rdev; } if (!pnp_irq_valid(pdev, 0)) { dev_err(&pdev->dev, "PNP IRQ not valid!\n"); - goto failure; + goto exit_free_dev_rdev; } if (!pnp_port_valid(pdev, 1) || pnp_port_len(pdev, 1) < CIR_IOREG_LENGTH) { dev_err(&pdev->dev, "Wake PNP Port not valid!\n"); - goto failure; + goto exit_free_dev_rdev; } nvt->cir_addr = pnp_port_start(pdev, 0); @@ -1021,24 +1022,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) spin_lock_init(&nvt->nvt_lock); spin_lock_init(&nvt->tx.lock); - ret = -EBUSY; - /* now claim resources */ - if (!request_region(nvt->cir_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - - if (!request_region(nvt->cir_wake_addr, - CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) - goto failure; - - if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, - NVT_DRIVER_NAME, (void *)nvt)) - goto failure; - pnp_set_drvdata(pdev, nvt); nvt->pdev = pdev; @@ -1046,7 +1029,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) ret = nvt_hw_detect(nvt); if (ret) - goto failure; + goto exit_free_dev_rdev; /* Initialize CIR & CIR Wake Logical Devices */ nvt_efm_enable(nvt); @@ -1061,7 +1044,7 @@ 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_protos = RC_TYPE_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->open = nvt_open; rdev->close = nvt_close; rdev->tx_ir = nvt_tx_ir; @@ -1084,13 +1067,32 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* tx bits */ rdev->tx_resolution = XYZ; #endif + nvt->rdev = rdev; ret = rc_register_device(rdev); if (ret) - goto failure; + goto exit_free_dev_rdev; + + ret = -EBUSY; + /* now claim resources */ + if (!request_region(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 (!request_region(nvt->cir_wake_addr, + CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) + goto exit_free_irq; + + if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, + NVT_DRIVER_NAME, (void *)nvt)) + goto exit_release_cir_wake_addr; device_init_wakeup(&pdev->dev, true); - nvt->rdev = rdev; + nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); if (debug) { cir_dump_regs(nvt); @@ -1099,24 +1101,23 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) return 0; -failure: - if (nvt->cir_irq) - free_irq(nvt->cir_irq, nvt); - if (nvt->cir_addr) - release_region(nvt->cir_addr, CIR_IOREG_LENGTH); - - if (nvt->cir_wake_irq) - free_irq(nvt->cir_wake_irq, nvt); - if (nvt->cir_wake_addr) - release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); - +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; } -static void __devexit nvt_remove(struct pnp_dev *pdev) +static void nvt_remove(struct pnp_dev *pdev) { struct nvt_dev *nvt = pnp_get_drvdata(pdev); unsigned long flags; @@ -1214,18 +1215,18 @@ static struct pnp_driver nvt_driver = { .id_table = nvt_ids, .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, .probe = nvt_probe, - .remove = __devexit_p(nvt_remove), + .remove = nvt_remove, .suspend = nvt_suspend, .resume = nvt_resume, .shutdown = nvt_shutdown, }; -int nvt_init(void) +static int nvt_init(void) { return pnp_register_driver(&nvt_driver); } -void nvt_exit(void) +static void nvt_exit(void) { pnp_unregister_driver(&nvt_driver); } |
