Lines Matching +full:panel +full:- +full:mipi +full:- +full:dbi +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0
3 * NewVision NV3052C IPS LCD panel driver
12 #include <linux/media-bus-format.h>
17 #include <linux/spi/spi.h>
39 struct drm_panel panel; member
40 struct mipi_dbi dbi; member
257 { 0x23, 0x20 }, // RGB interface control: DE MODE PCLK-N
436 static inline struct nv3052c *to_nv3052c(struct drm_panel *panel) in to_nv3052c() argument
438 return container_of(panel, struct nv3052c, panel); in to_nv3052c()
441 static int nv3052c_prepare(struct drm_panel *panel) in nv3052c_prepare() argument
443 struct nv3052c *priv = to_nv3052c(panel); in nv3052c_prepare()
444 const struct nv3052c_reg *panel_regs = priv->panel_info->panel_regs; in nv3052c_prepare()
445 unsigned int panel_regs_len = priv->panel_info->panel_regs_len; in nv3052c_prepare()
446 struct mipi_dbi *dbi = &priv->dbi; in nv3052c_prepare() local
450 err = regulator_enable(priv->supply); in nv3052c_prepare()
452 dev_err(priv->dev, "Failed to enable power supply: %d\n", err); in nv3052c_prepare()
457 gpiod_set_value_cansleep(priv->reset_gpio, 1); in nv3052c_prepare()
459 gpiod_set_value_cansleep(priv->reset_gpio, 0); in nv3052c_prepare()
463 err = mipi_dbi_command(dbi, panel_regs[i].cmd, in nv3052c_prepare()
467 dev_err(priv->dev, "Unable to set register: %d\n", err); in nv3052c_prepare()
472 err = mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); in nv3052c_prepare()
474 dev_err(priv->dev, "Unable to exit sleep mode: %d\n", err); in nv3052c_prepare()
481 regulator_disable(priv->supply); in nv3052c_prepare()
485 static int nv3052c_unprepare(struct drm_panel *panel) in nv3052c_unprepare() argument
487 struct nv3052c *priv = to_nv3052c(panel); in nv3052c_unprepare()
488 struct mipi_dbi *dbi = &priv->dbi; in nv3052c_unprepare() local
491 err = mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE); in nv3052c_unprepare()
493 dev_err(priv->dev, "Unable to enter sleep mode: %d\n", err); in nv3052c_unprepare()
495 gpiod_set_value_cansleep(priv->reset_gpio, 1); in nv3052c_unprepare()
496 regulator_disable(priv->supply); in nv3052c_unprepare()
501 static int nv3052c_enable(struct drm_panel *panel) in nv3052c_enable() argument
503 struct nv3052c *priv = to_nv3052c(panel); in nv3052c_enable()
504 struct mipi_dbi *dbi = &priv->dbi; in nv3052c_enable() local
507 err = mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); in nv3052c_enable()
509 dev_err(priv->dev, "Unable to enable display: %d\n", err); in nv3052c_enable()
513 if (panel->backlight) { in nv3052c_enable()
521 static int nv3052c_disable(struct drm_panel *panel) in nv3052c_disable() argument
523 struct nv3052c *priv = to_nv3052c(panel); in nv3052c_disable()
524 struct mipi_dbi *dbi = &priv->dbi; in nv3052c_disable() local
527 err = mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF); in nv3052c_disable()
529 dev_err(priv->dev, "Unable to disable display: %d\n", err); in nv3052c_disable()
536 static int nv3052c_get_modes(struct drm_panel *panel, in nv3052c_get_modes() argument
539 struct nv3052c *priv = to_nv3052c(panel); in nv3052c_get_modes()
540 const struct nv3052c_panel_info *panel_info = priv->panel_info; in nv3052c_get_modes()
544 for (i = 0; i < panel_info->num_modes; i++) { in nv3052c_get_modes()
545 mode = drm_mode_duplicate(connector->dev, in nv3052c_get_modes()
546 &panel_info->display_modes[i]); in nv3052c_get_modes()
548 return -ENOMEM; in nv3052c_get_modes()
552 mode->type = DRM_MODE_TYPE_DRIVER; in nv3052c_get_modes()
553 if (panel_info->num_modes == 1) in nv3052c_get_modes()
554 mode->type |= DRM_MODE_TYPE_PREFERRED; in nv3052c_get_modes()
559 connector->display_info.bpc = 8; in nv3052c_get_modes()
560 connector->display_info.width_mm = panel_info->width_mm; in nv3052c_get_modes()
561 connector->display_info.height_mm = panel_info->height_mm; in nv3052c_get_modes()
563 drm_display_info_set_bus_formats(&connector->display_info, in nv3052c_get_modes()
564 &panel_info->bus_format, 1); in nv3052c_get_modes()
565 connector->display_info.bus_flags = panel_info->bus_flags; in nv3052c_get_modes()
567 return panel_info->num_modes; in nv3052c_get_modes()
578 static int nv3052c_probe(struct spi_device *spi) in nv3052c_probe() argument
580 struct device *dev = &spi->dev; in nv3052c_probe()
586 return -ENOMEM; in nv3052c_probe()
588 priv->dev = dev; in nv3052c_probe()
590 priv->panel_info = of_device_get_match_data(dev); in nv3052c_probe()
591 if (!priv->panel_info) in nv3052c_probe()
592 return -EINVAL; in nv3052c_probe()
594 priv->supply = devm_regulator_get(dev, "power"); in nv3052c_probe()
595 if (IS_ERR(priv->supply)) in nv3052c_probe()
596 return dev_err_probe(dev, PTR_ERR(priv->supply), "Failed to get power supply\n"); in nv3052c_probe()
598 priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in nv3052c_probe()
599 if (IS_ERR(priv->reset_gpio)) in nv3052c_probe()
600 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), "Failed to get reset GPIO\n"); in nv3052c_probe()
602 err = mipi_dbi_spi_init(spi, &priv->dbi, NULL); in nv3052c_probe()
604 return dev_err_probe(dev, err, "MIPI DBI init failed\n"); in nv3052c_probe()
606 priv->dbi.read_commands = NULL; in nv3052c_probe()
608 spi_set_drvdata(spi, priv); in nv3052c_probe()
610 drm_panel_init(&priv->panel, dev, &nv3052c_funcs, in nv3052c_probe()
613 err = drm_panel_of_backlight(&priv->panel); in nv3052c_probe()
617 drm_panel_add(&priv->panel); in nv3052c_probe()
622 static void nv3052c_remove(struct spi_device *spi) in nv3052c_remove() argument
624 struct nv3052c *priv = spi_get_drvdata(spi); in nv3052c_remove()
626 drm_panel_remove(&priv->panel); in nv3052c_remove()
627 drm_panel_disable(&priv->panel); in nv3052c_remove()
628 drm_panel_unprepare(&priv->panel); in nv3052c_remove()
700 MODULE_DEVICE_TABLE(spi, nv3052c_ids);