162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ImgTec IR Hardware Decoder found in PowerDown Controller. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2010-2014 Imagination Technologies Ltd. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _IMG_IR_HW_H_ 962306a36Sopenharmony_ci#define _IMG_IR_HW_H_ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/kernel.h> 1262306a36Sopenharmony_ci#include <media/rc-core.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* constants */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define IMG_IR_CODETYPE_PULSELEN 0x0 /* Sony */ 1762306a36Sopenharmony_ci#define IMG_IR_CODETYPE_PULSEDIST 0x1 /* NEC, Toshiba, Micom, Sharp */ 1862306a36Sopenharmony_ci#define IMG_IR_CODETYPE_BIPHASE 0x2 /* RC-5/6 */ 1962306a36Sopenharmony_ci#define IMG_IR_CODETYPE_2BITPULSEPOS 0x3 /* RC-MM */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* Timing information */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/** 2562306a36Sopenharmony_ci * struct img_ir_control - Decoder control settings 2662306a36Sopenharmony_ci * @decoden: Primary decoder enable 2762306a36Sopenharmony_ci * @code_type: Decode type (see IMG_IR_CODETYPE_*) 2862306a36Sopenharmony_ci * @hdrtog: Detect header toggle symbol after leader symbol 2962306a36Sopenharmony_ci * @ldrdec: Don't discard leader if maximum width reached 3062306a36Sopenharmony_ci * @decodinpol: Decoder input polarity (1=active high) 3162306a36Sopenharmony_ci * @bitorien: Bit orientation (1=MSB first) 3262306a36Sopenharmony_ci * @d1validsel: Decoder 2 takes over if it detects valid data 3362306a36Sopenharmony_ci * @bitinv: Bit inversion switch (1=don't invert) 3462306a36Sopenharmony_ci * @decodend2: Secondary decoder enable (no leader symbol) 3562306a36Sopenharmony_ci * @bitoriend2: Bit orientation (1=MSB first) 3662306a36Sopenharmony_ci * @bitinvd2: Secondary decoder bit inversion switch (1=don't invert) 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_cistruct img_ir_control { 3962306a36Sopenharmony_ci unsigned decoden:1; 4062306a36Sopenharmony_ci unsigned code_type:2; 4162306a36Sopenharmony_ci unsigned hdrtog:1; 4262306a36Sopenharmony_ci unsigned ldrdec:1; 4362306a36Sopenharmony_ci unsigned decodinpol:1; 4462306a36Sopenharmony_ci unsigned bitorien:1; 4562306a36Sopenharmony_ci unsigned d1validsel:1; 4662306a36Sopenharmony_ci unsigned bitinv:1; 4762306a36Sopenharmony_ci unsigned decodend2:1; 4862306a36Sopenharmony_ci unsigned bitoriend2:1; 4962306a36Sopenharmony_ci unsigned bitinvd2:1; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/** 5362306a36Sopenharmony_ci * struct img_ir_timing_range - range of timing values 5462306a36Sopenharmony_ci * @min: Minimum timing value 5562306a36Sopenharmony_ci * @max: Maximum timing value (if < @min, this will be set to @min during 5662306a36Sopenharmony_ci * preprocessing step, so it is normally not explicitly initialised 5762306a36Sopenharmony_ci * and is taken care of by the tolerance) 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistruct img_ir_timing_range { 6062306a36Sopenharmony_ci u16 min; 6162306a36Sopenharmony_ci u16 max; 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/** 6562306a36Sopenharmony_ci * struct img_ir_symbol_timing - timing data for a symbol 6662306a36Sopenharmony_ci * @pulse: Timing range for the length of the pulse in this symbol 6762306a36Sopenharmony_ci * @space: Timing range for the length of the space in this symbol 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_cistruct img_ir_symbol_timing { 7062306a36Sopenharmony_ci struct img_ir_timing_range pulse; 7162306a36Sopenharmony_ci struct img_ir_timing_range space; 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/** 7562306a36Sopenharmony_ci * struct img_ir_free_timing - timing data for free time symbol 7662306a36Sopenharmony_ci * @minlen: Minimum number of bits of data 7762306a36Sopenharmony_ci * @maxlen: Maximum number of bits of data 7862306a36Sopenharmony_ci * @ft_min: Minimum free time after message 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_cistruct img_ir_free_timing { 8162306a36Sopenharmony_ci /* measured in bits */ 8262306a36Sopenharmony_ci u8 minlen; 8362306a36Sopenharmony_ci u8 maxlen; 8462306a36Sopenharmony_ci u16 ft_min; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/** 8862306a36Sopenharmony_ci * struct img_ir_timings - Timing values. 8962306a36Sopenharmony_ci * @ldr: Leader symbol timing data 9062306a36Sopenharmony_ci * @s00: Zero symbol timing data for primary decoder 9162306a36Sopenharmony_ci * @s01: One symbol timing data for primary decoder 9262306a36Sopenharmony_ci * @s10: Zero symbol timing data for secondary (no leader symbol) decoder 9362306a36Sopenharmony_ci * @s11: One symbol timing data for secondary (no leader symbol) decoder 9462306a36Sopenharmony_ci * @ft: Free time symbol timing data 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_cistruct img_ir_timings { 9762306a36Sopenharmony_ci struct img_ir_symbol_timing ldr, s00, s01, s10, s11; 9862306a36Sopenharmony_ci struct img_ir_free_timing ft; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/** 10262306a36Sopenharmony_ci * struct img_ir_filter - Filter IR events. 10362306a36Sopenharmony_ci * @data: Data to match. 10462306a36Sopenharmony_ci * @mask: Mask of bits to compare. 10562306a36Sopenharmony_ci * @minlen: Additional minimum number of bits. 10662306a36Sopenharmony_ci * @maxlen: Additional maximum number of bits. 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_cistruct img_ir_filter { 10962306a36Sopenharmony_ci u64 data; 11062306a36Sopenharmony_ci u64 mask; 11162306a36Sopenharmony_ci u8 minlen; 11262306a36Sopenharmony_ci u8 maxlen; 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/** 11662306a36Sopenharmony_ci * struct img_ir_timing_regvals - Calculated timing register values. 11762306a36Sopenharmony_ci * @ldr: Leader symbol timing register value 11862306a36Sopenharmony_ci * @s00: Zero symbol timing register value for primary decoder 11962306a36Sopenharmony_ci * @s01: One symbol timing register value for primary decoder 12062306a36Sopenharmony_ci * @s10: Zero symbol timing register value for secondary decoder 12162306a36Sopenharmony_ci * @s11: One symbol timing register value for secondary decoder 12262306a36Sopenharmony_ci * @ft: Free time symbol timing register value 12362306a36Sopenharmony_ci */ 12462306a36Sopenharmony_cistruct img_ir_timing_regvals { 12562306a36Sopenharmony_ci u32 ldr, s00, s01, s10, s11, ft; 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define IMG_IR_SCANCODE 0 /* new scancode */ 12962306a36Sopenharmony_ci#define IMG_IR_REPEATCODE 1 /* repeat the previous code */ 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/** 13262306a36Sopenharmony_ci * struct img_ir_scancode_req - Scancode request data. 13362306a36Sopenharmony_ci * @protocol: Protocol code of received message (defaults to 13462306a36Sopenharmony_ci * RC_PROTO_UNKNOWN). 13562306a36Sopenharmony_ci * @scancode: Scan code of received message (must be written by 13662306a36Sopenharmony_ci * handler if IMG_IR_SCANCODE is returned). 13762306a36Sopenharmony_ci * @toggle: Toggle bit (defaults to 0). 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_cistruct img_ir_scancode_req { 14062306a36Sopenharmony_ci enum rc_proto protocol; 14162306a36Sopenharmony_ci u32 scancode; 14262306a36Sopenharmony_ci u8 toggle; 14362306a36Sopenharmony_ci}; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/** 14662306a36Sopenharmony_ci * struct img_ir_decoder - Decoder settings for an IR protocol. 14762306a36Sopenharmony_ci * @type: Protocol types bitmap. 14862306a36Sopenharmony_ci * @tolerance: Timing tolerance as a percentage (default 10%). 14962306a36Sopenharmony_ci * @unit: Unit of timings in nanoseconds (default 1 us). 15062306a36Sopenharmony_ci * @timings: Primary timings 15162306a36Sopenharmony_ci * @rtimings: Additional override timings while waiting for repeats. 15262306a36Sopenharmony_ci * @repeat: Maximum repeat interval (always in milliseconds). 15362306a36Sopenharmony_ci * @control: Control flags. 15462306a36Sopenharmony_ci * 15562306a36Sopenharmony_ci * @scancode: Pointer to function to convert the IR data into a scancode (it 15662306a36Sopenharmony_ci * must be safe to execute in interrupt context). 15762306a36Sopenharmony_ci * Returns IMG_IR_SCANCODE to emit new scancode. 15862306a36Sopenharmony_ci * Returns IMG_IR_REPEATCODE to repeat previous code. 15962306a36Sopenharmony_ci * Returns -errno (e.g. -EINVAL) on error. 16062306a36Sopenharmony_ci * @filter: Pointer to function to convert scancode filter to raw hardware 16162306a36Sopenharmony_ci * filter. The minlen and maxlen fields will have been initialised 16262306a36Sopenharmony_ci * to the maximum range. 16362306a36Sopenharmony_ci */ 16462306a36Sopenharmony_cistruct img_ir_decoder { 16562306a36Sopenharmony_ci /* core description */ 16662306a36Sopenharmony_ci u64 type; 16762306a36Sopenharmony_ci unsigned int tolerance; 16862306a36Sopenharmony_ci unsigned int unit; 16962306a36Sopenharmony_ci struct img_ir_timings timings; 17062306a36Sopenharmony_ci struct img_ir_timings rtimings; 17162306a36Sopenharmony_ci unsigned int repeat; 17262306a36Sopenharmony_ci struct img_ir_control control; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* scancode logic */ 17562306a36Sopenharmony_ci int (*scancode)(int len, u64 raw, u64 enabled_protocols, 17662306a36Sopenharmony_ci struct img_ir_scancode_req *request); 17762306a36Sopenharmony_ci int (*filter)(const struct rc_scancode_filter *in, 17862306a36Sopenharmony_ci struct img_ir_filter *out, u64 protocols); 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_nec; 18262306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_jvc; 18362306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_sony; 18462306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_sharp; 18562306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_sanyo; 18662306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_rc5; 18762306a36Sopenharmony_ciextern struct img_ir_decoder img_ir_rc6; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/** 19062306a36Sopenharmony_ci * struct img_ir_reg_timings - Reg values for decoder timings at clock rate. 19162306a36Sopenharmony_ci * @ctrl: Processed control register value. 19262306a36Sopenharmony_ci * @timings: Processed primary timings. 19362306a36Sopenharmony_ci * @rtimings: Processed repeat timings. 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_cistruct img_ir_reg_timings { 19662306a36Sopenharmony_ci u32 ctrl; 19762306a36Sopenharmony_ci struct img_ir_timing_regvals timings; 19862306a36Sopenharmony_ci struct img_ir_timing_regvals rtimings; 19962306a36Sopenharmony_ci}; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistruct img_ir_priv; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#ifdef CONFIG_IR_IMG_HW 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cienum img_ir_mode { 20662306a36Sopenharmony_ci IMG_IR_M_NORMAL, 20762306a36Sopenharmony_ci IMG_IR_M_REPEATING, 20862306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 20962306a36Sopenharmony_ci IMG_IR_M_WAKE, 21062306a36Sopenharmony_ci#endif 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci/** 21462306a36Sopenharmony_ci * struct img_ir_priv_hw - Private driver data for hardware decoder. 21562306a36Sopenharmony_ci * @ct_quirks: Quirk bits for each code type. 21662306a36Sopenharmony_ci * @rdev: Remote control device 21762306a36Sopenharmony_ci * @clk_nb: Notifier block for clock notify events. 21862306a36Sopenharmony_ci * @end_timer: Timer until repeat timeout. 21962306a36Sopenharmony_ci * @suspend_timer: Timer to re-enable protocol. 22062306a36Sopenharmony_ci * @decoder: Current decoder settings. 22162306a36Sopenharmony_ci * @enabled_protocols: Currently enabled protocols. 22262306a36Sopenharmony_ci * @clk_hz: Current core clock rate in Hz. 22362306a36Sopenharmony_ci * @reg_timings: Timing reg values for decoder at clock rate. 22462306a36Sopenharmony_ci * @flags: IMG_IR_F_*. 22562306a36Sopenharmony_ci * @filters: HW filters (derived from scancode filters). 22662306a36Sopenharmony_ci * @mode: Current decode mode. 22762306a36Sopenharmony_ci * @stopping: Indicates that decoder is being taken down and timers 22862306a36Sopenharmony_ci * should not be restarted. 22962306a36Sopenharmony_ci * @suspend_irqen: Saved IRQ enable mask over suspend. 23062306a36Sopenharmony_ci * @quirk_suspend_irq: Saved IRQ enable mask over quirk suspend timer. 23162306a36Sopenharmony_ci */ 23262306a36Sopenharmony_cistruct img_ir_priv_hw { 23362306a36Sopenharmony_ci unsigned int ct_quirks[4]; 23462306a36Sopenharmony_ci struct rc_dev *rdev; 23562306a36Sopenharmony_ci struct notifier_block clk_nb; 23662306a36Sopenharmony_ci struct timer_list end_timer; 23762306a36Sopenharmony_ci struct timer_list suspend_timer; 23862306a36Sopenharmony_ci const struct img_ir_decoder *decoder; 23962306a36Sopenharmony_ci u64 enabled_protocols; 24062306a36Sopenharmony_ci unsigned long clk_hz; 24162306a36Sopenharmony_ci struct img_ir_reg_timings reg_timings; 24262306a36Sopenharmony_ci unsigned int flags; 24362306a36Sopenharmony_ci struct img_ir_filter filters[RC_FILTER_MAX]; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci enum img_ir_mode mode; 24662306a36Sopenharmony_ci bool stopping; 24762306a36Sopenharmony_ci u32 suspend_irqen; 24862306a36Sopenharmony_ci u32 quirk_suspend_irq; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) 25262306a36Sopenharmony_ci{ 25362306a36Sopenharmony_ci return hw->rdev; 25462306a36Sopenharmony_ci}; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_civoid img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status); 25762306a36Sopenharmony_civoid img_ir_setup_hw(struct img_ir_priv *priv); 25862306a36Sopenharmony_ciint img_ir_probe_hw(struct img_ir_priv *priv); 25962306a36Sopenharmony_civoid img_ir_remove_hw(struct img_ir_priv *priv); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 26262306a36Sopenharmony_ciint img_ir_suspend(struct device *dev); 26362306a36Sopenharmony_ciint img_ir_resume(struct device *dev); 26462306a36Sopenharmony_ci#else 26562306a36Sopenharmony_ci#define img_ir_suspend NULL 26662306a36Sopenharmony_ci#define img_ir_resume NULL 26762306a36Sopenharmony_ci#endif 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci#else 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistruct img_ir_priv_hw { 27262306a36Sopenharmony_ci}; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistatic inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci return false; 27762306a36Sopenharmony_ci}; 27862306a36Sopenharmony_cistatic inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status) 27962306a36Sopenharmony_ci{ 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_cistatic inline void img_ir_setup_hw(struct img_ir_priv *priv) 28262306a36Sopenharmony_ci{ 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_cistatic inline int img_ir_probe_hw(struct img_ir_priv *priv) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci return -ENODEV; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_cistatic inline void img_ir_remove_hw(struct img_ir_priv *priv) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci} 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci#define img_ir_suspend NULL 29362306a36Sopenharmony_ci#define img_ir_resume NULL 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci#endif /* CONFIG_IR_IMG_HW */ 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci#endif /* _IMG_IR_HW_H_ */ 298