1 /*
2  * ImgTec IR Decoder setup for Sharp protocol.
3  *
4  * Copyright 2012-2014 Imagination Technologies Ltd.
5  */
6 
7 #include "img-ir-hw.h"
8 
9 /* Convert Sharp data to a scancode */
10 static int img_ir_sharp_scancode(int len, u64 raw, int *scancode, u64 protocols)
11 {
12 	unsigned int addr, cmd, exp, chk;
13 
14 	if (len != 15)
15 		return -EINVAL;
16 
17 	addr = (raw >>   0) & 0x1f;
18 	cmd  = (raw >>   5) & 0xff;
19 	exp  = (raw >>  13) &  0x1;
20 	chk  = (raw >>  14) &  0x1;
21 
22 	/* validate data */
23 	if (!exp)
24 		return -EINVAL;
25 	if (chk)
26 		/* probably the second half of the message */
27 		return -EINVAL;
28 
29 	*scancode = addr << 8 | cmd;
30 	return IMG_IR_SCANCODE;
31 }
32 
33 /* Convert Sharp scancode to Sharp data filter */
34 static int img_ir_sharp_filter(const struct rc_scancode_filter *in,
35 			       struct img_ir_filter *out, u64 protocols)
36 {
37 	unsigned int addr, cmd, exp = 0, chk = 0;
38 	unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0;
39 
40 	addr   = (in->data >> 8) & 0x1f;
41 	addr_m = (in->mask >> 8) & 0x1f;
42 	cmd    = (in->data >> 0) & 0xff;
43 	cmd_m  = (in->mask >> 0) & 0xff;
44 	if (cmd_m) {
45 		/* if filtering commands, we can only match the first part */
46 		exp   = 1;
47 		exp_m = 1;
48 		chk   = 0;
49 		chk_m = 1;
50 	}
51 
52 	out->data = addr        |
53 		    cmd   <<  5 |
54 		    exp   << 13 |
55 		    chk   << 14;
56 	out->mask = addr_m      |
57 		    cmd_m <<  5 |
58 		    exp_m << 13 |
59 		    chk_m << 14;
60 
61 	return 0;
62 }
63 
64 /*
65  * Sharp decoder
66  * See also http://www.sbprojects.com/knowledge/ir/sharp.php
67  */
68 struct img_ir_decoder img_ir_sharp = {
69 	.type = RC_BIT_SHARP,
70 	.control = {
71 		.decoden = 0,
72 		.decodend2 = 1,
73 		.code_type = IMG_IR_CODETYPE_PULSEDIST,
74 		.d1validsel = 1,
75 	},
76 	/* main timings */
77 	.tolerance = 20,	/* 20% */
78 	.timings = {
79 		/* 0 symbol */
80 		.s10 = {
81 			.pulse = { 320	/* 320 us */ },
82 			.space = { 680	/* 1 ms period */ },
83 		},
84 		/* 1 symbol */
85 		.s11 = {
86 			.pulse = { 320	/* 320 us */ },
87 			.space = { 1680	/* 2 ms period */ },
88 		},
89 		/* free time */
90 		.ft = {
91 			.minlen = 15,
92 			.maxlen = 15,
93 			.ft_min = 5000,	/* 5 ms */
94 		},
95 	},
96 	/* scancode logic */
97 	.scancode = img_ir_sharp_scancode,
98 	.filter = img_ir_sharp_filter,
99 };
100