0001
0002
0003
0004
0005
0006
0007 #include <linux/delay.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/regulator/consumer.h>
0012
0013 #include <video/mipi_display.h>
0014
0015 #include <drm/drm_mipi_dsi.h>
0016 #include <drm/drm_modes.h>
0017 #include <drm/drm_panel.h>
0018
0019 struct sharp_ls060 {
0020 struct drm_panel panel;
0021 struct mipi_dsi_device *dsi;
0022 struct regulator *vddi_supply;
0023 struct regulator *vddh_supply;
0024 struct regulator *avdd_supply;
0025 struct regulator *avee_supply;
0026 struct gpio_desc *reset_gpio;
0027 bool prepared;
0028 };
0029
0030 static inline struct sharp_ls060 *to_sharp_ls060(struct drm_panel *panel)
0031 {
0032 return container_of(panel, struct sharp_ls060, panel);
0033 }
0034
0035 #define dsi_dcs_write_seq(dsi, seq...) ({ \
0036 static const u8 d[] = { seq }; \
0037 \
0038 mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
0039 })
0040
0041 static void sharp_ls060_reset(struct sharp_ls060 *ctx)
0042 {
0043 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
0044 usleep_range(10000, 11000);
0045 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
0046 usleep_range(10000, 11000);
0047 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
0048 usleep_range(10000, 11000);
0049 }
0050
0051 static int sharp_ls060_on(struct sharp_ls060 *ctx)
0052 {
0053 struct mipi_dsi_device *dsi = ctx->dsi;
0054 struct device *dev = &dsi->dev;
0055 int ret;
0056
0057 dsi->mode_flags |= MIPI_DSI_MODE_LPM;
0058
0059 ret = dsi_dcs_write_seq(dsi, 0xbb, 0x13);
0060 if (ret < 0) {
0061 dev_err(dev, "Failed to send command: %d\n", ret);
0062 return ret;
0063 }
0064
0065 ret = dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START);
0066 if (ret < 0) {
0067 dev_err(dev, "Failed to send command: %d\n", ret);
0068 return ret;
0069 }
0070
0071 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
0072 if (ret < 0) {
0073 dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
0074 return ret;
0075 }
0076 msleep(120);
0077
0078 ret = mipi_dsi_dcs_set_display_on(dsi);
0079 if (ret < 0) {
0080 dev_err(dev, "Failed to set display on: %d\n", ret);
0081 return ret;
0082 }
0083 msleep(50);
0084
0085 return 0;
0086 }
0087
0088 static int sharp_ls060_off(struct sharp_ls060 *ctx)
0089 {
0090 struct mipi_dsi_device *dsi = ctx->dsi;
0091 struct device *dev = &dsi->dev;
0092 int ret;
0093
0094 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
0095
0096 ret = mipi_dsi_dcs_set_display_off(dsi);
0097 if (ret < 0) {
0098 dev_err(dev, "Failed to set display off: %d\n", ret);
0099 return ret;
0100 }
0101 usleep_range(2000, 3000);
0102
0103 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
0104 if (ret < 0) {
0105 dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
0106 return ret;
0107 }
0108 msleep(121);
0109
0110 return 0;
0111 }
0112
0113 static int sharp_ls060_prepare(struct drm_panel *panel)
0114 {
0115 struct sharp_ls060 *ctx = to_sharp_ls060(panel);
0116 struct device *dev = &ctx->dsi->dev;
0117 int ret;
0118
0119 if (ctx->prepared)
0120 return 0;
0121
0122 ret = regulator_enable(ctx->vddi_supply);
0123 if (ret < 0)
0124 return ret;
0125
0126 ret = regulator_enable(ctx->avdd_supply);
0127 if (ret < 0)
0128 goto err_avdd;
0129
0130 usleep_range(1000, 2000);
0131
0132 ret = regulator_enable(ctx->avee_supply);
0133 if (ret < 0)
0134 goto err_avee;
0135
0136 usleep_range(10000, 11000);
0137
0138 ret = regulator_enable(ctx->vddh_supply);
0139 if (ret < 0)
0140 goto err_vddh;
0141
0142 usleep_range(10000, 11000);
0143
0144 sharp_ls060_reset(ctx);
0145
0146 ret = sharp_ls060_on(ctx);
0147 if (ret < 0) {
0148 dev_err(dev, "Failed to initialize panel: %d\n", ret);
0149 goto err_on;
0150 }
0151
0152 ctx->prepared = true;
0153
0154 return 0;
0155
0156 err_on:
0157 regulator_disable(ctx->vddh_supply);
0158
0159 usleep_range(10000, 11000);
0160
0161 err_vddh:
0162 regulator_disable(ctx->avee_supply);
0163
0164 err_avee:
0165 regulator_disable(ctx->avdd_supply);
0166
0167 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
0168
0169 err_avdd:
0170 regulator_disable(ctx->vddi_supply);
0171
0172 return ret;
0173 }
0174
0175 static int sharp_ls060_unprepare(struct drm_panel *panel)
0176 {
0177 struct sharp_ls060 *ctx = to_sharp_ls060(panel);
0178 struct device *dev = &ctx->dsi->dev;
0179 int ret;
0180
0181 if (!ctx->prepared)
0182 return 0;
0183
0184 ret = sharp_ls060_off(ctx);
0185 if (ret < 0)
0186 dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
0187
0188 regulator_disable(ctx->vddh_supply);
0189
0190 usleep_range(10000, 11000);
0191
0192 regulator_disable(ctx->avee_supply);
0193 regulator_disable(ctx->avdd_supply);
0194
0195 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
0196
0197 regulator_disable(ctx->vddi_supply);
0198
0199 ctx->prepared = false;
0200 return 0;
0201 }
0202
0203 static const struct drm_display_mode sharp_ls060_mode = {
0204 .clock = (1080 + 96 + 16 + 64) * (1920 + 4 + 1 + 16) * 60 / 1000,
0205 .hdisplay = 1080,
0206 .hsync_start = 1080 + 96,
0207 .hsync_end = 1080 + 96 + 16,
0208 .htotal = 1080 + 96 + 16 + 64,
0209 .vdisplay = 1920,
0210 .vsync_start = 1920 + 4,
0211 .vsync_end = 1920 + 4 + 1,
0212 .vtotal = 1920 + 4 + 1 + 16,
0213 .width_mm = 75,
0214 .height_mm = 132,
0215 };
0216
0217 static int sharp_ls060_get_modes(struct drm_panel *panel,
0218 struct drm_connector *connector)
0219 {
0220 struct drm_display_mode *mode;
0221
0222 mode = drm_mode_duplicate(connector->dev, &sharp_ls060_mode);
0223 if (!mode)
0224 return -ENOMEM;
0225
0226 drm_mode_set_name(mode);
0227
0228 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0229 connector->display_info.width_mm = mode->width_mm;
0230 connector->display_info.height_mm = mode->height_mm;
0231 drm_mode_probed_add(connector, mode);
0232
0233 return 1;
0234 }
0235
0236 static const struct drm_panel_funcs sharp_ls060_panel_funcs = {
0237 .prepare = sharp_ls060_prepare,
0238 .unprepare = sharp_ls060_unprepare,
0239 .get_modes = sharp_ls060_get_modes,
0240 };
0241
0242 static int sharp_ls060_probe(struct mipi_dsi_device *dsi)
0243 {
0244 struct device *dev = &dsi->dev;
0245 struct sharp_ls060 *ctx;
0246 int ret;
0247
0248 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
0249 if (!ctx)
0250 return -ENOMEM;
0251
0252 ctx->vddi_supply = devm_regulator_get(dev, "vddi");
0253 if (IS_ERR(ctx->vddi_supply))
0254 return PTR_ERR(ctx->vddi_supply);
0255
0256 ctx->vddh_supply = devm_regulator_get(dev, "vddh");
0257 if (IS_ERR(ctx->vddh_supply))
0258 return PTR_ERR(ctx->vddh_supply);
0259
0260 ctx->avdd_supply = devm_regulator_get(dev, "avdd");
0261 if (IS_ERR(ctx->avdd_supply))
0262 return PTR_ERR(ctx->avdd_supply);
0263
0264 ctx->avee_supply = devm_regulator_get(dev, "avee");
0265 if (IS_ERR(ctx->avee_supply))
0266 return PTR_ERR(ctx->avee_supply);
0267
0268 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
0269 if (IS_ERR(ctx->reset_gpio))
0270 return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
0271 "Failed to get reset-gpios\n");
0272
0273 ctx->dsi = dsi;
0274 mipi_dsi_set_drvdata(dsi, ctx);
0275
0276 dsi->lanes = 4;
0277 dsi->format = MIPI_DSI_FMT_RGB888;
0278 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
0279 MIPI_DSI_MODE_NO_EOT_PACKET |
0280 MIPI_DSI_CLOCK_NON_CONTINUOUS;
0281
0282 drm_panel_init(&ctx->panel, dev, &sharp_ls060_panel_funcs,
0283 DRM_MODE_CONNECTOR_DSI);
0284
0285 ret = drm_panel_of_backlight(&ctx->panel);
0286 if (ret)
0287 return dev_err_probe(dev, ret, "Failed to get backlight\n");
0288
0289 drm_panel_add(&ctx->panel);
0290
0291 ret = mipi_dsi_attach(dsi);
0292 if (ret < 0) {
0293 dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
0294 drm_panel_remove(&ctx->panel);
0295 return ret;
0296 }
0297
0298 return 0;
0299 }
0300
0301 static int sharp_ls060_remove(struct mipi_dsi_device *dsi)
0302 {
0303 struct sharp_ls060 *ctx = mipi_dsi_get_drvdata(dsi);
0304 int ret;
0305
0306 ret = mipi_dsi_detach(dsi);
0307 if (ret < 0)
0308 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
0309
0310 drm_panel_remove(&ctx->panel);
0311
0312 return 0;
0313 }
0314
0315 static const struct of_device_id sharp_ls060t1sx01_of_match[] = {
0316 { .compatible = "sharp,ls060t1sx01" },
0317 { }
0318 };
0319 MODULE_DEVICE_TABLE(of, sharp_ls060t1sx01_of_match);
0320
0321 static struct mipi_dsi_driver sharp_ls060_driver = {
0322 .probe = sharp_ls060_probe,
0323 .remove = sharp_ls060_remove,
0324 .driver = {
0325 .name = "panel-sharp-ls060t1sx01",
0326 .of_match_table = sharp_ls060t1sx01_of_match,
0327 },
0328 };
0329 module_mipi_dsi_driver(sharp_ls060_driver);
0330
0331 MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
0332 MODULE_DESCRIPTION("DRM driver for Sharp LS060T1SX01 1080p video mode dsi panel");
0333 MODULE_LICENSE("GPL v2");