diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-06-08 10:24:07 +0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-06-08 10:24:07 +0400 |
commit | a292241cccb7e20e8b997a9a44177e7c98141859 (patch) | |
tree | a0b0bb95e7dce3233a2d8b203f9e326cdec7a00e /drivers/media/rc | |
parent | d49cb7aeebb974713f9f7ab2991352d3050b095b (diff) | |
parent | 68807a0c2015cb40df4869e16651f0ce5cc14d52 (diff) | |
download | linux-a292241cccb7e20e8b997a9a44177e7c98141859.tar.xz |
Merge branch 'next' into for-linus
Prepare input updates for 3.16.
Diffstat (limited to 'drivers/media/rc')
112 files changed, 3335 insertions, 336 deletions
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 904f11367c29..8fbd377e6311 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -106,6 +106,15 @@ config IR_SANYO_DECODER uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes), and you need software decoding support. +config IR_SHARP_DECODER + tristate "Enable IR raw decoder for the Sharp protocol" + depends on RC_CORE + default y + + ---help--- + Enable this option if you have an infrared remote control which + uses the Sharp protocol, and you need software decoding support. + config IR_MCE_KBD_DECODER tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" depends on RC_CORE @@ -300,6 +309,8 @@ config IR_RX51 The driver uses omap DM timers for generating the carrier wave and pulses. +source "drivers/media/rc/img-ir/Kconfig" + config RC_LOOPBACK tristate "Remote Control Loopback Driver" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index f4eb32c0a455..f8b54ff46601 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o +obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o @@ -31,3 +32,4 @@ obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o obj-$(CONFIG_IR_IGUANA) += iguanair.o obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o obj-$(CONFIG_RC_ST) += st_rc.o +obj-$(CONFIG_IR_IMG) += img-ir/ diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 4d6a63fe6c5e..2df7c5516013 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -784,7 +784,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote) rdev->priv = ati_remote; rdev->driver_type = RC_DRIVER_SCANCODE; - rdev->allowed_protos = RC_BIT_OTHER; + rc_set_allowed_protocols(rdev, RC_BIT_OTHER); rdev->driver_name = "ati_remote"; rdev->open = ati_remote_rc_open; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index c1444f84717d..fc9d23f2ed3f 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1059,7 +1059,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) learning_mode_force = false; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->priv = dev; rdev->open = ene_open; rdev->close = ene_close; diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index d6fa441655d2..46b66e59438f 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id /* Set up the rc device */ rdev->priv = fintek; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->open = fintek_open; rdev->close = fintek_close; rdev->input_name = FINTEK_DESCRIPTION; diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 80c611c2e8c2..29b5f89813b4 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -145,9 +145,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->dev.parent = &pdev->dev; rcdev->driver_name = GPIO_IR_DRIVER_NAME; if (pdata->allowed_protos) - rcdev->allowed_protos = pdata->allowed_protos; + rc_set_allowed_protocols(rcdev, pdata->allowed_protos); else - rcdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rcdev, RC_BIT_ALL); rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index fdae05c4f377..627ddfd61980 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -286,10 +286,10 @@ static int iguanair_receiver(struct iguanair *ir, bool enable) } /* - * The iguana ir creates the carrier by busy spinning after each pulse or - * space. This is counted in CPU cycles, with the CPU running at 24MHz. It is + * The iguanair creates the carrier by busy spinning after each half period. + * This is counted in CPU cycles, with the CPU running at 24MHz. It is * broken down into 7-cycles and 4-cyles delays, with a preference for - * 4-cycle delays. + * 4-cycle delays, minus the overhead of the loop itself (cycle_overhead). */ static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier) { @@ -316,7 +316,14 @@ static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier) sevens = (4 - cycles) & 3; fours = (cycles - sevens * 7) / 4; - /* magic happens here */ + /* + * The firmware interprets these values as a relative offset + * for a branch. Immediately following the branches, there + * 4 instructions of 7 cycles (2 bytes each) and 110 + * instructions of 4 cycles (1 byte each). A relative branch + * of 0 will execute all of them, branch further for less + * cycle burning. + */ ir->packet->busy7 = (4 - sevens) * 2; ir->packet->busy4 = 110 - fours; } @@ -357,20 +364,14 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count) rc = -EINVAL; goto out; } - while (periods > 127) { - ir->packet->payload[size++] = 127 | space; - periods -= 127; + while (periods) { + unsigned p = min(periods, 127u); + ir->packet->payload[size++] = p | space; + periods -= p; } - - ir->packet->payload[size++] = periods | space; space ^= 0x80; } - if (count == 0) { - rc = -EINVAL; - goto out; - } - ir->packet->header.start = 0; ir->packet->header.direction = DIR_OUT; ir->packet->header.cmd = CMD_SEND; @@ -494,7 +495,7 @@ static int iguanair_probe(struct usb_interface *intf, usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->priv = ir; rc->open = iguanair_open; rc->close = iguanair_close; diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig new file mode 100644 index 000000000000..03ba9fc170fb --- /dev/null +++ b/drivers/media/rc/img-ir/Kconfig @@ -0,0 +1,61 @@ +config IR_IMG + tristate "ImgTec IR Decoder" + depends on RC_CORE + select IR_IMG_HW if !IR_IMG_RAW + help + Say Y or M here if you want to use the ImgTec infrared decoder + functionality found in SoCs such as TZ1090. + +config IR_IMG_RAW + bool "Raw decoder" + depends on IR_IMG + help + Say Y here to enable the raw mode driver which passes raw IR signal + changes to the IR raw decoders for software decoding. This is much + less reliable (due to lack of timestamps) and consumes more + processing power than using hardware decode, but can be useful for + testing, debug, and to make more protocols available. + +config IR_IMG_HW + bool "Hardware decoder" + depends on IR_IMG + help + Say Y here to enable the hardware decode driver which decodes the IR + signals in hardware. This is more reliable, consumes less processing + power since only a single interrupt is received for each scancode, + and allows an IR scancode to be used as a wake event. + +config IR_IMG_NEC + bool "NEC protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the NEC, extended NEC, and 32-bit + NEC protocols in the ImgTec infrared decoder block. + +config IR_IMG_JVC + bool "JVC protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the JVC protocol in the ImgTec + infrared decoder block. + +config IR_IMG_SONY + bool "Sony protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the Sony protocol in the ImgTec + infrared decoder block. + +config IR_IMG_SHARP + bool "Sharp protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the Sharp protocol in the ImgTec + infrared decoder block. + +config IR_IMG_SANYO + bool "Sanyo protocol support" + depends on IR_IMG_HW + help + Say Y here to enable support for the Sanyo protocol (used by Sanyo, + Aiwa, Chinon remotes) in the ImgTec infrared decoder block. diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile new file mode 100644 index 000000000000..92a459d99509 --- /dev/null +++ b/drivers/media/rc/img-ir/Makefile @@ -0,0 +1,11 @@ +img-ir-y := img-ir-core.o +img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o +img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o +img-ir-$(CONFIG_IR_IMG_NEC) += img-ir-nec.o +img-ir-$(CONFIG_IR_IMG_JVC) += img-ir-jvc.o +img-ir-$(CONFIG_IR_IMG_SONY) += img-ir-sony.o +img-ir-$(CONFIG_IR_IMG_SHARP) += img-ir-sharp.o +img-ir-$(CONFIG_IR_IMG_SANYO) += img-ir-sanyo.o +img-ir-objs := $(img-ir-y) + +obj-$(CONFIG_IR_IMG) += img-ir.o diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c new file mode 100644 index 000000000000..6b7834834fb8 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-core.c @@ -0,0 +1,176 @@ +/* + * ImgTec IR Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + * + * This contains core img-ir code for setting up the driver. The two interfaces + * (raw and hardware decode) are handled separately. + */ + +#include <linux/clk.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include "img-ir.h" + +static irqreturn_t img_ir_isr(int irq, void *dev_id) +{ + struct img_ir_priv *priv = dev_id; + u32 irq_status; + + spin_lock(&priv->lock); + /* we have to clear irqs before reading */ + irq_status = img_ir_read(priv, IMG_IR_IRQ_STATUS); + img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_status); + + /* don't handle valid data irqs if we're only interested in matches */ + irq_status &= img_ir_read(priv, IMG_IR_IRQ_ENABLE); + + /* hand off edge interrupts to raw decode handler */ + if (irq_status & IMG_IR_IRQ_EDGE && img_ir_raw_enabled(&priv->raw)) + img_ir_isr_raw(priv, irq_status); + + /* hand off hardware match interrupts to hardware decode handler */ + if (irq_status & (IMG_IR_IRQ_DATA_MATCH | + IMG_IR_IRQ_DATA_VALID | + IMG_IR_IRQ_DATA2_VALID) && + img_ir_hw_enabled(&priv->hw)) + img_ir_isr_hw(priv, irq_status); + + spin_unlock(&priv->lock); + return IRQ_HANDLED; +} + +static void img_ir_setup(struct img_ir_priv *priv) +{ + /* start off with interrupts disabled */ + img_ir_write(priv, IMG_IR_IRQ_ENABLE, 0); + + img_ir_setup_raw(priv); + img_ir_setup_hw(priv); + + if (!IS_ERR(priv->clk)) + clk_prepare_enable(priv->clk); +} + +static void img_ir_ident(struct img_ir_priv *priv) +{ + u32 core_rev = img_ir_read(priv, IMG_IR_CORE_REV); + + dev_info(priv->dev, + "IMG IR Decoder (%d.%d.%d.%d) probed successfully\n", + (core_rev & IMG_IR_DESIGNER) >> IMG_IR_DESIGNER_SHIFT, + (core_rev & IMG_IR_MAJOR_REV) >> IMG_IR_MAJOR_REV_SHIFT, + (core_rev & IMG_IR_MINOR_REV) >> IMG_IR_MINOR_REV_SHIFT, + (core_rev & IMG_IR_MAINT_REV) >> IMG_IR_MAINT_REV_SHIFT); + dev_info(priv->dev, "Modes:%s%s\n", + img_ir_hw_enabled(&priv->hw) ? " hardware" : "", + img_ir_raw_enabled(&priv->raw) ? " raw" : ""); +} + +static int img_ir_probe(struct platform_device *pdev) +{ + struct img_ir_priv *priv; + struct resource *res_regs; + int irq, error, error2; + + /* Get resources from platform device */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "cannot find IRQ resource\n"); + return irq; + } + + /* Private driver data */ + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "cannot allocate device data\n"); + return -ENOMEM; + } + platform_set_drvdata(pdev, priv); + priv->dev = &pdev->dev; + spin_lock_init(&priv->lock); + + /* Ioremap the registers */ + res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->reg_base = devm_ioremap_resource(&pdev->dev, res_regs); + if (IS_ERR(priv->reg_base)) + return PTR_ERR(priv->reg_base); + + /* Get core clock */ + priv->clk = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(priv->clk)) + dev_warn(&pdev->dev, "cannot get core clock resource\n"); + /* + * The driver doesn't need to know about the system ("sys") or power + * modulation ("mod") clocks yet + */ + + /* Set up raw & hw decoder */ + error = img_ir_probe_raw(priv); + error2 = img_ir_probe_hw(priv); + if (error && error2) + return (error == -ENODEV) ? error2 : error; + + /* Get the IRQ */ + priv->irq = irq; + error = request_irq(priv->irq, img_ir_isr, 0, "img-ir", priv); + if (error) { + dev_err(&pdev->dev, "cannot register IRQ %u\n", + priv->irq); + error = -EIO; + goto err_irq; + } + + img_ir_ident(priv); + img_ir_setup(priv); + + return 0; + +err_irq: + img_ir_remove_hw(priv); + img_ir_remove_raw(priv); + return error; +} + +static int img_ir_remove(struct platform_device *pdev) +{ + struct img_ir_priv *priv = platform_get_drvdata(pdev); + + free_irq(priv->irq, img_ir_isr); + img_ir_remove_hw(priv); + img_ir_remove_raw(priv); + + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + return 0; +} + +static SIMPLE_DEV_PM_OPS(img_ir_pmops, img_ir_suspend, img_ir_resume); + +static const struct of_device_id img_ir_match[] = { + { .compatible = "img,ir-rev1" }, + {} +}; +MODULE_DEVICE_TABLE(of, img_ir_match); + +static struct platform_driver img_ir_driver = { + .driver = { + .name = "img-ir", + .owner = THIS_MODULE, + .of_match_table = img_ir_match, + .pm = &img_ir_pmops, + }, + .probe = img_ir_probe, + .remove = img_ir_remove, +}; + +module_platform_driver(img_ir_driver); + +MODULE_AUTHOR("Imagination Technologies Ltd."); +MODULE_DESCRIPTION("ImgTec IR"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c new file mode 100644 index 000000000000..0127dd257a57 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -0,0 +1,1066 @@ +/* + * ImgTec IR Hardware Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + * + * This ties into the input subsystem using the RC-core. Protocol support is + * provided in separate modules which provide the parameters and scancode + * translation functions to set up the hardware decoder and interpret the + * resulting input. + */ + +#include <linux/bitops.h> +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/timer.h> +#include <media/rc-core.h> +#include "img-ir.h" + +/* Decoders lock (only modified to preprocess them) */ +static DEFINE_SPINLOCK(img_ir_decoders_lock); + +extern struct img_ir_decoder img_ir_nec; +extern struct img_ir_decoder img_ir_jvc; +extern struct img_ir_decoder img_ir_sony; +extern struct img_ir_decoder img_ir_sharp; +extern struct img_ir_decoder img_ir_sanyo; + +static bool img_ir_decoders_preprocessed; +static struct img_ir_decoder *img_ir_decoders[] = { +#ifdef CONFIG_IR_IMG_NEC + &img_ir_nec, +#endif +#ifdef CONFIG_IR_IMG_JVC + &img_ir_jvc, +#endif +#ifdef CONFIG_IR_IMG_SONY + &img_ir_sony, +#endif +#ifdef CONFIG_IR_IMG_SHARP + &img_ir_sharp, +#endif +#ifdef CONFIG_IR_IMG_SANYO + &img_ir_sanyo, +#endif + NULL +}; + +#define IMG_IR_F_FILTER BIT(RC_FILTER_NORMAL) /* enable filtering */ +#define IMG_IR_F_WAKE BIT(RC_FILTER_WAKEUP) /* enable waking */ + +/* code type quirks */ + +#define IMG_IR_QUIRK_CODE_BROKEN 0x1 /* Decode is broken */ +#define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs increment */ + +/* functions for preprocessing timings, ensuring max is set */ + +static void img_ir_timing_preprocess(struct img_ir_timing_range *range, + unsigned int unit) +{ + if (range->max < range->min) + range->max = range->min; + if (unit) { + /* multiply by unit and convert to microseconds */ + range->min = (range->min*unit)/1000; + range->max = (range->max*unit + 999)/1000; /* round up */ + } +} + +static void img_ir_symbol_timing_preprocess(struct img_ir_symbol_timing *timing, + unsigned int unit) +{ + img_ir_timing_preprocess(&timing->pulse, unit); + img_ir_timing_preprocess(&timing->space, unit); +} + +static void img_ir_timings_preprocess(struct img_ir_timings *timings, + unsigned int unit) +{ + img_ir_symbol_timing_preprocess(&timings->ldr, unit); + img_ir_symbol_timing_preprocess(&timings->s00, unit); + img_ir_symbol_timing_preprocess(&timings->s01, unit); + img_ir_symbol_timing_preprocess(&timings->s10, unit); + img_ir_symbol_timing_preprocess(&timings->s11, unit); + /* default s10 and s11 to s00 and s01 if no leader */ + if (unit) + /* multiply by unit and convert to microseconds (round up) */ + timings->ft.ft_min = (timings->ft.ft_min*unit + 999)/1000; +} + +/* functions for filling empty fields with defaults */ + +static void img_ir_timing_defaults(struct img_ir_timing_range *range, + struct img_ir_timing_range *defaults) +{ + if (!range->min) + range->min = defaults->min; + if (!range->max) + range->max = defaults->max; +} + +static void img_ir_symbol_timing_defaults(struct img_ir_symbol_timing *timing, + struct img_ir_symbol_timing *defaults) +{ + img_ir_timing_defaults(&timing->pulse, &defaults->pulse); + img_ir_timing_defaults(&timing->space, &defaults->space); +} + +static void img_ir_timings_defaults(struct img_ir_timings *timings, + struct img_ir_timings *defaults) +{ + img_ir_symbol_timing_defaults(&timings->ldr, &defaults->ldr); + img_ir_symbol_timing_defaults(&timings->s00, &defaults->s00); + img_ir_symbol_timing_defaults(&timings->s01, &defaults->s01); + img_ir_symbol_timing_defaults(&timings->s10, &defaults->s10); + img_ir_symbol_timing_defaults(&timings->s11, &defaults->s11); + if (!timings->ft.ft_min) + timings->ft.ft_min = defaults->ft.ft_min; +} + +/* functions for converting timings to register values */ + +/** + * img_ir_control() - Convert control struct to control register value. + * @control: Control data + * + * Returns: The control register value equivalent of @control. + */ +static u32 img_ir_control(const struct img_ir_control *control) +{ + u32 ctrl = control->code_type << IMG_IR_CODETYPE_SHIFT; + if (control->decoden) + ctrl |= IMG_IR_DECODEN; + if (control->hdrtog) + ctrl |= IMG_IR_HDRTOG; + if (control->ldrdec) + ctrl |= IMG_IR_LDRDEC; + if (control->decodinpol) + ctrl |= IMG_IR_DECODINPOL; + if (control->bitorien) + ctrl |= IMG_IR_BITORIEN; + if (control->d1validsel) + ctrl |= IMG_IR_D1VALIDSEL; + if (control->bitinv) + ctrl |= IMG_IR_BITINV; + if (control->decodend2) + ctrl |= IMG_IR_DECODEND2; + if (control->bitoriend2) + ctrl |= IMG_IR_BITORIEND2; + if (control->bitinvd2) + ctrl |= IMG_IR_BITINVD2; + return ctrl; +} + +/** + * img_ir_timing_range_convert() - Convert microsecond range. + * @out: Output timing range in clock cycles with a shift. + * @in: Input timing range in microseconds. + * @tolerance: Tolerance as a fraction of 128 (roughly percent). + * @clock_hz: IR clock rate in Hz. + * @shift: Shift of output units. + * + * Converts min and max from microseconds to IR clock cycles, applies a + * tolerance, and shifts for the register, rounding in the right direction. + * Note that in and out can safely be the same object. + */ +static void img_ir_timing_range_convert(struct img_ir_timing_range *out, + const struct img_ir_timing_range *in, + unsigned int tolerance, + unsigned long clock_hz, + unsigned int shift) +{ + unsigned int min = in->min; + unsigned int max = in->max; + /* add a tolerance */ + min = min - (min*tolerance >> 7); + max = max + (max*tolerance >> 7); + /* convert from microseconds into clock cycles */ + min = min*clock_hz / 1000000; + max = (max*clock_hz + 999999) / 1000000; /* round up */ + /* apply shift and copy to output */ + out->min = min >> shift; + out->max = (max + ((1 << shift) - 1)) >> shift; /* round up */ +} + +/** + * img_ir_symbol_timing() - Convert symbol timing struct to register value. + * @timing: Symbol timing data + * @tolerance: Timing tolerance where 0-128 represents 0-100% + * @clock_hz: Frequency of source clock in Hz + * @pd_shift: Shift to apply to symbol period + * @w_shift: Shift to apply to symbol width + * + * Returns: Symbol timing register value based on arguments. + */ +static u32 img_ir_symbol_timing(const struct img_ir_symbol_timing *timing, + unsigned int tolerance, + unsigned long clock_hz, + unsigned int pd_shift, + unsigned int w_shift) +{ + struct img_ir_timing_range hw_pulse, hw_period; + /* we calculate period in hw_period, then convert in place */ + hw_period.min = timing->pulse.min + timing->space.min; + hw_period.max = timing->pulse.max + timing->space.max; + img_ir_timing_range_convert(&hw_period, &hw_period, + tolerance, clock_hz, pd_shift); + img_ir_timing_range_convert(&hw_pulse, &timing->pulse, + tolerance, clock_hz, w_shift); + /* construct register value */ + return (hw_period.max << IMG_IR_PD_MAX_SHIFT) | + (hw_period.min << IMG_IR_PD_MIN_SHIFT) | + (hw_pulse.max << IMG_IR_W_MAX_SHIFT) | + (hw_pulse.min << IMG_IR_W_MIN_SHIFT); +} + +/** + * img_ir_free_timing() - Convert free time timing struct to register value. + * @timing: Free symbol timing data + * @clock_hz: Source clock frequency in Hz + * + * Returns: Free symbol timing register value. + */ +static u32 img_ir_free_timing(const struct img_ir_free_timing *timing, + unsigned long clock_hz) +{ + unsigned int minlen, maxlen, ft_min; + /* minlen is only 5 bits, and round minlen to multiple of 2 */ + if (timing->minlen < 30) + minlen = timing->minlen & -2; + else + minlen = 30; + /* maxlen has maximum value of 48, and round maxlen to multiple of 2 */ + if (timing->maxlen < 48) + maxlen = (timing->maxlen + 1) & -2; + else + maxlen = 48; + /* convert and shift ft_min, rounding upwards */ + ft_min = (timing->ft_min*clock_hz + 999999) / 1000000; + ft_min = (ft_min + 7) >> 3; + /* construct register value */ + return (maxlen << IMG_IR_MAXLEN_SHIFT) | + (minlen << IMG_IR_MINLEN_SHIFT) | + (ft_min << IMG_IR_FT_MIN_SHIFT); +} + +/** + * img_ir_free_timing_dynamic() - Update free time register value. + * @st_ft: Static free time register value from img_ir_free_timing. + * @filter: Current filter which may additionally restrict min/max len. + * + * Returns: Updated free time register value based on the current filter. + */ +static u32 img_ir_free_timing_dynamic(u32 st_ft, struct img_ir_filter *filter) +{ + unsigned int minlen, maxlen, newminlen, newmaxlen; + + /* round minlen, maxlen to multiple of 2 */ + newminlen = filter->minlen & -2; + newmaxlen = (filter->maxlen + 1) & -2; + /* extract min/max len from register */ + minlen = (st_ft & IMG_IR_MINLEN) >> IMG_IR_MINLEN_SHIFT; + maxlen = (st_ft & IMG_IR_MAXLEN) >> IMG_IR_MAXLEN_SHIFT; + /* if the new values are more restrictive, update the register value */ + if (newminlen > minlen) { + st_ft &= ~IMG_IR_MINLEN; + st_ft |= newminlen << IMG_IR_MINLEN_SHIFT; + } + if (newmaxlen < maxlen) { + st_ft &= ~IMG_IR_MAXLEN; + st_ft |= newmaxlen << IMG_IR_MAXLEN_SHIFT; + } + return st_ft; +} + +/** + * img_ir_timings_convert() - Convert timings to register values + * @regs: Output timing register values + * @timings: Input timing data + * @tolerance: Timing tolerance where 0-128 represents 0-100% + * @clock_hz: Source clock frequency in Hz + */ +static void img_ir_timings_convert(struct img_ir_timing_regvals *regs, + const struct img_ir_timings *timings, + unsigned int tolerance, + unsigned int clock_hz) +{ + /* leader symbol timings are divided by 16 */ + regs->ldr = img_ir_symbol_timing(&timings->ldr, tolerance, clock_hz, + 4, 4); + /* other symbol timings, pd fields only are divided by 2 */ + regs->s00 = img_ir_symbol_timing(&timings->s00, tolerance, clock_hz, + 1, 0); + regs->s01 = img_ir_symbol_timing(&timings->s01, tolerance, clock_hz, + 1, 0); + regs->s10 = img_ir_symbol_timing(&timings->s10, tolerance, clock_hz, + 1, 0); + regs->s11 = img_ir_symbol_timing(&timings->s11, tolerance, clock_hz, + 1, 0); + regs->ft = img_ir_free_timing(&timings->ft, clock_hz); +} + +/** + * img_ir_decoder_preprocess() - Preprocess timings in decoder. + * @decoder: Decoder to be preprocessed. + * + * Ensures that the symbol timing ranges are valid with respect to ordering, and + * does some fixed conversion on them. + */ +static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder) +{ + /* default tolerance */ + if (!decoder->tolerance) + decoder->tolerance = 10; /* percent */ + /* and convert tolerance to fraction out of 128 */ + decoder->tolerance = decoder->tolerance * 128 / 100; + + /* fill in implicit fields */ + img_ir_timings_preprocess(&decoder->timings, decoder->unit); + + /* do the same for repeat timings if applicable */ + if (decoder->repeat) { + img_ir_timings_preprocess(&decoder->rtimings, decoder->unit); + img_ir_timings_defaults(&decoder->rtimings, &decoder->timings); + } +} + +/** + * img_ir_decoder_convert() - Generate internal timings in decoder. + * @decoder: Decoder to be converted to internal timings. + * @timings: Timing register values. + * @clock_hz: IR clock rate in Hz. + * + * Fills out the repeat timings and timing register values for a specific clock + * rate. + */ +static void img_ir_decoder_convert(const struct img_ir_decoder *decoder, + struct img_ir_reg_timings *reg_timings, + unsigned int clock_hz) +{ + /* calculate control value */ + reg_timings->ctrl = img_ir_control(&decoder->control); + + /* fill in implicit fields and calculate register values */ + img_ir_timings_convert(®_timings->timings, &decoder->timings, + decoder->tolerance, clock_hz); + + /* do the same for repeat timings if applicable */ + if (decoder->repeat) + img_ir_timings_convert(®_timings->rtimings, + &decoder->rtimings, decoder->tolerance, + clock_hz); +} + +/** + * img_ir_write_timings() - Write timings to the hardware now + * @priv: IR private data + * @regs: Timing register values to write + * @type: RC filter type (RC_FILTER_*) + * + * Write timing register values @regs to the hardware, taking into account the + * current filter which may impose restrictions on the length of the expected + * data. + */ +static void img_ir_write_timings(struct img_ir_priv *priv, + struct img_ir_timing_regvals *regs, + enum rc_filter_type type) +{ + struct img_ir_priv_hw *hw = &priv->hw; + + /* filter may be more restrictive to minlen, maxlen */ + u32 ft = regs->ft; + if (hw->flags & BIT(type)) + ft = img_ir_free_timing_dynamic(regs->ft, &hw->filters[type]); + /* write to registers */ + img_ir_write(priv, IMG_IR_LEAD_SYMB_TIMING, regs->ldr); + img_ir_write(priv, IMG_IR_S00_SYMB_TIMING, regs->s00); + img_ir_write(priv, IMG_IR_S01_SYMB_TIMING, regs->s01); + img_ir_write(priv, IMG_IR_S10_SYMB_TIMING, regs->s10); + img_ir_write(priv, IMG_IR_S11_SYMB_TIMING, regs->s11); + img_ir_write(priv, IMG_IR_FREE_SYMB_TIMING, ft); + dev_dbg(priv->dev, "timings: ldr=%#x, s=[%#x, %#x, %#x, %#x], ft=%#x\n", + regs->ldr, regs->s00, regs->s01, regs->s10, regs->s11, ft); +} + +static void img_ir_write_filter(struct img_ir_priv *priv, + struct img_ir_filter *filter) +{ + if (filter) { + dev_dbg(priv->dev, "IR filter=%016llx & %016llx\n", + (unsigned long long)filter->data, + (unsigned long long)filter->mask); + img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_LW, (u32)filter->data); + img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_UP, (u32)(filter->data + >> 32)); + img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, (u32)filter->mask); + img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, (u32)(filter->mask + >> 32)); + } else { + dev_dbg(priv->dev, "IR clearing filter\n"); + img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, 0); + img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, 0); + } +} + +/* caller must have lock */ +static void _img_ir_set_filter(struct img_ir_priv *priv, + struct img_ir_filter *filter) +{ + struct img_ir_priv_hw *hw = &priv->hw; + u32 irq_en, irq_on; + + irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); + if (filter) { + /* Only use the match interrupt */ + hw->filters[RC_FILTER_NORMAL] = *filter; + hw->flags |= IMG_IR_F_FILTER; + irq_on = IMG_IR_IRQ_DATA_MATCH; + irq_en &= ~(IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID); + } else { + /* Only use the valid interrupt */ + hw->flags &= ~IMG_IR_F_FILTER; + irq_en &= ~IMG_IR_IRQ_DATA_MATCH; + irq_on = IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID; + } + irq_en |= irq_on; + + img_ir_write_filter(priv, filter); + /* clear any interrupts we're enabling so we don't handle old ones */ + img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_on); + img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en); +} + +/* caller must have lock */ +static void _img_ir_set_wake_filter(struct img_ir_priv *priv, + struct img_ir_filter *filter) +{ + struct img_ir_priv_hw *hw = &priv->hw; + if (filter) { + /* Enable wake, and copy filter for later */ + hw->filters[RC_FILTER_WAKEUP] = *filter; + hw->flags |= IMG_IR_F_WAKE; + } else { + /* Disable wake */ + hw->flags &= ~IMG_IR_F_WAKE; + } +} + +/* Callback for setting scancode filter */ +static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type, + struct rc_scancode_filter *sc_filter) +{ + struct img_ir_priv *priv = dev->priv; + struct img_ir_priv_hw *hw = &priv->hw; + struct img_ir_filter filter, *filter_ptr = &filter; + int ret = 0; + + dev_dbg(priv->dev, "IR scancode %sfilter=%08x & %08x\n", + type == RC_FILTER_WAKEUP ? "wake " : "", + sc_filter->data, + sc_filter->mask); + + spin_lock_irq(&priv->lock); + + /* filtering can always be disabled */ + if (!sc_filter->mask) { + filter_ptr = NULL; + goto set_unlock; + } + + /* current decoder must support scancode filtering */ + if (!hw->decoder || !hw->decoder->filter) { + ret = -EINVAL; + goto unlock; + } + + /* convert scancode filter to raw filter */ + filter.minlen = 0; + filter.maxlen = ~0; + ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols); + if (ret) + goto unlock; + dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n", + type == RC_FILTER_WAKEUP ? "wake " : "", + (unsigned long long)filter.data, + (unsigned long long)filter.mask); + +set_unlock: + /* apply raw filters */ + switch (type) { + case RC_FILTER_NORMAL: + _img_ir_set_filter(priv, filter_ptr); + break; + case RC_FILTER_WAKEUP: + _img_ir_set_wake_filter(priv, filter_ptr); + break; + default: + ret = -EINVAL; + } + +unlock: + spin_unlock_irq(&priv->lock); + return ret; +} + +static int img_ir_set_normal_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter); +} + +static int img_ir_set_wakeup_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter); +} + +/** + * img_ir_set_decoder() - Set the current decoder. + * @priv: IR private data. + * @decoder: Decoder to use with immediate effect. + * @proto: Protocol bitmap (or 0 to use decoder->type). + */ +static void img_ir_set_decoder(struct img_ir_priv *priv, + const struct img_ir_decoder *decoder, + u64 proto) +{ + struct img_ir_priv_hw *hw = &priv->hw; + struct rc_dev *rdev = hw->rdev; + u32 ir_status, irq_en; + spin_lock_irq(&priv->lock); + + /* switch off and disable interrupts */ + img_ir_write(priv, IMG_IR_CONTROL, 0); + irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); + img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en & IMG_IR_IRQ_EDGE); + img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_ALL & ~IMG_IR_IRQ_EDGE); + + /* ack any data already detected */ + ir_status = img_ir_read(priv, IMG_IR_STATUS); + if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) { + ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2); + img_ir_write(priv, IMG_IR_STATUS, ir_status); + img_ir_read(priv, IMG_IR_DATA_LW); + img_ir_read(priv, IMG_IR_DATA_UP); + } + + /* stop the end timer and switch back to normal mode */ + del_timer_sync(&hw->end_timer); + hw->mode = IMG_IR_M_NORMAL; + + /* clear the wakeup scancode filter */ + rdev->scancode_filters[RC_FILTER_WAKEUP].data = 0; + rdev->scancode_filters[RC_FILTER_WAKEUP].mask = 0; + + /* clear raw filters */ + _img_ir_set_filter(priv, NULL); + _img_ir_set_wake_filter(priv, NULL); + + /* clear the enabled protocols */ + hw->enabled_protocols = 0; + + /* switch decoder */ + hw->decoder = decoder; + if (!decoder) + goto unlock; + + /* set the enabled protocols */ + if (!proto) + proto = decoder->type; + hw->enabled_protocols = proto; + + /* write the new timings */ + img_ir_decoder_convert(decoder, &hw->reg_timings, hw->clk_hz); + img_ir_write_timings(priv, &hw->reg_timings.timings, RC_FILTER_NORMAL); + + /* set up and enable */ + img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); + + +unlock: + spin_unlock_irq(&priv->lock); +} + +/** + * img_ir_decoder_compatable() - Find whether a decoder will work with a device. + * @priv: IR private data. + * @dec: Decoder to check. + * + * Returns: true if @dec is compatible with the device @priv refers to. + */ +static bool img_ir_decoder_compatible(struct img_ir_priv *priv, + const struct img_ir_decoder *dec) +{ + unsigned int ct; + + /* don't accept decoders using code types which aren't supported */ + ct = dec->control.code_type; + if (priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_BROKEN) + return false; + + return true; +} + +/** + * img_ir_allowed_protos() - Get allowed protocols from global decoder list. + * @priv: IR private data. + * + * Returns: Mask of protocols supported by the device @priv refers to. + */ +static u64 img_ir_allowed_protos(struct img_ir_priv *priv) +{ + u64 protos = 0; + struct img_ir_decoder **decp; + + for (decp = img_ir_decoders; *decp; ++decp) { + const struct img_ir_decoder *dec = *decp; + if (img_ir_decoder_compatible(priv, dec)) + protos |= dec->type; + } + return protos; +} + +/* Callback for changing protocol using sysfs */ +static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type) +{ + struct img_ir_priv *priv = dev->priv; + struct img_ir_priv_hw *hw = &priv->hw; + struct rc_dev *rdev = hw->rdev; + struct img_ir_decoder **decp; + u64 wakeup_protocols; + + if (!*ir_type) { + /* disable all protocols */ + img_ir_set_decoder(priv, NULL, 0); + goto success; + } + for (decp = img_ir_decoders; *decp; ++decp) { + const struct img_ir_decoder *dec = *decp; + if (!img_ir_decoder_compatible(priv, dec)) + continue; + if (*ir_type & dec->type) { + *ir_type &= dec->type; + img_ir_set_decoder(priv, dec, *ir_type); + goto success; + } + } + return -EINVAL; + +success: + /* + * Only allow matching wakeup protocols for now, and only if filtering + * is supported. + */ + wakeup_protocols = *ir_type; + if (!hw->decoder || !hw->decoder->filter) + wakeup_protocols = 0; + rc_set_allowed_wakeup_protocols(rdev, wakeup_protocols); + rc_set_enabled_wakeup_protocols(rdev, wakeup_protocols); + return 0; +} + +/* Changes ir-core protocol device attribute */ +static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto) +{ + struct rc_dev *rdev = priv->hw.rdev; + + spin_lock_irq(&rdev->rc_map.lock); + rdev->rc_map.rc_type = __ffs64(proto); + spin_unlock_irq(&rdev->rc_map.lock); + + mutex_lock(&rdev->lock); + rc_set_enabled_protocols(rdev, proto); + rc_set_allowed_wakeup_protocols(rdev, proto); + rc_set_enabled_wakeup_protocols(rdev, proto); + mutex_unlock(&rdev->lock); +} + +/* Set up IR decoders */ +static void img_ir_init_decoders(void) +{ + struct img_ir_decoder **decp; + + spin_lock(&img_ir_decoders_lock); + if (!img_ir_decoders_preprocessed) { + for (decp = img_ir_decoders; *decp; ++decp) + img_ir_decoder_preprocess(*decp); + img_ir_decoders_preprocessed = true; + } + spin_unlock(&img_ir_decoders_lock); +} + +#ifdef CONFIG_PM_SLEEP +/** + * img_ir_enable_wake() - Switch to wake mode. + * @priv: IR private data. + * + * Returns: non-zero if the IR can wake the system. + */ +static int img_ir_enable_wake(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + int ret = 0; + + spin_lock_irq(&priv->lock); + if (hw->flags & IMG_IR_F_WAKE) { + /* interrupt only on a match */ + hw->suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE); + img_ir_write(priv, IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_DATA_MATCH); + img_ir_write_filter(priv, &hw->filters[RC_FILTER_WAKEUP]); + img_ir_write_timings(priv, &hw->reg_timings.timings, + RC_FILTER_WAKEUP); + hw->mode = IMG_IR_M_WAKE; + ret = 1; + } + spin_unlock_irq(&priv->lock); + return ret; +} + +/** + * img_ir_disable_wake() - Switch out of wake mode. + * @priv: IR private data + * + * Returns: 1 if the hardware should be allowed to wake from a sleep state. + * 0 otherwise. + */ +static int img_ir_disable_wake(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + int ret = 0; + + spin_lock_irq(&priv->lock); + if (hw->flags & IMG_IR_F_WAKE) { + /* restore normal filtering */ + if (hw->flags & IMG_IR_F_FILTER) { + img_ir_write(priv, IMG_IR_IRQ_ENABLE, + (hw->suspend_irqen & IMG_IR_IRQ_EDGE) | + IMG_IR_IRQ_DATA_MATCH); + img_ir_write_filter(priv, + &hw->filters[RC_FILTER_NORMAL]); + } else { + img_ir_write(priv, IMG_IR_IRQ_ENABLE, + (hw->suspend_irqen & IMG_IR_IRQ_EDGE) | + IMG_IR_IRQ_DATA_VALID | + IMG_IR_IRQ_DATA2_VALID); + img_ir_write_filter(priv, NULL); + } + img_ir_write_timings(priv, &hw->reg_timings.timings, + RC_FILTER_NORMAL); + hw->mode = IMG_IR_M_NORMAL; + ret = 1; + } + spin_unlock_irq(&priv->lock); + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +/* lock must be held */ +static void img_ir_begin_repeat(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + if (hw->mode == IMG_IR_M_NORMAL) { + /* switch to repeat timings */ + img_ir_write(priv, IMG_IR_CONTROL, 0); + hw->mode = IMG_IR_M_REPEATING; + img_ir_write_timings(priv, &hw->reg_timings.rtimings, + RC_FILTER_NORMAL); + img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); + } +} + +/* lock must be held */ +static void img_ir_end_repeat(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + if (hw->mode == IMG_IR_M_REPEATING) { + /* switch to normal timings */ + img_ir_write(priv, IMG_IR_CONTROL, 0); + hw->mode = IMG_IR_M_NORMAL; + img_ir_write_timings(priv, &hw->reg_timings.timings, + RC_FILTER_NORMAL); + img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl); + } +} + +/* lock must be held */ +static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) +{ + struct img_ir_priv_hw *hw = &priv->hw; + const struct img_ir_decoder *dec = hw->decoder; + int ret = IMG_IR_SCANCODE; + int scancode; + if (dec->scancode) + ret = dec->scancode(len, raw, &scancode, hw->enabled_protocols); + else if (len >= 32) + scancode = (u32)raw; + else if (len < 32) + scancode = (u32)raw & ((1 << len)-1); + dev_dbg(priv->dev, "data (%u bits) = %#llx\n", + len, (unsigned long long)raw); + if (ret == IMG_IR_SCANCODE) { + dev_dbg(priv->dev, "decoded scan code %#x\n", scancode); + rc_keydown(hw->rdev, scancode, 0); + img_ir_end_repeat(priv); + } else if (ret == IMG_IR_REPEATCODE) { + if (hw->mode == IMG_IR_M_REPEATING) { + dev_dbg(priv->dev, "decoded repeat code\n"); + rc_repeat(hw->rdev); + } else { + dev_dbg(priv->dev, "decoded unexpected repeat code, ignoring\n"); + } + } else { + dev_dbg(priv->dev, "decode failed (%d)\n", ret); + return; + } + + + if (dec->repeat) { + unsigned long interval; + + img_ir_begin_repeat(priv); + + /* update timer, but allowing for 1/8th tolerance */ + interval = dec->repeat + (dec->repeat >> 3); + mod_timer(&hw->end_timer, + jiffies + msecs_to_jiffies(interval)); + } +} + +/* timer function to end waiting for repeat. */ +static void img_ir_end_timer(unsigned long arg) +{ + struct img_ir_priv *priv = (struct img_ir_priv *)arg; + + spin_lock_irq(&priv->lock); + img_ir_end_repeat(priv); + spin_unlock_irq(&priv->lock); +} + +#ifdef CONFIG_COMMON_CLK +static void img_ir_change_frequency(struct img_ir_priv *priv, + struct clk_notifier_data *change) +{ + struct img_ir_priv_hw *hw = &priv->hw; + + dev_dbg(priv->dev, "clk changed %lu HZ -> %lu HZ\n", + change->old_rate, change->new_rate); + + spin_lock_irq(&priv->lock); + if (hw->clk_hz == change->new_rate) + goto unlock; + hw->clk_hz = change->new_rate; + /* refresh current timings */ + if (hw->decoder) { + img_ir_decoder_convert(hw->decoder, &hw->reg_timings, + hw->clk_hz); + switch (hw->mode) { + case IMG_IR_M_NORMAL: + img_ir_write_timings(priv, &hw->reg_timings.timings, + RC_FILTER_NORMAL); + break; + case IMG_IR_M_REPEATING: + img_ir_write_timings(priv, &hw->reg_timings.rtimings, + RC_FILTER_NORMAL); + break; +#ifdef CONFIG_PM_SLEEP + case IMG_IR_M_WAKE: + img_ir_write_timings(priv, &hw->reg_timings.timings, + RC_FILTER_WAKEUP); + break; +#endif + } + } +unlock: + spin_unlock_irq(&priv->lock); +} + +static int img_ir_clk_notify(struct notifier_block *self, unsigned long action, + void *data) +{ + struct img_ir_priv *priv = container_of(self, struct img_ir_priv, + hw.clk_nb); + switch (action) { + case POST_RATE_CHANGE: + img_ir_change_frequency(priv, data); + break; + default: + break; + } + return NOTIFY_OK; +} +#endif /* CONFIG_COMMON_CLK */ + +/* called with priv->lock held */ +void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) +{ + struct img_ir_priv_hw *hw = &priv->hw; + u32 ir_status, len, lw, up; + unsigned int ct; + + /* use the current decoder */ + if (!hw->decoder) + return; + + ir_status = img_ir_read(priv, IMG_IR_STATUS); + if (!(ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) + return; + ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2); + img_ir_write(priv, IMG_IR_STATUS, ir_status); + + len = (ir_status & IMG_IR_RXDLEN) >> IMG_IR_RXDLEN_SHIFT; + /* some versions report wrong length for certain code types */ + ct = hw->decoder->control.code_type; + if (hw->ct_quirks[ct] & IMG_IR_QUIRK_CODE_LEN_INCR) + ++len; + + lw = img_ir_read(priv, IMG_IR_DATA_LW); + up = img_ir_read(priv, IMG_IR_DATA_UP); + img_ir_handle_data(priv, len, (u64)up << 32 | lw); +} + +void img_ir_setup_hw(struct img_ir_priv *priv) +{ + struct img_ir_decoder **decp; + + if (!priv->hw.rdev) + return; + + /* Use the first available decoder (or disable stuff if NULL) */ + for (decp = img_ir_decoders; *decp; ++decp) { + const struct img_ir_decoder *dec = *decp; + if (img_ir_decoder_compatible(priv, dec)) { + img_ir_set_protocol(priv, dec->type); + img_ir_set_decoder(priv, dec, 0); + return; + } + } + img_ir_set_decoder(priv, NULL, 0); +} + +/** + * img_ir_probe_hw_caps() - Probe capabilities of the hardware. + * @priv: IR private data. + */ +static void img_ir_probe_hw_caps(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + /* + * When a version of the block becomes available without these quirks, + * they'll have to depend on the core revision. + */ + hw->ct_quirks[IMG_IR_CODETYPE_PULSELEN] + |= IMG_IR_QUIRK_CODE_LEN_INCR; + hw->ct_quirks[IMG_IR_CODETYPE_BIPHASE] + |= IMG_IR_QUIRK_CODE_BROKEN; + hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS] + |= IMG_IR_QUIRK_CODE_BROKEN; +} + +int img_ir_probe_hw(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + struct rc_dev *rdev; + int error; + + /* Ensure hardware decoders have been preprocessed */ + img_ir_init_decoders(); + + /* Probe hardware capabilities */ + img_ir_probe_hw_caps(priv); + + /* Set up the end timer */ + setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv); + + /* Register a clock notifier */ + if (!IS_ERR(priv->clk)) { + hw->clk_hz = clk_get_rate(priv->clk); +#ifdef CONFIG_COMMON_CLK + hw->clk_nb.notifier_call = img_ir_clk_notify; + error = clk_notifier_register(priv->clk, &hw->clk_nb); + if (error) + dev_warn(priv->dev, + "failed to register clock notifier\n"); +#endif + } else { + hw->clk_hz = 32768; + } + + /* Allocate hardware decoder */ + hw->rdev = rdev = rc_allocate_device(); + if (!rdev) { + dev_err(priv->dev, "cannot allocate input device\n"); + error = -ENOMEM; + goto err_alloc_rc; + } + rdev->priv = priv; + rdev->map_name = RC_MAP_EMPTY; + rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv)); + rdev->input_name = "IMG Infrared Decoder"; + rdev->s_filter = img_ir_set_normal_filter; + rdev->s_wakeup_filter = img_ir_set_wakeup_filter; + + /* Register hardware decoder */ + error = rc_register_device(rdev); + if (error) { + dev_err(priv->dev, "failed to register IR input device\n"); + goto err_register_rc; + } + + /* + * Set this after rc_register_device as no protocols have been + * registered yet. + */ + rdev->change_protocol = img_ir_change_protocol; + + device_init_wakeup(priv->dev, 1); + + return 0; + +err_register_rc: + img_ir_set_decoder(priv, NULL, 0); + hw->rdev = NULL; + rc_free_device(rdev); +err_alloc_rc: +#ifdef CONFIG_COMMON_CLK + if (!IS_ERR(priv->clk)) + clk_notifier_unregister(priv->clk, &hw->clk_nb); +#endif + return error; +} + +void img_ir_remove_hw(struct img_ir_priv *priv) +{ + struct img_ir_priv_hw *hw = &priv->hw; + struct rc_dev *rdev = hw->rdev; + if (!rdev) + return; + img_ir_set_decoder(priv, NULL, 0); + hw->rdev = NULL; + rc_unregister_device(rdev); +#ifdef CONFIG_COMMON_CLK + if (!IS_ERR(priv->clk)) + clk_notifier_unregister(priv->clk, &hw->clk_nb); +#endif +} + +#ifdef CONFIG_PM_SLEEP +int img_ir_suspend(struct device *dev) +{ + struct img_ir_priv *priv = dev_get_drvdata(dev); + + if (device_may_wakeup(dev) && img_ir_enable_wake(priv)) + enable_irq_wake(priv->irq); + return 0; +} + +int img_ir_resume(struct device *dev) +{ + struct img_ir_priv *priv = dev_get_drvdata(dev); + + if (device_may_wakeup(dev) && img_ir_disable_wake(priv)) + disable_irq_wake(priv->irq); + return 0; +} +#endif /* CONFIG_PM_SLEEP */ diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h new file mode 100644 index 000000000000..6c9a94a81190 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-hw.h @@ -0,0 +1,269 @@ +/* + * ImgTec IR Hardware Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + */ + +#ifndef _IMG_IR_HW_H_ +#define _IMG_IR_HW_H_ + +#include <linux/kernel.h> +#include <media/rc-core.h> + +/* constants */ + +#define IMG_IR_CODETYPE_PULSELEN 0x0 /* Sony */ +#define IMG_IR_CODETYPE_PULSEDIST 0x1 /* NEC, Toshiba, Micom, Sharp */ +#define IMG_IR_CODETYPE_BIPHASE 0x2 /* RC-5/6 */ +#define IMG_IR_CODETYPE_2BITPULSEPOS 0x3 /* RC-MM */ + + +/* Timing information */ + +/** + * struct img_ir_control - Decoder control settings + * @decoden: Primary decoder enable + * @code_type: Decode type (see IMG_IR_CODETYPE_*) + * @hdrtog: Detect header toggle symbol after leader symbol + * @ldrdec: Don't discard leader if maximum width reached + * @decodinpol: Decoder input polarity (1=active high) + * @bitorien: Bit orientation (1=MSB first) + * @d1validsel: Decoder 2 takes over if it detects valid data + * @bitinv: Bit inversion switch (1=don't invert) + * @decodend2: Secondary decoder enable (no leader symbol) + * @bitoriend2: Bit orientation (1=MSB first) + * @bitinvd2: Secondary decoder bit inversion switch (1=don't invert) + */ +struct img_ir_control { + unsigned decoden:1; + unsigned code_type:2; + unsigned hdrtog:1; + unsigned ldrdec:1; + unsigned decodinpol:1; + unsigned bitorien:1; + unsigned d1validsel:1; + unsigned bitinv:1; + unsigned decodend2:1; + unsigned bitoriend2:1; + unsigned bitinvd2:1; +}; + +/** + * struct img_ir_timing_range - range of timing values + * @min: Minimum timing value + * @max: Maximum timing value (if < @min, this will be set to @min during + * preprocessing step, so it is normally not explicitly initialised + * and is taken care of by the tolerance) + */ +struct img_ir_timing_range { + u16 min; + u16 max; +}; + +/** + * struct img_ir_symbol_timing - timing data for a symbol + * @pulse: Timing range for the length of the pulse in this symbol + * @space: Timing range for the length of the space in this symbol + */ +struct img_ir_symbol_timing { + struct img_ir_timing_range pulse; + struct img_ir_timing_range space; +}; + +/** + * struct img_ir_free_timing - timing data for free time symbol + * @minlen: Minimum number of bits of data + * @maxlen: Maximum number of bits of data + * @ft_min: Minimum free time after message + */ +struct img_ir_free_timing { + /* measured in bits */ + u8 minlen; + u8 maxlen; + u16 ft_min; +}; + +/** + * struct img_ir_timings - Timing values. + * @ldr: Leader symbol timing data + * @s00: Zero symbol timing data for primary decoder + * @s01: One symbol timing data for primary decoder + * @s10: Zero symbol timing data for secondary (no leader symbol) decoder + * @s11: One symbol timing data for secondary (no leader symbol) decoder + * @ft: Free time symbol timing data + */ +struct img_ir_timings { + struct img_ir_symbol_timing ldr, s00, s01, s10, s11; + struct img_ir_free_timing ft; +}; + +/** + * struct img_ir_filter - Filter IR events. + * @data: Data to match. + * @mask: Mask of bits to compare. + * @minlen: Additional minimum number of bits. + * @maxlen: Additional maximum number of bits. + */ +struct img_ir_filter { + u64 data; + u64 mask; + u8 minlen; + u8 maxlen; +}; + +/** + * struct img_ir_timing_regvals - Calculated timing register values. + * @ldr: Leader symbol timing register value + * @s00: Zero symbol timing register value for primary decoder + * @s01: One symbol timing register value for primary decoder + * @s10: Zero symbol timing register value for secondary decoder + * @s11: One symbol timing register value for secondary decoder + * @ft: Free time symbol timing register value + */ +struct img_ir_timing_regvals { + u32 ldr, s00, s01, s10, s11, ft; +}; + +#define IMG_IR_SCANCODE 0 /* new scancode */ +#define IMG_IR_REPEATCODE 1 /* repeat the previous code */ + +/** + * struct img_ir_decoder - Decoder settings for an IR protocol. + * @type: Protocol types bitmap. + * @tolerance: Timing tolerance as a percentage (default 10%). + * @unit: Unit of timings in nanoseconds (default 1 us). + * @timings: Primary timings + * @rtimings: Additional override timings while waiting for repeats. + * @repeat: Maximum repeat interval (always in milliseconds). + * @control: Control flags. + * + * @scancode: Pointer to function to convert the IR data into a scancode (it + * must be safe to execute in interrupt context). + * Returns IMG_IR_SCANCODE to emit new scancode. + * Returns IMG_IR_REPEATCODE to repeat previous code. + * Returns -errno (e.g. -EINVAL) on error. + * @filter: Pointer to function to convert scancode filter to raw hardware + * filter. The minlen and maxlen fields will have been initialised + * to the maximum range. + */ +struct img_ir_decoder { + /* core description */ + u64 type; + unsigned int tolerance; + unsigned int unit; + struct img_ir_timings timings; + struct img_ir_timings rtimings; + unsigned int repeat; + struct img_ir_control control; + + /* scancode logic */ + int (*scancode)(int len, u64 raw, int *scancode, u64 protocols); + int (*filter)(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols); +}; + +/** + * struct img_ir_reg_timings - Reg values for decoder timings at clock rate. + * @ctrl: Processed control register value. + * @timings: Processed primary timings. + * @rtimings: Processed repeat timings. + */ +struct img_ir_reg_timings { + u32 ctrl; + struct img_ir_timing_regvals timings; + struct img_ir_timing_regvals rtimings; +}; + +int img_ir_register_decoder(struct img_ir_decoder *dec); +void img_ir_unregister_decoder(struct img_ir_decoder *dec); + +struct img_ir_priv; + +#ifdef CONFIG_IR_IMG_HW + +enum img_ir_mode { + IMG_IR_M_NORMAL, + IMG_IR_M_REPEATING, +#ifdef CONFIG_PM_SLEEP + IMG_IR_M_WAKE, +#endif +}; + +/** + * struct img_ir_priv_hw - Private driver data for hardware decoder. + * @ct_quirks: Quirk bits for each code type. + * @rdev: Remote control device + * @clk_nb: Notifier block for clock notify events. + * @end_timer: Timer until repeat timeout. + * @decoder: Current decoder settings. + * @enabled_protocols: Currently enabled protocols. + * @clk_hz: Current core clock rate in Hz. + * @reg_timings: Timing reg values for decoder at clock rate. + * @flags: IMG_IR_F_*. + * @filters: HW filters (derived from scancode filters). + * @mode: Current decode mode. + * @suspend_irqen: Saved IRQ enable mask over suspend. + */ +struct img_ir_priv_hw { + unsigned int ct_quirks[4]; + struct rc_dev *rdev; + struct notifier_block clk_nb; + struct timer_list end_timer; + const struct img_ir_decoder *decoder; + u64 enabled_protocols; + unsigned long clk_hz; + struct img_ir_reg_timings reg_timings; + unsigned int flags; + struct img_ir_filter filters[RC_FILTER_MAX]; + + enum img_ir_mode mode; + u32 suspend_irqen; +}; + +static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) +{ + return hw->rdev; +}; + +void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status); +void img_ir_setup_hw(struct img_ir_priv *priv); +int img_ir_probe_hw(struct img_ir_priv *priv); +void img_ir_remove_hw(struct img_ir_priv *priv); + +#ifdef CONFIG_PM_SLEEP +int img_ir_suspend(struct device *dev); +int img_ir_resume(struct device *dev); +#else +#define img_ir_suspend NULL +#define img_ir_resume NULL +#endif + +#else + +struct img_ir_priv_hw { +}; + +static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) +{ + return false; +}; +static inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) +{ +} +static inline void img_ir_setup_hw(struct img_ir_priv *priv) +{ +} +static inline int img_ir_probe_hw(struct img_ir_priv *priv) +{ + return -ENODEV; +} +static inline void img_ir_remove_hw(struct img_ir_priv *priv) +{ +} + +#define img_ir_suspend NULL +#define img_ir_resume NULL + +#endif /* CONFIG_IR_IMG_HW */ + +#endif /* _IMG_IR_HW_H_ */ diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c b/drivers/media/rc/img-ir/img-ir-jvc.c new file mode 100644 index 000000000000..10209d200efb --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-jvc.c @@ -0,0 +1,81 @@ +/* + * ImgTec IR Decoder setup for JVC protocol. + * + * Copyright 2012-2014 Imagination Technologies Ltd. + */ + +#include "img-ir-hw.h" + +/* Convert JVC data to a scancode */ +static int img_ir_jvc_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int cust, data; + + if (len != 16) + return -EINVAL; + + cust = (raw >> 0) & 0xff; + data = (raw >> 8) & 0xff; + + *scancode = cust << 8 | data; + return IMG_IR_SCANCODE; +} + +/* Convert JVC scancode to JVC data filter */ +static int img_ir_jvc_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int cust, data; + unsigned int cust_m, data_m; + + cust = (in->data >> 8) & 0xff; + cust_m = (in->mask >> 8) & 0xff; + data = (in->data >> 0) & 0xff; + data_m = (in->mask >> 0) & 0xff; + + out->data = cust | data << 8; + out->mask = cust_m | data_m << 8; + + return 0; +} + +/* + * JVC decoder + * See also http://www.sbprojects.com/knowledge/ir/jvc.php + * http://support.jvc.com/consumer/support/documents/RemoteCodes.pdf + */ +struct img_ir_decoder img_ir_jvc = { + .type = RC_BIT_JVC, + .control = { + .decoden = 1, + .code_type = IMG_IR_CODETYPE_PULSEDIST, + }, + /* main timings */ + .unit = 527500, /* 527.5 us */ + .timings = { + /* leader symbol */ + .ldr = { + .pulse = { 16 /* 8.44 ms */ }, + .space = { 8 /* 4.22 ms */ }, + }, + /* 0 symbol */ + .s00 = { + .pulse = { 1 /* 527.5 us +-60 us */ }, + .space = { 1 /* 527.5 us */ }, + }, + /* 1 symbol */ + .s01 = { + .pulse = { 1 /* 527.5 us +-60 us */ }, + .space = { 3 /* 1.5825 ms +-40 us */ }, + }, + /* free time */ + .ft = { + .minlen = 16, + .maxlen = 16, + .ft_min = 10, /* 5.275 ms */ + }, + }, + /* scancode logic */ + .scancode = img_ir_jvc_scancode, + .filter = img_ir_jvc_filter, +}; diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c new file mode 100644 index 000000000000..751d9d945269 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-nec.c @@ -0,0 +1,151 @@ +/* + * ImgTec IR Decoder setup for NEC protocol. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + */ + +#include "img-ir-hw.h" +#include <linux/bitrev.h> + +/* Convert NEC data to a scancode */ +static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + /* a repeat code has no data */ + if (!len) + return IMG_IR_REPEATCODE; + if (len != 32) + return -EINVAL; + /* raw encoding: ddDDaaAA */ + addr = (raw >> 0) & 0xff; + addr_inv = (raw >> 8) & 0xff; + data = (raw >> 16) & 0xff; + data_inv = (raw >> 24) & 0xff; + if ((data_inv ^ data) != 0xff) { + /* 32-bit NEC (used by Apple and TiVo remotes) */ + /* scan encoding: as transmitted, MSBit = first received bit */ + *scancode = bitrev8(addr) << 24 | + bitrev8(addr_inv) << 16 | + bitrev8(data) << 8 | + bitrev8(data_inv); + } else if ((addr_inv ^ addr) != 0xff) { + /* Extended NEC */ + /* scan encoding: AAaaDD */ + *scancode = addr << 16 | + addr_inv << 8 | + data; + } else { + /* Normal NEC */ + /* scan encoding: AADD */ + *scancode = addr << 8 | + data; + } + return IMG_IR_SCANCODE; +} + +/* Convert NEC scancode to NEC data filter */ +static int img_ir_nec_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + unsigned int addr_m, addr_inv_m, data_m, data_inv_m; + + data = in->data & 0xff; + data_m = in->mask & 0xff; + + if ((in->data | in->mask) & 0xff000000) { + /* 32-bit NEC (used by Apple and TiVo remotes) */ + /* scan encoding: as transmitted, MSBit = first received bit */ + addr = bitrev8(in->data >> 24); + addr_m = bitrev8(in->mask >> 24); + addr_inv = bitrev8(in->data >> 16); + addr_inv_m = bitrev8(in->mask >> 16); + data = bitrev8(in->data >> 8); + data_m = bitrev8(in->mask >> 8); + data_inv = bitrev8(in->data >> 0); + data_inv_m = bitrev8(in->mask >> 0); + } else if ((in->data | in->mask) & 0x00ff0000) { + /* Extended NEC */ + /* scan encoding AAaaDD */ + addr = (in->data >> 16) & 0xff; + addr_m = (in->mask >> 16) & 0xff; + addr_inv = (in->data >> 8) & 0xff; + addr_inv_m = (in->mask >> 8) & 0xff; + data_inv = data ^ 0xff; + data_inv_m = data_m; + } else { + /* Normal NEC */ + /* scan encoding: AADD */ + addr = (in->data >> 8) & 0xff; + addr_m = (in->mask >> 8) & 0xff; + addr_inv = addr ^ 0xff; + addr_inv_m = addr_m; + data_inv = data ^ 0xff; + data_inv_m = data_m; + } + + /* raw encoding: ddDDaaAA */ + out->data = data_inv << 24 | + data << 16 | + addr_inv << 8 | + addr; + out->mask = data_inv_m << 24 | + data_m << 16 | + addr_inv_m << 8 | + addr_m; + return 0; +} + +/* + * NEC decoder + * See also http://www.sbprojects.com/knowledge/ir/nec.php + * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol + */ +struct img_ir_decoder img_ir_nec = { + .type = RC_BIT_NEC, + .control = { + .decoden = 1, + .code_type = IMG_IR_CODETYPE_PULSEDIST, + }, + /* main timings */ + .unit = 562500, /* 562.5 us */ + .timings = { + /* leader symbol */ + .ldr = { + .pulse = { 16 /* 9ms */ }, + .space = { 8 /* 4.5ms */ }, + }, + /* 0 symbol */ + .s00 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 1 /* 562.5 us */ }, + }, + /* 1 symbol */ + .s01 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 3 /* 1687.5 us */ }, + }, + /* free time */ + .ft = { + .minlen = 32, + .maxlen = 32, + .ft_min = 10, /* 5.625 ms */ + }, + }, + /* repeat codes */ + .repeat = 108, /* 108 ms */ + .rtimings = { + /* leader symbol */ + .ldr = { + .space = { 4 /* 2.25 ms */ }, + }, + /* free time */ + .ft = { + .minlen = 0, /* repeat code has no data */ + .maxlen = 0, + }, + }, + /* scancode logic */ + .scancode = img_ir_nec_scancode, + .filter = img_ir_nec_filter, +}; diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c new file mode 100644 index 000000000000..cfb01d9e571a --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -0,0 +1,151 @@ +/* + * ImgTec IR Raw Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + * + * This ties into the input subsystem using the RC-core in raw mode. Raw IR + * signal edges are reported and decoded by generic software decoders. + */ + +#include <linux/spinlock.h> +#include <media/rc-core.h> +#include "img-ir.h" + +#define ECHO_TIMEOUT_MS 150 /* ms between echos */ + +/* must be called with priv->lock held */ +static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status) +{ + struct img_ir_priv_raw *raw = &priv->raw; + struct rc_dev *rc_dev = priv->raw.rdev; + int multiple; + u32 ir_status; + + /* find whether both rise and fall was detected */ + multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE); + /* + * If so, we need to see if the level has actually changed. + * If it's just noise that we didn't have time to process, + * there's no point reporting it. + */ + ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD; + if (multiple && ir_status == raw->last_status) + return; + raw->last_status = ir_status; + + /* report the edge to the IR raw decoders */ + if (ir_status) /* low */ + ir_raw_event_store_edge(rc_dev, IR_SPACE); + else /* high */ + ir_raw_event_store_edge(rc_dev, IR_PULSE); + ir_raw_event_handle(rc_dev); +} + +/* called with priv->lock held */ +void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status) +{ + struct img_ir_priv_raw *raw = &priv->raw; + + /* check not removing */ + if (!raw->rdev) + return; + + img_ir_refresh_raw(priv, irq_status); + + /* start / push back the echo timer */ + mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS)); +} + +/* + * Echo timer callback function. + * The raw decoders expect to get a final sample even if there are no edges, in + * order to be assured of the final space. If there are no edges for a certain + * time we use this timer to emit a final sample to satisfy them. + */ +static void img_ir_echo_timer(unsigned long arg) +{ + struct img_ir_priv *priv = (struct img_ir_priv *)arg; + + spin_lock_irq(&priv->lock); + + /* check not removing */ + if (priv->raw.rdev) + /* + * It's safe to pass irq_status=0 since it's only used to check + * for double edges. + */ + img_ir_refresh_raw(priv, 0); + + spin_unlock_irq(&priv->lock); +} + +void img_ir_setup_raw(struct img_ir_priv *priv) +{ + u32 irq_en; + + if (!priv->raw.rdev) + return; + + /* clear and enable edge interrupts */ + spin_lock_irq(&priv->lock); + irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); + irq_en |= IMG_IR_IRQ_EDGE; + img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE); + img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en); + spin_unlock_irq(&priv->lock); +} + +int img_ir_probe_raw(struct img_ir_priv *priv) +{ + struct img_ir_priv_raw *raw = &priv->raw; + struct rc_dev *rdev; + int error; + + /* Set up the echo timer */ + setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv); + + /* Allocate raw decoder */ + raw->rdev = rdev = rc_allocate_device(); + if (!rdev) { + dev_err(priv->dev, "cannot allocate raw input device\n"); + return -ENOMEM; + } + rdev->priv = priv; + rdev->map_name = RC_MAP_EMPTY; + rdev->input_name = "IMG Infrared Decoder Raw"; + rdev->driver_type = RC_DRIVER_IR_RAW; + + /* Register raw decoder */ + error = rc_register_device(rdev); + if (error) { + dev_err(priv->dev, "failed to register raw IR input device\n"); + rc_free_device(rdev); + raw->rdev = NULL; + return error; + } + + return 0; +} + +void img_ir_remove_raw(struct img_ir_priv *priv) +{ + struct img_ir_priv_raw *raw = &priv->raw; + struct rc_dev *rdev = raw->rdev; + u32 irq_en; + + if (!rdev) + return; + + /* switch off and disable raw (edge) interrupts */ + spin_lock_irq(&priv->lock); + raw->rdev = NULL; + irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE); + irq_en &= ~IMG_IR_IRQ_EDGE; + img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en); + img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE); + spin_unlock_irq(&priv->lock); + + rc_unregister_device(rdev); + + del_timer_sync(&raw->timer); +} diff --git a/drivers/media/rc/img-ir/img-ir-raw.h b/drivers/media/rc/img-ir/img-ir-raw.h new file mode 100644 index 000000000000..9802ffd51b9a --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-raw.h @@ -0,0 +1,60 @@ +/* + * ImgTec IR Raw Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + */ + +#ifndef _IMG_IR_RAW_H_ +#define _IMG_IR_RAW_H_ + +struct img_ir_priv; + +#ifdef CONFIG_IR_IMG_RAW + +/** + * struct img_ir_priv_raw - Private driver data for raw decoder. + * @rdev: Raw remote control device + * @timer: Timer to echo samples to keep soft decoders happy. + * @last_status: Last raw status bits. + */ +struct img_ir_priv_raw { + struct rc_dev *rdev; + struct timer_list timer; + u32 last_status; +}; + +static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw) +{ + return raw->rdev; +}; + +void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status); +void img_ir_setup_raw(struct img_ir_priv *priv); +int img_ir_probe_raw(struct img_ir_priv *priv); +void img_ir_remove_raw(struct img_ir_priv *priv); + +#else + +struct img_ir_priv_raw { +}; +static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw) +{ + return false; +}; +static inline void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status) +{ +} +static inline void img_ir_setup_raw(struct img_ir_priv *priv) +{ +} +static inline int img_ir_probe_raw(struct img_ir_priv *priv) +{ + return -ENODEV; +} +static inline void img_ir_remove_raw(struct img_ir_priv *priv) +{ +} + +#endif /* CONFIG_IR_IMG_RAW */ + +#endif /* _IMG_IR_RAW_H_ */ diff --git a/drivers/media/rc/img-ir/img-ir-sanyo.c b/drivers/media/rc/img-ir/img-ir-sanyo.c new file mode 100644 index 000000000000..c2c763e08a41 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-sanyo.c @@ -0,0 +1,122 @@ +/* + * ImgTec IR Decoder setup for Sanyo protocol. + * + * Copyright 2012-2014 Imagination Technologies Ltd. + * + * From ir-sanyo-decoder.c: + * + * This protocol uses the NEC protocol timings. However, data is formatted as: + * 13 bits Custom Code + * 13 bits NOT(Custom Code) + * 8 bits Key data + * 8 bits NOT(Key data) + * + * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon + * Information for this protocol is available at the Sanyo LC7461 datasheet. + */ + +#include "img-ir-hw.h" + +/* Convert Sanyo data to a scancode */ +static int img_ir_sanyo_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + /* a repeat code has no data */ + if (!len) + return IMG_IR_REPEATCODE; + if (len != 42) + return -EINVAL; + addr = (raw >> 0) & 0x1fff; + addr_inv = (raw >> 13) & 0x1fff; + data = (raw >> 26) & 0xff; + data_inv = (raw >> 34) & 0xff; + /* Validate data */ + if ((data_inv ^ data) != 0xff) + return -EINVAL; + /* Validate address */ + if ((addr_inv ^ addr) != 0x1fff) + return -EINVAL; + + /* Normal Sanyo */ + *scancode = addr << 8 | data; + return IMG_IR_SCANCODE; +} + +/* Convert Sanyo scancode to Sanyo data filter */ +static int img_ir_sanyo_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int addr, addr_inv, data, data_inv; + unsigned int addr_m, data_m; + + data = in->data & 0xff; + data_m = in->mask & 0xff; + data_inv = data ^ 0xff; + + if (in->data & 0xff700000) + return -EINVAL; + + addr = (in->data >> 8) & 0x1fff; + addr_m = (in->mask >> 8) & 0x1fff; + addr_inv = addr ^ 0x1fff; + + out->data = (u64)data_inv << 34 | + (u64)data << 26 | + addr_inv << 13 | + addr; + out->mask = (u64)data_m << 34 | + (u64)data_m << 26 | + addr_m << 13 | + addr_m; + return 0; +} + +/* Sanyo decoder */ +struct img_ir_decoder img_ir_sanyo = { + .type = RC_BIT_SANYO, + .control = { + .decoden = 1, + .code_type = IMG_IR_CODETYPE_PULSEDIST, + }, + /* main timings */ + .unit = 562500, /* 562.5 us */ + .timings = { + /* leader symbol */ + .ldr = { + .pulse = { 16 /* 9ms */ }, + .space = { 8 /* 4.5ms */ }, + }, + /* 0 symbol */ + .s00 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 1 /* 562.5 us */ }, + }, + /* 1 symbol */ + .s01 = { + .pulse = { 1 /* 562.5 us */ }, + .space = { 3 /* 1687.5 us */ }, + }, + /* free time */ + .ft = { + .minlen = 42, + .maxlen = 42, + .ft_min = 10, /* 5.625 ms */ + }, + }, + /* repeat codes */ + .repeat = 108, /* 108 ms */ + .rtimings = { + /* leader symbol */ + .ldr = { + .space = { 4 /* 2.25 ms */ }, + }, + /* free time */ + .ft = { + .minlen = 0, /* repeat code has no data */ + .maxlen = 0, + }, + }, + /* scancode logic */ + .scancode = img_ir_sanyo_scancode, + .filter = img_ir_sanyo_filter, +}; diff --git a/drivers/media/rc/img-ir/img-ir-sharp.c b/drivers/media/rc/img-ir/img-ir-sharp.c new file mode 100644 index 000000000000..3397cc5a6794 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-sharp.c @@ -0,0 +1,99 @@ +/* + * ImgTec IR Decoder setup for Sharp protocol. + * + * Copyright 2012-2014 Imagination Technologies Ltd. + */ + +#include "img-ir-hw.h" + +/* Convert Sharp data to a scancode */ +static int img_ir_sharp_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int addr, cmd, exp, chk; + + if (len != 15) + return -EINVAL; + + addr = (raw >> 0) & 0x1f; + cmd = (raw >> 5) & 0xff; + exp = (raw >> 13) & 0x1; + chk = (raw >> 14) & 0x1; + + /* validate data */ + if (!exp) + return -EINVAL; + if (chk) + /* probably the second half of the message */ + return -EINVAL; + + *scancode = addr << 8 | cmd; + return IMG_IR_SCANCODE; +} + +/* Convert Sharp scancode to Sharp data filter */ +static int img_ir_sharp_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int addr, cmd, exp = 0, chk = 0; + unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0; + + addr = (in->data >> 8) & 0x1f; + addr_m = (in->mask >> 8) & 0x1f; + cmd = (in->data >> 0) & 0xff; + cmd_m = (in->mask >> 0) & 0xff; + if (cmd_m) { + /* if filtering commands, we can only match the first part */ + exp = 1; + exp_m = 1; + chk = 0; + chk_m = 1; + } + + out->data = addr | + cmd << 5 | + exp << 13 | + chk << 14; + out->mask = addr_m | + cmd_m << 5 | + exp_m << 13 | + chk_m << 14; + + return 0; +} + +/* + * Sharp decoder + * See also http://www.sbprojects.com/knowledge/ir/sharp.php + */ +struct img_ir_decoder img_ir_sharp = { + .type = RC_BIT_SHARP, + .control = { + .decoden = 0, + .decodend2 = 1, + .code_type = IMG_IR_CODETYPE_PULSEDIST, + .d1validsel = 1, + }, + /* main timings */ + .tolerance = 20, /* 20% */ + .timings = { + /* 0 symbol */ + .s10 = { + .pulse = { 320 /* 320 us */ }, + .space = { 680 /* 1 ms period */ }, + }, + /* 1 symbol */ + .s11 = { + .pulse = { 320 /* 320 us */ }, + .space = { 1680 /* 2 ms period */ }, + }, + /* free time */ + .ft = { + .minlen = 15, + .maxlen = 15, + .ft_min = 5000, /* 5 ms */ + }, + }, + /* scancode logic */ + .scancode = img_ir_sharp_scancode, + .filter = img_ir_sharp_filter, +}; diff --git a/drivers/media/rc/img-ir/img-ir-sony.c b/drivers/media/rc/img-ir/img-ir-sony.c new file mode 100644 index 000000000000..993409a51a71 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-sony.c @@ -0,0 +1,145 @@ +/* + * ImgTec IR Decoder setup for Sony (SIRC) protocol. + * + * Copyright 2012-2014 Imagination Technologies Ltd. + */ + +#include "img-ir-hw.h" + +/* Convert Sony data to a scancode */ +static int img_ir_sony_scancode(int len, u64 raw, int *scancode, u64 protocols) +{ + unsigned int dev, subdev, func; + + switch (len) { + case 12: + if (!(protocols & RC_BIT_SONY12)) + return -EINVAL; + func = raw & 0x7f; /* first 7 bits */ + raw >>= 7; + dev = raw & 0x1f; /* next 5 bits */ + subdev = 0; + break; + case 15: + if (!(protocols & RC_BIT_SONY15)) + return -EINVAL; + func = raw & 0x7f; /* first 7 bits */ + raw >>= 7; + dev = raw & 0xff; /* next 8 bits */ + subdev = 0; + break; + case 20: + if (!(protocols & RC_BIT_SONY20)) + return -EINVAL; + func = raw & 0x7f; /* first 7 bits */ + raw >>= 7; + dev = raw & 0x1f; /* next 5 bits */ + raw >>= 5; + subdev = raw & 0xff; /* next 8 bits */ + break; + default: + return -EINVAL; + } + *scancode = dev << 16 | subdev << 8 | func; + return IMG_IR_SCANCODE; +} + +/* Convert NEC scancode to NEC data filter */ +static int img_ir_sony_filter(const struct rc_scancode_filter *in, + struct img_ir_filter *out, u64 protocols) +{ + unsigned int dev, subdev, func; + unsigned int dev_m, subdev_m, func_m; + unsigned int len = 0; + + dev = (in->data >> 16) & 0xff; + dev_m = (in->mask >> 16) & 0xff; + subdev = (in->data >> 8) & 0xff; + subdev_m = (in->mask >> 8) & 0xff; + func = (in->data >> 0) & 0x7f; + func_m = (in->mask >> 0) & 0x7f; + + if (subdev & subdev_m) { + /* can't encode subdev and higher device bits */ + if (dev & dev_m & 0xe0) + return -EINVAL; + /* subdevice (extended) bits only in 20 bit encoding */ + if (!(protocols & RC_BIT_SONY20)) + return -EINVAL; + len = 20; + dev_m &= 0x1f; + } else if (dev & dev_m & 0xe0) { + /* upper device bits only in 15 bit encoding */ + if (!(protocols & RC_BIT_SONY15)) + return -EINVAL; + len = 15; + subdev_m = 0; + } else { + /* + * The hardware mask cannot distinguish high device bits and low + * extended bits, so logically AND those bits of the masks + * together. + */ + subdev_m &= (dev_m >> 5) | 0xf8; + dev_m &= 0x1f; + } + + /* ensure there aren't any bits straying between fields */ + dev &= dev_m; + subdev &= subdev_m; + + /* write the hardware filter */ + out->data = func | + dev << 7 | + subdev << 15; + out->mask = func_m | + dev_m << 7 | + subdev_m << 15; + + if (len) { + out->minlen = len; + out->maxlen = len; + } + return 0; +} + +/* + * Sony SIRC decoder + * See also http://www.sbprojects.com/knowledge/ir/sirc.php + * http://picprojects.org.uk/projects/sirc/sonysirc.pdf + */ +struct img_ir_decoder img_ir_sony = { + .type = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20, + .control = { + .decoden = 1, + .code_type = IMG_IR_CODETYPE_PULSELEN, + }, + /* main timings */ + .unit = 600000, /* 600 us */ + .timings = { + /* leader symbol */ + .ldr = { + .pulse = { 4 /* 2.4 ms */ }, + .space = { 1 /* 600 us */ }, + }, + /* 0 symbol */ + .s00 = { + .pulse = { 1 /* 600 us */ }, + .space = { 1 /* 600 us */ }, + }, + /* 1 symbol */ + .s01 = { + .pulse = { 2 /* 1.2 ms */ }, + .space = { 1 /* 600 us */ }, + }, + /* free time */ + .ft = { + .minlen = 12, + .maxlen = 20, + .ft_min = 10, /* 6 ms */ + }, + }, + /* scancode logic */ + .scancode = img_ir_sony_scancode, + .filter = img_ir_sony_filter, +}; diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h new file mode 100644 index 000000000000..afb189394af9 --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir.h @@ -0,0 +1,166 @@ +/* + * ImgTec IR Decoder found in PowerDown Controller. + * + * Copyright 2010-2014 Imagination Technologies Ltd. + */ + +#ifndef _IMG_IR_H_ +#define _IMG_IR_H_ + +#include <linux/io.h> +#include <linux/spinlock.h> + +#include "img-ir-raw.h" +#include "img-ir-hw.h" + +/* registers */ + +/* relative to the start of the IR block of registers */ +#define IMG_IR_CONTROL 0x00 +#define IMG_IR_STATUS 0x04 +#define IMG_IR_DATA_LW 0x08 +#define IMG_IR_DATA_UP 0x0c +#define IMG_IR_LEAD_SYMB_TIMING 0x10 +#define IMG_IR_S00_SYMB_TIMING 0x14 +#define IMG_IR_S01_SYMB_TIMING 0x18 +#define IMG_IR_S10_SYMB_TIMING 0x1c +#define IMG_IR_S11_SYMB_TIMING 0x20 +#define IMG_IR_FREE_SYMB_TIMING 0x24 +#define IMG_IR_POW_MOD_PARAMS 0x28 +#define IMG_IR_POW_MOD_ENABLE 0x2c +#define IMG_IR_IRQ_MSG_DATA_LW 0x30 +#define IMG_IR_IRQ_MSG_DATA_UP 0x34 +#define IMG_IR_IRQ_MSG_MASK_LW 0x38 +#define IMG_IR_IRQ_MSG_MASK_UP 0x3c +#define IMG_IR_IRQ_ENABLE 0x40 +#define IMG_IR_IRQ_STATUS 0x44 +#define IMG_IR_IRQ_CLEAR 0x48 +#define IMG_IR_IRCORE_ID 0xf0 +#define IMG_IR_CORE_REV 0xf4 +#define IMG_IR_CORE_DES1 0xf8 +#define IMG_IR_CORE_DES2 0xfc + + +/* field masks */ + +/* IMG_IR_CONTROL */ +#define IMG_IR_DECODEN 0x40000000 +#define IMG_IR_CODETYPE 0x30000000 +#define IMG_IR_CODETYPE_SHIFT 28 +#define IMG_IR_HDRTOG 0x08000000 +#define IMG_IR_LDRDEC 0x04000000 +#define IMG_IR_DECODINPOL 0x02000000 /* active high */ +#define IMG_IR_BITORIEN 0x01000000 /* MSB first */ +#define IMG_IR_D1VALIDSEL 0x00008000 +#define IMG_IR_BITINV 0x00000040 /* don't invert */ +#define IMG_IR_DECODEND2 0x00000010 +#define IMG_IR_BITORIEND2 0x00000002 /* MSB first */ +#define IMG_IR_BITINVD2 0x00000001 /* don't invert */ + +/* IMG_IR_STATUS */ +#define IMG_IR_RXDVALD2 0x00001000 +#define IMG_IR_IRRXD 0x00000400 +#define IMG_IR_TOGSTATE 0x00000200 +#define IMG_IR_RXDVAL 0x00000040 +#define IMG_IR_RXDLEN 0x0000003f +#define IMG_IR_RXDLEN_SHIFT 0 + +/* IMG_IR_LEAD_SYMB_TIMING, IMG_IR_Sxx_SYMB_TIMING */ +#define IMG_IR_PD_MAX 0xff000000 +#define IMG_IR_PD_MAX_SHIFT 24 +#define IMG_IR_PD_MIN 0x00ff0000 +#define IMG_IR_PD_MIN_SHIFT 16 +#define IMG_IR_W_MAX 0x0000ff00 +#define IMG_IR_W_MAX_SHIFT 8 +#define IMG_IR_W_MIN 0x000000ff +#define IMG_IR_W_MIN_SHIFT 0 + +/* IMG_IR_FREE_SYMB_TIMING */ +#define IMG_IR_MAXLEN 0x0007e000 +#define IMG_IR_MAXLEN_SHIFT 13 +#define IMG_IR_MINLEN 0x00001f00 +#define IMG_IR_MINLEN_SHIFT 8 +#define IMG_IR_FT_MIN 0x000000ff +#define IMG_IR_FT_MIN_SHIFT 0 + +/* IMG_IR_POW_MOD_PARAMS */ +#define IMG_IR_PERIOD_LEN 0x3f000000 +#define IMG_IR_PERIOD_LEN_SHIFT 24 +#define IMG_IR_PERIOD_DUTY 0x003f0000 +#define IMG_IR_PERIOD_DUTY_SHIFT 16 +#define IMG_IR_STABLE_STOP 0x00003f00 +#define IMG_IR_STABLE_STOP_SHIFT 8 +#define IMG_IR_STABLE_START 0x0000003f +#define IMG_IR_STABLE_START_SHIFT 0 + +/* IMG_IR_POW_MOD_ENABLE */ +#define IMG_IR_POWER_OUT_EN 0x00000002 +#define IMG_IR_POWER_MOD_EN 0x00000001 + +/* IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_STATUS, IMG_IR_IRQ_CLEAR */ +#define IMG_IR_IRQ_DEC2_ERR 0x00000080 +#define IMG_IR_IRQ_DEC_ERR 0x00000040 +#define IMG_IR_IRQ_ACT_LEVEL 0x00000020 +#define IMG_IR_IRQ_FALL_EDGE 0x00000010 +#define IMG_IR_IRQ_RISE_EDGE 0x00000008 +#define IMG_IR_IRQ_DATA_MATCH 0x00000004 +#define IMG_IR_IRQ_DATA2_VALID 0x00000002 +#define IMG_IR_IRQ_DATA_VALID 0x00000001 +#define IMG_IR_IRQ_ALL 0x000000ff +#define IMG_IR_IRQ_EDGE (IMG_IR_IRQ_FALL_EDGE | IMG_IR_IRQ_RISE_EDGE) + +/* IMG_IR_CORE_ID */ +#define IMG_IR_CORE_ID 0x00ff0000 +#define IMG_IR_CORE_ID_SHIFT 16 +#define IMG_IR_CORE_CONFIG 0x0000ffff +#define IMG_IR_CORE_CONFIG_SHIFT 0 + +/* IMG_IR_CORE_REV */ +#define IMG_IR_DESIGNER 0xff000000 +#define IMG_IR_DESIGNER_SHIFT 24 +#define IMG_IR_MAJOR_REV 0x00ff0000 +#define IMG_IR_MAJOR_REV_SHIFT 16 +#define IMG_IR_MINOR_REV 0x0000ff00 +#define IMG_IR_MINOR_REV_SHIFT 8 +#define IMG_IR_MAINT_REV 0x000000ff +#define IMG_IR_MAINT_REV_SHIFT 0 + +struct device; +struct clk; + +/** + * struct img_ir_priv - Private driver data. + * @dev: Platform device. + * @irq: IRQ number. + * @clk: Input clock. + * @reg_base: Iomem base address of IR register block. + * @lock: Protects IR registers and variables in this struct. + * @raw: Driver data for raw decoder. + * @hw: Driver data for hardware decoder. + */ +struct img_ir_priv { + struct device *dev; + int irq; + struct clk *clk; + void __iomem *reg_base; + spinlock_t lock; + + struct img_ir_priv_raw raw; + struct img_ir_priv_hw hw; +}; + +/* Hardware access */ + +static inline void img_ir_write(struct img_ir_priv *priv, + unsigned int reg_offs, unsigned int data) +{ + iowrite32(data, priv->reg_base + reg_offs); +} + +static inline unsigned int img_ir_read(struct img_ir_priv *priv, + unsigned int reg_offs) +{ + return ioread32(priv->reg_base + reg_offs); +} + +#endif /* _IMG_IR_H_ */ diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 822b9f47ca72..6f24e77b1488 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1017,7 +1017,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - if (*rc_type && !(*rc_type & rc->allowed_protos)) + if (*rc_type && !rc_protocols_allowed(rc, *rc_type)) dev_warn(dev, "Looks like you're trying to use an IR protocol " "this device does not support\n"); @@ -1867,7 +1867,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) rdev->priv = ictx; rdev->driver_type = RC_DRIVER_SCANCODE; - rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */ + /* iMON PAD or MCE */ + rc_set_allowed_protocols(rdev, RC_BIT_OTHER | RC_BIT_RC6_MCE); rdev->change_protocol = imon_ir_change_protocol; rdev->driver_name = MOD_NAME; @@ -1880,7 +1881,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) if (ictx->product == 0xffdc) { imon_get_ffdc_type(ictx); - rdev->allowed_protos = ictx->rc_type; + rc_set_allowed_protocols(rdev, ictx->rc_type); } imon_set_display_type(ictx); diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 3948138ca870..4ea62a1dcfda 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct jvc_dec *data = &dev->raw->jvc; - if (!(dev->enabled_protocols & RC_BIT_JVC)) + if (!rc_protocols_enabled(dev, RC_BIT_JVC)) return 0; if (!is_timing_event(ev)) { diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index ed2c8a1ed8ca..d731da6c414d 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) struct lirc_codec *lirc = &dev->raw->lirc; int sample; - if (!(dev->enabled_protocols & RC_BIT_LIRC)) + if (!rc_protocols_enabled(dev, RC_BIT_LIRC)) return 0; if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 9f3c9b59f30c..0c55f794c8cf 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; unsigned long delay; - if (!(dev->enabled_protocols & RC_BIT_MCE_KBD)) + if (!rc_protocols_enabled(dev, RC_BIT_MCE_KBD)) return 0; if (!is_timing_event(ev)) { diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 9a9009411439..35c42e5e270b 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -1,6 +1,6 @@ /* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol * - * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2010 by Mauro Carvalho Chehab * * 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 @@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 address, not_address, command, not_command; bool send_32bits = false; - if (!(dev->enabled_protocols & RC_BIT_NEC)) + if (!rc_protocols_enabled(dev, RC_BIT_NEC)) return 0; if (!is_timing_event(ev)) { @@ -222,6 +222,6 @@ module_init(ir_nec_decode_init); module_exit(ir_nec_decode_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); MODULE_DESCRIPTION("NEC IR protocol decoder"); diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 5c42750c7b71..763c9d131d0f 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -1,6 +1,6 @@ /* ir-raw.c - handle IR pulse/space events * - * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2010 by Mauro Carvalho Chehab * * 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 @@ -256,7 +256,7 @@ int ir_raw_event_register(struct rc_dev *dev) return -ENOMEM; dev->raw->dev = dev; - dev->enabled_protocols = ~0; + rc_set_enabled_protocols(dev, ~0); rc = kfifo_alloc(&dev->raw->kfifo, sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, GFP_KERNEL); @@ -352,6 +352,7 @@ void ir_raw_init(void) load_jvc_decode(); load_sony_decode(); load_sanyo_decode(); + load_sharp_decode(); load_mce_kbd_decode(); load_lirc_codec(); diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 4e53a319c5d8..4295d9b250c8 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -1,6 +1,6 @@ /* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol * - * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2010 by Mauro Carvalho Chehab * * 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 @@ -52,7 +52,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 toggle; u32 scancode; - if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X))) + if (!rc_protocols_enabled(dev, RC_BIT_RC5 | RC_BIT_RC5X)) return 0; if (!is_timing_event(ev)) { @@ -128,7 +128,7 @@ again: if (data->wanted_bits == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; - if (!(dev->enabled_protocols & RC_BIT_RC5X)) { + if (!rc_protocols_enabled(dev, RC_BIT_RC5X)) { data->state = STATE_INACTIVE; return 0; } @@ -145,7 +145,7 @@ again: } else { /* RC5 */ u8 command, system; - if (!(dev->enabled_protocols & RC_BIT_RC5)) { + if (!rc_protocols_enabled(dev, RC_BIT_RC5)) { data->state = STATE_INACTIVE; return 0; } @@ -193,6 +193,6 @@ module_init(ir_rc5_decode_init); module_exit(ir_rc5_decode_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); MODULE_DESCRIPTION("RC5(x) IR protocol decoder"); diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c index 865fe84fd854..dc18b7434db8 100644 --- a/drivers/media/rc/ir-rc5-sz-decoder.c +++ b/drivers/media/rc/ir-rc5-sz-decoder.c @@ -1,6 +1,6 @@ /* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol * - * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2010 by Mauro Carvalho Chehab * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com> * * This program is free software; you can redistribute it and/or modify @@ -48,7 +48,7 @@ static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev) u8 toggle, command, system; u32 scancode; - if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) + if (!rc_protocols_enabled(dev, RC_BIT_RC5_SZ)) return 0; if (!is_timing_event(ev)) { diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 7cba7d33a3fa..cfbd64e3999c 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -89,9 +89,9 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 toggle; - if (!(dev->enabled_protocols & - (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE))) + if (!rc_protocols_enabled(dev, RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | + RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | + RC_BIT_RC6_MCE)) return 0; if (!is_timing_event(ev)) { diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index 0a06205b5677..eb715f04dc27 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -1,6 +1,6 @@ /* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol * - * Copyright (C) 2011 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2011 by Mauro Carvalho Chehab * * 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 @@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 address, command, not_command; - if (!(dev->enabled_protocols & RC_BIT_SANYO)) + if (!rc_protocols_enabled(dev, RC_BIT_SANYO)) return 0; if (!is_timing_event(ev)) { @@ -200,6 +200,6 @@ module_init(ir_sanyo_decode_init); module_exit(ir_sanyo_decode_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); MODULE_DESCRIPTION("SANYO IR protocol decoder"); diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c new file mode 100644 index 000000000000..66d20394ceaa --- /dev/null +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -0,0 +1,200 @@ +/* ir-sharp-decoder.c - handle Sharp IR Pulse/Space protocol + * + * Copyright (C) 2013-2014 Imagination Technologies Ltd. + * + * Based on NEC decoder: + * Copyright (C) 2010 by Mauro Carvalho Chehab + * + * 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 version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/bitrev.h> +#include <linux/module.h> +#include "rc-core-priv.h" + +#define SHARP_NBITS 15 +#define SHARP_UNIT 40000 /* ns */ +#define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */ +#define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */ +#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */ +#define SHARP_ECHO_SPACE (1000 * SHARP_UNIT) /* 40 ms */ +#define SHARP_TRAILER_SPACE (125 * SHARP_UNIT) /* 5 ms (even longer) */ + +enum sharp_state { + STATE_INACTIVE, + STATE_BIT_PULSE, + STATE_BIT_SPACE, + STATE_TRAILER_PULSE, + STATE_ECHO_SPACE, + STATE_TRAILER_SPACE, +}; + +/** + * ir_sharp_decode() - Decode one Sharp pulse or space + * @dev: the struct rc_dev descriptor of the device + * @duration: the struct ir_raw_event descriptor of the pulse/space + * + * This function returns -EINVAL if the pulse violates the state machine + */ +static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) +{ + struct sharp_dec *data = &dev->raw->sharp; + u32 msg, echo, address, command, scancode; + + if (!rc_protocols_enabled(dev, RC_BIT_SHARP)) + return 0; + + if (!is_timing_event(ev)) { + if (ev.reset) + data->state = STATE_INACTIVE; + return 0; + } + + IR_dprintk(2, "Sharp decode started at state %d (%uus %s)\n", + data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + + switch (data->state) { + + case STATE_INACTIVE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, SHARP_BIT_PULSE, + SHARP_BIT_PULSE / 2)) + break; + + data->count = 0; + data->pulse_len = ev.duration; + data->state = STATE_BIT_SPACE; + return 0; + + case STATE_BIT_PULSE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, SHARP_BIT_PULSE, + SHARP_BIT_PULSE / 2)) + break; + + data->pulse_len = ev.duration; + data->state = STATE_BIT_SPACE; + return 0; + + case STATE_BIT_SPACE: + if (ev.pulse) + break; + + data->bits <<= 1; + if (eq_margin(data->pulse_len + ev.duration, SHARP_BIT_1_PERIOD, + SHARP_BIT_PULSE * 2)) + data->bits |= 1; + else if (!eq_margin(data->pulse_len + ev.duration, + SHARP_BIT_0_PERIOD, SHARP_BIT_PULSE * 2)) + break; + data->count++; + + if (data->count == SHARP_NBITS || + data->count == SHARP_NBITS * 2) + data->state = STATE_TRAILER_PULSE; + else + data->state = STATE_BIT_PULSE; + + return 0; + + case STATE_TRAILER_PULSE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, SHARP_BIT_PULSE, + SHARP_BIT_PULSE / 2)) + break; + + if (data->count == SHARP_NBITS) { + /* exp,chk bits should be 1,0 */ + if ((data->bits & 0x3) != 0x2) + break; + data->state = STATE_ECHO_SPACE; + } else { + data->state = STATE_TRAILER_SPACE; + } + return 0; + + case STATE_ECHO_SPACE: + if (ev.pulse) + break; + + if (!eq_margin(ev.duration, SHARP_ECHO_SPACE, + SHARP_ECHO_SPACE / 4)) + break; + + data->state = STATE_BIT_PULSE; + + return 0; + + case STATE_TRAILER_SPACE: + if (ev.pulse) + break; + + if (!geq_margin(ev.duration, SHARP_TRAILER_SPACE, + SHARP_BIT_PULSE / 2)) + break; + + /* Validate - command, ext, chk should be inverted in 2nd */ + msg = (data->bits >> 15) & 0x7fff; + echo = data->bits & 0x7fff; + if ((msg ^ echo) != 0x3ff) { + IR_dprintk(1, + "Sharp checksum error: received 0x%04x, 0x%04x\n", + msg, echo); + break; + } + + address = bitrev8((msg >> 7) & 0xf8); + command = bitrev8((msg >> 2) & 0xff); + + scancode = address << 8 | command; + IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode); + + rc_keydown(dev, scancode, 0); + data->state = STATE_INACTIVE; + return 0; + } + + IR_dprintk(1, "Sharp decode failed at count %d state %d (%uus %s)\n", + data->count, data->state, TO_US(ev.duration), + TO_STR(ev.pulse)); + data->state = STATE_INACTIVE; + return -EINVAL; +} + +static struct ir_raw_handler sharp_handler = { + .protocols = RC_BIT_SHARP, + .decode = ir_sharp_decode, +}; + +static int __init ir_sharp_decode_init(void) +{ + ir_raw_handler_register(&sharp_handler); + + pr_info("IR Sharp protocol handler initialized\n"); + return 0; +} + +static void __exit ir_sharp_decode_exit(void) +{ + ir_raw_handler_unregister(&sharp_handler); +} + +module_init(ir_sharp_decode_init); +module_exit(ir_sharp_decode_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("James Hogan <james.hogan@imgtec.com>"); +MODULE_DESCRIPTION("Sharp IR protocol decoder"); diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 29ab9c2db060..599c19a73360 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -45,8 +45,8 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; u8 device, subdevice, function; - if (!(dev->enabled_protocols & - (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) + if (!rc_protocols_enabled(dev, RC_BIT_SONY12 | RC_BIT_SONY15 | + RC_BIT_SONY20)) return 0; if (!is_timing_event(ev)) { @@ -124,7 +124,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) switch (data->count) { case 12: - if (!(dev->enabled_protocols & RC_BIT_SONY12)) { + if (!rc_protocols_enabled(dev, RC_BIT_SONY12)) { data->state = STATE_INACTIVE; return 0; } @@ -133,7 +133,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) function = bitrev8((data->bits >> 4) & 0xFE); break; case 15: - if (!(dev->enabled_protocols & RC_BIT_SONY15)) { + if (!rc_protocols_enabled(dev, RC_BIT_SONY15)) { data->state = STATE_INACTIVE; return 0; } @@ -142,7 +142,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) function = bitrev8((data->bits >> 7) & 0xFE); break; case 20: - if (!(dev->enabled_protocols & RC_BIT_SONY20)) { + if (!rc_protocols_enabled(dev, RC_BIT_SONY20)) { data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 63b42252166a..ab24cc6d3655 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* set up ir-core props */ rdev->priv = itdev; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->open = ite_open; rdev->close = ite_close; rdev->s_idle = ite_s_idle; diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c index b0e42df7ff82..01d901fbfc8b 100644 --- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -87,4 +87,4 @@ module_init(init_rc_map_adstech_dvb_t_pci) module_exit(exit_rc_map_adstech_dvb_t_pci) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c index 8c92ff95f94d..bf9efa007e1c 100644 --- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -78,4 +78,4 @@ module_init(init_rc_map_apac_viewcomp) module_exit(exit_rc_map_apac_viewcomp) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c index 2caf2117759b..9e674ba5dd4f 100644 --- a/drivers/media/rc/keymaps/rc-asus-pc39.c +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -89,4 +89,4 @@ module_init(init_rc_map_asus_pc39) module_exit(exit_rc_map_asus_pc39) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-asus-ps3-100.c b/drivers/media/rc/keymaps/rc-asus-ps3-100.c index ba76609c5936..e45de35f528f 100644 --- a/drivers/media/rc/keymaps/rc-asus-ps3-100.c +++ b/drivers/media/rc/keymaps/rc-asus-ps3-100.c @@ -1,6 +1,6 @@ /* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller * - * Copyright (c) 2012 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2012 by Mauro Carvalho Chehab * * Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.com> * @@ -88,4 +88,4 @@ module_init(init_rc_map_asus_ps3_100) module_exit(exit_rc_map_asus_ps3_100) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c index 2031224a2027..91392d4cfd6d 100644 --- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -67,4 +67,4 @@ module_init(init_rc_map_ati_tv_wonder_hd_600) module_exit(exit_rc_map_ati_tv_wonder_hd_600) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c index 894939ac17f2..ff30a71d623e 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -73,4 +73,4 @@ module_init(init_rc_map_avermedia_a16d) module_exit(exit_rc_map_avermedia_a16d) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c index d2aaf5b9e39f..d7471a6de9b4 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -95,4 +95,4 @@ module_init(init_rc_map_avermedia_cardbus) module_exit(exit_rc_map_avermedia_cardbus) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c index dc2baf062398..e2417d6331fe 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -76,4 +76,4 @@ module_init(init_rc_map_avermedia_dvbt) module_exit(exit_rc_map_avermedia_dvbt) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index 04269d31fa19..843598a5f1b5 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -1,6 +1,6 @@ /* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br> * * This program is free software; you can redistribute it and/or modify @@ -145,4 +145,4 @@ module_init(init_rc_map_avermedia_m135a) module_exit(exit_rc_map_avermedia_m135a) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index e83b1a1939bf..b24e7481ac21 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -93,4 +93,4 @@ module_init(init_rc_map_avermedia_m733a_rm_k6) module_exit(exit_rc_map_avermedia_m733a_rm_k6) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c index c6063dfcd507..3f68fbecc188 100644 --- a/drivers/media/rc/keymaps/rc-avermedia.c +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -84,4 +84,4 @@ module_init(init_rc_map_avermedia) module_exit(exit_rc_map_avermedia) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c index 14f78451e64e..c35bc5b835c4 100644 --- a/drivers/media/rc/keymaps/rc-avertv-303.c +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -83,4 +83,4 @@ module_init(init_rc_map_avertv_303) module_exit(exit_rc_map_avertv_303) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 086b4b1f19e1..1fc344e9daa7 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -106,4 +106,4 @@ module_init(init_rc_map_behold_columbus) module_exit(exit_rc_map_behold_columbus) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index 0877e3480941..d6519f8ac95a 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -139,4 +139,4 @@ module_init(init_rc_map_behold) module_exit(exit_rc_map_behold) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index 8311e092c098..b196a5f436a3 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -91,4 +91,4 @@ module_init(init_rc_map_budget_ci_old) module_exit(exit_rc_map_budget_ci_old) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c index 0c87fbaf99ab..a099c080bf8c 100644 --- a/drivers/media/rc/keymaps/rc-cinergy-1400.c +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -82,4 +82,4 @@ module_init(init_rc_map_cinergy_1400) module_exit(exit_rc_map_cinergy_1400) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c index 309e9e3fb6f3..b0f4328bdd6f 100644 --- a/drivers/media/rc/keymaps/rc-cinergy.c +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -76,4 +76,4 @@ module_init(init_rc_map_cinergy) module_exit(exit_rc_map_cinergy) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index 492a05ade7e1..a0fa543c9f9e 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -1,6 +1,6 @@ /* rc-dvb0700-big.c - Keytable for devices in dvb0700 * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * TODO: This table is a real mess, as it merges RC codes from several * devices into a big table. It also has both RC-5 and NEC codes inside. @@ -122,4 +122,4 @@ module_init(init_rc_map) module_exit(exit_rc_map) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c index 454ea596a7ee..907941145eb7 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -1,6 +1,6 @@ /* rc-dvb0700-big.c - Keytable for devices in dvb0700 * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * TODO: This table is a real mess, as it merges RC codes from several * devices into a big table. It also has both RC-5 and NEC codes inside. @@ -233,4 +233,4 @@ module_init(init_rc_map) module_exit(exit_rc_map) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c index 67fc9fb0c007..46e7ae414cc8 100644 --- a/drivers/media/rc/keymaps/rc-dm1105-nec.c +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -74,4 +74,4 @@ module_init(init_rc_map_dm1105_nec) module_exit(exit_rc_map_dm1105_nec) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c index 91ea91de9179..d2826b46fea2 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -76,4 +76,4 @@ module_init(init_rc_map_dntv_live_dvb_t) module_exit(exit_rc_map_dntv_live_dvb_t) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c index fd680d4d3eb6..0d74769467b5 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -95,4 +95,4 @@ module_init(init_rc_map_dntv_live_dvbt_pro) module_exit(exit_rc_map_dntv_live_dvbt_pro) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c index d1fcd64c0f90..7f1e06be175b 100644 --- a/drivers/media/rc/keymaps/rc-em-terratec.c +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -67,4 +67,4 @@ module_init(init_rc_map_em_terratec) module_exit(exit_rc_map_em_terratec) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index 2fe45e41fe49..4fc3904daf06 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -79,4 +79,4 @@ module_init(init_rc_map_encore_enltv_fm53) module_exit(exit_rc_map_encore_enltv_fm53) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index 223de75a6d1c..f1914e23d203 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -110,4 +110,4 @@ module_init(init_rc_map_encore_enltv) module_exit(exit_rc_map_encore_enltv) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index 669cbff22b7e..9c6c55240d18 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -88,4 +88,4 @@ module_init(init_rc_map_encore_enltv2) module_exit(exit_rc_map_encore_enltv2) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c index 2c647fc25916..2370d2a3deb6 100644 --- a/drivers/media/rc/keymaps/rc-evga-indtube.c +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -59,4 +59,4 @@ module_init(init_rc_map_evga_indtube) module_exit(exit_rc_map_evga_indtube) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c index 76921445c1d9..b5c96ed84376 100644 --- a/drivers/media/rc/keymaps/rc-eztv.c +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -94,4 +94,4 @@ module_init(init_rc_map_eztv) module_exit(exit_rc_map_eztv) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c index 3a6bba311b08..25cb89fac03c 100644 --- a/drivers/media/rc/keymaps/rc-flydvb.c +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -75,4 +75,4 @@ module_init(init_rc_map_flydvb) module_exit(exit_rc_map_flydvb) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c index bf9da584643b..e71377dd0534 100644 --- a/drivers/media/rc/keymaps/rc-flyvideo.c +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -68,4 +68,4 @@ module_init(init_rc_map_flyvideo) module_exit(exit_rc_map_flyvideo) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c index 2f0970fe7832..cf0608dc83d5 100644 --- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -96,4 +96,4 @@ module_init(init_rc_map_fusionhdtv_mce) module_exit(exit_rc_map_fusionhdtv_mce) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c index 0e98ec467c34..03575bdb2eca 100644 --- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -79,4 +79,4 @@ module_init(init_rc_map_gadmei_rm008z) module_exit(exit_rc_map_gadmei_rm008z) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c index a2e2faa1d1b3..b2ab13b0dcb1 100644 --- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -82,4 +82,4 @@ module_init(init_rc_map_genius_tvgo_a11mce) module_exit(exit_rc_map_genius_tvgo_a11mce) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c index 864614e19314..229a36ac7f0a 100644 --- a/drivers/media/rc/keymaps/rc-gotview7135.c +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -77,4 +77,4 @@ module_init(init_rc_map_gotview7135) module_exit(exit_rc_map_gotview7135) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index 929bbbc16393..36d57f7c532b 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c @@ -8,7 +8,7 @@ * - Hauppauge Black; * - DSR-0112 remote bundled with Haupauge MiniStick. * - * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010-2011 by Mauro Carvalho Chehab * * 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 @@ -290,4 +290,4 @@ module_init(init_rc_map_rc5_hauppauge_new) module_exit(exit_rc_map_rc5_hauppauge_new) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c index 34540dfc3df5..9ee154cb0c6b 100644 --- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -86,4 +86,4 @@ module_init(init_rc_map_iodata_bctv7e) module_exit(exit_rc_map_iodata_bctv7e) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index 4264a787c150..60803a732c08 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -85,4 +85,4 @@ module_init(init_rc_map_kaiomy) module_exit(exit_rc_map_kaiomy) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c index e48cd267dda6..ba087eed1ed9 100644 --- a/drivers/media/rc/keymaps/rc-kworld-315u.c +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -81,4 +81,4 @@ module_init(init_rc_map_kworld_315u) module_exit(exit_rc_map_kworld_315u) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-kworld-pc150u.c b/drivers/media/rc/keymaps/rc-kworld-pc150u.c index 233bb5ee087f..b92e571f4def 100644 --- a/drivers/media/rc/keymaps/rc-kworld-pc150u.c +++ b/drivers/media/rc/keymaps/rc-kworld-pc150u.c @@ -4,7 +4,7 @@ * * Copyright (c) 2010 by Kyle Strickland * (based on kworld-plus-tv-analog.c by - * Mauro Carvalho Chehab <mchehab@redhat.com>) + * Mauro Carvalho Chehab) * * 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 diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index 32998d6b787d..edc868564f99 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -97,4 +97,4 @@ module_init(init_rc_map_kworld_plus_tv_analog) module_exit(exit_rc_map_kworld_plus_tv_analog) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c index e7038bb71bf6..92424ef2aaa6 100644 --- a/drivers/media/rc/keymaps/rc-manli.c +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -132,4 +132,4 @@ module_init(init_rc_map_manli) module_exit(exit_rc_map_manli) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c index c393d8a50bca..fd7a55c56167 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -121,4 +121,4 @@ module_init(init_rc_map_msi_tvanywhere_plus) module_exit(exit_rc_map_msi_tvanywhere_plus) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index a7003d3a3c8a..4233a8d4d63e 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -67,4 +67,4 @@ module_init(init_rc_map_msi_tvanywhere) module_exit(exit_rc_map_msi_tvanywhere) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index 3f0ddd7afd30..8ec881adb7cf 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -94,4 +94,4 @@ module_init(init_rc_map_nebula) module_exit(exit_rc_map_nebula) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index 8d4dae2e2ece..292bbad35d21 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -14,7 +14,7 @@ #include <linux/module.h> /* Terratec Cinergy Hybrid T USB XS FM - Mauro Carvalho Chehab <mchehab@redhat.com> + Mauro Carvalho Chehab */ static struct rc_map_table nec_terratec_cinergy_xs[] = { @@ -155,4 +155,4 @@ module_init(init_rc_map_nec_terratec_cinergy_xs) module_exit(exit_rc_map_nec_terratec_cinergy_xs) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index 9e65f07157ab..ca1b82a2c54f 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -83,4 +83,4 @@ module_init(init_rc_map_norwood) module_exit(exit_rc_map_norwood) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c index 65d0cfc3c33b..1fb946024512 100644 --- a/drivers/media/rc/keymaps/rc-npgtech.c +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -78,4 +78,4 @@ module_init(init_rc_map_npgtech) module_exit(exit_rc_map_npgtech) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c index bf2cbdfe2e32..5ef01ab3fd50 100644 --- a/drivers/media/rc/keymaps/rc-pctv-sedna.c +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -78,4 +78,4 @@ module_init(init_rc_map_pctv_sedna) module_exit(exit_rc_map_pctv_sedna) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c index b46cd8fe6438..a218b471a4ca 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-color.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -92,4 +92,4 @@ module_init(init_rc_map_pinnacle_color) module_exit(exit_rc_map_pinnacle_color) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c index d525df9ad868..4a3f467a47a2 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -87,4 +87,4 @@ module_init(init_rc_map_pinnacle_grey) module_exit(exit_rc_map_pinnacle_grey) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index a4603d035374..e89cc10b68bf 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -68,4 +68,4 @@ module_init(init_rc_map_pinnacle_pctv_hd) module_exit(exit_rc_map_pinnacle_pctv_hd) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c index 33eb64333c6f..d967c3816fdc 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-002t.c +++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -75,4 +75,4 @@ module_init(init_rc_map_pixelview) module_exit(exit_rc_map_pixelview) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c index 21f4dd25c2ec..224d0efaa6e5 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -81,4 +81,4 @@ module_init(init_rc_map_pixelview) module_exit(exit_rc_map_pixelview) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index f944ad2cac2b..781d788d6b6d 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -81,4 +81,4 @@ module_init(init_rc_map_pixelview_new) module_exit(exit_rc_map_pixelview_new) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c index a6020eea7b95..39e6feaa35a3 100644 --- a/drivers/media/rc/keymaps/rc-pixelview.c +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -80,4 +80,4 @@ module_init(init_rc_map_pixelview) module_exit(exit_rc_map_pixelview) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c index e74c571a5e44..e96fa3ab9f4b 100644 --- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -79,4 +79,4 @@ module_init(init_rc_map_powercolor_real_angel) module_exit(exit_rc_map_powercolor_real_angel) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c index adee8035ce96..eef626ee02df 100644 --- a/drivers/media/rc/keymaps/rc-proteus-2309.c +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -67,4 +67,4 @@ module_init(init_rc_map_proteus_2309) module_exit(exit_rc_map_proteus_2309) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c index 722597a20e4a..cec6fe466829 100644 --- a/drivers/media/rc/keymaps/rc-purpletv.c +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -79,4 +79,4 @@ module_init(init_rc_map_purpletv) module_exit(exit_rc_map_purpletv) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c index 0105d63c07a9..5ac89ce8c053 100644 --- a/drivers/media/rc/keymaps/rc-pv951.c +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -76,4 +76,4 @@ module_init(init_rc_map_pv951) module_exit(exit_rc_map_pv951) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c index 073694d50f49..9f778bd091db 100644 --- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -76,4 +76,4 @@ module_init(init_rc_map_real_audio_220_32_keys) module_exit(exit_rc_map_real_audio_220_32_keys) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 5039be782bc5..24ce2a252502 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -73,4 +73,4 @@ module_init(init_rc_map_tbs_nec) module_exit(exit_rc_map_tbs_nec) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c index 53629fb0151f..97eb83ab5a35 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -90,4 +90,4 @@ module_init(init_rc_map_terratec_cinergy_xs) module_exit(exit_rc_map_terratec_cinergy_xs) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c index f2c3b75d8580..38e0c0875596 100644 --- a/drivers/media/rc/keymaps/rc-tevii-nec.c +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -86,4 +86,4 @@ module_init(init_rc_map_tevii_nec) module_exit(exit_rc_map_tevii_nec) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index 80217ffc91db..c766d3b2b6b0 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -80,4 +80,4 @@ module_init(init_rc_map_tt_1500) module_exit(exit_rc_map_tt_1500) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c index 8bfc3e8d909d..8a354775a2d8 100644 --- a/drivers/media/rc/keymaps/rc-videomate-s350.c +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -83,4 +83,4 @@ module_init(init_rc_map_videomate_s350) module_exit(exit_rc_map_videomate_s350) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c index 390ce9431b35..eb0cda7766c4 100644 --- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -85,4 +85,4 @@ module_init(init_rc_map_videomate_tv_pvr) module_exit(exit_rc_map_videomate_tv_pvr) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index 2852bf705064..c1dd598e828e 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -80,4 +80,4 @@ module_init(init_rc_map_winfast_usbii_deluxe) module_exit(exit_rc_map_winfast_usbii_deluxe) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c index 2df1cba23600..8a779da1e973 100644 --- a/drivers/media/rc/keymaps/rc-winfast.c +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -2,7 +2,7 @@ * * keymap imported from ir-keymaps.c * - * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (c) 2010 by Mauro Carvalho Chehab * * 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 @@ -100,4 +100,4 @@ module_init(init_rc_map_winfast) module_exit(exit_rc_map_winfast) MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index a25bb1581e46..5d8f3d40d820 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -84,7 +84,7 @@ #define MCE_PORT_IR 0x4 /* (0x4 << 5) | MCE_CMD = 0x9f */ #define MCE_PORT_SYS 0x7 /* (0x7 << 5) | MCE_CMD = 0xff */ #define MCE_PORT_SER 0x6 /* 0xc0 thru 0xdf flush & 0x1f bytes */ -#define MCE_PORT_MASK 0xe0 /* Mask out command bits */ +#define MCE_PORT_MASK 0xe0 /* Mask out command bits */ /* Command port headers */ #define MCE_CMD_PORT_IR 0x9f /* IR-related cmd/rsp */ @@ -153,19 +153,6 @@ #define MCE_COMMAND_IRDATA 0x80 #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ -/* module parameters */ -#ifdef CONFIG_USB_DEBUG -static bool debug = 1; -#else -static bool debug; -#endif - -#define mce_dbg(dev, fmt, ...) \ - do { \ - if (debug) \ - dev_info(dev, fmt, ## __VA_ARGS__); \ - } while (0) - /* general constants */ #define SEND_FLAG_IN_PROGRESS 1 #define SEND_FLAG_COMPLETE 2 @@ -541,16 +528,13 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd) static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, int offset, int len, bool out) { - char codes[USB_BUFLEN * 3 + 1]; - char inout[9]; +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) + char *inout; u8 cmd, subcmd, data1, data2, data3, data4; struct device *dev = ir->dev; - int i, start, skip = 0; + int start, skip = 0; u32 carrier, period; - if (!debug) - return; - /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ if (ir->flags.microsoft_gen1 && !out && !offset) skip = 2; @@ -558,16 +542,10 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, if (len <= skip) return; - for (i = 0; i < len && i < USB_BUFLEN; i++) - snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff); - - dev_info(dev, "%sx data: %s(length=%d)\n", - (out ? "t" : "r"), codes, len); + dev_dbg(dev, "%cx data: %*ph (length=%d)", + (out ? 't' : 'r'), min(len, USB_BUFLEN), buf, len); - if (out) - strcpy(inout, "Request\0"); - else - strcpy(inout, "Got\0"); + inout = out ? "Request" : "Got"; start = offset + skip; cmd = buf[start] & 0xff; @@ -583,50 +561,50 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; if ((subcmd == MCE_CMD_PORT_SYS) && (data1 == MCE_CMD_RESUME)) - dev_info(dev, "Device resume requested\n"); + dev_dbg(dev, "Device resume requested"); else - dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + dev_dbg(dev, "Unknown command 0x%02x 0x%02x", cmd, subcmd); break; case MCE_CMD_PORT_SYS: switch (subcmd) { case MCE_RSP_EQEMVER: if (!out) - dev_info(dev, "Emulator interface version %x\n", + dev_dbg(dev, "Emulator interface version %x", data1); break; case MCE_CMD_G_REVISION: if (len == 2) - dev_info(dev, "Get hw/sw rev?\n"); + dev_dbg(dev, "Get hw/sw rev?"); else - dev_info(dev, "hw/sw rev 0x%02x 0x%02x " - "0x%02x 0x%02x\n", data1, data2, + dev_dbg(dev, "hw/sw rev 0x%02x 0x%02x 0x%02x 0x%02x", + data1, data2, buf[start + 4], buf[start + 5]); break; case MCE_CMD_RESUME: - dev_info(dev, "Device resume requested\n"); + dev_dbg(dev, "Device resume requested"); break; case MCE_RSP_CMD_ILLEGAL: - dev_info(dev, "Illegal PORT_SYS command\n"); + dev_dbg(dev, "Illegal PORT_SYS command"); break; case MCE_RSP_EQWAKEVERSION: if (!out) - dev_info(dev, "Wake version, proto: 0x%02x, " + dev_dbg(dev, "Wake version, proto: 0x%02x, " "payload: 0x%02x, address: 0x%02x, " - "version: 0x%02x\n", + "version: 0x%02x", data1, data2, data3, data4); break; case MCE_RSP_GETPORTSTATUS: if (!out) /* We use data1 + 1 here, to match hw labels */ - dev_info(dev, "TX port %d: blaster is%s connected\n", + dev_dbg(dev, "TX port %d: blaster is%s connected", data1 + 1, data4 ? " not" : ""); break; case MCE_CMD_FLASHLED: - dev_info(dev, "Attempting to flash LED\n"); + dev_dbg(dev, "Attempting to flash LED"); break; default: - dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + dev_dbg(dev, "Unknown command 0x%02x 0x%02x", cmd, subcmd); break; } @@ -634,13 +612,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, case MCE_CMD_PORT_IR: switch (subcmd) { case MCE_CMD_SIG_END: - dev_info(dev, "End of signal\n"); + dev_dbg(dev, "End of signal"); break; case MCE_CMD_PING: - dev_info(dev, "Ping\n"); + dev_dbg(dev, "Ping"); break; case MCE_CMD_UNKNOWN: - dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", + dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x", data1, data2); break; case MCE_RSP_EQIRCFS: @@ -649,51 +627,51 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, if (!period) break; carrier = (1000 * 1000) / period; - dev_info(dev, "%s carrier of %u Hz (period %uus)\n", + dev_dbg(dev, "%s carrier of %u Hz (period %uus)", inout, carrier, period); break; case MCE_CMD_GETIRCFS: - dev_info(dev, "Get carrier mode and freq\n"); + dev_dbg(dev, "Get carrier mode and freq"); break; case MCE_RSP_EQIRTXPORTS: - dev_info(dev, "%s transmit blaster mask of 0x%02x\n", + dev_dbg(dev, "%s transmit blaster mask of 0x%02x", inout, data1); break; case MCE_RSP_EQIRTIMEOUT: /* value is in units of 50us, so x*50/1000 ms */ period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000; - dev_info(dev, "%s receive timeout of %d ms\n", + dev_dbg(dev, "%s receive timeout of %d ms", inout, period); break; case MCE_CMD_GETIRTIMEOUT: - dev_info(dev, "Get receive timeout\n"); + dev_dbg(dev, "Get receive timeout"); break; case MCE_CMD_GETIRTXPORTS: - dev_info(dev, "Get transmit blaster mask\n"); + dev_dbg(dev, "Get transmit blaster mask"); break; case MCE_RSP_EQIRRXPORTEN: - dev_info(dev, "%s %s-range receive sensor in use\n", + dev_dbg(dev, "%s %s-range receive sensor in use", inout, data1 == 0x02 ? "short" : "long"); break; case MCE_CMD_GETIRRXPORTEN: /* aka MCE_RSP_EQIRRXCFCNT */ if (out) - dev_info(dev, "Get receive sensor\n"); + dev_dbg(dev, "Get receive sensor"); else if (ir->learning_enabled) - dev_info(dev, "RX pulse count: %d\n", + dev_dbg(dev, "RX pulse count: %d", ((data1 << 8) | data2)); break; case MCE_RSP_EQIRNUMPORTS: if (out) break; - dev_info(dev, "Num TX ports: %x, num RX ports: %x\n", + dev_dbg(dev, "Num TX ports: %x, num RX ports: %x", data1, data2); break; case MCE_RSP_CMD_ILLEGAL: - dev_info(dev, "Illegal PORT_IR command\n"); + dev_dbg(dev, "Illegal PORT_IR command"); break; default: - dev_info(dev, "Unknown command 0x%02x 0x%02x\n", + dev_dbg(dev, "Unknown command 0x%02x 0x%02x", cmd, subcmd); break; } @@ -703,10 +681,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, } if (cmd == MCE_IRDATA_TRAILER) - dev_info(dev, "End of raw IR data\n"); + dev_dbg(dev, "End of raw IR data"); else if ((cmd != MCE_CMD_PORT_IR) && ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA)) - dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem); + dev_dbg(dev, "Raw IR data, %d pulse/space samples", ir->rem); +#endif } static void mce_async_callback(struct urb *urb) @@ -718,10 +697,25 @@ static void mce_async_callback(struct urb *urb) return; ir = urb->context; - if (ir) { + + switch (urb->status) { + /* success */ + case 0: len = urb->actual_length; mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); + break; + + case -ECONNRESET: + case -ENOENT: + case -EILSEQ: + case -ESHUTDOWN: + break; + + case -EPIPE: + default: + dev_err(ir->dev, "Error: request urb status = %d", urb->status); + break; } /* the transfer buffer and urb were allocated in mce_request_packet */ @@ -770,17 +764,17 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, return; } - mce_dbg(dev, "receive request called (size=%#x)\n", size); + dev_dbg(dev, "receive request called (size=%#x)", size); async_urb->transfer_buffer_length = size; async_urb->dev = ir->usbdev; res = usb_submit_urb(async_urb, GFP_ATOMIC); if (res) { - mce_dbg(dev, "receive request FAILED! (res=%d)\n", res); + dev_err(dev, "receive request FAILED! (res=%d)", res); return; } - mce_dbg(dev, "receive request complete (res=%d)\n", res); + dev_dbg(dev, "receive request complete (res=%d)", res); } static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) @@ -895,8 +889,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) ir->carrier = carrier; cmdbuf[2] = MCE_CMD_SIG_END; cmdbuf[3] = MCE_IRDATA_TRAILER; - mce_dbg(ir->dev, "%s: disabling carrier " - "modulation\n", __func__); + dev_dbg(ir->dev, "disabling carrier modulation"); mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); return carrier; } @@ -907,8 +900,8 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) ir->carrier = carrier; cmdbuf[2] = prescaler; cmdbuf[3] = divisor; - mce_dbg(ir->dev, "%s: requesting %u HZ " - "carrier\n", __func__, carrier); + dev_dbg(ir->dev, "requesting %u HZ carrier", + carrier); /* Transmit new carrier to mce device */ mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); @@ -998,7 +991,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) * US_TO_NS(MCE_TIME_UNIT); - mce_dbg(ir->dev, "Storing %s with duration %d\n", + dev_dbg(ir->dev, "Storing %s with duration %d", rawir.pulse ? "pulse" : "space", rawir.duration); @@ -1032,7 +1025,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ir->parser_state = CMD_HEADER; } if (event) { - mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); + dev_dbg(ir->dev, "processed IR data"); ir_raw_event_handle(ir->rc); } } @@ -1055,7 +1048,7 @@ static void mceusb_dev_recv(struct urb *urb) if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { ir->send_flags = SEND_FLAG_COMPLETE; - mce_dbg(ir->dev, "setup answer received %d bytes\n", + dev_dbg(ir->dev, "setup answer received %d bytes\n", buf_len); } @@ -1067,13 +1060,14 @@ static void mceusb_dev_recv(struct urb *urb) case -ECONNRESET: case -ENOENT: + case -EILSEQ: case -ESHUTDOWN: usb_unlink_urb(urb); return; case -EPIPE: default: - mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status); + dev_err(ir->dev, "Error: urb status = %d", urb->status); break; } @@ -1095,7 +1089,7 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); if (!data) { - dev_err(dev, "%s: memory allocation failed!\n", __func__); + dev_err(dev, "%s: memory allocation failed!", __func__); return; } @@ -1106,28 +1100,28 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, data, USB_CTRL_MSG_SZ, HZ * 3); - mce_dbg(dev, "%s - ret = %d\n", __func__, ret); - mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", - __func__, data[0], data[1]); + dev_dbg(dev, "set address - ret = %d", ret); + dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", + data[0], data[1]); /* set feature: bit rate 38400 bps */ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, 0xc04e, 0x0000, NULL, 0, HZ * 3); - mce_dbg(dev, "%s - ret = %d\n", __func__, ret); + dev_dbg(dev, "set feature - ret = %d", ret); /* bRequest 4: set char length to 8 bits */ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), 4, USB_TYPE_VENDOR, 0x0808, 0x0000, NULL, 0, HZ * 3); - mce_dbg(dev, "%s - retB = %d\n", __func__, ret); + dev_dbg(dev, "set char length - retB = %d", ret); /* bRequest 2: set handshaking to use DTR/DSR */ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), 2, USB_TYPE_VENDOR, 0x0000, 0x0100, NULL, 0, HZ * 3); - mce_dbg(dev, "%s - retC = %d\n", __func__, ret); + dev_dbg(dev, "set handshake - retC = %d", ret); /* device resume */ mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME)); @@ -1198,7 +1192,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc = rc_allocate_device(); if (!rc) { - dev_err(dev, "remote dev allocation failed\n"); + dev_err(dev, "remote dev allocation failed"); goto out; } @@ -1217,7 +1211,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->dev.parent = dev; rc->priv = ir; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->timeout = MS_TO_NS(100); if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; @@ -1230,7 +1224,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) ret = rc_register_device(rc); if (ret < 0) { - dev_err(dev, "remote dev registration failed\n"); + dev_err(dev, "remote dev registration failed"); goto out; } @@ -1258,7 +1252,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, bool tx_mask_normal; int ir_intfnum; - mce_dbg(&intf->dev, "%s called\n", __func__); + dev_dbg(&intf->dev, "%s called", __func__); idesc = intf->cur_altsetting; @@ -1286,8 +1280,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, ep_in = ep; ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; ep_in->bInterval = 1; - mce_dbg(&intf->dev, "acceptable inbound endpoint " - "found\n"); + dev_dbg(&intf->dev, "acceptable inbound endpoint found"); } if ((ep_out == NULL) @@ -1301,12 +1294,11 @@ static int mceusb_dev_probe(struct usb_interface *intf, ep_out = ep; ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; ep_out->bInterval = 1; - mce_dbg(&intf->dev, "acceptable outbound endpoint " - "found\n"); + dev_dbg(&intf->dev, "acceptable outbound endpoint found"); } } if (ep_in == NULL) { - mce_dbg(&intf->dev, "inbound and/or endpoint not found\n"); + dev_dbg(&intf->dev, "inbound and/or endpoint not found"); return -ENODEV; } @@ -1357,7 +1349,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* flush buffers on the device */ - mce_dbg(&intf->dev, "Flushing receive buffers\n"); + dev_dbg(&intf->dev, "Flushing receive buffers\n"); mce_flush_rx_buffer(ir, maxp); /* figure out which firmware/emulator version this hardware has */ @@ -1382,10 +1374,9 @@ static int mceusb_dev_probe(struct usb_interface *intf, device_set_wakeup_capable(ir->dev, true); device_set_wakeup_enable(ir->dev, true); - dev_info(&intf->dev, "Registered %s with mce emulator interface " - "version %x\n", name, ir->emver); - dev_info(&intf->dev, "%x tx ports (0x%x cabled) and " - "%x rx sensors (0x%x active)\n", + dev_info(&intf->dev, "Registered %s with mce emulator interface version %x", + name, ir->emver); + dev_info(&intf->dev, "%x tx ports (0x%x cabled) and %x rx sensors (0x%x active)", ir->num_txports, ir->txports_cabled, ir->num_rxports, ir->rxports_active); @@ -1399,7 +1390,7 @@ urb_in_alloc_fail: buf_in_alloc_fail: kfree(ir); mem_alloc_fail: - dev_err(&intf->dev, "%s: device setup failed!\n", __func__); + dev_err(&intf->dev, "%s: device setup failed!", __func__); return -ENOMEM; } @@ -1427,7 +1418,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf) static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message) { struct mceusb_dev *ir = usb_get_intfdata(intf); - dev_info(ir->dev, "suspend\n"); + dev_info(ir->dev, "suspend"); usb_kill_urb(ir->urb_in); return 0; } @@ -1435,7 +1426,7 @@ static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message) static int mceusb_dev_resume(struct usb_interface *intf) { struct mceusb_dev *ir = usb_get_intfdata(intf); - dev_info(ir->dev, "resume\n"); + dev_info(ir->dev, "resume"); if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) return -EIO; return 0; @@ -1457,6 +1448,3 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(usb, mceusb_dev_table); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 21ee0dc1b7ec..d244e1a83f43 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -330,9 +330,6 @@ static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt) /* Enable CIR Wake via PSOUT# (Pin60) */ nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); - /* enable cir interrupt of mouse/keyboard IRQ event */ - nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); - /* enable pme interrupt of cir wakeup event */ nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); @@ -456,7 +453,6 @@ static void nvt_enable_wake(struct nvt_dev *nvt) nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI); nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE); - nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS); nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2); nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE); @@ -989,6 +985,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) goto exit_free_dev_rdev; ret = -ENODEV; + /* activate pnp device */ + if (pnp_activate_dev(pdev) < 0) { + dev_err(&pdev->dev, "Could not activate PNP device!\n"); + goto exit_free_dev_rdev; + } + /* validate pnp resources */ if (!pnp_port_valid(pdev, 0) || pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) { @@ -1042,7 +1044,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->open = nvt_open; rdev->close = nvt_close; rdev->tx_ir = nvt_tx_ir; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 07e83108df0f..e1cf23c3875b 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -363,7 +363,6 @@ struct nvt_dev { #define LOGICAL_DEV_ENABLE 0x01 #define CIR_WAKE_ENABLE_BIT 0x08 -#define CIR_INTR_MOUSE_IRQ_BIT 0x80 #define PME_INTR_CIR_PASS_BIT 0x08 /* w83677hg CIR pin config */ diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 70a180bb0bd0..da536c93c978 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -1,7 +1,7 @@ /* * Remote Controller core raw events header * - * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2010 by Mauro Carvalho Chehab * * 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 @@ -88,6 +88,12 @@ struct ir_raw_event_ctrl { unsigned count; u64 bits; } sanyo; + struct sharp_dec { + int state; + unsigned count; + u32 bits; + unsigned int pulse_len; + } sharp; struct mce_kbd_dec { struct input_dev *idev; struct timer_list rx_timeout; @@ -204,6 +210,13 @@ static inline void load_sony_decode(void) { } static inline void load_sanyo_decode(void) { } #endif +/* from ir-sharp-decoder.c */ +#ifdef CONFIG_IR_SHARP_DECODER_MODULE +#define load_sharp_decode() request_module_nowait("ir-sharp-decoder") +#else +static inline void load_sharp_decode(void) { } +#endif + /* from ir-mce_kbd-decoder.c */ #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE #define load_mce_kbd_decode() request_module_nowait("ir-mce_kbd-decoder") diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 53d02827a472..0a88e0cf964f 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -195,7 +195,7 @@ static int __init loop_init(void) rc->map_name = RC_MAP_EMPTY; rc->priv = &loopdev; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->timeout = 100 * 1000 * 1000; /* 100 ms */ rc->min_timeout = 1; rc->max_timeout = UINT_MAX; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 02e2f38c9c85..970b93d6f399 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1,6 +1,6 @@ /* rc-main.c - Remote Controller core module * - * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com> + * Copyright (C) 2009-2010 by Mauro Carvalho Chehab * * 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 @@ -24,7 +24,7 @@ /* Bitmap to store allocated device numbers from 0 to IRRCV_NUM_DEVICES - 1 */ #define IRRCV_NUM_DEVICES 256 -DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES); +static DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES); /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ #define IR_TAB_MIN_SIZE 256 @@ -62,7 +62,7 @@ struct rc_map *rc_map_get(const char *name) map = seek_rc_map(name); #ifdef MODULE if (!map) { - int rc = request_module(name); + int rc = request_module("%s", name); if (rc < 0) { printk(KERN_ERR "Couldn't load IR keymap %s\n", name); return NULL; @@ -633,9 +633,9 @@ EXPORT_SYMBOL_GPL(rc_repeat); static void ir_do_keydown(struct rc_dev *dev, int scancode, u32 keycode, u8 toggle) { - bool new_event = !dev->keypressed || - dev->last_scancode != scancode || - dev->last_toggle != toggle; + bool new_event = (!dev->keypressed || + dev->last_scancode != scancode || + dev->last_toggle != toggle); if (new_event && dev->keypressed) ir_do_keyup(dev, false); @@ -653,9 +653,10 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode, "key 0x%04x, scancode 0x%04x\n", dev->input_name, keycode, scancode); input_report_key(dev->input_dev, keycode, 1); + + led_trigger_event(led_feedback, LED_FULL); } - led_trigger_event(led_feedback, LED_FULL); input_sync(dev->input_dev); } @@ -790,18 +791,44 @@ static struct { RC_BIT_SONY20, "sony" }, { RC_BIT_RC5_SZ, "rc-5-sz" }, { RC_BIT_SANYO, "sanyo" }, + { RC_BIT_SHARP, "sharp" }, { RC_BIT_MCE_KBD, "mce_kbd" }, { RC_BIT_LIRC, "lirc" }, }; /** - * show_protocols() - shows the current IR protocol(s) + * struct rc_filter_attribute - Device attribute relating to a filter type. + * @attr: Device attribute. + * @type: Filter type. + * @mask: false for filter value, true for filter mask. + */ +struct rc_filter_attribute { + struct device_attribute attr; + enum rc_filter_type type; + bool mask; +}; +#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr) + +#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type) \ + struct rc_filter_attribute dev_attr_##_name = { \ + .attr = __ATTR(_name, _mode, _show, _store), \ + .type = (_type), \ + } +#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask) \ + struct rc_filter_attribute dev_attr_##_name = { \ + .attr = __ATTR(_name, _mode, _show, _store), \ + .type = (_type), \ + .mask = (_mask), \ + } + +/** + * show_protocols() - shows the current/wakeup IR protocol(s) * @device: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the output buffer * * This routine is a callback routine for input read the IR protocol type(s). - * it is trigged by reading /sys/class/rc/rc?/protocols. + * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols. * It returns the protocol names of supported protocols. * Enabled protocols are printed in brackets. * @@ -812,6 +839,7 @@ static ssize_t show_protocols(struct device *device, struct device_attribute *mattr, char *buf) { struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); u64 allowed, enabled; char *tmp = buf; int i; @@ -822,9 +850,10 @@ static ssize_t show_protocols(struct device *device, mutex_lock(&dev->lock); - enabled = dev->enabled_protocols; - if (dev->driver_type == RC_DRIVER_SCANCODE) - allowed = dev->allowed_protos; + enabled = dev->enabled_protocols[fattr->type]; + if (dev->driver_type == RC_DRIVER_SCANCODE || + fattr->type == RC_FILTER_WAKEUP) + allowed = dev->allowed_protocols[fattr->type]; else if (dev->raw) allowed = ir_raw_get_allowed_protocols(); else { @@ -856,14 +885,14 @@ static ssize_t show_protocols(struct device *device, } /** - * store_protocols() - changes the current IR protocol(s) + * store_protocols() - changes the current/wakeup IR protocol(s) * @device: the device descriptor * @mattr: the device attribute struct (unused) * @buf: a pointer to the input buffer * @len: length of the input buffer * * This routine is for changing the IR protocol type. - * It is trigged by writing to /sys/class/rc/rc?/protocols. + * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols. * Writing "+proto" will add a protocol to the list of enabled protocols. * Writing "-proto" will remove a protocol from the list of enabled protocols. * Writing "proto" will enable only "proto". @@ -880,12 +909,16 @@ static ssize_t store_protocols(struct device *device, size_t len) { struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); bool enable, disable; const char *tmp; - u64 type; + u64 old_type, type; u64 mask; int rc, i, count = 0; ssize_t ret; + int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); + struct rc_scancode_filter local_filter, *filter; /* Device is being removed */ if (!dev) @@ -898,7 +931,8 @@ static ssize_t store_protocols(struct device *device, ret = -EINVAL; goto out; } - type = dev->enabled_protocols; + old_type = dev->enabled_protocols[fattr->type]; + type = old_type; while ((tmp = strsep((char **) &data, " \n")) != NULL) { if (!*tmp) @@ -946,8 +980,10 @@ static ssize_t store_protocols(struct device *device, goto out; } - if (dev->change_protocol) { - rc = dev->change_protocol(dev, &type); + change_protocol = (fattr->type == RC_FILTER_NORMAL) + ? dev->change_protocol : dev->change_wakeup_protocol; + if (change_protocol) { + rc = change_protocol(dev, &type); if (rc < 0) { IR_dprintk(1, "Error setting protocols to 0x%llx\n", (long long)type); @@ -956,10 +992,39 @@ static ssize_t store_protocols(struct device *device, } } - dev->enabled_protocols = type; + dev->enabled_protocols[fattr->type] = type; IR_dprintk(1, "Current protocol(s): 0x%llx\n", (long long)type); + /* + * If the protocol is changed the filter needs updating. + * Try setting the same filter with the new protocol (if any). + * Fall back to clearing the filter. + */ + filter = &dev->scancode_filters[fattr->type]; + set_filter = (fattr->type == RC_FILTER_NORMAL) + ? dev->s_filter : dev->s_wakeup_filter; + + if (set_filter && old_type != type && filter->mask) { + local_filter = *filter; + if (!type) { + /* no protocol => clear filter */ + ret = -1; + } else { + /* hardware filtering => try setting, otherwise clear */ + ret = set_filter(dev, &local_filter); + } + if (ret < 0) { + /* clear the filter */ + local_filter.data = 0; + local_filter.mask = 0; + set_filter(dev, &local_filter); + } + + /* commit the new filter */ + *filter = local_filter; + } + ret = len; out: @@ -967,6 +1032,121 @@ out: return ret; } +/** + * show_filter() - shows the current scancode filter value or mask + * @device: the device descriptor + * @attr: the device attribute struct + * @buf: a pointer to the output buffer + * + * This routine is a callback routine to read a scancode filter value or mask. + * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask]. + * It prints the current scancode filter value or mask of the appropriate filter + * type in hexadecimal into @buf and returns the size of the buffer. + * + * Bits of the filter value corresponding to set bits in the filter mask are + * compared against input scancodes and non-matching scancodes are discarded. + * + * dev->lock is taken to guard against races between device registration, + * store_filter and show_filter. + */ +static ssize_t show_filter(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); + u32 val; + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + mutex_lock(&dev->lock); + if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) || + (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter)) + val = 0; + else if (fattr->mask) + val = dev->scancode_filters[fattr->type].mask; + else + val = dev->scancode_filters[fattr->type].data; + mutex_unlock(&dev->lock); + + return sprintf(buf, "%#x\n", val); +} + +/** + * store_filter() - changes the scancode filter value + * @device: the device descriptor + * @attr: the device attribute struct + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is for changing a scancode filter value or mask. + * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask]. + * Returns -EINVAL if an invalid filter value for the current protocol was + * specified or if scancode filtering is not supported by the driver, otherwise + * returns @len. + * + * Bits of the filter value corresponding to set bits in the filter mask are + * compared against input scancodes and non-matching scancodes are discarded. + * + * dev->lock is taken to guard against races between device registration, + * store_filter and show_filter. + */ +static ssize_t store_filter(struct device *device, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); + struct rc_scancode_filter local_filter, *filter; + int ret; + unsigned long val; + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + /* Can the scancode filter be set? */ + set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : + dev->s_wakeup_filter; + if (!set_filter) + return -EINVAL; + + mutex_lock(&dev->lock); + + /* Tell the driver about the new filter */ + filter = &dev->scancode_filters[fattr->type]; + local_filter = *filter; + if (fattr->mask) + local_filter.mask = val; + else + local_filter.data = val; + + if (!dev->enabled_protocols[fattr->type] && local_filter.mask) { + /* refuse to set a filter unless a protocol is enabled */ + ret = -EINVAL; + goto unlock; + } + + ret = set_filter(dev, &local_filter); + if (ret < 0) + goto unlock; + + /* Success, commit the new filter */ + *filter = local_filter; + +unlock: + mutex_unlock(&dev->lock); + return (ret < 0) ? ret : count; +} + static void rc_dev_release(struct device *device) { } @@ -996,25 +1176,58 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) /* * Static device attribute struct with the sysfs attributes for IR's */ -static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, - show_protocols, store_protocols); +static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols, RC_FILTER_NORMAL); +static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols, RC_FILTER_WAKEUP); +static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_NORMAL, false); +static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_NORMAL, true); +static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_WAKEUP, false); +static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_WAKEUP, true); + +static struct attribute *rc_dev_protocol_attrs[] = { + &dev_attr_protocols.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_protocol_attr_grp = { + .attrs = rc_dev_protocol_attrs, +}; -static struct attribute *rc_dev_attrs[] = { - &dev_attr_protocols.attr, +static struct attribute *rc_dev_wakeup_protocol_attrs[] = { + &dev_attr_wakeup_protocols.attr.attr, NULL, }; -static struct attribute_group rc_dev_attr_grp = { - .attrs = rc_dev_attrs, +static struct attribute_group rc_dev_wakeup_protocol_attr_grp = { + .attrs = rc_dev_wakeup_protocol_attrs, }; -static const struct attribute_group *rc_dev_attr_groups[] = { - &rc_dev_attr_grp, - NULL +static struct attribute *rc_dev_filter_attrs[] = { + &dev_attr_filter.attr.attr, + &dev_attr_filter_mask.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_filter_attr_grp = { + .attrs = rc_dev_filter_attrs, +}; + +static struct attribute *rc_dev_wakeup_filter_attrs[] = { + &dev_attr_wakeup_filter.attr.attr, + &dev_attr_wakeup_filter_mask.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_wakeup_filter_attr_grp = { + .attrs = rc_dev_wakeup_filter_attrs, }; static struct device_type rc_dev_type = { - .groups = rc_dev_attr_groups, .release = rc_dev_release, .uevent = rc_dev_uevent, }; @@ -1071,7 +1284,7 @@ int rc_register_device(struct rc_dev *dev) static bool raw_init = false; /* raw decoders loaded? */ struct rc_map *rc_map; const char *path; - int rc, devno; + int rc, devno, attr = 0; if (!dev || !dev->map_name) return -EINVAL; @@ -1091,14 +1304,6 @@ int rc_register_device(struct rc_dev *dev) if (dev->close) dev->input_dev->close = ir_close; - /* - * Take the lock here, as the device sysfs node will appear - * when device_add() is called, which may trigger an ir-keytable udev - * rule, which will in turn call show_protocols and access - * dev->enabled_protocols before it has been initialized. - */ - mutex_lock(&dev->lock); - do { devno = find_first_zero_bit(ir_core_dev_number, IRRCV_NUM_DEVICES); @@ -1107,6 +1312,24 @@ int rc_register_device(struct rc_dev *dev) return -ENOMEM; } while (test_and_set_bit(devno, ir_core_dev_number)); + dev->dev.groups = dev->sysfs_groups; + dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; + if (dev->s_filter) + dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; + if (dev->s_wakeup_filter) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp; + if (dev->change_wakeup_protocol) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp; + dev->sysfs_groups[attr++] = NULL; + + /* + * Take the lock here, as the device sysfs node will appear + * when device_add() is called, which may trigger an ir-keytable udev + * rule, which will in turn call show_protocols and access + * dev->enabled_protocols before it has been initialized. + */ + mutex_lock(&dev->lock); + dev->devno = devno; dev_set_name(&dev->dev, "rc%ld", dev->devno); dev_set_drvdata(&dev->dev, dev); @@ -1172,7 +1395,7 @@ int rc_register_device(struct rc_dev *dev) rc = dev->change_protocol(dev, &rc_type); if (rc < 0) goto out_raw; - dev->enabled_protocols = rc_type; + dev->enabled_protocols[RC_FILTER_NORMAL] = rc_type; } mutex_unlock(&dev->lock); @@ -1260,5 +1483,5 @@ int rc_core_debug; /* ir_debug level (0,1,2) */ EXPORT_SYMBOL_GPL(rc_core_debug); module_param_named(debug, rc_core_debug, int, 0644); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index a5d4f883d053..47cd373e2295 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -922,7 +922,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) rc->dev.parent = dev; rc->priv = rr3; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->timeout = US_TO_NS(2750); rc->tx_ir = redrat3_transmit_ir; rc->s_tx_carrier = redrat3_set_tx_carrier; diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 8f0cddb9e8f2..22e4c1f28ab4 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_device *pdev) st_rc_hardware_init(rc_dev); rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); /* rx sampling rate is 10Mhz */ rdev->rx_resolution = 100; rdev->timeout = US_TO_NS(MAX_SYMB_TIME); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index d7b11e6a9982..f4e0bc3d382c 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -322,7 +322,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) rdev->dev.parent = dev; rdev->priv = sz; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rdev, RC_BIT_ALL); rdev->driver_name = DRIVER_NAME; rdev->map_name = RC_MAP_STREAMZAP; diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index d8de2056a4f6..c5be38e2a2fe 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -318,7 +318,7 @@ static int ttusbir_probe(struct usb_interface *intf, usb_to_input_id(tt->udev, &rc->input_id); rc->dev.parent = &intf->dev; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(rc, RC_BIT_ALL); rc->priv = tt; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_TT_1500; diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 904baf4eec28..a8b981f5ce2e 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1082,7 +1082,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->dev.parent = &device->dev; data->dev->timeout = MS_TO_NS(100); data->dev->rx_resolution = US_TO_NS(2); - data->dev->allowed_protos = RC_BIT_ALL; + rc_set_allowed_protocols(data->dev, RC_BIT_ALL); err = rc_register_device(data->dev); if (err) |