Lines Matching +full:dir +full:- +full:685 +full:- +full:panel

1 // SPDX-License-Identifier: GPL-2.0-only
5 * This panel can be configured to support:
6 * - 8-bit serial RGB interface
7 * - 24-bit parallel RGB interface
8 * - 8-bit ITU-R BT.601 interface
9 * - 8-bit ITU-R BT.656 interface
10 * - Up to 320RGBx240 dots resolution TFT LCD displays
11 * - Scaling, brightness and contrast
19 * Derived from drivers/drm/gpu/panel/panel-samsung-ld9040.c
64 /* 0 = right-to-left, 1 = left-to-right (default), horizontal flip */
66 /* 0 = down-to-up, 1 = up-to-down (default), vertical flip */
127 /* Formula A for YCbCR->RGB = 0, Formula B = 1 */
140 #define ILI9322_GLOBAL_RESET_ASSERT 0x00 /* bit 0 = 0 -> reset */
144 * Upper nybble, bits 4-7 are negative gamma
145 * Lower nybble, bits 0-3 are positive gamma
157 * enum ili9322_input - the format of the incoming signal to the panel
159 * The panel can be connected to various input streams and four of them can
191 "8 bit ITU-R BT.656 720Y 360CbCr",
192 "8 bit ITU-R BT.656 640Y 320CbCr",
196 * struct ili9322_config - the system specific ILI9322 configuration
197 * @width_mm: physical panel width [mm]
198 * @height_mm: physical panel height [mm]
199 * @flip_horizontal: flip the image horizontally (right-to-left scan)
201 * @flip_vertical: flip the image vertically (down-to-up scan)
214 * peak-to-peak amplitude of the communcation signals to the physical
243 * +----------------------------------------------------------->
273 struct drm_panel panel; member
285 static inline struct ili9322 *panel_to_ili9322(struct drm_panel *panel) in panel_to_ili9322() argument
287 return container_of(panel, struct ili9322, panel); in panel_to_ili9322()
330 /* Just register 0 is read-only */ in ili9322_writeable_reg()
344 static int ili9322_init(struct drm_panel *panel, struct ili9322 *ili) in ili9322_init() argument
351 ret = regmap_write(ili->regmap, ILI9322_GLOBAL_RESET, in ili9322_init()
354 dev_err(ili->dev, "can't issue GRESET (%d)\n", ret); in ili9322_init()
359 if (ili->vreg1out != U8_MAX) { in ili9322_init()
360 ret = regmap_write(ili->regmap, ILI9322_VREG1_VOLTAGE, in ili9322_init()
361 ili->vreg1out); in ili9322_init()
363 dev_err(ili->dev, "can't set up VREG1OUT (%d)\n", ret); in ili9322_init()
368 if (ili->vcom_amplitude != U8_MAX) { in ili9322_init()
369 ret = regmap_write(ili->regmap, ILI9322_VCOM_AMP, in ili9322_init()
370 ili->vcom_amplitude); in ili9322_init()
372 dev_err(ili->dev, in ili9322_init()
378 if (ili->vcom_high != U8_MAX) { in ili9322_init()
379 ret = regmap_write(ili->regmap, ILI9322_VCOM_HIGH, in ili9322_init()
380 ili->vcom_high); in ili9322_init()
382 dev_err(ili->dev, "can't set up VCOM high (%d)\n", ret); in ili9322_init()
388 for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) { in ili9322_init()
389 ret = regmap_write(ili->regmap, ILI9322_GAMMA_1 + i, in ili9322_init()
390 ili->gamma[i]); in ili9322_init()
392 dev_err(ili->dev, in ili9322_init()
404 if (ili->conf->dclk_active_high) in ili9322_init()
406 if (ili->conf->de_active_high) in ili9322_init()
408 if (ili->conf->hsync_active_high) in ili9322_init()
410 if (ili->conf->vsync_active_high) in ili9322_init()
412 ret = regmap_write(ili->regmap, ILI9322_POL, reg); in ili9322_init()
414 dev_err(ili->dev, "can't write POL register (%d)\n", ret); in ili9322_init()
422 reg = ili->conf->syncmode; in ili9322_init()
424 ret = regmap_write(ili->regmap, ILI9322_IF_CTRL, reg); in ili9322_init()
426 dev_err(ili->dev, "can't write IF CTRL register (%d)\n", ret); in ili9322_init()
431 reg = (ili->input << 4); in ili9322_init()
433 if (!ili->conf->flip_horizontal) in ili9322_init()
435 if (!ili->conf->flip_vertical) in ili9322_init()
438 ret = regmap_write(ili->regmap, ILI9322_ENTRY, reg); in ili9322_init()
440 dev_err(ili->dev, "can't write ENTRY reg (%d)\n", ret); in ili9322_init()
443 dev_info(ili->dev, "display is in %s mode, syncmode %02x\n", in ili9322_init()
444 ili9322_inputs[ili->input], in ili9322_init()
445 ili->conf->syncmode); in ili9322_init()
447 dev_info(ili->dev, "initialized display\n"); in ili9322_init()
453 * This power-on sequence if from the datasheet, page 57.
460 gpiod_set_value(ili->reset_gpio, 1); in ili9322_power_on()
462 ret = regulator_bulk_enable(ARRAY_SIZE(ili->supplies), ili->supplies); in ili9322_power_on()
464 dev_err(ili->dev, "unable to enable regulators\n"); in ili9322_power_on()
469 /* De-assert RESET */ in ili9322_power_on()
470 gpiod_set_value(ili->reset_gpio, 0); in ili9322_power_on()
479 return regulator_bulk_disable(ARRAY_SIZE(ili->supplies), ili->supplies); in ili9322_power_off()
482 static int ili9322_disable(struct drm_panel *panel) in ili9322_disable() argument
484 struct ili9322 *ili = panel_to_ili9322(panel); in ili9322_disable()
487 ret = regmap_write(ili->regmap, ILI9322_POW_CTRL, in ili9322_disable()
490 dev_err(ili->dev, "unable to go to standby mode\n"); in ili9322_disable()
497 static int ili9322_unprepare(struct drm_panel *panel) in ili9322_unprepare() argument
499 struct ili9322 *ili = panel_to_ili9322(panel); in ili9322_unprepare()
504 static int ili9322_prepare(struct drm_panel *panel) in ili9322_prepare() argument
506 struct ili9322 *ili = panel_to_ili9322(panel); in ili9322_prepare()
513 ret = ili9322_init(panel, ili); in ili9322_prepare()
515 ili9322_unprepare(panel); in ili9322_prepare()
520 static int ili9322_enable(struct drm_panel *panel) in ili9322_enable() argument
522 struct ili9322 *ili = panel_to_ili9322(panel); in ili9322_enable()
525 ret = regmap_write(ili->regmap, ILI9322_POW_CTRL, in ili9322_enable()
528 dev_err(ili->dev, "unable to enable panel\n"); in ili9322_enable()
631 static int ili9322_get_modes(struct drm_panel *panel, in ili9322_get_modes() argument
634 struct ili9322 *ili = panel_to_ili9322(panel); in ili9322_get_modes()
635 struct drm_device *drm = connector->dev; in ili9322_get_modes()
639 info = &connector->display_info; in ili9322_get_modes()
640 info->width_mm = ili->conf->width_mm; in ili9322_get_modes()
641 info->height_mm = ili->conf->height_mm; in ili9322_get_modes()
642 if (ili->conf->dclk_active_high) in ili9322_get_modes()
643 info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; in ili9322_get_modes()
645 info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; in ili9322_get_modes()
647 if (ili->conf->de_active_high) in ili9322_get_modes()
648 info->bus_flags |= DRM_BUS_FLAG_DE_HIGH; in ili9322_get_modes()
650 info->bus_flags |= DRM_BUS_FLAG_DE_LOW; in ili9322_get_modes()
652 switch (ili->input) { in ili9322_get_modes()
680 dev_err(panel->dev, "bad mode or failed to add mode\n"); in ili9322_get_modes()
681 return -EINVAL; in ili9322_get_modes()
688 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in ili9322_get_modes()
691 if (ili->conf->hsync_active_high) in ili9322_get_modes()
692 mode->flags |= DRM_MODE_FLAG_PHSYNC; in ili9322_get_modes()
694 mode->flags |= DRM_MODE_FLAG_NHSYNC; in ili9322_get_modes()
695 if (ili->conf->vsync_active_high) in ili9322_get_modes()
696 mode->flags |= DRM_MODE_FLAG_PVSYNC; in ili9322_get_modes()
698 mode->flags |= DRM_MODE_FLAG_NVSYNC; in ili9322_get_modes()
700 mode->width_mm = ili->conf->width_mm; in ili9322_get_modes()
701 mode->height_mm = ili->conf->height_mm; in ili9322_get_modes()
717 struct device *dev = &spi->dev; in ili9322_probe()
727 return -ENOMEM; in ili9322_probe()
731 ili->dev = dev; in ili9322_probe()
737 ili->conf = of_device_get_match_data(dev); in ili9322_probe()
738 if (!ili->conf) { in ili9322_probe()
740 return -ENODEV; in ili9322_probe()
743 val = ili->conf->vreg1out_mv; in ili9322_probe()
746 ili->vreg1out = U8_MAX; in ili9322_probe()
750 return -EINVAL; in ili9322_probe()
754 return -EINVAL; in ili9322_probe()
758 return -EINVAL; in ili9322_probe()
760 val -= 3600; in ili9322_probe()
763 ili->vreg1out = val; in ili9322_probe()
766 val = ili->conf->vcom_high_percent; in ili9322_probe()
769 ili->vcom_high = U8_MAX; in ili9322_probe()
773 return -EINVAL; in ili9322_probe()
777 return -EINVAL; in ili9322_probe()
779 val -= 37; in ili9322_probe()
781 ili->vcom_high = val; in ili9322_probe()
784 val = ili->conf->vcom_amplitude_percent; in ili9322_probe()
787 ili->vcom_high = U8_MAX; in ili9322_probe()
791 return -EINVAL; in ili9322_probe()
795 return -EINVAL; in ili9322_probe()
797 val -= 70; in ili9322_probe()
800 ili->vcom_amplitude = val; in ili9322_probe()
803 for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) { in ili9322_probe()
804 val = ili->conf->gamma_corr_neg[i]; in ili9322_probe()
810 val = ili->conf->gamma_corr_pos[i]; in ili9322_probe()
816 ili->gamma[i] = gamma; in ili9322_probe()
820 ili->supplies[0].supply = "vcc"; /* 2.7-3.6 V */ in ili9322_probe()
821 ili->supplies[1].supply = "iovcc"; /* 1.65-3.6V */ in ili9322_probe()
822 ili->supplies[2].supply = "vci"; /* 2.7-3.6V */ in ili9322_probe()
823 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ili->supplies), in ili9322_probe()
824 ili->supplies); in ili9322_probe()
827 ret = regulator_set_voltage(ili->supplies[0].consumer, in ili9322_probe()
831 ret = regulator_set_voltage(ili->supplies[1].consumer, in ili9322_probe()
835 ret = regulator_set_voltage(ili->supplies[2].consumer, in ili9322_probe()
840 ili->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in ili9322_probe()
841 if (IS_ERR(ili->reset_gpio)) { in ili9322_probe()
843 return PTR_ERR(ili->reset_gpio); in ili9322_probe()
846 spi->bits_per_word = 8; in ili9322_probe()
853 ili->regmap = devm_regmap_init(dev, &ili9322_regmap_bus, dev, in ili9322_probe()
855 if (IS_ERR(ili->regmap)) { in ili9322_probe()
857 return PTR_ERR(ili->regmap); in ili9322_probe()
860 ret = regmap_read(ili->regmap, ILI9322_CHIP_ID, &val); in ili9322_probe()
868 return -ENODEV; in ili9322_probe()
872 if (ili->conf->input == ILI9322_INPUT_UNKNOWN) { in ili9322_probe()
873 ret = regmap_read(ili->regmap, ILI9322_ENTRY, &val); in ili9322_probe()
879 ili->input = (val >> 4) & 0x0f; in ili9322_probe()
880 if (ili->input >= ILI9322_INPUT_UNKNOWN) in ili9322_probe()
881 ili->input = ILI9322_INPUT_UNKNOWN; in ili9322_probe()
883 ili->input = ili->conf->input; in ili9322_probe()
886 drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs, in ili9322_probe()
889 drm_panel_add(&ili->panel); in ili9322_probe()
899 drm_panel_remove(&ili->panel); in ili9322_remove()
903 * The D-Link DIR-685 panel is marked LM918A01-1A SY-B4-091116-E0199
920 .compatible = "dlink,dir-685-panel",
935 .name = "panel-ilitek-ili9322",
942 MODULE_DESCRIPTION("ILI9322 LCD panel driver");