diff --git a/drm_iface.c b/drm_iface.c index fc22f7b..138c20c 100644 --- a/drm_iface.c +++ b/drm_iface.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include @@ -35,10 +35,6 @@ #include "indicators.h" -#define GPIO_DISP 22 -#define GPIO_SCS 8 -#define GPIO_VCOM 23 - #define CMD_WRITE_LINE 0b10000000 #define CMD_CLEAR_SCREEN 0b00100000 @@ -61,6 +57,9 @@ struct sharp_memory_panel { unsigned char *trailer_buf; char indicators[MAX_INDICATORS]; + + struct gpio_desc *gpio_disp; + struct gpio_desc *gpio_vcom; }; static struct sharp_memory_panel* g_panel = NULL; @@ -78,7 +77,7 @@ static void vcom_timer_callback(struct timer_list *t) // Toggle the GPIO pin vcom_setting = (vcom_setting) ? 0 : 1; - gpio_set_value(GPIO_VCOM, vcom_setting); + gpiod_set_value(panel->gpio_vcom, 1); // Reschedule the timer mod_timer(&panel->vcom_timer, jiffies + msecs_to_jiffies(1000)); @@ -98,9 +97,8 @@ static int sharp_memory_spi_clear_screen(struct sharp_memory_panel *panel) // Write clear screen command ndelay(80); - gpio_set_value(GPIO_SCS, 1); + rc = spi_sync_transfer(panel->spi, panel->spi_3_xfers, 2); - gpio_set_value(GPIO_SCS, 0); return rc; } @@ -133,9 +131,8 @@ static int sharp_memory_spi_write_tagged_lines(struct sharp_memory_panel *panel, panel->spi_3_xfers[2].len = 1; ndelay(80); - gpio_set_value(GPIO_SCS, 1); + rc = spi_sync_transfer(panel->spi, panel->spi_3_xfers, 3); - gpio_set_value(GPIO_SCS, 0); return rc; } @@ -331,9 +328,8 @@ static void power_off(struct sharp_memory_panel *panel) printk(KERN_INFO "sharp_memory: powering off\n"); /* Turn off power and all signals */ - gpio_set_value(GPIO_SCS, 0); - gpio_set_value(GPIO_DISP, 0); - gpio_set_value(GPIO_VCOM, 0); + gpiod_set_value(panel->gpio_disp, 0); + gpiod_set_value(panel->gpio_vcom, 0); } static void sharp_memory_pipe_enable(struct drm_simple_display_pipe *pipe, @@ -355,14 +351,13 @@ static void sharp_memory_pipe_enable(struct drm_simple_display_pipe *pipe, } // Power up sequence - gpio_set_value(GPIO_SCS, 0); - gpio_set_value(GPIO_DISP, 1); - gpio_set_value(GPIO_VCOM, 0); + gpiod_set_value(panel->gpio_disp, 1); + gpiod_set_value(panel->gpio_vcom, 0); usleep_range(5000, 10000); // Clear display if (sharp_memory_spi_clear_screen(panel)) { - gpio_set_value(GPIO_DISP, 0); // Power down display, VCOM is not running + gpiod_set_value(panel->gpio_disp, 0); // Power down display, VCOM is not running goto out_exit; } @@ -508,6 +503,15 @@ int drm_probe(struct spi_device *spi) } g_panel = panel; + // Initialize GPIO + panel->gpio_disp = devm_gpiod_get(dev, "disp", GPIOD_OUT_HIGH); + if (IS_ERR(panel->gpio_disp)) + return dev_err_probe(dev, PTR_ERR(panel->gpio_disp), "Failed to get GPIO 'disp'\n"); + + panel->gpio_vcom = devm_gpiod_get(dev, "vcom", GPIOD_OUT_LOW); + if (IS_ERR(panel->gpio_vcom)) + return dev_err_probe(dev, PTR_ERR(panel->gpio_vcom), "Failed to get GPIO 'vcom'\n"); + // Initalize DRM mode drm = &panel->drm; ret = drmm_mode_config_init(drm); @@ -577,6 +581,8 @@ int drm_probe(struct spi_device *spi) void drm_remove(struct spi_device *spi) { struct drm_device *drm; + struct device *dev; + struct sharp_memory_panel *panel; printk(KERN_INFO "sharp_memory: drm_remove\n"); @@ -586,6 +592,14 @@ void drm_remove(struct spi_device *spi) // Get DRM and panel device from SPI drm = spi_get_drvdata(spi); + // Clean up the GPIO descriptors + dev = &spi->dev; + panel = drm_to_panel(drm); + + devm_gpiod_put(dev, panel->gpio_disp); + devm_gpiod_put(dev, panel->gpio_vcom); + + drm_dev_unplug(drm); drm_atomic_helper_shutdown(drm); } diff --git a/drm_iface.h b/drm_iface.h index 8e79b06..eb83305 100644 --- a/drm_iface.h +++ b/drm_iface.h @@ -2,7 +2,7 @@ #define DRM_IFACE_H_ #include -#include +#include #include #include #include diff --git a/sharp.dts b/sharp.dts index 10d8327..2e16032 100644 --- a/sharp.dts +++ b/sharp.dts @@ -48,6 +48,10 @@ reg = <0>; pinctrl-names = "default"; pinctrl-0 = <&sharp_pins>; + + vcom-gpios = <&gpio 23 0>; + disp-gpios = <&gpio 22 0>; + spi-cs-high = <1>; spi-max-frequency = <8000000>; buswidth = <8>;