18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ImgTec IR Hardware Decoder found in PowerDown Controller. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2010-2014 Imagination Technologies Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef _IMG_IR_HW_H_ 98c2ecf20Sopenharmony_ci#define _IMG_IR_HW_H_ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <media/rc-core.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* constants */ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define IMG_IR_CODETYPE_PULSELEN 0x0 /* Sony */ 178c2ecf20Sopenharmony_ci#define IMG_IR_CODETYPE_PULSEDIST 0x1 /* NEC, Toshiba, Micom, Sharp */ 188c2ecf20Sopenharmony_ci#define IMG_IR_CODETYPE_BIPHASE 0x2 /* RC-5/6 */ 198c2ecf20Sopenharmony_ci#define IMG_IR_CODETYPE_2BITPULSEPOS 0x3 /* RC-MM */ 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* Timing information */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/** 258c2ecf20Sopenharmony_ci * struct img_ir_control - Decoder control settings 268c2ecf20Sopenharmony_ci * @decoden: Primary decoder enable 278c2ecf20Sopenharmony_ci * @code_type: Decode type (see IMG_IR_CODETYPE_*) 288c2ecf20Sopenharmony_ci * @hdrtog: Detect header toggle symbol after leader symbol 298c2ecf20Sopenharmony_ci * @ldrdec: Don't discard leader if maximum width reached 308c2ecf20Sopenharmony_ci * @decodinpol: Decoder input polarity (1=active high) 318c2ecf20Sopenharmony_ci * @bitorien: Bit orientation (1=MSB first) 328c2ecf20Sopenharmony_ci * @d1validsel: Decoder 2 takes over if it detects valid data 338c2ecf20Sopenharmony_ci * @bitinv: Bit inversion switch (1=don't invert) 348c2ecf20Sopenharmony_ci * @decodend2: Secondary decoder enable (no leader symbol) 358c2ecf20Sopenharmony_ci * @bitoriend2: Bit orientation (1=MSB first) 368c2ecf20Sopenharmony_ci * @bitinvd2: Secondary decoder bit inversion switch (1=don't invert) 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_cistruct img_ir_control { 398c2ecf20Sopenharmony_ci unsigned decoden:1; 408c2ecf20Sopenharmony_ci unsigned code_type:2; 418c2ecf20Sopenharmony_ci unsigned hdrtog:1; 428c2ecf20Sopenharmony_ci unsigned ldrdec:1; 438c2ecf20Sopenharmony_ci unsigned decodinpol:1; 448c2ecf20Sopenharmony_ci unsigned bitorien:1; 458c2ecf20Sopenharmony_ci unsigned d1validsel:1; 468c2ecf20Sopenharmony_ci unsigned bitinv:1; 478c2ecf20Sopenharmony_ci unsigned decodend2:1; 488c2ecf20Sopenharmony_ci unsigned bitoriend2:1; 498c2ecf20Sopenharmony_ci unsigned bitinvd2:1; 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/** 538c2ecf20Sopenharmony_ci * struct img_ir_timing_range - range of timing values 548c2ecf20Sopenharmony_ci * @min: Minimum timing value 558c2ecf20Sopenharmony_ci * @max: Maximum timing value (if < @min, this will be set to @min during 568c2ecf20Sopenharmony_ci * preprocessing step, so it is normally not explicitly initialised 578c2ecf20Sopenharmony_ci * and is taken care of by the tolerance) 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_cistruct img_ir_timing_range { 608c2ecf20Sopenharmony_ci u16 min; 618c2ecf20Sopenharmony_ci u16 max; 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/** 658c2ecf20Sopenharmony_ci * struct img_ir_symbol_timing - timing data for a symbol 668c2ecf20Sopenharmony_ci * @pulse: Timing range for the length of the pulse in this symbol 678c2ecf20Sopenharmony_ci * @space: Timing range for the length of the space in this symbol 688c2ecf20Sopenharmony_ci */ 698c2ecf20Sopenharmony_cistruct img_ir_symbol_timing { 708c2ecf20Sopenharmony_ci struct img_ir_timing_range pulse; 718c2ecf20Sopenharmony_ci struct img_ir_timing_range space; 728c2ecf20Sopenharmony_ci}; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/** 758c2ecf20Sopenharmony_ci * struct img_ir_free_timing - timing data for free time symbol 768c2ecf20Sopenharmony_ci * @minlen: Minimum number of bits of data 778c2ecf20Sopenharmony_ci * @maxlen: Maximum number of bits of data 788c2ecf20Sopenharmony_ci * @ft_min: Minimum free time after message 798c2ecf20Sopenharmony_ci */ 808c2ecf20Sopenharmony_cistruct img_ir_free_timing { 818c2ecf20Sopenharmony_ci /* measured in bits */ 828c2ecf20Sopenharmony_ci u8 minlen; 838c2ecf20Sopenharmony_ci u8 maxlen; 848c2ecf20Sopenharmony_ci u16 ft_min; 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/** 888c2ecf20Sopenharmony_ci * struct img_ir_timings - Timing values. 898c2ecf20Sopenharmony_ci * @ldr: Leader symbol timing data 908c2ecf20Sopenharmony_ci * @s00: Zero symbol timing data for primary decoder 918c2ecf20Sopenharmony_ci * @s01: One symbol timing data for primary decoder 928c2ecf20Sopenharmony_ci * @s10: Zero symbol timing data for secondary (no leader symbol) decoder 938c2ecf20Sopenharmony_ci * @s11: One symbol timing data for secondary (no leader symbol) decoder 948c2ecf20Sopenharmony_ci * @ft: Free time symbol timing data 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_cistruct img_ir_timings { 978c2ecf20Sopenharmony_ci struct img_ir_symbol_timing ldr, s00, s01, s10, s11; 988c2ecf20Sopenharmony_ci struct img_ir_free_timing ft; 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/** 1028c2ecf20Sopenharmony_ci * struct img_ir_filter - Filter IR events. 1038c2ecf20Sopenharmony_ci * @data: Data to match. 1048c2ecf20Sopenharmony_ci * @mask: Mask of bits to compare. 1058c2ecf20Sopenharmony_ci * @minlen: Additional minimum number of bits. 1068c2ecf20Sopenharmony_ci * @maxlen: Additional maximum number of bits. 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_cistruct img_ir_filter { 1098c2ecf20Sopenharmony_ci u64 data; 1108c2ecf20Sopenharmony_ci u64 mask; 1118c2ecf20Sopenharmony_ci u8 minlen; 1128c2ecf20Sopenharmony_ci u8 maxlen; 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci/** 1168c2ecf20Sopenharmony_ci * struct img_ir_timing_regvals - Calculated timing register values. 1178c2ecf20Sopenharmony_ci * @ldr: Leader symbol timing register value 1188c2ecf20Sopenharmony_ci * @s00: Zero symbol timing register value for primary decoder 1198c2ecf20Sopenharmony_ci * @s01: One symbol timing register value for primary decoder 1208c2ecf20Sopenharmony_ci * @s10: Zero symbol timing register value for secondary decoder 1218c2ecf20Sopenharmony_ci * @s11: One symbol timing register value for secondary decoder 1228c2ecf20Sopenharmony_ci * @ft: Free time symbol timing register value 1238c2ecf20Sopenharmony_ci */ 1248c2ecf20Sopenharmony_cistruct img_ir_timing_regvals { 1258c2ecf20Sopenharmony_ci u32 ldr, s00, s01, s10, s11, ft; 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#define IMG_IR_SCANCODE 0 /* new scancode */ 1298c2ecf20Sopenharmony_ci#define IMG_IR_REPEATCODE 1 /* repeat the previous code */ 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/** 1328c2ecf20Sopenharmony_ci * struct img_ir_scancode_req - Scancode request data. 1338c2ecf20Sopenharmony_ci * @protocol: Protocol code of received message (defaults to 1348c2ecf20Sopenharmony_ci * RC_PROTO_UNKNOWN). 1358c2ecf20Sopenharmony_ci * @scancode: Scan code of received message (must be written by 1368c2ecf20Sopenharmony_ci * handler if IMG_IR_SCANCODE is returned). 1378c2ecf20Sopenharmony_ci * @toggle: Toggle bit (defaults to 0). 1388c2ecf20Sopenharmony_ci */ 1398c2ecf20Sopenharmony_cistruct img_ir_scancode_req { 1408c2ecf20Sopenharmony_ci enum rc_proto protocol; 1418c2ecf20Sopenharmony_ci u32 scancode; 1428c2ecf20Sopenharmony_ci u8 toggle; 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci/** 1468c2ecf20Sopenharmony_ci * struct img_ir_decoder - Decoder settings for an IR protocol. 1478c2ecf20Sopenharmony_ci * @type: Protocol types bitmap. 1488c2ecf20Sopenharmony_ci * @tolerance: Timing tolerance as a percentage (default 10%). 1498c2ecf20Sopenharmony_ci * @unit: Unit of timings in nanoseconds (default 1 us). 1508c2ecf20Sopenharmony_ci * @timings: Primary timings 1518c2ecf20Sopenharmony_ci * @rtimings: Additional override timings while waiting for repeats. 1528c2ecf20Sopenharmony_ci * @repeat: Maximum repeat interval (always in milliseconds). 1538c2ecf20Sopenharmony_ci * @control: Control flags. 1548c2ecf20Sopenharmony_ci * 1558c2ecf20Sopenharmony_ci * @scancode: Pointer to function to convert the IR data into a scancode (it 1568c2ecf20Sopenharmony_ci * must be safe to execute in interrupt context). 1578c2ecf20Sopenharmony_ci * Returns IMG_IR_SCANCODE to emit new scancode. 1588c2ecf20Sopenharmony_ci * Returns IMG_IR_REPEATCODE to repeat previous code. 1598c2ecf20Sopenharmony_ci * Returns -errno (e.g. -EINVAL) on error. 1608c2ecf20Sopenharmony_ci * @filter: Pointer to function to convert scancode filter to raw hardware 1618c2ecf20Sopenharmony_ci * filter. The minlen and maxlen fields will have been initialised 1628c2ecf20Sopenharmony_ci * to the maximum range. 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_cistruct img_ir_decoder { 1658c2ecf20Sopenharmony_ci /* core description */ 1668c2ecf20Sopenharmony_ci u64 type; 1678c2ecf20Sopenharmony_ci unsigned int tolerance; 1688c2ecf20Sopenharmony_ci unsigned int unit; 1698c2ecf20Sopenharmony_ci struct img_ir_timings timings; 1708c2ecf20Sopenharmony_ci struct img_ir_timings rtimings; 1718c2ecf20Sopenharmony_ci unsigned int repeat; 1728c2ecf20Sopenharmony_ci struct img_ir_control control; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* scancode logic */ 1758c2ecf20Sopenharmony_ci int (*scancode)(int len, u64 raw, u64 enabled_protocols, 1768c2ecf20Sopenharmony_ci struct img_ir_scancode_req *request); 1778c2ecf20Sopenharmony_ci int (*filter)(const struct rc_scancode_filter *in, 1788c2ecf20Sopenharmony_ci struct img_ir_filter *out, u64 protocols); 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_nec; 1828c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_jvc; 1838c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_sony; 1848c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_sharp; 1858c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_sanyo; 1868c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_rc5; 1878c2ecf20Sopenharmony_ciextern struct img_ir_decoder img_ir_rc6; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/** 1908c2ecf20Sopenharmony_ci * struct img_ir_reg_timings - Reg values for decoder timings at clock rate. 1918c2ecf20Sopenharmony_ci * @ctrl: Processed control register value. 1928c2ecf20Sopenharmony_ci * @timings: Processed primary timings. 1938c2ecf20Sopenharmony_ci * @rtimings: Processed repeat timings. 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_cistruct img_ir_reg_timings { 1968c2ecf20Sopenharmony_ci u32 ctrl; 1978c2ecf20Sopenharmony_ci struct img_ir_timing_regvals timings; 1988c2ecf20Sopenharmony_ci struct img_ir_timing_regvals rtimings; 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistruct img_ir_priv; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci#ifdef CONFIG_IR_IMG_HW 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cienum img_ir_mode { 2068c2ecf20Sopenharmony_ci IMG_IR_M_NORMAL, 2078c2ecf20Sopenharmony_ci IMG_IR_M_REPEATING, 2088c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 2098c2ecf20Sopenharmony_ci IMG_IR_M_WAKE, 2108c2ecf20Sopenharmony_ci#endif 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci/** 2148c2ecf20Sopenharmony_ci * struct img_ir_priv_hw - Private driver data for hardware decoder. 2158c2ecf20Sopenharmony_ci * @ct_quirks: Quirk bits for each code type. 2168c2ecf20Sopenharmony_ci * @rdev: Remote control device 2178c2ecf20Sopenharmony_ci * @clk_nb: Notifier block for clock notify events. 2188c2ecf20Sopenharmony_ci * @end_timer: Timer until repeat timeout. 2198c2ecf20Sopenharmony_ci * @suspend_timer: Timer to re-enable protocol. 2208c2ecf20Sopenharmony_ci * @decoder: Current decoder settings. 2218c2ecf20Sopenharmony_ci * @enabled_protocols: Currently enabled protocols. 2228c2ecf20Sopenharmony_ci * @clk_hz: Current core clock rate in Hz. 2238c2ecf20Sopenharmony_ci * @reg_timings: Timing reg values for decoder at clock rate. 2248c2ecf20Sopenharmony_ci * @flags: IMG_IR_F_*. 2258c2ecf20Sopenharmony_ci * @filters: HW filters (derived from scancode filters). 2268c2ecf20Sopenharmony_ci * @mode: Current decode mode. 2278c2ecf20Sopenharmony_ci * @stopping: Indicates that decoder is being taken down and timers 2288c2ecf20Sopenharmony_ci * should not be restarted. 2298c2ecf20Sopenharmony_ci * @suspend_irqen: Saved IRQ enable mask over suspend. 2308c2ecf20Sopenharmony_ci * @quirk_suspend_irq: Saved IRQ enable mask over quirk suspend timer. 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_cistruct img_ir_priv_hw { 2338c2ecf20Sopenharmony_ci unsigned int ct_quirks[4]; 2348c2ecf20Sopenharmony_ci struct rc_dev *rdev; 2358c2ecf20Sopenharmony_ci struct notifier_block clk_nb; 2368c2ecf20Sopenharmony_ci struct timer_list end_timer; 2378c2ecf20Sopenharmony_ci struct timer_list suspend_timer; 2388c2ecf20Sopenharmony_ci const struct img_ir_decoder *decoder; 2398c2ecf20Sopenharmony_ci u64 enabled_protocols; 2408c2ecf20Sopenharmony_ci unsigned long clk_hz; 2418c2ecf20Sopenharmony_ci struct img_ir_reg_timings reg_timings; 2428c2ecf20Sopenharmony_ci unsigned int flags; 2438c2ecf20Sopenharmony_ci struct img_ir_filter filters[RC_FILTER_MAX]; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci enum img_ir_mode mode; 2468c2ecf20Sopenharmony_ci bool stopping; 2478c2ecf20Sopenharmony_ci u32 suspend_irqen; 2488c2ecf20Sopenharmony_ci u32 quirk_suspend_irq; 2498c2ecf20Sopenharmony_ci}; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci return hw->rdev; 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_civoid img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status); 2578c2ecf20Sopenharmony_civoid img_ir_setup_hw(struct img_ir_priv *priv); 2588c2ecf20Sopenharmony_ciint img_ir_probe_hw(struct img_ir_priv *priv); 2598c2ecf20Sopenharmony_civoid img_ir_remove_hw(struct img_ir_priv *priv); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 2628c2ecf20Sopenharmony_ciint img_ir_suspend(struct device *dev); 2638c2ecf20Sopenharmony_ciint img_ir_resume(struct device *dev); 2648c2ecf20Sopenharmony_ci#else 2658c2ecf20Sopenharmony_ci#define img_ir_suspend NULL 2668c2ecf20Sopenharmony_ci#define img_ir_resume NULL 2678c2ecf20Sopenharmony_ci#endif 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci#else 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_cistruct img_ir_priv_hw { 2728c2ecf20Sopenharmony_ci}; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistatic inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci return false; 2778c2ecf20Sopenharmony_ci}; 2788c2ecf20Sopenharmony_cistatic inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_cistatic inline void img_ir_setup_hw(struct img_ir_priv *priv) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_cistatic inline int img_ir_probe_hw(struct img_ir_priv *priv) 2858c2ecf20Sopenharmony_ci{ 2868c2ecf20Sopenharmony_ci return -ENODEV; 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_cistatic inline void img_ir_remove_hw(struct img_ir_priv *priv) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci} 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci#define img_ir_suspend NULL 2938c2ecf20Sopenharmony_ci#define img_ir_resume NULL 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci#endif /* CONFIG_IR_IMG_HW */ 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci#endif /* _IMG_IR_HW_H_ */ 298