This source file includes following definitions.
- to_tpg110
- tpg110_readwrite_reg
- tpg110_read_reg
- tpg110_write_reg
- tpg110_startup
- tpg110_disable
- tpg110_enable
- tpg110_get_modes
- tpg110_probe
- tpg110_remove
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 #include <drm/drm_modes.h>
  14 #include <drm/drm_panel.h>
  15 #include <drm/drm_print.h>
  16 
  17 #include <linux/backlight.h>
  18 #include <linux/bitops.h>
  19 #include <linux/delay.h>
  20 #include <linux/gpio/consumer.h>
  21 #include <linux/init.h>
  22 #include <linux/kernel.h>
  23 #include <linux/module.h>
  24 #include <linux/platform_device.h>
  25 #include <linux/spi/spi.h>
  26 
  27 #define TPG110_TEST                     0x00
  28 #define TPG110_CHIPID                   0x01
  29 #define TPG110_CTRL1                    0x02
  30 #define TPG110_RES_MASK                 GENMASK(2, 0)
  31 #define TPG110_RES_800X480              0x07
  32 #define TPG110_RES_640X480              0x06
  33 #define TPG110_RES_480X272              0x05
  34 #define TPG110_RES_480X640              0x04
  35 #define TPG110_RES_480X272_D            0x01 
  36 #define TPG110_RES_400X240_D            0x00 
  37 #define TPG110_CTRL2                    0x03
  38 #define TPG110_CTRL2_PM                 BIT(0)
  39 #define TPG110_CTRL2_RES_PM_CTRL        BIT(7)
  40 
  41 
  42 
  43 
  44 struct tpg110_panel_mode {
  45         
  46 
  47 
  48         const char *name;
  49         
  50 
  51 
  52         u32 magic;
  53         
  54 
  55 
  56         struct drm_display_mode mode;
  57         
  58 
  59 
  60         u32 bus_flags;
  61 };
  62 
  63 
  64 
  65 
  66 struct tpg110 {
  67         
  68 
  69 
  70         struct device *dev;
  71         
  72 
  73 
  74         struct spi_device *spi;
  75         
  76 
  77 
  78         struct drm_panel panel;
  79         
  80 
  81 
  82         struct backlight_device *backlight;
  83         
  84 
  85 
  86         const struct tpg110_panel_mode *panel_mode;
  87         
  88 
  89 
  90         u32 width;
  91         
  92 
  93 
  94         u32 height;
  95         
  96 
  97 
  98         struct gpio_desc *grestb;
  99 };
 100 
 101 
 102 
 103 
 104 
 105 static const struct tpg110_panel_mode tpg110_modes[] = {
 106         {
 107                 .name = "800x480 RGB",
 108                 .magic = TPG110_RES_800X480,
 109                 .mode = {
 110                         .clock = 33200,
 111                         .hdisplay = 800,
 112                         .hsync_start = 800 + 40,
 113                         .hsync_end = 800 + 40 + 1,
 114                         .htotal = 800 + 40 + 1 + 216,
 115                         .vdisplay = 480,
 116                         .vsync_start = 480 + 10,
 117                         .vsync_end = 480 + 10 + 1,
 118                         .vtotal = 480 + 10 + 1 + 35,
 119                         .vrefresh = 60,
 120                 },
 121                 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 122         },
 123         {
 124                 .name = "640x480 RGB",
 125                 .magic = TPG110_RES_640X480,
 126                 .mode = {
 127                         .clock = 25200,
 128                         .hdisplay = 640,
 129                         .hsync_start = 640 + 24,
 130                         .hsync_end = 640 + 24 + 1,
 131                         .htotal = 640 + 24 + 1 + 136,
 132                         .vdisplay = 480,
 133                         .vsync_start = 480 + 18,
 134                         .vsync_end = 480 + 18 + 1,
 135                         .vtotal = 480 + 18 + 1 + 27,
 136                         .vrefresh = 60,
 137                 },
 138                 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 139         },
 140         {
 141                 .name = "480x272 RGB",
 142                 .magic = TPG110_RES_480X272,
 143                 .mode = {
 144                         .clock = 9000,
 145                         .hdisplay = 480,
 146                         .hsync_start = 480 + 2,
 147                         .hsync_end = 480 + 2 + 1,
 148                         .htotal = 480 + 2 + 1 + 43,
 149                         .vdisplay = 272,
 150                         .vsync_start = 272 + 2,
 151                         .vsync_end = 272 + 2 + 1,
 152                         .vtotal = 272 + 2 + 1 + 12,
 153                         .vrefresh = 60,
 154                 },
 155                 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 156         },
 157         {
 158                 .name = "480x640 RGB",
 159                 .magic = TPG110_RES_480X640,
 160                 .mode = {
 161                         .clock = 20500,
 162                         .hdisplay = 480,
 163                         .hsync_start = 480 + 2,
 164                         .hsync_end = 480 + 2 + 1,
 165                         .htotal = 480 + 2 + 1 + 43,
 166                         .vdisplay = 640,
 167                         .vsync_start = 640 + 4,
 168                         .vsync_end = 640 + 4 + 1,
 169                         .vtotal = 640 + 4 + 1 + 8,
 170                         .vrefresh = 60,
 171                 },
 172                 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 173         },
 174         {
 175                 .name = "400x240 RGB",
 176                 .magic = TPG110_RES_400X240_D,
 177                 .mode = {
 178                         .clock = 8300,
 179                         .hdisplay = 400,
 180                         .hsync_start = 400 + 20,
 181                         .hsync_end = 400 + 20 + 1,
 182                         .htotal = 400 + 20 + 1 + 108,
 183                         .vdisplay = 240,
 184                         .vsync_start = 240 + 2,
 185                         .vsync_end = 240 + 2 + 1,
 186                         .vtotal = 240 + 2 + 1 + 20,
 187                         .vrefresh = 60,
 188                 },
 189                 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
 190         },
 191 };
 192 
 193 static inline struct tpg110 *
 194 to_tpg110(struct drm_panel *panel)
 195 {
 196         return container_of(panel, struct tpg110, panel);
 197 }
 198 
 199 static u8 tpg110_readwrite_reg(struct tpg110 *tpg, bool write,
 200                                u8 address, u8 outval)
 201 {
 202         struct spi_message m;
 203         struct spi_transfer t[2];
 204         u8 buf[2];
 205         int ret;
 206 
 207         spi_message_init(&m);
 208         memset(t, 0, sizeof(t));
 209 
 210         if (write) {
 211                 
 212 
 213 
 214 
 215 
 216                 buf[0] = address << 2;
 217                 buf[0] &= ~0x03;
 218                 buf[1] = outval;
 219 
 220                 t[0].bits_per_word = 8;
 221                 t[0].tx_buf = &buf[0];
 222                 t[0].len = 1;
 223 
 224                 t[1].tx_buf = &buf[1];
 225                 t[1].len = 1;
 226                 t[1].bits_per_word = 8;
 227         } else {
 228                 
 229                 buf[0] = address << 1;
 230                 buf[0] |= 0x01;
 231 
 232                 
 233 
 234 
 235 
 236 
 237                 t[0].bits_per_word = 7;
 238                 t[0].tx_buf = &buf[0];
 239                 t[0].len = 1;
 240 
 241                 t[1].rx_buf = &buf[1];
 242                 t[1].len = 1;
 243                 t[1].bits_per_word = 8;
 244         }
 245 
 246         spi_message_add_tail(&t[0], &m);
 247         spi_message_add_tail(&t[1], &m);
 248         ret = spi_sync(tpg->spi, &m);
 249         if (ret) {
 250                 DRM_DEV_ERROR(tpg->dev, "SPI message error %d\n", ret);
 251                 return ret;
 252         }
 253         if (write)
 254                 return 0;
 255         
 256         return buf[1];
 257 }
 258 
 259 static u8 tpg110_read_reg(struct tpg110 *tpg, u8 address)
 260 {
 261         return tpg110_readwrite_reg(tpg, false, address, 0);
 262 }
 263 
 264 static void tpg110_write_reg(struct tpg110 *tpg, u8 address, u8 outval)
 265 {
 266         tpg110_readwrite_reg(tpg, true, address, outval);
 267 }
 268 
 269 static int tpg110_startup(struct tpg110 *tpg)
 270 {
 271         u8 val;
 272         int i;
 273 
 274         
 275         gpiod_set_value_cansleep(tpg->grestb, 0);
 276         usleep_range(1000, 2000);
 277         DRM_DEV_DEBUG(tpg->dev, "de-asserted GRESTB\n");
 278 
 279         
 280         tpg110_write_reg(tpg, TPG110_TEST, 0x55);
 281         val = tpg110_read_reg(tpg, TPG110_TEST);
 282         if (val != 0x55) {
 283                 DRM_DEV_ERROR(tpg->dev, "failed communication test\n");
 284                 return -ENODEV;
 285         }
 286 
 287         val = tpg110_read_reg(tpg, TPG110_CHIPID);
 288         DRM_DEV_INFO(tpg->dev, "TPG110 chip ID: %d version: %d\n",
 289                  val >> 4, val & 0x0f);
 290 
 291         
 292         val = tpg110_read_reg(tpg, TPG110_CTRL1);
 293         val &= TPG110_RES_MASK;
 294         switch (val) {
 295         case TPG110_RES_400X240_D:
 296                 DRM_DEV_INFO(tpg->dev,
 297                          "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n");
 298                 break;
 299         case TPG110_RES_480X272_D:
 300                 DRM_DEV_INFO(tpg->dev,
 301                          "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n");
 302                 break;
 303         case TPG110_RES_480X640:
 304                 DRM_DEV_INFO(tpg->dev, "480x640 RGB\n");
 305                 break;
 306         case TPG110_RES_480X272:
 307                 DRM_DEV_INFO(tpg->dev, "480x272 RGB\n");
 308                 break;
 309         case TPG110_RES_640X480:
 310                 DRM_DEV_INFO(tpg->dev, "640x480 RGB\n");
 311                 break;
 312         case TPG110_RES_800X480:
 313                 DRM_DEV_INFO(tpg->dev, "800x480 RGB\n");
 314                 break;
 315         default:
 316                 DRM_DEV_ERROR(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val);
 317                 break;
 318         }
 319 
 320         
 321         if (val == TPG110_RES_480X272_D)
 322                 val = TPG110_RES_480X272;
 323 
 324         for (i = 0; i < ARRAY_SIZE(tpg110_modes); i++) {
 325                 const struct tpg110_panel_mode *pm;
 326 
 327                 pm = &tpg110_modes[i];
 328                 if (pm->magic == val) {
 329                         tpg->panel_mode = pm;
 330                         break;
 331                 }
 332         }
 333         if (i == ARRAY_SIZE(tpg110_modes)) {
 334                 DRM_DEV_ERROR(tpg->dev, "unsupported mode (%02x) detected\n",
 335                         val);
 336                 return -ENODEV;
 337         }
 338 
 339         val = tpg110_read_reg(tpg, TPG110_CTRL2);
 340         DRM_DEV_INFO(tpg->dev, "resolution and standby is controlled by %s\n",
 341                  (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware");
 342         
 343         val |= TPG110_CTRL2_RES_PM_CTRL;
 344         tpg110_write_reg(tpg, TPG110_CTRL2, val);
 345 
 346         return 0;
 347 }
 348 
 349 static int tpg110_disable(struct drm_panel *panel)
 350 {
 351         struct tpg110 *tpg = to_tpg110(panel);
 352         u8 val;
 353 
 354         
 355         val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);
 356         val &= ~TPG110_CTRL2_PM;
 357         tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);
 358 
 359         backlight_disable(tpg->backlight);
 360 
 361         return 0;
 362 }
 363 
 364 static int tpg110_enable(struct drm_panel *panel)
 365 {
 366         struct tpg110 *tpg = to_tpg110(panel);
 367         u8 val;
 368 
 369         backlight_enable(tpg->backlight);
 370 
 371         
 372         val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);
 373         val |= TPG110_CTRL2_PM;
 374         tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);
 375 
 376         return 0;
 377 }
 378 
 379 
 380 
 381 
 382 
 383 
 384 
 385 
 386 
 387 static int tpg110_get_modes(struct drm_panel *panel)
 388 {
 389         struct drm_connector *connector = panel->connector;
 390         struct tpg110 *tpg = to_tpg110(panel);
 391         struct drm_display_mode *mode;
 392 
 393         connector->display_info.width_mm = tpg->width;
 394         connector->display_info.height_mm = tpg->height;
 395         connector->display_info.bus_flags = tpg->panel_mode->bus_flags;
 396 
 397         mode = drm_mode_duplicate(panel->drm, &tpg->panel_mode->mode);
 398         drm_mode_set_name(mode);
 399         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 400 
 401         mode->width_mm = tpg->width;
 402         mode->height_mm = tpg->height;
 403 
 404         drm_mode_probed_add(connector, mode);
 405 
 406         return 1;
 407 }
 408 
 409 static const struct drm_panel_funcs tpg110_drm_funcs = {
 410         .disable = tpg110_disable,
 411         .enable = tpg110_enable,
 412         .get_modes = tpg110_get_modes,
 413 };
 414 
 415 static int tpg110_probe(struct spi_device *spi)
 416 {
 417         struct device *dev = &spi->dev;
 418         struct device_node *np = dev->of_node;
 419         struct tpg110 *tpg;
 420         int ret;
 421 
 422         tpg = devm_kzalloc(dev, sizeof(*tpg), GFP_KERNEL);
 423         if (!tpg)
 424                 return -ENOMEM;
 425         tpg->dev = dev;
 426 
 427         
 428         ret = of_property_read_u32(np, "width-mm", &tpg->width);
 429         if (ret)
 430                 DRM_DEV_ERROR(dev, "no panel width specified\n");
 431         ret = of_property_read_u32(np, "height-mm", &tpg->height);
 432         if (ret)
 433                 DRM_DEV_ERROR(dev, "no panel height specified\n");
 434 
 435         
 436         tpg->backlight = devm_of_find_backlight(dev);
 437         if (IS_ERR(tpg->backlight))
 438                 return PTR_ERR(tpg->backlight);
 439 
 440         
 441         tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH);
 442         if (IS_ERR(tpg->grestb)) {
 443                 DRM_DEV_ERROR(dev, "no GRESTB GPIO\n");
 444                 return -ENODEV;
 445         }
 446 
 447         spi->bits_per_word = 8;
 448         spi->mode |= SPI_3WIRE_HIZ;
 449         ret = spi_setup(spi);
 450         if (ret < 0) {
 451                 DRM_DEV_ERROR(dev, "spi setup failed.\n");
 452                 return ret;
 453         }
 454         tpg->spi = spi;
 455 
 456         ret = tpg110_startup(tpg);
 457         if (ret)
 458                 return ret;
 459 
 460         drm_panel_init(&tpg->panel);
 461         tpg->panel.dev = dev;
 462         tpg->panel.funcs = &tpg110_drm_funcs;
 463         spi_set_drvdata(spi, tpg);
 464 
 465         return drm_panel_add(&tpg->panel);
 466 }
 467 
 468 static int tpg110_remove(struct spi_device *spi)
 469 {
 470         struct tpg110 *tpg = spi_get_drvdata(spi);
 471 
 472         drm_panel_remove(&tpg->panel);
 473         return 0;
 474 }
 475 
 476 static const struct of_device_id tpg110_match[] = {
 477         { .compatible = "tpo,tpg110", },
 478         {},
 479 };
 480 MODULE_DEVICE_TABLE(of, tpg110_match);
 481 
 482 static struct spi_driver tpg110_driver = {
 483         .probe          = tpg110_probe,
 484         .remove         = tpg110_remove,
 485         .driver         = {
 486                 .name   = "tpo-tpg110-panel",
 487                 .of_match_table = tpg110_match,
 488         },
 489 };
 490 module_spi_driver(tpg110_driver);
 491 
 492 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 493 MODULE_DESCRIPTION("TPO TPG110 panel driver");
 494 MODULE_LICENSE("GPL v2");