^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ImgTec IR Raw Decoder found in PowerDown Controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2010-2014 Imagination Technologies Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This ties into the input subsystem using the RC-core in raw mode. Raw IR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * signal edges are reported and decoded by generic software decoders.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <media/rc-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "img-ir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define ECHO_TIMEOUT_MS 150 /* ms between echos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* must be called with priv->lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct img_ir_priv_raw *raw = &priv->raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct rc_dev *rc_dev = priv->raw.rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int multiple;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u32 ir_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* find whether both rise and fall was detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * If so, we need to see if the level has actually changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * If it's just noise that we didn't have time to process,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * there's no point reporting it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (multiple && ir_status == raw->last_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) raw->last_status = ir_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* report the edge to the IR raw decoders */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (ir_status) /* low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ir_raw_event_store_edge(rc_dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) else /* high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ir_raw_event_store_edge(rc_dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ir_raw_event_handle(rc_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* called with priv->lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct img_ir_priv_raw *raw = &priv->raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* check not removing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!raw->rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) img_ir_refresh_raw(priv, irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* start / push back the echo timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Echo timer callback function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * The raw decoders expect to get a final sample even if there are no edges, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * order to be assured of the final space. If there are no edges for a certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * time we use this timer to emit a final sample to satisfy them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void img_ir_echo_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct img_ir_priv *priv = from_timer(priv, t, raw.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* check not removing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (priv->raw.rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * It's safe to pass irq_status=0 since it's only used to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * for double edges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) img_ir_refresh_raw(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void img_ir_setup_raw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 irq_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!priv->raw.rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* clear and enable edge interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) irq_en |= IMG_IR_IRQ_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int img_ir_probe_raw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct img_ir_priv_raw *raw = &priv->raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct rc_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Set up the echo timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) timer_setup(&raw->timer, img_ir_echo_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Allocate raw decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!rdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dev_err(priv->dev, "cannot allocate raw input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) rdev->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rdev->map_name = RC_MAP_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) rdev->device_name = "IMG Infrared Decoder Raw";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Register raw decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) error = rc_register_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dev_err(priv->dev, "failed to register raw IR input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rc_free_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) raw->rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void img_ir_remove_raw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct img_ir_priv_raw *raw = &priv->raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct rc_dev *rdev = raw->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 irq_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (!rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* switch off and disable raw (edge) interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) raw->rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) irq_en &= ~IMG_IR_IRQ_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) rc_unregister_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) del_timer_sync(&raw->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }