Commit 5ad05eca authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab
Browse files

media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC



Calling udelay for than 1000us does not always yield the correct
results.

Cc: stable@vger.kernel.org
Reported-by: default avatarМихаил <vrserver1@gmail.com>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 10923471
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -48,11 +48,29 @@ static int gpio_ir_tx_set_carrier(struct rc_dev *dev, u32 carrier)
	return 0;
}

static void delay_until(ktime_t until)
{
	/*
	 * delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on
	 * m68k ndelay(s64) does not compile; so use s32 rather than s64.
	 */
	s32 delta;

	while (true) {
		delta = ktime_us_delta(until, ktime_get());
		if (delta <= 0)
			return;

		/* udelay more than 1ms may not work */
		delta = min(delta, 1000);
		udelay(delta);
	}
}

static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf,
				   uint count)
{
	ktime_t edge;
	s32 delta;
	int i;

	local_irq_disable();
@@ -63,9 +81,7 @@ static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf,
		gpiod_set_value(gpio_ir->gpio, !(i % 2));

		edge = ktime_add_us(edge, txbuf[i]);
		delta = ktime_us_delta(edge, ktime_get());
		if (delta > 0)
			udelay(delta);
		delay_until(edge);
	}

	gpiod_set_value(gpio_ir->gpio, 0);
@@ -97,9 +113,7 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
		if (i % 2) {
			// space
			edge = ktime_add_us(edge, txbuf[i]);
			delta = ktime_us_delta(edge, ktime_get());
			if (delta > 0)
				udelay(delta);
			delay_until(edge);
		} else {
			// pulse
			ktime_t last = ktime_add_us(edge, txbuf[i]);