^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * LIRC base driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * by Artur Lipowski <alipowski@interia.pl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "rc-core-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <uapi/linux/lirc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define LIRCBUF_SIZE 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static dev_t lirc_base_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Used to keep track of allocated lirc devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static DEFINE_IDA(lirc_ida);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Only used for sysfs but defined to void otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct class *lirc_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @dev: the struct rc_dev descriptor of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @ev: the struct ir_raw_event descriptor of the pulse/space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct lirc_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Packet start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (ev.reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Userspace expects a long space event before the start of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * the signal to use as a sync. This may be done with repeat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * packets and normal samples. But if a reset has been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * then we assume that a long time has passed, so we send a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * space with the maximum time value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) sample = LIRC_SPACE(LIRC_VALUE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) dev_dbg(&dev->dev, "delivering reset sync space to lirc_dev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Carrier reports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) } else if (ev.carrier_report) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sample = LIRC_FREQUENCY(ev.carrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dev_dbg(&dev->dev, "carrier report (freq: %d)\n", sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Packet end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else if (ev.timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (dev->gap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) dev->gap_start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev->gap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dev->gap_duration = ev.duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) sample = LIRC_TIMEOUT(ev.duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* Normal sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (dev->gap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) dev->gap_duration += ktime_to_us(ktime_sub(ktime_get(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) dev->gap_start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Cap by LIRC_VALUE_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) dev->gap_duration = min_t(u64, dev->gap_duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) LIRC_VALUE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) list_for_each_entry(fh, &dev->lirc_fh, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) kfifo_put(&fh->rawir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) LIRC_SPACE(dev->gap_duration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dev->gap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) sample = ev.pulse ? LIRC_PULSE(ev.duration) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) LIRC_SPACE(ev.duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ev.duration, TO_STR(ev.pulse));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * bpf does not care about the gap generated above; that exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * for backwards compatibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) lirc_bpf_run(dev, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) list_for_each_entry(fh, &dev->lirc_fh, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (LIRC_IS_TIMEOUT(sample) && !fh->send_timeout_reports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (kfifo_put(&fh->rawir, sample))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * lirc_scancode_event() - Send scancode data to lirc to be relayed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * userspace. This can be called in atomic context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @dev: the struct rc_dev descriptor of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @lsc: the struct lirc_scancode describing the decoded scancode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) void lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct lirc_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) lsc->timestamp = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) list_for_each_entry(fh, &dev->lirc_fh, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (kfifo_put(&fh->scancodes, *lsc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXPORT_SYMBOL_GPL(lirc_scancode_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int lirc_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) lirc_cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (!fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) get_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!dev->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto out_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (dev->driver_type == RC_DRIVER_IR_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (kfifo_alloc(&fh->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto out_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (kfifo_alloc(&fh->scancodes, 32, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto out_rawir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) fh->send_mode = LIRC_MODE_PULSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) fh->rc = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) fh->send_timeout_reports = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (dev->driver_type == RC_DRIVER_SCANCODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fh->rec_mode = LIRC_MODE_SCANCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) fh->rec_mode = LIRC_MODE_MODE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) retval = rc_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto out_kfifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) init_waitqueue_head(&fh->wait_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) file->private_data = fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) list_add(&fh->list, &dev->lirc_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) stream_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) out_kfifo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) kfifo_free(&fh->scancodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) out_rawir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (dev->driver_type == RC_DRIVER_IR_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) kfifo_free(&fh->rawir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) out_fh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) kfree(fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) put_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int lirc_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct rc_dev *dev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) list_del(&fh->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (dev->driver_type == RC_DRIVER_IR_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) kfifo_free(&fh->rawir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) kfifo_free(&fh->scancodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) kfree(fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) rc_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) put_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static ssize_t lirc_transmit(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) size_t n, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct rc_dev *dev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned int *txbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct ir_raw_event *raw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) size_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ktime_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) s64 towait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned int duration = 0; /* signal duration in us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = mutex_lock_interruptible(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!dev->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!dev->tx_ir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (fh->send_mode == LIRC_MODE_SCANCODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct lirc_scancode scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (n != sizeof(scan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (copy_from_user(&scan, buf, sizeof(scan))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (scan.flags || scan.keycode || scan.timestamp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* We only have encoders for 32-bit protocols. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (scan.scancode > U32_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (!raw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) raw, LIRCBUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto out_kfree_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (!txbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) goto out_kfree_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) for (i = 0; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) txbuf[i] = raw[i].duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (dev->s_tx_carrier) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int carrier = ir_raw_encode_carrier(scan.rc_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (carrier > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev->s_tx_carrier(dev, carrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) count = n / sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (count > LIRCBUF_SIZE || count % 2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) txbuf = memdup_user(buf, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (IS_ERR(txbuf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = PTR_ERR(txbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (txbuf[i] > IR_MAX_DURATION - duration || !txbuf[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) duration += txbuf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = dev->tx_ir(dev, txbuf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) kfree(txbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) kfree(raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * The lircd gap calculation expects the write function to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * wait for the actual IR signal to be transmitted before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) towait = ktime_us_delta(ktime_add_us(start, duration),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ktime_get());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (towait > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) schedule_timeout(usecs_to_jiffies(towait));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) out_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) kfree(txbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) out_kfree_raw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) kfree(raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct rc_dev *dev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) u32 __user *argp = (u32 __user *)(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (_IOC_DIR(cmd) & _IOC_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = get_user(val, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = mutex_lock_interruptible(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!dev->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) case LIRC_GET_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (dev->driver_type == RC_DRIVER_SCANCODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) val |= LIRC_CAN_REC_SCANCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (dev->driver_type == RC_DRIVER_IR_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) val |= LIRC_CAN_REC_MODE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (dev->rx_resolution)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) val |= LIRC_CAN_GET_REC_RESOLUTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (dev->tx_ir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) val |= LIRC_CAN_SEND_PULSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (dev->s_tx_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) val |= LIRC_CAN_SET_TRANSMITTER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (dev->s_tx_carrier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) val |= LIRC_CAN_SET_SEND_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (dev->s_tx_duty_cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (dev->s_rx_carrier_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) val |= LIRC_CAN_SET_REC_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) LIRC_CAN_SET_REC_CARRIER_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (dev->s_learning_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (dev->s_carrier_report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) val |= LIRC_CAN_MEASURE_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (dev->max_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) val |= LIRC_CAN_SET_REC_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* mode support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case LIRC_GET_REC_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) val = fh->rec_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case LIRC_SET_REC_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) switch (dev->driver_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) case RC_DRIVER_IR_RAW_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case RC_DRIVER_SCANCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (val != LIRC_MODE_SCANCODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case RC_DRIVER_IR_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (!(val == LIRC_MODE_MODE2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) val == LIRC_MODE_SCANCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) fh->rec_mode = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case LIRC_GET_SEND_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!dev->tx_ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) val = fh->send_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case LIRC_SET_SEND_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!dev->tx_ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) fh->send_mode = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* TX settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case LIRC_SET_TRANSMITTER_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!dev->s_tx_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = dev->s_tx_mask(dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case LIRC_SET_SEND_CARRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!dev->s_tx_carrier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = dev->s_tx_carrier(dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case LIRC_SET_SEND_DUTY_CYCLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!dev->s_tx_duty_cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) else if (val <= 0 || val >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = dev->s_tx_duty_cycle(dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* RX settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) case LIRC_SET_REC_CARRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!dev->s_rx_carrier_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) else if (val <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = dev->s_rx_carrier_range(dev, fh->carrier_low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case LIRC_SET_REC_CARRIER_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!dev->s_rx_carrier_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) else if (val <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) fh->carrier_low = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case LIRC_GET_REC_RESOLUTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!dev->rx_resolution)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) val = dev->rx_resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) case LIRC_SET_WIDEBAND_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!dev->s_learning_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ret = dev->s_learning_mode(dev, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case LIRC_SET_MEASURE_CARRIER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!dev->s_carrier_report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ret = dev->s_carrier_report(dev, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Generic timeout support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case LIRC_GET_MIN_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (!dev->max_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) val = dev->min_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case LIRC_GET_MAX_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!dev->max_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) val = dev->max_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case LIRC_SET_REC_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!dev->max_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (val < dev->min_timeout || val > dev->max_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) else if (dev->s_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = dev->s_timeout(dev, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) dev->timeout = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case LIRC_GET_REC_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!dev->timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) val = dev->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) case LIRC_SET_REC_TIMEOUT_REPORTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (dev->driver_type != RC_DRIVER_IR_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) fh->send_timeout_reports = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!ret && _IOC_DIR(cmd) & _IOC_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ret = put_user(val, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static __poll_t lirc_poll(struct file *file, struct poll_table_struct *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct rc_dev *rcdev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) __poll_t events = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) poll_wait(file, &fh->wait_poll, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (!rcdev->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) events = EPOLLHUP | EPOLLERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) } else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (fh->rec_mode == LIRC_MODE_SCANCODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) !kfifo_is_empty(&fh->scancodes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) events = EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (fh->rec_mode == LIRC_MODE_MODE2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) !kfifo_is_empty(&fh->rawir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) events = EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static ssize_t lirc_read_mode2(struct file *file, char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) size_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct rc_dev *rcdev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) unsigned int copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (kfifo_is_empty(&fh->rawir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (file->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = wait_event_interruptible(fh->wait_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) !kfifo_is_empty(&fh->rawir) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) !rcdev->registered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (!rcdev->registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ret = mutex_lock_interruptible(&rcdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) mutex_unlock(&rcdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) } while (copied == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static ssize_t lirc_read_scancode(struct file *file, char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) size_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct rc_dev *rcdev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) unsigned int copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (length < sizeof(struct lirc_scancode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) length % sizeof(struct lirc_scancode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (kfifo_is_empty(&fh->scancodes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (file->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ret = wait_event_interruptible(fh->wait_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) !kfifo_is_empty(&fh->scancodes) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) !rcdev->registered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (!rcdev->registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ret = mutex_lock_interruptible(&rcdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) mutex_unlock(&rcdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) } while (copied == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static ssize_t lirc_read(struct file *file, char __user *buffer, size_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct lirc_fh *fh = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct rc_dev *rcdev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!rcdev->registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (fh->rec_mode == LIRC_MODE_MODE2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return lirc_read_mode2(file, buffer, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) else /* LIRC_MODE_SCANCODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return lirc_read_scancode(file, buffer, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static const struct file_operations lirc_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) .write = lirc_transmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) .unlocked_ioctl = lirc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) .compat_ioctl = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) .read = lirc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .poll = lirc_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .open = lirc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .release = lirc_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static void lirc_release_device(struct device *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) put_device(&rcdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int lirc_register(struct rc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) const char *rx_type, *tx_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int err, minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (minor < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) device_initialize(&dev->lirc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) dev->lirc_dev.class = lirc_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dev->lirc_dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dev->lirc_dev.release = lirc_release_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dev_set_name(&dev->lirc_dev, "lirc%d", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) INIT_LIST_HEAD(&dev->lirc_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_lock_init(&dev->lirc_fh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) cdev_init(&dev->lirc_cdev, &lirc_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto out_ida;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) get_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) switch (dev->driver_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) case RC_DRIVER_SCANCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) rx_type = "scancode";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case RC_DRIVER_IR_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) rx_type = "raw IR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) rx_type = "no";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (dev->tx_ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) tx_type = "raw IR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) tx_type = "no";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d, %s receiver, %s transmitter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) dev->driver_name, minor, rx_type, tx_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) out_ida:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ida_simple_remove(&lirc_ida, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) void lirc_unregister(struct rc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct lirc_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) dev->driver_name, MINOR(dev->lirc_dev.devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) spin_lock_irqsave(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) list_for_each_entry(fh, &dev->lirc_fh, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) wake_up_poll(&fh->wait_poll, EPOLLHUP | EPOLLERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int __init lirc_dev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) lirc_class = class_create(THIS_MODULE, "lirc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (IS_ERR(lirc_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pr_err("class_create failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return PTR_ERR(lirc_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX, "lirc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) class_destroy(lirc_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) pr_err("alloc_chrdev_region failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pr_debug("IR Remote Control driver registered, major %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) MAJOR(lirc_base_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) void __exit lirc_dev_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) class_destroy(lirc_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct rc_dev *rc_dev_get_from_fd(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct fd f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct lirc_fh *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct rc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ERR_PTR(-EBADF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (f.file->f_op != &lirc_fops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) fh = f.file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dev = fh->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) get_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) MODULE_ALIAS("lirc_dev");