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