On Fri Jun 13 14:21:51 2025 +0300, Cosmin Tanislav wrote: > Replace the static transmit buffer with a dynamically allocated one, > removing the limit imposed on the number of pulses to transmit. > > Calculate the number of pulses for each duration in the received buffer > ahead of time, while also adding up the total pulses, to be able to > allocate a buffer that perfectly fits the total number of pulses, then > populate it. > > Signed-off-by: Cosmin Tanislav <demonsin...@gmail.com> > Signed-off-by: Sean Young <s...@mess.org> > Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>
Patch committed. Thanks, Hans Verkuil drivers/media/rc/ir-spi.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) --- diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 8fc8e496e6aa..50e30e2fae22 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -21,13 +21,11 @@ #define IR_SPI_DRIVER_NAME "ir-spi" #define IR_SPI_DEFAULT_FREQUENCY 38000 -#define IR_SPI_MAX_BUFSIZE 4096 struct ir_spi_data { u32 freq; bool negated; - u16 tx_buf[IR_SPI_MAX_BUFSIZE]; u16 pulse; u16 space; @@ -43,17 +41,22 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun unsigned int len = 0; struct ir_spi_data *idata = dev->priv; struct spi_transfer xfer; + u16 *tx_buf; /* convert the pulse/space signal to raw binary signal */ for (i = 0; i < count; i++) { - unsigned int periods; - int j; - u16 val; + buffer[i] = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000); + len += buffer[i]; + } - periods = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000); + tx_buf = kmalloc_array(len, sizeof(*tx_buf), GFP_KERNEL); + if (!tx_buf) + return -ENOMEM; - if (len + periods >= IR_SPI_MAX_BUFSIZE) - return -EINVAL; + len = 0; + for (i = 0; i < count; i++) { + int j; + u16 val; /* * The first value in buffer is a pulse, so that 0, 2, 4, ... @@ -61,19 +64,19 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun * contain a space duration. */ val = (i % 2) ? idata->space : idata->pulse; - for (j = 0; j < periods; j++) - idata->tx_buf[len++] = val; + for (j = 0; j < buffer[i]; j++) + tx_buf[len++] = val; } memset(&xfer, 0, sizeof(xfer)); xfer.speed_hz = idata->freq * 16; - xfer.len = len * sizeof(*idata->tx_buf); - xfer.tx_buf = idata->tx_buf; + xfer.len = len * sizeof(*tx_buf); + xfer.tx_buf = tx_buf; ret = regulator_enable(idata->regulator); if (ret) - return ret; + goto err_free_tx_buf; ret = spi_sync_transfer(idata->spi, &xfer, 1); if (ret) @@ -81,6 +84,10 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun regulator_disable(idata->regulator); +err_free_tx_buf: + + kfree(tx_buf); + return ret ? ret : count; }