These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / fbtft / fbtft_device.c
index df6cd77..071f79b 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define pr_fmt(fmt) "fbtft_device: " fmt
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
+#include <video/mipi_display.h>
 
 #include "fbtft.h"
 
-#define DRVNAME "fbtft_device"
-
 #define MAX_GPIOS 32
 
 static struct spi_device *spi_device;
@@ -34,8 +30,7 @@ static struct platform_device *p_device;
 
 static char *name;
 module_param(name, charp, 0);
-MODULE_PARM_DESC(name, "Devicename (required). " \
-"name=list => list all supported devices.");
+MODULE_PARM_DESC(name, "Devicename (required). name=list => list all supported devices.");
 
 static unsigned rotate;
 module_param(rotate, uint, 0);
@@ -61,8 +56,7 @@ MODULE_PARM_DESC(mode, "SPI mode (override device default)");
 static char *gpios;
 module_param(gpios, charp, 0);
 MODULE_PARM_DESC(gpios,
-"List of gpios. Comma separated with the form: reset:23,dc:24 " \
-"(when overriding the default, all gpios must be specified)");
+"List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)");
 
 static unsigned fps;
 module_param(fps, uint, 0);
@@ -88,8 +82,7 @@ MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
 
 static bool custom;
 module_param(custom, bool, 0);
-MODULE_PARM_DESC(custom, "Add a custom display device. " \
-"Use speed= argument to make it a SPI device, else platform_device");
+MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device");
 
 static unsigned width;
 module_param(width, uint, 0);
@@ -118,7 +111,6 @@ module_param(verbose, uint, 0);
 MODULE_PARM_DESC(verbose,
 "0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
 
-
 struct fbtft_device_display {
        char *name;
        struct spi_board_info *spi;
@@ -135,6 +127,59 @@ static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
                "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
                "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
 
+#define CBERRY28_GAMMA \
+               "D0 00 14 15 13 2C 42 43 4E 09 16 14 18 21\n" \
+               "D0 00 14 15 13 0B 43 55 53 0C 17 14 23 20"
+
+static int cberry28_init_sequence[] = {
+       /* turn off sleep mode */
+       -1, MIPI_DCS_EXIT_SLEEP_MODE,
+       -2, 120,
+
+       /* set pixel format to RGB-565 */
+       -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
+
+       -1, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33,
+
+       /*
+        * VGH = 13.26V
+        * VGL = -10.43V
+        */
+       -1, 0xB7, 0x35,
+
+       /*
+        * VDV and VRH register values come from command write
+        * (instead of NVM)
+        */
+       -1, 0xC2, 0x01, 0xFF,
+
+       /*
+        * VAP =  4.7V + (VCOM + VCOM offset + 0.5 * VDV)
+        * VAN = -4.7V + (VCOM + VCOM offset + 0.5 * VDV)
+        */
+       -1, 0xC3, 0x17,
+
+       /* VDV = 0V */
+       -1, 0xC4, 0x20,
+
+       /* VCOM = 0.675V */
+       -1, 0xBB, 0x17,
+
+       /* VCOM offset = 0V */
+       -1, 0xC5, 0x20,
+
+       /*
+        * AVDD = 6.8V
+        * AVCL = -4.8V
+        * VDS = 2.3V
+        */
+       -1, 0xD0, 0xA4, 0xA1,
+
+       -1, MIPI_DCS_SET_DISPLAY_ON,
+
+       -3,
+};
+
 static int hy28b_init_sequence[] = {
        -1, 0x00e7, 0x0010, -1, 0x0000, 0x0001,
        -1, 0x0001, 0x0100, -1, 0x0002, 0x0700,
@@ -232,7 +277,7 @@ static struct fbtft_device_display displays[] = {
                                .display = {
                                        .buswidth = 8,
                                        .backlight = 1,
-                                       .fbtftops.set_addr_win = \
+                                       .fbtftops.set_addr_win =
                                            adafruit18_green_tab_set_addr_win,
                                },
                                .bgr = true,
@@ -321,6 +366,27 @@ static struct fbtft_device_display displays[] = {
                                },
                        }
                }
+       }, {
+               .name = "admatec_c-berry28",
+               .spi = &(struct spi_board_info) {
+                       .modalias = "fb_st7789v",
+                       .max_speed_hz = 48000000,
+                       .mode = SPI_MODE_0,
+                       .platform_data = &(struct fbtft_platform_data) {
+                               .display = {
+                                       .buswidth = 8,
+                                       .backlight = 1,
+                                       .init_sequence = cberry28_init_sequence,
+                               },
+                               .gpios = (const struct fbtft_gpio []) {
+                                       { "reset", 25 },
+                                       { "dc", 22 },
+                                       { "led", 18 },
+                                       {},
+                               },
+                               .gamma = CBERRY28_GAMMA,
+                       }
+               }
        }, {
                .name = "agm1264k-fl",
                .pdev = &(struct platform_device) {
@@ -399,6 +465,37 @@ static struct fbtft_device_display displays[] = {
                                },
                        }
                }
+       }, {
+               .name = "ew24ha0",
+               .spi = &(struct spi_board_info) {
+                       .modalias = "fb_uc1611",
+                       .max_speed_hz = 32000000,
+                       .mode = SPI_MODE_3,
+                       .platform_data = &(struct fbtft_platform_data) {
+                               .display = {
+                                       .buswidth = 8,
+                               },
+                               .gpios = (const struct fbtft_gpio []) {
+                                       { "dc", 24 },
+                                       {},
+                               },
+                       }
+               }
+       }, {
+               .name = "ew24ha0_9bit",
+               .spi = &(struct spi_board_info) {
+                       .modalias = "fb_uc1611",
+                       .max_speed_hz = 32000000,
+                       .mode = SPI_MODE_3,
+                       .platform_data = &(struct fbtft_platform_data) {
+                               .display = {
+                                       .buswidth = 9,
+                               },
+                               .gpios = (const struct fbtft_gpio []) {
+                                       {},
+                               },
+                       }
+               }
        }, {
                .name = "flexfb",
                .spi = &(struct spi_board_info) {
@@ -558,8 +655,8 @@ static struct fbtft_device_display displays[] = {
                                .gpios = (const struct fbtft_gpio []) {
                                        /* Wiring for LCD adapter kit */
                                        { "reset", 7 },
-                                       { "dc", 0 },    /* rev 2: 2 */
-                                       { "wr", 1 },    /* rev 2: 3 */
+                                       { "dc", 0 },    /* rev 2: 2 */
+                                       { "wr", 1 },    /* rev 2: 3 */
                                        { "cs", 8 },
                                        { "db00", 17 },
                                        { "db01", 18 },
@@ -776,13 +873,13 @@ static struct fbtft_device_display displays[] = {
                                        { "dc", 25 },
                                        {},
                                },
-                               .gamma =        "0 2 2 2 2 2 2 2 " \
-                                               "2 2 2 2 2 2 2 2 " \
-                                               "2 2 2 2 2 2 2 2 " \
-                                               "2 2 2 2 2 2 2 3 " \
-                                               "3 3 3 3 3 3 3 3 " \
-                                               "3 3 3 3 3 3 3 3 " \
-                                               "3 3 3 4 4 4 4 4 " \
+                               .gamma =        "0 2 2 2 2 2 2 2 "
+                                               "2 2 2 2 2 2 2 2 "
+                                               "2 2 2 2 2 2 2 2 "
+                                               "2 2 2 2 2 2 2 3 "
+                                               "3 3 3 3 3 3 3 3 "
+                                               "3 3 3 3 3 3 3 3 "
+                                               "3 3 3 4 4 4 4 4 "
                                                "4 4 4 4 4 4 4"
                        }
                }
@@ -896,7 +993,7 @@ static struct fbtft_device_display displays[] = {
                                        .buswidth = 16,
                                        .txbuflen = -2, /* disable buffer */
                                        .backlight = 1,
-                                       .fbtftops.write = \
+                                       .fbtftops.write =
                                                fbtft_write_gpio16_wr_latched,
                                },
                                .bgr = true,
@@ -1063,7 +1160,8 @@ static struct fbtft_device_display displays[] = {
                                .display = {
                                        .buswidth = 8,
                                        .backlight = 1,
-                                       .init_sequence = waveshare32b_init_sequence,
+                                       .init_sequence =
+                                               waveshare32b_init_sequence,
                                },
                                .bgr = true,
                                .gpios = (const struct fbtft_gpio []) {
@@ -1172,15 +1270,13 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
 static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
                                                int xs, int ys, int xe, int ye)
 {
-       fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
-               "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
        write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
        write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
        write_reg(par, 0x2C);
 }
 
 /* used if gpios parameter is present */
-static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
+static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { };
 
 static void fbtft_device_pdev_release(struct device *dev)
 {
@@ -1193,16 +1289,16 @@ static int spi_device_found(struct device *dev, void *data)
 {
        struct spi_device *spi = container_of(dev, struct spi_device, dev);
 
-       pr_info(DRVNAME":      %s %s %dkHz %d bits mode=0x%02X\n",
-               spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
-               spi->bits_per_word, spi->mode);
+       dev_info(dev, "%s %s %dkHz %d bits mode=0x%02X\n", spi->modalias,
+                dev_name(dev), spi->max_speed_hz / 1000, spi->bits_per_word,
+                spi->mode);
 
        return 0;
 }
 
 static void pr_spi_devices(void)
 {
-       pr_info(DRVNAME":  SPI devices registered:\n");
+       pr_debug("SPI devices registered:\n");
        bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
 }
 
@@ -1212,16 +1308,15 @@ static int p_device_found(struct device *dev, void *data)
        *pdev = container_of(dev, struct platform_device, dev);
 
        if (strstr(pdev->name, "fb"))
-               pr_info(DRVNAME":      %s id=%d pdata? %s\n",
-                               pdev->name, pdev->id,
-                               pdev->dev.platform_data ? "yes" : "no");
+               dev_info(dev, "%s id=%d pdata? %s\n", pdev->name, pdev->id,
+                        pdev->dev.platform_data ? "yes" : "no");
 
        return 0;
 }
 
 static void pr_p_devices(void)
 {
-       pr_info(DRVNAME":  'fb' Platform devices registered:\n");
+       pr_debug("'fb' Platform devices registered:\n");
        bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
 }
 
@@ -1236,7 +1331,7 @@ static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
        dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
        if (dev) {
                if (verbose)
-                       pr_info(DRVNAME": Deleting %s\n", str);
+                       dev_info(dev, "Deleting %s\n", str);
                device_del(dev);
        }
 }
@@ -1247,8 +1342,8 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
 
        master = spi_busnum_to_master(spi->bus_num);
        if (!master) {
-               pr_err(DRVNAME ":  spi_busnum_to_master(%d) returned NULL\n",
-                                                               spi->bus_num);
+               pr_err("spi_busnum_to_master(%d) returned NULL\n",
+                      spi->bus_num);
                return -EINVAL;
        }
        /* make sure it's available */
@@ -1256,7 +1351,7 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
        spi_device = spi_new_device(master, spi);
        put_device(&master->dev);
        if (!spi_device) {
-               pr_err(DRVNAME ":    spi_new_device() returned NULL\n");
+               dev_err(&master->dev, "spi_new_device() returned NULL\n");
                return -EPERM;
        }
        return 0;
@@ -1279,11 +1374,9 @@ static int __init fbtft_device_init(void)
        long val;
        int ret = 0;
 
-       pr_debug("\n\n"DRVNAME": init\n");
-
        if (name == NULL) {
 #ifdef MODULE
-               pr_err(DRVNAME":  missing module parameter: 'name'\n");
+               pr_err("missing module parameter: 'name'\n");
                return -EINVAL;
 #else
                return 0;
@@ -1291,41 +1384,37 @@ static int __init fbtft_device_init(void)
        }
 
        if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
-               pr_err(DRVNAME \
-                       ":  init parameter: exceeded max array size: %d\n",
-                       FBTFT_MAX_INIT_SEQUENCE);
+               pr_err("init parameter: exceeded max array size: %d\n",
+                      FBTFT_MAX_INIT_SEQUENCE);
                return -EINVAL;
        }
 
        /* parse module parameter: gpios */
        while ((p_gpio = strsep(&gpios, ","))) {
                if (strchr(p_gpio, ':') == NULL) {
-                       pr_err(DRVNAME \
-                               ":  error: missing ':' in gpios parameter: %s\n",
-                               p_gpio);
+                       pr_err("error: missing ':' in gpios parameter: %s\n",
+                              p_gpio);
                        return -EINVAL;
                }
                p_num = p_gpio;
                p_name = strsep(&p_num, ":");
                if (p_name == NULL || p_num == NULL) {
-                       pr_err(DRVNAME \
-                               ":  something bad happened parsing gpios parameter: %s\n",
-                               p_gpio);
+                       pr_err("something bad happened parsing gpios parameter: %s\n",
+                              p_gpio);
                        return -EINVAL;
                }
                ret = kstrtol(p_num, 10, &val);
                if (ret) {
-                       pr_err(DRVNAME \
-                               ":  could not parse number in gpios parameter: %s:%s\n",
-                               p_name, p_num);
+                       pr_err("could not parse number in gpios parameter: %s:%s\n",
+                              p_name, p_num);
                        return -EINVAL;
                }
-               strcpy(fbtft_device_param_gpios[i].name, p_name);
+               strncpy(fbtft_device_param_gpios[i].name, p_name,
+                       FBTFT_GPIO_NAME_SIZE - 1);
                fbtft_device_param_gpios[i++].gpio = (int) val;
                if (i == MAX_GPIOS) {
-                       pr_err(DRVNAME \
-                               ":  gpios parameter: exceeded max array size: %d\n",
-                               MAX_GPIOS);
+                       pr_err("gpios parameter: exceeded max array size: %d\n",
+                              MAX_GPIOS);
                        return -EINVAL;
                }
        }
@@ -1338,7 +1427,7 @@ static int __init fbtft_device_init(void)
        if (verbose > 2)
                pr_p_devices(); /* print list of 'fb' platform devices */
 
-       pr_debug(DRVNAME":  name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
+       pr_debug("name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
 
        if (rotate > 0 && rotate < 4) {
                rotate = (4 - rotate) * 90;
@@ -1352,11 +1441,11 @@ static int __init fbtft_device_init(void)
        }
 
        /* name=list lists all supported displays */
-       if (strncmp(name, "list", 32) == 0) {
-               pr_info(DRVNAME":  Supported displays:\n");
+       if (strncmp(name, "list", FBTFT_GPIO_NAME_SIZE) == 0) {
+               pr_info("Supported displays:\n");
 
                for (i = 0; i < ARRAY_SIZE(displays); i++)
-                       pr_info(DRVNAME":      %s\n", displays[i].name);
+                       pr_info("%s\n", displays[i].name);
                return -ECANCELED;
        }
 
@@ -1387,7 +1476,7 @@ static int __init fbtft_device_init(void)
                                p_device = displays[i].pdev;
                                pdata = p_device->dev.platform_data;
                        } else {
-                               pr_err(DRVNAME": broken displays array\n");
+                               pr_err("broken displays array\n");
                                return -EINVAL;
                        }
 
@@ -1419,43 +1508,38 @@ static int __init fbtft_device_init(void)
                        if (displays[i].spi) {
                                ret = fbtft_device_spi_device_register(spi);
                                if (ret) {
-                                       pr_err(DRVNAME \
-                                               ": failed to register SPI device\n");
+                                       pr_err("failed to register SPI device\n");
                                        return ret;
                                }
-                               found = true;
-                               break;
                        } else {
                                ret = platform_device_register(p_device);
                                if (ret < 0) {
-                                       pr_err(DRVNAME \
-                                               ":    platform_device_register() returned %d\n",
-                                               ret);
+                                       pr_err("platform_device_register() returned %d\n",
+                                              ret);
                                        return ret;
                                }
-                               found = true;
-                               break;
                        }
+                       found = true;
+                       break;
                }
        }
 
        if (!found) {
-               pr_err(DRVNAME":  display not supported: '%s'\n", name);
+               pr_err("display not supported: '%s'\n", name);
                return -EINVAL;
        }
 
        if (verbose && pdata && pdata->gpios) {
                gpio = pdata->gpios;
-               pr_info(DRVNAME":  GPIOS used by '%s':\n", name);
+               pr_info("GPIOS used by '%s':\n", name);
                found = false;
                while (verbose && gpio->name[0]) {
-                       pr_info(DRVNAME":    '%s' = GPIO%d\n",
-                               gpio->name, gpio->gpio);
+                       pr_info("'%s' = GPIO%d\n", gpio->name, gpio->gpio);
                        gpio++;
                        found = true;
                }
                if (!found)
-                       pr_info(DRVNAME":    (none)\n");
+                       pr_info("(none)\n");
        }
 
        if (spi_device && (verbose > 1))
@@ -1468,8 +1552,6 @@ static int __init fbtft_device_init(void)
 
 static void __exit fbtft_device_exit(void)
 {
-       pr_debug(DRVNAME" - exit\n");
-
        if (spi_device) {
                device_del(&spi_device->dev);
                kfree(spi_device);