Lines Matching +full:electronic +full:- +full:serial +full:- +full:number
1 // SPDX-License-Identifier: GPL-2.0-only
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
160 * be selected by electronic straps on the display. However it is possible
161 * to select another mode or override the electronic default with this
181 "8 bit serial RGB through",
182 "8 bit serial RGB aligned",
183 "8 bit serial RGB dummy 320x240",
184 "8 bit serial RGB dummy 360x240",
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
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 * +----------------------------------------------------------->
330 /* Just register 0 is read-only */ in ili9322_writeable_reg()
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()
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()
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()
535 /* Serial RGB 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()
704 return 1; /* Number of modes */ 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",