diff options
Diffstat (limited to 'drivers/media/rc')
-rw-r--r-- | drivers/media/rc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/media/rc/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/rc/gpio-ir-recv.c | 2 | ||||
-rw-r--r-- | drivers/media/rc/igorplugusb.c | 2 | ||||
-rw-r--r-- | drivers/media/rc/imon.c | 5 | ||||
-rw-r--r-- | drivers/media/rc/ir-lirc-codec.c | 34 | ||||
-rw-r--r-- | drivers/media/rc/ir-mce_kbd-decoder.c | 49 | ||||
-rw-r--r-- | drivers/media/rc/keymaps/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/rc/keymaps/rc-dvico-mce.c | 92 | ||||
-rw-r--r-- | drivers/media/rc/keymaps/rc-dvico-portable.c | 74 | ||||
-rw-r--r-- | drivers/media/rc/keymaps/rc-lirc.c | 42 | ||||
-rw-r--r-- | drivers/media/rc/lirc_dev.c | 122 | ||||
-rw-r--r-- | drivers/media/rc/mceusb.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/rc-core-priv.h | 2 | ||||
-rw-r--r-- | drivers/media/rc/rc-ir-raw.c | 6 | ||||
-rw-r--r-- | drivers/media/rc/rc-main.c | 8 | ||||
-rw-r--r-- | drivers/media/rc/serial_ir.c | 4 | ||||
-rw-r--r-- | drivers/media/rc/sir_ir.c | 438 | ||||
-rw-r--r-- | drivers/media/rc/st_rc.c | 15 | ||||
-rw-r--r-- | drivers/media/rc/sunxi-cir.c | 21 | ||||
-rw-r--r-- | drivers/media/rc/winbond-cir.c | 4 |
21 files changed, 688 insertions, 247 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d1d3fd00ed89..e422f3d56f76 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -426,4 +426,13 @@ config IR_SERIAL_TRANSMITTER ---help--- Serial Port Transmitter support +config IR_SIR + tristate "Built-in SIR IrDA port" + depends on RC_CORE + ---help--- + Say Y if you want to use a IrDA SIR port Transceivers. + + To compile this driver as a module, choose M here: the module will + be called sir-ir. + endif #RC_DEVICES diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 679aa0af85cd..245e2c2d0b22 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -39,4 +39,5 @@ obj-$(CONFIG_RC_ST) += st_rc.o obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o obj-$(CONFIG_IR_IMG) += img-ir/ obj-$(CONFIG_IR_SERIAL) += serial_ir.o +obj-$(CONFIG_IR_SIR) += sir_ir.o obj-$(CONFIG_IR_MTK) += mtk-cir.o diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 4a4895e4d599..b4f773b9dc1d 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -158,7 +158,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->input_id.version = 0x0100; rcdev->dev.parent = &pdev->dev; rcdev->driver_name = GPIO_IR_DRIVER_NAME; - rcdev->min_timeout = 0; + rcdev->min_timeout = 1; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; if (pdata->allowed_protos) diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index 0f0ed4ea4d06..cb6d4f1247da 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -205,7 +205,7 @@ static int igorplugusb_probe(struct usb_interface *intf, rc->allowed_protocols = RC_BIT_ALL_IR_DECODER & ~(RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | - RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO); + RC_BIT_SONY20 | RC_BIT_SANYO); rc->priv = ir; rc->driver_name = DRIVER_NAME; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 89823d24a384..3489010601b5 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -2412,9 +2412,8 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, mutex_lock(&ictx->lock); if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { - init_timer(&ictx->ttimer); - ictx->ttimer.data = (unsigned long)ictx; - ictx->ttimer.function = imon_touch_display_timeout; + setup_timer(&ictx->ttimer, imon_touch_display_timeout, + (unsigned long)ictx); } ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 8517d5153fcf..de85f1d7ce43 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -139,7 +139,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, } if (!dev->tx_ir) { - ret = -ENOSYS; + ret = -EINVAL; goto out; } @@ -221,19 +221,19 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, /* TX settings */ case LIRC_SET_TRANSMITTER_MASK: if (!dev->s_tx_mask) - return -ENOSYS; + return -ENOTTY; return dev->s_tx_mask(dev, val); case LIRC_SET_SEND_CARRIER: if (!dev->s_tx_carrier) - return -ENOSYS; + return -ENOTTY; return dev->s_tx_carrier(dev, val); case LIRC_SET_SEND_DUTY_CYCLE: if (!dev->s_tx_duty_cycle) - return -ENOSYS; + return -ENOTTY; if (val <= 0 || val >= 100) return -EINVAL; @@ -243,7 +243,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, /* RX settings */ case LIRC_SET_REC_CARRIER: if (!dev->s_rx_carrier_range) - return -ENOSYS; + return -ENOTTY; if (val <= 0) return -EINVAL; @@ -253,6 +253,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, val); case LIRC_SET_REC_CARRIER_RANGE: + if (!dev->s_rx_carrier_range) + return -ENOTTY; + if (val <= 0) return -EINVAL; @@ -260,37 +263,40 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, return 0; case LIRC_GET_REC_RESOLUTION: + if (!dev->rx_resolution) + return -ENOTTY; + val = dev->rx_resolution; break; case LIRC_SET_WIDEBAND_RECEIVER: if (!dev->s_learning_mode) - return -ENOSYS; + return -ENOTTY; return dev->s_learning_mode(dev, !!val); case LIRC_SET_MEASURE_CARRIER_MODE: if (!dev->s_carrier_report) - return -ENOSYS; + return -ENOTTY; return dev->s_carrier_report(dev, !!val); /* Generic timeout support */ case LIRC_GET_MIN_TIMEOUT: if (!dev->max_timeout) - return -ENOSYS; + return -ENOTTY; val = DIV_ROUND_UP(dev->min_timeout, 1000); break; case LIRC_GET_MAX_TIMEOUT: if (!dev->max_timeout) - return -ENOSYS; + return -ENOTTY; val = dev->max_timeout / 1000; break; case LIRC_SET_REC_TIMEOUT: if (!dev->max_timeout) - return -ENOSYS; + return -ENOTTY; tmp = val * 1000; @@ -305,6 +311,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, break; case LIRC_SET_REC_TIMEOUT_REPORTS: + if (!dev->timeout) + return -ENOTTY; + lirc->send_timeout_reports = !!val; break; @@ -361,8 +370,11 @@ static int ir_lirc_register(struct rc_dev *dev) if (rc) goto rbuf_init_failed; - if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + 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; if (dev->s_tx_mask) diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 5226d510e847..6a4d58b88d91 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -23,7 +23,7 @@ * - MCIR-2 29-bit IR signals used for mouse movement and buttons * - MCIR-2 32-bit IR signals used for standard keyboard keys * - * The media keys on the keyboard send RC-6 signals that are inditinguishable + * The media keys on the keyboard send RC-6 signals that are indistinguishable * from the keys of the same name on the stock MCE remote, and will be handled * by the standard RC-6 decoder, and be made available to the system via the * input device for the remote, rather than the keyboard/mouse one. @@ -339,6 +339,7 @@ again: } data->state = STATE_INACTIVE; + input_event(data->idev, EV_MSC, MSC_SCAN, scancode); input_sync(data->idev); return 0; } @@ -418,9 +419,53 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev) return 0; } +static const struct ir_raw_timings_manchester ir_mce_kbd_timings = { + .leader = MCIR2_PREFIX_PULSE, + .invert = 1, + .clock = MCIR2_UNIT, + .trailer_space = MCIR2_UNIT * 10, +}; + +/** + * ir_mce_kbd_encode() - Encode a scancode as a stream of raw events + * + * @protocol: protocol to encode + * @scancode: scancode to encode + * @events: array of raw ir events to write into + * @max: maximum size of @events + * + * Returns: The number of events written. + * -ENOBUFS if there isn't enough space in the array to fit the + * encoding. In this case all @max events will have been written. + */ +static int ir_mce_kbd_encode(enum rc_type protocol, u32 scancode, + struct ir_raw_event *events, unsigned int max) +{ + struct ir_raw_event *e = events; + int len, ret; + u64 raw; + + if (protocol == RC_TYPE_MCIR2_KBD) { + raw = scancode | + ((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS); + len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1; + } else { + raw = scancode | + ((u64)MCIR2_MOUSE_HEADER << MCIR2_MOUSE_NBITS); + len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS + 1; + } + + ret = ir_raw_gen_manchester(&e, max, &ir_mce_kbd_timings, len, raw); + if (ret < 0) + return ret; + + return e - events; +} + static struct ir_raw_handler mce_kbd_handler = { - .protocols = RC_BIT_MCE_KBD, + .protocols = RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE, .decode = ir_mce_kbd_decode, + .encode = ir_mce_kbd_encode, .raw_register = ir_mce_kbd_register, .raw_unregister = ir_mce_kbd_unregister, }; diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index ffe9e612f8d6..2945f99907b5 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -57,7 +57,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-kworld-pc150u.o \ rc-kworld-plus-tv-analog.o \ rc-leadtek-y04g0051.o \ - rc-lirc.o \ rc-lme2510.o \ rc-manli.o \ rc-medion-x10.o \ diff --git a/drivers/media/rc/keymaps/rc-dvico-mce.c b/drivers/media/rc/keymaps/rc-dvico-mce.c index e5f098c50235..d1e861f4d095 100644 --- a/drivers/media/rc/keymaps/rc-dvico-mce.c +++ b/drivers/media/rc/keymaps/rc-dvico-mce.c @@ -12,58 +12,58 @@ #include <linux/module.h> static struct rc_map_table rc_map_dvico_mce_table[] = { - { 0xfe02, KEY_TV }, - { 0xfe0e, KEY_MP3 }, - { 0xfe1a, KEY_DVD }, - { 0xfe1e, KEY_FAVORITES }, - { 0xfe16, KEY_SETUP }, - { 0xfe46, KEY_POWER2 }, - { 0xfe0a, KEY_EPG }, - { 0xfe49, KEY_BACK }, - { 0xfe4d, KEY_MENU }, - { 0xfe51, KEY_UP }, - { 0xfe5b, KEY_LEFT }, - { 0xfe5f, KEY_RIGHT }, - { 0xfe53, KEY_DOWN }, - { 0xfe5e, KEY_OK }, - { 0xfe59, KEY_INFO }, - { 0xfe55, KEY_TAB }, - { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */ - { 0xfe12, KEY_NEXTSONG }, /* Skip */ - { 0xfe42, KEY_ENTER }, /* Windows/Start */ - { 0xfe15, KEY_VOLUMEUP }, - { 0xfe05, KEY_VOLUMEDOWN }, - { 0xfe11, KEY_CHANNELUP }, - { 0xfe09, KEY_CHANNELDOWN }, - { 0xfe52, KEY_CAMERA }, - { 0xfe5a, KEY_TUNER }, /* Live */ - { 0xfe19, KEY_OPEN }, - { 0xfe0b, KEY_1 }, - { 0xfe17, KEY_2 }, - { 0xfe1b, KEY_3 }, - { 0xfe07, KEY_4 }, - { 0xfe50, KEY_5 }, - { 0xfe54, KEY_6 }, - { 0xfe48, KEY_7 }, - { 0xfe4c, KEY_8 }, - { 0xfe58, KEY_9 }, - { 0xfe13, KEY_ANGLE }, /* Aspect */ - { 0xfe03, KEY_0 }, - { 0xfe1f, KEY_ZOOM }, - { 0xfe43, KEY_REWIND }, - { 0xfe47, KEY_PLAYPAUSE }, - { 0xfe4f, KEY_FASTFORWARD }, - { 0xfe57, KEY_MUTE }, - { 0xfe0d, KEY_STOP }, - { 0xfe01, KEY_RECORD }, - { 0xfe4e, KEY_POWER }, + { 0x0102, KEY_TV }, + { 0x010e, KEY_MP3 }, + { 0x011a, KEY_DVD }, + { 0x011e, KEY_FAVORITES }, + { 0x0116, KEY_SETUP }, + { 0x0146, KEY_POWER2 }, + { 0x010a, KEY_EPG }, + { 0x0149, KEY_BACK }, + { 0x014d, KEY_MENU }, + { 0x0151, KEY_UP }, + { 0x015b, KEY_LEFT }, + { 0x015f, KEY_RIGHT }, + { 0x0153, KEY_DOWN }, + { 0x015e, KEY_OK }, + { 0x0159, KEY_INFO }, + { 0x0155, KEY_TAB }, + { 0x010f, KEY_PREVIOUSSONG },/* Replay */ + { 0x0112, KEY_NEXTSONG }, /* Skip */ + { 0x0142, KEY_ENTER }, /* Windows/Start */ + { 0x0115, KEY_VOLUMEUP }, + { 0x0105, KEY_VOLUMEDOWN }, + { 0x0111, KEY_CHANNELUP }, + { 0x0109, KEY_CHANNELDOWN }, + { 0x0152, KEY_CAMERA }, + { 0x015a, KEY_TUNER }, /* Live */ + { 0x0119, KEY_OPEN }, + { 0x010b, KEY_1 }, + { 0x0117, KEY_2 }, + { 0x011b, KEY_3 }, + { 0x0107, KEY_4 }, + { 0x0150, KEY_5 }, + { 0x0154, KEY_6 }, + { 0x0148, KEY_7 }, + { 0x014c, KEY_8 }, + { 0x0158, KEY_9 }, + { 0x0113, KEY_ANGLE }, /* Aspect */ + { 0x0103, KEY_0 }, + { 0x011f, KEY_ZOOM }, + { 0x0143, KEY_REWIND }, + { 0x0147, KEY_PLAYPAUSE }, + { 0x014f, KEY_FASTFORWARD }, + { 0x0157, KEY_MUTE }, + { 0x010d, KEY_STOP }, + { 0x0101, KEY_RECORD }, + { 0x014e, KEY_POWER }, }; static struct rc_map_list dvico_mce_map = { .map = { .scan = rc_map_dvico_mce_table, .size = ARRAY_SIZE(rc_map_dvico_mce_table), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_NEC, .name = RC_MAP_DVICO_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-dvico-portable.c b/drivers/media/rc/keymaps/rc-dvico-portable.c index 94ceeee94b3f..ac4cb515cbf1 100644 --- a/drivers/media/rc/keymaps/rc-dvico-portable.c +++ b/drivers/media/rc/keymaps/rc-dvico-portable.c @@ -12,49 +12,49 @@ #include <linux/module.h> static struct rc_map_table rc_map_dvico_portable_table[] = { - { 0xfc02, KEY_SETUP }, /* Profile */ - { 0xfc43, KEY_POWER2 }, - { 0xfc06, KEY_EPG }, - { 0xfc5a, KEY_BACK }, - { 0xfc05, KEY_MENU }, - { 0xfc47, KEY_INFO }, - { 0xfc01, KEY_TAB }, - { 0xfc42, KEY_PREVIOUSSONG },/* Replay */ - { 0xfc49, KEY_VOLUMEUP }, - { 0xfc09, KEY_VOLUMEDOWN }, - { 0xfc54, KEY_CHANNELUP }, - { 0xfc0b, KEY_CHANNELDOWN }, - { 0xfc16, KEY_CAMERA }, - { 0xfc40, KEY_TUNER }, /* ATV/DTV */ - { 0xfc45, KEY_OPEN }, - { 0xfc19, KEY_1 }, - { 0xfc18, KEY_2 }, - { 0xfc1b, KEY_3 }, - { 0xfc1a, KEY_4 }, - { 0xfc58, KEY_5 }, - { 0xfc59, KEY_6 }, - { 0xfc15, KEY_7 }, - { 0xfc14, KEY_8 }, - { 0xfc17, KEY_9 }, - { 0xfc44, KEY_ANGLE }, /* Aspect */ - { 0xfc55, KEY_0 }, - { 0xfc07, KEY_ZOOM }, - { 0xfc0a, KEY_REWIND }, - { 0xfc08, KEY_PLAYPAUSE }, - { 0xfc4b, KEY_FASTFORWARD }, - { 0xfc5b, KEY_MUTE }, - { 0xfc04, KEY_STOP }, - { 0xfc56, KEY_RECORD }, - { 0xfc57, KEY_POWER }, - { 0xfc41, KEY_UNKNOWN }, /* INPUT */ - { 0xfc00, KEY_UNKNOWN }, /* HD */ + { 0x0302, KEY_SETUP }, /* Profile */ + { 0x0343, KEY_POWER2 }, + { 0x0306, KEY_EPG }, + { 0x035a, KEY_BACK }, + { 0x0305, KEY_MENU }, + { 0x0347, KEY_INFO }, + { 0x0301, KEY_TAB }, + { 0x0342, KEY_PREVIOUSSONG },/* Replay */ + { 0x0349, KEY_VOLUMEUP }, + { 0x0309, KEY_VOLUMEDOWN }, + { 0x0354, KEY_CHANNELUP }, + { 0x030b, KEY_CHANNELDOWN }, + { 0x0316, KEY_CAMERA }, + { 0x0340, KEY_TUNER }, /* ATV/DTV */ + { 0x0345, KEY_OPEN }, + { 0x0319, KEY_1 }, + { 0x0318, KEY_2 }, + { 0x031b, KEY_3 }, + { 0x031a, KEY_4 }, + { 0x0358, KEY_5 }, + { 0x0359, KEY_6 }, + { 0x0315, KEY_7 }, + { 0x0314, KEY_8 }, + { 0x0317, KEY_9 }, + { 0x0344, KEY_ANGLE }, /* Aspect */ + { 0x0355, KEY_0 }, + { 0x0307, KEY_ZOOM }, + { 0x030a, KEY_REWIND }, + { 0x0308, KEY_PLAYPAUSE }, + { 0x034b, KEY_FASTFORWARD }, + { 0x035b, KEY_MUTE }, + { 0x0304, KEY_STOP }, + { 0x0356, KEY_RECORD }, + { 0x0357, KEY_POWER }, + { 0x0341, KEY_UNKNOWN }, /* INPUT */ + { 0x0300, KEY_UNKNOWN }, /* HD */ }; static struct rc_map_list dvico_portable_map = { .map = { .scan = rc_map_dvico_portable_table, .size = ARRAY_SIZE(rc_map_dvico_portable_table), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .rc_type = RC_TYPE_NEC, .name = RC_MAP_DVICO_PORTABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c deleted file mode 100644 index e172f5db5803..000000000000 --- a/drivers/media/rc/keymaps/rc-lirc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass - * all raw IR data to the lirc userspace decoder. - * - * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <media/rc-core.h> -#include <linux/module.h> - -static struct rc_map_table lirc[] = { - { }, -}; - -static struct rc_map_list lirc_map = { - .map = { - .scan = lirc, - .size = ARRAY_SIZE(lirc), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_LIRC, - } -}; - -static int __init init_rc_map_lirc(void) -{ - return rc_map_register(&lirc_map); -} - -static void __exit exit_rc_map_lirc(void) -{ - rc_map_unregister(&lirc_map); -} - -module_init(init_rc_map_lirc) -module_exit(exit_rc_map_lirc) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 1688893a65bb..8d60c9f00df9 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -54,7 +54,8 @@ struct irctl { struct lirc_buffer *buf; unsigned int chunk_size; - struct cdev *cdev; + struct device dev; + struct cdev cdev; struct task_struct *task; long jiffies_to_wait; @@ -76,15 +77,21 @@ static void lirc_irctl_init(struct irctl *ir) ir->d.minor = NOPLUG; } -static void lirc_irctl_cleanup(struct irctl *ir) +static void lirc_release(struct device *ld) { - device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); + struct irctl *ir = container_of(ld, struct irctl, dev); + + put_device(ir->dev.parent); if (ir->buf != ir->d.rbuf) { lirc_buffer_free(ir->buf); kfree(ir->buf); } - ir->buf = NULL; + + mutex_lock(&lirc_dev_lock); + irctls[ir->d.minor] = NULL; + mutex_unlock(&lirc_dev_lock); + kfree(ir); } /* helper function @@ -157,32 +164,21 @@ static int lirc_cdev_add(struct irctl *ir) struct cdev *cdev; int retval; - cdev = cdev_alloc(); - if (!cdev) - return -ENOMEM; + cdev = &ir->cdev; if (d->fops) { - cdev->ops = d->fops; + cdev_init(cdev, d->fops); cdev->owner = d->owner; } else { - cdev->ops = &lirc_dev_fops; + cdev_init(cdev, &lirc_dev_fops); cdev->owner = THIS_MODULE; } retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); if (retval) - goto err_out; - - retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); - if (retval) - goto err_out; - - ir->cdev = cdev; - - return 0; + return retval; -err_out: - cdev_del(cdev); - return retval; + cdev->kobj.parent = &ir->dev.kobj; + return cdev_add(cdev, ir->dev.devt, 1); } static int lirc_allocate_buffer(struct irctl *ir) @@ -304,9 +300,12 @@ static int lirc_allocate_driver(struct lirc_driver *d) ir->d = *d; - device_create(lirc_class, ir->d.dev, - MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, - "lirc%u", ir->d.minor); + ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor); + ir->dev.class = lirc_class; + ir->dev.parent = d->dev; + ir->dev.release = lirc_release; + dev_set_name(&ir->dev, "lirc%d", ir->d.minor); + device_initialize(&ir->dev); if (d->sample_rate) { ir->jiffies_to_wait = HZ / d->sample_rate; @@ -329,14 +328,22 @@ static int lirc_allocate_driver(struct lirc_driver *d) goto out_sysfs; ir->attached = 1; + + err = device_add(&ir->dev); + if (err) + goto out_cdev; + mutex_unlock(&lirc_dev_lock); + get_device(ir->dev.parent); + dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", ir->d.name, ir->d.minor); return minor; - +out_cdev: + cdev_del(&ir->cdev); out_sysfs: - device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); + put_device(&ir->dev); out_lock: mutex_unlock(&lirc_dev_lock); @@ -364,7 +371,6 @@ EXPORT_SYMBOL(lirc_register_driver); int lirc_unregister_driver(int minor) { struct irctl *ir; - struct cdev *cdev; if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { pr_err("minor (%d) must be between 0 and %d!\n", @@ -378,8 +384,6 @@ int lirc_unregister_driver(int minor) return -ENOENT; } - cdev = ir->cdev; - mutex_lock(&lirc_dev_lock); if (ir->d.minor != minor) { @@ -401,22 +405,20 @@ int lirc_unregister_driver(int minor) dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", ir->d.name, ir->d.minor); wake_up_interruptible(&ir->buf->wait_poll); - mutex_lock(&ir->irctl_lock); + } - if (ir->d.set_use_dec) - ir->d.set_use_dec(ir->d.data); + mutex_lock(&ir->irctl_lock); - module_put(cdev->owner); - mutex_unlock(&ir->irctl_lock); - } else { - lirc_irctl_cleanup(ir); - cdev_del(cdev); - kfree(ir); - irctls[minor] = NULL; - } + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); + mutex_unlock(&ir->irctl_lock); mutex_unlock(&lirc_dev_lock); + device_del(&ir->dev); + cdev_del(&ir->cdev); + put_device(&ir->dev); + return 0; } EXPORT_SYMBOL(lirc_unregister_driver); @@ -424,7 +426,6 @@ EXPORT_SYMBOL(lirc_unregister_driver); int lirc_dev_fop_open(struct inode *inode, struct file *file) { struct irctl *ir; - struct cdev *cdev; int retval = 0; if (iminor(inode) >= MAX_IRCTL_DEVICES) { @@ -461,18 +462,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) goto error; } - cdev = ir->cdev; - if (try_module_get(cdev->owner)) { - ir->open++; - if (ir->d.set_use_inc) - retval = ir->d.set_use_inc(ir->d.data); - - if (retval) { - module_put(cdev->owner); - ir->open--; - } else if (ir->buf) { + ir->open++; + if (ir->d.set_use_inc) + retval = ir->d.set_use_inc(ir->d.data); + if (retval) { + ir->open--; + } else { + if (ir->buf) lirc_buffer_clear(ir->buf); - } if (ir->task) wake_up_process(ir->task); } @@ -487,7 +484,6 @@ EXPORT_SYMBOL(lirc_dev_fop_open); int lirc_dev_fop_close(struct inode *inode, struct file *file) { struct irctl *ir = irctls[iminor(inode)]; - struct cdev *cdev; int ret; if (!ir) { @@ -495,25 +491,14 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) return -EINVAL; } - cdev = ir->cdev; - ret = mutex_lock_killable(&lirc_dev_lock); WARN_ON(ret); rc_close(ir->d.rdev); ir->open--; - if (ir->attached) { - if (ir->d.set_use_dec) - ir->d.set_use_dec(ir->d.data); - module_put(cdev->owner); - } else { - lirc_irctl_cleanup(ir); - cdev_del(cdev); - irctls[ir->d.minor] = NULL; - kfree(ir); - } - + if (ir->d.set_use_dec) + ir->d.set_use_dec(ir->d.data); if (!ret) mutex_unlock(&lirc_dev_lock); @@ -623,7 +608,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) result = put_user(ir->d.max_timeout, (__u32 __user *)arg); break; default: - result = -EINVAL; + result = -ENOTTY; } mutex_unlock(&ir->irctl_lock); @@ -780,15 +765,12 @@ static int __init lirc_dev_init(void) return retval; } - pr_info("IR Remote Control driver registered, major %d\n", MAJOR(lirc_base_dev)); return 0; } - - static void __exit lirc_dev_exit(void) { class_destroy(lirc_class); diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 238d8eaf7d94..93b16fe3ab38 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1288,8 +1288,8 @@ static int mceusb_dev_probe(struct usb_interface *intf, } } } - if (ep_in == NULL) { - dev_dbg(&intf->dev, "inbound and/or endpoint not found"); + if (!ep_in || !ep_out) { + dev_dbg(&intf->dev, "required endpoints not found\n"); return -ENODEV; } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index a70a5c557434..0455b273c2fc 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -185,7 +185,7 @@ struct ir_raw_timings_manchester { int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, const struct ir_raw_timings_manchester *timings, - unsigned int n, unsigned int data); + unsigned int n, u64 data); /** * ir_raw_gen_pulse_space() - generate pulse and space raw events. diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 7fa84b64a2ae..90f66dc7c0d7 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -258,13 +258,13 @@ static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols) */ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, const struct ir_raw_timings_manchester *timings, - unsigned int n, unsigned int data) + unsigned int n, u64 data) { bool need_pulse; - unsigned int i; + u64 i; int ret = -ENOBUFS; - i = 1 << (n - 1); + i = BIT_ULL(n - 1); if (timings->leader) { if (!max--) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d84533699668..6ec73357fa47 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -746,6 +746,8 @@ static int rc_validate_filter(struct rc_dev *dev, [RC_TYPE_NECX] = 0xffffff, [RC_TYPE_NEC32] = 0xffffffff, [RC_TYPE_SANYO] = 0x1fffff, + [RC_TYPE_MCIR2_KBD] = 0xffff, + [RC_TYPE_MCIR2_MSE] = 0x1fffff, [RC_TYPE_RC6_0] = 0xffff, [RC_TYPE_RC6_6A_20] = 0xfffff, [RC_TYPE_RC6_6A_24] = 0xffffff, @@ -878,7 +880,8 @@ static const struct { { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" }, { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" }, { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" }, - { RC_BIT_MCE_KBD, "mce_kbd", "ir-mce_kbd-decoder" }, + { RC_BIT_MCIR2_KBD | + RC_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, { RC_BIT_XMP, "xmp", "ir-xmp-decoder" }, { RC_BIT_CEC, "cec", NULL }, }; @@ -1346,7 +1349,8 @@ static const char * const proto_variant_names[] = { [RC_TYPE_NECX] = "nec-x", [RC_TYPE_NEC32] = "nec-32", [RC_TYPE_SANYO] = "sanyo", - [RC_TYPE_MCE_KBD] = "mce_kbd", + [RC_TYPE_MCIR2_KBD] = "mcir2-kbd", + [RC_TYPE_MCIR2_MSE] = "mcir2-mse", [RC_TYPE_RC6_0] = "rc-6-0", [RC_TYPE_RC6_6A_20] = "rc-6-6a-20", [RC_TYPE_RC6_6A_24] = "rc-6-6a-24", diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 41b54e40176c..2f0a0d248936 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -56,7 +56,7 @@ struct serial_ir_hw { static int type; static int io; static int irq; -static bool iommap; +static ulong iommap; static int ioshift; static bool softcarrier = true; static bool share_irq; @@ -837,7 +837,7 @@ module_param(io, int, 0444); MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); /* some architectures (e.g. intel xscale) have memory mapped registers */ -module_param(iommap, bool, 0444); +module_param(iommap, ulong, 0444); MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)"); /* diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c new file mode 100644 index 000000000000..e12ec50bf0bf --- /dev/null +++ b/drivers/media/rc/sir_ir.c @@ -0,0 +1,438 @@ +/* + * IR SIR driver, (C) 2000 Milan Pikula <www@fornax.sk> + * + * sir_ir - Device driver for use with SIR (serial infra red) + * mode of IrDA on many notebooks. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/serial_reg.h> +#include <linux/ktime.h> +#include <linux/delay.h> +#include <linux/platform_device.h> + +#include <media/rc-core.h> + +/* SECTION: Definitions */ +#define PULSE '[' + +/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ +#define TIME_CONST (9000000ul / 115200ul) + +/* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */ +#define SIR_TIMEOUT (HZ * 5 / 100) + +/* onboard sir ports are typically com3 */ +static int io = 0x3e8; +static int irq = 4; +static int threshold = 3; + +static DEFINE_SPINLOCK(timer_lock); +static struct timer_list timerlist; +/* time of last signal change detected */ +static ktime_t last; +/* time of last UART data ready interrupt */ +static ktime_t last_intr_time; +static int last_value; +static struct rc_dev *rcdev; + +static struct platform_device *sir_ir_dev; + +static DEFINE_SPINLOCK(hardware_lock); + +/* SECTION: Prototypes */ + +/* Communication with user-space */ +static void add_read_queue(int flag, unsigned long val); +static int init_chrdev(void); +/* Hardware */ +static irqreturn_t sir_interrupt(int irq, void *dev_id); +static void send_space(unsigned long len); +static void send_pulse(unsigned long len); +static int init_hardware(void); +static void drop_hardware(void); +/* Initialisation */ +static int init_port(void); +static void drop_port(void); + +static inline unsigned int sinp(int offset) +{ + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ + outb(value, io + offset); +} + +/* SECTION: Communication with user-space */ +static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf, + unsigned int count) +{ + unsigned long flags; + int i; + + local_irq_save(flags); + for (i = 0; i < count;) { + if (tx_buf[i]) + send_pulse(tx_buf[i]); + i++; + if (i >= count) + break; + if (tx_buf[i]) + send_space(tx_buf[i]); + i++; + } + local_irq_restore(flags); + + return count; +} + +static void add_read_queue(int flag, unsigned long val) +{ + DEFINE_IR_RAW_EVENT(ev); + + pr_debug("add flag %d with val %lu\n", flag, val); + + /* + * statistically, pulses are ~TIME_CONST/2 too long. we could + * maybe make this more exact, but this is good enough + */ + if (flag) { + /* pulse */ + if (val > TIME_CONST / 2) + val -= TIME_CONST / 2; + else /* should not ever happen */ + val = 1; + ev.pulse = true; + } else { + val += TIME_CONST / 2; + } + ev.duration = US_TO_NS(val); + + ir_raw_event_store_with_filter(rcdev, &ev); +} + +static int init_chrdev(void) +{ + rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW); + if (!rcdev) + return -ENOMEM; + + rcdev->input_name = "SIR IrDA port"; + rcdev->input_phys = KBUILD_MODNAME "/input0"; + rcdev->input_id.bustype = BUS_HOST; + rcdev->input_id.vendor = 0x0001; + rcdev->input_id.product = 0x0001; + rcdev->input_id.version = 0x0100; + rcdev->tx_ir = sir_tx_ir; + rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rcdev->driver_name = KBUILD_MODNAME; + rcdev->map_name = RC_MAP_RC6_MCE; + rcdev->timeout = IR_DEFAULT_TIMEOUT; + rcdev->dev.parent = &sir_ir_dev->dev; + + return devm_rc_register_device(&sir_ir_dev->dev, rcdev); +} + +/* SECTION: Hardware */ +static void sir_timeout(unsigned long data) +{ + /* + * if last received signal was a pulse, but receiving stopped + * within the 9 bit frame, we need to finish this pulse and + * simulate a signal change to from pulse to space. Otherwise + * upper layers will receive two sequences next time. + */ + + unsigned long flags; + unsigned long pulse_end; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&timer_lock, flags); + if (last_value) { + /* clear unread bits in UART and restart */ + outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); + /* determine 'virtual' pulse end: */ + pulse_end = min_t(unsigned long, + ktime_us_delta(last, last_intr_time), + IR_MAX_DURATION); + dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n", + last_value, pulse_end); + add_read_queue(last_value, pulse_end); + last_value = 0; + last = last_intr_time; + } + spin_unlock_irqrestore(&timer_lock, flags); + ir_raw_event_handle(rcdev); +} + +static irqreturn_t sir_interrupt(int irq, void *dev_id) +{ + unsigned char data; + ktime_t curr_time; + static unsigned long delt; + unsigned long deltintr; + unsigned long flags; + int iir, lsr; + + while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { + switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */ + case UART_IIR_MSI: + (void)inb(io + UART_MSR); + break; + case UART_IIR_RLSI: + case UART_IIR_THRI: + (void)inb(io + UART_LSR); + break; + case UART_IIR_RDI: + /* avoid interference with timer */ + spin_lock_irqsave(&timer_lock, flags); + do { + del_timer(&timerlist); + data = inb(io + UART_RX); + curr_time = ktime_get(); + delt = min_t(unsigned long, + ktime_us_delta(last, curr_time), + IR_MAX_DURATION); + deltintr = min_t(unsigned long, + ktime_us_delta(last_intr_time, + curr_time), + IR_MAX_DURATION); + dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n", + deltintr, (int)data); + /* + * if nothing came in last X cycles, + * it was gap + */ + if (deltintr > TIME_CONST * threshold) { + if (last_value) { + dev_dbg(&sir_ir_dev->dev, "GAP\n"); + /* simulate signal change */ + add_read_queue(last_value, + delt - + deltintr); + last_value = 0; + last = last_intr_time; + delt = deltintr; + } + } + data = 1; + if (data ^ last_value) { + /* + * deltintr > 2*TIME_CONST, remember? + * the other case is timeout + */ + add_read_queue(last_value, + delt - TIME_CONST); + last_value = data; + last = curr_time; + last = ktime_sub_us(last, + TIME_CONST); + } + last_intr_time = curr_time; + if (data) { + /* + * start timer for end of + * sequence detection + */ + timerlist.expires = jiffies + + SIR_TIMEOUT; + add_timer(&timerlist); + } + + lsr = inb(io + UART_LSR); + } while (lsr & UART_LSR_DR); /* data ready */ + spin_unlock_irqrestore(&timer_lock, flags); + break; + default: + break; + } + } + ir_raw_event_handle(rcdev); + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void send_space(unsigned long len) +{ + usleep_range(len, len + 25); +} + +static void send_pulse(unsigned long len) +{ + long bytes_out = len / TIME_CONST; + + if (bytes_out == 0) + bytes_out++; + + while (bytes_out--) { + outb(PULSE, io + UART_TX); + /* FIXME treba seriozne cakanie z char/serial.c */ + while (!(inb(io + UART_LSR) & UART_LSR_THRE)) + ; + } +} + +static int init_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + /* reset UART */ + outb(0, io + UART_MCR); + outb(0, io + UART_IER); + /* init UART */ + /* set DLAB, speed = 115200 */ + outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR); + outb(1, io + UART_DLL); outb(0, io + UART_DLM); + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */ + outb(UART_LCR_WLEN7, io + UART_LCR); + /* FIFO operation */ + outb(UART_FCR_ENABLE_FIFO, io + UART_FCR); + /* interrupts */ + /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ + outb(UART_IER_RDI, io + UART_IER); + /* turn on UART */ + outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR); + spin_unlock_irqrestore(&hardware_lock, flags); + return 0; +} + +static void drop_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + + /* turn off interrupts */ + outb(0, io + UART_IER); + + spin_unlock_irqrestore(&hardware_lock, flags); +} + +/* SECTION: Initialisation */ + +static int init_port(void) +{ + int retval; + + setup_timer(&timerlist, sir_timeout, 0); + + /* get I/O port access and IRQ line */ + if (!request_region(io, 8, KBUILD_MODNAME)) { + pr_err("i/o port 0x%.4x already in use.\n", io); + return -EBUSY; + } + retval = request_irq(irq, sir_interrupt, 0, + KBUILD_MODNAME, NULL); + if (retval < 0) { + release_region(io, 8); + pr_err("IRQ %d already in use.\n", irq); + return retval; + } + pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq); + + return 0; +} + +static void drop_port(void) +{ + free_irq(irq, NULL); + del_timer_sync(&timerlist); + release_region(io, 8); +} + +static int init_sir_ir(void) +{ + int retval; + + retval = init_port(); + if (retval < 0) + return retval; + init_hardware(); + return 0; +} + +static int sir_ir_probe(struct platform_device *dev) +{ + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + + return init_sir_ir(); +} + +static int sir_ir_remove(struct platform_device *dev) +{ + return 0; +} + +static struct platform_driver sir_ir_driver = { + .probe = sir_ir_probe, + .remove = sir_ir_remove, + .driver = { + .name = "sir_ir", + }, +}; + +static int __init sir_ir_init(void) +{ + int retval; + + retval = platform_driver_register(&sir_ir_driver); + if (retval) + return retval; + + sir_ir_dev = platform_device_alloc("sir_ir", 0); + if (!sir_ir_dev) { + retval = -ENOMEM; + goto pdev_alloc_fail; + } + + retval = platform_device_add(sir_ir_dev); + if (retval) + goto pdev_add_fail; + + return 0; + +pdev_add_fail: + platform_device_put(sir_ir_dev); +pdev_alloc_fail: + platform_driver_unregister(&sir_ir_driver); + return retval; +} + +static void __exit sir_ir_exit(void) +{ + drop_hardware(); + drop_port(); + platform_device_unregister(sir_ir_dev); + platform_driver_unregister(&sir_ir_driver); +} + +module_init(sir_ir_init); +module_exit(sir_ir_exit); + +MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); +MODULE_AUTHOR("Milan Pikula"); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); + +module_param(threshold, int, 0444); +MODULE_PARM_DESC(threshold, "space detection threshold (3)"); diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index f0d7190e3919..a08e1dd06124 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -165,8 +165,7 @@ static void st_rc_hardware_init(struct st_rc_device *dev) unsigned int rx_sampling_freq_div; /* Enable the IP */ - if (dev->rstc) - reset_control_deassert(dev->rstc); + reset_control_deassert(dev->rstc); clk_prepare_enable(dev->sys_clock); baseclock = clk_get_rate(dev->sys_clock); @@ -281,10 +280,11 @@ static int st_rc_probe(struct platform_device *pdev) else rc_dev->rx_base = rc_dev->base; - rc_dev->rstc = reset_control_get_optional(dev, NULL); - if (IS_ERR(rc_dev->rstc)) - rc_dev->rstc = NULL; + if (IS_ERR(rc_dev->rstc)) { + ret = PTR_ERR(rc_dev->rstc); + goto err; + } rc_dev->dev = dev; platform_set_drvdata(pdev, rc_dev); @@ -298,7 +298,7 @@ static int st_rc_probe(struct platform_device *pdev) rdev->open = st_rc_open; rdev->close = st_rc_close; rdev->driver_name = IR_ST_NAME; - rdev->map_name = RC_MAP_LIRC; + rdev->map_name = RC_MAP_EMPTY; rdev->input_name = "ST Remote Control Receiver"; ret = rc_register_device(rdev); @@ -352,8 +352,7 @@ static int st_rc_suspend(struct device *dev) writel(0x00, rc_dev->rx_base + IRB_RX_EN); writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN); clk_disable_unprepare(rc_dev->sys_clock); - if (rc_dev->rstc) - reset_control_assert(rc_dev->rstc); + reset_control_assert(rc_dev->rstc); } return 0; diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index 25b006167810..4b785dd775c1 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -174,16 +174,11 @@ static int sunxi_ir_probe(struct platform_device *pdev) /* Reset (optional) */ ir->rst = devm_reset_control_get_optional(dev, NULL); - if (IS_ERR(ir->rst)) { - ret = PTR_ERR(ir->rst); - if (ret == -EPROBE_DEFER) - return ret; - ir->rst = NULL; - } else { - ret = reset_control_deassert(ir->rst); - if (ret) - return ret; - } + if (IS_ERR(ir->rst)) + return PTR_ERR(ir->rst); + ret = reset_control_deassert(ir->rst); + if (ret) + return ret; ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); if (ret) { @@ -291,8 +286,7 @@ exit_clkdisable_clk: exit_clkdisable_apb_clk: clk_disable_unprepare(ir->apb_clk); exit_reset_assert: - if (ir->rst) - reset_control_assert(ir->rst); + reset_control_assert(ir->rst); return ret; } @@ -304,8 +298,7 @@ static int sunxi_ir_remove(struct platform_device *pdev) clk_disable_unprepare(ir->clk); clk_disable_unprepare(ir->apb_clk); - if (ir->rst) - reset_control_assert(ir->rst); + reset_control_assert(ir->rst); spin_lock_irqsave(&ir->ir_lock, flags); /* disable IR IRQ */ diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index dc1c8305ad23..5a4d4a611197 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1082,7 +1082,9 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->tx_ir = wbcir_tx; data->dev->priv = data; data->dev->dev.parent = &device->dev; - data->dev->timeout = MS_TO_NS(100); + data->dev->min_timeout = 1; + data->dev->timeout = IR_DEFAULT_TIMEOUT; + data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; data->dev->rx_resolution = US_TO_NS(2); data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER; data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX | |