root/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. s6e3ha2_dcs_write
  2. s6e3ha2_test_key_on_f0
  3. s6e3ha2_test_key_off_f0
  4. s6e3ha2_test_key_on_fc
  5. s6e3ha2_test_key_off_fc
  6. s6e3ha2_single_dsi_set
  7. s6e3ha2_freq_calibration
  8. s6e3ha2_aor_control
  9. s6e3ha2_caps_elvss_set
  10. s6e3ha2_acl_off
  11. s6e3ha2_acl_off_opr
  12. s6e3ha2_test_global
  13. s6e3ha2_test
  14. s6e3ha2_touch_hsync_on1
  15. s6e3ha2_pentile_control
  16. s6e3ha2_poc_global
  17. s6e3ha2_poc_setting
  18. s6e3ha2_pcd_set_off
  19. s6e3ha2_err_fg_set
  20. s6e3ha2_hbm_off
  21. s6e3ha2_te_start_setting
  22. s6e3ha2_gamma_update
  23. s6e3ha2_get_brightness
  24. s6e3ha2_set_vint
  25. s6e3ha2_get_brightness_index
  26. s6e3ha2_update_gamma
  27. s6e3ha2_set_brightness
  28. s6e3ha2_panel_init
  29. s6e3ha2_power_off
  30. s6e3ha2_disable
  31. s6e3ha2_unprepare
  32. s6e3ha2_power_on
  33. s6e3ha2_prepare
  34. s6e3ha2_enable
  35. s6e3ha2_get_modes
  36. s6e3ha2_probe
  37. s6e3ha2_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver.
   4  *
   5  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
   6  * Donghwa Lee <dh09.lee@samsung.com>
   7  * Hyungwon Hwang <human.hwang@samsung.com>
   8  * Hoegeun Kwon <hoegeun.kwon@samsung.com>
   9  */
  10 
  11 #include <linux/backlight.h>
  12 #include <linux/delay.h>
  13 #include <linux/gpio/consumer.h>
  14 #include <linux/module.h>
  15 #include <linux/of_device.h>
  16 #include <linux/regulator/consumer.h>
  17 
  18 #include <drm/drm_mipi_dsi.h>
  19 #include <drm/drm_modes.h>
  20 #include <drm/drm_panel.h>
  21 #include <drm/drm_print.h>
  22 
  23 #define S6E3HA2_MIN_BRIGHTNESS          0
  24 #define S6E3HA2_MAX_BRIGHTNESS          100
  25 #define S6E3HA2_DEFAULT_BRIGHTNESS      80
  26 
  27 #define S6E3HA2_NUM_GAMMA_STEPS         46
  28 #define S6E3HA2_GAMMA_CMD_CNT           35
  29 #define S6E3HA2_VINT_STATUS_MAX         10
  30 
  31 static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = {
  32         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83,
  33           0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c,
  34           0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00,
  35           0x00, 0x00 },
  36         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84,
  37           0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a,
  38           0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00,
  39           0x00, 0x00 },
  40         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  41           0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a,
  42           0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00,
  43           0x00, 0x00 },
  44         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  45           0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a,
  46           0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00,
  47           0x00, 0x00 },
  48         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85,
  49           0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b,
  50           0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00,
  51           0x00, 0x00 },
  52         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  53           0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b,
  54           0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00,
  55           0x00, 0x00 },
  56         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  57           0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89,
  58           0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00,
  59           0x00, 0x00 },
  60         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  61           0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c,
  62           0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
  63           0x00, 0x00 },
  64         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  65           0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88,
  66           0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
  67           0x00, 0x00 },
  68         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
  69           0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a,
  70           0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00,
  71           0x00, 0x00 },
  72         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  73           0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b,
  74           0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00,
  75           0x00, 0x00 },
  76         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  77           0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c,
  78           0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00,
  79           0x00, 0x00 },
  80         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  81           0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c,
  82           0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00,
  83           0x00, 0x00 },
  84         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  85           0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
  86           0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00,
  87           0x00, 0x00 },
  88         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  89           0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
  90           0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00,
  91           0x00, 0x00 },
  92         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  93           0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b,
  94           0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
  95           0x00, 0x00 },
  96         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
  97           0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e,
  98           0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
  99           0x00, 0x00 },
 100         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
 101           0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e,
 102           0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00,
 103           0x00, 0x00 },
 104         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
 105           0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d,
 106           0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
 107           0x00, 0x00 },
 108         { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
 109           0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c,
 110           0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
 111           0x00, 0x00 },
 112         { 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83,
 113           0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a,
 114           0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
 115           0x00, 0x00 },
 116         { 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83,
 117           0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a,
 118           0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 119           0x00, 0x00 },
 120         { 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83,
 121           0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89,
 122           0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
 123           0x00, 0x00 },
 124         { 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83,
 125           0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a,
 126           0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00,
 127           0x00, 0x00 },
 128         { 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82,
 129           0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87,
 130           0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
 131           0x00, 0x00 },
 132         { 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82,
 133           0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88,
 134           0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
 135           0x00, 0x00 },
 136         { 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83,
 137           0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89,
 138           0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
 139           0x00, 0x00 },
 140         { 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82,
 141           0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86,
 142           0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
 143           0x00, 0x00 },
 144         { 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82,
 145           0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87,
 146           0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00,
 147           0x00, 0x00 },
 148         { 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81,
 149           0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86,
 150           0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
 151           0x00, 0x00 },
 152         { 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82,
 153           0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83,
 154           0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00,
 155           0x00, 0x00 },
 156         { 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82,
 157           0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82,
 158           0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
 159           0x00, 0x00 },
 160         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
 161           0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80,
 162           0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
 163           0x00, 0x00 },
 164         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81,
 165           0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
 166           0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
 167           0x00, 0x00 },
 168         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
 169           0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
 170           0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
 171           0x00, 0x00 },
 172         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
 173           0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82,
 174           0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 175           0x00, 0x00 },
 176         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
 177           0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83,
 178           0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 179           0x00, 0x00 },
 180         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
 181           0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83,
 182           0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
 183           0x00, 0x00 },
 184         { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80,
 185           0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81,
 186           0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00,
 187           0x00, 0x00 },
 188         { 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81,
 189           0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83,
 190           0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00,
 191           0x00, 0x00 },
 192         { 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80,
 193           0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80,
 194           0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 195           0x00, 0x00 },
 196         { 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80,
 197           0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d,
 198           0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 199           0x00, 0x00 },
 200         { 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80,
 201           0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82,
 202           0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 203           0x00, 0x00 },
 204         { 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80,
 205           0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 206           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 207           0x00, 0x00 },
 208         { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
 209           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 210           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 211           0x00, 0x00 },
 212         { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
 213           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 214           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
 215           0x00, 0x00 }
 216 };
 217 
 218 unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = {
 219         0x18, 0x19, 0x1a, 0x1b, 0x1c,
 220         0x1d, 0x1e, 0x1f, 0x20, 0x21
 221 };
 222 
 223 enum s6e3ha2_type {
 224         HA2_TYPE,
 225         HF2_TYPE,
 226 };
 227 
 228 struct s6e3ha2_panel_desc {
 229         const struct drm_display_mode *mode;
 230         enum s6e3ha2_type type;
 231 };
 232 
 233 struct s6e3ha2 {
 234         struct device *dev;
 235         struct drm_panel panel;
 236         struct backlight_device *bl_dev;
 237 
 238         struct regulator_bulk_data supplies[2];
 239         struct gpio_desc *reset_gpio;
 240         struct gpio_desc *enable_gpio;
 241 
 242         const struct s6e3ha2_panel_desc *desc;
 243 };
 244 
 245 static int s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len)
 246 {
 247         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
 248 
 249         return mipi_dsi_dcs_write_buffer(dsi, data, len);
 250 }
 251 
 252 #define s6e3ha2_dcs_write_seq_static(ctx, seq...) do {  \
 253         static const u8 d[] = { seq };                  \
 254         int ret;                                        \
 255         ret = s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d)); \
 256         if (ret < 0)                                    \
 257                 return ret;                             \
 258 } while (0)
 259 
 260 #define s6e3ha2_call_write_func(ret, func) do { \
 261         ret = (func);                           \
 262         if (ret < 0)                            \
 263                 return ret;                     \
 264 } while (0)
 265 
 266 static int s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx)
 267 {
 268         s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
 269         return 0;
 270 }
 271 
 272 static int s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx)
 273 {
 274         s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5);
 275         return 0;
 276 }
 277 
 278 static int s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx)
 279 {
 280         s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
 281         return 0;
 282 }
 283 
 284 static int s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx)
 285 {
 286         s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5);
 287         return 0;
 288 }
 289 
 290 static int s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx)
 291 {
 292         s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67);
 293         s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09);
 294         return 0;
 295 }
 296 
 297 static int s6e3ha2_freq_calibration(struct s6e3ha2 *ctx)
 298 {
 299         s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c);
 300         if (ctx->desc->type == HF2_TYPE)
 301                 s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67, 0x40, 0xc5);
 302         s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39);
 303         s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0);
 304         s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20);
 305 
 306         if (ctx->desc->type == HA2_TYPE)
 307                 s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62,
 308                                                   0x40, 0x80, 0xc0, 0x28, 0x28,
 309                                                   0x28, 0x28, 0x39, 0xc5);
 310         else
 311                 s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x14, 0x6d,
 312                                                   0x40, 0x80, 0xc0, 0x28, 0x28,
 313                                                   0x28, 0x28, 0x39, 0xc5);
 314 
 315         return 0;
 316 }
 317 
 318 static int s6e3ha2_aor_control(struct s6e3ha2 *ctx)
 319 {
 320         s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10);
 321         return 0;
 322 }
 323 
 324 static int s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx)
 325 {
 326         s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a);
 327         return 0;
 328 }
 329 
 330 static int s6e3ha2_acl_off(struct s6e3ha2 *ctx)
 331 {
 332         s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00);
 333         return 0;
 334 }
 335 
 336 static int s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx)
 337 {
 338         s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40);
 339         return 0;
 340 }
 341 
 342 static int s6e3ha2_test_global(struct s6e3ha2 *ctx)
 343 {
 344         s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07);
 345         return 0;
 346 }
 347 
 348 static int s6e3ha2_test(struct s6e3ha2 *ctx)
 349 {
 350         s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19);
 351         return 0;
 352 }
 353 
 354 static int s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx)
 355 {
 356         s6e3ha2_dcs_write_seq_static(ctx, 0xbd, 0x33, 0x11, 0x02,
 357                                         0x16, 0x02, 0x16);
 358         return 0;
 359 }
 360 
 361 static int s6e3ha2_pentile_control(struct s6e3ha2 *ctx)
 362 {
 363         s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8);
 364         return 0;
 365 }
 366 
 367 static int s6e3ha2_poc_global(struct s6e3ha2 *ctx)
 368 {
 369         s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20);
 370         return 0;
 371 }
 372 
 373 static int s6e3ha2_poc_setting(struct s6e3ha2 *ctx)
 374 {
 375         s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08);
 376         return 0;
 377 }
 378 
 379 static int s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx)
 380 {
 381         s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51);
 382         return 0;
 383 }
 384 
 385 static int s6e3ha2_err_fg_set(struct s6e3ha2 *ctx)
 386 {
 387         s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44);
 388         return 0;
 389 }
 390 
 391 static int s6e3ha2_hbm_off(struct s6e3ha2 *ctx)
 392 {
 393         s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00);
 394         return 0;
 395 }
 396 
 397 static int s6e3ha2_te_start_setting(struct s6e3ha2 *ctx)
 398 {
 399         s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09);
 400         return 0;
 401 }
 402 
 403 static int s6e3ha2_gamma_update(struct s6e3ha2 *ctx)
 404 {
 405         s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03);
 406         ndelay(100); /* need for 100ns delay */
 407         s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00);
 408         return 0;
 409 }
 410 
 411 static int s6e3ha2_get_brightness(struct backlight_device *bl_dev)
 412 {
 413         return bl_dev->props.brightness;
 414 }
 415 
 416 static int s6e3ha2_set_vint(struct s6e3ha2 *ctx)
 417 {
 418         struct backlight_device *bl_dev = ctx->bl_dev;
 419         unsigned int brightness = bl_dev->props.brightness;
 420         unsigned char data[] = { 0xf4, 0x8b,
 421                         vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) /
 422                         S6E3HA2_MAX_BRIGHTNESS] };
 423 
 424         return s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data));
 425 }
 426 
 427 static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness)
 428 {
 429         return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) /
 430                 S6E3HA2_MAX_BRIGHTNESS;
 431 }
 432 
 433 static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness)
 434 {
 435         struct backlight_device *bl_dev = ctx->bl_dev;
 436         unsigned int index = s6e3ha2_get_brightness_index(brightness);
 437         u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, };
 438         int ret;
 439 
 440         memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT);
 441         s6e3ha2_call_write_func(ret,
 442                                 s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data)));
 443 
 444         s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
 445         bl_dev->props.brightness = brightness;
 446 
 447         return 0;
 448 }
 449 
 450 static int s6e3ha2_set_brightness(struct backlight_device *bl_dev)
 451 {
 452         struct s6e3ha2 *ctx = bl_get_data(bl_dev);
 453         unsigned int brightness = bl_dev->props.brightness;
 454         int ret;
 455 
 456         if (brightness < S6E3HA2_MIN_BRIGHTNESS ||
 457                 brightness > bl_dev->props.max_brightness) {
 458                 dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
 459                 return -EINVAL;
 460         }
 461 
 462         if (bl_dev->props.power > FB_BLANK_NORMAL)
 463                 return -EPERM;
 464 
 465         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
 466         s6e3ha2_call_write_func(ret, s6e3ha2_update_gamma(ctx, brightness));
 467         s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
 468         s6e3ha2_call_write_func(ret, s6e3ha2_set_vint(ctx));
 469         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
 470 
 471         return 0;
 472 }
 473 
 474 static const struct backlight_ops s6e3ha2_bl_ops = {
 475         .get_brightness = s6e3ha2_get_brightness,
 476         .update_status = s6e3ha2_set_brightness,
 477 };
 478 
 479 static int s6e3ha2_panel_init(struct s6e3ha2 *ctx)
 480 {
 481         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
 482         int ret;
 483 
 484         s6e3ha2_call_write_func(ret, mipi_dsi_dcs_exit_sleep_mode(dsi));
 485         usleep_range(5000, 6000);
 486 
 487         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
 488         s6e3ha2_call_write_func(ret, s6e3ha2_single_dsi_set(ctx));
 489         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
 490         s6e3ha2_call_write_func(ret, s6e3ha2_freq_calibration(ctx));
 491         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
 492         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
 493 
 494         return 0;
 495 }
 496 
 497 static int s6e3ha2_power_off(struct s6e3ha2 *ctx)
 498 {
 499         return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
 500 }
 501 
 502 static int s6e3ha2_disable(struct drm_panel *panel)
 503 {
 504         struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
 505         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
 506         int ret;
 507 
 508         s6e3ha2_call_write_func(ret, mipi_dsi_dcs_enter_sleep_mode(dsi));
 509         s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_off(dsi));
 510 
 511         msleep(40);
 512         ctx->bl_dev->props.power = FB_BLANK_NORMAL;
 513 
 514         return 0;
 515 }
 516 
 517 static int s6e3ha2_unprepare(struct drm_panel *panel)
 518 {
 519         struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
 520 
 521         return s6e3ha2_power_off(ctx);
 522 }
 523 
 524 static int s6e3ha2_power_on(struct s6e3ha2 *ctx)
 525 {
 526         int ret;
 527 
 528         ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
 529         if (ret < 0)
 530                 return ret;
 531 
 532         msleep(120);
 533 
 534         gpiod_set_value(ctx->enable_gpio, 0);
 535         usleep_range(5000, 6000);
 536         gpiod_set_value(ctx->enable_gpio, 1);
 537 
 538         gpiod_set_value(ctx->reset_gpio, 1);
 539         usleep_range(5000, 6000);
 540         gpiod_set_value(ctx->reset_gpio, 0);
 541         usleep_range(5000, 6000);
 542 
 543         return 0;
 544 }
 545 static int s6e3ha2_prepare(struct drm_panel *panel)
 546 {
 547         struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
 548         int ret;
 549 
 550         ret = s6e3ha2_power_on(ctx);
 551         if (ret < 0)
 552                 return ret;
 553 
 554         ret = s6e3ha2_panel_init(ctx);
 555         if (ret < 0)
 556                 goto err;
 557 
 558         ctx->bl_dev->props.power = FB_BLANK_NORMAL;
 559 
 560         return 0;
 561 
 562 err:
 563         s6e3ha2_power_off(ctx);
 564         return ret;
 565 }
 566 
 567 static int s6e3ha2_enable(struct drm_panel *panel)
 568 {
 569         struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
 570         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
 571         int ret;
 572 
 573         /* common setting */
 574         s6e3ha2_call_write_func(ret,
 575                 mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK));
 576 
 577         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
 578         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
 579         s6e3ha2_call_write_func(ret, s6e3ha2_touch_hsync_on1(ctx));
 580         s6e3ha2_call_write_func(ret, s6e3ha2_pentile_control(ctx));
 581         s6e3ha2_call_write_func(ret, s6e3ha2_poc_global(ctx));
 582         s6e3ha2_call_write_func(ret, s6e3ha2_poc_setting(ctx));
 583         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
 584 
 585         /* pcd setting off for TB */
 586         s6e3ha2_call_write_func(ret, s6e3ha2_pcd_set_off(ctx));
 587         s6e3ha2_call_write_func(ret, s6e3ha2_err_fg_set(ctx));
 588         s6e3ha2_call_write_func(ret, s6e3ha2_te_start_setting(ctx));
 589 
 590         /* brightness setting */
 591         s6e3ha2_call_write_func(ret, s6e3ha2_set_brightness(ctx->bl_dev));
 592         s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
 593         s6e3ha2_call_write_func(ret, s6e3ha2_caps_elvss_set(ctx));
 594         s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
 595         s6e3ha2_call_write_func(ret, s6e3ha2_acl_off(ctx));
 596         s6e3ha2_call_write_func(ret, s6e3ha2_acl_off_opr(ctx));
 597         s6e3ha2_call_write_func(ret, s6e3ha2_hbm_off(ctx));
 598 
 599         /* elvss temp compensation */
 600         s6e3ha2_call_write_func(ret, s6e3ha2_test_global(ctx));
 601         s6e3ha2_call_write_func(ret, s6e3ha2_test(ctx));
 602         s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
 603 
 604         s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_on(dsi));
 605         ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
 606 
 607         return 0;
 608 }
 609 
 610 static const struct drm_display_mode s6e3ha2_mode = {
 611         .clock = 222372,
 612         .hdisplay = 1440,
 613         .hsync_start = 1440 + 1,
 614         .hsync_end = 1440 + 1 + 1,
 615         .htotal = 1440 + 1 + 1 + 1,
 616         .vdisplay = 2560,
 617         .vsync_start = 2560 + 1,
 618         .vsync_end = 2560 + 1 + 1,
 619         .vtotal = 2560 + 1 + 1 + 15,
 620         .vrefresh = 60,
 621         .flags = 0,
 622 };
 623 
 624 static const struct s6e3ha2_panel_desc samsung_s6e3ha2 = {
 625         .mode = &s6e3ha2_mode,
 626         .type = HA2_TYPE,
 627 };
 628 
 629 static const struct drm_display_mode s6e3hf2_mode = {
 630         .clock = 247856,
 631         .hdisplay = 1600,
 632         .hsync_start = 1600 + 1,
 633         .hsync_end = 1600 + 1 + 1,
 634         .htotal = 1600 + 1 + 1 + 1,
 635         .vdisplay = 2560,
 636         .vsync_start = 2560 + 1,
 637         .vsync_end = 2560 + 1 + 1,
 638         .vtotal = 2560 + 1 + 1 + 15,
 639         .vrefresh = 60,
 640         .flags = 0,
 641 };
 642 
 643 static const struct s6e3ha2_panel_desc samsung_s6e3hf2 = {
 644         .mode = &s6e3hf2_mode,
 645         .type = HF2_TYPE,
 646 };
 647 
 648 static int s6e3ha2_get_modes(struct drm_panel *panel)
 649 {
 650         struct drm_connector *connector = panel->connector;
 651         struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
 652         struct drm_display_mode *mode;
 653 
 654         mode = drm_mode_duplicate(panel->drm, ctx->desc->mode);
 655         if (!mode) {
 656                 DRM_ERROR("failed to add mode %ux%ux@%u\n",
 657                         ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
 658                         ctx->desc->mode->vrefresh);
 659                 return -ENOMEM;
 660         }
 661 
 662         drm_mode_set_name(mode);
 663 
 664         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 665         drm_mode_probed_add(connector, mode);
 666 
 667         connector->display_info.width_mm = 71;
 668         connector->display_info.height_mm = 125;
 669 
 670         return 1;
 671 }
 672 
 673 static const struct drm_panel_funcs s6e3ha2_drm_funcs = {
 674         .disable = s6e3ha2_disable,
 675         .unprepare = s6e3ha2_unprepare,
 676         .prepare = s6e3ha2_prepare,
 677         .enable = s6e3ha2_enable,
 678         .get_modes = s6e3ha2_get_modes,
 679 };
 680 
 681 static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
 682 {
 683         struct device *dev = &dsi->dev;
 684         struct s6e3ha2 *ctx;
 685         int ret;
 686 
 687         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
 688         if (!ctx)
 689                 return -ENOMEM;
 690 
 691         mipi_dsi_set_drvdata(dsi, ctx);
 692 
 693         ctx->dev = dev;
 694         ctx->desc = of_device_get_match_data(dev);
 695 
 696         dsi->lanes = 4;
 697         dsi->format = MIPI_DSI_FMT_RGB888;
 698         dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
 699 
 700         ctx->supplies[0].supply = "vdd3";
 701         ctx->supplies[1].supply = "vci";
 702 
 703         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
 704                                       ctx->supplies);
 705         if (ret < 0) {
 706                 dev_err(dev, "failed to get regulators: %d\n", ret);
 707                 return ret;
 708         }
 709 
 710         ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
 711         if (IS_ERR(ctx->reset_gpio)) {
 712                 dev_err(dev, "cannot get reset-gpios %ld\n",
 713                         PTR_ERR(ctx->reset_gpio));
 714                 return PTR_ERR(ctx->reset_gpio);
 715         }
 716 
 717         ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
 718         if (IS_ERR(ctx->enable_gpio)) {
 719                 dev_err(dev, "cannot get enable-gpios %ld\n",
 720                         PTR_ERR(ctx->enable_gpio));
 721                 return PTR_ERR(ctx->enable_gpio);
 722         }
 723 
 724         ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx,
 725                                                 &s6e3ha2_bl_ops, NULL);
 726         if (IS_ERR(ctx->bl_dev)) {
 727                 dev_err(dev, "failed to register backlight device\n");
 728                 return PTR_ERR(ctx->bl_dev);
 729         }
 730 
 731         ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS;
 732         ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
 733         ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
 734 
 735         drm_panel_init(&ctx->panel);
 736         ctx->panel.dev = dev;
 737         ctx->panel.funcs = &s6e3ha2_drm_funcs;
 738 
 739         ret = drm_panel_add(&ctx->panel);
 740         if (ret < 0)
 741                 goto unregister_backlight;
 742 
 743         ret = mipi_dsi_attach(dsi);
 744         if (ret < 0)
 745                 goto remove_panel;
 746 
 747         return ret;
 748 
 749 remove_panel:
 750         drm_panel_remove(&ctx->panel);
 751 
 752 unregister_backlight:
 753         backlight_device_unregister(ctx->bl_dev);
 754 
 755         return ret;
 756 }
 757 
 758 static int s6e3ha2_remove(struct mipi_dsi_device *dsi)
 759 {
 760         struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi);
 761 
 762         mipi_dsi_detach(dsi);
 763         drm_panel_remove(&ctx->panel);
 764         backlight_device_unregister(ctx->bl_dev);
 765 
 766         return 0;
 767 }
 768 
 769 static const struct of_device_id s6e3ha2_of_match[] = {
 770         { .compatible = "samsung,s6e3ha2", .data = &samsung_s6e3ha2 },
 771         { .compatible = "samsung,s6e3hf2", .data = &samsung_s6e3hf2 },
 772         { }
 773 };
 774 MODULE_DEVICE_TABLE(of, s6e3ha2_of_match);
 775 
 776 static struct mipi_dsi_driver s6e3ha2_driver = {
 777         .probe = s6e3ha2_probe,
 778         .remove = s6e3ha2_remove,
 779         .driver = {
 780                 .name = "panel-samsung-s6e3ha2",
 781                 .of_match_table = s6e3ha2_of_match,
 782         },
 783 };
 784 module_mipi_dsi_driver(s6e3ha2_driver);
 785 
 786 MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
 787 MODULE_AUTHOR("Hyungwon Hwang <human.hwang@samsung.com>");
 788 MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>");
 789 MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver");
 790 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */