Skip to content

Commit

Permalink
[media] ir-spi: Fix issues with lirc API
Browse files Browse the repository at this point in the history
The ir-spi driver has 2 issues which prevents it from working with
lirc:

1. The ir-spi driver uses 16 bits of SPI data to create one cycle of
the waveform. As such our SPI clock needs to be 16x faster than the
carrier frequency.

The driver is inconsistent in how it currently handles this. It
initializes it to the carrier frequency:

But the commit message has some example code which initialises it
to 16x the carrier frequency:

	val = 608000;
	ret = ioctl(fd, LIRC_SET_SEND_CARRIER, &val);

To maintain compatibility with lirc, always do the frequency adjustment
in the driver.

2. lirc presents pulses in microseconds, but the ir-spi driver treats
them as cycles of the carrier. Similar to other lirc drivers, do the
conversion with DIV_ROUND_CLOSEST().

Fixes: fe052da ("[media] rc: add support for IR LEDs driven through SPI")

Cc: stable@vger.kernel.org
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
  • Loading branch information
Anton Blanchard authored and Mauro Carvalho Chehab committed Jun 7, 2017
1 parent fb3562c commit cc20ba4
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/media/rc/ir-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,13 @@ static int ir_spi_tx(struct rc_dev *dev,

/* convert the pulse/space signal to raw binary signal */
for (i = 0; i < count; i++) {
unsigned int periods;
int j;
u16 val;

if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE)
periods = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000);

if (len + periods >= IR_SPI_MAX_BUFSIZE)
return -EINVAL;

/*
Expand All @@ -69,13 +72,13 @@ static int ir_spi_tx(struct rc_dev *dev,
* contain a space duration.
*/
val = (i % 2) ? idata->space : idata->pulse;
for (j = 0; j < buffer[i]; j++)
for (j = 0; j < periods; j++)
idata->tx_buf[len++] = val;
}

memset(&xfer, 0, sizeof(xfer));

xfer.speed_hz = idata->freq;
xfer.speed_hz = idata->freq * 16;
xfer.len = len * sizeof(*idata->tx_buf);
xfer.tx_buf = idata->tx_buf;

Expand Down

0 comments on commit cc20ba4

Please sign in to comment.