root/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c

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

DEFINITIONS

This source file includes following definitions.
  1. ti_osd_panel
  2. osd101t2587_panel_disable
  3. osd101t2587_panel_unprepare
  4. osd101t2587_panel_prepare
  5. osd101t2587_panel_enable
  6. osd101t2587_panel_get_modes
  7. osd101t2587_panel_add
  8. osd101t2587_panel_probe
  9. osd101t2587_panel_remove
  10. osd101t2587_panel_shutdown

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
   4  *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
   5  */
   6 
   7 #include <linux/backlight.h>
   8 #include <linux/module.h>
   9 #include <linux/of.h>
  10 #include <linux/regulator/consumer.h>
  11 
  12 #include <drm/drm_crtc.h>
  13 #include <drm/drm_device.h>
  14 #include <drm/drm_mipi_dsi.h>
  15 #include <drm/drm_panel.h>
  16 
  17 #include <video/mipi_display.h>
  18 
  19 struct osd101t2587_panel {
  20         struct drm_panel base;
  21         struct mipi_dsi_device *dsi;
  22 
  23         struct backlight_device *backlight;
  24         struct regulator *supply;
  25 
  26         bool prepared;
  27         bool enabled;
  28 
  29         const struct drm_display_mode *default_mode;
  30 };
  31 
  32 static inline struct osd101t2587_panel *ti_osd_panel(struct drm_panel *panel)
  33 {
  34         return container_of(panel, struct osd101t2587_panel, base);
  35 }
  36 
  37 static int osd101t2587_panel_disable(struct drm_panel *panel)
  38 {
  39         struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
  40         int ret;
  41 
  42         if (!osd101t2587->enabled)
  43                 return 0;
  44 
  45         backlight_disable(osd101t2587->backlight);
  46 
  47         ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);
  48 
  49         osd101t2587->enabled = false;
  50 
  51         return ret;
  52 }
  53 
  54 static int osd101t2587_panel_unprepare(struct drm_panel *panel)
  55 {
  56         struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
  57 
  58         if (!osd101t2587->prepared)
  59                 return 0;
  60 
  61         regulator_disable(osd101t2587->supply);
  62         osd101t2587->prepared = false;
  63 
  64         return 0;
  65 }
  66 
  67 static int osd101t2587_panel_prepare(struct drm_panel *panel)
  68 {
  69         struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
  70         int ret;
  71 
  72         if (osd101t2587->prepared)
  73                 return 0;
  74 
  75         ret = regulator_enable(osd101t2587->supply);
  76         if (!ret)
  77                 osd101t2587->prepared = true;
  78 
  79         return ret;
  80 }
  81 
  82 static int osd101t2587_panel_enable(struct drm_panel *panel)
  83 {
  84         struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
  85         int ret;
  86 
  87         if (osd101t2587->enabled)
  88                 return 0;
  89 
  90         ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
  91         if (ret)
  92                 return ret;
  93 
  94         backlight_enable(osd101t2587->backlight);
  95 
  96         osd101t2587->enabled = true;
  97 
  98         return ret;
  99 }
 100 
 101 static const struct drm_display_mode default_mode_osd101t2587 = {
 102         .clock = 164400,
 103         .hdisplay = 1920,
 104         .hsync_start = 1920 + 152,
 105         .hsync_end = 1920 + 152 + 52,
 106         .htotal = 1920 + 152 + 52 + 20,
 107         .vdisplay = 1200,
 108         .vsync_start = 1200 + 24,
 109         .vsync_end = 1200 + 24 + 6,
 110         .vtotal = 1200 + 24 + 6 + 48,
 111         .vrefresh = 60,
 112         .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 113 };
 114 
 115 static int osd101t2587_panel_get_modes(struct drm_panel *panel)
 116 {
 117         struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
 118         struct drm_display_mode *mode;
 119 
 120         mode = drm_mode_duplicate(panel->drm, osd101t2587->default_mode);
 121         if (!mode) {
 122                 dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
 123                         osd101t2587->default_mode->hdisplay,
 124                         osd101t2587->default_mode->vdisplay,
 125                         osd101t2587->default_mode->vrefresh);
 126                 return -ENOMEM;
 127         }
 128 
 129         drm_mode_set_name(mode);
 130 
 131         drm_mode_probed_add(panel->connector, mode);
 132 
 133         panel->connector->display_info.width_mm = 217;
 134         panel->connector->display_info.height_mm = 136;
 135 
 136         return 1;
 137 }
 138 
 139 static const struct drm_panel_funcs osd101t2587_panel_funcs = {
 140         .disable = osd101t2587_panel_disable,
 141         .unprepare = osd101t2587_panel_unprepare,
 142         .prepare = osd101t2587_panel_prepare,
 143         .enable = osd101t2587_panel_enable,
 144         .get_modes = osd101t2587_panel_get_modes,
 145 };
 146 
 147 static const struct of_device_id osd101t2587_of_match[] = {
 148         {
 149                 .compatible = "osddisplays,osd101t2587-53ts",
 150                 .data = &default_mode_osd101t2587,
 151         }, {
 152                 /* sentinel */
 153         }
 154 };
 155 MODULE_DEVICE_TABLE(of, osd101t2587_of_match);
 156 
 157 static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587)
 158 {
 159         struct device *dev = &osd101t2587->dsi->dev;
 160 
 161         osd101t2587->supply = devm_regulator_get(dev, "power");
 162         if (IS_ERR(osd101t2587->supply))
 163                 return PTR_ERR(osd101t2587->supply);
 164 
 165         osd101t2587->backlight = devm_of_find_backlight(dev);
 166         if (IS_ERR(osd101t2587->backlight))
 167                 return PTR_ERR(osd101t2587->backlight);
 168 
 169         drm_panel_init(&osd101t2587->base);
 170         osd101t2587->base.funcs = &osd101t2587_panel_funcs;
 171         osd101t2587->base.dev = &osd101t2587->dsi->dev;
 172 
 173         return drm_panel_add(&osd101t2587->base);
 174 }
 175 
 176 static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi)
 177 {
 178         struct osd101t2587_panel *osd101t2587;
 179         const struct of_device_id *id;
 180         int ret;
 181 
 182         id = of_match_node(osd101t2587_of_match, dsi->dev.of_node);
 183         if (!id)
 184                 return -ENODEV;
 185 
 186         dsi->lanes = 4;
 187         dsi->format = MIPI_DSI_FMT_RGB888;
 188         dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
 189                           MIPI_DSI_MODE_VIDEO_BURST |
 190                           MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 191                           MIPI_DSI_MODE_EOT_PACKET;
 192 
 193         osd101t2587 = devm_kzalloc(&dsi->dev, sizeof(*osd101t2587), GFP_KERNEL);
 194         if (!osd101t2587)
 195                 return -ENOMEM;
 196 
 197         mipi_dsi_set_drvdata(dsi, osd101t2587);
 198 
 199         osd101t2587->dsi = dsi;
 200         osd101t2587->default_mode = id->data;
 201 
 202         ret = osd101t2587_panel_add(osd101t2587);
 203         if (ret < 0)
 204                 return ret;
 205 
 206         ret = mipi_dsi_attach(dsi);
 207         if (ret)
 208                 drm_panel_remove(&osd101t2587->base);
 209 
 210         return ret;
 211 }
 212 
 213 static int osd101t2587_panel_remove(struct mipi_dsi_device *dsi)
 214 {
 215         struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
 216         int ret;
 217 
 218         ret = osd101t2587_panel_disable(&osd101t2587->base);
 219         if (ret < 0)
 220                 dev_warn(&dsi->dev, "failed to disable panel: %d\n", ret);
 221 
 222         osd101t2587_panel_unprepare(&osd101t2587->base);
 223 
 224         drm_panel_remove(&osd101t2587->base);
 225 
 226         ret = mipi_dsi_detach(dsi);
 227         if (ret < 0)
 228                 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
 229 
 230         return ret;
 231 }
 232 
 233 static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
 234 {
 235         struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
 236 
 237         osd101t2587_panel_disable(&osd101t2587->base);
 238         osd101t2587_panel_unprepare(&osd101t2587->base);
 239 }
 240 
 241 static struct mipi_dsi_driver osd101t2587_panel_driver = {
 242         .driver = {
 243                 .name = "panel-osd-osd101t2587-53ts",
 244                 .of_match_table = osd101t2587_of_match,
 245         },
 246         .probe = osd101t2587_panel_probe,
 247         .remove = osd101t2587_panel_remove,
 248         .shutdown = osd101t2587_panel_shutdown,
 249 };
 250 module_mipi_dsi_driver(osd101t2587_panel_driver);
 251 
 252 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
 253 MODULE_DESCRIPTION("OSD101T2587-53TS DSI panel");
 254 MODULE_LICENSE("GPL v2");

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