Calculate lirc features when necessary, and add LIRC_{S,G}ET_REC_MODE cases to ir_lirc_ioctl.
This makes lirc_dev_fop_ioctl() unnecessary since all cases are already handled by ir_lirc_ioctl(). Signed-off-by: Sean Young <s...@mess.org> --- drivers/media/rc/ir-lirc-codec.c | 79 ++++++++++++++++++++++++---------------- drivers/media/rc/lirc_dev.c | 62 ++----------------------------- include/media/lirc_dev.h | 4 -- 3 files changed, 50 insertions(+), 95 deletions(-) diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 1ed69c9e64bf..f933e7617882 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -231,8 +231,54 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, } switch (cmd) { + case LIRC_GET_FEATURES: + if (dev->driver_type == RC_DRIVER_IR_RAW) { + val |= LIRC_CAN_REC_MODE2; + if (dev->rx_resolution) + val |= LIRC_CAN_GET_REC_RESOLUTION; + } + + if (dev->tx_ir) { + val |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE; + if (dev->s_tx_mask) + val |= LIRC_CAN_SET_TRANSMITTER_MASK; + if (dev->s_tx_carrier) + val |= LIRC_CAN_SET_SEND_CARRIER; + if (dev->s_tx_duty_cycle) + val |= LIRC_CAN_SET_SEND_DUTY_CYCLE; + } + + if (dev->s_rx_carrier_range) + val |= LIRC_CAN_SET_REC_CARRIER | + LIRC_CAN_SET_REC_CARRIER_RANGE; + + if (dev->s_learning_mode) + val |= LIRC_CAN_USE_WIDEBAND_RECEIVER; + + if (dev->s_carrier_report) + val |= LIRC_CAN_MEASURE_CARRIER; + + if (dev->max_timeout) + val |= LIRC_CAN_SET_REC_TIMEOUT; + + break; /* mode support */ + case LIRC_GET_REC_MODE: + if (dev->driver_type == RC_DRIVER_IR_RAW_TX) + return -ENOTTY; + + val = LIRC_MODE_MODE2; + break; + + case LIRC_SET_REC_MODE: + if (dev->driver_type == RC_DRIVER_IR_RAW_TX) + return -ENOTTY; + + if (val != LIRC_MODE_MODE2) + return -EINVAL; + return 0; + case LIRC_GET_SEND_MODE: if (!dev->tx_ir) return -ENOTTY; @@ -353,7 +399,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, break; default: - return lirc_dev_fop_ioctl(filep, cmd, arg); + return -ENOTTY; } if (_IOC_DIR(cmd) & _IOC_READ) @@ -380,44 +426,13 @@ int ir_lirc_register(struct rc_dev *dev) { struct lirc_dev *ldev; int rc = -ENOMEM; - unsigned long features = 0; ldev = lirc_allocate_device(); if (!ldev) return rc; - if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { - features |= LIRC_CAN_REC_MODE2; - if (dev->rx_resolution) - features |= LIRC_CAN_GET_REC_RESOLUTION; - } - - if (dev->tx_ir) { - features |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE; - if (dev->s_tx_mask) - features |= LIRC_CAN_SET_TRANSMITTER_MASK; - if (dev->s_tx_carrier) - features |= LIRC_CAN_SET_SEND_CARRIER; - if (dev->s_tx_duty_cycle) - features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; - } - - if (dev->s_rx_carrier_range) - features |= LIRC_CAN_SET_REC_CARRIER | - LIRC_CAN_SET_REC_CARRIER_RANGE; - - if (dev->s_learning_mode) - features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; - - if (dev->s_carrier_report) - features |= LIRC_CAN_MEASURE_CARRIER; - - if (dev->max_timeout) - features |= LIRC_CAN_SET_REC_TIMEOUT; - snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)", dev->driver_name); - ldev->features = features; ldev->buf = NULL; ldev->chunk_size = sizeof(int); ldev->buffer_size = LIRCBUF_SIZE; diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 3cc95deaa84e..95058ea01e62 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -109,6 +109,7 @@ EXPORT_SYMBOL(lirc_free_device); int lirc_register_device(struct lirc_dev *d) { + struct rc_dev *rcdev = d->rdev; int minor; int err; @@ -146,7 +147,7 @@ int lirc_register_device(struct lirc_dev *d) /* some safety check 8-) */ d->name[sizeof(d->name) - 1] = '\0'; - if (LIRC_CAN_REC(d->features)) { + if (rcdev->driver_type == RC_DRIVER_IR_RAW) { err = lirc_allocate_buffer(d); if (err) return err; @@ -290,63 +291,6 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) } EXPORT_SYMBOL(lirc_dev_fop_poll); -long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct rc_dev *rcdev = file->private_data; - struct lirc_dev *d = rcdev->lirc_dev; - __u32 mode; - int result; - - dev_dbg(&d->dev, LOGHEAD "ioctl called (0x%x)\n", - d->name, d->minor, cmd); - - result = mutex_lock_interruptible(&d->mutex); - if (result) - return result; - - if (!d->attached) { - result = -ENODEV; - goto out; - } - - switch (cmd) { - case LIRC_GET_FEATURES: - result = put_user(d->features, (__u32 __user *)arg); - break; - case LIRC_GET_REC_MODE: - if (!LIRC_CAN_REC(d->features)) { - result = -ENOTTY; - break; - } - - result = put_user(LIRC_REC2MODE - (d->features & LIRC_CAN_REC_MASK), - (__u32 __user *)arg); - break; - case LIRC_SET_REC_MODE: - if (!LIRC_CAN_REC(d->features)) { - result = -ENOTTY; - break; - } - - result = get_user(mode, (__u32 __user *)arg); - if (!result && !(LIRC_MODE2REC(mode) & d->features)) - result = -EINVAL; - /* - * FIXME: We should actually set the mode somehow but - * for now, lirc_serial doesn't support mode changing either - */ - break; - default: - result = -ENOTTY; - } - -out: - mutex_unlock(&d->mutex); - return result; -} -EXPORT_SYMBOL(lirc_dev_fop_ioctl); - ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length, @@ -375,7 +319,7 @@ ssize_t lirc_dev_fop_read(struct file *file, goto out_locked; } - if (!LIRC_CAN_REC(d->features)) { + if (rcdev->driver_type != RC_DRIVER_IR_RAW) { ret = -EINVAL; goto out_locked; } diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index dd0c078796e8..86a3cf798775 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h @@ -115,8 +115,6 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, * * @name: used for logging * @minor: the minor device (/dev/lircX) number for the device - * @features: lirc compatible hardware features, like LIRC_MODE_RAW, - * LIRC_CAN\_\*, as defined at include/media/lirc.h. * @buffer_size: Number of FIFO buffers with @chunk_size size. * Only used if @rbuf is NULL. * @chunk_size: Size of each FIFO buffer. @@ -138,7 +136,6 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, struct lirc_dev { char name[40]; unsigned int minor; - __u32 features; unsigned int buffer_size; /* in chunks holding one code each */ unsigned int chunk_size; @@ -172,7 +169,6 @@ void lirc_unregister_device(struct lirc_dev *d); int lirc_dev_fop_open(struct inode *inode, struct file *file); int lirc_dev_fop_close(struct inode *inode, struct file *file); unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait); -long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length, loff_t *ppos); #endif -- 2.13.6