This switches the fbtft-core to use GPIO descriptors
rather than numerical gpios: Utilize the GPIO library's
intrinsic handling of OF GPIOs and polarity.
If the line is flagged active low, gpiolib will deal with
this.

Signed-off-by: Nishad Kamdar <nishadkam...@gmail.com>
---
 drivers/staging/fbtft/fbtft-core.c | 127 ++++++++++++-----------------
 drivers/staging/fbtft/fbtft.h      |  22 ++---
 2 files changed, 61 insertions(+), 88 deletions(-)

diff --git a/drivers/staging/fbtft/fbtft-core.c 
b/drivers/staging/fbtft/fbtft-core.c
index a2df02d97a8e..75ee16074126 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -16,7 +16,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
@@ -24,7 +24,6 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 #include <video/mipi_display.h>
 
 #include "fbtft.h"
@@ -38,8 +37,8 @@ int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, 
size_t len, int dc)
 {
        int ret;
 
-       if (gpio_is_valid(par->gpio.dc))
-               gpio_set_value(par->gpio.dc, dc);
+       if (par->gpio.dc)
+               gpiod_set_value(par->gpio.dc, dc);
 
        ret = par->fbtftops.write(par, buf, len);
        if (ret < 0)
@@ -72,7 +71,7 @@ void fbtft_dbg_hex(const struct device *dev, int groupsize,
 EXPORT_SYMBOL(fbtft_dbg_hex);
 
 static unsigned long fbtft_request_gpios_match(struct fbtft_par *par,
-                                              const struct fbtft_gpio *gpio)
+                                              struct fbtft_gpio *gpio)
 {
        int ret;
        unsigned int val;
@@ -82,34 +81,34 @@ static unsigned long fbtft_request_gpios_match(struct 
fbtft_par *par,
 
        if (strcasecmp(gpio->name, "reset") == 0) {
                par->gpio.reset = gpio->gpio;
-               return GPIOF_OUT_INIT_HIGH;
+               return GPIOD_OUT_HIGH;
        } else if (strcasecmp(gpio->name, "dc") == 0) {
                par->gpio.dc = gpio->gpio;
-               return GPIOF_OUT_INIT_LOW;
+               return GPIOD_OUT_LOW;
        } else if (strcasecmp(gpio->name, "cs") == 0) {
                par->gpio.cs = gpio->gpio;
-               return GPIOF_OUT_INIT_HIGH;
+               return GPIOD_OUT_HIGH;
        } else if (strcasecmp(gpio->name, "wr") == 0) {
                par->gpio.wr = gpio->gpio;
-               return GPIOF_OUT_INIT_HIGH;
+               return GPIOD_OUT_HIGH;
        } else if (strcasecmp(gpio->name, "rd") == 0) {
                par->gpio.rd = gpio->gpio;
-               return GPIOF_OUT_INIT_HIGH;
+               return GPIOD_OUT_HIGH;
        } else if (strcasecmp(gpio->name, "latch") == 0) {
                par->gpio.latch = gpio->gpio;
-               return GPIOF_OUT_INIT_LOW;
+               return GPIOD_OUT_LOW;
        } else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') {
                ret = kstrtouint(&gpio->name[2], 10, &val);
                if (ret == 0 && val < 16) {
                        par->gpio.db[val] = gpio->gpio;
-                       return GPIOF_OUT_INIT_LOW;
+                       return GPIOD_OUT_LOW;
                }
        } else if (strcasecmp(gpio->name, "led") == 0) {
                par->gpio.led[0] = gpio->gpio;
-               return GPIOF_OUT_INIT_LOW;
+               return GPIOD_OUT_LOW;
        } else if (strcasecmp(gpio->name, "led_") == 0) {
                par->gpio.led[0] = gpio->gpio;
-               return GPIOF_OUT_INIT_HIGH;
+               return GPIOD_OUT_HIGH;
        }
 
        return FBTFT_GPIO_NO_MATCH;
@@ -118,7 +117,8 @@ static unsigned long fbtft_request_gpios_match(struct 
fbtft_par *par,
 static int fbtft_request_gpios(struct fbtft_par *par)
 {
        struct fbtft_platform_data *pdata = par->pdata;
-       const struct fbtft_gpio *gpio;
+       struct device *dev = par->info->device;
+       struct fbtft_gpio *gpio;
        unsigned long flags;
        int ret;
 
@@ -136,19 +136,19 @@ static int fbtft_request_gpios(struct fbtft_par *par)
                if (flags == FBTFT_GPIO_NO_MATCH)
                        flags = fbtft_request_gpios_match(par, gpio);
                if (flags != FBTFT_GPIO_NO_MATCH) {
-                       ret = devm_gpio_request_one(par->info->device,
-                                             gpio->gpio, flags,
-                                             par->info->device->driver->name);
-                       if (ret < 0) {
-                               dev_err(par->info->device,
-                                       "%s: gpio_request_one('%s'=%d) failed 
with %d\n",
-                                       __func__, gpio->name,
-                                       gpio->gpio, ret);
+                       gpio->gpio = devm_gpiod_get(dev,
+                                                   dev->driver->name, flags);
+                       if (IS_ERR(gpio->gpio)) {
+                               ret = PTR_ERR(gpio->gpio);
+                               dev_err(dev,
+                                       "%s: Failed to request %s GPIO:%d\n",
+                                       __func__, gpio->name, ret);
                                return ret;
+
                        }
                        fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par,
-                                     "%s: '%s' = GPIO%d\n",
-                                     __func__, gpio->name, gpio->gpio);
+                                     "%s: '%s' GPIO\n",
+                                     __func__, gpio->name);
                }
                gpio++;
        }
@@ -158,7 +158,8 @@ static int fbtft_request_gpios(struct fbtft_par *par)
 
 #ifdef CONFIG_OF
 static int fbtft_request_one_gpio(struct fbtft_par *par,
-                                 const char *name, int index, int *gpiop)
+                                 const char *name, int index,
+                                 struct gpio_desc **gpiop)
 {
        struct device *dev = par->info->device;
        struct device_node *node = dev->of_node;
@@ -166,32 +167,17 @@ static int fbtft_request_one_gpio(struct fbtft_par *par,
        enum of_gpio_flags of_flags;
 
        if (of_find_property(node, name, NULL)) {
-               gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
-               if (gpio == -ENOENT)
-                       return 0;
-               if (gpio == -EPROBE_DEFER)
-                       return gpio;
-               if (gpio < 0) {
-                       dev_err(dev,
-                               "failed to get '%s' from DT\n", name);
-                       return gpio;
-               }
-
-               /* active low translates to initially low */
-               flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
-                                                       GPIOF_OUT_INIT_HIGH;
-               ret = devm_gpio_request_one(dev, gpio, flags,
-                                           dev->driver->name);
-               if (ret) {
+               *gpiop = devm_gpiod_get_index(dev, dev->driver->name, index,
+                                             GPIOD_OUT_HIGH);
+               if (IS_ERR(*gpiop)) {
+                       ret = PTR_ERR(*gpiop);
                        dev_err(dev,
-                               "gpio_request_one('%s'=%d) failed with %d\n",
-                               name, gpio, ret);
+                               "Failed to request %s GPIO:%d\n", name, ret);
                        return ret;
+
                }
-               if (gpiop)
-                       *gpiop = gpio;
-               fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
-                             __func__, name, gpio);
+               fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n",
+                             __func__, name);
        }
 
        return ret;
@@ -254,9 +240,9 @@ static int fbtft_backlight_update_status(struct 
backlight_device *bd)
 
        if ((bd->props.power == FB_BLANK_UNBLANK) &&
            (bd->props.fb_blank == FB_BLANK_UNBLANK))
-               gpio_set_value(par->gpio.led[0], polarity);
+               gpiod_set_value(par->gpio.led[0], polarity);
        else
-               gpio_set_value(par->gpio.led[0], !polarity);
+               gpiod_set_value(par->gpio.led[0], !polarity);
 
        return 0;
 }
@@ -286,7 +272,7 @@ void fbtft_register_backlight(struct fbtft_par *par)
        struct backlight_device *bd;
        struct backlight_properties bl_props = { 0, };
 
-       if (par->gpio.led[0] == -1) {
+       if (!par->gpio.led[0]) {
                fbtft_par_dbg(DEBUG_BACKLIGHT, par,
                              "%s(): led pin not set, exiting.\n", __func__);
                return;
@@ -295,7 +281,7 @@ void fbtft_register_backlight(struct fbtft_par *par)
        bl_props.type = BACKLIGHT_RAW;
        /* Assume backlight is off, get polarity from current state of pin */
        bl_props.power = FB_BLANK_POWERDOWN;
-       if (!gpio_get_value(par->gpio.led[0]))
+       if (!gpiod_get_value(par->gpio.led[0]))
                par->polarity = true;
 
        bd = backlight_device_register(dev_driver_string(par->info->device),
@@ -333,12 +319,12 @@ static void fbtft_set_addr_win(struct fbtft_par *par, int 
xs, int ys, int xe,
 
 static void fbtft_reset(struct fbtft_par *par)
 {
-       if (par->gpio.reset == -1)
+       if (!par->gpio.reset)
                return;
        fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
-       gpio_set_value_cansleep(par->gpio.reset, 0);
+       gpiod_set_value_cansleep(par->gpio.reset, 0);
        usleep_range(20, 40);
-       gpio_set_value_cansleep(par->gpio.reset, 1);
+       gpiod_set_value_cansleep(par->gpio.reset, 1);
        msleep(120);
 }
 
@@ -663,7 +649,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct 
fbtft_display *display,
        int txbuflen = display->txbuflen;
        unsigned int bpp = display->bpp;
        unsigned int fps = display->fps;
-       int vmem_size, i;
+       int vmem_size;
        const s16 *init_sequence = display->init_sequence;
        char *gamma = display->gamma;
        u32 *gamma_curves = NULL;
@@ -841,19 +827,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct 
fbtft_display *display,
                par->txbuf.len = txbuflen;
        }
 
-       /* Initialize gpios to disabled */
-       par->gpio.reset = -1;
-       par->gpio.dc = -1;
-       par->gpio.rd = -1;
-       par->gpio.wr = -1;
-       par->gpio.cs = -1;
-       par->gpio.latch = -1;
-       for (i = 0; i < 16; i++) {
-               par->gpio.db[i] = -1;
-               par->gpio.led[i] = -1;
-               par->gpio.aux[i] = -1;
-       }
-
        /* default fbtft operations */
        par->fbtftops.write = fbtft_write_spi;
        par->fbtftops.read = fbtft_read_spi;
@@ -1035,8 +1008,8 @@ static int fbtft_init_display_dt(struct fbtft_par *par)
                return -EINVAL;
 
        par->fbtftops.reset(par);
-       if (par->gpio.cs != -1)
-               gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+       if (!par->gpio.cs)
+               gpiod_set_value(par->gpio.cs, 0);  /* Activate chip */
 
        while (p) {
                if (val & FBTFT_OF_INIT_CMD) {
@@ -1126,8 +1099,8 @@ int fbtft_init_display(struct fbtft_par *par)
        }
 
        par->fbtftops.reset(par);
-       if (par->gpio.cs != -1)
-               gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+       if (!par->gpio.cs)
+               gpiod_set_value(par->gpio.cs, 0);  /* Activate chip */
 
        i = 0;
        while (i < FBTFT_MAX_INIT_SEQUENCE) {
@@ -1227,7 +1200,7 @@ static int fbtft_verify_gpios(struct fbtft_par *par)
        fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
 
        if (pdata->display.buswidth != 9 &&  par->startbyte == 0 &&
-           par->gpio.dc < 0) {
+           !par->gpio.dc) {
                dev_err(par->info->device,
                        "Missing info about 'dc' gpio. Aborting.\n");
                return -EINVAL;
@@ -1236,12 +1209,12 @@ static int fbtft_verify_gpios(struct fbtft_par *par)
        if (!par->pdev)
                return 0;
 
-       if (par->gpio.wr < 0) {
+       if (!par->gpio.wr) {
                dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n");
                return -EINVAL;
        }
        for (i = 0; i < pdata->display.buswidth; i++) {
-               if (par->gpio.db[i] < 0) {
+               if (!par->gpio.db[i]) {
                        dev_err(par->info->device,
                                "Missing 'db%02d' gpio. Aborting.\n", i);
                        return -EINVAL;
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
index ac427baa464a..a9eed11c29b0 100644
--- a/drivers/staging/fbtft/fbtft.h
+++ b/drivers/staging/fbtft/fbtft.h
@@ -27,7 +27,7 @@
  */
 struct fbtft_gpio {
        char name[FBTFT_GPIO_NAME_SIZE];
-       unsigned int gpio;
+       struct gpio_desc *gpio;
 };
 
 struct fbtft_par;
@@ -134,7 +134,7 @@ struct fbtft_display {
  */
 struct fbtft_platform_data {
        struct fbtft_display display;
-       const struct fbtft_gpio *gpios;
+       struct fbtft_gpio *gpios;
        unsigned int rotate;
        bool bgr;
        unsigned int fps;
@@ -207,15 +207,15 @@ struct fbtft_par {
        unsigned int dirty_lines_start;
        unsigned int dirty_lines_end;
        struct {
-               int reset;
-               int dc;
-               int rd;
-               int wr;
-               int latch;
-               int cs;
-               int db[16];
-               int led[16];
-               int aux[16];
+               struct gpio_desc *reset;
+               struct gpio_desc *dc;
+               struct gpio_desc *rd;
+               struct gpio_desc *wr;
+               struct gpio_desc *latch;
+               struct gpio_desc *cs;
+               struct gpio_desc *db[16];
+               struct gpio_desc *led[16];
+               struct gpio_desc *aux[16];
        } gpio;
        const s16 *init_sequence;
        struct {
-- 
2.17.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to