xref: /OK3568_Linux_fs/u-boot/drivers/input/rockchip_ir.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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