Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");