Lines Matching +full:gpio +full:- +full:n
2 * MIPI DBI Type A and B driver using GPIO
6 * SPDX-License-Identifier: Apache-2.0
12 #include <zephyr/drivers/gpio.h>
20 /* Compile in a data bus LUT for improved performance if at least one instance uses an 8-bit bus */
21 #define _8_BIT_MODE_PRESENT(n) (DT_INST_PROP_LEN(n, data_gpios) == 8) | argument
29 /* Read (type B) GPIO */
32 /* Write (type B) or Read/!Write (type A) GPIO */
35 /* Enable/strobe GPIO (type A) */
38 /* Chip-select GPIO */
41 /* Command/Data GPIO */
44 /* Reset GPIO */
48 /* Data GPIO remap look-up table. Valid if mipi_dbi_bitbang_data.single_port is set */
60 /* Indicates whether all data GPIO pins are on the same port and the data LUT is used. */
63 /* Data GPIO port device. Valid if mipi_dbi_bitbang_data.single_port is set */
73 if (data->single_port) { in mipi_dbi_bitbang_set_data_gpios()
74 gpio_port_set_masked(data->data_port, config->data_mask, config->data_lut[value]); in mipi_dbi_bitbang_set_data_gpios()
77 for (int i = 0; i < config->data_bus_width; i++) { in mipi_dbi_bitbang_set_data_gpios()
78 gpio_pin_set_dt(&config->data[i], (value & (1 << i)) != 0); in mipi_dbi_bitbang_set_data_gpios()
89 const struct mipi_dbi_bitbang_config *config = dev->config; in mipi_dbi_bitbang_write_helper()
90 struct mipi_dbi_bitbang_data *data = dev->data; in mipi_dbi_bitbang_write_helper()
94 ret = k_mutex_lock(&data->lock, K_FOREVER); in mipi_dbi_bitbang_write_helper()
99 switch (dbi_config->mode) { in mipi_dbi_bitbang_write_helper()
103 gpio_pin_set_dt(&config->cs, 1); in mipi_dbi_bitbang_write_helper()
105 gpio_pin_set_dt(&config->wr, 0); in mipi_dbi_bitbang_write_helper()
106 gpio_pin_set_dt(&config->cmd_data, 0); in mipi_dbi_bitbang_write_helper()
108 gpio_pin_set_dt(&config->wr, 1); in mipi_dbi_bitbang_write_helper()
111 gpio_pin_set_dt(&config->cmd_data, 1); in mipi_dbi_bitbang_write_helper()
114 gpio_pin_set_dt(&config->wr, 0); in mipi_dbi_bitbang_write_helper()
116 gpio_pin_set_dt(&config->wr, 1); in mipi_dbi_bitbang_write_helper()
117 len--; in mipi_dbi_bitbang_write_helper()
120 gpio_pin_set_dt(&config->cs, 0); in mipi_dbi_bitbang_write_helper()
127 gpio_pin_set_dt(&config->cs, 1); in mipi_dbi_bitbang_write_helper()
128 gpio_pin_set_dt(&config->wr, 0); in mipi_dbi_bitbang_write_helper()
130 gpio_pin_set_dt(&config->e, 1); in mipi_dbi_bitbang_write_helper()
131 gpio_pin_set_dt(&config->cmd_data, 0); in mipi_dbi_bitbang_write_helper()
133 gpio_pin_set_dt(&config->e, 0); in mipi_dbi_bitbang_write_helper()
136 gpio_pin_set_dt(&config->cmd_data, 1); in mipi_dbi_bitbang_write_helper()
139 gpio_pin_set_dt(&config->e, 1); in mipi_dbi_bitbang_write_helper()
141 gpio_pin_set_dt(&config->e, 0); in mipi_dbi_bitbang_write_helper()
142 len--; in mipi_dbi_bitbang_write_helper()
145 gpio_pin_set_dt(&config->cs, 0); in mipi_dbi_bitbang_write_helper()
149 LOG_ERR("MIPI DBI mode %u is not supported.", dbi_config->mode); in mipi_dbi_bitbang_write_helper()
150 ret = -ENOTSUP; in mipi_dbi_bitbang_write_helper()
153 k_mutex_unlock(&data->lock); in mipi_dbi_bitbang_write_helper()
172 return mipi_dbi_bitbang_write_helper(dev, dbi_config, false, 0x0, framebuf, desc->buf_size); in mipi_dbi_bitbang_write_display()
177 const struct mipi_dbi_bitbang_config *config = dev->config; in mipi_dbi_bitbang_reset()
182 ret = gpio_pin_set_dt(&config->reset, 1); in mipi_dbi_bitbang_reset()
187 return gpio_pin_set_dt(&config->reset, 0); in mipi_dbi_bitbang_reset()
192 const struct mipi_dbi_bitbang_config *config = dev->config; in mipi_dbi_bitbang_init()
196 struct mipi_dbi_bitbang_data *data = dev->data; in mipi_dbi_bitbang_init()
199 if (gpio_is_ready_dt(&config->cmd_data)) { in mipi_dbi_bitbang_init()
200 ret = gpio_pin_configure_dt(&config->cmd_data, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
205 gpio_pin_set_dt(&config->cmd_data, 0); in mipi_dbi_bitbang_init()
207 if (gpio_is_ready_dt(&config->rd)) { in mipi_dbi_bitbang_init()
208 gpio_pin_configure_dt(&config->rd, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
210 gpio_pin_set_dt(&config->rd, 1); in mipi_dbi_bitbang_init()
212 if (gpio_is_ready_dt(&config->wr)) { in mipi_dbi_bitbang_init()
213 ret = gpio_pin_configure_dt(&config->wr, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
218 gpio_pin_set_dt(&config->wr, 1); in mipi_dbi_bitbang_init()
220 if (gpio_is_ready_dt(&config->e)) { in mipi_dbi_bitbang_init()
221 gpio_pin_configure_dt(&config->e, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
223 gpio_pin_set_dt(&config->e, 0); in mipi_dbi_bitbang_init()
225 if (gpio_is_ready_dt(&config->cs)) { in mipi_dbi_bitbang_init()
226 ret = gpio_pin_configure_dt(&config->cs, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
231 gpio_pin_set_dt(&config->cs, 0); in mipi_dbi_bitbang_init()
233 if (gpio_is_ready_dt(&config->reset)) { in mipi_dbi_bitbang_init()
234 ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
239 gpio_pin_set_dt(&config->reset, 0); in mipi_dbi_bitbang_init()
241 for (int i = 0; i < config->data_bus_width; i++) { in mipi_dbi_bitbang_init()
242 if (gpio_is_ready_dt(&config->data[i])) { in mipi_dbi_bitbang_init()
243 ret = gpio_pin_configure_dt(&config->data[i], GPIO_OUTPUT_ACTIVE); in mipi_dbi_bitbang_init()
248 gpio_pin_set_dt(&config->data[i], 0); in mipi_dbi_bitbang_init()
256 * For 8-bit mode only because LUT size grows exponentially. in mipi_dbi_bitbang_init()
258 if (config->data_bus_width == 8) { in mipi_dbi_bitbang_init()
259 data->single_port = true; in mipi_dbi_bitbang_init()
260 data->data_port = config->data[0].port; in mipi_dbi_bitbang_init()
261 for (int i = 1; i < config->data_bus_width; i++) { in mipi_dbi_bitbang_init()
262 if (data->data_port != config->data[i].port) { in mipi_dbi_bitbang_init()
263 data->single_port = false; in mipi_dbi_bitbang_init()
267 if (data->single_port) { in mipi_dbi_bitbang_init()
268 LOG_DBG("LUT optimization enabled. data_mask=0x%x", config->data_mask); in mipi_dbi_bitbang_init()
274 LOG_ERR("Failed to configure %s GPIO pin.", failed_pin); in mipi_dbi_bitbang_init()
284 /* This macro is repeatedly called by LISTIFY() at compile-time to generate the data bus LUT */
285 #define LUT_GEN(i, n) (((i & (1 << 0)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 0)) : 0) | \ argument
286 ((i & (1 << 1)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 1)) : 0) | \
287 ((i & (1 << 2)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 2)) : 0) | \
288 ((i & (1 << 3)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 3)) : 0) | \
289 ((i & (1 << 4)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 4)) : 0) | \
290 ((i & (1 << 5)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 5)) : 0) | \
291 ((i & (1 << 6)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 6)) : 0) | \
292 ((i & (1 << 7)) ? (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 7)) : 0))
294 /* If at least one instance has an 8-bit bus, add a data look-up table to the read-only config.
299 #define DATA_LUT_OPTIMIZATION(n) \ argument
300 .data_lut = { LISTIFY(256, LUT_GEN, (,), n) }, \
301 .data_mask = ((1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 0)) | \
302 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 1)) | \
303 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 2)) | \
304 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 3)) | \
305 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 4)) | \
306 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 5)) | \
307 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 6)) | \
308 (1 << DT_INST_GPIO_PIN_BY_IDX(n, data_gpios, 7)))
310 #define DATA_LUT_OPTIMIZATION(n) argument
313 #define MIPI_DBI_BITBANG_INIT(n) \ argument
314 static const struct mipi_dbi_bitbang_config mipi_dbi_bitbang_config_##n = { \
315 .data = {GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 0, {0}), \
316 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 1, {0}), \
317 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 2, {0}), \
318 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 3, {0}), \
319 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 4, {0}), \
320 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 5, {0}), \
321 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 6, {0}), \
322 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 7, {0}), \
323 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 8, {0}), \
324 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 9, {0}), \
325 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 10, {0}), \
326 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 11, {0}), \
327 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 12, {0}), \
328 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 13, {0}), \
329 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 14, {0}), \
330 GPIO_DT_SPEC_INST_GET_BY_IDX_OR(n, data_gpios, 15, {0})}, \
331 .data_bus_width = DT_INST_PROP_LEN(n, data_gpios), \
332 .rd = GPIO_DT_SPEC_INST_GET_OR(n, rd_gpios, {}), \
333 .wr = GPIO_DT_SPEC_INST_GET_OR(n, wr_gpios, {}), \
334 .e = GPIO_DT_SPEC_INST_GET_OR(n, e_gpios, {}), \
335 .cs = GPIO_DT_SPEC_INST_GET_OR(n, cs_gpios, {}), \
336 .cmd_data = GPIO_DT_SPEC_INST_GET_OR(n, dc_gpios, {}), \
337 .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {}), \
338 DATA_LUT_OPTIMIZATION(n) \
340 BUILD_ASSERT(DT_INST_PROP_LEN(n, data_gpios) <= MIPI_DBI_MAX_DATA_BUS_WIDTH, \
342 static struct mipi_dbi_bitbang_data mipi_dbi_bitbang_data_##n; \
343 DEVICE_DT_INST_DEFINE(n, mipi_dbi_bitbang_init, NULL, &mipi_dbi_bitbang_data_##n, \
344 &mipi_dbi_bitbang_config_##n, POST_KERNEL, \