Skip to content

Commit c809c37

Browse files
rexutkartben
authored andcommitted
drivers: mipi_dbi_spi: splitting SPI write function
The more complex the SPI transfer algorithms become, the more confusing the current implementation of the SPI write 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 write 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 d0ba5a3 commit c809c37

File tree

1 file changed

+102
-59
lines changed

1 file changed

+102
-59
lines changed

drivers/mipi_dbi/mipi_dbi_spi.c

Lines changed: 102 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ uint32_t var = MIPI_DBI_SPI_READ_REQUIRED;
4646
*/
4747
#define MIPI_DBI_DC_BIT BIT(8)
4848

49-
static int mipi_dbi_spi_write_helper(const struct device *dev,
50-
const struct mipi_dbi_config *dbi_config,
51-
bool cmd_present, uint8_t cmd,
52-
const uint8_t *data_buf, size_t len)
49+
static inline int
50+
mipi_dbi_spi_write_helper_3wire(const struct device *dev,
51+
const struct mipi_dbi_config *dbi_config,
52+
bool cmd_present, uint8_t cmd,
53+
const uint8_t *data_buf, size_t len)
5354
{
5455
const struct mipi_dbi_spi_config *config = dev->config;
5556
struct mipi_dbi_spi_data *data = dev->data;
@@ -60,70 +61,112 @@ static int mipi_dbi_spi_write_helper(const struct device *dev,
6061
};
6162
int ret = 0;
6263

64+
/*
65+
* 9 bit word mode must be used, as the command/data bit
66+
* is stored before the data word.
67+
*/
68+
69+
if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK)
70+
!= SPI_WORD_SET(9)) {
71+
return -ENOTSUP;
72+
}
73+
buffer.buf = &data->spi_byte;
74+
buffer.len = 2;
75+
76+
/* Send command */
77+
if (cmd_present) {
78+
data->spi_byte = cmd;
79+
ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set);
80+
if (ret < 0) {
81+
goto out;
82+
}
83+
}
84+
/* Write data, byte by byte */
85+
for (size_t i = 0; i < len; i++) {
86+
data->spi_byte = MIPI_DBI_DC_BIT | data_buf[i];
87+
ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set);
88+
if (ret < 0) {
89+
goto out;
90+
}
91+
}
92+
out:
93+
return ret;
94+
}
95+
96+
static inline int
97+
mipi_dbi_spi_write_helper_4wire(const struct device *dev,
98+
const struct mipi_dbi_config *dbi_config,
99+
bool cmd_present, uint8_t cmd,
100+
const uint8_t *data_buf, size_t len)
101+
{
102+
const struct mipi_dbi_spi_config *config = dev->config;
103+
struct spi_buf buffer;
104+
struct spi_buf_set buf_set = {
105+
.buffers = &buffer,
106+
.count = 1,
107+
};
108+
int ret = 0;
109+
110+
/*
111+
* 4 wire mode is much simpler. We just toggle the
112+
* command/data GPIO to indicate if we are sending
113+
* a command or data
114+
*/
115+
116+
buffer.buf = &cmd;
117+
buffer.len = sizeof(cmd);
118+
119+
if (cmd_present) {
120+
/* Set CD pin low for command */
121+
gpio_pin_set_dt(&config->cmd_data, 0);
122+
ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set);
123+
if (ret < 0) {
124+
goto out;
125+
}
126+
}
127+
128+
if (len > 0) {
129+
buffer.buf = (void *)data_buf;
130+
buffer.len = len;
131+
132+
/* Set CD pin high for data */
133+
gpio_pin_set_dt(&config->cmd_data, 1);
134+
ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set);
135+
if (ret < 0) {
136+
goto out;
137+
}
138+
}
139+
out:
140+
return ret;
141+
}
142+
143+
static int mipi_dbi_spi_write_helper(const struct device *dev,
144+
const struct mipi_dbi_config *dbi_config,
145+
bool cmd_present, uint8_t cmd,
146+
const uint8_t *data_buf, size_t len)
147+
{
148+
struct mipi_dbi_spi_data *data = dev->data;
149+
int ret = 0;
150+
63151
ret = k_mutex_lock(&data->lock, K_FOREVER);
64152
if (ret < 0) {
65153
return ret;
66154
}
67155

68156
if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE &&
69157
IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) {
70-
/* 9 bit word mode must be used, as the command/data bit
71-
* is stored before the data word.
72-
*/
73-
if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK)
74-
!= SPI_WORD_SET(9)) {
75-
return -ENOTSUP;
76-
}
77-
buffer.buf = &data->spi_byte;
78-
buffer.len = 2;
79-
80-
/* Send command */
81-
if (cmd_present) {
82-
data->spi_byte = cmd;
83-
ret = spi_write(config->spi_dev, &dbi_config->config,
84-
&buf_set);
85-
if (ret < 0) {
86-
goto out;
87-
}
88-
}
89-
/* Write data, byte by byte */
90-
for (size_t i = 0; i < len; i++) {
91-
data->spi_byte = MIPI_DBI_DC_BIT | data_buf[i];
92-
ret = spi_write(config->spi_dev, &dbi_config->config,
93-
&buf_set);
94-
if (ret < 0) {
95-
goto out;
96-
}
158+
ret = mipi_dbi_spi_write_helper_3wire(dev, dbi_config,
159+
cmd_present, cmd,
160+
data_buf, len);
161+
if (ret < 0) {
162+
goto out;
97163
}
98164
} else if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) {
99-
/* 4 wire mode is much simpler. We just toggle the
100-
* command/data GPIO to indicate if we are sending
101-
* a command or data
102-
*/
103-
buffer.buf = &cmd;
104-
buffer.len = sizeof(cmd);
105-
106-
if (cmd_present) {
107-
/* Set CD pin low for command */
108-
gpio_pin_set_dt(&config->cmd_data, 0);
109-
ret = spi_write(config->spi_dev, &dbi_config->config,
110-
&buf_set);
111-
if (ret < 0) {
112-
goto out;
113-
}
114-
}
115-
116-
if (len > 0) {
117-
buffer.buf = (void *)data_buf;
118-
buffer.len = len;
119-
120-
/* Set CD pin high for data */
121-
gpio_pin_set_dt(&config->cmd_data, 1);
122-
ret = spi_write(config->spi_dev, &dbi_config->config,
123-
&buf_set);
124-
if (ret < 0) {
125-
goto out;
126-
}
165+
ret = mipi_dbi_spi_write_helper_4wire(dev, dbi_config,
166+
cmd_present, cmd,
167+
data_buf, len);
168+
if (ret < 0) {
169+
goto out;
127170
}
128171
} else {
129172
/* Otherwise, unsupported mode */

0 commit comments

Comments
 (0)