summaryrefslogtreecommitdiff
path: root/drivers/media/rc/ene_ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/rc/ene_ir.c')
-rw-r--r--drivers/media/rc/ene_ir.c121
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);