linux/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2017 NXP Semiconductors.
   4 * Author: Marco Franchi <marco.franchi@nxp.com>
   5 *
   6 * Based on Panel Simple driver by Thierry Reding <treding@nvidia.com>
   7 */
   8
   9#include <linux/backlight.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/regulator/consumer.h>
  13
  14#include <drm/drmP.h>
  15#include <drm/drm_crtc.h>
  16#include <drm/drm_panel.h>
  17
  18#include <video/display_timing.h>
  19#include <video/videomode.h>
  20
  21struct seiko_panel_desc {
  22        const struct drm_display_mode *modes;
  23        unsigned int num_modes;
  24        const struct display_timing *timings;
  25        unsigned int num_timings;
  26
  27        unsigned int bpc;
  28
  29        /**
  30         * @width: width (in millimeters) of the panel's active display area
  31         * @height: height (in millimeters) of the panel's active display area
  32         */
  33        struct {
  34                unsigned int width;
  35                unsigned int height;
  36        } size;
  37
  38        u32 bus_format;
  39        u32 bus_flags;
  40};
  41
  42struct seiko_panel {
  43        struct drm_panel base;
  44        bool prepared;
  45        bool enabled;
  46        const struct seiko_panel_desc *desc;
  47        struct backlight_device *backlight;
  48        struct regulator *dvdd;
  49        struct regulator *avdd;
  50};
  51
  52static inline struct seiko_panel *to_seiko_panel(struct drm_panel *panel)
  53{
  54        return container_of(panel, struct seiko_panel, base);
  55}
  56
  57static int seiko_panel_get_fixed_modes(struct seiko_panel *panel)
  58{
  59        struct drm_connector *connector = panel->base.connector;
  60        struct drm_device *drm = panel->base.drm;
  61        struct drm_display_mode *mode;
  62        unsigned int i, num = 0;
  63
  64        if (!panel->desc)
  65                return 0;
  66
  67        for (i = 0; i < panel->desc->num_timings; i++) {
  68                const struct display_timing *dt = &panel->desc->timings[i];
  69                struct videomode vm;
  70
  71                videomode_from_timing(dt, &vm);
  72                mode = drm_mode_create(drm);
  73                if (!mode) {
  74                        dev_err(drm->dev, "failed to add mode %ux%u\n",
  75                                dt->hactive.typ, dt->vactive.typ);
  76                        continue;
  77                }
  78
  79                drm_display_mode_from_videomode(&vm, mode);
  80
  81                mode->type |= DRM_MODE_TYPE_DRIVER;
  82
  83                if (panel->desc->num_timings == 1)
  84                        mode->type |= DRM_MODE_TYPE_PREFERRED;
  85
  86                drm_mode_probed_add(connector, mode);
  87                num++;
  88        }
  89
  90        for (i = 0; i < panel->desc->num_modes; i++) {
  91                const struct drm_display_mode *m = &panel->desc->modes[i];
  92
  93                mode = drm_mode_duplicate(drm, m);
  94                if (!mode) {
  95                        dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
  96                                m->hdisplay, m->vdisplay, m->vrefresh);
  97                        continue;
  98                }
  99
 100                mode->type |= DRM_MODE_TYPE_DRIVER;
 101
 102                if (panel->desc->num_modes == 1)
 103                        mode->type |= DRM_MODE_TYPE_PREFERRED;
 104
 105                drm_mode_set_name(mode);
 106
 107                drm_mode_probed_add(connector, mode);
 108                num++;
 109        }
 110
 111        connector->display_info.bpc = panel->desc->bpc;
 112        connector->display_info.width_mm = panel->desc->size.width;
 113        connector->display_info.height_mm = panel->desc->size.height;
 114        if (panel->desc->bus_format)
 115                drm_display_info_set_bus_formats(&connector->display_info,
 116                                                 &panel->desc->bus_format, 1);
 117        connector->display_info.bus_flags = panel->desc->bus_flags;
 118
 119        return num;
 120}
 121
 122static int seiko_panel_disable(struct drm_panel *panel)
 123{
 124        struct seiko_panel *p = to_seiko_panel(panel);
 125
 126        if (!p->enabled)
 127                return 0;
 128
 129        if (p->backlight) {
 130                p->backlight->props.power = FB_BLANK_POWERDOWN;
 131                p->backlight->props.state |= BL_CORE_FBBLANK;
 132                backlight_update_status(p->backlight);
 133        }
 134
 135        p->enabled = false;
 136
 137        return 0;
 138}
 139
 140static int seiko_panel_unprepare(struct drm_panel *panel)
 141{
 142        struct seiko_panel *p = to_seiko_panel(panel);
 143
 144        if (!p->prepared)
 145                return 0;
 146
 147        regulator_disable(p->avdd);
 148
 149        /* Add a 100ms delay as per the panel datasheet */
 150        msleep(100);
 151
 152        regulator_disable(p->dvdd);
 153
 154        p->prepared = false;
 155
 156        return 0;
 157}
 158
 159static int seiko_panel_prepare(struct drm_panel *panel)
 160{
 161        struct seiko_panel *p = to_seiko_panel(panel);
 162        int err;
 163
 164        if (p->prepared)
 165                return 0;
 166
 167        err = regulator_enable(p->dvdd);
 168        if (err < 0) {
 169                dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
 170                return err;
 171        }
 172
 173        /* Add a 100ms delay as per the panel datasheet */
 174        msleep(100);
 175
 176        err = regulator_enable(p->avdd);
 177        if (err < 0) {
 178                dev_err(panel->dev, "failed to enable avdd: %d\n", err);
 179                goto disable_dvdd;
 180        }
 181
 182        p->prepared = true;
 183
 184        return 0;
 185
 186disable_dvdd:
 187        regulator_disable(p->dvdd);
 188        return err;
 189}
 190
 191static int seiko_panel_enable(struct drm_panel *panel)
 192{
 193        struct seiko_panel *p = to_seiko_panel(panel);
 194
 195        if (p->enabled)
 196                return 0;
 197
 198        if (p->backlight) {
 199                p->backlight->props.state &= ~BL_CORE_FBBLANK;
 200                p->backlight->props.power = FB_BLANK_UNBLANK;
 201                backlight_update_status(p->backlight);
 202        }
 203
 204        p->enabled = true;
 205
 206        return 0;
 207}
 208
 209static int seiko_panel_get_modes(struct drm_panel *panel)
 210{
 211        struct seiko_panel *p = to_seiko_panel(panel);
 212
 213        /* add hard-coded panel modes */
 214        return seiko_panel_get_fixed_modes(p);
 215}
 216
 217static int seiko_panel_get_timings(struct drm_panel *panel,
 218                                    unsigned int num_timings,
 219                                    struct display_timing *timings)
 220{
 221        struct seiko_panel *p = to_seiko_panel(panel);
 222        unsigned int i;
 223
 224        if (p->desc->num_timings < num_timings)
 225                num_timings = p->desc->num_timings;
 226
 227        if (timings)
 228                for (i = 0; i < num_timings; i++)
 229                        timings[i] = p->desc->timings[i];
 230
 231        return p->desc->num_timings;
 232}
 233
 234static const struct drm_panel_funcs seiko_panel_funcs = {
 235        .disable = seiko_panel_disable,
 236        .unprepare = seiko_panel_unprepare,
 237        .prepare = seiko_panel_prepare,
 238        .enable = seiko_panel_enable,
 239        .get_modes = seiko_panel_get_modes,
 240        .get_timings = seiko_panel_get_timings,
 241};
 242
 243static int seiko_panel_probe(struct device *dev,
 244                                        const struct seiko_panel_desc *desc)
 245{
 246        struct device_node *backlight;
 247        struct seiko_panel *panel;
 248        int err;
 249
 250        panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
 251        if (!panel)
 252                return -ENOMEM;
 253
 254        panel->enabled = false;
 255        panel->prepared = false;
 256        panel->desc = desc;
 257
 258        panel->dvdd = devm_regulator_get(dev, "dvdd");
 259        if (IS_ERR(panel->dvdd))
 260                return PTR_ERR(panel->dvdd);
 261
 262        panel->avdd = devm_regulator_get(dev, "avdd");
 263        if (IS_ERR(panel->avdd))
 264                return PTR_ERR(panel->avdd);
 265
 266        backlight = of_parse_phandle(dev->of_node, "backlight", 0);
 267        if (backlight) {
 268                panel->backlight = of_find_backlight_by_node(backlight);
 269                of_node_put(backlight);
 270
 271                if (!panel->backlight)
 272                        return -EPROBE_DEFER;
 273        }
 274
 275        drm_panel_init(&panel->base);
 276        panel->base.dev = dev;
 277        panel->base.funcs = &seiko_panel_funcs;
 278
 279        err = drm_panel_add(&panel->base);
 280        if (err < 0)
 281                return err;
 282
 283        dev_set_drvdata(dev, panel);
 284
 285        return 0;
 286}
 287
 288static int seiko_panel_remove(struct platform_device *pdev)
 289{
 290        struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
 291
 292        drm_panel_remove(&panel->base);
 293
 294        seiko_panel_disable(&panel->base);
 295
 296        if (panel->backlight)
 297                put_device(&panel->backlight->dev);
 298
 299        return 0;
 300}
 301
 302static void seiko_panel_shutdown(struct platform_device *pdev)
 303{
 304        struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
 305
 306        seiko_panel_disable(&panel->base);
 307}
 308
 309static const struct display_timing seiko_43wvf1g_timing = {
 310        .pixelclock = { 33500000, 33500000, 33500000 },
 311        .hactive = { 800, 800, 800 },
 312        .hfront_porch = {  164, 164, 164 },
 313        .hback_porch = { 89, 89, 89 },
 314        .hsync_len = { 10, 10, 10 },
 315        .vactive = { 480, 480, 480 },
 316        .vfront_porch = { 10, 10, 10 },
 317        .vback_porch = { 23, 23, 23 },
 318        .vsync_len = { 10, 10, 10 },
 319        .flags = DISPLAY_FLAGS_DE_LOW,
 320};
 321
 322static const struct seiko_panel_desc seiko_43wvf1g = {
 323        .timings = &seiko_43wvf1g_timing,
 324        .num_timings = 1,
 325        .bpc = 8,
 326        .size = {
 327                .width = 93,
 328                .height = 57,
 329        },
 330        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 331        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
 332};
 333
 334static const struct of_device_id platform_of_match[] = {
 335        {
 336                .compatible = "sii,43wvf1g",
 337                .data = &seiko_43wvf1g,
 338        }, {
 339                /* sentinel */
 340        }
 341};
 342MODULE_DEVICE_TABLE(of, platform_of_match);
 343
 344static int seiko_panel_platform_probe(struct platform_device *pdev)
 345{
 346        const struct of_device_id *id;
 347
 348        id = of_match_node(platform_of_match, pdev->dev.of_node);
 349        if (!id)
 350                return -ENODEV;
 351
 352        return seiko_panel_probe(&pdev->dev, id->data);
 353}
 354
 355static struct platform_driver seiko_panel_platform_driver = {
 356        .driver = {
 357                .name = "seiko_panel",
 358                .of_match_table = platform_of_match,
 359        },
 360        .probe = seiko_panel_platform_probe,
 361        .remove = seiko_panel_remove,
 362        .shutdown = seiko_panel_shutdown,
 363};
 364module_platform_driver(seiko_panel_platform_driver);
 365
 366MODULE_AUTHOR("Marco Franchi <marco.franchi@nxp.com>");
 367MODULE_DESCRIPTION("Seiko 43WVF1G panel driver");
 368MODULE_LICENSE("GPL v2");
 369