/* 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_ */ 
 |