1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Amlogic Meson IR remote receiver 4 * 5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> 6 */ 7 8 #include <linux/device.h> 9 #include <linux/err.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/spinlock.h> 16 #include <linux/bitfield.h> 17 #include <linux/regmap.h> 18 19 #include <media/rc-core.h> 20 21 #define DRIVER_NAME "meson-ir" 22 23 #define IR_DEC_LDR_ACTIVE 0x00 24 #define IR_DEC_LDR_IDLE 0x04 25 #define IR_DEC_LDR_REPEAT 0x08 26 #define IR_DEC_BIT_0 0x0c 27 #define IR_DEC_REG0 0x10 28 #define IR_DEC_REG0_BASE_TIME GENMASK(11, 0) 29 #define IR_DEC_FRAME 0x14 30 #define IR_DEC_STATUS 0x18 31 #define IR_DEC_STATUS_PULSE BIT(8) 32 #define IR_DEC_REG1 0x1c 33 #define IR_DEC_REG1_TIME_IV GENMASK(28, 16) 34 #define IR_DEC_REG1_ENABLE BIT(15) 35 #define IR_DEC_REG1_MODE GENMASK(8, 7) 36 #define IR_DEC_REG1_IRQSEL GENMASK(3, 2) 37 #define IR_DEC_REG1_RESET BIT(0) 38 /* The following regs are only available on Meson 8b and newer */ 39 #define IR_DEC_REG2 0x20 40 #define IR_DEC_REG2_MODE GENMASK(3, 0) 41 42 #define DEC_MODE_NEC 0x0 43 #define DEC_MODE_RAW 0x2 44 45 #define IRQSEL_NEC_MODE 0 46 #define IRQSEL_RISE_FALL 1 47 #define IRQSEL_FALL 2 48 #define IRQSEL_RISE 3 49 50 #define MESON_RAW_TRATE 10 /* us */ 51 #define MESON_HW_TRATE 20 /* us */ 52 53 struct meson_ir { 54 struct regmap *reg; 55 struct rc_dev *rc; 56 spinlock_t lock; 57 }; 58 59 static const struct regmap_config meson_ir_regmap_config = { 60 .reg_bits = 32, 61 .val_bits = 32, 62 .reg_stride = 4, 63 }; 64 65 static irqreturn_t meson_ir_irq(int irqno, void *dev_id) 66 { 67 struct meson_ir *ir = dev_id; 68 u32 duration, status; 69 struct ir_raw_event rawir = {}; 70 71 spin_lock(&ir->lock); 72 73 regmap_read(ir->reg, IR_DEC_REG1, &duration); 74 duration = FIELD_GET(IR_DEC_REG1_TIME_IV, duration); 75 rawir.duration = duration * MESON_RAW_TRATE; 76 77 regmap_read(ir->reg, IR_DEC_STATUS, &status); 78 rawir.pulse = !!(status & IR_DEC_STATUS_PULSE); 79 80 ir_raw_event_store_with_timeout(ir->rc, &rawir); 81 82 spin_unlock(&ir->lock); 83 84 return IRQ_HANDLED; 85 } 86 87 static int meson_ir_probe(struct platform_device *pdev) 88 { 89 struct device *dev = &pdev->dev; 90 struct device_node *node = dev->of_node; 91 void __iomem *res_start; 92 const char *map_name; 93 struct meson_ir *ir; 94 int irq, ret; 95 96 ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); 97 if (!ir) 98 return -ENOMEM; 99 100 res_start = devm_platform_ioremap_resource(pdev, 0); 101 if (IS_ERR(res_start)) 102 return PTR_ERR(res_start); 103 104 ir->reg = devm_regmap_init_mmio(&pdev->dev, res_start, 105 &meson_ir_regmap_config); 106 if (IS_ERR(ir->reg)) 107 return PTR_ERR(ir->reg); 108 109 irq = platform_get_irq(pdev, 0); 110 if (irq < 0) 111 return irq; 112 113 ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW); 114 if (!ir->rc) { 115 dev_err(dev, "failed to allocate rc device\n"); 116 return -ENOMEM; 117 } 118 119 ir->rc->priv = ir; 120 ir->rc->device_name = DRIVER_NAME; 121 ir->rc->input_phys = DRIVER_NAME "/input0"; 122 ir->rc->input_id.bustype = BUS_HOST; 123 map_name = of_get_property(node, "linux,rc-map-name", NULL); 124 ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; 125 ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; 126 ir->rc->rx_resolution = MESON_RAW_TRATE; 127 ir->rc->min_timeout = 1; 128 ir->rc->timeout = IR_DEFAULT_TIMEOUT; 129 ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; 130 ir->rc->driver_name = DRIVER_NAME; 131 132 spin_lock_init(&ir->lock); 133 platform_set_drvdata(pdev, ir); 134 135 ret = devm_rc_register_device(dev, ir->rc); 136 if (ret) { 137 dev_err(dev, "failed to register rc device\n"); 138 return ret; 139 } 140 141 ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir); 142 if (ret) { 143 dev_err(dev, "failed to request irq\n"); 144 return ret; 145 } 146 147 /* Reset the decoder */ 148 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_RESET, 149 IR_DEC_REG1_RESET); 150 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_RESET, 0); 151 152 /* Set general operation mode (= raw/software decoding) */ 153 if (of_device_is_compatible(node, "amlogic,meson6-ir")) 154 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_MODE, 155 FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_RAW)); 156 else 157 regmap_update_bits(ir->reg, IR_DEC_REG2, IR_DEC_REG2_MODE, 158 FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_RAW)); 159 160 /* Set rate */ 161 regmap_update_bits(ir->reg, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, 162 FIELD_PREP(IR_DEC_REG0_BASE_TIME, 163 MESON_RAW_TRATE - 1)); 164 /* IRQ on rising and falling edges */ 165 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_IRQSEL, 166 FIELD_PREP(IR_DEC_REG1_IRQSEL, IRQSEL_RISE_FALL)); 167 /* Enable the decoder */ 168 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 169 IR_DEC_REG1_ENABLE); 170 171 dev_info(dev, "receiver initialized\n"); 172 173 return 0; 174 } 175 176 static void meson_ir_remove(struct platform_device *pdev) 177 { 178 struct meson_ir *ir = platform_get_drvdata(pdev); 179 unsigned long flags; 180 181 /* Disable the decoder */ 182 spin_lock_irqsave(&ir->lock, flags); 183 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0); 184 spin_unlock_irqrestore(&ir->lock, flags); 185 } 186 187 static void meson_ir_shutdown(struct platform_device *pdev) 188 { 189 struct device *dev = &pdev->dev; 190 struct device_node *node = dev->of_node; 191 struct meson_ir *ir = platform_get_drvdata(pdev); 192 unsigned long flags; 193 194 spin_lock_irqsave(&ir->lock, flags); 195 196 /* 197 * Set operation mode to NEC/hardware decoding to give 198 * bootloader a chance to power the system back on 199 */ 200 if (of_device_is_compatible(node, "amlogic,meson6-ir")) 201 regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_MODE, 202 FIELD_PREP(IR_DEC_REG1_MODE, DEC_MODE_NEC)); 203 else 204 regmap_update_bits(ir->reg, IR_DEC_REG2, IR_DEC_REG2_MODE, 205 FIELD_PREP(IR_DEC_REG2_MODE, DEC_MODE_NEC)); 206 207 /* Set rate to default value */ 208 regmap_update_bits(ir->reg, IR_DEC_REG0, IR_DEC_REG0_BASE_TIME, 209 FIELD_PREP(IR_DEC_REG0_BASE_TIME, 210 MESON_HW_TRATE - 1)); 211 212 spin_unlock_irqrestore(&ir->lock, flags); 213 } 214 215 static const struct of_device_id meson_ir_match[] = { 216 { .compatible = "amlogic,meson6-ir" }, 217 { .compatible = "amlogic,meson8b-ir" }, 218 { .compatible = "amlogic,meson-gxbb-ir" }, 219 { }, 220 }; 221 MODULE_DEVICE_TABLE(of, meson_ir_match); 222 223 static struct platform_driver meson_ir_driver = { 224 .probe = meson_ir_probe, 225 .remove_new = meson_ir_remove, 226 .shutdown = meson_ir_shutdown, 227 .driver = { 228 .name = DRIVER_NAME, 229 .of_match_table = meson_ir_match, 230 }, 231 }; 232 233 module_platform_driver(meson_ir_driver); 234 235 MODULE_DESCRIPTION("Amlogic Meson IR remote receiver driver"); 236 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 237 MODULE_LICENSE("GPL v2"); 238