1178825Sdfr// SPDX-License-Identifier: GPL-2.0-or-later 2233294Sstas/* 3233294Sstas * ImgTec IR Decoder setup for Sony (SIRC) protocol. 4233294Sstas * 5178825Sdfr * Copyright 2012-2014 Imagination Technologies Ltd. 6233294Sstas */ 7178825Sdfr 8233294Sstas#include "img-ir-hw.h" 9233294Sstas 10233294Sstas/* Convert Sony data to a scancode */ 11178825Sdfrstatic int img_ir_sony_scancode(int len, u64 raw, u64 enabled_protocols, 12233294Sstas struct img_ir_scancode_req *request) 13233294Sstas{ 14178825Sdfr unsigned int dev, subdev, func; 15233294Sstas 16233294Sstas switch (len) { 17233294Sstas case 12: 18178825Sdfr if (!(enabled_protocols & RC_PROTO_BIT_SONY12)) 19233294Sstas return -EINVAL; 20233294Sstas func = raw & 0x7f; /* first 7 bits */ 21233294Sstas raw >>= 7; 22178825Sdfr dev = raw & 0x1f; /* next 5 bits */ 23233294Sstas subdev = 0; 24233294Sstas request->protocol = RC_PROTO_SONY12; 25233294Sstas break; 26233294Sstas case 15: 27233294Sstas if (!(enabled_protocols & RC_PROTO_BIT_SONY15)) 28233294Sstas return -EINVAL; 29233294Sstas func = raw & 0x7f; /* first 7 bits */ 30233294Sstas raw >>= 7; 31233294Sstas dev = raw & 0xff; /* next 8 bits */ 32233294Sstas subdev = 0; 33233294Sstas request->protocol = RC_PROTO_SONY15; 34178825Sdfr break; 35178825Sdfr case 20: 36178825Sdfr if (!(enabled_protocols & RC_PROTO_BIT_SONY20)) 37178825Sdfr return -EINVAL; 38178825Sdfr func = raw & 0x7f; /* first 7 bits */ 39178825Sdfr raw >>= 7; 40178825Sdfr dev = raw & 0x1f; /* next 5 bits */ 41178825Sdfr raw >>= 5; 42178825Sdfr subdev = raw & 0xff; /* next 8 bits */ 43178825Sdfr request->protocol = RC_PROTO_SONY20; 44178825Sdfr break; 45178825Sdfr default: 46178825Sdfr return -EINVAL; 47233294Sstas } 48178825Sdfr request->scancode = dev << 16 | subdev << 8 | func; 49178825Sdfr return IMG_IR_SCANCODE; 50178825Sdfr} 51178825Sdfr 52178825Sdfr/* Convert NEC scancode to NEC data filter */ 53178825Sdfrstatic int img_ir_sony_filter(const struct rc_scancode_filter *in, 54234027Sstas struct img_ir_filter *out, u64 protocols) 55233294Sstas{ 56234027Sstas unsigned int dev, subdev, func; 57233294Sstas unsigned int dev_m, subdev_m, func_m; 58178825Sdfr unsigned int len = 0; 59178825Sdfr 60178825Sdfr dev = (in->data >> 16) & 0xff; 61178825Sdfr dev_m = (in->mask >> 16) & 0xff; 62178825Sdfr subdev = (in->data >> 8) & 0xff; 63178825Sdfr subdev_m = (in->mask >> 8) & 0xff; 64178825Sdfr func = (in->data >> 0) & 0x7f; 65178825Sdfr func_m = (in->mask >> 0) & 0x7f; 66178825Sdfr 67178825Sdfr protocols &= RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | 68178825Sdfr RC_PROTO_BIT_SONY20; 69178825Sdfr 70233294Sstas /* 71178825Sdfr * If only one bit is set, we were requested to do an exact 72178825Sdfr * protocol. This should be the case for wakeup filters; for 73233294Sstas * normal filters, guess the protocol from the scancode. 74233294Sstas */ 75178825Sdfr if (!is_power_of_2(protocols)) { 76178825Sdfr if (subdev & subdev_m) 77178825Sdfr protocols = RC_PROTO_BIT_SONY20; 78178825Sdfr else if (dev & dev_m & 0xe0) 79178825Sdfr protocols = RC_PROTO_BIT_SONY15; 80178825Sdfr else 81178825Sdfr protocols = RC_PROTO_BIT_SONY12; 82233294Sstas } 83233294Sstas 84178825Sdfr if (protocols == RC_PROTO_BIT_SONY20) { 85178825Sdfr /* can't encode subdev and higher device bits */ 86178825Sdfr if (dev & dev_m & 0xe0) 87178825Sdfr return -EINVAL; 88178825Sdfr len = 20; 89178825Sdfr dev_m &= 0x1f; 90178825Sdfr } else if (protocols == RC_PROTO_BIT_SONY15) { 91178825Sdfr len = 15; 92178825Sdfr subdev_m = 0; 93178825Sdfr } else { 94178825Sdfr /* 95178825Sdfr * The hardware mask cannot distinguish high device bits and low 96178825Sdfr * extended bits, so logically AND those bits of the masks 97178825Sdfr * together. 98178825Sdfr */ 99178825Sdfr subdev_m &= (dev_m >> 5) | 0xf8; 100233294Sstas dev_m &= 0x1f; 101178825Sdfr } 102233294Sstas 103233294Sstas /* ensure there aren't any bits straying between fields */ 104233294Sstas dev &= dev_m; 105233294Sstas subdev &= subdev_m; 106178825Sdfr 107178825Sdfr /* write the hardware filter */ 108178825Sdfr out->data = func | 109178825Sdfr dev << 7 | 110233294Sstas subdev << 15; 111178825Sdfr out->mask = func_m | 112178825Sdfr dev_m << 7 | 113233294Sstas subdev_m << 15; 114178825Sdfr 115178825Sdfr if (len) { 116178825Sdfr out->minlen = len; 117178825Sdfr out->maxlen = len; 118178825Sdfr } 119178825Sdfr return 0; 120178825Sdfr} 121233294Sstas 122178825Sdfr/* 123234027Sstas * Sony SIRC decoder 124233294Sstas * See also http://www.sbprojects.com/knowledge/ir/sirc.php 125234027Sstas * http://picprojects.org.uk/projects/sirc/sonysirc.pdf 126233294Sstas */ 127234027Sstasstruct img_ir_decoder img_ir_sony = { 128233294Sstas .type = RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | RC_PROTO_BIT_SONY20, 129233294Sstas .control = { 130233294Sstas .decoden = 1, 131233294Sstas .code_type = IMG_IR_CODETYPE_PULSELEN, 132233294Sstas }, 133234027Sstas /* main timings */ 134233294Sstas .unit = 600000, /* 600 us */ 135234027Sstas .timings = { 136233294Sstas /* leader symbol */ 137234027Sstas .ldr = { 138233294Sstas .pulse = { 4 /* 2.4 ms */ }, 139233294Sstas .space = { 1 /* 600 us */ }, 140233294Sstas }, 141233294Sstas /* 0 symbol */ 142233294Sstas .s00 = { 143233294Sstas .pulse = { 1 /* 600 us */ }, 144233294Sstas .space = { 1 /* 600 us */ }, 145233294Sstas }, 146233294Sstas /* 1 symbol */ 147233294Sstas .s01 = { 148178825Sdfr .pulse = { 2 /* 1.2 ms */ }, 149233294Sstas .space = { 1 /* 600 us */ }, 150233294Sstas }, 151233294Sstas /* free time */ 152233294Sstas .ft = { 153178825Sdfr .minlen = 12, 154178825Sdfr .maxlen = 20, 155233294Sstas .ft_min = 10, /* 6 ms */ 156233294Sstas }, 157178825Sdfr }, 158233294Sstas /* scancode logic */ 159178825Sdfr .scancode = img_ir_sony_scancode, 160178825Sdfr .filter = img_ir_sony_filter, 161178825Sdfr}; 162233294Sstas