Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
0003  *
0004  * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
0005  */
0006 
0007 #include <linux/bitrev.h>
0008 #include <linux/module.h>
0009 #include "rc-core-priv.h"
0010 
0011 #define SONY_UNIT       600 /* us */
0012 #define SONY_HEADER_PULSE   (4 * SONY_UNIT)
0013 #define SONY_HEADER_SPACE   (1 * SONY_UNIT)
0014 #define SONY_BIT_0_PULSE    (1 * SONY_UNIT)
0015 #define SONY_BIT_1_PULSE    (2 * SONY_UNIT)
0016 #define SONY_BIT_SPACE      (1 * SONY_UNIT)
0017 #define SONY_TRAILER_SPACE  (10 * SONY_UNIT) /* minimum */
0018 
0019 enum sony_state {
0020     STATE_INACTIVE,
0021     STATE_HEADER_SPACE,
0022     STATE_BIT_PULSE,
0023     STATE_BIT_SPACE,
0024     STATE_FINISHED,
0025 };
0026 
0027 /**
0028  * ir_sony_decode() - Decode one Sony pulse or space
0029  * @dev:    the struct rc_dev descriptor of the device
0030  * @ev:         the struct ir_raw_event descriptor of the pulse/space
0031  *
0032  * This function returns -EINVAL if the pulse violates the state machine
0033  */
0034 static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
0035 {
0036     struct sony_dec *data = &dev->raw->sony;
0037     enum rc_proto protocol;
0038     u32 scancode;
0039     u8 device, subdevice, function;
0040 
0041     if (!is_timing_event(ev)) {
0042         if (ev.overflow)
0043             data->state = STATE_INACTIVE;
0044         return 0;
0045     }
0046 
0047     if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
0048         goto out;
0049 
0050     dev_dbg(&dev->dev, "Sony decode started at state %d (%uus %s)\n",
0051         data->state, ev.duration, TO_STR(ev.pulse));
0052 
0053     switch (data->state) {
0054 
0055     case STATE_INACTIVE:
0056         if (!ev.pulse)
0057             break;
0058 
0059         if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2))
0060             break;
0061 
0062         data->count = 0;
0063         data->state = STATE_HEADER_SPACE;
0064         return 0;
0065 
0066     case STATE_HEADER_SPACE:
0067         if (ev.pulse)
0068             break;
0069 
0070         if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2))
0071             break;
0072 
0073         data->state = STATE_BIT_PULSE;
0074         return 0;
0075 
0076     case STATE_BIT_PULSE:
0077         if (!ev.pulse)
0078             break;
0079 
0080         data->bits <<= 1;
0081         if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
0082             data->bits |= 1;
0083         else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
0084             break;
0085 
0086         data->count++;
0087         data->state = STATE_BIT_SPACE;
0088         return 0;
0089 
0090     case STATE_BIT_SPACE:
0091         if (ev.pulse)
0092             break;
0093 
0094         if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
0095             break;
0096 
0097         decrease_duration(&ev, SONY_BIT_SPACE);
0098 
0099         if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
0100             data->state = STATE_BIT_PULSE;
0101             return 0;
0102         }
0103 
0104         data->state = STATE_FINISHED;
0105         fallthrough;
0106 
0107     case STATE_FINISHED:
0108         if (ev.pulse)
0109             break;
0110 
0111         if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
0112             break;
0113 
0114         switch (data->count) {
0115         case 12:
0116             if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY12))
0117                 goto finish_state_machine;
0118 
0119             device    = bitrev8((data->bits <<  3) & 0xF8);
0120             subdevice = 0;
0121             function  = bitrev8((data->bits >>  4) & 0xFE);
0122             protocol = RC_PROTO_SONY12;
0123             break;
0124         case 15:
0125             if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY15))
0126                 goto finish_state_machine;
0127 
0128             device    = bitrev8((data->bits >>  0) & 0xFF);
0129             subdevice = 0;
0130             function  = bitrev8((data->bits >>  7) & 0xFE);
0131             protocol = RC_PROTO_SONY15;
0132             break;
0133         case 20:
0134             if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY20))
0135                 goto finish_state_machine;
0136 
0137             device    = bitrev8((data->bits >>  5) & 0xF8);
0138             subdevice = bitrev8((data->bits >>  0) & 0xFF);
0139             function  = bitrev8((data->bits >> 12) & 0xFE);
0140             protocol = RC_PROTO_SONY20;
0141             break;
0142         default:
0143             dev_dbg(&dev->dev, "Sony invalid bitcount %u\n",
0144                 data->count);
0145             goto out;
0146         }
0147 
0148         scancode = device << 16 | subdevice << 8 | function;
0149         dev_dbg(&dev->dev, "Sony(%u) scancode 0x%05x\n", data->count,
0150             scancode);
0151         rc_keydown(dev, protocol, scancode, 0);
0152         goto finish_state_machine;
0153     }
0154 
0155 out:
0156     dev_dbg(&dev->dev, "Sony decode failed at state %d (%uus %s)\n",
0157         data->state, ev.duration, TO_STR(ev.pulse));
0158     data->state = STATE_INACTIVE;
0159     return -EINVAL;
0160 
0161 finish_state_machine:
0162     data->state = STATE_INACTIVE;
0163     return 0;
0164 }
0165 
0166 static const struct ir_raw_timings_pl ir_sony_timings = {
0167     .header_pulse  = SONY_HEADER_PULSE,
0168     .bit_space     = SONY_BIT_SPACE,
0169     .bit_pulse[0]  = SONY_BIT_0_PULSE,
0170     .bit_pulse[1]  = SONY_BIT_1_PULSE,
0171     .trailer_space = SONY_TRAILER_SPACE + SONY_BIT_SPACE,
0172     .msb_first     = 0,
0173 };
0174 
0175 /**
0176  * ir_sony_encode() - Encode a scancode as a stream of raw events
0177  *
0178  * @protocol:   protocol to encode
0179  * @scancode:   scancode to encode
0180  * @events: array of raw ir events to write into
0181  * @max:    maximum size of @events
0182  *
0183  * Returns: The number of events written.
0184  *      -ENOBUFS if there isn't enough space in the array to fit the
0185  *      encoding. In this case all @max events will have been written.
0186  */
0187 static int ir_sony_encode(enum rc_proto protocol, u32 scancode,
0188               struct ir_raw_event *events, unsigned int max)
0189 {
0190     struct ir_raw_event *e = events;
0191     u32 raw, len;
0192     int ret;
0193 
0194     if (protocol == RC_PROTO_SONY12) {
0195         raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9);
0196         len = 12;
0197     } else if (protocol == RC_PROTO_SONY15) {
0198         raw = (scancode & 0x7f) | ((scancode & 0xff0000) >> 9);
0199         len = 15;
0200     } else {
0201         raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9) |
0202                ((scancode & 0xff00) << 4);
0203         len = 20;
0204     }
0205 
0206     ret = ir_raw_gen_pl(&e, max, &ir_sony_timings, len, raw);
0207     if (ret < 0)
0208         return ret;
0209 
0210     return e - events;
0211 }
0212 
0213 static struct ir_raw_handler sony_handler = {
0214     .protocols  = RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 |
0215                             RC_PROTO_BIT_SONY20,
0216     .decode     = ir_sony_decode,
0217     .encode     = ir_sony_encode,
0218     .carrier    = 40000,
0219     .min_timeout    = SONY_TRAILER_SPACE,
0220 };
0221 
0222 static int __init ir_sony_decode_init(void)
0223 {
0224     ir_raw_handler_register(&sony_handler);
0225 
0226     printk(KERN_INFO "IR Sony protocol handler initialized\n");
0227     return 0;
0228 }
0229 
0230 static void __exit ir_sony_decode_exit(void)
0231 {
0232     ir_raw_handler_unregister(&sony_handler);
0233 }
0234 
0235 module_init(ir_sony_decode_init);
0236 module_exit(ir_sony_decode_exit);
0237 
0238 MODULE_LICENSE("GPL");
0239 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
0240 MODULE_DESCRIPTION("Sony IR protocol decoder");