diff options
Diffstat (limited to 'drivers/media/rc/ene_ir.c')
| -rw-r--r-- | drivers/media/rc/ene_ir.c | 121 |
1 files changed, 52 insertions, 69 deletions
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index ed184f68c17c..d6c54a3bccc2 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1,23 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * driver for ENE KB3926 B/C/D/E/F CIR (pnp id: ENE0XXX) * * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * * Special thanks to: * Sami R. <maesesami@gmail.com> for lot of help in debugging and therefore * bringing to life support for transmission & learning mode. @@ -27,7 +13,6 @@ * on latest notebooks * * ENE for partial device documentation - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -189,7 +174,7 @@ static int ene_hw_detect(struct ene_device *dev) return 0; } -/* Read properities of hw sample buffer */ +/* Read properties of hw sample buffer */ static void ene_rx_setup_hw_buffer(struct ene_device *dev) { u16 tmp; @@ -331,8 +316,6 @@ static int ene_rx_get_sample_reg(struct ene_device *dev) /* Sense current received carrier */ static void ene_rx_sense_carrier(struct ene_device *dev) { - DEFINE_IR_RAW_EVENT(ev); - int carrier, duty_cycle; int period = ene_read_reg(dev, ENE_CIRCAR_PRD); int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD); @@ -353,9 +336,11 @@ static void ene_rx_sense_carrier(struct ene_device *dev) dbg("RX: sensed carrier = %d Hz, duty cycle %d%%", carrier, duty_cycle); if (dev->carrier_detect_enabled) { - ev.carrier_report = true; - ev.carrier = carrier; - ev.duty_cycle = duty_cycle; + struct ir_raw_event ev = { + .carrier_report = true, + .carrier = carrier, + .duty_cycle = duty_cycle + }; ir_raw_event_store(dev->rdev, &ev); } } @@ -447,28 +432,25 @@ static void ene_rx_setup(struct ene_device *dev) select_timeout: if (dev->rx_fan_input_inuse) { - dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); + dev->rdev->rx_resolution = ENE_FW_SAMPLE_PERIOD_FAN; /* Fan input doesn't support timeouts, it just ends the input with a maximum sample */ dev->rdev->min_timeout = dev->rdev->max_timeout = - US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * - ENE_FW_SAMPLE_PERIOD_FAN); + ENE_FW_SMPL_BUF_FAN_MSK * + ENE_FW_SAMPLE_PERIOD_FAN; } else { - dev->rdev->rx_resolution = US_TO_NS(sample_period); + dev->rdev->rx_resolution = sample_period; /* Theoreticly timeout is unlimited, but we cap it * because it was seen that on one device, it * would stop sending spaces after around 250 msec. * Besides, this is close to 2^32 anyway and timeout is u32. */ - dev->rdev->min_timeout = US_TO_NS(127 * sample_period); - dev->rdev->max_timeout = US_TO_NS(200000); + dev->rdev->min_timeout = 127 * sample_period; + dev->rdev->max_timeout = 200000; } - if (dev->hw_learning_and_tx_capable) - dev->rdev->tx_resolution = US_TO_NS(sample_period); - if (dev->rdev->timeout > dev->rdev->max_timeout) dev->rdev->timeout = dev->rdev->max_timeout; if (dev->rdev->timeout < dev->rdev->min_timeout) @@ -476,7 +458,7 @@ select_timeout: } /* Enable the device for receive */ -static void ene_rx_enable(struct ene_device *dev) +static void ene_rx_enable_hw(struct ene_device *dev) { u8 reg_value; @@ -504,11 +486,17 @@ static void ene_rx_enable(struct ene_device *dev) /* enter idle mode */ ir_raw_event_set_idle(dev->rdev, true); +} + +/* Enable the device for receive - wrapper to track the state*/ +static void ene_rx_enable(struct ene_device *dev) +{ + ene_rx_enable_hw(dev); dev->rx_enabled = true; } /* Disable the device receiver */ -static void ene_rx_disable(struct ene_device *dev) +static void ene_rx_disable_hw(struct ene_device *dev) { /* disable inputs */ ene_rx_enable_cir_engine(dev, false); @@ -516,8 +504,13 @@ static void ene_rx_disable(struct ene_device *dev) /* disable hardware IRQ and firmware flag */ ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); - ir_raw_event_set_idle(dev->rdev, true); +} + +/* Disable the device receiver - wrapper to track the state */ +static void ene_rx_disable(struct ene_device *dev) +{ + ene_rx_disable_hw(dev); dev->rx_enabled = false; } @@ -664,9 +657,9 @@ exit: } /* timer to simulate tx done interrupt */ -static void ene_tx_irqsim(unsigned long data) +static void ene_tx_irqsim(struct timer_list *t) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = timer_container_of(dev, t, tx_sim_timer); unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -727,7 +720,7 @@ static irqreturn_t ene_isr(int irq, void *data) unsigned long flags; irqreturn_t retval = IRQ_NONE; struct ene_device *dev = (struct ene_device *)data; - DEFINE_IR_RAW_EVENT(ev); + struct ir_raw_event ev = {}; spin_lock_irqsave(&dev->hw_lock, flags); @@ -802,7 +795,7 @@ static irqreturn_t ene_isr(int irq, void *data) dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); - ev.duration = US_TO_NS(hw_sample); + ev.duration = hw_sample; ev.pulse = pulse; ir_raw_event_store_with_filter(dev->rdev, &ev); } @@ -822,7 +815,7 @@ static void ene_setup_default_settings(struct ene_device *dev) dev->learning_mode_enabled = learning_mode_force; /* Set reasonable default timeout */ - dev->rdev->timeout = US_TO_NS(150000); + dev->rdev->timeout = MS_TO_US(150); } /* Upload all hardware settings at once. Used at load and resume time */ @@ -893,7 +886,7 @@ static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier) dbg("TX: out of range %d-%d kHz carrier", 2000 / ENE_CIRMOD_PRD_MIN, 2000 / ENE_CIRMOD_PRD_MAX); - return -1; + return -EINVAL; } dev->tx_period = period; @@ -968,7 +961,7 @@ static int ene_transmit(struct rc_dev *rdev, unsigned *buf, unsigned n) dev->tx_reg = 0; dev->tx_done = 0; dev->tx_sample = 0; - dev->tx_sample_pulse = 0; + dev->tx_sample_pulse = false; dbg("TX: %d samples", dev->tx_len); @@ -1001,7 +994,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; @@ -1022,6 +1015,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) spin_lock_init(&dev->hw_lock); dev->hw_io = pnp_port_start(pnp_dev, 0); + dev->irq = pnp_irq(pnp_dev, 0); + pnp_set_drvdata(pnp_dev, dev); dev->pnp_dev = pnp_dev; @@ -1037,33 +1032,31 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!dev->hw_learning_and_tx_capable && txsim) { dev->hw_learning_and_tx_capable = true; - setup_timer(&dev->tx_sim_timer, ene_tx_irqsim, - (long unsigned int)dev); + timer_setup(&dev->tx_sim_timer, ene_tx_irqsim, 0); pr_warn("Simulation of TX activated\n"); } if (!dev->hw_learning_and_tx_capable) learning_mode_force = false; - rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->priv = dev; rdev->open = ene_open; rdev->close = ene_close; rdev->s_idle = ene_set_idle; rdev->driver_name = ENE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->input_name = "ENE eHome Infrared Remote Receiver"; + rdev->device_name = "ENE eHome Infrared Remote Receiver"; if (dev->hw_learning_and_tx_capable) { - rdev->s_learning_mode = ene_set_learning_mode; + rdev->s_wideband_receiver = ene_set_learning_mode; init_completion(&dev->tx_complete); rdev->tx_ir = ene_transmit; rdev->s_tx_mask = ene_set_tx_mask; rdev->s_tx_carrier = ene_set_tx_carrier; rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle; rdev->s_carrier_report = ene_set_carrier_report; - rdev->input_name = "ENE eHome Infrared Remote Transceiver"; + rdev->device_name = "ENE eHome Infrared Remote Transceiver"; } dev->rdev = rdev; @@ -1085,7 +1078,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) goto exit_unregister_device; } - dev->irq = pnp_irq(pnp_dev, 0); if (request_irq(dev->irq, ene_isr, IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) { goto exit_release_hw_io; @@ -1111,6 +1103,8 @@ static void ene_remove(struct pnp_dev *pnp_dev) struct ene_device *dev = pnp_get_drvdata(pnp_dev); unsigned long flags; + rc_unregister_device(dev->rdev); + timer_delete_sync(&dev->tx_sim_timer); spin_lock_irqsave(&dev->hw_lock, flags); ene_rx_disable(dev); ene_rx_restore_hw_buffer(dev); @@ -1118,14 +1112,12 @@ static void ene_remove(struct pnp_dev *pnp_dev) free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); - rc_unregister_device(dev->rdev); kfree(dev); } /* enable wake on IR (wakes on specific button on original remote) */ -static void ene_enable_wake(struct ene_device *dev, int enable) +static void ene_enable_wake(struct ene_device *dev, bool enable) { - enable = enable && device_may_wakeup(&dev->pnp_dev->dev); dbg("wake on IR %s", enable ? "enabled" : "disabled"); ene_set_clear_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, enable); } @@ -1134,9 +1126,12 @@ static void ene_enable_wake(struct ene_device *dev, int enable) static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state) { struct ene_device *dev = pnp_get_drvdata(pnp_dev); - ene_enable_wake(dev, true); + bool wake = device_may_wakeup(&dev->pnp_dev->dev); + + if (!wake && dev->rx_enabled) + ene_rx_disable_hw(dev); - /* TODO: add support for wake pattern */ + ene_enable_wake(dev, wake); return 0; } @@ -1181,16 +1176,6 @@ static struct pnp_driver ene_driver = { .shutdown = ene_shutdown, }; -static int __init ene_init(void) -{ - return pnp_register_driver(&ene_driver); -} - -static void ene_exit(void) -{ - pnp_unregister_driver(&ene_driver); -} - module_param(sample_period, int, S_IRUGO); MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)"); @@ -1206,11 +1191,9 @@ MODULE_PARM_DESC(txsim, MODULE_DEVICE_TABLE(pnp, ene_ids); MODULE_DESCRIPTION - ("Infrared input driver for KB3926B/C/D/E/F " - "(aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); + ("Infrared input driver for KB3926B/C/D/E/F (aka ENE0100/ENE0200/ENE0201/ENE0202) CIR port"); MODULE_AUTHOR("Maxim Levitsky"); MODULE_LICENSE("GPL"); -module_init(ene_init); -module_exit(ene_exit); +module_pnp_driver(ene_driver); |
