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 */
15static 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_TYPE_SHARP;
36	request->scancode = addr << 8 | cmd;
37	return IMG_IR_SCANCODE;
38}
39
40/* Convert Sharp scancode to Sharp data filter */
41static 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 */
75struct img_ir_decoder img_ir_sharp = {
76	.type = RC_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