board-sapphire-panel.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. /* linux/arch/arm/mach-msm/board-sapphire-panel.c
  2. * Copyright (C) 2007-2009 HTC Corporation.
  3. * Author: Thomas Tsai <thomas_tsai@htc.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/delay.h>
  18. #include <linux/leds.h>
  19. #include <linux/clk.h>
  20. #include <linux/err.h>
  21. #include <linux/io.h>
  22. #include <linux/gpio.h>
  23. #include <asm/mach-types.h>
  24. #include <mach/msm_fb.h>
  25. #include <mach/vreg.h>
  26. #include <mach/htc_pwrsink.h>
  27. #include <mach/proc_comm.h>
  28. #include "gpio_chip.h"
  29. #include "board-sapphire.h"
  30. #include "devices.h"
  31. #define DEBUG_SAPPHIRE_PANEL 0
  32. #define userid 0xD10
  33. #define VSYNC_GPIO 97
  34. enum sapphire_panel_type {
  35. SAPPHIRE_PANEL_SHARP = 0,
  36. SAPPHIRE_PANEL_TOPPOLY,
  37. NUM_OF_SAPPHIRE_PANELS,
  38. };
  39. static int g_panel_id = -1 ;
  40. static int g_panel_inited = 0 ;
  41. #define SAPPHIRE_DEFAULT_BACKLIGHT_BRIGHTNESS 132
  42. #define GOOGLE_DEFAULT_BACKLIGHT_BRIGHTNESS 102
  43. #define SDBB SAPPHIRE_DEFAULT_BACKLIGHT_BRIGHTNESS
  44. #define GDBB GOOGLE_DEFAULT_BACKLIGHT_BRIGHTNESS
  45. static int sapphire_backlight_off;
  46. static int sapphire_backlight_brightness =
  47. SAPPHIRE_DEFAULT_BACKLIGHT_BRIGHTNESS;
  48. static uint8_t sapphire_backlight_last_level = 33;
  49. static DEFINE_MUTEX(sapphire_backlight_lock);
  50. /* Divide dimming level into 12 sections, and restrict maximum level to 27 */
  51. #define DIMMING_STEPS 12
  52. static unsigned dimming_levels[NUM_OF_SAPPHIRE_PANELS][DIMMING_STEPS] = {
  53. {0, 1, 2, 3, 6, 9, 11, 13, 16, 19, 22, 25}, /* Sharp */
  54. {0, 1, 2, 4, 7, 10, 13, 15, 18, 21, 24, 27}, /* Toppolly */
  55. };
  56. static unsigned pwrsink_percents[] = {0, 6, 8, 15, 26, 34, 46, 54, 65, 77, 87,
  57. 100};
  58. static void sapphire_set_backlight_level(uint8_t level)
  59. {
  60. unsigned dimming_factor = 255/DIMMING_STEPS + 1;
  61. int index, new_level ;
  62. unsigned percent;
  63. unsigned long flags;
  64. int i = 0;
  65. /* Non-linear transform for the difference between two
  66. * kind of default backlight settings.
  67. */
  68. new_level = level<=GDBB ?
  69. level*SDBB/GDBB : (SDBB + (level-GDBB)*(255-SDBB) / (255-GDBB)) ;
  70. index = new_level/dimming_factor ;
  71. #if DEBUG_SAPPHIRE_PANEL
  72. printk(KERN_INFO "level=%d, new level=%d, dimming_levels[%d]=%d\n",
  73. level, new_level, index, dimming_levels[g_panel_id][index]);
  74. #endif
  75. percent = pwrsink_percents[index];
  76. level = dimming_levels[g_panel_id][index];
  77. if (sapphire_backlight_last_level == level)
  78. return;
  79. if (level == 0) {
  80. gpio_set_value(27, 0);
  81. msleep(2);
  82. } else {
  83. local_irq_save(flags);
  84. if (sapphire_backlight_last_level == 0) {
  85. gpio_set_value(27, 1);
  86. udelay(40);
  87. sapphire_backlight_last_level = 33;
  88. }
  89. i = (sapphire_backlight_last_level - level + 33) % 33;
  90. while (i-- > 0) {
  91. gpio_set_value(27, 0);
  92. udelay(1);
  93. gpio_set_value(27, 1);
  94. udelay(1);
  95. }
  96. local_irq_restore(flags);
  97. }
  98. sapphire_backlight_last_level = level;
  99. htc_pwrsink_set(PWRSINK_BACKLIGHT, percent);
  100. }
  101. #define MDDI_CLIENT_CORE_BASE 0x108000
  102. #define LCD_CONTROL_BLOCK_BASE 0x110000
  103. #define SPI_BLOCK_BASE 0x120000
  104. #define I2C_BLOCK_BASE 0x130000
  105. #define PWM_BLOCK_BASE 0x140000
  106. #define GPIO_BLOCK_BASE 0x150000
  107. #define SYSTEM_BLOCK1_BASE 0x160000
  108. #define SYSTEM_BLOCK2_BASE 0x170000
  109. #define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
  110. #define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)
  111. #define PWM0OFF (PWM_BLOCK_BASE|0x1C)
  112. #define V_VDDE2E_VDD2_GPIO 0
  113. #define V_VDDE2E_VDD2_GPIO_5M 89
  114. #define MDDI_RST_N 82
  115. #define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
  116. #define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
  117. #define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
  118. #define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
  119. #define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
  120. #define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
  121. #define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
  122. #define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
  123. #define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
  124. #define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
  125. #define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
  126. #define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
  127. #define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
  128. #define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
  129. #define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
  130. #define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
  131. #define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
  132. #define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
  133. #define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
  134. #define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
  135. #define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
  136. #define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
  137. #define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
  138. #define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
  139. #define START (LCD_CONTROL_BLOCK_BASE|0x08)
  140. #define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
  141. #define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
  142. #define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
  143. #define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
  144. #define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
  145. #define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
  146. #define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
  147. #define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
  148. #define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
  149. #define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
  150. #define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
  151. #define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
  152. #define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
  153. #define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
  154. #define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
  155. #define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
  156. #define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
  157. #define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
  158. #define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
  159. #define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
  160. #define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
  161. #define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
  162. #define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
  163. #define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
  164. #define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
  165. #define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
  166. #define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
  167. #define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
  168. #define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
  169. #define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
  170. #define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
  171. #define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
  172. #define SSICTL (SPI_BLOCK_BASE|0x00)
  173. #define SSITIME (SPI_BLOCK_BASE|0x04)
  174. #define SSITX (SPI_BLOCK_BASE|0x08)
  175. #define SSIRX (SPI_BLOCK_BASE|0x0C)
  176. #define SSIINTC (SPI_BLOCK_BASE|0x10)
  177. #define SSIINTS (SPI_BLOCK_BASE|0x14)
  178. #define SSIDBG1 (SPI_BLOCK_BASE|0x18)
  179. #define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
  180. #define SSIID (SPI_BLOCK_BASE|0x20)
  181. #define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
  182. #define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
  183. #define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
  184. #define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
  185. #define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
  186. #define GPIODATA (GPIO_BLOCK_BASE|0x00)
  187. #define GPIODIR (GPIO_BLOCK_BASE|0x04)
  188. #define GPIOIS (GPIO_BLOCK_BASE|0x08)
  189. #define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
  190. #define GPIOIEV (GPIO_BLOCK_BASE|0x10)
  191. #define GPIOIE (GPIO_BLOCK_BASE|0x14)
  192. #define GPIORIS (GPIO_BLOCK_BASE|0x18)
  193. #define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
  194. #define GPIOIC (GPIO_BLOCK_BASE|0x20)
  195. #define GPIOOMS (GPIO_BLOCK_BASE|0x24)
  196. #define GPIOPC (GPIO_BLOCK_BASE|0x28)
  197. #define GPIOID (GPIO_BLOCK_BASE|0x30)
  198. #define SPI_WRITE(reg, val) \
  199. { SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
  200. { 0, 5 },
  201. #define SPI_WRITE1(reg) \
  202. { SSITX, (reg) & 0xff }, \
  203. { 0, 5 },
  204. struct mddi_table {
  205. uint32_t reg;
  206. uint32_t value;
  207. };
  208. static struct mddi_table mddi_toshiba_init_table[] = {
  209. { DPSET0, 0x09e90046 },
  210. { DPSET1, 0x00000118 },
  211. { DPSUS, 0x00000000 },
  212. { DPRUN, 0x00000001 },
  213. { 1, 14 }, /* msleep 14 */
  214. { SYSCKENA, 0x00000001 },
  215. /*{ CLKENB, 0x000000EF } */
  216. { CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */
  217. /*{ CLKENB, 0x000025CB }, Clock enable register */
  218. { GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
  219. { GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */
  220. { GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */
  221. { GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */
  222. { WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */
  223. { GPIOIBE, 0x000003FF },
  224. { GPIOIS, 0x00000000 },
  225. { GPIOIC, 0x000003FF },
  226. { GPIOIE, 0x00000000 },
  227. { GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
  228. { 1, 1 }, /* msleep 1 */
  229. { GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
  230. { DRAMPWR, 0x00000001 }, /* eDRAM power */
  231. };
  232. static struct mddi_table mddi_toshiba_panel_init_table[] = {
  233. { SRST, 0x00000003 }, /* FIFO/LCDC not reset */
  234. { PORT_ENB, 0x00000001 }, /* Enable sync. Port */
  235. { START, 0x00000000 }, /* To stop operation */
  236. /*{ START, 0x00000001 }, To start operation */
  237. { PORT, 0x00000004 }, /* Polarity of VS/HS/DE. */
  238. { CMN, 0x00000000 },
  239. { GAMMA, 0x00000000 }, /* No Gamma correction */
  240. { INTFLG, 0x00000000 }, /* VSYNC interrupt flag clear/status */
  241. { INTMSK, 0x00000000 }, /* VSYNC interrupt mask is off. */
  242. { MPLFBUF, 0x00000000 }, /* Select frame buffer's base address. */
  243. { HDE_LEFT, 0x00000000 }, /* The value of HDE_LEFT. */
  244. { VDE_TOP, 0x00000000 }, /* The value of VDE_TPO. */
  245. { PXL, 0x00000001 }, /* 1. RGB666 */
  246. /* 2. Data is valid from 1st frame of beginning. */
  247. { HDE_START, 0x00000006 }, /* HDE_START= 14 PCLK */
  248. { HDE_SIZE, 0x0000009F }, /* HDE_SIZE=320 PCLK */
  249. { HSW, 0x00000004 }, /* HSW= 10 PCLK */
  250. { VSW, 0x00000001 }, /* VSW=2 HCYCLE */
  251. { VDE_START, 0x00000003 }, /* VDE_START=4 HCYCLE */
  252. { VDE_SIZE, 0x000001DF }, /* VDE_SIZE=480 HCYCLE */
  253. { WAKEUP, 0x000001e2 }, /* Wakeup position in VSYNC mode. */
  254. { WSYN_DLY, 0x00000000 }, /* Wakeup position in VSIN mode. */
  255. { REGENB, 0x00000001 }, /* Set 1 to enable to change the value of registers. */
  256. { CLKENB, 0x000025CB }, /* Clock enable register */
  257. { SSICTL, 0x00000170 }, /* SSI control register */
  258. { SSITIME, 0x00000250 }, /* SSI timing control register */
  259. { SSICTL, 0x00000172 }, /* SSI control register */
  260. };
  261. static struct mddi_table mddi_sharp_init_table[] = {
  262. { VCYCLE, 0x000001eb },
  263. { HCYCLE, 0x000000ae },
  264. { REGENB, 0x00000001 }, /* Set 1 to enable to change the value of registers. */
  265. { GPIODATA, 0x00040000 }, /* GPIO2 low */
  266. { GPIODIR, 0x00000004 }, /* GPIO2 out */
  267. { 1, 1 }, /* msleep 1 */
  268. { GPIODATA, 0x00040004 }, /* GPIO2 high */
  269. { 1, 10 }, /* msleep 10 */
  270. SPI_WRITE(0x5f, 0x01)
  271. SPI_WRITE1(0x11)
  272. { 1, 200 }, /* msleep 200 */
  273. SPI_WRITE1(0x29)
  274. SPI_WRITE1(0xde)
  275. { START, 0x00000001 }, /* To start operation */
  276. };
  277. static struct mddi_table mddi_sharp_deinit_table[] = {
  278. { 1, 200 }, /* msleep 200 */
  279. SPI_WRITE(0x10, 0x1)
  280. { 1, 100 }, /* msleep 100 */
  281. { GPIODATA, 0x00040004 }, /* GPIO2 high */
  282. { GPIODIR, 0x00000004 }, /* GPIO2 out */
  283. { GPIODATA, 0x00040000 }, /* GPIO2 low */
  284. { 1, 10 }, /* msleep 10 */
  285. };
  286. static struct mddi_table mddi_tpo_init_table[] = {
  287. { VCYCLE, 0x000001e5 },
  288. { HCYCLE, 0x000000ac },
  289. { REGENB, 0x00000001 }, /* Set 1 to enable to change the value of registers. */
  290. { 0, 20 }, /* udelay 20 */
  291. { GPIODATA, 0x00000004 }, /* GPIO2 high */
  292. { GPIODIR, 0x00000004 }, /* GPIO2 out */
  293. { 0, 20 }, /* udelay 20 */
  294. SPI_WRITE(0x08, 0x01)
  295. { 0, 500 }, /* udelay 500 */
  296. SPI_WRITE(0x08, 0x00)
  297. SPI_WRITE(0x02, 0x00)
  298. SPI_WRITE(0x03, 0x04)
  299. SPI_WRITE(0x04, 0x0e)
  300. SPI_WRITE(0x09, 0x02)
  301. SPI_WRITE(0x0b, 0x08)
  302. SPI_WRITE(0x0c, 0x53)
  303. SPI_WRITE(0x0d, 0x01)
  304. SPI_WRITE(0x0e, 0xe0)
  305. SPI_WRITE(0x0f, 0x01)
  306. SPI_WRITE(0x10, 0x58)
  307. SPI_WRITE(0x20, 0x1e)
  308. SPI_WRITE(0x21, 0x0a)
  309. SPI_WRITE(0x22, 0x0a)
  310. SPI_WRITE(0x23, 0x1e)
  311. SPI_WRITE(0x25, 0x32)
  312. SPI_WRITE(0x26, 0x00)
  313. SPI_WRITE(0x27, 0xac)
  314. SPI_WRITE(0x29, 0x06)
  315. SPI_WRITE(0x2a, 0xa4)
  316. SPI_WRITE(0x2b, 0x45)
  317. SPI_WRITE(0x2c, 0x45)
  318. SPI_WRITE(0x2d, 0x15)
  319. SPI_WRITE(0x2e, 0x5a)
  320. SPI_WRITE(0x2f, 0xff)
  321. SPI_WRITE(0x30, 0x6b)
  322. SPI_WRITE(0x31, 0x0d)
  323. SPI_WRITE(0x32, 0x48)
  324. SPI_WRITE(0x33, 0x82)
  325. SPI_WRITE(0x34, 0xbd)
  326. SPI_WRITE(0x35, 0xe7)
  327. SPI_WRITE(0x36, 0x18)
  328. SPI_WRITE(0x37, 0x94)
  329. SPI_WRITE(0x38, 0x01)
  330. SPI_WRITE(0x39, 0x5d)
  331. SPI_WRITE(0x3a, 0xae)
  332. SPI_WRITE(0x3b, 0xff)
  333. SPI_WRITE(0x07, 0x09)
  334. { 0, 10 }, /* udelay 10 */
  335. { START, 0x00000001 }, /* To start operation */
  336. };
  337. static struct mddi_table mddi_tpo_deinit_table[] = {
  338. SPI_WRITE(0x07, 0x19)
  339. { START, 0x00000000 }, /* To stop operation */
  340. { GPIODATA, 0x00040004 }, /* GPIO2 high */
  341. { GPIODIR, 0x00000004 }, /* GPIO2 out */
  342. { GPIODATA, 0x00040000 }, /* GPIO2 low */
  343. { 0, 5 }, /* usleep 5 */
  344. };
  345. #define GPIOSEL_VWAKEINT (1U << 0)
  346. #define INTMASK_VWAKEOUT (1U << 0)
  347. static void sapphire_process_mddi_table(
  348. struct msm_mddi_client_data *client_data,
  349. const struct mddi_table *table,
  350. size_t count)
  351. {
  352. int i;
  353. for (i = 0; i < count; i++) {
  354. uint32_t reg = table[i].reg;
  355. uint32_t value = table[i].value;
  356. if (reg == 0)
  357. udelay(value);
  358. else if (reg == 1)
  359. msleep(value);
  360. else
  361. client_data->remote_write(client_data, value, reg);
  362. }
  363. }
  364. static struct vreg *vreg_lcm_2v85;
  365. static void sapphire_mddi_power_client(struct msm_mddi_client_data *client_data,
  366. int on)
  367. {
  368. unsigned id, on_off;
  369. #if DEBUG_SAPPHIRE_PANEL
  370. printk(KERN_INFO "sapphire_mddi_client_power:%d\r\n", on);
  371. #endif
  372. if (on) {
  373. on_off = 0;
  374. id = PM_VREG_PDOWN_MDDI_ID;
  375. msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  376. gpio_set_value(SAPPHIRE_MDDI_1V5_EN, 1);
  377. mdelay(5); /* delay time >5ms and <10ms */
  378. if (is_12pin_camera())
  379. gpio_set_value(V_VDDE2E_VDD2_GPIO_5M, 1);
  380. else
  381. gpio_set_value(V_VDDE2E_VDD2_GPIO, 1);
  382. gpio_set_value(SAPPHIRE_GPIO_MDDI_32K_EN, 1);
  383. msleep(3);
  384. id = PM_VREG_PDOWN_AUX_ID;
  385. msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  386. vreg_enable(vreg_lcm_2v85);
  387. msleep(3);
  388. } else {
  389. gpio_set_value(SAPPHIRE_GPIO_MDDI_32K_EN, 0);
  390. gpio_set_value(MDDI_RST_N, 0);
  391. msleep(10);
  392. vreg_disable(vreg_lcm_2v85);
  393. on_off = 1;
  394. id = PM_VREG_PDOWN_AUX_ID;
  395. msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  396. msleep(5);
  397. if (is_12pin_camera())
  398. gpio_set_value(V_VDDE2E_VDD2_GPIO_5M, 0);
  399. else
  400. gpio_set_value(V_VDDE2E_VDD2_GPIO, 0);
  401. msleep(200);
  402. gpio_set_value(SAPPHIRE_MDDI_1V5_EN, 0);
  403. id = PM_VREG_PDOWN_MDDI_ID;
  404. msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  405. }
  406. }
  407. static int sapphire_mddi_toshiba_client_init(
  408. struct msm_mddi_bridge_platform_data *bridge_data,
  409. struct msm_mddi_client_data *client_data)
  410. {
  411. int panel_id;
  412. /* Set the MDDI_RST_N accroding to MDDI client repectively(
  413. * been set in sapphire_mddi_power_client() originally)
  414. */
  415. gpio_set_value(MDDI_RST_N, 1);
  416. msleep(10);
  417. client_data->auto_hibernate(client_data, 0);
  418. sapphire_process_mddi_table(client_data, mddi_toshiba_init_table,
  419. ARRAY_SIZE(mddi_toshiba_init_table));
  420. client_data->auto_hibernate(client_data, 1);
  421. g_panel_id = panel_id =
  422. (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  423. if (panel_id > 1) {
  424. #if DEBUG_SAPPHIRE_PANEL
  425. printk(KERN_ERR "unknown panel id at mddi_enable\n");
  426. #endif
  427. return -1;
  428. }
  429. return 0;
  430. }
  431. static int sapphire_mddi_toshiba_client_uninit(
  432. struct msm_mddi_bridge_platform_data *bridge_data,
  433. struct msm_mddi_client_data *client_data)
  434. {
  435. gpio_set_value(MDDI_RST_N, 0);
  436. msleep(10);
  437. return 0;
  438. }
  439. static int sapphire_mddi_panel_unblank(
  440. struct msm_mddi_bridge_platform_data *bridge_data,
  441. struct msm_mddi_client_data *client_data)
  442. {
  443. int panel_id, ret = 0;
  444. sapphire_set_backlight_level(0);
  445. client_data->auto_hibernate(client_data, 0);
  446. sapphire_process_mddi_table(client_data, mddi_toshiba_panel_init_table,
  447. ARRAY_SIZE(mddi_toshiba_panel_init_table));
  448. panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  449. switch (panel_id) {
  450. case 0:
  451. #if DEBUG_SAPPHIRE_PANEL
  452. printk(KERN_DEBUG "init sharp panel\n");
  453. #endif
  454. sapphire_process_mddi_table(client_data,
  455. mddi_sharp_init_table,
  456. ARRAY_SIZE(mddi_sharp_init_table));
  457. break;
  458. case 1:
  459. #if DEBUG_SAPPHIRE_PANEL
  460. printk(KERN_DEBUG "init tpo panel\n");
  461. #endif
  462. sapphire_process_mddi_table(client_data,
  463. mddi_tpo_init_table,
  464. ARRAY_SIZE(mddi_tpo_init_table));
  465. break;
  466. default:
  467. printk(KERN_DEBUG "unknown panel_id: %d\n", panel_id);
  468. ret = -1;
  469. };
  470. mutex_lock(&sapphire_backlight_lock);
  471. sapphire_set_backlight_level(sapphire_backlight_brightness);
  472. sapphire_backlight_off = 0;
  473. mutex_unlock(&sapphire_backlight_lock);
  474. client_data->auto_hibernate(client_data, 1);
  475. /* reenable vsync */
  476. client_data->remote_write(client_data, GPIOSEL_VWAKEINT,
  477. GPIOSEL);
  478. client_data->remote_write(client_data, INTMASK_VWAKEOUT,
  479. INTMASK);
  480. return ret;
  481. }
  482. static int sapphire_mddi_panel_blank(
  483. struct msm_mddi_bridge_platform_data *bridge_data,
  484. struct msm_mddi_client_data *client_data)
  485. {
  486. int panel_id, ret = 0;
  487. panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  488. client_data->auto_hibernate(client_data, 0);
  489. switch (panel_id) {
  490. case 0:
  491. printk(KERN_DEBUG "deinit sharp panel\n");
  492. sapphire_process_mddi_table(client_data,
  493. mddi_sharp_deinit_table,
  494. ARRAY_SIZE(mddi_sharp_deinit_table));
  495. break;
  496. case 1:
  497. printk(KERN_DEBUG "deinit tpo panel\n");
  498. sapphire_process_mddi_table(client_data,
  499. mddi_tpo_deinit_table,
  500. ARRAY_SIZE(mddi_tpo_deinit_table));
  501. break;
  502. default:
  503. printk(KERN_DEBUG "unknown panel_id: %d\n", panel_id);
  504. ret = -1;
  505. };
  506. client_data->auto_hibernate(client_data, 1);
  507. mutex_lock(&sapphire_backlight_lock);
  508. sapphire_set_backlight_level(0);
  509. sapphire_backlight_off = 1;
  510. mutex_unlock(&sapphire_backlight_lock);
  511. client_data->remote_write(client_data, 0, SYSCLKENA);
  512. client_data->remote_write(client_data, 1, DPSUS);
  513. return ret;
  514. }
  515. /* Initial sequence of sharp panel with Novatek NT35399 MDDI client */
  516. static const struct mddi_table sharp2_init_table[] = {
  517. { 0x02A0, 0x00 },
  518. { 0x02A1, 0x00 },
  519. { 0x02A2, 0x3F },
  520. { 0x02A3, 0x01 },
  521. { 0x02B0, 0x00 },
  522. { 0x02B1, 0x00 },
  523. { 0x02B2, 0xDF },
  524. { 0x02B3, 0x01 },
  525. { 0x02D0, 0x00 },
  526. { 0x02D1, 0x00 },
  527. { 0x02D2, 0x00 },
  528. { 0x02D3, 0x00 },
  529. { 0x0350, 0x80 }, /* Set frame tearing effect(FTE) position */
  530. { 0x0351, 0x00 },
  531. { 0x0360, 0x30 },
  532. { 0x0361, 0xC1 },
  533. { 0x0362, 0x00 },
  534. { 0x0370, 0x00 },
  535. { 0x0371, 0xEF },
  536. { 0x0372, 0x01 },
  537. { 0x0B00, 0x10 },
  538. { 0x0B10, 0x00 },
  539. { 0x0B20, 0x22 },
  540. { 0x0B30, 0x46 },
  541. { 0x0B40, 0x07 },
  542. { 0x0B41, 0x1C },
  543. { 0x0B50, 0x0F },
  544. { 0x0B51, 0x7A },
  545. { 0x0B60, 0x16 },
  546. { 0x0B70, 0x0D },
  547. { 0x0B80, 0x04 },
  548. { 0x0B90, 0x07 },
  549. { 0x0BA0, 0x04 },
  550. { 0x0BA1, 0x86 },
  551. { 0x0BB0, 0xFF },
  552. { 0x0BB1, 0x01 },
  553. { 0x0BB2, 0xF7 },
  554. { 0x0BB3, 0x01 },
  555. { 0x0BC0, 0x00 },
  556. { 0x0BC1, 0x00 },
  557. { 0x0BC2, 0x00 },
  558. { 0x0BC3, 0x00 },
  559. { 0x0BE0, 0x01 },
  560. { 0x0BE1, 0x3F },
  561. { 0x0BF0, 0x03 },
  562. { 0x0C10, 0x02 },
  563. { 0x0C30, 0x22 },
  564. { 0x0C31, 0x20 },
  565. { 0x0C40, 0x48 },
  566. { 0x0C41, 0x06 },
  567. { 0xE00, 0x0028},
  568. { 0xE01, 0x002F},
  569. { 0xE02, 0x0032},
  570. { 0xE03, 0x000A},
  571. { 0xE04, 0x0023},
  572. { 0xE05, 0x0024},
  573. { 0xE06, 0x0022},
  574. { 0xE07, 0x0012},
  575. { 0xE08, 0x000D},
  576. { 0xE09, 0x0035},
  577. { 0xE0A, 0x000E},
  578. { 0xE0B, 0x001A},
  579. { 0xE0C, 0x003C},
  580. { 0xE0D, 0x003A},
  581. { 0xE0E, 0x0050},
  582. { 0xE0F, 0x0069},
  583. { 0xE10, 0x0006},
  584. { 0xE11, 0x001F},
  585. { 0xE12, 0x0035},
  586. { 0xE13, 0x0020},
  587. { 0xE14, 0x0043},
  588. { 0xE15, 0x0030},
  589. { 0xE16, 0x003C},
  590. { 0xE17, 0x0010},
  591. { 0xE18, 0x0009},
  592. { 0xE19, 0x0051},
  593. { 0xE1A, 0x001D},
  594. { 0xE1B, 0x003C},
  595. { 0xE1C, 0x0053},
  596. { 0xE1D, 0x0041},
  597. { 0xE1E, 0x0045},
  598. { 0xE1F, 0x004B},
  599. { 0xE20, 0x000A},
  600. { 0xE21, 0x0014},
  601. { 0xE22, 0x001C},
  602. { 0xE23, 0x0013},
  603. { 0xE24, 0x002E},
  604. { 0xE25, 0x0029},
  605. { 0xE26, 0x001B},
  606. { 0xE27, 0x0014},
  607. { 0xE28, 0x000E},
  608. { 0xE29, 0x0032},
  609. { 0xE2A, 0x000D},
  610. { 0xE2B, 0x001B},
  611. { 0xE2C, 0x0033},
  612. { 0xE2D, 0x0033},
  613. { 0xE2E, 0x005B},
  614. { 0xE2F, 0x0069},
  615. { 0xE30, 0x0006},
  616. { 0xE31, 0x0014},
  617. { 0xE32, 0x003D},
  618. { 0xE33, 0x0029},
  619. { 0xE34, 0x0042},
  620. { 0xE35, 0x0032},
  621. { 0xE36, 0x003F},
  622. { 0xE37, 0x000E},
  623. { 0xE38, 0x0008},
  624. { 0xE39, 0x0059},
  625. { 0xE3A, 0x0015},
  626. { 0xE3B, 0x002E},
  627. { 0xE3C, 0x0049},
  628. { 0xE3D, 0x0058},
  629. { 0xE3E, 0x0061},
  630. { 0xE3F, 0x006B},
  631. { 0xE40, 0x000A},
  632. { 0xE41, 0x001A},
  633. { 0xE42, 0x0022},
  634. { 0xE43, 0x0014},
  635. { 0xE44, 0x002F},
  636. { 0xE45, 0x002A},
  637. { 0xE46, 0x001A},
  638. { 0xE47, 0x0014},
  639. { 0xE48, 0x000E},
  640. { 0xE49, 0x002F},
  641. { 0xE4A, 0x000F},
  642. { 0xE4B, 0x001B},
  643. { 0xE4C, 0x0030},
  644. { 0xE4D, 0x002C},
  645. { 0xE4E, 0x0051},
  646. { 0xE4F, 0x0069},
  647. { 0xE50, 0x0006},
  648. { 0xE51, 0x001E},
  649. { 0xE52, 0x0043},
  650. { 0xE53, 0x002F},
  651. { 0xE54, 0x0043},
  652. { 0xE55, 0x0032},
  653. { 0xE56, 0x0043},
  654. { 0xE57, 0x000D},
  655. { 0xE58, 0x0008},
  656. { 0xE59, 0x0059},
  657. { 0xE5A, 0x0016},
  658. { 0xE5B, 0x0030},
  659. { 0xE5C, 0x004B},
  660. { 0xE5D, 0x0051},
  661. { 0xE5E, 0x005A},
  662. { 0xE5F, 0x006B},
  663. { 0x0290, 0x01 },
  664. };
  665. #undef TPO2_ONE_GAMMA
  666. /* Initial sequence of TPO panel with Novatek NT35399 MDDI client */
  667. static const struct mddi_table tpo2_init_table[] = {
  668. /* Panel interface control */
  669. { 0xB30, 0x44 },
  670. { 0xB40, 0x00 },
  671. { 0xB41, 0x87 },
  672. { 0xB50, 0x06 },
  673. { 0xB51, 0x7B },
  674. { 0xB60, 0x0E },
  675. { 0xB70, 0x0F },
  676. { 0xB80, 0x03 },
  677. { 0xB90, 0x00 },
  678. { 0x350, 0x70 }, /* FTE is at line 0x70 */
  679. /* Entry Mode */
  680. { 0x360, 0x30 },
  681. { 0x361, 0xC1 },
  682. { 0x362, 0x04 },
  683. /* 0x2 for gray scale gamma correction, 0x12 for RGB gamma correction */
  684. #ifdef TPO2_ONE_GAMMA
  685. { 0xB00, 0x02 },
  686. #else
  687. { 0xB00, 0x12 },
  688. #endif
  689. /* Driver output control */
  690. { 0x371, 0xEF },
  691. { 0x372, 0x03 },
  692. /* DCDC on glass control */
  693. { 0xC31, 0x10 },
  694. { 0xBA0, 0x00 },
  695. { 0xBA1, 0x86 },
  696. /* VCOMH voltage control */
  697. { 0xC50, 0x3b },
  698. /* Special function control */
  699. { 0xC10, 0x82 },
  700. /* Power control */
  701. { 0xC40, 0x44 },
  702. { 0xC41, 0x02 },
  703. /* Source output control */
  704. { 0xBE0, 0x01 },
  705. { 0xBE1, 0x00 },
  706. /* Windows address setting */
  707. { 0x2A0, 0x00 },
  708. { 0x2A1, 0x00 },
  709. { 0x2A2, 0x3F },
  710. { 0x2A3, 0x01 },
  711. { 0x2B0, 0x00 },
  712. { 0x2B1, 0x00 },
  713. { 0x2B2, 0xDF },
  714. { 0x2B3, 0x01 },
  715. /* RAM address setting */
  716. { 0x2D0, 0x00 },
  717. { 0x2D1, 0x00 },
  718. { 0x2D2, 0x00 },
  719. { 0x2D3, 0x00 },
  720. { 0xF20, 0x55 },
  721. { 0xF21, 0xAA },
  722. { 0xF22, 0x66 },
  723. { 0xF57, 0x45 },
  724. /*
  725. * The NT35399 provides gray or RGB gamma correction table,
  726. * which determinated by register-0xb00, and following table
  727. */
  728. #ifdef TPO2_ONE_GAMMA
  729. /* Positive Gamma setting */
  730. { 0xE00, 0x04 },
  731. { 0xE01, 0x12 },
  732. { 0xE02, 0x18 },
  733. { 0xE03, 0x10 },
  734. { 0xE04, 0x29 },
  735. { 0xE05, 0x26 },
  736. { 0xE06, 0x1f },
  737. { 0xE07, 0x11 },
  738. { 0xE08, 0x0c },
  739. { 0xE09, 0x3a },
  740. { 0xE0A, 0x0d },
  741. { 0xE0B, 0x28 },
  742. { 0xE0C, 0x40 },
  743. { 0xE0D, 0x4e },
  744. { 0xE0E, 0x6f },
  745. { 0xE0F, 0x5E },
  746. /* Negative Gamma setting */
  747. { 0xE10, 0x0B },
  748. { 0xE11, 0x00 },
  749. { 0xE12, 0x00 },
  750. { 0xE13, 0x1F },
  751. { 0xE14, 0x4b },
  752. { 0xE15, 0x33 },
  753. { 0xE16, 0x13 },
  754. { 0xE17, 0x12 },
  755. { 0xE18, 0x0d },
  756. { 0xE19, 0x2f },
  757. { 0xE1A, 0x16 },
  758. { 0xE1B, 0x2e },
  759. { 0xE1C, 0x49 },
  760. { 0xE1D, 0x41 },
  761. { 0xE1E, 0x46 },
  762. { 0xE1F, 0x55 },
  763. #else
  764. /* Red Positive Gamma */
  765. { 0xE00, 0x0f },
  766. { 0xE01, 0x19 },
  767. { 0xE02, 0x22 },
  768. { 0xE03, 0x0b },
  769. { 0xE04, 0x23 },
  770. { 0xE05, 0x23 },
  771. { 0xE06, 0x14 },
  772. { 0xE07, 0x13 },
  773. { 0xE08, 0x0f },
  774. { 0xE09, 0x2a },
  775. { 0xE0A, 0x0d },
  776. { 0xE0B, 0x26 },
  777. { 0xE0C, 0x43 },
  778. { 0xE0D, 0x20 },
  779. { 0xE0E, 0x2a },
  780. { 0xE0F, 0x5c },
  781. /* Red Negative Gamma */
  782. { 0xE10, 0x0d },
  783. { 0xE11, 0x45 },
  784. { 0xE12, 0x4c },
  785. { 0xE13, 0x1c },
  786. { 0xE14, 0x4d },
  787. { 0xE15, 0x33 },
  788. { 0xE16, 0x23 },
  789. { 0xE17, 0x0f },
  790. { 0xE18, 0x0b },
  791. { 0xE19, 0x3a },
  792. { 0xE1A, 0x19 },
  793. { 0xE1B, 0x32 },
  794. { 0xE1C, 0x4e },
  795. { 0xE1D, 0x37 },
  796. { 0xE1E, 0x38 },
  797. { 0xE1F, 0x3b },
  798. /* Green Positive Gamma */
  799. { 0xE20, 0x00 },
  800. { 0xE21, 0x09 },
  801. { 0xE22, 0x10 },
  802. { 0xE23, 0x0f },
  803. { 0xE24, 0x29 },
  804. { 0xE25, 0x23 },
  805. { 0xE26, 0x0b },
  806. { 0xE27, 0x14 },
  807. { 0xE28, 0x12 },
  808. { 0xE29, 0x25 },
  809. { 0xE2A, 0x12 },
  810. { 0xE2B, 0x2f },
  811. { 0xE2C, 0x43 },
  812. { 0xE2D, 0x2d },
  813. { 0xE2E, 0x52 },
  814. { 0xE2F, 0x61 },
  815. /* Green Negative Gamma */
  816. { 0xE30, 0x08 },
  817. { 0xE31, 0x1d },
  818. { 0xE32, 0x3f },
  819. { 0xE33, 0x1c },
  820. { 0xE34, 0x44 },
  821. { 0xE35, 0x2e },
  822. { 0xE36, 0x28 },
  823. { 0xE37, 0x0c },
  824. { 0xE38, 0x0a },
  825. { 0xE39, 0x42 },
  826. { 0xE3A, 0x17 },
  827. { 0xE3B, 0x30 },
  828. { 0xE3C, 0x4b },
  829. { 0xE3D, 0x3f },
  830. { 0xE3E, 0x43 },
  831. { 0xE3F, 0x45 },
  832. /* Blue Positive Gamma */
  833. { 0xE40, 0x32 },
  834. { 0xE41, 0x32 },
  835. { 0xE42, 0x31 },
  836. { 0xE43, 0x06 },
  837. { 0xE44, 0x08 },
  838. { 0xE45, 0x0d },
  839. { 0xE46, 0x04 },
  840. { 0xE47, 0x14 },
  841. { 0xE48, 0x0f },
  842. { 0xE49, 0x1d },
  843. { 0xE4A, 0x1a },
  844. { 0xE4B, 0x39 },
  845. { 0xE4C, 0x4c },
  846. { 0xE4D, 0x1e },
  847. { 0xE4E, 0x43 },
  848. { 0xE4F, 0x61 },
  849. /* Blue Negative Gamma */
  850. { 0xE50, 0x08 },
  851. { 0xE51, 0x2c },
  852. { 0xE52, 0x4e },
  853. { 0xE53, 0x13 },
  854. { 0xE54, 0x3a },
  855. { 0xE55, 0x26 },
  856. { 0xE56, 0x30 },
  857. { 0xE57, 0x0f },
  858. { 0xE58, 0x0a },
  859. { 0xE59, 0x49 },
  860. { 0xE5A, 0x34 },
  861. { 0xE5B, 0x4a },
  862. { 0xE5C, 0x53 },
  863. { 0xE5D, 0x28 },
  864. { 0xE5E, 0x26 },
  865. { 0xE5F, 0x27 },
  866. #endif
  867. /* Sleep in mode */
  868. { 0x110, 0x00 },
  869. { 0x1, 0x23 },
  870. /* Display on mode */
  871. { 0x290, 0x00 },
  872. { 0x1, 0x27 },
  873. /* Driver output control */
  874. { 0x372, 0x01 },
  875. { 0x1, 0x40 },
  876. /* Display on mode */
  877. { 0x290, 0x01 },
  878. };
  879. static const struct mddi_table tpo2_display_on[] = {
  880. { 0x290, 0x01 },
  881. };
  882. static const struct mddi_table tpo2_display_off[] = {
  883. { 0x110, 0x01 },
  884. { 0x290, 0x00 },
  885. { 0x1, 100 },
  886. };
  887. static const struct mddi_table tpo2_power_off[] = {
  888. { 0x0110, 0x01 },
  889. };
  890. static int nt35399_detect_panel(struct msm_mddi_client_data *client_data)
  891. {
  892. int id = -1, i ;
  893. /* If the MDDI client is failed to report the panel ID,
  894. * perform retrial 5 times.
  895. */
  896. for( i=0; i < 5; i++ ) {
  897. client_data->remote_write(client_data, 0, 0x110);
  898. msleep(5);
  899. id = client_data->remote_read(client_data, userid) ;
  900. if( id == 0 || id == 1 ) {
  901. if(i==0) {
  902. printk(KERN_ERR "%s: got valid panel ID=%d, "
  903. "without retry\n",
  904. __FUNCTION__, id);
  905. }
  906. else {
  907. printk(KERN_ERR "%s: got valid panel ID=%d, "
  908. "after %d retry\n",
  909. __FUNCTION__, id, i+1);
  910. }
  911. break ;
  912. }
  913. printk(KERN_ERR "%s: got invalid panel ID:%d, trial #%d\n",
  914. __FUNCTION__, id, i+1);
  915. gpio_set_value(MDDI_RST_N, 0);
  916. msleep(5);
  917. gpio_set_value(MDDI_RST_N, 1);
  918. msleep(10);
  919. gpio_set_value(MDDI_RST_N, 0);
  920. udelay(100);
  921. gpio_set_value(MDDI_RST_N, 1);
  922. mdelay(10);
  923. }
  924. printk(KERN_INFO "%s: final panel id=%d\n", __FUNCTION__, id);
  925. switch(id) {
  926. case 0:
  927. return SAPPHIRE_PANEL_TOPPOLY;
  928. case 1:
  929. return SAPPHIRE_PANEL_SHARP;
  930. default :
  931. printk(KERN_ERR "%s(): Invalid panel ID: %d, "
  932. "treat as sharp panel.", __FUNCTION__, id);
  933. return SAPPHIRE_PANEL_SHARP;
  934. }
  935. }
  936. static int nt35399_client_init(
  937. struct msm_mddi_bridge_platform_data *bridge_data,
  938. struct msm_mddi_client_data *client_data)
  939. {
  940. int panel_id;
  941. if (g_panel_inited == 0) {
  942. g_panel_id = panel_id = nt35399_detect_panel(client_data);
  943. g_panel_inited = 1 ;
  944. } else {
  945. gpio_set_value(MDDI_RST_N, 1);
  946. msleep(10);
  947. gpio_set_value(MDDI_RST_N, 0);
  948. udelay(100);
  949. gpio_set_value(MDDI_RST_N, 1);
  950. mdelay(10);
  951. g_panel_id = panel_id = nt35399_detect_panel(client_data);
  952. if (panel_id == -1) {
  953. printk("Invalid panel id\n");
  954. return -1;
  955. }
  956. client_data->auto_hibernate(client_data, 0);
  957. if (panel_id == SAPPHIRE_PANEL_TOPPOLY) {
  958. sapphire_process_mddi_table(client_data, tpo2_init_table,
  959. ARRAY_SIZE(tpo2_init_table));
  960. } else if(panel_id == SAPPHIRE_PANEL_SHARP) {
  961. sapphire_process_mddi_table(client_data, sharp2_init_table,
  962. ARRAY_SIZE(sharp2_init_table));
  963. }
  964. client_data->auto_hibernate(client_data, 1);
  965. }
  966. return 0;
  967. }
  968. static int nt35399_client_uninit(
  969. struct msm_mddi_bridge_platform_data *bridge_data,
  970. struct msm_mddi_client_data *cdata)
  971. {
  972. return 0;
  973. }
  974. static int nt35399_panel_unblank(
  975. struct msm_mddi_bridge_platform_data *bridge_data,
  976. struct msm_mddi_client_data *client_data)
  977. {
  978. int ret = 0;
  979. mdelay(20);
  980. sapphire_set_backlight_level(0);
  981. client_data->auto_hibernate(client_data, 0);
  982. mutex_lock(&sapphire_backlight_lock);
  983. sapphire_set_backlight_level(sapphire_backlight_brightness);
  984. sapphire_backlight_off = 0;
  985. mutex_unlock(&sapphire_backlight_lock);
  986. client_data->auto_hibernate(client_data, 1);
  987. return ret;
  988. }
  989. static int nt35399_panel_blank(
  990. struct msm_mddi_bridge_platform_data *bridge_data,
  991. struct msm_mddi_client_data *client_data)
  992. {
  993. int ret = 0;
  994. client_data->auto_hibernate(client_data, 0);
  995. sapphire_process_mddi_table(client_data, tpo2_display_off,
  996. ARRAY_SIZE(tpo2_display_off));
  997. client_data->auto_hibernate(client_data, 1);
  998. mutex_lock(&sapphire_backlight_lock);
  999. sapphire_set_backlight_level(0);
  1000. sapphire_backlight_off = 1;
  1001. mutex_unlock(&sapphire_backlight_lock);
  1002. return ret;
  1003. }
  1004. static void sapphire_brightness_set(struct led_classdev *led_cdev, enum led_brightness value)
  1005. {
  1006. mutex_lock(&sapphire_backlight_lock);
  1007. sapphire_backlight_brightness = value;
  1008. if (!sapphire_backlight_off)
  1009. sapphire_set_backlight_level(sapphire_backlight_brightness);
  1010. mutex_unlock(&sapphire_backlight_lock);
  1011. }
  1012. static struct led_classdev sapphire_backlight_led = {
  1013. .name = "lcd-backlight",
  1014. .brightness = SAPPHIRE_DEFAULT_BACKLIGHT_BRIGHTNESS,
  1015. .brightness_set = sapphire_brightness_set,
  1016. };
  1017. static int sapphire_backlight_probe(struct platform_device *pdev)
  1018. {
  1019. led_classdev_register(&pdev->dev, &sapphire_backlight_led);
  1020. return 0;
  1021. }
  1022. static int sapphire_backlight_remove(struct platform_device *pdev)
  1023. {
  1024. led_classdev_unregister(&sapphire_backlight_led);
  1025. return 0;
  1026. }
  1027. static struct platform_driver sapphire_backlight_driver = {
  1028. .probe = sapphire_backlight_probe,
  1029. .remove = sapphire_backlight_remove,
  1030. .driver = {
  1031. .name = "sapphire-backlight",
  1032. .owner = THIS_MODULE,
  1033. },
  1034. };
  1035. static struct resource resources_msm_fb[] = {
  1036. {
  1037. .start = SMI64_MSM_FB_BASE,
  1038. .end = SMI64_MSM_FB_BASE + SMI64_MSM_FB_SIZE - 1,
  1039. .flags = IORESOURCE_MEM,
  1040. },
  1041. };
  1042. static struct msm_mddi_bridge_platform_data toshiba_client_data = {
  1043. .init = sapphire_mddi_toshiba_client_init,
  1044. .uninit = sapphire_mddi_toshiba_client_uninit,
  1045. .blank = sapphire_mddi_panel_blank,
  1046. .unblank = sapphire_mddi_panel_unblank,
  1047. .fb_data = {
  1048. .xres = 320,
  1049. .yres = 480,
  1050. .width = 45,
  1051. .height = 67,
  1052. .output_format = 0,
  1053. },
  1054. };
  1055. #define NT35399_MFR_NAME 0x0bda
  1056. #define NT35399_PRODUCT_CODE 0x8a47
  1057. static void nt35399_fixup(uint16_t * mfr_name, uint16_t * product_code)
  1058. {
  1059. printk(KERN_DEBUG "%s: enter.\n", __func__);
  1060. *mfr_name = NT35399_MFR_NAME ;
  1061. *product_code= NT35399_PRODUCT_CODE ;
  1062. }
  1063. static struct msm_mddi_bridge_platform_data nt35399_client_data = {
  1064. .init = nt35399_client_init,
  1065. .uninit = nt35399_client_uninit,
  1066. .blank = nt35399_panel_blank,
  1067. .unblank = nt35399_panel_unblank,
  1068. .fb_data = {
  1069. .xres = 320,
  1070. .yres = 480,
  1071. .output_format = 0,
  1072. },
  1073. };
  1074. static struct msm_mddi_platform_data mddi_pdata = {
  1075. .clk_rate = 122880000,
  1076. .power_client = sapphire_mddi_power_client,
  1077. .fixup = nt35399_fixup,
  1078. .vsync_irq = MSM_GPIO_TO_INT(VSYNC_GPIO),
  1079. .fb_resource = resources_msm_fb,
  1080. .num_clients = 2,
  1081. .client_platform_data = {
  1082. {
  1083. .product_id = (0xd263 << 16 | 0),
  1084. .name = "mddi_c_d263_0000",
  1085. .id = 0,
  1086. .client_data = &toshiba_client_data,
  1087. .clk_rate = 0,
  1088. },
  1089. {
  1090. .product_id =
  1091. (NT35399_MFR_NAME << 16 | NT35399_PRODUCT_CODE),
  1092. .name = "mddi_c_simple" ,
  1093. .id = 0,
  1094. .client_data = &nt35399_client_data,
  1095. .clk_rate = 0,
  1096. },
  1097. },
  1098. };
  1099. static struct platform_device sapphire_backlight = {
  1100. .name = "sapphire-backlight",
  1101. };
  1102. int __init sapphire_init_panel(void)
  1103. {
  1104. int rc = -1;
  1105. uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA); /* GPIO27 */
  1106. if (!machine_is_sapphire())
  1107. return 0;
  1108. /* checking board as soon as possible */
  1109. printk("sapphire_init_panel:machine_is_sapphire=%d, machine_arch_type=%d, MACH_TYPE_SAPPHIRE=%d\r\n", machine_is_sapphire(), machine_arch_type, MACH_TYPE_SAPPHIRE);
  1110. if (!machine_is_sapphire())
  1111. return 0;
  1112. vreg_lcm_2v85 = vreg_get(0, "gp4");
  1113. if (IS_ERR(vreg_lcm_2v85))
  1114. return PTR_ERR(vreg_lcm_2v85);
  1115. msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
  1116. /* setup FB by SMI size */
  1117. if (sapphire_get_smi_size() == 32) {
  1118. resources_msm_fb[0].start = SMI32_MSM_FB_BASE;
  1119. resources_msm_fb[0].end = SMI32_MSM_FB_BASE + SMI32_MSM_FB_SIZE - 1;
  1120. }
  1121. rc = gpio_request(VSYNC_GPIO, "vsync");
  1122. if (rc)
  1123. return rc;
  1124. rc = gpio_direction_input(VSYNC_GPIO);
  1125. if (rc)
  1126. return rc;
  1127. rc = platform_device_register(&msm_device_mdp);
  1128. if (rc)
  1129. return rc;
  1130. msm_device_mddi0.dev.platform_data = &mddi_pdata;
  1131. rc = platform_device_register(&msm_device_mddi0);
  1132. if (rc)
  1133. return rc;
  1134. platform_device_register(&sapphire_backlight);
  1135. return platform_driver_register(&sapphire_backlight_driver);
  1136. }
  1137. device_initcall(sapphire_init_panel);