162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ImgTec IR Decoder setup for Sharp protocol.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2012-2014 Imagination Technologies Ltd.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "img-ir-hw.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/* Convert Sharp data to a scancode */
1162306a36Sopenharmony_cistatic int img_ir_sharp_scancode(int len, u64 raw, u64 enabled_protocols,
1262306a36Sopenharmony_ci				 struct img_ir_scancode_req *request)
1362306a36Sopenharmony_ci{
1462306a36Sopenharmony_ci	unsigned int addr, cmd, exp, chk;
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	if (len != 15)
1762306a36Sopenharmony_ci		return -EINVAL;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	addr = (raw >>   0) & 0x1f;
2062306a36Sopenharmony_ci	cmd  = (raw >>   5) & 0xff;
2162306a36Sopenharmony_ci	exp  = (raw >>  13) &  0x1;
2262306a36Sopenharmony_ci	chk  = (raw >>  14) &  0x1;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	/* validate data */
2562306a36Sopenharmony_ci	if (!exp)
2662306a36Sopenharmony_ci		return -EINVAL;
2762306a36Sopenharmony_ci	if (chk)
2862306a36Sopenharmony_ci		/* probably the second half of the message */
2962306a36Sopenharmony_ci		return -EINVAL;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	request->protocol = RC_PROTO_SHARP;
3262306a36Sopenharmony_ci	request->scancode = addr << 8 | cmd;
3362306a36Sopenharmony_ci	return IMG_IR_SCANCODE;
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* Convert Sharp scancode to Sharp data filter */
3762306a36Sopenharmony_cistatic int img_ir_sharp_filter(const struct rc_scancode_filter *in,
3862306a36Sopenharmony_ci			       struct img_ir_filter *out, u64 protocols)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	unsigned int addr, cmd, exp = 0, chk = 0;
4162306a36Sopenharmony_ci	unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	addr   = (in->data >> 8) & 0x1f;
4462306a36Sopenharmony_ci	addr_m = (in->mask >> 8) & 0x1f;
4562306a36Sopenharmony_ci	cmd    = (in->data >> 0) & 0xff;
4662306a36Sopenharmony_ci	cmd_m  = (in->mask >> 0) & 0xff;
4762306a36Sopenharmony_ci	if (cmd_m) {
4862306a36Sopenharmony_ci		/* if filtering commands, we can only match the first part */
4962306a36Sopenharmony_ci		exp   = 1;
5062306a36Sopenharmony_ci		exp_m = 1;
5162306a36Sopenharmony_ci		chk   = 0;
5262306a36Sopenharmony_ci		chk_m = 1;
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	out->data = addr        |
5662306a36Sopenharmony_ci		    cmd   <<  5 |
5762306a36Sopenharmony_ci		    exp   << 13 |
5862306a36Sopenharmony_ci		    chk   << 14;
5962306a36Sopenharmony_ci	out->mask = addr_m      |
6062306a36Sopenharmony_ci		    cmd_m <<  5 |
6162306a36Sopenharmony_ci		    exp_m << 13 |
6262306a36Sopenharmony_ci		    chk_m << 14;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	return 0;
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci/*
6862306a36Sopenharmony_ci * Sharp decoder
6962306a36Sopenharmony_ci * See also http://www.sbprojects.com/knowledge/ir/sharp.php
7062306a36Sopenharmony_ci */
7162306a36Sopenharmony_cistruct img_ir_decoder img_ir_sharp = {
7262306a36Sopenharmony_ci	.type = RC_PROTO_BIT_SHARP,
7362306a36Sopenharmony_ci	.control = {
7462306a36Sopenharmony_ci		.decoden = 0,
7562306a36Sopenharmony_ci		.decodend2 = 1,
7662306a36Sopenharmony_ci		.code_type = IMG_IR_CODETYPE_PULSEDIST,
7762306a36Sopenharmony_ci		.d1validsel = 1,
7862306a36Sopenharmony_ci	},
7962306a36Sopenharmony_ci	/* main timings */
8062306a36Sopenharmony_ci	.tolerance = 20,	/* 20% */
8162306a36Sopenharmony_ci	.timings = {
8262306a36Sopenharmony_ci		/* 0 symbol */
8362306a36Sopenharmony_ci		.s10 = {
8462306a36Sopenharmony_ci			.pulse = { 320	/* 320 us */ },
8562306a36Sopenharmony_ci			.space = { 680	/* 1 ms period */ },
8662306a36Sopenharmony_ci		},
8762306a36Sopenharmony_ci		/* 1 symbol */
8862306a36Sopenharmony_ci		.s11 = {
8962306a36Sopenharmony_ci			.pulse = { 320	/* 320 us */ },
9062306a36Sopenharmony_ci			.space = { 1680	/* 2 ms period */ },
9162306a36Sopenharmony_ci		},
9262306a36Sopenharmony_ci		/* free time */
9362306a36Sopenharmony_ci		.ft = {
9462306a36Sopenharmony_ci			.minlen = 15,
9562306a36Sopenharmony_ci			.maxlen = 15,
9662306a36Sopenharmony_ci			.ft_min = 5000,	/* 5 ms */
9762306a36Sopenharmony_ci		},
9862306a36Sopenharmony_ci	},
9962306a36Sopenharmony_ci	/* scancode logic */
10062306a36Sopenharmony_ci	.scancode = img_ir_sharp_scancode,
10162306a36Sopenharmony_ci	.filter = img_ir_sharp_filter,
10262306a36Sopenharmony_ci};
103