xref: /rk3399_rockchip-uboot/drivers/input/rockchip_ir.c (revision 87e4c6020eff05133e40ab8b7b0e37e6a2be37e4)
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