1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 16:52:14 +02:00
Files
u-boot-megous/drivers/ir/sunxi-ir.h
Ondrej Jirman ba8c26ce40 initial
2019-03-04 15:37:41 +01:00

207 lines
5.6 KiB
C
Executable File

/*
* (C) Copyright 2007-2016
* Allwinnertech Technology Co., Ltd <www.allwinnertech.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __SUNXI_IR_H__
#define __SUNXI_IR_H__
extern void ir_clk_cfg(void);
#define MAX_IR_ADDR_NUM (64)
#define IR_DETECT_NULL (1)
#define IR_DETECT_OK (2)
#define IR_DETECT_END (3)
//#define SUNXI_IR_DEBUG
#ifdef SUNXI_IR_DEBUG
#define print_debug(fmt...) printf(fmt...)
#else
#define print_debug(fmt...)
#endif
#define CONFIG_FPGA_V4_PLATFORM
//Registers
#define IR_REG(x) (x)
#define IR_CTRL_REG IR_REG(0x00) //IR Control
#define IR_RXCFG_REG IR_REG(0x10) //Rx Config
#define IR_RXDAT_REG IR_REG(0x20) //Rx Data
#define IR_RXINTE_REG IR_REG(0x2C) //Rx Interrupt Enable
#define IR_RXINTS_REG IR_REG(0x30) //Rx Interrupt Status
#define IR_SPLCFG_REG IR_REG(0x34) //IR Sample Config
#define IR_FIFO_SIZE (64) /* 64Bytes */
#if (defined CONFIG_FPGA_V4_PLATFORM) || (defined CONFIG_FPGA_V7_PLATFORM)
#define CIR_24M_CLK_USED
#endif
#ifdef CIR_24M_CLK_USED
#define IR_SIMPLE_UNIT (21333) /* simple in ns */
#define IR_CLK (24000000) /* fpga clk output is fixed */
#define IR_CIR_MODE (0x3<<4) /* CIR mode enable */
#define IR_ENTIRE_ENABLE (0x3<<0) /* IR entire enable */
#define IR_SAMPLE_DEV (0x3<<0) /* 24MHz/512 =46875Hz (21333ns) */
#define IR_FIFO_32 (((IR_FIFO_SIZE>>1)-1)<<8)
#define IR_IRQ_STATUS ((0x1<<4)|0x3)
#else
#define IR_SIMPLE_UNIT (32000) /* simple in ns */
#define IR_CLK (8000000)
#define IR_CIR_MODE (0x3<<4) /* CIR mode enable */
#define IR_ENTIRE_ENABLE (0x3<<0) /* IR entire enable */
#define IR_SAMPLE_DEV (0x2<<0) /* 4MHz/256 =31250Hz (32000ns) */
#define IR_FIFO_32 (((IR_FIFO_SIZE>>1)-1)<<8)
#define IR_IRQ_STATUS ((0x1<<4)|0x3)
#endif
//Bit Definition of IR_RXINTS_REG Register
#define IR_RXINTS_RXOF (0x1<<0) /* Rx FIFO Overflow */
#define IR_RXINTS_RXPE (0x1<<1) /* Rx Packet End */
#define IR_RXINTS_RXDA (0x1<<4) /* Rx FIFO Data Available */
#ifdef CIR_24M_CLK_USED
#define IR_RXFILT_VAL (((16)&0x3f)<<2) /* Filter Threshold = 16*21.3 = ~341us < 500us */
#define IR_RXIDLE_VAL (((5)&0xff)<<8) /* Idle Threshold = (5+1)*128*21.3 = ~16.4ms > 9ms */
#define IR_ACTIVE_T ((0&0xff)<<16) /* Active Threshold */
#define IR_ACTIVE_T_C ((1&0xff)<<23) /* Active Threshold */
#else
#define IR_RXFILT_VAL (((12)&0x3f)<<2) /* Filter Threshold = 12*32 = ~384us < 500us */
#define IR_RXIDLE_VAL (((2)&0xff)<<8) /* Idle Threshold = (2+1)*128*32 = ~23.8ms > 9ms */
#define IR_ACTIVE_T ((99&0xff)<<16) /* Active Threshold */
#define IR_ACTIVE_T_C ((0&0xff)<<23) /* Active Threshold */
#endif
enum ir_mode {
CIR_MODE_ENABLE,
IR_MODULE_ENABLE,
};
enum ir_sample_config {
IR_SAMPLE_REG_CLEAR,
IR_CLK_SAMPLE,
IR_FILTER_TH,
IR_IDLE_TH,
IR_ACTIVE_TH,
};
enum ir_irq_config {
IR_IRQ_STATUS_CLEAR,
IR_IRQ_ENABLE,
IR_IRQ_FIFO_SIZE,
};
enum {
IR_SUPLY_DISABLE = 0,
IR_SUPLY_ENABLE,
};
struct ir_raw_event {
union {
u32 duration;
struct {
u32 carrier;
u8 duty_cycle;
};
};
unsigned pulse:1;
unsigned reset:1;
unsigned timeout:1;
unsigned carrier_report:1;
};
#define DEFINE_IR_RAW_EVENT(event) \
struct ir_raw_event event = { \
{ .duration = 0 } , \
.pulse = 0, \
.reset = 0, \
.timeout = 0, \
.carrier_report = 0 }
static inline void init_ir_raw_event(struct ir_raw_event *ev)
{
memset(ev, 0, sizeof(*ev));
}
struct nec_dec {
int state;
unsigned count;
u32 bits;
bool is_nec_x;
bool necx_repeat;
bool curt_repeat;
};
struct sunxi_ir_data {
u32 ir_addr_cnt;
u32 ir_recoverykey[MAX_IR_ADDR_NUM];
u32 ir_addr[MAX_IR_ADDR_NUM];
};
struct ir_raw_buffer {
unsigned long dcnt; /*Packet Count*/
struct nec_dec nec;
u32 scancode;
#define IR_RAW_BUF_SIZE 128
struct ir_raw_event raw[IR_RAW_BUF_SIZE];
};
/* macros for IR decoders */
static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin)
{
return d1 > (d2 - margin);
}
static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin)
{
return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
}
static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y)
{
return x->pulse != y->pulse;
}
static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
{
if (duration > ev->duration)
ev->duration = 0;
else
ev->duration -= duration;
}
/* Returns true if event is normal pulse/space event */
static inline bool is_timing_event(struct ir_raw_event ev)
{
return !ev.carrier_report && !ev.reset;
}
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
void rc_keydown(struct ir_raw_buffer *ir_raw, u32 scancode, u8 toggle);
int ir_setup(void);
void ir_disable(void);
#endif /* end of __SUNXI_IR_H__ */