Message ID | 20190608112342.64416-2-jitao.shi@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] dt-bindings: display: panel: add AUO kd101n80-45na panel bindings | expand |
Hi Jitao. Thanks for another panel driver. The comments for the panel-boe-tv101wum-nl6 diver to extent applies to this driver too. Please address these and I will do a proper review of the next version. I notice that error handlign is a little bit less in this driver. consier what approch to use and see if you can align between these drivers, and if in doubt use panel-simple as your role model. Sam On Sat, Jun 08, 2019 at 07:23:42PM +0800, Jitao Shi wrote: > Add driver for AUO kd101n80-45na panel. > This panel supports the resolution 1200x1920, dsi video mode > and 4 lanes. > > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> > --- > drivers/gpu/drm/panel/Kconfig | 10 + > drivers/gpu/drm/panel/Makefile | 1 + > .../gpu/drm/panel/panel-auo-kd101n80-45na.c | 352 ++++++++++++++++++ > 3 files changed, 363 insertions(+) > create mode 100644 drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index e36dbb4df867..f5cd5af9ce42 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -272,4 +272,14 @@ config DRM_PANEL_TRULY_NT35597_WQXGA > help > Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI > Video Mode panel > + > +config DRM_PANEL_AUO_KD101N80_45NA > + tristate "AUO KD101N80_45NA 1200x1920 panel" > + depends on OF > + depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > + help > + Say Y here if you want to support for AUO KD101N80_45NA WUXGA PANEL > + DSI Video Mode panel > + > endmenu > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 78e3dc376bdd..1056933bdf2e 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -28,3 +28,4 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o > obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o > obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o > obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o > +obj-$(CONFIG_DRM_PANEL_AUO_KD101N80_45NA) += panel-auo-kd101n80-45na.o > diff --git a/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c b/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c > new file mode 100644 > index 000000000000..ab7bfc059e8a > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c > @@ -0,0 +1,352 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2018 MediaTek Inc. > + * Author: Jitao Shi <jitao.shi@mediatek.com> > + */ > + > +#include <linux/backlight.h> > +#include <linux/gpio/consumer.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/regulator/consumer.h> > + > +#include <drm/drmP.h> > +#include <drm/drm_crtc.h> > +#include <drm/drm_mipi_dsi.h> > +#include <drm/drm_panel.h> > + > +#include <video/mipi_display.h> > + > +struct auo_panel { > + struct drm_panel base; > + struct mipi_dsi_device *dsi; > + > + struct backlight_device *backlight; > + struct regulator *pp1800; > + struct regulator *avee; > + struct regulator *avdd; > + struct gpio_desc *enable_gpio; > + > + bool prepared; > + bool enabled; > + > + const struct drm_display_mode *mode; > +}; > + > +static inline struct auo_panel *to_auo_panel(struct drm_panel *panel) > +{ > + return container_of(panel, struct auo_panel, base); > +} > + > +static int auo_panel_init(struct auo_panel *auo) > +{ > + struct drm_panel *panel = &auo->base; > + int err; > + > + err = mipi_dsi_dcs_exit_sleep_mode(auo->dsi); > + if (err < 0) { > + DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n", > + err); > + return err; > + } > + > + /* T3.1*/ > + msleep(120); > + > + err = mipi_dsi_dcs_set_display_on(auo->dsi); > + if (err < 0) { > + DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n", > + err); > + } > + /* T3.1 + T3.2: > 200ms */ > + msleep(120); > + > + return err; > +} > + > +static int auo_panel_off(struct auo_panel *auo) > +{ > + struct mipi_dsi_device *dsi = auo->dsi; > + int ret; > + > + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; > + > + ret = mipi_dsi_dcs_set_display_off(dsi); > + if (ret < 0) > + return ret; > + > + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > +static int auo_panel_disable(struct drm_panel *panel) > +{ > + struct auo_panel *auo = to_auo_panel(panel); > + > + if (!auo->enabled) > + return 0; > + > + backlight_disable(auo->backlight); > + > + auo->enabled = false; > + > + return 0; > +} > + > +static int auo_panel_unprepare(struct drm_panel *panel) > +{ > + struct auo_panel *auo = to_auo_panel(panel); > + int ret; > + > + if (!auo->prepared) > + return 0; > + > + ret = auo_panel_off(auo); > + if (ret < 0) { > + dev_err(panel->dev, "failed to set panel off: %d\n", ret); > + return ret; > + } > + > + msleep(150); > + regulator_disable(auo->avee); > + regulator_disable(auo->avdd); > + usleep_range(5000, 7000); > + regulator_disable(auo->pp1800); > + if (auo->enable_gpio) > + gpiod_set_value(auo->enable_gpio, 0); > + > + auo->prepared = false; > + > + return 0; > +} > + > +static int auo_panel_prepare(struct drm_panel *panel) > +{ > + struct auo_panel *auo = to_auo_panel(panel); > + int ret; > + > + if (auo->prepared) > + return 0; > + > + if (auo->enable_gpio) { > + gpiod_set_value(auo->enable_gpio, 0); > + usleep_range(1000, 1500); > + } > + > + ret = regulator_enable(auo->pp1800); > + if (ret < 0) > + return ret; > + ret = regulator_enable(auo->avdd); > + if (ret < 0) > + goto poweroff1v8; > + ret = regulator_enable(auo->avee); > + if (ret < 0) > + goto poweroffavdd; > + > + if (auo->enable_gpio) { > + gpiod_set_value(auo->enable_gpio, 1); > + usleep_range(10000, 12000); > + } > + > + ret = auo_panel_init(auo); > + if (ret < 0) { > + dev_err(panel->dev, "failed to init panel: %d\n", ret); > + goto poweroff; > + } > + > + auo->prepared = true; > + > + return 0; > + > +poweroff: > + regulator_disable(auo->avee); > +poweroffavdd: > + regulator_disable(auo->avdd); > +poweroff1v8: > + usleep_range(5000, 7000); > + regulator_disable(auo->pp1800); > + if (auo->enable_gpio) > + gpiod_set_value(auo->enable_gpio, 0); > + return ret; > +} > + > +static int auo_panel_enable(struct drm_panel *panel) > +{ > + struct auo_panel *auo = to_auo_panel(panel); > + int ret; > + > + if (auo->enabled) > + return 0; > + > + ret = backlight_enable(auo->backlight); > + if (ret) { > + DRM_DEV_ERROR(panel->drm->dev, > + "Failed to enable backlight %d\n", ret); > + return ret; > + } > + > + auo->enabled = true; > + > + return 0; > +} > + > +static const struct drm_display_mode default_mode = { > + .clock = 157000, > + .hdisplay = 1200, > + .hsync_start = 1200 + 80, > + .hsync_end = 1200 + 80 + 24, > + .htotal = 1200 + 80 + 24 + 36, > + .vdisplay = 1920, > + .vsync_start = 1920 + 16, > + .vsync_end = 1920 + 16 + 4, > + .vtotal = 1920 + 16 + 4 + 16, > + .vrefresh = 60, > +}; > + > +static int auo_panel_get_modes(struct drm_panel *panel) > +{ > + struct drm_display_mode *mode; > + > + mode = drm_mode_duplicate(panel->drm, &default_mode); > + if (!mode) { > + dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n", > + default_mode.hdisplay, default_mode.vdisplay, > + default_mode.vrefresh); > + return -ENOMEM; > + } > + > + drm_mode_set_name(mode); > + > + drm_mode_probed_add(panel->connector, mode); > + > + panel->connector->display_info.width_mm = 135; > + panel->connector->display_info.height_mm = 216; > + panel->connector->display_info.bpc = 8; > + > + return 1; > +} > + > +static const struct drm_panel_funcs auo_panel_funcs = { > + .disable = auo_panel_disable, > + .unprepare = auo_panel_unprepare, > + .prepare = auo_panel_prepare, > + .enable = auo_panel_enable, > + .get_modes = auo_panel_get_modes, > +}; > + > +static int auo_panel_add(struct auo_panel *auo) > +{ > + struct device *dev = &auo->dsi->dev; > + > + auo->avdd = devm_regulator_get(dev, "avdd"); > + if (IS_ERR(auo->avdd)) > + return PTR_ERR(auo->avdd); > + > + auo->avee = devm_regulator_get(dev, "avee"); > + if (IS_ERR(auo->avee)) > + return PTR_ERR(auo->avee); > + > + auo->pp1800 = devm_regulator_get(dev, "pp1800"); > + if (IS_ERR(auo->pp1800)) > + return PTR_ERR(auo->pp1800); > + > + auo->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); > + if (IS_ERR(auo->enable_gpio)) { > + dev_err(dev, "cannot get reset-gpios %ld\n", > + PTR_ERR(auo->enable_gpio)); > + auo->enable_gpio = NULL; > + } else { > + gpiod_set_value(auo->enable_gpio, 0); > + } > + > + auo->backlight = devm_of_find_backlight(dev); > + if (IS_ERR(auo->backlight)) > + return PTR_ERR(auo->backlight); > + > + drm_panel_init(&auo->base); > + auo->base.funcs = &auo_panel_funcs; > + auo->base.dev = &auo->dsi->dev; > + > + return drm_panel_add(&auo->base); > +} > + > +static void auo_panel_del(struct auo_panel *auo) > +{ > + if (auo->base.dev) > + drm_panel_remove(&auo->base); > +} > + > +static int auo_panel_probe(struct mipi_dsi_device *dsi) > +{ > + struct auo_panel *auo; > + int ret; > + > + dsi->lanes = 4; > + dsi->format = MIPI_DSI_FMT_RGB888; > + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | > + MIPI_DSI_MODE_LPM; > + > + auo = devm_kzalloc(&dsi->dev, sizeof(*auo), GFP_KERNEL); > + if (!auo) > + return -ENOMEM; > + > + mipi_dsi_set_drvdata(dsi, auo); > + > + auo->dsi = dsi; > + > + ret = auo_panel_add(auo); > + if (ret < 0) > + return ret; > + > + return mipi_dsi_attach(dsi); > +} > + > +static int auo_panel_remove(struct mipi_dsi_device *dsi) > +{ > + struct auo_panel *auo = mipi_dsi_get_drvdata(dsi); > + int ret; > + > + ret = auo_panel_disable(&auo->base); > + if (ret < 0) > + dev_err(&dsi->dev, "failed to disable panel: %d\n", ret); > + > + ret = mipi_dsi_detach(dsi); > + if (ret < 0) > + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); > + > + auo_panel_del(auo); > + > + return 0; > +} > + > +static void auo_panel_shutdown(struct mipi_dsi_device *dsi) > +{ > + struct auo_panel *auo = mipi_dsi_get_drvdata(dsi); > + > + auo_panel_disable(&auo->base); > +} > + > +static const struct of_device_id auo_of_match[] = { > + { .compatible = "auo,kd101n80-45na", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, auo_of_match); > + > +static struct mipi_dsi_driver auo_panel_driver = { > + .driver = { > + .name = "panel-auo-kd101n80-45na", > + .of_match_table = auo_of_match, > + }, > + .probe = auo_panel_probe, > + .remove = auo_panel_remove, > + .shutdown = auo_panel_shutdown, > +}; > +module_mipi_dsi_driver(auo_panel_driver); > + > +MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>"); > +MODULE_DESCRIPTION("AUO kd101n80-45na wuxga (1200x1920) video mode panel driver"); > +MODULE_LICENSE("GPL v2"); > + > -- > 2.21.0 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index e36dbb4df867..f5cd5af9ce42 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -272,4 +272,14 @@ config DRM_PANEL_TRULY_NT35597_WQXGA help Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI Video Mode panel + +config DRM_PANEL_AUO_KD101N80_45NA + tristate "AUO KD101N80_45NA 1200x1920 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to support for AUO KD101N80_45NA WUXGA PANEL + DSI Video Mode panel + endmenu diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 78e3dc376bdd..1056933bdf2e 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -28,3 +28,4 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o +obj-$(CONFIG_DRM_PANEL_AUO_KD101N80_45NA) += panel-auo-kd101n80-45na.o diff --git a/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c b/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c new file mode 100644 index 000000000000..ab7bfc059e8a --- /dev/null +++ b/drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Jitao Shi <jitao.shi@mediatek.com> + */ + +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +struct auo_panel { + struct drm_panel base; + struct mipi_dsi_device *dsi; + + struct backlight_device *backlight; + struct regulator *pp1800; + struct regulator *avee; + struct regulator *avdd; + struct gpio_desc *enable_gpio; + + bool prepared; + bool enabled; + + const struct drm_display_mode *mode; +}; + +static inline struct auo_panel *to_auo_panel(struct drm_panel *panel) +{ + return container_of(panel, struct auo_panel, base); +} + +static int auo_panel_init(struct auo_panel *auo) +{ + struct drm_panel *panel = &auo->base; + int err; + + err = mipi_dsi_dcs_exit_sleep_mode(auo->dsi); + if (err < 0) { + DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n", + err); + return err; + } + + /* T3.1*/ + msleep(120); + + err = mipi_dsi_dcs_set_display_on(auo->dsi); + if (err < 0) { + DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n", + err); + } + /* T3.1 + T3.2: > 200ms */ + msleep(120); + + return err; +} + +static int auo_panel_off(struct auo_panel *auo) +{ + struct mipi_dsi_device *dsi = auo->dsi; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) + return ret; + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) + return ret; + + return 0; +} + +static int auo_panel_disable(struct drm_panel *panel) +{ + struct auo_panel *auo = to_auo_panel(panel); + + if (!auo->enabled) + return 0; + + backlight_disable(auo->backlight); + + auo->enabled = false; + + return 0; +} + +static int auo_panel_unprepare(struct drm_panel *panel) +{ + struct auo_panel *auo = to_auo_panel(panel); + int ret; + + if (!auo->prepared) + return 0; + + ret = auo_panel_off(auo); + if (ret < 0) { + dev_err(panel->dev, "failed to set panel off: %d\n", ret); + return ret; + } + + msleep(150); + regulator_disable(auo->avee); + regulator_disable(auo->avdd); + usleep_range(5000, 7000); + regulator_disable(auo->pp1800); + if (auo->enable_gpio) + gpiod_set_value(auo->enable_gpio, 0); + + auo->prepared = false; + + return 0; +} + +static int auo_panel_prepare(struct drm_panel *panel) +{ + struct auo_panel *auo = to_auo_panel(panel); + int ret; + + if (auo->prepared) + return 0; + + if (auo->enable_gpio) { + gpiod_set_value(auo->enable_gpio, 0); + usleep_range(1000, 1500); + } + + ret = regulator_enable(auo->pp1800); + if (ret < 0) + return ret; + ret = regulator_enable(auo->avdd); + if (ret < 0) + goto poweroff1v8; + ret = regulator_enable(auo->avee); + if (ret < 0) + goto poweroffavdd; + + if (auo->enable_gpio) { + gpiod_set_value(auo->enable_gpio, 1); + usleep_range(10000, 12000); + } + + ret = auo_panel_init(auo); + if (ret < 0) { + dev_err(panel->dev, "failed to init panel: %d\n", ret); + goto poweroff; + } + + auo->prepared = true; + + return 0; + +poweroff: + regulator_disable(auo->avee); +poweroffavdd: + regulator_disable(auo->avdd); +poweroff1v8: + usleep_range(5000, 7000); + regulator_disable(auo->pp1800); + if (auo->enable_gpio) + gpiod_set_value(auo->enable_gpio, 0); + return ret; +} + +static int auo_panel_enable(struct drm_panel *panel) +{ + struct auo_panel *auo = to_auo_panel(panel); + int ret; + + if (auo->enabled) + return 0; + + ret = backlight_enable(auo->backlight); + if (ret) { + DRM_DEV_ERROR(panel->drm->dev, + "Failed to enable backlight %d\n", ret); + return ret; + } + + auo->enabled = true; + + return 0; +} + +static const struct drm_display_mode default_mode = { + .clock = 157000, + .hdisplay = 1200, + .hsync_start = 1200 + 80, + .hsync_end = 1200 + 80 + 24, + .htotal = 1200 + 80 + 24 + 36, + .vdisplay = 1920, + .vsync_start = 1920 + 16, + .vsync_end = 1920 + 16 + 4, + .vtotal = 1920 + 16 + 4 + 16, + .vrefresh = 60, +}; + +static int auo_panel_get_modes(struct drm_panel *panel) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(panel->drm, &default_mode); + if (!mode) { + dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n", + default_mode.hdisplay, default_mode.vdisplay, + default_mode.vrefresh); + return -ENOMEM; + } + + drm_mode_set_name(mode); + + drm_mode_probed_add(panel->connector, mode); + + panel->connector->display_info.width_mm = 135; + panel->connector->display_info.height_mm = 216; + panel->connector->display_info.bpc = 8; + + return 1; +} + +static const struct drm_panel_funcs auo_panel_funcs = { + .disable = auo_panel_disable, + .unprepare = auo_panel_unprepare, + .prepare = auo_panel_prepare, + .enable = auo_panel_enable, + .get_modes = auo_panel_get_modes, +}; + +static int auo_panel_add(struct auo_panel *auo) +{ + struct device *dev = &auo->dsi->dev; + + auo->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(auo->avdd)) + return PTR_ERR(auo->avdd); + + auo->avee = devm_regulator_get(dev, "avee"); + if (IS_ERR(auo->avee)) + return PTR_ERR(auo->avee); + + auo->pp1800 = devm_regulator_get(dev, "pp1800"); + if (IS_ERR(auo->pp1800)) + return PTR_ERR(auo->pp1800); + + auo->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(auo->enable_gpio)) { + dev_err(dev, "cannot get reset-gpios %ld\n", + PTR_ERR(auo->enable_gpio)); + auo->enable_gpio = NULL; + } else { + gpiod_set_value(auo->enable_gpio, 0); + } + + auo->backlight = devm_of_find_backlight(dev); + if (IS_ERR(auo->backlight)) + return PTR_ERR(auo->backlight); + + drm_panel_init(&auo->base); + auo->base.funcs = &auo_panel_funcs; + auo->base.dev = &auo->dsi->dev; + + return drm_panel_add(&auo->base); +} + +static void auo_panel_del(struct auo_panel *auo) +{ + if (auo->base.dev) + drm_panel_remove(&auo->base); +} + +static int auo_panel_probe(struct mipi_dsi_device *dsi) +{ + struct auo_panel *auo; + int ret; + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM; + + auo = devm_kzalloc(&dsi->dev, sizeof(*auo), GFP_KERNEL); + if (!auo) + return -ENOMEM; + + mipi_dsi_set_drvdata(dsi, auo); + + auo->dsi = dsi; + + ret = auo_panel_add(auo); + if (ret < 0) + return ret; + + return mipi_dsi_attach(dsi); +} + +static int auo_panel_remove(struct mipi_dsi_device *dsi) +{ + struct auo_panel *auo = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = auo_panel_disable(&auo->base); + if (ret < 0) + dev_err(&dsi->dev, "failed to disable panel: %d\n", ret); + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); + + auo_panel_del(auo); + + return 0; +} + +static void auo_panel_shutdown(struct mipi_dsi_device *dsi) +{ + struct auo_panel *auo = mipi_dsi_get_drvdata(dsi); + + auo_panel_disable(&auo->base); +} + +static const struct of_device_id auo_of_match[] = { + { .compatible = "auo,kd101n80-45na", }, + { } +}; +MODULE_DEVICE_TABLE(of, auo_of_match); + +static struct mipi_dsi_driver auo_panel_driver = { + .driver = { + .name = "panel-auo-kd101n80-45na", + .of_match_table = auo_of_match, + }, + .probe = auo_panel_probe, + .remove = auo_panel_remove, + .shutdown = auo_panel_shutdown, +}; +module_mipi_dsi_driver(auo_panel_driver); + +MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>"); +MODULE_DESCRIPTION("AUO kd101n80-45na wuxga (1200x1920) video mode panel driver"); +MODULE_LICENSE("GPL v2"); +
Add driver for AUO kd101n80-45na panel. This panel supports the resolution 1200x1920, dsi video mode and 4 lanes. Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> --- drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-auo-kd101n80-45na.c | 352 ++++++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-auo-kd101n80-45na.c