1 /*
2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <clk.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 #include <dm/ofnode.h>
23 DECLARE_GLOBAL_DATA_PTR;
24
25 static struct nec_dec nec;
26 static struct rc_map *rc_map;
27
rockchip_ir_get_keycode(struct udevice * dev)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
rockchip_ir_get_repeat(struct udevice * dev)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
ir_lookup_by_scancode(struct rockchip_ir_priv * priv,u32 usercode,u32 scancode)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
ir_parse_keys(struct udevice * dev)69 static int ir_parse_keys(struct udevice *dev)
70 {
71 int i, j;
72 int len;
73 int ret;
74 u32 val;
75 ofnode node;
76
77 i = 0;
78 dev_for_each_subnode(node, dev) {
79 ret = ofnode_read_u32(node, "rockchip,usercode", &val);
80 if (ret) {
81 debug("unable to get usercode\n");
82 return -1;
83 }
84 rc_map[i].usercode = val;
85 if (rc_map[i].usercode == 0) {
86 debug("missing usercode property in the dts\n");
87 return -1;
88 }
89 debug("add new usercode:0x%x\n", rc_map[i].usercode);
90 len = ofnode_read_size(node, "rockchip,key_table");
91 len /= sizeof(u32);
92 debug("len:%d\n", len);
93 rc_map[i].nbuttons = len / 2;
94
95 ret = ofnode_read_u32_array(node, "rockchip,key_table",
96 (u32 *)rc_map[i].scan, len);
97 if (ret) {
98 debug("missing key_table property in the dts\n");
99 return -1;
100 }
101 for (j = 0; j < (len / 2); j++) {
102 debug("[%d],usercode=0x%x scancode=0x%x keycode=0x%x\n",
103 i,
104 rc_map[i].usercode,
105 rc_map[i].scan[j].scancode,
106 rc_map[i].scan[j].keycode);
107 }
108 i++;
109 }
110
111 return 0;
112 }
113
114 /**
115 * ir_nec_decode() - Decode one NEC pulse or space
116 * @duration: the struct ir_raw_event descriptor of the pulse/space
117 */
ir_nec_decode(struct rockchip_ir_priv * priv,struct ir_raw_event * ev)118 static int ir_nec_decode(struct rockchip_ir_priv *priv, struct ir_raw_event *ev)
119 {
120 int ret;
121 u32 usercode;
122 u32 scancode;
123 u8 __maybe_unused address, not_address, command, not_command;
124 struct nec_dec *data = &nec;
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 }
170 data->count++;
171
172 if (data->count == NEC_NBITS) {
173 address = ((data->bits >> 24) & 0xff);
174 not_address = ((data->bits >> 16) & 0xff);
175 command = ((data->bits >> 8) & 0xff);
176 not_command = ((data->bits >> 0) & 0xff);
177
178 if ((command ^ not_command) != 0xff) {
179 debug("NEC checksum error: received 0x%08x\n",
180 data->bits);
181 }
182 usercode = address << 8 | not_address;
183 scancode = command << 8 | not_command;
184
185 /* change to dts format */
186 usercode = bitrev16(usercode);
187 scancode = (bitrev16(scancode) >> 8) & 0xFF;
188 debug("usercode 0x%04x scancode 0x%04x\n",
189 usercode, scancode);
190
191 data->state = STATE_INACTIVE;
192 ret = ir_lookup_by_scancode(priv, usercode, scancode);
193 if (!ret)
194 debug("keycode 0x%02x repeat 0x%x\n",
195 priv->keycode, priv->repeat);
196 else
197 debug("ir lookup by scancode failed\n");
198 } else {
199 data->state = STATE_BIT_PULSE;
200 }
201
202 return 0;
203 }
204
205 debug("NEC decode failed at count %d state %d (%uus %s)\n",
206 data->count, data->state, TO_US(ev->duration), TO_STR(ev->pulse));
207 data->state = STATE_INACTIVE;
208
209 return -1;
210 }
211
rockchip_ir_irq(int irq,void * data)212 static void rockchip_ir_irq(int irq, void *data)
213 {
214 u32 val;
215 u32 cycle_hpr, cycle_lpr, cycle;
216 struct ir_raw_event ev;
217 struct rockchip_ir_priv *priv = (struct rockchip_ir_priv *)data;
218
219 val = readl(priv->base + PWM_STA_REG(priv->id));
220 cycle_hpr = readl(priv->base + PWM_HPR_REG);
221 cycle_lpr = readl(priv->base + PWM_LPR_REG);
222 if (val & PWM_CH_POL(priv->id)) {
223 cycle = cycle_hpr;
224 ev.pulse = 0;
225 } else {
226 cycle = cycle_lpr;
227 ev.pulse = 1;
228 }
229 writel(PWM_CH_INT(priv->id),
230 priv->base + PWM_STA_REG(priv->id));
231
232 ev.duration = cycle * priv->period;
233 ir_nec_decode(priv, &ev);
234 }
235
rockchip_ir_hw_init(struct udevice * dev)236 static void rockchip_ir_hw_init(struct udevice *dev)
237 {
238 unsigned long tmp;
239 struct rockchip_ir_priv *priv = dev_get_priv(dev);
240
241 /* Enable capture mode, non-scaled clock, prescale 1 */
242 writel(REG_CTL_MD, priv->base + PWM_CTL_REG);
243
244 /* Clear Interrupt Status */
245 writel(PWM_CH_INT(priv->id),
246 priv->base + PWM_STA_REG(priv->id));
247
248 /* Enable IRQ */
249 writel(PWM_CH_INT(priv->id),
250 priv->base + PWM_INT_REG(priv->id));
251
252 /* Enable IR Module */
253 tmp = readl(priv->base + PWM_CTL_REG);
254 writel(tmp | REG_CTL_EN, priv->base + PWM_CTL_REG);
255 }
256
rockchip_ir_ofdata_to_platdata(struct udevice * dev)257 static int rockchip_ir_ofdata_to_platdata(struct udevice *dev)
258 {
259 ofnode node;
260 int ret;
261 int subnode_num = 0;
262 u32 val;
263 struct rockchip_ir_priv *priv = dev_get_priv(dev);
264
265 dev_for_each_subnode(node, dev) {
266 ret = ofnode_read_u32(node, "rockchip,usercode", &val);
267 if (!ret)
268 subnode_num++;
269 }
270
271 priv->num = subnode_num;
272
273 if (priv->num == 0) {
274 debug("no ir map in dts\n");
275 return -1;
276 }
277 priv->base = dev_read_addr(dev);
278 priv->id = (priv->base >> 4) & 0xF;
279
280 return 0;
281 }
282
rockchip_ir_probe(struct udevice * dev)283 static int rockchip_ir_probe(struct udevice *dev)
284 {
285 int ret;
286 struct clk clk;
287 struct udevice *pinctrl;
288 struct rockchip_ir_priv *priv = dev_get_priv(dev);
289
290 rc_map = calloc(1, priv->num * sizeof(struct rc_map));
291 if (!rc_map) {
292 debug("%s: failed to calloc\n", __func__);
293 return -EINVAL;
294 }
295
296 ret = ir_parse_keys(dev);
297 if (ret) {
298 debug("%s: failed to parse keys\n", __func__);
299 return -EINVAL;
300 }
301 /*
302 * The PWM does not have decicated interrupt number in dts and can
303 * not get periph_id by pinctrl framework, so let's init then here.
304 */
305 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
306 if (ret) {
307 debug("%s: can't find pinctrl device\n", __func__);
308 return -EINVAL;
309 }
310
311 ret = clk_get_by_index(dev, 0, &clk);
312 if (ret) {
313 debug("%s get clock fail!\n", __func__);
314 return -EINVAL;
315 }
316 priv->freq = clk_get_rate(&clk);
317 debug("%s pwm clk = %lu\n", __func__, priv->freq);
318 priv->period = 1000000000 / priv->freq;
319
320 irq_install_handler(IRQ_PWM,
321 (interrupt_handler_t *)rockchip_ir_irq, priv);
322 irq_handler_enable(IRQ_PWM);
323
324 rockchip_ir_hw_init(dev);
325
326 return ret;
327 }
328
329 static const struct dm_rc_ops rockchip_ir_ops = {
330 .get_keycode = rockchip_ir_get_keycode,
331 .get_repeat = rockchip_ir_get_repeat,
332 };
333
334 static const struct udevice_id rockchip_ir_ids[] = {
335 { .compatible = "rockchip,remotectl-pwm" },
336 { }
337 };
338
339 U_BOOT_DRIVER(rockchip_ir) = {
340 .name = "rockchip_ir",
341 .id = UCLASS_RC,
342 .of_match = rockchip_ir_ids,
343 .ofdata_to_platdata = rockchip_ir_ofdata_to_platdata,
344 .probe = rockchip_ir_probe,
345 .ops = &rockchip_ir_ops,
346 .priv_auto_alloc_size = sizeof(struct rockchip_ir_priv),
347 };
348