1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <clk.h> 8 #include <common.h> 9 #include <dm.h> 10 #include <dm/pinctrl.h> 11 #include <errno.h> 12 #include <rc.h> 13 #include <rockchip_ir.h> 14 #include <irq-generic.h> 15 #include <irq-platform.h> 16 17 #include <linux/bitrev.h> 18 #include <linux/input.h> 19 20 #include <asm/arch/periph.h> 21 #include <asm/io.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 static struct nec_dec nec; 26 static struct rc_map *rc_map; 27 28 static int rockchip_ir_get_keycode(struct udevice *dev) 29 { 30 struct rockchip_ir_priv *priv = dev_get_priv(dev); 31 32 return priv->keycode; 33 } 34 35 static int rockchip_ir_get_repeat(struct udevice *dev) 36 { 37 struct rockchip_ir_priv *priv = dev_get_priv(dev); 38 39 return priv->repeat; 40 } 41 42 static int ir_lookup_by_scancode(struct rockchip_ir_priv *priv, 43 u32 usercode, 44 u32 scancode) 45 { 46 int i, j; 47 48 for (i = 0; i < priv->num; i++) { 49 if (rc_map[i].usercode == usercode) 50 break; 51 } 52 for (j = 0; i < priv->num && j < rc_map[i].nbuttons; j++) { 53 if (rc_map[i].scan[j].scancode == scancode) { 54 if (priv->keycode == rc_map[i].scan[j].keycode) 55 priv->repeat++; 56 else 57 priv->repeat = 0; 58 priv->keycode = rc_map[i].scan[j].keycode; 59 return 0; 60 } 61 } 62 63 priv->keycode = KEY_RESERVED; 64 priv->repeat = 0; 65 66 return -1; 67 } 68 69 static int ir_parse_keys(struct udevice *dev) 70 { 71 int i, j; 72 int len; 73 int ret; 74 int subnode; 75 int node = dev_of_offset(dev); 76 const void *blob = gd->fdt_blob; 77 78 i = 0; 79 fdt_for_each_subnode(subnode, blob, node) { 80 rc_map[i].usercode = fdtdec_get_uint(blob, subnode, 81 "rockchip,usercode", 82 1234u); 83 if (rc_map[i].usercode == 1234u) { 84 debug("missing usercode property in the dts\n"); 85 return -1; 86 } 87 debug("add new usercode:0x%x\n", rc_map[i].usercode); 88 fdt_get_property(blob, subnode, "rockchip,key_table", &len); 89 len /= sizeof(u32); 90 debug("len:%d\n", len); 91 rc_map[i].nbuttons = len / 2; 92 ret = fdtdec_get_int_array(blob, subnode, "rockchip,key_table", 93 (u32 *)rc_map[i].scan, len); 94 if (ret) { 95 debug("missing key_table property in the dts\n"); 96 return -1; 97 } 98 for (j = 0; j < (len / 2); j++) { 99 debug("[%d],usercode=0x%x scancode=0x%x keycode=0x%x\n", 100 i, 101 rc_map[i].usercode, 102 rc_map[i].scan[j].scancode, 103 rc_map[i].scan[j].keycode); 104 } 105 i++; 106 } 107 108 return 0; 109 } 110 111 /** 112 * ir_nec_decode() - Decode one NEC pulse or space 113 * @duration: the struct ir_raw_event descriptor of the pulse/space 114 */ 115 static int ir_nec_decode(struct rockchip_ir_priv *priv, struct ir_raw_event *ev) 116 { 117 int ret; 118 u32 usercode; 119 u32 scancode; 120 u8 __maybe_unused address, not_address, command, not_command; 121 struct nec_dec *data = &nec; 122 123 debug("NEC decode started at state %d (%uus %s)\n", 124 data->state, TO_US(ev->duration), TO_STR(ev->pulse)); 125 126 switch (data->state) { 127 case STATE_INACTIVE: 128 if (!ev->pulse) 129 break; 130 131 if (!eq_margin(ev->duration, NEC_HEADER_PULSE, NEC_UNIT * 2)) 132 break; 133 134 data->count = 0; 135 data->state = STATE_HEADER_SPACE; 136 return 0; 137 138 case STATE_HEADER_SPACE: 139 if (ev->pulse) 140 break; 141 142 if (eq_margin(ev->duration, NEC_HEADER_SPACE, NEC_UNIT)) { 143 data->state = STATE_BIT_PULSE; 144 return 0; 145 } 146 147 break; 148 149 case STATE_BIT_PULSE: 150 if (!ev->pulse) 151 break; 152 153 if (!eq_margin(ev->duration, NEC_BIT_PULSE, NEC_UNIT / 2)) 154 break; 155 156 data->state = STATE_BIT_SPACE; 157 return 0; 158 159 case STATE_BIT_SPACE: 160 if (ev->pulse) 161 break; 162 163 data->bits <<= 1; 164 if (eq_margin(ev->duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) 165 data->bits |= 1; 166 else if (!eq_margin(ev->duration, NEC_BIT_0_SPACE, 167 NEC_UNIT / 2)) 168 break; 169 data->count++; 170 171 if (data->count == NEC_NBITS) { 172 address = ((data->bits >> 24) & 0xff); 173 not_address = ((data->bits >> 16) & 0xff); 174 command = ((data->bits >> 8) & 0xff); 175 not_command = ((data->bits >> 0) & 0xff); 176 177 if ((command ^ not_command) != 0xff) { 178 debug("NEC checksum error: received 0x%08x\n", 179 data->bits); 180 } 181 usercode = address << 8 | not_address; 182 scancode = command << 8 | not_command; 183 debug("raw usercode 0x%04x scancode 0x%04x\n", 184 usercode, scancode); 185 /* change to dts format */ 186 usercode = bitrev16(usercode); 187 scancode = (bitrev16(scancode) >> 8) & 0xFF; 188 189 data->state = STATE_INACTIVE; 190 ret = ir_lookup_by_scancode(priv, usercode, scancode); 191 if (!ret) 192 debug("keycode 0x%02x repeat 0x%x\n", 193 priv->keycode, priv->repeat); 194 else 195 debug("ir lookup by scancode failed\n"); 196 } else { 197 data->state = STATE_BIT_PULSE; 198 } 199 200 return 0; 201 } 202 203 debug("NEC decode failed at count %d state %d (%uus %s)\n", 204 data->count, data->state, TO_US(ev->duration), TO_STR(ev->pulse)); 205 data->state = STATE_INACTIVE; 206 207 return -1; 208 } 209 210 static void rockchip_ir_irq(int irq, void *data) 211 { 212 u32 val; 213 u32 cycle_hpr, cycle_lpr, cycle; 214 struct ir_raw_event ev; 215 struct rockchip_ir_priv *priv = (struct rockchip_ir_priv *)data; 216 217 val = readl(priv->base + PWM_STA_REG(priv->id)); 218 cycle_hpr = readl(priv->base + PWM_HPR_REG); 219 cycle_lpr = readl(priv->base + PWM_LPR_REG); 220 if (val & PWM_CH_POL(priv->id)) { 221 cycle = cycle_hpr; 222 ev.pulse = 0; 223 } else { 224 cycle = cycle_lpr; 225 ev.pulse = 1; 226 } 227 writel(PWM_CH_INT(priv->id), 228 priv->base + PWM_STA_REG(priv->id)); 229 ev.duration = cycle * priv->period; 230 ir_nec_decode(priv, &ev); 231 } 232 233 static void rockchip_ir_hw_init(struct udevice *dev) 234 { 235 unsigned long tmp; 236 struct rockchip_ir_priv *priv = dev_get_priv(dev); 237 238 /* Enable capture mode, non-scaled clock, prescale 1 */ 239 writel(REG_CTL_MD, priv->base + PWM_CTL_REG); 240 241 /* Clear Interrupt Status */ 242 writel(PWM_CH_INT(priv->id), 243 priv->base + PWM_STA_REG(priv->id)); 244 245 /* Enable IRQ */ 246 writel(PWM_CH_INT(priv->id), 247 priv->base + PWM_INT_REG(priv->id)); 248 249 /* Enable IR Module */ 250 tmp = readl(priv->base + PWM_CTL_REG); 251 writel(tmp | REG_CTL_EN, priv->base + PWM_CTL_REG); 252 } 253 254 static int rockchip_ir_ofdata_to_platdata(struct udevice *dev) 255 { 256 int node = dev_of_offset(dev); 257 const void *blob = gd->fdt_blob; 258 struct rockchip_ir_priv *priv = dev_get_priv(dev); 259 260 priv->num = fdtdec_get_child_count(blob, node); 261 if (priv->num == 0) { 262 debug("no ir map in dts\n"); 263 return -1; 264 } 265 priv->base = devfdt_get_addr(dev); 266 priv->id = (priv->base >> 4) & 0xF; 267 268 return 0; 269 } 270 271 static int rockchip_ir_probe(struct udevice *dev) 272 { 273 int ret; 274 struct clk clk; 275 struct udevice *pinctrl; 276 struct rockchip_ir_priv *priv = dev_get_priv(dev); 277 278 rc_map = calloc(1, priv->num * sizeof(struct rc_map)); 279 if (!rc_map) { 280 debug("%s: failed to calloc\n", __func__); 281 return -EINVAL; 282 } 283 284 ret = ir_parse_keys(dev); 285 if (ret) { 286 debug("%s: failed to parse keys\n", __func__); 287 return -EINVAL; 288 } 289 290 /* 291 * The PWM does not have decicated interrupt number in dts and can 292 * not get periph_id by pinctrl framework, so let's init then here. 293 */ 294 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 295 if (ret) { 296 debug("%s: can't find pinctrl device\n", __func__); 297 return -EINVAL; 298 } 299 300 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM0 + priv->id); 301 if (ret) { 302 debug("%s pwm%d pinctrl init fail\n", __func__, priv->id); 303 return -EINVAL; 304 } 305 306 ret = clk_get_by_index(dev, 0, &clk); 307 if (ret) { 308 debug("%s get clock fail!\n", __func__); 309 return -EINVAL; 310 } 311 priv->freq = clk_get_rate(&clk); 312 debug("%s pwm clk = %lu\n", __func__, priv->freq); 313 priv->period = 1000000000 / priv->freq; 314 315 irq_install_handler(IRQ_PWM, 316 (interrupt_handler_t *)rockchip_ir_irq, priv); 317 irq_handler_enable(IRQ_PWM); 318 319 rockchip_ir_hw_init(dev); 320 321 return ret; 322 } 323 324 static const struct dm_rc_ops rockchip_ir_ops = { 325 .get_keycode = rockchip_ir_get_keycode, 326 .get_repeat = rockchip_ir_get_repeat, 327 }; 328 329 static const struct udevice_id rockchip_ir_ids[] = { 330 { .compatible = "rockchip,remotectl-pwm" }, 331 { } 332 }; 333 334 U_BOOT_DRIVER(rockchip_ir) = { 335 .name = "rockchip_ir", 336 .id = UCLASS_RC, 337 .of_match = rockchip_ir_ids, 338 .ofdata_to_platdata = rockchip_ir_ofdata_to_platdata, 339 .probe = rockchip_ir_probe, 340 .ops = &rockchip_ir_ops, 341 .priv_auto_alloc_size = sizeof(struct rockchip_ir_priv), 342 }; 343