Skip to content

Commit d0ba5a3

Browse files
rexutkartben
authored andcommitted
drivers: mipi_dbi_spi: splitting SPI read function
The more complex the SPI transfer algorithms become, the more confusing the current implementation of the SPI command read function becomes. Furthermore, if further as yet unknown MIPI DBI modes are to be supported, the scope of this implementation would increase dramatically. With the splitting now introduced, the existing SPI transfer algorithms are moved to individual auxiliary functions and the SPI read function only focus on the decision of the respective MIPI DBI mode and the device lock/unlock. Signed-off-by: Stephan Linz <linz@li-pro.net>
1 parent 0c93541 commit d0ba5a3

File tree

1 file changed

+115
-56
lines changed

1 file changed

+115
-56
lines changed

drivers/mipi_dbi/mipi_dbi_spi.c

Lines changed: 115 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -157,89 +157,148 @@ static int mipi_dbi_spi_write_display(const struct device *dev,
157157

158158
#if MIPI_DBI_SPI_READ_REQUIRED
159159

160-
static int mipi_dbi_spi_command_read(const struct device *dev,
161-
const struct mipi_dbi_config *dbi_config,
162-
uint8_t *cmds, size_t num_cmds,
163-
uint8_t *response, size_t len)
160+
static inline int
161+
mipi_dbi_spi_read_helper_3wire(const struct device *dev,
162+
const struct mipi_dbi_config *dbi_config,
163+
uint8_t *cmds, size_t num_cmds,
164+
uint8_t *response, size_t len)
164165
{
165166
const struct mipi_dbi_spi_config *config = dev->config;
166167
struct mipi_dbi_spi_data *data = dev->data;
168+
struct spi_config tmp_config;
167169
struct spi_buf buffer;
168170
struct spi_buf_set buf_set = {
169171
.buffers = &buffer,
170172
.count = 1,
171173
};
172174
int ret = 0;
173-
struct spi_config tmp_config;
174175

175-
ret = k_mutex_lock(&data->lock, K_FOREVER);
176-
if (ret < 0) {
177-
return ret;
176+
/*
177+
* We have to emulate 3 wire mode by packing the data/command
178+
* bit into the upper bit of the SPI transfer, switch SPI to
179+
* 9 bit mode, and write the transfer.
180+
*/
181+
182+
if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK)
183+
!= SPI_WORD_SET(9)) {
184+
return -ENOTSUP;
178185
}
186+
179187
memcpy(&tmp_config, &dbi_config->config, sizeof(tmp_config));
180-
if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE &&
181-
IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) {
182-
/* We have to emulate 3 wire mode by packing the data/command
183-
* bit into the upper bit of the SPI transfer.
184-
* switch SPI to 9 bit mode, and write the transfer
185-
*/
186-
tmp_config.operation &= ~SPI_WORD_SIZE_MASK;
187-
tmp_config.operation |= SPI_WORD_SET(9);
188+
tmp_config.operation &= ~SPI_WORD_SIZE_MASK;
189+
tmp_config.operation |= SPI_WORD_SET(9);
188190

189-
buffer.buf = &data->spi_byte;
190-
buffer.len = 1;
191-
/* Send each command */
192-
for (size_t i = 0; i < num_cmds; i++) {
193-
data->spi_byte = cmds[i];
194-
ret = spi_write(config->spi_dev, &tmp_config, &buf_set);
195-
if (ret < 0) {
196-
goto out;
197-
}
191+
buffer.buf = &data->spi_byte;
192+
buffer.len = 1;
193+
194+
/* Send each command */
195+
for (size_t i = 0; i < num_cmds; i++) {
196+
data->spi_byte = cmds[i];
197+
ret = spi_write(config->spi_dev, &tmp_config, &buf_set);
198+
if (ret < 0) {
199+
goto out;
200+
}
201+
}
202+
203+
/* Now, we can switch to 8 bit mode, and read data */
204+
buffer.buf = (void *)response;
205+
buffer.len = len;
206+
ret = spi_read(config->spi_dev, &dbi_config->config, &buf_set);
207+
208+
out:
209+
spi_release(config->spi_dev, &tmp_config); /* Really necessary here? */
210+
return ret;
211+
}
212+
213+
static inline int
214+
mipi_dbi_spi_read_helper_4wire(const struct device *dev,
215+
const struct mipi_dbi_config *dbi_config,
216+
uint8_t *cmds, size_t num_cmds,
217+
uint8_t *response, size_t len)
218+
{
219+
const struct mipi_dbi_spi_config *config = dev->config;
220+
struct spi_config tmp_config;
221+
struct spi_buf buffer;
222+
struct spi_buf_set buf_set = {
223+
.buffers = &buffer,
224+
.count = 1,
225+
};
226+
int ret = 0;
227+
228+
/*
229+
* 4 wire mode is much simpler. We just toggle the
230+
* command/data GPIO to indicate if we are sending
231+
* a command or data. Note that since some SPI displays
232+
* require CS to be held low for the entire read sequence,
233+
* we set SPI_HOLD_ON_CS
234+
*/
235+
236+
memcpy(&tmp_config, &dbi_config->config, sizeof(tmp_config));
237+
tmp_config.operation |= SPI_HOLD_ON_CS;
238+
239+
if (num_cmds > 0) {
240+
buffer.buf = cmds;
241+
buffer.len = num_cmds;
242+
243+
/* Set CD pin low for command */
244+
gpio_pin_set_dt(&config->cmd_data, 0);
245+
246+
ret = spi_write(config->spi_dev, &tmp_config, &buf_set);
247+
if (ret < 0) {
248+
goto out;
198249
}
199-
/* Now, we can switch to 8 bit mode, and read data */
250+
}
251+
252+
if (len > 0) {
200253
buffer.buf = (void *)response;
201254
buffer.len = len;
202-
ret = spi_read(config->spi_dev, &dbi_config->config, &buf_set);
203-
} else if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) {
204-
/* 4 wire mode is much simpler. We just toggle the
205-
* command/data GPIO to indicate if we are sending
206-
* a command or data. Note that since some SPI displays
207-
* require CS to be held low for the entire read sequence,
208-
* we set SPI_HOLD_ON_CS
209-
*/
210-
tmp_config.operation |= SPI_HOLD_ON_CS;
211255

212-
if (num_cmds > 0) {
213-
buffer.buf = cmds;
214-
buffer.len = num_cmds;
215-
/* Set CD pin low for command */
216-
gpio_pin_set_dt(&config->cmd_data, 0);
256+
/* Set CD pin high for data */
257+
gpio_pin_set_dt(&config->cmd_data, 1);
217258

218-
ret = spi_write(config->spi_dev, &tmp_config,
219-
&buf_set);
220-
if (ret < 0) {
221-
goto out;
222-
}
259+
ret = spi_read(config->spi_dev, &tmp_config, &buf_set);
260+
if (ret < 0) {
261+
goto out;
223262
}
263+
}
224264

225-
if (len > 0) {
226-
/* Set CD pin high for data */
227-
gpio_pin_set_dt(&config->cmd_data, 1);
265+
out:
266+
spi_release(config->spi_dev, &tmp_config);
267+
return ret;
268+
}
228269

229-
buffer.buf = (void *)response;
230-
buffer.len = len;
231-
ret = spi_read(config->spi_dev, &tmp_config,
232-
&buf_set);
233-
if (ret < 0) {
234-
goto out;
235-
}
270+
static int mipi_dbi_spi_command_read(const struct device *dev,
271+
const struct mipi_dbi_config *dbi_config,
272+
uint8_t *cmds, size_t num_cmds,
273+
uint8_t *response, size_t len)
274+
{
275+
struct mipi_dbi_spi_data *data = dev->data;
276+
int ret = 0;
277+
278+
ret = k_mutex_lock(&data->lock, K_FOREVER);
279+
if (ret < 0) {
280+
return ret;
281+
}
282+
if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE &&
283+
IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) {
284+
ret = mipi_dbi_spi_read_helper_3wire(dev, dbi_config,
285+
cmds, num_cmds,
286+
response, len);
287+
if (ret < 0) {
288+
goto out;
289+
}
290+
} else if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) {
291+
ret = mipi_dbi_spi_read_helper_4wire(dev, dbi_config,
292+
cmds, num_cmds,
293+
response, len);
294+
if (ret < 0) {
295+
goto out;
236296
}
237297
} else {
238298
/* Otherwise, unsupported mode */
239299
ret = -ENOTSUP;
240300
}
241301
out:
242-
spi_release(config->spi_dev, &tmp_config);
243302
k_mutex_unlock(&data->lock);
244303
return ret;
245304
}

0 commit comments

Comments
 (0)