[PATCH 01/26] Staging: fbtft: fbtft-core: Switch to the gpio descriptor interface

From: Nishad Kamdar
Date: Sun Nov 25 2018 - 06:23:36 EST


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 <nishadkamdar@xxxxxxxxx>
---
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