18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * ImgTec IR Decoder setup for Sharp protocol.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2012-2014 Imagination Technologies Ltd.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "img-ir-hw.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/* Convert Sharp data to a scancode */
118c2ecf20Sopenharmony_cistatic int img_ir_sharp_scancode(int len, u64 raw, u64 enabled_protocols,
128c2ecf20Sopenharmony_ci				 struct img_ir_scancode_req *request)
138c2ecf20Sopenharmony_ci{
148c2ecf20Sopenharmony_ci	unsigned int addr, cmd, exp, chk;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	if (len != 15)
178c2ecf20Sopenharmony_ci		return -EINVAL;
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci	addr = (raw >>   0) & 0x1f;
208c2ecf20Sopenharmony_ci	cmd  = (raw >>   5) & 0xff;
218c2ecf20Sopenharmony_ci	exp  = (raw >>  13) &  0x1;
228c2ecf20Sopenharmony_ci	chk  = (raw >>  14) &  0x1;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	/* validate data */
258c2ecf20Sopenharmony_ci	if (!exp)
268c2ecf20Sopenharmony_ci		return -EINVAL;
278c2ecf20Sopenharmony_ci	if (chk)
288c2ecf20Sopenharmony_ci		/* probably the second half of the message */
298c2ecf20Sopenharmony_ci		return -EINVAL;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	request->protocol = RC_PROTO_SHARP;
328c2ecf20Sopenharmony_ci	request->scancode = addr << 8 | cmd;
338c2ecf20Sopenharmony_ci	return IMG_IR_SCANCODE;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* Convert Sharp scancode to Sharp data filter */
378c2ecf20Sopenharmony_cistatic int img_ir_sharp_filter(const struct rc_scancode_filter *in,
388c2ecf20Sopenharmony_ci			       struct img_ir_filter *out, u64 protocols)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	unsigned int addr, cmd, exp = 0, chk = 0;
418c2ecf20Sopenharmony_ci	unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	addr   = (in->data >> 8) & 0x1f;
448c2ecf20Sopenharmony_ci	addr_m = (in->mask >> 8) & 0x1f;
458c2ecf20Sopenharmony_ci	cmd    = (in->data >> 0) & 0xff;
468c2ecf20Sopenharmony_ci	cmd_m  = (in->mask >> 0) & 0xff;
478c2ecf20Sopenharmony_ci	if (cmd_m) {
488c2ecf20Sopenharmony_ci		/* if filtering commands, we can only match the first part */
498c2ecf20Sopenharmony_ci		exp   = 1;
508c2ecf20Sopenharmony_ci		exp_m = 1;
518c2ecf20Sopenharmony_ci		chk   = 0;
528c2ecf20Sopenharmony_ci		chk_m = 1;
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	out->data = addr        |
568c2ecf20Sopenharmony_ci		    cmd   <<  5 |
578c2ecf20Sopenharmony_ci		    exp   << 13 |
588c2ecf20Sopenharmony_ci		    chk   << 14;
598c2ecf20Sopenharmony_ci	out->mask = addr_m      |
608c2ecf20Sopenharmony_ci		    cmd_m <<  5 |
618c2ecf20Sopenharmony_ci		    exp_m << 13 |
628c2ecf20Sopenharmony_ci		    chk_m << 14;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	return 0;
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/*
688c2ecf20Sopenharmony_ci * Sharp decoder
698c2ecf20Sopenharmony_ci * See also http://www.sbprojects.com/knowledge/ir/sharp.php
708c2ecf20Sopenharmony_ci */
718c2ecf20Sopenharmony_cistruct img_ir_decoder img_ir_sharp = {
728c2ecf20Sopenharmony_ci	.type = RC_PROTO_BIT_SHARP,
738c2ecf20Sopenharmony_ci	.control = {
748c2ecf20Sopenharmony_ci		.decoden = 0,
758c2ecf20Sopenharmony_ci		.decodend2 = 1,
768c2ecf20Sopenharmony_ci		.code_type = IMG_IR_CODETYPE_PULSEDIST,
778c2ecf20Sopenharmony_ci		.d1validsel = 1,
788c2ecf20Sopenharmony_ci	},
798c2ecf20Sopenharmony_ci	/* main timings */
808c2ecf20Sopenharmony_ci	.tolerance = 20,	/* 20% */
818c2ecf20Sopenharmony_ci	.timings = {
828c2ecf20Sopenharmony_ci		/* 0 symbol */
838c2ecf20Sopenharmony_ci		.s10 = {
848c2ecf20Sopenharmony_ci			.pulse = { 320	/* 320 us */ },
858c2ecf20Sopenharmony_ci			.space = { 680	/* 1 ms period */ },
868c2ecf20Sopenharmony_ci		},
878c2ecf20Sopenharmony_ci		/* 1 symbol */
888c2ecf20Sopenharmony_ci		.s11 = {
898c2ecf20Sopenharmony_ci			.pulse = { 320	/* 320 us */ },
908c2ecf20Sopenharmony_ci			.space = { 1680	/* 2 ms period */ },
918c2ecf20Sopenharmony_ci		},
928c2ecf20Sopenharmony_ci		/* free time */
938c2ecf20Sopenharmony_ci		.ft = {
948c2ecf20Sopenharmony_ci			.minlen = 15,
958c2ecf20Sopenharmony_ci			.maxlen = 15,
968c2ecf20Sopenharmony_ci			.ft_min = 5000,	/* 5 ms */
978c2ecf20Sopenharmony_ci		},
988c2ecf20Sopenharmony_ci	},
998c2ecf20Sopenharmony_ci	/* scancode logic */
1008c2ecf20Sopenharmony_ci	.scancode = img_ir_sharp_scancode,
1018c2ecf20Sopenharmony_ci	.filter = img_ir_sharp_filter,
1028c2ecf20Sopenharmony_ci};
103