linux/drivers/media/rc/img-ir/img-ir-sanyo.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * ImgTec IR Decoder setup for Sanyo protocol.
   4 *
   5 * Copyright 2012-2014 Imagination Technologies Ltd.
   6 *
   7 * From ir-sanyo-decoder.c:
   8 *
   9 * This protocol uses the NEC protocol timings. However, data is formatted as:
  10 *      13 bits Custom Code
  11 *      13 bits NOT(Custom Code)
  12 *      8 bits Key data
  13 *      8 bits NOT(Key data)
  14 *
  15 * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
  16 * Information for this protocol is available at the Sanyo LC7461 datasheet.
  17 */
  18
  19#include "img-ir-hw.h"
  20
  21/* Convert Sanyo data to a scancode */
  22static int img_ir_sanyo_scancode(int len, u64 raw, u64 enabled_protocols,
  23                                 struct img_ir_scancode_req *request)
  24{
  25        unsigned int addr, addr_inv, data, data_inv;
  26        /* a repeat code has no data */
  27        if (!len)
  28                return IMG_IR_REPEATCODE;
  29        if (len != 42)
  30                return -EINVAL;
  31        addr     = (raw >>  0) & 0x1fff;
  32        addr_inv = (raw >> 13) & 0x1fff;
  33        data     = (raw >> 26) & 0xff;
  34        data_inv = (raw >> 34) & 0xff;
  35        /* Validate data */
  36        if ((data_inv ^ data) != 0xff)
  37                return -EINVAL;
  38        /* Validate address */
  39        if ((addr_inv ^ addr) != 0x1fff)
  40                return -EINVAL;
  41
  42        /* Normal Sanyo */
  43        request->protocol = RC_PROTO_SANYO;
  44        request->scancode = addr << 8 | data;
  45        return IMG_IR_SCANCODE;
  46}
  47
  48/* Convert Sanyo scancode to Sanyo data filter */
  49static int img_ir_sanyo_filter(const struct rc_scancode_filter *in,
  50                               struct img_ir_filter *out, u64 protocols)
  51{
  52        unsigned int addr, addr_inv, data, data_inv;
  53        unsigned int addr_m, data_m;
  54
  55        data = in->data & 0xff;
  56        data_m = in->mask & 0xff;
  57        data_inv = data ^ 0xff;
  58
  59        if (in->data & 0xff700000)
  60                return -EINVAL;
  61
  62        addr       = (in->data >> 8) & 0x1fff;
  63        addr_m     = (in->mask >> 8) & 0x1fff;
  64        addr_inv   = addr ^ 0x1fff;
  65
  66        out->data = (u64)data_inv << 34 |
  67                    (u64)data     << 26 |
  68                         addr_inv << 13 |
  69                         addr;
  70        out->mask = (u64)data_m << 34 |
  71                    (u64)data_m << 26 |
  72                         addr_m << 13 |
  73                         addr_m;
  74        return 0;
  75}
  76
  77/* Sanyo decoder */
  78struct img_ir_decoder img_ir_sanyo = {
  79        .type = RC_PROTO_BIT_SANYO,
  80        .control = {
  81                .decoden = 1,
  82                .code_type = IMG_IR_CODETYPE_PULSEDIST,
  83        },
  84        /* main timings */
  85        .unit = 562500, /* 562.5 us */
  86        .timings = {
  87                /* leader symbol */
  88                .ldr = {
  89                        .pulse = { 16   /* 9ms */ },
  90                        .space = { 8    /* 4.5ms */ },
  91                },
  92                /* 0 symbol */
  93                .s00 = {
  94                        .pulse = { 1    /* 562.5 us */ },
  95                        .space = { 1    /* 562.5 us */ },
  96                },
  97                /* 1 symbol */
  98                .s01 = {
  99                        .pulse = { 1    /* 562.5 us */ },
 100                        .space = { 3    /* 1687.5 us */ },
 101                },
 102                /* free time */
 103                .ft = {
 104                        .minlen = 42,
 105                        .maxlen = 42,
 106                        .ft_min = 10,   /* 5.625 ms */
 107                },
 108        },
 109        /* repeat codes */
 110        .repeat = 108,                  /* 108 ms */
 111        .rtimings = {
 112                /* leader symbol */
 113                .ldr = {
 114                        .space = { 4    /* 2.25 ms */ },
 115                },
 116                /* free time */
 117                .ft = {
 118                        .minlen = 0,    /* repeat code has no data */
 119                        .maxlen = 0,
 120                },
 121        },
 122        /* scancode logic */
 123        .scancode = img_ir_sanyo_scancode,
 124        .filter = img_ir_sanyo_filter,
 125};
 126