From patchwork Fri Dec 13 15:12:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hogan X-Patchwork-Id: 3340951 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4DE3C9F380 for ; Fri, 13 Dec 2013 15:15:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0A736201B7 for ; Fri, 13 Dec 2013 15:15:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 41EC0204FB for ; Fri, 13 Dec 2013 15:15:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752524Ab3LMPPl (ORCPT ); Fri, 13 Dec 2013 10:15:41 -0500 Received: from multi.imgtec.com ([194.200.65.239]:53942 "EHLO multi.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753417Ab3LMPPA (ORCPT ); Fri, 13 Dec 2013 10:15:00 -0500 From: James Hogan To: Mauro Carvalho Chehab , CC: James Hogan Subject: [PATCH 03/11] media: rc: img-ir: add raw driver Date: Fri, 13 Dec 2013 15:12:51 +0000 Message-ID: <1386947579-26703-4-git-send-email-james.hogan@imgtec.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1386947579-26703-1-git-send-email-james.hogan@imgtec.com> References: <1386947579-26703-1-git-send-email-james.hogan@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.154.65] X-SEF-Processed: 7_3_0_01192__2013_12_13_15_14_56 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add raw IR remote control input driver for the ImgTec Infrared decoder block raw edge interrupts. Generic software protocol decoders are used to allow multiple protocols to be supported at a time, including those not supported by the hardware decoder. Signed-off-by: James Hogan Cc: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org --- drivers/media/rc/img-ir/img-ir-raw.c | 107 +++++++++++++++++++++++++++++++++++ drivers/media/rc/img-ir/img-ir-raw.h | 58 +++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 drivers/media/rc/img-ir/img-ir-raw.c create mode 100644 drivers/media/rc/img-ir/img-ir-raw.h 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..7e90300d6daf --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -0,0 +1,107 @@ +/* + * ImgTec IR Raw Decoder found in PowerDown Controller. + * + * Copyright 2010-2013 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 +#include +#include "img-ir.h" + +void img_ir_isr_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); +} + +void img_ir_setup_raw(struct img_ir_priv *priv) +{ + u32 irq_en; + unsigned long flags; + + if (!priv->raw.rdev) + return; + + /* clear and enable edge interrupts */ + spin_lock_irqsave(&priv->lock, flags); + 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_irqrestore(&priv->lock, flags); +} + +int img_ir_probe_raw(struct img_ir_priv *priv) +{ + struct img_ir_priv_raw *raw = &priv->raw; + struct rc_dev *rdev; + int error; + + /* 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; + unsigned long flags; + u32 irq_en; + + if (!rdev) + return; + + /* switch off and disable raw (edge) interrupts */ + spin_lock_irqsave(&priv->lock, flags); + 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_irqrestore(&priv->lock, flags); + + rc_unregister_device(rdev); +} 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..d302a65e19dc --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-raw.h @@ -0,0 +1,58 @@ +/* + * ImgTec IR Raw Decoder found in PowerDown Controller. + * + * Copyright 2010-2013 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 + * @last_status: Last raw status bits. + */ +struct img_ir_priv_raw { + struct rc_dev *rdev; + 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_ */