Commit 8cc8ccba authored by Otto Pflüger's avatar Otto Pflüger Committed by Noralf Trønnes

drm/mipi-dbi: Lock SPI bus before setting D/C GPIO

Multiple displays may be connected to the same bus and share a D/C GPIO,
so the display driver needs exclusive access to the bus to ensure that
it can control the D/C GPIO safely.
Signed-off-by: default avatarOtto Pflüger <otto.pflueger@abscue.de>
Reviewed-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Acked-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230724065654.5269-2-otto.pflueger@abscue.de
parent 8e4bb53c
...@@ -1140,10 +1140,13 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd, ...@@ -1140,10 +1140,13 @@ static int mipi_dbi_typec3_command_read(struct mipi_dbi *dbi, u8 *cmd,
return -ENOMEM; return -ENOMEM;
tr[1].rx_buf = buf; tr[1].rx_buf = buf;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 0); gpiod_set_value_cansleep(dbi->dc, 0);
spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr)); spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr));
ret = spi_sync(spi, &m); ret = spi_sync_locked(spi, &m);
spi_bus_unlock(spi->controller);
if (ret) if (ret)
goto err_free; goto err_free;
...@@ -1177,19 +1180,24 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd, ...@@ -1177,19 +1180,24 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd,
MIPI_DBI_DEBUG_COMMAND(*cmd, par, num); MIPI_DBI_DEBUG_COMMAND(*cmd, par, num);
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 0); gpiod_set_value_cansleep(dbi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1); ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
spi_bus_unlock(spi->controller);
if (ret || !num) if (ret || !num)
return ret; return ret;
if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes) if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes)
bpw = 16; bpw = 16;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 1); gpiod_set_value_cansleep(dbi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
spi_bus_unlock(spi->controller);
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); return ret;
} }
/** /**
...@@ -1271,7 +1279,8 @@ EXPORT_SYMBOL(mipi_dbi_spi_init); ...@@ -1271,7 +1279,8 @@ EXPORT_SYMBOL(mipi_dbi_spi_init);
* @len: Buffer length * @len: Buffer length
* *
* This SPI transfer helper breaks up the transfer of @buf into chunks which * This SPI transfer helper breaks up the transfer of @buf into chunks which
* the SPI controller driver can handle. * the SPI controller driver can handle. The SPI bus must be locked when
* calling this.
* *
* Returns: * Returns:
* Zero on success, negative error code on failure. * Zero on success, negative error code on failure.
...@@ -1305,7 +1314,7 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, ...@@ -1305,7 +1314,7 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
buf += chunk; buf += chunk;
len -= chunk; len -= chunk;
ret = spi_sync(spi, &m); ret = spi_sync_locked(spi, &m);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -316,19 +316,24 @@ static int ili9225_dbi_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par, ...@@ -316,19 +316,24 @@ static int ili9225_dbi_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par,
u32 speed_hz; u32 speed_hz;
int ret; int ret;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 0); gpiod_set_value_cansleep(dbi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1); ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
spi_bus_unlock(spi->controller);
if (ret || !num) if (ret || !num)
return ret; return ret;
if (*cmd == ILI9225_WRITE_DATA_TO_GRAM && !dbi->swap_bytes) if (*cmd == ILI9225_WRITE_DATA_TO_GRAM && !dbi->swap_bytes)
bpw = 16; bpw = 16;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 1); gpiod_set_value_cansleep(dbi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
spi_bus_unlock(spi->controller);
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num); return ret;
} }
static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = { static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = {
......
...@@ -59,9 +59,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par, ...@@ -59,9 +59,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
* before being transferred as 8-bit on the big endian SPI bus. * before being transferred as 8-bit on the big endian SPI bus.
*/ */
buf[0] = cpu_to_be16(*cmd); buf[0] = cpu_to_be16(*cmd);
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(mipi->dc, 0); gpiod_set_value_cansleep(mipi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 2); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 2);
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, buf, 2); ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, buf, 2);
spi_bus_unlock(spi->controller);
if (ret || !num) if (ret || !num)
goto free; goto free;
...@@ -79,9 +81,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par, ...@@ -79,9 +81,11 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes) if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
bpw = 16; bpw = 16;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(mipi->dc, 1); gpiod_set_value_cansleep(mipi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num); ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num);
spi_bus_unlock(spi->controller);
free: free:
kfree(buf); kfree(buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment