^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ImgTec IR Hardware Decoder found in PowerDown Controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2010-2014 Imagination Technologies Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This ties into the input subsystem using the RC-core. Protocol support is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * provided in separate modules which provide the parameters and scancode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * translation functions to set up the hardware decoder and interpret the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * resulting input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <media/rc-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "img-ir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* Decoders lock (only modified to preprocess them) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static DEFINE_SPINLOCK(img_ir_decoders_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static bool img_ir_decoders_preprocessed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct img_ir_decoder *img_ir_decoders[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifdef CONFIG_IR_IMG_NEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) &img_ir_nec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef CONFIG_IR_IMG_JVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) &img_ir_jvc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifdef CONFIG_IR_IMG_SONY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) &img_ir_sony,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #ifdef CONFIG_IR_IMG_SHARP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) &img_ir_sharp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_IR_IMG_SANYO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) &img_ir_sanyo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_IR_IMG_RC5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) &img_ir_rc5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #ifdef CONFIG_IR_IMG_RC6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) &img_ir_rc6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IMG_IR_F_FILTER BIT(RC_FILTER_NORMAL) /* enable filtering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define IMG_IR_F_WAKE BIT(RC_FILTER_WAKEUP) /* enable waking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* code type quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define IMG_IR_QUIRK_CODE_BROKEN 0x1 /* Decode is broken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IMG_IR_QUIRK_CODE_LEN_INCR 0x2 /* Bit length needs increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * The decoder generates rapid interrupts without actually having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * received any new data after an incomplete IR code is decoded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IMG_IR_QUIRK_CODE_IRQ 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* functions for preprocessing timings, ensuring max is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void img_ir_timing_preprocess(struct img_ir_timing_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (range->max < range->min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) range->max = range->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (unit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* multiply by unit and convert to microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) range->min = (range->min*unit)/1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) range->max = (range->max*unit + 999)/1000; /* round up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void img_ir_symbol_timing_preprocess(struct img_ir_symbol_timing *timing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) img_ir_timing_preprocess(&timing->pulse, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) img_ir_timing_preprocess(&timing->space, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void img_ir_timings_preprocess(struct img_ir_timings *timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) img_ir_symbol_timing_preprocess(&timings->ldr, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) img_ir_symbol_timing_preprocess(&timings->s00, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) img_ir_symbol_timing_preprocess(&timings->s01, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) img_ir_symbol_timing_preprocess(&timings->s10, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) img_ir_symbol_timing_preprocess(&timings->s11, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* default s10 and s11 to s00 and s01 if no leader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* multiply by unit and convert to microseconds (round up) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) timings->ft.ft_min = (timings->ft.ft_min*unit + 999)/1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* functions for filling empty fields with defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void img_ir_timing_defaults(struct img_ir_timing_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct img_ir_timing_range *defaults)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!range->min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) range->min = defaults->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!range->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) range->max = defaults->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void img_ir_symbol_timing_defaults(struct img_ir_symbol_timing *timing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct img_ir_symbol_timing *defaults)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) img_ir_timing_defaults(&timing->pulse, &defaults->pulse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) img_ir_timing_defaults(&timing->space, &defaults->space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void img_ir_timings_defaults(struct img_ir_timings *timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct img_ir_timings *defaults)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) img_ir_symbol_timing_defaults(&timings->ldr, &defaults->ldr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) img_ir_symbol_timing_defaults(&timings->s00, &defaults->s00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) img_ir_symbol_timing_defaults(&timings->s01, &defaults->s01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) img_ir_symbol_timing_defaults(&timings->s10, &defaults->s10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) img_ir_symbol_timing_defaults(&timings->s11, &defaults->s11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (!timings->ft.ft_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) timings->ft.ft_min = defaults->ft.ft_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* functions for converting timings to register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * img_ir_control() - Convert control struct to control register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @control: Control data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * Returns: The control register value equivalent of @control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static u32 img_ir_control(const struct img_ir_control *control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 ctrl = control->code_type << IMG_IR_CODETYPE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (control->decoden)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ctrl |= IMG_IR_DECODEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (control->hdrtog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ctrl |= IMG_IR_HDRTOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (control->ldrdec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ctrl |= IMG_IR_LDRDEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (control->decodinpol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ctrl |= IMG_IR_DECODINPOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (control->bitorien)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ctrl |= IMG_IR_BITORIEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (control->d1validsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ctrl |= IMG_IR_D1VALIDSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (control->bitinv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ctrl |= IMG_IR_BITINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (control->decodend2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ctrl |= IMG_IR_DECODEND2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (control->bitoriend2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ctrl |= IMG_IR_BITORIEND2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (control->bitinvd2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ctrl |= IMG_IR_BITINVD2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * img_ir_timing_range_convert() - Convert microsecond range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @out: Output timing range in clock cycles with a shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @in: Input timing range in microseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @tolerance: Tolerance as a fraction of 128 (roughly percent).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @clock_hz: IR clock rate in Hz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @shift: Shift of output units.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Converts min and max from microseconds to IR clock cycles, applies a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * tolerance, and shifts for the register, rounding in the right direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Note that in and out can safely be the same object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void img_ir_timing_range_convert(struct img_ir_timing_range *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) const struct img_ir_timing_range *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned int tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned long clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned int shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned int min = in->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned int max = in->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* add a tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) min = min - (min*tolerance >> 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) max = max + (max*tolerance >> 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* convert from microseconds into clock cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) min = min*clock_hz / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) max = (max*clock_hz + 999999) / 1000000; /* round up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* apply shift and copy to output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out->min = min >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) out->max = (max + ((1 << shift) - 1)) >> shift; /* round up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * img_ir_symbol_timing() - Convert symbol timing struct to register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @timing: Symbol timing data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @tolerance: Timing tolerance where 0-128 represents 0-100%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @clock_hz: Frequency of source clock in Hz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @pd_shift: Shift to apply to symbol period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @w_shift: Shift to apply to symbol width
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Returns: Symbol timing register value based on arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static u32 img_ir_symbol_timing(const struct img_ir_symbol_timing *timing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned long clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned int pd_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int w_shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct img_ir_timing_range hw_pulse, hw_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* we calculate period in hw_period, then convert in place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) hw_period.min = timing->pulse.min + timing->space.min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) hw_period.max = timing->pulse.max + timing->space.max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) img_ir_timing_range_convert(&hw_period, &hw_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) tolerance, clock_hz, pd_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) img_ir_timing_range_convert(&hw_pulse, &timing->pulse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) tolerance, clock_hz, w_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* construct register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return (hw_period.max << IMG_IR_PD_MAX_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) (hw_period.min << IMG_IR_PD_MIN_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) (hw_pulse.max << IMG_IR_W_MAX_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) (hw_pulse.min << IMG_IR_W_MIN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * img_ir_free_timing() - Convert free time timing struct to register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @timing: Free symbol timing data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @clock_hz: Source clock frequency in Hz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * Returns: Free symbol timing register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static u32 img_ir_free_timing(const struct img_ir_free_timing *timing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) unsigned long clock_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned int minlen, maxlen, ft_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* minlen is only 5 bits, and round minlen to multiple of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (timing->minlen < 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) minlen = timing->minlen & -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) minlen = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* maxlen has maximum value of 48, and round maxlen to multiple of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (timing->maxlen < 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) maxlen = (timing->maxlen + 1) & -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) maxlen = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* convert and shift ft_min, rounding upwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ft_min = (timing->ft_min*clock_hz + 999999) / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ft_min = (ft_min + 7) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* construct register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return (maxlen << IMG_IR_MAXLEN_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (minlen << IMG_IR_MINLEN_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) (ft_min << IMG_IR_FT_MIN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * img_ir_free_timing_dynamic() - Update free time register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @st_ft: Static free time register value from img_ir_free_timing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @filter: Current filter which may additionally restrict min/max len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Returns: Updated free time register value based on the current filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static u32 img_ir_free_timing_dynamic(u32 st_ft, struct img_ir_filter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int minlen, maxlen, newminlen, newmaxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* round minlen, maxlen to multiple of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) newminlen = filter->minlen & -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) newmaxlen = (filter->maxlen + 1) & -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* extract min/max len from register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) minlen = (st_ft & IMG_IR_MINLEN) >> IMG_IR_MINLEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) maxlen = (st_ft & IMG_IR_MAXLEN) >> IMG_IR_MAXLEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* if the new values are more restrictive, update the register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (newminlen > minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) st_ft &= ~IMG_IR_MINLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) st_ft |= newminlen << IMG_IR_MINLEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (newmaxlen < maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) st_ft &= ~IMG_IR_MAXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) st_ft |= newmaxlen << IMG_IR_MAXLEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return st_ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * img_ir_timings_convert() - Convert timings to register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * @regs: Output timing register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * @timings: Input timing data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * @tolerance: Timing tolerance where 0-128 represents 0-100%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * @clock_hz: Source clock frequency in Hz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void img_ir_timings_convert(struct img_ir_timing_regvals *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) const struct img_ir_timings *timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned int clock_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* leader symbol timings are divided by 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) regs->ldr = img_ir_symbol_timing(&timings->ldr, tolerance, clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* other symbol timings, pd fields only are divided by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) regs->s00 = img_ir_symbol_timing(&timings->s00, tolerance, clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) regs->s01 = img_ir_symbol_timing(&timings->s01, tolerance, clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) regs->s10 = img_ir_symbol_timing(&timings->s10, tolerance, clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) regs->s11 = img_ir_symbol_timing(&timings->s11, tolerance, clock_hz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) regs->ft = img_ir_free_timing(&timings->ft, clock_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * img_ir_decoder_preprocess() - Preprocess timings in decoder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @decoder: Decoder to be preprocessed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Ensures that the symbol timing ranges are valid with respect to ordering, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * does some fixed conversion on them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* default tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!decoder->tolerance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) decoder->tolerance = 10; /* percent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* and convert tolerance to fraction out of 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) decoder->tolerance = decoder->tolerance * 128 / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* fill in implicit fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) img_ir_timings_preprocess(&decoder->timings, decoder->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* do the same for repeat timings if applicable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (decoder->repeat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) img_ir_timings_preprocess(&decoder->rtimings, decoder->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) img_ir_timings_defaults(&decoder->rtimings, &decoder->timings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * img_ir_decoder_convert() - Generate internal timings in decoder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * @decoder: Decoder to be converted to internal timings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * @reg_timings: Timing register values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * @clock_hz: IR clock rate in Hz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * Fills out the repeat timings and timing register values for a specific clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void img_ir_decoder_convert(const struct img_ir_decoder *decoder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct img_ir_reg_timings *reg_timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned int clock_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* calculate control value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) reg_timings->ctrl = img_ir_control(&decoder->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* fill in implicit fields and calculate register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) img_ir_timings_convert(®_timings->timings, &decoder->timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) decoder->tolerance, clock_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* do the same for repeat timings if applicable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (decoder->repeat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) img_ir_timings_convert(®_timings->rtimings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) &decoder->rtimings, decoder->tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) clock_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * img_ir_write_timings() - Write timings to the hardware now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * @priv: IR private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @regs: Timing register values to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @type: RC filter type (RC_FILTER_*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * Write timing register values @regs to the hardware, taking into account the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * current filter which may impose restrictions on the length of the expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void img_ir_write_timings(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct img_ir_timing_regvals *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) enum rc_filter_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* filter may be more restrictive to minlen, maxlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u32 ft = regs->ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (hw->flags & BIT(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ft = img_ir_free_timing_dynamic(regs->ft, &hw->filters[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* write to registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) img_ir_write(priv, IMG_IR_LEAD_SYMB_TIMING, regs->ldr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) img_ir_write(priv, IMG_IR_S00_SYMB_TIMING, regs->s00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) img_ir_write(priv, IMG_IR_S01_SYMB_TIMING, regs->s01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) img_ir_write(priv, IMG_IR_S10_SYMB_TIMING, regs->s10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) img_ir_write(priv, IMG_IR_S11_SYMB_TIMING, regs->s11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) img_ir_write(priv, IMG_IR_FREE_SYMB_TIMING, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_dbg(priv->dev, "timings: ldr=%#x, s=[%#x, %#x, %#x, %#x], ft=%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) regs->ldr, regs->s00, regs->s01, regs->s10, regs->s11, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static void img_ir_write_filter(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct img_ir_filter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dev_dbg(priv->dev, "IR filter=%016llx & %016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (unsigned long long)filter->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (unsigned long long)filter->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_LW, (u32)filter->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_UP, (u32)(filter->data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, (u32)filter->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, (u32)(filter->mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) dev_dbg(priv->dev, "IR clearing filter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* caller must have lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void _img_ir_set_filter(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct img_ir_filter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u32 irq_en, irq_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Only use the match interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) hw->filters[RC_FILTER_NORMAL] = *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) hw->flags |= IMG_IR_F_FILTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) irq_on = IMG_IR_IRQ_DATA_MATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) irq_en &= ~(IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Only use the valid interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) hw->flags &= ~IMG_IR_F_FILTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) irq_en &= ~IMG_IR_IRQ_DATA_MATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) irq_on = IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) irq_en |= irq_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) img_ir_write_filter(priv, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* clear any interrupts we're enabling so we don't handle old ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* caller must have lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static void _img_ir_set_wake_filter(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct img_ir_filter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Enable wake, and copy filter for later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) hw->filters[RC_FILTER_WAKEUP] = *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) hw->flags |= IMG_IR_F_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* Disable wake */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) hw->flags &= ~IMG_IR_F_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* Callback for setting scancode filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct rc_scancode_filter *sc_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct img_ir_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct img_ir_filter filter, *filter_ptr = &filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dev_dbg(priv->dev, "IR scancode %sfilter=%08x & %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) type == RC_FILTER_WAKEUP ? "wake " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) sc_filter->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) sc_filter->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* filtering can always be disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!sc_filter->mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) filter_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto set_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* current decoder must support scancode filtering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!hw->decoder || !hw->decoder->filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* convert scancode filter to raw filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) filter.minlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) filter.maxlen = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (type == RC_FILTER_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* guess scancode from protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = hw->decoder->filter(sc_filter, &filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dev->enabled_protocols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* for wakeup user provided exact protocol variant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret = hw->decoder->filter(sc_filter, &filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 1ULL << dev->wakeup_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) type == RC_FILTER_WAKEUP ? "wake " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) (unsigned long long)filter.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) (unsigned long long)filter.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) set_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* apply raw filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) case RC_FILTER_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) _img_ir_set_filter(priv, filter_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) case RC_FILTER_WAKEUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) _img_ir_set_wake_filter(priv, filter_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int img_ir_set_normal_filter(struct rc_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct rc_scancode_filter *sc_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int img_ir_set_wakeup_filter(struct rc_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct rc_scancode_filter *sc_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * img_ir_set_decoder() - Set the current decoder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @priv: IR private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * @decoder: Decoder to use with immediate effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * @proto: Protocol bitmap (or 0 to use decoder->type).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void img_ir_set_decoder(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) const struct img_ir_decoder *decoder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) u64 proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct rc_dev *rdev = hw->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) u32 ir_status, irq_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * First record that the protocol is being stopped so that the end timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * isn't restarted while we're trying to stop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) hw->stopping = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Release the lock to stop the end timer, since the end timer handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * acquires the lock and we don't want to deadlock waiting for it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) del_timer_sync(&hw->end_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) del_timer_sync(&hw->suspend_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) hw->stopping = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* switch off and disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) img_ir_write(priv, IMG_IR_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en & IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_ALL & ~IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* ack any data already detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ir_status = img_ir_read(priv, IMG_IR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) img_ir_write(priv, IMG_IR_STATUS, ir_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* always read data to clear buffer if IR wakes the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) img_ir_read(priv, IMG_IR_DATA_LW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) img_ir_read(priv, IMG_IR_DATA_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* switch back to normal mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) hw->mode = IMG_IR_M_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* clear the wakeup scancode filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) rdev->scancode_wakeup_filter.data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) rdev->scancode_wakeup_filter.mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rdev->wakeup_protocol = RC_PROTO_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* clear raw filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) _img_ir_set_filter(priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) _img_ir_set_wake_filter(priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* clear the enabled protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) hw->enabled_protocols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* switch decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) hw->decoder = decoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* set the enabled protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (!proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) proto = decoder->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) hw->enabled_protocols = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* write the new timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) img_ir_decoder_convert(decoder, &hw->reg_timings, hw->clk_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) img_ir_write_timings(priv, &hw->reg_timings.timings, RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* set up and enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * img_ir_decoder_compatable() - Find whether a decoder will work with a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * @priv: IR private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * @dec: Decoder to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * Returns: true if @dec is compatible with the device @priv refers to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static bool img_ir_decoder_compatible(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) const struct img_ir_decoder *dec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* don't accept decoders using code types which aren't supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ct = dec->control.code_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_BROKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * img_ir_allowed_protos() - Get allowed protocols from global decoder list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * @priv: IR private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * Returns: Mask of protocols supported by the device @priv refers to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static u64 img_ir_allowed_protos(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) u64 protos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct img_ir_decoder **decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) for (decp = img_ir_decoders; *decp; ++decp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) const struct img_ir_decoder *dec = *decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (img_ir_decoder_compatible(priv, dec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) protos |= dec->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return protos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* Callback for changing protocol using sysfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct img_ir_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct rc_dev *rdev = hw->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct img_ir_decoder **decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u64 wakeup_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!*ir_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* disable all protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) img_ir_set_decoder(priv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) for (decp = img_ir_decoders; *decp; ++decp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) const struct img_ir_decoder *dec = *decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!img_ir_decoder_compatible(priv, dec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (*ir_type & dec->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) *ir_type &= dec->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) img_ir_set_decoder(priv, dec, *ir_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * Only allow matching wakeup protocols for now, and only if filtering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) wakeup_protocols = *ir_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!hw->decoder || !hw->decoder->filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) wakeup_protocols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) rdev->allowed_wakeup_protocols = wakeup_protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* Changes ir-core protocol device attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct rc_dev *rdev = priv->hw.rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) mutex_lock(&rdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) rdev->enabled_protocols = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) rdev->allowed_wakeup_protocols = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mutex_unlock(&rdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* Set up IR decoders */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static void img_ir_init_decoders(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct img_ir_decoder **decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) spin_lock(&img_ir_decoders_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (!img_ir_decoders_preprocessed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) for (decp = img_ir_decoders; *decp; ++decp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) img_ir_decoder_preprocess(*decp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) img_ir_decoders_preprocessed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) spin_unlock(&img_ir_decoders_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * img_ir_enable_wake() - Switch to wake mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * @priv: IR private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Returns: non-zero if the IR can wake the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static int img_ir_enable_wake(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (hw->flags & IMG_IR_F_WAKE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* interrupt only on a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) hw->suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) img_ir_write(priv, IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_DATA_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) img_ir_write_filter(priv, &hw->filters[RC_FILTER_WAKEUP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) img_ir_write_timings(priv, &hw->reg_timings.timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) RC_FILTER_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) hw->mode = IMG_IR_M_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * img_ir_disable_wake() - Switch out of wake mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * @priv: IR private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * Returns: 1 if the hardware should be allowed to wake from a sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static int img_ir_disable_wake(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (hw->flags & IMG_IR_F_WAKE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* restore normal filtering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (hw->flags & IMG_IR_F_FILTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) img_ir_write(priv, IMG_IR_IRQ_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) IMG_IR_IRQ_DATA_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) img_ir_write_filter(priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) &hw->filters[RC_FILTER_NORMAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) img_ir_write(priv, IMG_IR_IRQ_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) IMG_IR_IRQ_DATA_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) IMG_IR_IRQ_DATA2_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) img_ir_write_filter(priv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) img_ir_write_timings(priv, &hw->reg_timings.timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) hw->mode = IMG_IR_M_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* lock must be held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static void img_ir_begin_repeat(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (hw->mode == IMG_IR_M_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /* switch to repeat timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) img_ir_write(priv, IMG_IR_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) hw->mode = IMG_IR_M_REPEATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) img_ir_write_timings(priv, &hw->reg_timings.rtimings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* lock must be held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static void img_ir_end_repeat(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (hw->mode == IMG_IR_M_REPEATING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* switch to normal timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) img_ir_write(priv, IMG_IR_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) hw->mode = IMG_IR_M_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) img_ir_write_timings(priv, &hw->reg_timings.timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* lock must be held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) const struct img_ir_decoder *dec = hw->decoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int ret = IMG_IR_SCANCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct img_ir_scancode_req request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) request.protocol = RC_PROTO_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) request.toggle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (dec->scancode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = dec->scancode(len, raw, hw->enabled_protocols, &request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) else if (len >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) request.scancode = (u32)raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) else if (len < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) request.scancode = (u32)raw & ((1 << len)-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) dev_dbg(priv->dev, "data (%u bits) = %#llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) len, (unsigned long long)raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret == IMG_IR_SCANCODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) dev_dbg(priv->dev, "decoded scan code %#x, toggle %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) request.scancode, request.toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) rc_keydown(hw->rdev, request.protocol, request.scancode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) request.toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) img_ir_end_repeat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) } else if (ret == IMG_IR_REPEATCODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (hw->mode == IMG_IR_M_REPEATING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) dev_dbg(priv->dev, "decoded repeat code\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) rc_repeat(hw->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) dev_dbg(priv->dev, "decoded unexpected repeat code, ignoring\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) dev_dbg(priv->dev, "decode failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* we mustn't update the end timer while trying to stop it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (dec->repeat && !hw->stopping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) unsigned long interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) img_ir_begin_repeat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) /* update timer, but allowing for 1/8th tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) interval = dec->repeat + (dec->repeat >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) mod_timer(&hw->end_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) jiffies + msecs_to_jiffies(interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* timer function to end waiting for repeat. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static void img_ir_end_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct img_ir_priv *priv = from_timer(priv, t, hw.end_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) img_ir_end_repeat(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Timer function to re-enable the current protocol after it had been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * cleared when invalid interrupts were generated due to a quirk in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * img-ir decoder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static void img_ir_suspend_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct img_ir_priv *priv = from_timer(priv, t, hw.suspend_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * Don't overwrite enabled valid/match IRQs if they have already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * changed by e.g. a filter change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if ((priv->hw.quirk_suspend_irq & IMG_IR_IRQ_EDGE) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) img_ir_read(priv, IMG_IR_IRQ_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) img_ir_write(priv, IMG_IR_IRQ_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) priv->hw.quirk_suspend_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /* enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) img_ir_write(priv, IMG_IR_CONTROL, priv->hw.reg_timings.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static void img_ir_change_frequency(struct img_ir_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct clk_notifier_data *change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) dev_dbg(priv->dev, "clk changed %lu HZ -> %lu HZ\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) change->old_rate, change->new_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) spin_lock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (hw->clk_hz == change->new_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) hw->clk_hz = change->new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* refresh current timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (hw->decoder) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) img_ir_decoder_convert(hw->decoder, &hw->reg_timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) hw->clk_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) switch (hw->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case IMG_IR_M_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) img_ir_write_timings(priv, &hw->reg_timings.timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case IMG_IR_M_REPEATING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) img_ir_write_timings(priv, &hw->reg_timings.rtimings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) RC_FILTER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case IMG_IR_M_WAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) img_ir_write_timings(priv, &hw->reg_timings.timings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) RC_FILTER_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) spin_unlock_irq(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) static int img_ir_clk_notify(struct notifier_block *self, unsigned long action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct img_ir_priv *priv = container_of(self, struct img_ir_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) hw.clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) case POST_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) img_ir_change_frequency(priv, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) #endif /* CONFIG_COMMON_CLK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* called with priv->lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) u32 ir_status, len, lw, up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) unsigned int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* use the current decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!hw->decoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ct = hw->decoder->control.code_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ir_status = img_ir_read(priv, IMG_IR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (!(ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!(priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_IRQ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) hw->stopping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * The below functionality is added as a work around to stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * multiple Interrupts generated when an incomplete IR code is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * received by the decoder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * The decoder generates rapid interrupts without actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * having received any new data. After a single interrupt it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * expected to clear up, but instead multiple interrupts are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * rapidly generated. only way to get out of this loop is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * reset the control register after a short delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) img_ir_write(priv, IMG_IR_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) hw->quirk_suspend_irq = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) img_ir_write(priv, IMG_IR_IRQ_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) hw->quirk_suspend_irq & IMG_IR_IRQ_EDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* Timer activated to re-enable the protocol. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) mod_timer(&hw->suspend_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) jiffies + msecs_to_jiffies(5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) img_ir_write(priv, IMG_IR_STATUS, ir_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) len = (ir_status & IMG_IR_RXDLEN) >> IMG_IR_RXDLEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* some versions report wrong length for certain code types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (hw->ct_quirks[ct] & IMG_IR_QUIRK_CODE_LEN_INCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ++len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) lw = img_ir_read(priv, IMG_IR_DATA_LW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) up = img_ir_read(priv, IMG_IR_DATA_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) img_ir_handle_data(priv, len, (u64)up << 32 | lw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) void img_ir_setup_hw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct img_ir_decoder **decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (!priv->hw.rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* Use the first available decoder (or disable stuff if NULL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) for (decp = img_ir_decoders; *decp; ++decp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) const struct img_ir_decoder *dec = *decp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (img_ir_decoder_compatible(priv, dec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) img_ir_set_protocol(priv, dec->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) img_ir_set_decoder(priv, dec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) img_ir_set_decoder(priv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * img_ir_probe_hw_caps() - Probe capabilities of the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * @priv: IR private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static void img_ir_probe_hw_caps(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * When a version of the block becomes available without these quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * they'll have to depend on the core revision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) hw->ct_quirks[IMG_IR_CODETYPE_PULSELEN]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) |= IMG_IR_QUIRK_CODE_LEN_INCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) hw->ct_quirks[IMG_IR_CODETYPE_BIPHASE]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) |= IMG_IR_QUIRK_CODE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) |= IMG_IR_QUIRK_CODE_BROKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int img_ir_probe_hw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct rc_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Ensure hardware decoders have been preprocessed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) img_ir_init_decoders();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* Probe hardware capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) img_ir_probe_hw_caps(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Set up the end timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) timer_setup(&hw->end_timer, img_ir_end_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) timer_setup(&hw->suspend_timer, img_ir_suspend_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* Register a clock notifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (!IS_ERR(priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) hw->clk_hz = clk_get_rate(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) hw->clk_nb.notifier_call = img_ir_clk_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) error = clk_notifier_register(priv->clk, &hw->clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dev_warn(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) "failed to register clock notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) hw->clk_hz = 32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* Allocate hardware decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) hw->rdev = rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (!rdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) dev_err(priv->dev, "cannot allocate input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) goto err_alloc_rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) rdev->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) rdev->map_name = RC_MAP_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) rdev->allowed_protocols = img_ir_allowed_protos(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) rdev->device_name = "IMG Infrared Decoder";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) rdev->s_filter = img_ir_set_normal_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) rdev->s_wakeup_filter = img_ir_set_wakeup_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Register hardware decoder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) error = rc_register_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) dev_err(priv->dev, "failed to register IR input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto err_register_rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * Set this after rc_register_device as no protocols have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * registered yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) rdev->change_protocol = img_ir_change_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) device_init_wakeup(priv->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) err_register_rc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) img_ir_set_decoder(priv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) hw->rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) rc_free_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) err_alloc_rc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (!IS_ERR(priv->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) clk_notifier_unregister(priv->clk, &hw->clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) void img_ir_remove_hw(struct img_ir_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct img_ir_priv_hw *hw = &priv->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct rc_dev *rdev = hw->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) img_ir_set_decoder(priv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) hw->rdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) rc_unregister_device(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (!IS_ERR(priv->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) clk_notifier_unregister(priv->clk, &hw->clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) int img_ir_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct img_ir_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (device_may_wakeup(dev) && img_ir_enable_wake(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) enable_irq_wake(priv->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int img_ir_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct img_ir_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (device_may_wakeup(dev) && img_ir_disable_wake(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) disable_irq_wake(priv->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) #endif /* CONFIG_PM_SLEEP */