Lines Matching +full:panel +full:- +full:mipi +full:- +full:dbi +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0
3 * Panel driver for the Samsung S6D27A1 480x800 DPI RGB panel.
4 * Found in the Samsung Galaxy Ace 2 GT-I8160 mobile phone.
15 #include <linux/media-bus-format.h>
19 #include <linux/spi/spi.h>
26 #define S6D27A1_READID1 0xDA /* Read panel ID 1 */
27 #define S6D27A1_READID2 0xDB /* Read panel ID 2 */
28 #define S6D27A1_READID3 0xDC /* Read panel ID 3 */
33 #define S6D27A1_PANELCTL 0xF7 /* Panel Control*/
44 struct mipi_dbi dbi; member
45 struct drm_panel panel; member
52 * The vendor driver states that the S6D27A1 panel
69 static inline struct s6d27a1 *to_s6d27a1(struct drm_panel *panel) in to_s6d27a1() argument
71 return container_of(panel, struct s6d27a1, panel); in to_s6d27a1()
76 struct mipi_dbi *dbi = &ctx->dbi; in s6d27a1_read_mtp_id() local
80 ret = mipi_dbi_command_read(dbi, S6D27A1_READID1, &id1); in s6d27a1_read_mtp_id()
82 dev_err(ctx->dev, "unable to read MTP ID 1\n"); in s6d27a1_read_mtp_id()
85 ret = mipi_dbi_command_read(dbi, S6D27A1_READID2, &id2); in s6d27a1_read_mtp_id()
87 dev_err(ctx->dev, "unable to read MTP ID 2\n"); in s6d27a1_read_mtp_id()
90 ret = mipi_dbi_command_read(dbi, S6D27A1_READID3, &id3); in s6d27a1_read_mtp_id()
92 dev_err(ctx->dev, "unable to read MTP ID 3\n"); in s6d27a1_read_mtp_id()
95 dev_info(ctx->dev, "MTP ID: %02x %02x %02x\n", id1, id2, id3); in s6d27a1_read_mtp_id()
100 struct mipi_dbi *dbi = &ctx->dbi; in s6d27a1_power_on() local
104 ret = regulator_bulk_enable(ARRAY_SIZE(ctx->regulators), in s6d27a1_power_on()
105 ctx->regulators); in s6d27a1_power_on()
107 dev_err(ctx->dev, "failed to enable regulators: %d\n", ret); in s6d27a1_power_on()
114 gpiod_set_value_cansleep(ctx->reset, 1); in s6d27a1_power_on()
116 /* De-assert reset */ in s6d27a1_power_on()
117 gpiod_set_value_cansleep(ctx->reset, 0); in s6d27a1_power_on()
122 * Exit sleep mode and initialize display - some hammering is in s6d27a1_power_on()
125 mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); in s6d27a1_power_on()
126 mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); in s6d27a1_power_on()
130 mipi_dbi_command(dbi, S6D27A1_PASSWD_L2, 0x5A, 0x5A); in s6d27a1_power_on()
133 mipi_dbi_command(dbi, S6D27A1_RESCTL, 0x22); in s6d27a1_power_on()
135 mipi_dbi_command(dbi, S6D27A1_PANELCTL2, 0x00, 0x02, 0x03, 0x04, 0x05, 0x08, 0x00, 0x0c); in s6d27a1_power_on()
137 mipi_dbi_command(dbi, S6D27A1_MANPWR, 0x01, 0x00, 0x00, 0x08, 0x08, 0x02, 0x00); in s6d27a1_power_on()
139 mipi_dbi_command(dbi, S6D27A1_DISPCTL, 0x19, 0x00, 0x08, 0x0D, 0x03, 0x41, 0x3F); in s6d27a1_power_on()
141 mipi_dbi_command(dbi, S6D27A1_PWRCTL1, 0x00, 0x00, 0x00, 0x00, 0x55, in s6d27a1_power_on()
144 mipi_dbi_command(dbi, S6D27A1_SRCCTL, 0x03, 0x09, 0x8A, 0x00, 0x01, 0x16); in s6d27a1_power_on()
146 mipi_dbi_command(dbi, S6D27A1_PANELCTL, 0x00, 0x05, 0x06, 0x07, 0x08, in s6d27a1_power_on()
156 mipi_dbi_command(dbi, S6D27A1_PASSWD_L2, 0xA5, 0xA5); in s6d27a1_power_on()
166 gpiod_set_value_cansleep(ctx->reset, 1); in s6d27a1_power_off()
167 return regulator_bulk_disable(ARRAY_SIZE(ctx->regulators), in s6d27a1_power_off()
168 ctx->regulators); in s6d27a1_power_off()
171 static int s6d27a1_unprepare(struct drm_panel *panel) in s6d27a1_unprepare() argument
173 struct s6d27a1 *ctx = to_s6d27a1(panel); in s6d27a1_unprepare()
174 struct mipi_dbi *dbi = &ctx->dbi; in s6d27a1_unprepare() local
176 mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE); in s6d27a1_unprepare()
178 return s6d27a1_power_off(to_s6d27a1(panel)); in s6d27a1_unprepare()
181 static int s6d27a1_disable(struct drm_panel *panel) in s6d27a1_disable() argument
183 struct s6d27a1 *ctx = to_s6d27a1(panel); in s6d27a1_disable()
184 struct mipi_dbi *dbi = &ctx->dbi; in s6d27a1_disable() local
186 mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF); in s6d27a1_disable()
192 static int s6d27a1_prepare(struct drm_panel *panel) in s6d27a1_prepare() argument
194 return s6d27a1_power_on(to_s6d27a1(panel)); in s6d27a1_prepare()
197 static int s6d27a1_enable(struct drm_panel *panel) in s6d27a1_enable() argument
199 struct s6d27a1 *ctx = to_s6d27a1(panel); in s6d27a1_enable()
200 struct mipi_dbi *dbi = &ctx->dbi; in s6d27a1_enable() local
202 mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); in s6d27a1_enable()
207 static int s6d27a1_get_modes(struct drm_panel *panel, in s6d27a1_get_modes() argument
210 struct s6d27a1 *ctx = to_s6d27a1(panel); in s6d27a1_get_modes()
214 mode = drm_mode_duplicate(connector->dev, &s6d27a1_480_800_mode); in s6d27a1_get_modes()
216 dev_err(ctx->dev, "failed to add mode\n"); in s6d27a1_get_modes()
217 return -ENOMEM; in s6d27a1_get_modes()
220 connector->display_info.bpc = 8; in s6d27a1_get_modes()
221 connector->display_info.width_mm = mode->width_mm; in s6d27a1_get_modes()
222 connector->display_info.height_mm = mode->height_mm; in s6d27a1_get_modes()
223 connector->display_info.bus_flags = in s6d27a1_get_modes()
225 drm_display_info_set_bus_formats(&connector->display_info, in s6d27a1_get_modes()
229 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in s6d27a1_get_modes()
244 static int s6d27a1_probe(struct spi_device *spi) in s6d27a1_probe() argument
246 struct device *dev = &spi->dev; in s6d27a1_probe()
252 return -ENOMEM; in s6d27a1_probe()
254 ctx->dev = dev; in s6d27a1_probe()
260 ctx->regulators[0].supply = "vci"; in s6d27a1_probe()
261 ctx->regulators[1].supply = "vccio"; in s6d27a1_probe()
263 ARRAY_SIZE(ctx->regulators), in s6d27a1_probe()
264 ctx->regulators); in s6d27a1_probe()
268 ctx->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in s6d27a1_probe()
269 if (IS_ERR(ctx->reset)) { in s6d27a1_probe()
270 ret = PTR_ERR(ctx->reset); in s6d27a1_probe()
274 ret = mipi_dbi_spi_init(spi, &ctx->dbi, NULL); in s6d27a1_probe()
276 return dev_err_probe(dev, ret, "MIPI DBI init failed\n"); in s6d27a1_probe()
278 ctx->dbi.read_commands = s6d27a1_dbi_read_commands; in s6d27a1_probe()
280 drm_panel_init(&ctx->panel, dev, &s6d27a1_drm_funcs, in s6d27a1_probe()
283 ret = drm_panel_of_backlight(&ctx->panel); in s6d27a1_probe()
287 spi_set_drvdata(spi, ctx); in s6d27a1_probe()
289 drm_panel_add(&ctx->panel); in s6d27a1_probe()
294 static void s6d27a1_remove(struct spi_device *spi) in s6d27a1_remove() argument
296 struct s6d27a1 *ctx = spi_get_drvdata(spi); in s6d27a1_remove()
298 drm_panel_remove(&ctx->panel); in s6d27a1_remove()
311 .name = "s6d27a1-panel",
318 MODULE_DESCRIPTION("Samsung S6D27A1 panel driver");