Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | /* SPDX-License-Identifier: GPL-2.0-or-later */ /* * ImgTec IR Hardware Decoder found in PowerDown Controller. * * Copyright 2010-2014 Imagination Technologies Ltd. */ #ifndef _IMG_IR_HW_H_ #define _IMG_IR_HW_H_ #include <linux/kernel.h> #include <media/rc-core.h> /* constants */ #define IMG_IR_CODETYPE_PULSELEN 0x0 /* Sony */ #define IMG_IR_CODETYPE_PULSEDIST 0x1 /* NEC, Toshiba, Micom, Sharp */ #define IMG_IR_CODETYPE_BIPHASE 0x2 /* RC-5/6 */ #define IMG_IR_CODETYPE_2BITPULSEPOS 0x3 /* RC-MM */ /* Timing information */ /** * struct img_ir_control - Decoder control settings * @decoden: Primary decoder enable * @code_type: Decode type (see IMG_IR_CODETYPE_*) * @hdrtog: Detect header toggle symbol after leader symbol * @ldrdec: Don't discard leader if maximum width reached * @decodinpol: Decoder input polarity (1=active high) * @bitorien: Bit orientation (1=MSB first) * @d1validsel: Decoder 2 takes over if it detects valid data * @bitinv: Bit inversion switch (1=don't invert) * @decodend2: Secondary decoder enable (no leader symbol) * @bitoriend2: Bit orientation (1=MSB first) * @bitinvd2: Secondary decoder bit inversion switch (1=don't invert) */ struct img_ir_control { unsigned decoden:1; unsigned code_type:2; unsigned hdrtog:1; unsigned ldrdec:1; unsigned decodinpol:1; unsigned bitorien:1; unsigned d1validsel:1; unsigned bitinv:1; unsigned decodend2:1; unsigned bitoriend2:1; unsigned bitinvd2:1; }; /** * struct img_ir_timing_range - range of timing values * @min: Minimum timing value * @max: Maximum timing value (if < @min, this will be set to @min during * preprocessing step, so it is normally not explicitly initialised * and is taken care of by the tolerance) */ struct img_ir_timing_range { u16 min; u16 max; }; /** * struct img_ir_symbol_timing - timing data for a symbol * @pulse: Timing range for the length of the pulse in this symbol * @space: Timing range for the length of the space in this symbol */ struct img_ir_symbol_timing { struct img_ir_timing_range pulse; struct img_ir_timing_range space; }; /** * struct img_ir_free_timing - timing data for free time symbol * @minlen: Minimum number of bits of data * @maxlen: Maximum number of bits of data * @ft_min: Minimum free time after message */ struct img_ir_free_timing { /* measured in bits */ u8 minlen; u8 maxlen; u16 ft_min; }; /** * struct img_ir_timings - Timing values. * @ldr: Leader symbol timing data * @s00: Zero symbol timing data for primary decoder * @s01: One symbol timing data for primary decoder * @s10: Zero symbol timing data for secondary (no leader symbol) decoder * @s11: One symbol timing data for secondary (no leader symbol) decoder * @ft: Free time symbol timing data */ struct img_ir_timings { struct img_ir_symbol_timing ldr, s00, s01, s10, s11; struct img_ir_free_timing ft; }; /** * struct img_ir_filter - Filter IR events. * @data: Data to match. * @mask: Mask of bits to compare. * @minlen: Additional minimum number of bits. * @maxlen: Additional maximum number of bits. */ struct img_ir_filter { u64 data; u64 mask; u8 minlen; u8 maxlen; }; /** * struct img_ir_timing_regvals - Calculated timing register values. * @ldr: Leader symbol timing register value * @s00: Zero symbol timing register value for primary decoder * @s01: One symbol timing register value for primary decoder * @s10: Zero symbol timing register value for secondary decoder * @s11: One symbol timing register value for secondary decoder * @ft: Free time symbol timing register value */ struct img_ir_timing_regvals { u32 ldr, s00, s01, s10, s11, ft; }; #define IMG_IR_SCANCODE 0 /* new scancode */ #define IMG_IR_REPEATCODE 1 /* repeat the previous code */ /** * struct img_ir_scancode_req - Scancode request data. * @protocol: Protocol code of received message (defaults to * RC_PROTO_UNKNOWN). * @scancode: Scan code of received message (must be written by * handler if IMG_IR_SCANCODE is returned). * @toggle: Toggle bit (defaults to 0). */ struct img_ir_scancode_req { enum rc_proto protocol; u32 scancode; u8 toggle; }; /** * struct img_ir_decoder - Decoder settings for an IR protocol. * @type: Protocol types bitmap. * @tolerance: Timing tolerance as a percentage (default 10%). * @unit: Unit of timings in nanoseconds (default 1 us). * @timings: Primary timings * @rtimings: Additional override timings while waiting for repeats. * @repeat: Maximum repeat interval (always in milliseconds). * @control: Control flags. * * @scancode: Pointer to function to convert the IR data into a scancode (it * must be safe to execute in interrupt context). * Returns IMG_IR_SCANCODE to emit new scancode. * Returns IMG_IR_REPEATCODE to repeat previous code. * Returns -errno (e.g. -EINVAL) on error. * @filter: Pointer to function to convert scancode filter to raw hardware * filter. The minlen and maxlen fields will have been initialised * to the maximum range. */ struct img_ir_decoder { /* core description */ u64 type; unsigned int tolerance; unsigned int unit; struct img_ir_timings timings; struct img_ir_timings rtimings; unsigned int repeat; struct img_ir_control control; /* scancode logic */ int (*scancode)(int len, u64 raw, u64 enabled_protocols, struct img_ir_scancode_req *request); int (*filter)(const struct rc_scancode_filter *in, struct img_ir_filter *out, u64 protocols); }; extern struct img_ir_decoder img_ir_nec; extern struct img_ir_decoder img_ir_jvc; extern struct img_ir_decoder img_ir_sony; extern struct img_ir_decoder img_ir_sharp; extern struct img_ir_decoder img_ir_sanyo; extern struct img_ir_decoder img_ir_rc5; extern struct img_ir_decoder img_ir_rc6; /** * struct img_ir_reg_timings - Reg values for decoder timings at clock rate. * @ctrl: Processed control register value. * @timings: Processed primary timings. * @rtimings: Processed repeat timings. */ struct img_ir_reg_timings { u32 ctrl; struct img_ir_timing_regvals timings; struct img_ir_timing_regvals rtimings; }; struct img_ir_priv; #ifdef CONFIG_IR_IMG_HW enum img_ir_mode { IMG_IR_M_NORMAL, IMG_IR_M_REPEATING, #ifdef CONFIG_PM_SLEEP IMG_IR_M_WAKE, #endif }; /** * struct img_ir_priv_hw - Private driver data for hardware decoder. * @ct_quirks: Quirk bits for each code type. * @rdev: Remote control device * @clk_nb: Notifier block for clock notify events. * @end_timer: Timer until repeat timeout. * @suspend_timer: Timer to re-enable protocol. * @decoder: Current decoder settings. * @enabled_protocols: Currently enabled protocols. * @clk_hz: Current core clock rate in Hz. * @reg_timings: Timing reg values for decoder at clock rate. * @flags: IMG_IR_F_*. * @filters: HW filters (derived from scancode filters). * @mode: Current decode mode. * @stopping: Indicates that decoder is being taken down and timers * should not be restarted. * @suspend_irqen: Saved IRQ enable mask over suspend. * @quirk_suspend_irq: Saved IRQ enable mask over quirk suspend timer. */ struct img_ir_priv_hw { unsigned int ct_quirks[4]; struct rc_dev *rdev; struct notifier_block clk_nb; struct timer_list end_timer; struct timer_list suspend_timer; const struct img_ir_decoder *decoder; u64 enabled_protocols; unsigned long clk_hz; struct img_ir_reg_timings reg_timings; unsigned int flags; struct img_ir_filter filters[RC_FILTER_MAX]; enum img_ir_mode mode; bool stopping; u32 suspend_irqen; u32 quirk_suspend_irq; }; static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) { return hw->rdev; }; void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status); void img_ir_setup_hw(struct img_ir_priv *priv); int img_ir_probe_hw(struct img_ir_priv *priv); void img_ir_remove_hw(struct img_ir_priv *priv); #ifdef CONFIG_PM_SLEEP int img_ir_suspend(struct device *dev); int img_ir_resume(struct device *dev); #else #define img_ir_suspend NULL #define img_ir_resume NULL #endif #else struct img_ir_priv_hw { }; static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) { return false; }; static inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) { } static inline void img_ir_setup_hw(struct img_ir_priv *priv) { } static inline int img_ir_probe_hw(struct img_ir_priv *priv) { return -ENODEV; } static inline void img_ir_remove_hw(struct img_ir_priv *priv) { } #define img_ir_suspend NULL #define img_ir_resume NULL #endif /* CONFIG_IR_IMG_HW */ #endif /* _IMG_IR_HW_H_ */ |