img-ir-hw.h 8.0 KB
Newer Older
1 2 3 4
/*
 * ImgTec IR Hardware Decoder found in PowerDown Controller.
 *
 * Copyright 2010-2014 Imagination Technologies Ltd.
5 6 7 8 9
 *
 * 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.
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
 */

#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_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 */
165 166
	int (*scancode)(int len, u64 raw, enum rc_type *protocol,
			u32 *scancode, u64 enabled_protocols);
167 168 169 170
	int (*filter)(const struct rc_scancode_filter *in,
		      struct img_ir_filter *out, u64 protocols);
};

171 172 173 174 175 176
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;

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
/**
 * 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;
};

int img_ir_register_decoder(struct img_ir_decoder *dec);
void img_ir_unregister_decoder(struct img_ir_decoder *dec);

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.
 * @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.
217 218
 * @stopping:		Indicates that decoder is being taken down and timers
 *			should not be restarted.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
 * @suspend_irqen:	Saved IRQ enable mask over suspend.
 */
struct img_ir_priv_hw {
	unsigned int			ct_quirks[4];
	struct rc_dev			*rdev;
	struct notifier_block		clk_nb;
	struct timer_list		end_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;
234
	bool				stopping;
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
	u32				suspend_irqen;
};

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