root/drivers/gpu/drm/tiny/hx8357d.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. yx240qv29_enable
  2. hx8357d_probe
  3. hx8357d_remove
  4. hx8357d_shutdown

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * DRM driver for the HX8357D LCD controller
   4  *
   5  * Copyright 2018 Broadcom
   6  * Copyright 2018 David Lechner <david@lechnology.com>
   7  * Copyright 2016 Noralf Trønnes
   8  * Copyright (C) 2015 Adafruit Industries
   9  * Copyright (C) 2013 Christian Vogelgsang
  10  */
  11 
  12 #include <linux/backlight.h>
  13 #include <linux/delay.h>
  14 #include <linux/gpio/consumer.h>
  15 #include <linux/module.h>
  16 #include <linux/property.h>
  17 #include <linux/spi/spi.h>
  18 
  19 #include <drm/drm_atomic_helper.h>
  20 #include <drm/drm_drv.h>
  21 #include <drm/drm_fb_helper.h>
  22 #include <drm/drm_gem_cma_helper.h>
  23 #include <drm/drm_gem_framebuffer_helper.h>
  24 #include <drm/drm_mipi_dbi.h>
  25 #include <drm/drm_modeset_helper.h>
  26 #include <video/mipi_display.h>
  27 
  28 #define HX8357D_SETOSC 0xb0
  29 #define HX8357D_SETPOWER 0xb1
  30 #define HX8357D_SETRGB 0xb3
  31 #define HX8357D_SETCYC 0xb3
  32 #define HX8357D_SETCOM 0xb6
  33 #define HX8357D_SETEXTC 0xb9
  34 #define HX8357D_SETSTBA 0xc0
  35 #define HX8357D_SETPANEL 0xcc
  36 #define HX8357D_SETGAMMA 0xe0
  37 
  38 #define HX8357D_MADCTL_MY  0x80
  39 #define HX8357D_MADCTL_MX  0x40
  40 #define HX8357D_MADCTL_MV  0x20
  41 #define HX8357D_MADCTL_ML  0x10
  42 #define HX8357D_MADCTL_RGB 0x00
  43 #define HX8357D_MADCTL_BGR 0x08
  44 #define HX8357D_MADCTL_MH  0x04
  45 
  46 static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
  47                              struct drm_crtc_state *crtc_state,
  48                              struct drm_plane_state *plane_state)
  49 {
  50         struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
  51         struct mipi_dbi *dbi = &dbidev->dbi;
  52         u8 addr_mode;
  53         int ret, idx;
  54 
  55         if (!drm_dev_enter(pipe->crtc.dev, &idx))
  56                 return;
  57 
  58         DRM_DEBUG_KMS("\n");
  59 
  60         ret = mipi_dbi_poweron_conditional_reset(dbidev);
  61         if (ret < 0)
  62                 goto out_exit;
  63         if (ret == 1)
  64                 goto out_enable;
  65 
  66         /* setextc */
  67         mipi_dbi_command(dbi, HX8357D_SETEXTC, 0xFF, 0x83, 0x57);
  68         msleep(150);
  69 
  70         /* setRGB which also enables SDO */
  71         mipi_dbi_command(dbi, HX8357D_SETRGB, 0x00, 0x00, 0x06, 0x06);
  72 
  73         /* -1.52V */
  74         mipi_dbi_command(dbi, HX8357D_SETCOM, 0x25);
  75 
  76         /* Normal mode 70Hz, Idle mode 55 Hz */
  77         mipi_dbi_command(dbi, HX8357D_SETOSC, 0x68);
  78 
  79         /* Set Panel - BGR, Gate direction swapped */
  80         mipi_dbi_command(dbi, HX8357D_SETPANEL, 0x05);
  81 
  82         mipi_dbi_command(dbi, HX8357D_SETPOWER,
  83                          0x00,  /* Not deep standby */
  84                          0x15,  /* BT */
  85                          0x1C,  /* VSPR */
  86                          0x1C,  /* VSNR */
  87                          0x83,  /* AP */
  88                          0xAA);  /* FS */
  89 
  90         mipi_dbi_command(dbi, HX8357D_SETSTBA,
  91                          0x50,  /* OPON normal */
  92                          0x50,  /* OPON idle */
  93                          0x01,  /* STBA */
  94                          0x3C,  /* STBA */
  95                          0x1E,  /* STBA */
  96                          0x08);  /* GEN */
  97 
  98         mipi_dbi_command(dbi, HX8357D_SETCYC,
  99                          0x02,  /* NW 0x02 */
 100                          0x40,  /* RTN */
 101                          0x00,  /* DIV */
 102                          0x2A,  /* DUM */
 103                          0x2A,  /* DUM */
 104                          0x0D,  /* GDON */
 105                          0x78);  /* GDOFF */
 106 
 107         mipi_dbi_command(dbi, HX8357D_SETGAMMA,
 108                          0x02,
 109                          0x0A,
 110                          0x11,
 111                          0x1d,
 112                          0x23,
 113                          0x35,
 114                          0x41,
 115                          0x4b,
 116                          0x4b,
 117                          0x42,
 118                          0x3A,
 119                          0x27,
 120                          0x1B,
 121                          0x08,
 122                          0x09,
 123                          0x03,
 124                          0x02,
 125                          0x0A,
 126                          0x11,
 127                          0x1d,
 128                          0x23,
 129                          0x35,
 130                          0x41,
 131                          0x4b,
 132                          0x4b,
 133                          0x42,
 134                          0x3A,
 135                          0x27,
 136                          0x1B,
 137                          0x08,
 138                          0x09,
 139                          0x03,
 140                          0x00,
 141                          0x01);
 142 
 143         /* 16 bit */
 144         mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT,
 145                          MIPI_DCS_PIXEL_FMT_16BIT);
 146 
 147         /* TE off */
 148         mipi_dbi_command(dbi, MIPI_DCS_SET_TEAR_ON, 0x00);
 149 
 150         /* tear line */
 151         mipi_dbi_command(dbi, MIPI_DCS_SET_TEAR_SCANLINE, 0x00, 0x02);
 152 
 153         /* Exit Sleep */
 154         mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
 155         msleep(150);
 156 
 157         /* display on */
 158         mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
 159         usleep_range(5000, 7000);
 160 
 161 out_enable:
 162         switch (dbidev->rotation) {
 163         default:
 164                 addr_mode = HX8357D_MADCTL_MX | HX8357D_MADCTL_MY;
 165                 break;
 166         case 90:
 167                 addr_mode = HX8357D_MADCTL_MV | HX8357D_MADCTL_MY;
 168                 break;
 169         case 180:
 170                 addr_mode = 0;
 171                 break;
 172         case 270:
 173                 addr_mode = HX8357D_MADCTL_MV | HX8357D_MADCTL_MX;
 174                 break;
 175         }
 176         mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
 177         mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
 178 out_exit:
 179         drm_dev_exit(idx);
 180 }
 181 
 182 static const struct drm_simple_display_pipe_funcs hx8357d_pipe_funcs = {
 183         .enable = yx240qv29_enable,
 184         .disable = mipi_dbi_pipe_disable,
 185         .update = mipi_dbi_pipe_update,
 186         .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
 187 };
 188 
 189 static const struct drm_display_mode yx350hv15_mode = {
 190         DRM_SIMPLE_MODE(320, 480, 60, 75),
 191 };
 192 
 193 DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops);
 194 
 195 static struct drm_driver hx8357d_driver = {
 196         .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 197         .fops                   = &hx8357d_fops,
 198         .release                = mipi_dbi_release,
 199         DRM_GEM_CMA_VMAP_DRIVER_OPS,
 200         .debugfs_init           = mipi_dbi_debugfs_init,
 201         .name                   = "hx8357d",
 202         .desc                   = "HX8357D",
 203         .date                   = "20181023",
 204         .major                  = 1,
 205         .minor                  = 0,
 206 };
 207 
 208 static const struct of_device_id hx8357d_of_match[] = {
 209         { .compatible = "adafruit,yx350hv15" },
 210         { }
 211 };
 212 MODULE_DEVICE_TABLE(of, hx8357d_of_match);
 213 
 214 static const struct spi_device_id hx8357d_id[] = {
 215         { "yx350hv15", 0 },
 216         { }
 217 };
 218 MODULE_DEVICE_TABLE(spi, hx8357d_id);
 219 
 220 static int hx8357d_probe(struct spi_device *spi)
 221 {
 222         struct device *dev = &spi->dev;
 223         struct mipi_dbi_dev *dbidev;
 224         struct drm_device *drm;
 225         struct gpio_desc *dc;
 226         u32 rotation = 0;
 227         int ret;
 228 
 229         dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL);
 230         if (!dbidev)
 231                 return -ENOMEM;
 232 
 233         drm = &dbidev->drm;
 234         ret = devm_drm_dev_init(dev, drm, &hx8357d_driver);
 235         if (ret) {
 236                 kfree(dbidev);
 237                 return ret;
 238         }
 239 
 240         drm_mode_config_init(drm);
 241 
 242         dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
 243         if (IS_ERR(dc)) {
 244                 DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
 245                 return PTR_ERR(dc);
 246         }
 247 
 248         dbidev->backlight = devm_of_find_backlight(dev);
 249         if (IS_ERR(dbidev->backlight))
 250                 return PTR_ERR(dbidev->backlight);
 251 
 252         device_property_read_u32(dev, "rotation", &rotation);
 253 
 254         ret = mipi_dbi_spi_init(spi, &dbidev->dbi, dc);
 255         if (ret)
 256                 return ret;
 257 
 258         ret = mipi_dbi_dev_init(dbidev, &hx8357d_pipe_funcs, &yx350hv15_mode, rotation);
 259         if (ret)
 260                 return ret;
 261 
 262         drm_mode_config_reset(drm);
 263 
 264         ret = drm_dev_register(drm, 0);
 265         if (ret)
 266                 return ret;
 267 
 268         spi_set_drvdata(spi, drm);
 269 
 270         drm_fbdev_generic_setup(drm, 0);
 271 
 272         return 0;
 273 }
 274 
 275 static int hx8357d_remove(struct spi_device *spi)
 276 {
 277         struct drm_device *drm = spi_get_drvdata(spi);
 278 
 279         drm_dev_unplug(drm);
 280         drm_atomic_helper_shutdown(drm);
 281 
 282         return 0;
 283 }
 284 
 285 static void hx8357d_shutdown(struct spi_device *spi)
 286 {
 287         drm_atomic_helper_shutdown(spi_get_drvdata(spi));
 288 }
 289 
 290 static struct spi_driver hx8357d_spi_driver = {
 291         .driver = {
 292                 .name = "hx8357d",
 293                 .of_match_table = hx8357d_of_match,
 294         },
 295         .id_table = hx8357d_id,
 296         .probe = hx8357d_probe,
 297         .remove = hx8357d_remove,
 298         .shutdown = hx8357d_shutdown,
 299 };
 300 module_spi_driver(hx8357d_spi_driver);
 301 
 302 MODULE_DESCRIPTION("HX8357D DRM driver");
 303 MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
 304 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */