0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/spinlock.h>
0012 #include <media/rc-core.h>
0013 #include "img-ir.h"
0014
0015 #define ECHO_TIMEOUT_MS 150
0016
0017
0018 static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status)
0019 {
0020 struct img_ir_priv_raw *raw = &priv->raw;
0021 struct rc_dev *rc_dev = priv->raw.rdev;
0022 int multiple;
0023 u32 ir_status;
0024
0025
0026 multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE);
0027
0028
0029
0030
0031
0032 ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD;
0033 if (multiple && ir_status == raw->last_status)
0034 return;
0035 raw->last_status = ir_status;
0036
0037
0038 if (ir_status)
0039 ir_raw_event_store_edge(rc_dev, false);
0040 else
0041 ir_raw_event_store_edge(rc_dev, true);
0042 ir_raw_event_handle(rc_dev);
0043 }
0044
0045
0046 void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
0047 {
0048 struct img_ir_priv_raw *raw = &priv->raw;
0049
0050
0051 if (!raw->rdev)
0052 return;
0053
0054 img_ir_refresh_raw(priv, irq_status);
0055
0056
0057 mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS));
0058 }
0059
0060
0061
0062
0063
0064
0065
0066 static void img_ir_echo_timer(struct timer_list *t)
0067 {
0068 struct img_ir_priv *priv = from_timer(priv, t, raw.timer);
0069
0070 spin_lock_irq(&priv->lock);
0071
0072
0073 if (priv->raw.rdev)
0074
0075
0076
0077
0078 img_ir_refresh_raw(priv, 0);
0079
0080 spin_unlock_irq(&priv->lock);
0081 }
0082
0083 void img_ir_setup_raw(struct img_ir_priv *priv)
0084 {
0085 u32 irq_en;
0086
0087 if (!priv->raw.rdev)
0088 return;
0089
0090
0091 spin_lock_irq(&priv->lock);
0092 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
0093 irq_en |= IMG_IR_IRQ_EDGE;
0094 img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
0095 img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
0096 spin_unlock_irq(&priv->lock);
0097 }
0098
0099 int img_ir_probe_raw(struct img_ir_priv *priv)
0100 {
0101 struct img_ir_priv_raw *raw = &priv->raw;
0102 struct rc_dev *rdev;
0103 int error;
0104
0105
0106 timer_setup(&raw->timer, img_ir_echo_timer, 0);
0107
0108
0109 raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
0110 if (!rdev) {
0111 dev_err(priv->dev, "cannot allocate raw input device\n");
0112 return -ENOMEM;
0113 }
0114 rdev->priv = priv;
0115 rdev->map_name = RC_MAP_EMPTY;
0116 rdev->device_name = "IMG Infrared Decoder Raw";
0117
0118
0119 error = rc_register_device(rdev);
0120 if (error) {
0121 dev_err(priv->dev, "failed to register raw IR input device\n");
0122 rc_free_device(rdev);
0123 raw->rdev = NULL;
0124 return error;
0125 }
0126
0127 return 0;
0128 }
0129
0130 void img_ir_remove_raw(struct img_ir_priv *priv)
0131 {
0132 struct img_ir_priv_raw *raw = &priv->raw;
0133 struct rc_dev *rdev = raw->rdev;
0134 u32 irq_en;
0135
0136 if (!rdev)
0137 return;
0138
0139
0140 spin_lock_irq(&priv->lock);
0141 raw->rdev = NULL;
0142 irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
0143 irq_en &= ~IMG_IR_IRQ_EDGE;
0144 img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
0145 img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
0146 spin_unlock_irq(&priv->lock);
0147
0148 rc_unregister_device(rdev);
0149
0150 del_timer_sync(&raw->timer);
0151 }