Lines Matching +full:panel +full:- +full:dsi
1 // SPDX-License-Identifier: GPL-2.0+
3 * MIPI-DSI Sony ACX424AKP panel driver. This is a 480x864
4 * AMOLED panel with a command-only DSI interface.
8 * Based on code and know-how from Marcus Lorentzon
9 * Copyright (C) ST-Ericsson SA 2010
36 * and panel 00 ... seems like default values.
41 struct drm_panel panel; member
86 static inline struct acx424akp *panel_to_acx424akp(struct drm_panel *panel) in panel_to_acx424akp() argument
88 return container_of(panel, struct acx424akp, panel); in panel_to_acx424akp()
97 struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev); in acx424akp_set_brightness() local
99 int duty_ns = bl->props.brightness; in acx424akp_set_brightness()
106 pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1); in acx424akp_set_brightness()
112 dev_dbg(acx->dev, "calculated duty cycle %02x\n", pwm_ratio); in acx424akp_set_brightness()
113 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, in acx424akp_set_brightness()
116 dev_err(acx->dev, "failed to set display PWM ratio (%d)\n", ret); in acx424akp_set_brightness()
130 ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1); in acx424akp_set_brightness()
132 dev_err(acx->dev, "failed to unlock CMD 2 (%d)\n", ret); in acx424akp_set_brightness()
136 ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1); in acx424akp_set_brightness()
138 dev_err(acx->dev, "failed to enter page 1 (%d)\n", ret); in acx424akp_set_brightness()
142 ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1); in acx424akp_set_brightness()
144 dev_err(acx->dev, "failed to disable MTP reload (%d)\n", ret); in acx424akp_set_brightness()
147 ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1); in acx424akp_set_brightness()
149 dev_err(acx->dev, "failed to set PWM divisor (%d)\n", ret); in acx424akp_set_brightness()
153 ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1); in acx424akp_set_brightness()
155 dev_err(acx->dev, "failed to lock CMD 2 (%d)\n", ret); in acx424akp_set_brightness()
161 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, in acx424akp_set_brightness()
164 dev_err(acx->dev, "failed to enable display backlight (%d)\n", ret); in acx424akp_set_brightness()
177 struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev); in acx424akp_read_id() local
178 u8 vendor, version, panel; in acx424akp_read_id() local
182 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID1, &vendor, 1); in acx424akp_read_id()
184 dev_err(acx->dev, "could not vendor ID byte\n"); in acx424akp_read_id()
187 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID2, &version, 1); in acx424akp_read_id()
189 dev_err(acx->dev, "could not read device version byte\n"); in acx424akp_read_id()
192 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID3, &panel, 1); in acx424akp_read_id()
194 dev_err(acx->dev, "could not read panel ID byte\n"); in acx424akp_read_id()
199 dev_err(acx->dev, "device vendor ID is zero\n"); in acx424akp_read_id()
200 return -ENODEV; in acx424akp_read_id()
203 val = (vendor << 8) | panel; in acx424akp_read_id()
208 dev_info(acx->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n", in acx424akp_read_id()
209 vendor, version, panel); in acx424akp_read_id()
212 dev_info(acx->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n", in acx424akp_read_id()
213 vendor, version, panel); in acx424akp_read_id()
224 ret = regulator_enable(acx->supply); in acx424akp_power_on()
226 dev_err(acx->dev, "failed to enable supply (%d)\n", ret); in acx424akp_power_on()
231 gpiod_set_value_cansleep(acx->reset_gpio, 1); in acx424akp_power_on()
233 /* De-assert RESET */ in acx424akp_power_on()
234 gpiod_set_value_cansleep(acx->reset_gpio, 0); in acx424akp_power_on()
243 gpiod_set_value_cansleep(acx->reset_gpio, 1); in acx424akp_power_off()
246 regulator_disable(acx->supply); in acx424akp_power_off()
249 static int acx424akp_prepare(struct drm_panel *panel) in acx424akp_prepare() argument
251 struct acx424akp *acx = panel_to_acx424akp(panel); in acx424akp_prepare()
252 struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev); in acx424akp_prepare() local
262 dev_err(acx->dev, "failed to read panel ID (%d)\n", ret); in acx424akp_prepare()
267 ret = mipi_dsi_dcs_set_tear_on(dsi, in acx424akp_prepare()
270 dev_err(acx->dev, "failed to enable vblank TE (%d)\n", ret); in acx424akp_prepare()
278 * selects DSI, similar code is found in other drivers such as the in acx424akp_prepare()
279 * Sharp LS043T1LE01 which makes us suspect that this panel may be in acx424akp_prepare()
284 ret = mipi_dsi_dcs_write(dsi, ACX424_DCS_SET_MDDI, in acx424akp_prepare()
287 dev_err(acx->dev, "failed to set MDDI (%d)\n", ret); in acx424akp_prepare()
292 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); in acx424akp_prepare()
294 dev_err(acx->dev, "failed to exit sleep mode (%d)\n", ret); in acx424akp_prepare()
299 ret = mipi_dsi_dcs_set_display_on(dsi); in acx424akp_prepare()
301 dev_err(acx->dev, "failed to turn display on (%d)\n", ret); in acx424akp_prepare()
304 if (acx->video_mode) { in acx424akp_prepare()
306 ret = mipi_dsi_turn_on_peripheral(dsi); in acx424akp_prepare()
308 dev_err(acx->dev, "failed to turn on peripheral\n"); in acx424akp_prepare()
313 acx->bl->props.power = FB_BLANK_NORMAL; in acx424akp_prepare()
322 static int acx424akp_unprepare(struct drm_panel *panel) in acx424akp_unprepare() argument
324 struct acx424akp *acx = panel_to_acx424akp(panel); in acx424akp_unprepare()
325 struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev); in acx424akp_unprepare() local
331 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, in acx424akp_unprepare()
334 dev_err(acx->dev, "failed to disable display backlight (%d)\n", ret); in acx424akp_unprepare()
338 ret = mipi_dsi_dcs_set_display_off(dsi); in acx424akp_unprepare()
340 dev_err(acx->dev, "failed to turn display off (%d)\n", ret); in acx424akp_unprepare()
345 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); in acx424akp_unprepare()
347 dev_err(acx->dev, "failed to enter sleep mode (%d)\n", ret); in acx424akp_unprepare()
353 acx->bl->props.power = FB_BLANK_POWERDOWN; in acx424akp_unprepare()
358 static int acx424akp_enable(struct drm_panel *panel) in acx424akp_enable() argument
360 struct acx424akp *acx = panel_to_acx424akp(panel); in acx424akp_enable()
366 acx->bl->props.power = FB_BLANK_UNBLANK; in acx424akp_enable()
371 static int acx424akp_disable(struct drm_panel *panel) in acx424akp_disable() argument
373 struct acx424akp *acx = panel_to_acx424akp(panel); in acx424akp_disable()
379 acx->bl->props.power = FB_BLANK_NORMAL; in acx424akp_disable()
384 static int acx424akp_get_modes(struct drm_panel *panel, in acx424akp_get_modes() argument
387 struct acx424akp *acx = panel_to_acx424akp(panel); in acx424akp_get_modes()
390 if (acx->video_mode) in acx424akp_get_modes()
391 mode = drm_mode_duplicate(connector->dev, in acx424akp_get_modes()
394 mode = drm_mode_duplicate(connector->dev, in acx424akp_get_modes()
397 dev_err(panel->dev, "bad mode or failed to add mode\n"); in acx424akp_get_modes()
398 return -EINVAL; in acx424akp_get_modes()
401 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in acx424akp_get_modes()
403 connector->display_info.width_mm = mode->width_mm; in acx424akp_get_modes()
404 connector->display_info.height_mm = mode->height_mm; in acx424akp_get_modes()
419 static int acx424akp_probe(struct mipi_dsi_device *dsi) in acx424akp_probe() argument
421 struct device *dev = &dsi->dev; in acx424akp_probe()
427 return -ENOMEM; in acx424akp_probe()
428 acx->video_mode = of_property_read_bool(dev->of_node, in acx424akp_probe()
429 "enforce-video-mode"); in acx424akp_probe()
431 mipi_dsi_set_drvdata(dsi, acx); in acx424akp_probe()
432 acx->dev = dev; in acx424akp_probe()
434 dsi->lanes = 2; in acx424akp_probe()
435 dsi->format = MIPI_DSI_FMT_RGB888; in acx424akp_probe()
437 * FIXME: these come from the ST-Ericsson vendor driver for the in acx424akp_probe()
439 * platform, if you have the datasheet, please cross-check the in acx424akp_probe()
442 dsi->lp_rate = 19200000; in acx424akp_probe()
443 dsi->hs_rate = 420160000; in acx424akp_probe()
445 if (acx->video_mode) in acx424akp_probe()
447 dsi->mode_flags = in acx424akp_probe()
451 dsi->mode_flags = in acx424akp_probe()
455 acx->supply = devm_regulator_get(dev, "vddi"); in acx424akp_probe()
456 if (IS_ERR(acx->supply)) in acx424akp_probe()
457 return PTR_ERR(acx->supply); in acx424akp_probe()
460 acx->reset_gpio = devm_gpiod_get_optional(dev, "reset", in acx424akp_probe()
462 if (IS_ERR(acx->reset_gpio)) { in acx424akp_probe()
463 ret = PTR_ERR(acx->reset_gpio); in acx424akp_probe()
464 if (ret != -EPROBE_DEFER) in acx424akp_probe()
469 drm_panel_init(&acx->panel, dev, &acx424akp_drm_funcs, in acx424akp_probe()
472 acx->bl = devm_backlight_device_register(dev, "acx424akp", dev, acx, in acx424akp_probe()
474 if (IS_ERR(acx->bl)) { in acx424akp_probe()
476 return PTR_ERR(acx->bl); in acx424akp_probe()
478 acx->bl->props.max_brightness = 1023; in acx424akp_probe()
479 acx->bl->props.brightness = 512; in acx424akp_probe()
480 acx->bl->props.power = FB_BLANK_POWERDOWN; in acx424akp_probe()
482 drm_panel_add(&acx->panel); in acx424akp_probe()
484 ret = mipi_dsi_attach(dsi); in acx424akp_probe()
486 drm_panel_remove(&acx->panel); in acx424akp_probe()
493 static int acx424akp_remove(struct mipi_dsi_device *dsi) in acx424akp_remove() argument
495 struct acx424akp *acx = mipi_dsi_get_drvdata(dsi); in acx424akp_remove()
497 mipi_dsi_detach(dsi); in acx424akp_remove()
498 drm_panel_remove(&acx->panel); in acx424akp_remove()
513 .name = "panel-sony-acx424akp",
520 MODULE_DESCRIPTION("MIPI-DSI Sony acx424akp Panel Driver");