/*
 * ImgTec IR Hardware Decoder found in PowerDown Controller.
 *
 * Copyright 2010-2014 Imagination Technologies Ltd.
 *
 * 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 ties into the input subsystem using the RC-core. Protocol support is
 * provided in separate modules which provide the parameters and scancode
 * translation functions to set up the hardware decoder and interpret the
 * resulting input.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <media/rc-core.h>
#include "img-ir.h"

/* Decoders lock (only modified to preprocess them) */
static DEFINE_SPINLOCK(img_ir_decoders_lock);

static bool img_ir_decoders_preprocessed;
static struct img_ir_decoder *img_ir_decoders[] = {
#ifdef CPTCFG_IR_IMG_NEC
	&img_ir_nec,
#endif
#ifdef CPTCFG_IR_IMG_JVC
	&img_ir_jvc,
#endif
#ifdef CPTCFG_IR_IMG_SONY
	&img_ir_sony,
#endif
#ifdef CPTCFG_IR_IMG_SHARP
	&img_ir_sharp,
#endif
#ifdef CPTCFG_IR_IMG_SANYO
	&img_ir_sanyo,
#endif
	NULL
};

#define IMG_IR_F_FILTER		BIT(RC_FILTER_NORMAL)	/* enable filtering */
#define IMG_IR_F_WAKE		BIT(RC_FILTER_WAKEUP)	/* enable waking */

/* code type quirks */

#define IMG_IR_QUIRK_CODE_BROKEN	0x1	/* Decode is broken */
#define IMG_IR_QUIRK_CODE_LEN_INCR	0x2	/* Bit length needs increment */

/* functions for preprocessing timings, ensuring max is set */

static void img_ir_timing_preprocess(struct img_ir_timing_range *range,
				     unsigned int unit)
{
	if (range->max < range->min)
		range->max = range->min;
	if (unit) {
		/* multiply by unit and convert to microseconds */
		range->min = (range->min*unit)/1000;
		range->max = (range->max*unit + 999)/1000; /* round up */
	}
}

static void img_ir_symbol_timing_preprocess(struct img_ir_symbol_timing *timing,
					    unsigned int unit)
{
	img_ir_timing_preprocess(&timing->pulse, unit);
	img_ir_timing_preprocess(&timing->space, unit);
}

static void img_ir_timings_preprocess(struct img_ir_timings *timings,
				      unsigned int unit)
{
	img_ir_symbol_timing_preprocess(&timings->ldr, unit);
	img_ir_symbol_timing_preprocess(&timings->s00, unit);
	img_ir_symbol_timing_preprocess(&timings->s01, unit);
	img_ir_symbol_timing_preprocess(&timings->s10, unit);
	img_ir_symbol_timing_preprocess(&timings->s11, unit);
	/* default s10 and s11 to s00 and s01 if no leader */
	if (unit)
		/* multiply by unit and convert to microseconds (round up) */
		timings->ft.ft_min = (timings->ft.ft_min*unit + 999)/1000;
}

/* functions for filling empty fields with defaults */

static void img_ir_timing_defaults(struct img_ir_timing_range *range,
				   struct img_ir_timing_range *defaults)
{
	if (!range->min)
		range->min = defaults->min;
	if (!range->max)
		range->max = defaults->max;
}

static void img_ir_symbol_timing_defaults(struct img_ir_symbol_timing *timing,
					  struct img_ir_symbol_timing *defaults)
{
	img_ir_timing_defaults(&timing->pulse, &defaults->pulse);
	img_ir_timing_defaults(&timing->space, &defaults->space);
}

static void img_ir_timings_defaults(struct img_ir_timings *timings,
				    struct img_ir_timings *defaults)
{
	img_ir_symbol_timing_defaults(&timings->ldr, &defaults->ldr);
	img_ir_symbol_timing_defaults(&timings->s00, &defaults->s00);
	img_ir_symbol_timing_defaults(&timings->s01, &defaults->s01);
	img_ir_symbol_timing_defaults(&timings->s10, &defaults->s10);
	img_ir_symbol_timing_defaults(&timings->s11, &defaults->s11);
	if (!timings->ft.ft_min)
		timings->ft.ft_min = defaults->ft.ft_min;
}

/* functions for converting timings to register values */

/**
 * img_ir_control() - Convert control struct to control register value.
 * @control:	Control data
 *
 * Returns:	The control register value equivalent of @control.
 */
static u32 img_ir_control(const struct img_ir_control *control)
{
	u32 ctrl = control->code_type << IMG_IR_CODETYPE_SHIFT;
	if (control->decoden)
		ctrl |= IMG_IR_DECODEN;
	if (control->hdrtog)
		ctrl |= IMG_IR_HDRTOG;
	if (control->ldrdec)
		ctrl |= IMG_IR_LDRDEC;
	if (control->decodinpol)
		ctrl |= IMG_IR_DECODINPOL;
	if (control->bitorien)
		ctrl |= IMG_IR_BITORIEN;
	if (control->d1validsel)
		ctrl |= IMG_IR_D1VALIDSEL;
	if (control->bitinv)
		ctrl |= IMG_IR_BITINV;
	if (control->decodend2)
		ctrl |= IMG_IR_DECODEND2;
	if (control->bitoriend2)
		ctrl |= IMG_IR_BITORIEND2;
	if (control->bitinvd2)
		ctrl |= IMG_IR_BITINVD2;
	return ctrl;
}

/**
 * img_ir_timing_range_convert() - Convert microsecond range.
 * @out:	Output timing range in clock cycles with a shift.
 * @in:		Input timing range in microseconds.
 * @tolerance:	Tolerance as a fraction of 128 (roughly percent).
 * @clock_hz:	IR clock rate in Hz.
 * @shift:	Shift of output units.
 *
 * Converts min and max from microseconds to IR clock cycles, applies a
 * tolerance, and shifts for the register, rounding in the right direction.
 * Note that in and out can safely be the same object.
 */
static void img_ir_timing_range_convert(struct img_ir_timing_range *out,
					const struct img_ir_timing_range *in,
					unsigned int tolerance,
					unsigned long clock_hz,
					unsigned int shift)
{
	unsigned int min = in->min;
	unsigned int max = in->max;
	/* add a tolerance */
	min = min - (min*tolerance >> 7);
	max = max + (max*tolerance >> 7);
	/* convert from microseconds into clock cycles */
	min = min*clock_hz / 1000000;
	max = (max*clock_hz + 999999) / 1000000; /* round up */
	/* apply shift and copy to output */
	out->min = min >> shift;
	out->max = (max + ((1 << shift) - 1)) >> shift; /* round up */
}

/**
 * img_ir_symbol_timing() - Convert symbol timing struct to register value.
 * @timing:	Symbol timing data
 * @tolerance:	Timing tolerance where 0-128 represents 0-100%
 * @clock_hz:	Frequency of source clock in Hz
 * @pd_shift:	Shift to apply to symbol period
 * @w_shift:	Shift to apply to symbol width
 *
 * Returns:	Symbol timing register value based on arguments.
 */
static u32 img_ir_symbol_timing(const struct img_ir_symbol_timing *timing,
				unsigned int tolerance,
				unsigned long clock_hz,
				unsigned int pd_shift,
				unsigned int w_shift)
{
	struct img_ir_timing_range hw_pulse, hw_period;
	/* we calculate period in hw_period, then convert in place */
	hw_period.min = timing->pulse.min + timing->space.min;
	hw_period.max = timing->pulse.max + timing->space.max;
	img_ir_timing_range_convert(&hw_period, &hw_period,
			tolerance, clock_hz, pd_shift);
	img_ir_timing_range_convert(&hw_pulse, &timing->pulse,
			tolerance, clock_hz, w_shift);
	/* construct register value */
	return	(hw_period.max	<< IMG_IR_PD_MAX_SHIFT)	|
		(hw_period.min	<< IMG_IR_PD_MIN_SHIFT)	|
		(hw_pulse.max	<< IMG_IR_W_MAX_SHIFT)	|
		(hw_pulse.min	<< IMG_IR_W_MIN_SHIFT);
}

/**
 * img_ir_free_timing() - Convert free time timing struct to register value.
 * @timing:	Free symbol timing data
 * @clock_hz:	Source clock frequency in Hz
 *
 * Returns:	Free symbol timing register value.
 */
static u32 img_ir_free_timing(const struct img_ir_free_timing *timing,
			      unsigned long clock_hz)
{
	unsigned int minlen, maxlen, ft_min;
	/* minlen is only 5 bits, and round minlen to multiple of 2 */
	if (timing->minlen < 30)
		minlen = timing->minlen & -2;
	else
		minlen = 30;
	/* maxlen has maximum value of 48, and round maxlen to multiple of 2 */
	if (timing->maxlen < 48)
		maxlen = (timing->maxlen + 1) & -2;
	else
		maxlen = 48;
	/* convert and shift ft_min, rounding upwards */
	ft_min = (timing->ft_min*clock_hz + 999999) / 1000000;
	ft_min = (ft_min + 7) >> 3;
	/* construct register value */
	return	(maxlen << IMG_IR_MAXLEN_SHIFT)	|
		(minlen << IMG_IR_MINLEN_SHIFT)	|
		(ft_min << IMG_IR_FT_MIN_SHIFT);
}

/**
 * img_ir_free_timing_dynamic() - Update free time register value.
 * @st_ft:	Static free time register value from img_ir_free_timing.
 * @filter:	Current filter which may additionally restrict min/max len.
 *
 * Returns:	Updated free time register value based on the current filter.
 */
static u32 img_ir_free_timing_dynamic(u32 st_ft, struct img_ir_filter *filter)
{
	unsigned int minlen, maxlen, newminlen, newmaxlen;

	/* round minlen, maxlen to multiple of 2 */
	newminlen = filter->minlen & -2;
	newmaxlen = (filter->maxlen + 1) & -2;
	/* extract min/max len from register */
	minlen = (st_ft & IMG_IR_MINLEN) >> IMG_IR_MINLEN_SHIFT;
	maxlen = (st_ft & IMG_IR_MAXLEN) >> IMG_IR_MAXLEN_SHIFT;
	/* if the new values are more restrictive, update the register value */
	if (newminlen > minlen) {
		st_ft &= ~IMG_IR_MINLEN;
		st_ft |= newminlen << IMG_IR_MINLEN_SHIFT;
	}
	if (newmaxlen < maxlen) {
		st_ft &= ~IMG_IR_MAXLEN;
		st_ft |= newmaxlen << IMG_IR_MAXLEN_SHIFT;
	}
	return st_ft;
}

/**
 * img_ir_timings_convert() - Convert timings to register values
 * @regs:	Output timing register values
 * @timings:	Input timing data
 * @tolerance:	Timing tolerance where 0-128 represents 0-100%
 * @clock_hz:	Source clock frequency in Hz
 */
static void img_ir_timings_convert(struct img_ir_timing_regvals *regs,
				   const struct img_ir_timings *timings,
				   unsigned int tolerance,
				   unsigned int clock_hz)
{
	/* leader symbol timings are divided by 16 */
	regs->ldr = img_ir_symbol_timing(&timings->ldr, tolerance, clock_hz,
			4, 4);
	/* other symbol timings, pd fields only are divided by 2 */
	regs->s00 = img_ir_symbol_timing(&timings->s00, tolerance, clock_hz,
			1, 0);
	regs->s01 = img_ir_symbol_timing(&timings->s01, tolerance, clock_hz,
			1, 0);
	regs->s10 = img_ir_symbol_timing(&timings->s10, tolerance, clock_hz,
			1, 0);
	regs->s11 = img_ir_symbol_timing(&timings->s11, tolerance, clock_hz,
			1, 0);
	regs->ft = img_ir_free_timing(&timings->ft, clock_hz);
}

/**
 * img_ir_decoder_preprocess() - Preprocess timings in decoder.
 * @decoder:	Decoder to be preprocessed.
 *
 * Ensures that the symbol timing ranges are valid with respect to ordering, and
 * does some fixed conversion on them.
 */
static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder)
{
	/* default tolerance */
	if (!decoder->tolerance)
		decoder->tolerance = 10; /* percent */
	/* and convert tolerance to fraction out of 128 */
	decoder->tolerance = decoder->tolerance * 128 / 100;

	/* fill in implicit fields */
	img_ir_timings_preprocess(&decoder->timings, decoder->unit);

	/* do the same for repeat timings if applicable */
	if (decoder->repeat) {
		img_ir_timings_preprocess(&decoder->rtimings, decoder->unit);
		img_ir_timings_defaults(&decoder->rtimings, &decoder->timings);
	}
}

/**
 * img_ir_decoder_convert() - Generate internal timings in decoder.
 * @decoder:	Decoder to be converted to internal timings.
 * @timings:	Timing register values.
 * @clock_hz:	IR clock rate in Hz.
 *
 * Fills out the repeat timings and timing register values for a specific clock
 * rate.
 */
static void img_ir_decoder_convert(const struct img_ir_decoder *decoder,
				   struct img_ir_reg_timings *reg_timings,
				   unsigned int clock_hz)
{
	/* calculate control value */
	reg_timings->ctrl = img_ir_control(&decoder->control);

	/* fill in implicit fields and calculate register values */
	img_ir_timings_convert(&reg_timings->timings, &decoder->timings,
			       decoder->tolerance, clock_hz);

	/* do the same for repeat timings if applicable */
	if (decoder->repeat)
		img_ir_timings_convert(&reg_timings->rtimings,
				       &decoder->rtimings, decoder->tolerance,
				       clock_hz);
}

/**
 * img_ir_write_timings() - Write timings to the hardware now
 * @priv:	IR private data
 * @regs:	Timing register values to write
 * @type:	RC filter type (RC_FILTER_*)
 *
 * Write timing register values @regs to the hardware, taking into account the
 * current filter which may impose restrictions on the length of the expected
 * data.
 */
static void img_ir_write_timings(struct img_ir_priv *priv,
				 struct img_ir_timing_regvals *regs,
				 enum rc_filter_type type)
{
	struct img_ir_priv_hw *hw = &priv->hw;

	/* filter may be more restrictive to minlen, maxlen */
	u32 ft = regs->ft;
	if (hw->flags & BIT(type))
		ft = img_ir_free_timing_dynamic(regs->ft, &hw->filters[type]);
	/* write to registers */
	img_ir_write(priv, IMG_IR_LEAD_SYMB_TIMING, regs->ldr);
	img_ir_write(priv, IMG_IR_S00_SYMB_TIMING, regs->s00);
	img_ir_write(priv, IMG_IR_S01_SYMB_TIMING, regs->s01);
	img_ir_write(priv, IMG_IR_S10_SYMB_TIMING, regs->s10);
	img_ir_write(priv, IMG_IR_S11_SYMB_TIMING, regs->s11);
	img_ir_write(priv, IMG_IR_FREE_SYMB_TIMING, ft);
	dev_dbg(priv->dev, "timings: ldr=%#x, s=[%#x, %#x, %#x, %#x], ft=%#x\n",
		regs->ldr, regs->s00, regs->s01, regs->s10, regs->s11, ft);
}

static void img_ir_write_filter(struct img_ir_priv *priv,
				struct img_ir_filter *filter)
{
	if (filter) {
		dev_dbg(priv->dev, "IR filter=%016llx & %016llx\n",
			(unsigned long long)filter->data,
			(unsigned long long)filter->mask);
		img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_LW, (u32)filter->data);
		img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_UP, (u32)(filter->data
									>> 32));
		img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, (u32)filter->mask);
		img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, (u32)(filter->mask
									>> 32));
	} else {
		dev_dbg(priv->dev, "IR clearing filter\n");
		img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, 0);
		img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, 0);
	}
}

/* caller must have lock */
static void _img_ir_set_filter(struct img_ir_priv *priv,
			       struct img_ir_filter *filter)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	u32 irq_en, irq_on;

	irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
	if (filter) {
		/* Only use the match interrupt */
		hw->filters[RC_FILTER_NORMAL] = *filter;
		hw->flags |= IMG_IR_F_FILTER;
		irq_on = IMG_IR_IRQ_DATA_MATCH;
		irq_en &= ~(IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID);
	} else {
		/* Only use the valid interrupt */
		hw->flags &= ~IMG_IR_F_FILTER;
		irq_en &= ~IMG_IR_IRQ_DATA_MATCH;
		irq_on = IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID;
	}
	irq_en |= irq_on;

	img_ir_write_filter(priv, filter);
	/* clear any interrupts we're enabling so we don't handle old ones */
	img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_on);
	img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
}

/* caller must have lock */
static void _img_ir_set_wake_filter(struct img_ir_priv *priv,
				    struct img_ir_filter *filter)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	if (filter) {
		/* Enable wake, and copy filter for later */
		hw->filters[RC_FILTER_WAKEUP] = *filter;
		hw->flags |= IMG_IR_F_WAKE;
	} else {
		/* Disable wake */
		hw->flags &= ~IMG_IR_F_WAKE;
	}
}

/* Callback for setting scancode filter */
static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type,
			     struct rc_scancode_filter *sc_filter)
{
	struct img_ir_priv *priv = dev->priv;
	struct img_ir_priv_hw *hw = &priv->hw;
	struct img_ir_filter filter, *filter_ptr = &filter;
	int ret = 0;

	dev_dbg(priv->dev, "IR scancode %sfilter=%08x & %08x\n",
		type == RC_FILTER_WAKEUP ? "wake " : "",
		sc_filter->data,
		sc_filter->mask);

	spin_lock_irq(&priv->lock);

	/* filtering can always be disabled */
	if (!sc_filter->mask) {
		filter_ptr = NULL;
		goto set_unlock;
	}

	/* current decoder must support scancode filtering */
	if (!hw->decoder || !hw->decoder->filter) {
		ret = -EINVAL;
		goto unlock;
	}

	/* convert scancode filter to raw filter */
	filter.minlen = 0;
	filter.maxlen = ~0;
	ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols);
	if (ret)
		goto unlock;
	dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n",
		type == RC_FILTER_WAKEUP ? "wake " : "",
		(unsigned long long)filter.data,
		(unsigned long long)filter.mask);

set_unlock:
	/* apply raw filters */
	switch (type) {
	case RC_FILTER_NORMAL:
		_img_ir_set_filter(priv, filter_ptr);
		break;
	case RC_FILTER_WAKEUP:
		_img_ir_set_wake_filter(priv, filter_ptr);
		break;
	default:
		ret = -EINVAL;
	}

unlock:
	spin_unlock_irq(&priv->lock);
	return ret;
}

static int img_ir_set_normal_filter(struct rc_dev *dev,
				    struct rc_scancode_filter *sc_filter)
{
	return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter);
}

static int img_ir_set_wakeup_filter(struct rc_dev *dev,
				    struct rc_scancode_filter *sc_filter)
{
	return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter);
}

/**
 * img_ir_set_decoder() - Set the current decoder.
 * @priv:	IR private data.
 * @decoder:	Decoder to use with immediate effect.
 * @proto:	Protocol bitmap (or 0 to use decoder->type).
 */
static void img_ir_set_decoder(struct img_ir_priv *priv,
			       const struct img_ir_decoder *decoder,
			       u64 proto)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	struct rc_dev *rdev = hw->rdev;
	u32 ir_status, irq_en;
	spin_lock_irq(&priv->lock);

	/* switch off and disable interrupts */
	img_ir_write(priv, IMG_IR_CONTROL, 0);
	irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
	img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en & IMG_IR_IRQ_EDGE);
	img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_ALL & ~IMG_IR_IRQ_EDGE);

	/* ack any data already detected */
	ir_status = img_ir_read(priv, IMG_IR_STATUS);
	if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) {
		ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
		img_ir_write(priv, IMG_IR_STATUS, ir_status);
		img_ir_read(priv, IMG_IR_DATA_LW);
		img_ir_read(priv, IMG_IR_DATA_UP);
	}

	/* stop the end timer and switch back to normal mode */
	del_timer_sync(&hw->end_timer);
	hw->mode = IMG_IR_M_NORMAL;

	/* clear the wakeup scancode filter */
	rdev->scancode_wakeup_filter.data = 0;
	rdev->scancode_wakeup_filter.mask = 0;

	/* clear raw filters */
	_img_ir_set_filter(priv, NULL);
	_img_ir_set_wake_filter(priv, NULL);

	/* clear the enabled protocols */
	hw->enabled_protocols = 0;

	/* switch decoder */
	hw->decoder = decoder;
	if (!decoder)
		goto unlock;

	/* set the enabled protocols */
	if (!proto)
		proto = decoder->type;
	hw->enabled_protocols = proto;

	/* write the new timings */
	img_ir_decoder_convert(decoder, &hw->reg_timings, hw->clk_hz);
	img_ir_write_timings(priv, &hw->reg_timings.timings, RC_FILTER_NORMAL);

	/* set up and enable */
	img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);


unlock:
	spin_unlock_irq(&priv->lock);
}

/**
 * img_ir_decoder_compatable() - Find whether a decoder will work with a device.
 * @priv:	IR private data.
 * @dec:	Decoder to check.
 *
 * Returns:	true if @dec is compatible with the device @priv refers to.
 */
static bool img_ir_decoder_compatible(struct img_ir_priv *priv,
				      const struct img_ir_decoder *dec)
{
	unsigned int ct;

	/* don't accept decoders using code types which aren't supported */
	ct = dec->control.code_type;
	if (priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_BROKEN)
		return false;

	return true;
}

/**
 * img_ir_allowed_protos() - Get allowed protocols from global decoder list.
 * @priv:	IR private data.
 *
 * Returns:	Mask of protocols supported by the device @priv refers to.
 */
static u64 img_ir_allowed_protos(struct img_ir_priv *priv)
{
	u64 protos = 0;
	struct img_ir_decoder **decp;

	for (decp = img_ir_decoders; *decp; ++decp) {
		const struct img_ir_decoder *dec = *decp;
		if (img_ir_decoder_compatible(priv, dec))
			protos |= dec->type;
	}
	return protos;
}

/* Callback for changing protocol using sysfs */
static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type)
{
	struct img_ir_priv *priv = dev->priv;
	struct img_ir_priv_hw *hw = &priv->hw;
	struct rc_dev *rdev = hw->rdev;
	struct img_ir_decoder **decp;
	u64 wakeup_protocols;

	if (!*ir_type) {
		/* disable all protocols */
		img_ir_set_decoder(priv, NULL, 0);
		goto success;
	}
	for (decp = img_ir_decoders; *decp; ++decp) {
		const struct img_ir_decoder *dec = *decp;
		if (!img_ir_decoder_compatible(priv, dec))
			continue;
		if (*ir_type & dec->type) {
			*ir_type &= dec->type;
			img_ir_set_decoder(priv, dec, *ir_type);
			goto success;
		}
	}
	return -EINVAL;

success:
	/*
	 * Only allow matching wakeup protocols for now, and only if filtering
	 * is supported.
	 */
	wakeup_protocols = *ir_type;
	if (!hw->decoder || !hw->decoder->filter)
		wakeup_protocols = 0;
	rdev->allowed_wakeup_protocols = wakeup_protocols;
	rdev->enabled_wakeup_protocols = wakeup_protocols;
	return 0;
}

/* Changes ir-core protocol device attribute */
static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
{
	struct rc_dev *rdev = priv->hw.rdev;

	spin_lock_irq(&rdev->rc_map.lock);
	rdev->rc_map.rc_type = __ffs64(proto);
	spin_unlock_irq(&rdev->rc_map.lock);

	mutex_lock(&rdev->lock);
	rdev->enabled_protocols = proto;
	rdev->allowed_wakeup_protocols = proto;
	rdev->enabled_wakeup_protocols = proto;
	mutex_unlock(&rdev->lock);
}

/* Set up IR decoders */
static void img_ir_init_decoders(void)
{
	struct img_ir_decoder **decp;

	spin_lock(&img_ir_decoders_lock);
	if (!img_ir_decoders_preprocessed) {
		for (decp = img_ir_decoders; *decp; ++decp)
			img_ir_decoder_preprocess(*decp);
		img_ir_decoders_preprocessed = true;
	}
	spin_unlock(&img_ir_decoders_lock);
}

#ifdef CONFIG_PM_SLEEP
/**
 * img_ir_enable_wake() - Switch to wake mode.
 * @priv:	IR private data.
 *
 * Returns:	non-zero if the IR can wake the system.
 */
static int img_ir_enable_wake(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	int ret = 0;

	spin_lock_irq(&priv->lock);
	if (hw->flags & IMG_IR_F_WAKE) {
		/* interrupt only on a match */
		hw->suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
		img_ir_write(priv, IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_DATA_MATCH);
		img_ir_write_filter(priv, &hw->filters[RC_FILTER_WAKEUP]);
		img_ir_write_timings(priv, &hw->reg_timings.timings,
				     RC_FILTER_WAKEUP);
		hw->mode = IMG_IR_M_WAKE;
		ret = 1;
	}
	spin_unlock_irq(&priv->lock);
	return ret;
}

/**
 * img_ir_disable_wake() - Switch out of wake mode.
 * @priv:	IR private data
 *
 * Returns:	1 if the hardware should be allowed to wake from a sleep state.
 *		0 otherwise.
 */
static int img_ir_disable_wake(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	int ret = 0;

	spin_lock_irq(&priv->lock);
	if (hw->flags & IMG_IR_F_WAKE) {
		/* restore normal filtering */
		if (hw->flags & IMG_IR_F_FILTER) {
			img_ir_write(priv, IMG_IR_IRQ_ENABLE,
				     (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
				     IMG_IR_IRQ_DATA_MATCH);
			img_ir_write_filter(priv,
					    &hw->filters[RC_FILTER_NORMAL]);
		} else {
			img_ir_write(priv, IMG_IR_IRQ_ENABLE,
				     (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
				     IMG_IR_IRQ_DATA_VALID |
				     IMG_IR_IRQ_DATA2_VALID);
			img_ir_write_filter(priv, NULL);
		}
		img_ir_write_timings(priv, &hw->reg_timings.timings,
				     RC_FILTER_NORMAL);
		hw->mode = IMG_IR_M_NORMAL;
		ret = 1;
	}
	spin_unlock_irq(&priv->lock);
	return ret;
}
#endif /* CONFIG_PM_SLEEP */

/* lock must be held */
static void img_ir_begin_repeat(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	if (hw->mode == IMG_IR_M_NORMAL) {
		/* switch to repeat timings */
		img_ir_write(priv, IMG_IR_CONTROL, 0);
		hw->mode = IMG_IR_M_REPEATING;
		img_ir_write_timings(priv, &hw->reg_timings.rtimings,
				     RC_FILTER_NORMAL);
		img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
	}
}

/* lock must be held */
static void img_ir_end_repeat(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	if (hw->mode == IMG_IR_M_REPEATING) {
		/* switch to normal timings */
		img_ir_write(priv, IMG_IR_CONTROL, 0);
		hw->mode = IMG_IR_M_NORMAL;
		img_ir_write_timings(priv, &hw->reg_timings.timings,
				     RC_FILTER_NORMAL);
		img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
	}
}

/* lock must be held */
static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	const struct img_ir_decoder *dec = hw->decoder;
	int ret = IMG_IR_SCANCODE;
	u32 scancode;
	enum rc_type protocol = RC_TYPE_UNKNOWN;

	if (dec->scancode)
		ret = dec->scancode(len, raw, &protocol, &scancode, hw->enabled_protocols);
	else if (len >= 32)
		scancode = (u32)raw;
	else if (len < 32)
		scancode = (u32)raw & ((1 << len)-1);
	dev_dbg(priv->dev, "data (%u bits) = %#llx\n",
		len, (unsigned long long)raw);
	if (ret == IMG_IR_SCANCODE) {
		dev_dbg(priv->dev, "decoded scan code %#x\n", scancode);
		rc_keydown(hw->rdev, protocol, scancode, 0);
		img_ir_end_repeat(priv);
	} else if (ret == IMG_IR_REPEATCODE) {
		if (hw->mode == IMG_IR_M_REPEATING) {
			dev_dbg(priv->dev, "decoded repeat code\n");
			rc_repeat(hw->rdev);
		} else {
			dev_dbg(priv->dev, "decoded unexpected repeat code, ignoring\n");
		}
	} else {
		dev_dbg(priv->dev, "decode failed (%d)\n", ret);
		return;
	}


	if (dec->repeat) {
		unsigned long interval;

		img_ir_begin_repeat(priv);

		/* update timer, but allowing for 1/8th tolerance */
		interval = dec->repeat + (dec->repeat >> 3);
		mod_timer(&hw->end_timer,
			  jiffies + msecs_to_jiffies(interval));
	}
}

/* timer function to end waiting for repeat. */
static void img_ir_end_timer(unsigned long arg)
{
	struct img_ir_priv *priv = (struct img_ir_priv *)arg;

	spin_lock_irq(&priv->lock);
	img_ir_end_repeat(priv);
	spin_unlock_irq(&priv->lock);
}

#ifdef CONFIG_COMMON_CLK
static void img_ir_change_frequency(struct img_ir_priv *priv,
				    struct clk_notifier_data *change)
{
	struct img_ir_priv_hw *hw = &priv->hw;

	dev_dbg(priv->dev, "clk changed %lu HZ -> %lu HZ\n",
		change->old_rate, change->new_rate);

	spin_lock_irq(&priv->lock);
	if (hw->clk_hz == change->new_rate)
		goto unlock;
	hw->clk_hz = change->new_rate;
	/* refresh current timings */
	if (hw->decoder) {
		img_ir_decoder_convert(hw->decoder, &hw->reg_timings,
				       hw->clk_hz);
		switch (hw->mode) {
		case IMG_IR_M_NORMAL:
			img_ir_write_timings(priv, &hw->reg_timings.timings,
					     RC_FILTER_NORMAL);
			break;
		case IMG_IR_M_REPEATING:
			img_ir_write_timings(priv, &hw->reg_timings.rtimings,
					     RC_FILTER_NORMAL);
			break;
#ifdef CONFIG_PM_SLEEP
		case IMG_IR_M_WAKE:
			img_ir_write_timings(priv, &hw->reg_timings.timings,
					     RC_FILTER_WAKEUP);
			break;
#endif
		}
	}
unlock:
	spin_unlock_irq(&priv->lock);
}

static int img_ir_clk_notify(struct notifier_block *self, unsigned long action,
			     void *data)
{
	struct img_ir_priv *priv = container_of(self, struct img_ir_priv,
						hw.clk_nb);
	switch (action) {
	case POST_RATE_CHANGE:
		img_ir_change_frequency(priv, data);
		break;
	default:
		break;
	}
	return NOTIFY_OK;
}
#endif /* CONFIG_COMMON_CLK */

/* called with priv->lock held */
void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	u32 ir_status, len, lw, up;
	unsigned int ct;

	/* use the current decoder */
	if (!hw->decoder)
		return;

	ir_status = img_ir_read(priv, IMG_IR_STATUS);
	if (!(ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)))
		return;
	ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
	img_ir_write(priv, IMG_IR_STATUS, ir_status);

	len = (ir_status & IMG_IR_RXDLEN) >> IMG_IR_RXDLEN_SHIFT;
	/* some versions report wrong length for certain code types */
	ct = hw->decoder->control.code_type;
	if (hw->ct_quirks[ct] & IMG_IR_QUIRK_CODE_LEN_INCR)
		++len;

	lw = img_ir_read(priv, IMG_IR_DATA_LW);
	up = img_ir_read(priv, IMG_IR_DATA_UP);
	img_ir_handle_data(priv, len, (u64)up << 32 | lw);
}

void img_ir_setup_hw(struct img_ir_priv *priv)
{
	struct img_ir_decoder **decp;

	if (!priv->hw.rdev)
		return;

	/* Use the first available decoder (or disable stuff if NULL) */
	for (decp = img_ir_decoders; *decp; ++decp) {
		const struct img_ir_decoder *dec = *decp;
		if (img_ir_decoder_compatible(priv, dec)) {
			img_ir_set_protocol(priv, dec->type);
			img_ir_set_decoder(priv, dec, 0);
			return;
		}
	}
	img_ir_set_decoder(priv, NULL, 0);
}

/**
 * img_ir_probe_hw_caps() - Probe capabilities of the hardware.
 * @priv:	IR private data.
 */
static void img_ir_probe_hw_caps(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	/*
	 * When a version of the block becomes available without these quirks,
	 * they'll have to depend on the core revision.
	 */
	hw->ct_quirks[IMG_IR_CODETYPE_PULSELEN]
		|= IMG_IR_QUIRK_CODE_LEN_INCR;
	hw->ct_quirks[IMG_IR_CODETYPE_BIPHASE]
		|= IMG_IR_QUIRK_CODE_BROKEN;
	hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS]
		|= IMG_IR_QUIRK_CODE_BROKEN;
}

int img_ir_probe_hw(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	struct rc_dev *rdev;
	int error;

	/* Ensure hardware decoders have been preprocessed */
	img_ir_init_decoders();

	/* Probe hardware capabilities */
	img_ir_probe_hw_caps(priv);

	/* Set up the end timer */
	setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv);

	/* Register a clock notifier */
	if (!IS_ERR(priv->clk)) {
		hw->clk_hz = clk_get_rate(priv->clk);
#ifdef CONFIG_COMMON_CLK
		hw->clk_nb.notifier_call = img_ir_clk_notify;
		error = clk_notifier_register(priv->clk, &hw->clk_nb);
		if (error)
			dev_warn(priv->dev,
				 "failed to register clock notifier\n");
#endif
	} else {
		hw->clk_hz = 32768;
	}

	/* Allocate hardware decoder */
	hw->rdev = rdev = rc_allocate_device();
	if (!rdev) {
		dev_err(priv->dev, "cannot allocate input device\n");
		error = -ENOMEM;
		goto err_alloc_rc;
	}
	rdev->priv = priv;
	rdev->map_name = RC_MAP_EMPTY;
	rdev->allowed_protocols = img_ir_allowed_protos(priv);
	rdev->input_name = "IMG Infrared Decoder";
	rdev->s_filter = img_ir_set_normal_filter;
	rdev->s_wakeup_filter = img_ir_set_wakeup_filter;

	/* Register hardware decoder */
	error = rc_register_device(rdev);
	if (error) {
		dev_err(priv->dev, "failed to register IR input device\n");
		goto err_register_rc;
	}

	/*
	 * Set this after rc_register_device as no protocols have been
	 * registered yet.
	 */
	rdev->change_protocol = img_ir_change_protocol;

	device_init_wakeup(priv->dev, 1);

	return 0;

err_register_rc:
	img_ir_set_decoder(priv, NULL, 0);
	hw->rdev = NULL;
	rc_free_device(rdev);
err_alloc_rc:
#ifdef CONFIG_COMMON_CLK
	if (!IS_ERR(priv->clk))
		clk_notifier_unregister(priv->clk, &hw->clk_nb);
#endif
	return error;
}

void img_ir_remove_hw(struct img_ir_priv *priv)
{
	struct img_ir_priv_hw *hw = &priv->hw;
	struct rc_dev *rdev = hw->rdev;
	if (!rdev)
		return;
	img_ir_set_decoder(priv, NULL, 0);
	hw->rdev = NULL;
	rc_unregister_device(rdev);
#ifdef CONFIG_COMMON_CLK
	if (!IS_ERR(priv->clk))
		clk_notifier_unregister(priv->clk, &hw->clk_nb);
#endif
}

#ifdef CONFIG_PM_SLEEP
int img_ir_suspend(struct device *dev)
{
	struct img_ir_priv *priv = dev_get_drvdata(dev);

	if (device_may_wakeup(dev) && img_ir_enable_wake(priv))
		enable_irq_wake(priv->irq);
	return 0;
}

int img_ir_resume(struct device *dev)
{
	struct img_ir_priv *priv = dev_get_drvdata(dev);

	if (device_may_wakeup(dev) && img_ir_disable_wake(priv))
		disable_irq_wake(priv->irq);
	return 0;
}
#endif	/* CONFIG_PM_SLEEP */
