1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/array_size.h> 4 #include <linux/delay.h> 5 #include <linux/err.h> 6 #include <linux/gpio/consumer.h> 7 #include <linux/mod_devicetable.h> 8 #include <linux/module.h> 9 #include <linux/property.h> 10 #include <linux/regulator/consumer.h> 11 12 #include <video/mipi_display.h> 13 14 #include <drm/drm_mipi_dsi.h> 15 #include <drm/drm_modes.h> 16 #include <drm/drm_panel.h> 17 18 #define R69328_MACP 0xb0 /* Manufacturer Access CMD Protect */ 19 #define R69328_MACP_ON 0x03 20 #define R69328_MACP_OFF 0x04 21 22 #define R69328_GAMMA_SET_A 0xc8 /* Gamma Setting A */ 23 #define R69328_GAMMA_SET_B 0xc9 /* Gamma Setting B */ 24 #define R69328_GAMMA_SET_C 0xca /* Gamma Setting C */ 25 26 #define R69328_POWER_SET 0xd1 27 28 struct renesas_r69328 { 29 struct drm_panel panel; 30 struct mipi_dsi_device *dsi; 31 32 struct regulator *vdd_supply; 33 struct regulator *vddio_supply; 34 struct gpio_desc *reset_gpio; 35 36 bool prepared; 37 }; 38 39 static inline struct renesas_r69328 *to_renesas_r69328(struct drm_panel *panel) 40 { 41 return container_of(panel, struct renesas_r69328, panel); 42 } 43 44 static void renesas_r69328_reset(struct renesas_r69328 *priv) 45 { 46 gpiod_set_value_cansleep(priv->reset_gpio, 1); 47 usleep_range(10000, 11000); 48 gpiod_set_value_cansleep(priv->reset_gpio, 0); 49 usleep_range(2000, 3000); 50 } 51 52 static int renesas_r69328_prepare(struct drm_panel *panel) 53 { 54 struct renesas_r69328 *priv = to_renesas_r69328(panel); 55 struct device *dev = &priv->dsi->dev; 56 int ret; 57 58 if (priv->prepared) 59 return 0; 60 61 ret = regulator_enable(priv->vdd_supply); 62 if (ret) { 63 dev_err(dev, "failed to enable vdd power supply\n"); 64 return ret; 65 } 66 67 usleep_range(10000, 11000); 68 69 ret = regulator_enable(priv->vddio_supply); 70 if (ret < 0) { 71 dev_err(dev, "failed to enable vddio power supply\n"); 72 return ret; 73 } 74 75 usleep_range(10000, 11000); 76 77 renesas_r69328_reset(priv); 78 79 priv->prepared = true; 80 return 0; 81 } 82 83 static int renesas_r69328_enable(struct drm_panel *panel) 84 { 85 struct renesas_r69328 *priv = to_renesas_r69328(panel); 86 struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; 87 88 /* Set address mode */ 89 mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); 90 mipi_dsi_dcs_set_pixel_format_multi(&ctx, MIPI_DCS_PIXEL_FMT_24BIT << 4); 91 mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); 92 93 mipi_dsi_msleep(&ctx, 100); 94 95 /* MACP Off */ 96 mipi_dsi_generic_write_seq_multi(&ctx, R69328_MACP, R69328_MACP_OFF); 97 98 mipi_dsi_generic_write_seq_multi(&ctx, R69328_POWER_SET, 0x14, 0x1d, 99 0x21, 0x67, 0x11, 0x9a); 100 101 mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_A, 0x00, 0x1a, 102 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 103 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, 104 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 105 0x11, 0x18, 0x1e, 0x1c, 0x00); 106 107 mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_B, 0x00, 0x1a, 108 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 109 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, 110 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 111 0x11, 0x18, 0x1e, 0x1c, 0x00); 112 113 mipi_dsi_generic_write_seq_multi(&ctx, R69328_GAMMA_SET_C, 0x00, 0x1a, 114 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 115 0x11, 0x18, 0x1e, 0x1c, 0x00, 0x00, 0x1a, 116 0x20, 0x28, 0x25, 0x24, 0x26, 0x15, 0x13, 117 0x11, 0x18, 0x1e, 0x1c, 0x00); 118 119 /* MACP On */ 120 mipi_dsi_generic_write_seq_multi(&ctx, R69328_MACP, R69328_MACP_ON); 121 122 mipi_dsi_dcs_set_display_on_multi(&ctx); 123 mipi_dsi_msleep(&ctx, 50); 124 125 return 0; 126 } 127 128 static int renesas_r69328_disable(struct drm_panel *panel) 129 { 130 struct renesas_r69328 *priv = to_renesas_r69328(panel); 131 struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi }; 132 133 mipi_dsi_dcs_set_display_off_multi(&ctx); 134 mipi_dsi_msleep(&ctx, 60); 135 mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); 136 137 return 0; 138 } 139 140 static int renesas_r69328_unprepare(struct drm_panel *panel) 141 { 142 struct renesas_r69328 *priv = to_renesas_r69328(panel); 143 144 if (!priv->prepared) 145 return 0; 146 147 gpiod_set_value_cansleep(priv->reset_gpio, 1); 148 149 usleep_range(5000, 6000); 150 151 regulator_disable(priv->vddio_supply); 152 regulator_disable(priv->vdd_supply); 153 154 priv->prepared = false; 155 return 0; 156 } 157 158 static const struct drm_display_mode renesas_r69328_mode = { 159 .clock = (720 + 92 + 62 + 4) * (1280 + 6 + 3 + 1) * 60 / 1000, 160 .hdisplay = 720, 161 .hsync_start = 720 + 92, 162 .hsync_end = 720 + 92 + 62, 163 .htotal = 720 + 92 + 62 + 4, 164 .vdisplay = 1280, 165 .vsync_start = 1280 + 6, 166 .vsync_end = 1280 + 6 + 3, 167 .vtotal = 1280 + 6 + 3 + 1, 168 .width_mm = 59, 169 .height_mm = 105, 170 }; 171 172 static int renesas_r69328_get_modes(struct drm_panel *panel, 173 struct drm_connector *connector) 174 { 175 struct drm_display_mode *mode; 176 177 mode = drm_mode_duplicate(connector->dev, &renesas_r69328_mode); 178 if (!mode) 179 return -ENOMEM; 180 181 drm_mode_set_name(mode); 182 183 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 184 connector->display_info.width_mm = mode->width_mm; 185 connector->display_info.height_mm = mode->height_mm; 186 drm_mode_probed_add(connector, mode); 187 188 return 1; 189 } 190 191 static const struct drm_panel_funcs renesas_r69328_panel_funcs = { 192 .prepare = renesas_r69328_prepare, 193 .enable = renesas_r69328_enable, 194 .disable = renesas_r69328_disable, 195 .unprepare = renesas_r69328_unprepare, 196 .get_modes = renesas_r69328_get_modes, 197 }; 198 199 static int renesas_r69328_probe(struct mipi_dsi_device *dsi) 200 { 201 struct device *dev = &dsi->dev; 202 struct renesas_r69328 *priv; 203 int ret; 204 205 priv = devm_drm_panel_alloc(dev, struct renesas_r69328, panel, 206 &renesas_r69328_panel_funcs, 207 DRM_MODE_CONNECTOR_DSI); 208 if (IS_ERR(priv)) 209 return PTR_ERR(priv); 210 211 priv->vdd_supply = devm_regulator_get(dev, "vdd"); 212 if (IS_ERR(priv->vdd_supply)) 213 return dev_err_probe(dev, PTR_ERR(priv->vdd_supply), 214 "Failed to get vdd-supply\n"); 215 216 priv->vddio_supply = devm_regulator_get(dev, "vddio"); 217 if (IS_ERR(priv->vddio_supply)) 218 return dev_err_probe(dev, PTR_ERR(priv->vddio_supply), 219 "Failed to get vddio-supply\n"); 220 221 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", 222 GPIOD_OUT_LOW); 223 if (IS_ERR(priv->reset_gpio)) 224 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), 225 "Failed to get reset-gpios\n"); 226 227 priv->dsi = dsi; 228 mipi_dsi_set_drvdata(dsi, priv); 229 230 dsi->lanes = 4; 231 dsi->format = MIPI_DSI_FMT_RGB888; 232 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | 233 MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; 234 235 ret = drm_panel_of_backlight(&priv->panel); 236 if (ret) 237 return dev_err_probe(dev, ret, "Failed to get backlight\n"); 238 239 drm_panel_add(&priv->panel); 240 241 ret = mipi_dsi_attach(dsi); 242 if (ret) { 243 drm_panel_remove(&priv->panel); 244 return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); 245 } 246 247 return 0; 248 } 249 250 static void renesas_r69328_remove(struct mipi_dsi_device *dsi) 251 { 252 struct renesas_r69328 *priv = mipi_dsi_get_drvdata(dsi); 253 int ret; 254 255 ret = mipi_dsi_detach(dsi); 256 if (ret) 257 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); 258 259 drm_panel_remove(&priv->panel); 260 } 261 262 static const struct of_device_id renesas_r69328_of_match[] = { 263 { .compatible = "jdi,dx12d100vm0eaa" }, 264 { /* sentinel */ } 265 }; 266 MODULE_DEVICE_TABLE(of, renesas_r69328_of_match); 267 268 static struct mipi_dsi_driver renesas_r69328_driver = { 269 .probe = renesas_r69328_probe, 270 .remove = renesas_r69328_remove, 271 .driver = { 272 .name = "panel-renesas-r69328", 273 .of_match_table = renesas_r69328_of_match, 274 }, 275 }; 276 module_mipi_dsi_driver(renesas_r69328_driver); 277 278 MODULE_AUTHOR("Maxim Schwalm <maxim.schwalm@gmail.com>"); 279 MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); 280 MODULE_DESCRIPTION("Renesas R69328-based panel driver"); 281 MODULE_LICENSE("GPL"); 282