hx8357.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * Driver for the Himax HX-8357 LCD Controller
  3. *
  4. * Copyright 2012 Free Electrons
  5. *
  6. * Licensed under the GPLv2 or later.
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/lcd.h>
  10. #include <linux/module.h>
  11. #include <linux/of.h>
  12. #include <linux/of_device.h>
  13. #include <linux/of_gpio.h>
  14. #include <linux/spi/spi.h>
  15. #define HX8357_NUM_IM_PINS 3
  16. #define HX8357_SWRESET 0x01
  17. #define HX8357_GET_RED_CHANNEL 0x06
  18. #define HX8357_GET_GREEN_CHANNEL 0x07
  19. #define HX8357_GET_BLUE_CHANNEL 0x08
  20. #define HX8357_GET_POWER_MODE 0x0a
  21. #define HX8357_GET_MADCTL 0x0b
  22. #define HX8357_GET_PIXEL_FORMAT 0x0c
  23. #define HX8357_GET_DISPLAY_MODE 0x0d
  24. #define HX8357_GET_SIGNAL_MODE 0x0e
  25. #define HX8357_GET_DIAGNOSTIC_RESULT 0x0f
  26. #define HX8357_ENTER_SLEEP_MODE 0x10
  27. #define HX8357_EXIT_SLEEP_MODE 0x11
  28. #define HX8357_ENTER_PARTIAL_MODE 0x12
  29. #define HX8357_ENTER_NORMAL_MODE 0x13
  30. #define HX8357_EXIT_INVERSION_MODE 0x20
  31. #define HX8357_ENTER_INVERSION_MODE 0x21
  32. #define HX8357_SET_DISPLAY_OFF 0x28
  33. #define HX8357_SET_DISPLAY_ON 0x29
  34. #define HX8357_SET_COLUMN_ADDRESS 0x2a
  35. #define HX8357_SET_PAGE_ADDRESS 0x2b
  36. #define HX8357_WRITE_MEMORY_START 0x2c
  37. #define HX8357_READ_MEMORY_START 0x2e
  38. #define HX8357_SET_PARTIAL_AREA 0x30
  39. #define HX8357_SET_SCROLL_AREA 0x33
  40. #define HX8357_SET_TEAR_OFF 0x34
  41. #define HX8357_SET_TEAR_ON 0x35
  42. #define HX8357_SET_ADDRESS_MODE 0x36
  43. #define HX8357_SET_SCROLL_START 0x37
  44. #define HX8357_EXIT_IDLE_MODE 0x38
  45. #define HX8357_ENTER_IDLE_MODE 0x39
  46. #define HX8357_SET_PIXEL_FORMAT 0x3a
  47. #define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1)
  48. #define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5)
  49. #define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6)
  50. #define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4)
  51. #define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4)
  52. #define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4)
  53. #define HX8357_WRITE_MEMORY_CONTINUE 0x3c
  54. #define HX8357_READ_MEMORY_CONTINUE 0x3e
  55. #define HX8357_SET_TEAR_SCAN_LINES 0x44
  56. #define HX8357_GET_SCAN_LINES 0x45
  57. #define HX8357_READ_DDB_START 0xa1
  58. #define HX8357_SET_DISPLAY_MODE 0xb4
  59. #define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3)
  60. #define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4)
  61. #define HX8357_SET_PANEL_DRIVING 0xc0
  62. #define HX8357_SET_DISPLAY_FRAME 0xc5
  63. #define HX8357_SET_RGB 0xc6
  64. #define HX8357_SET_RGB_ENABLE_HIGH (1 << 1)
  65. #define HX8357_SET_GAMMA 0xc8
  66. #define HX8357_SET_POWER 0xd0
  67. #define HX8357_SET_VCOM 0xd1
  68. #define HX8357_SET_POWER_NORMAL 0xd2
  69. #define HX8357_SET_PANEL_RELATED 0xe9
  70. struct hx8357_data {
  71. unsigned im_pins[HX8357_NUM_IM_PINS];
  72. unsigned reset;
  73. struct spi_device *spi;
  74. int state;
  75. };
  76. static u8 hx8357_seq_power[] = {
  77. HX8357_SET_POWER, 0x44, 0x41, 0x06,
  78. };
  79. static u8 hx8357_seq_vcom[] = {
  80. HX8357_SET_VCOM, 0x40, 0x10,
  81. };
  82. static u8 hx8357_seq_power_normal[] = {
  83. HX8357_SET_POWER_NORMAL, 0x05, 0x12,
  84. };
  85. static u8 hx8357_seq_panel_driving[] = {
  86. HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
  87. };
  88. static u8 hx8357_seq_display_frame[] = {
  89. HX8357_SET_DISPLAY_FRAME, 0x0c,
  90. };
  91. static u8 hx8357_seq_panel_related[] = {
  92. HX8357_SET_PANEL_RELATED, 0x01,
  93. };
  94. static u8 hx8357_seq_undefined1[] = {
  95. 0xea, 0x03, 0x00, 0x00,
  96. };
  97. static u8 hx8357_seq_undefined2[] = {
  98. 0xeb, 0x40, 0x54, 0x26, 0xdb,
  99. };
  100. static u8 hx8357_seq_gamma[] = {
  101. HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
  102. 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
  103. };
  104. static u8 hx8357_seq_address_mode[] = {
  105. HX8357_SET_ADDRESS_MODE, 0xc0,
  106. };
  107. static u8 hx8357_seq_pixel_format[] = {
  108. HX8357_SET_PIXEL_FORMAT,
  109. HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
  110. HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
  111. };
  112. static u8 hx8357_seq_column_address[] = {
  113. HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
  114. };
  115. static u8 hx8357_seq_page_address[] = {
  116. HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
  117. };
  118. static u8 hx8357_seq_rgb[] = {
  119. HX8357_SET_RGB, 0x02,
  120. };
  121. static u8 hx8357_seq_display_mode[] = {
  122. HX8357_SET_DISPLAY_MODE,
  123. HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
  124. HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
  125. };
  126. static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
  127. u8 *txbuf, u16 txlen,
  128. u8 *rxbuf, u16 rxlen)
  129. {
  130. struct hx8357_data *lcd = lcd_get_data(lcdev);
  131. struct spi_message msg;
  132. struct spi_transfer xfer[2];
  133. u16 *local_txbuf = NULL;
  134. int ret = 0;
  135. memset(xfer, 0, sizeof(xfer));
  136. spi_message_init(&msg);
  137. if (txlen) {
  138. int i;
  139. local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
  140. if (!local_txbuf)
  141. return -ENOMEM;
  142. for (i = 0; i < txlen; i++) {
  143. local_txbuf[i] = txbuf[i];
  144. if (i > 0)
  145. local_txbuf[i] |= 1 << 8;
  146. }
  147. xfer[0].len = 2 * txlen;
  148. xfer[0].bits_per_word = 9;
  149. xfer[0].tx_buf = local_txbuf;
  150. spi_message_add_tail(&xfer[0], &msg);
  151. }
  152. if (rxlen) {
  153. xfer[1].len = rxlen;
  154. xfer[1].bits_per_word = 8;
  155. xfer[1].rx_buf = rxbuf;
  156. spi_message_add_tail(&xfer[1], &msg);
  157. }
  158. ret = spi_sync(lcd->spi, &msg);
  159. if (ret < 0)
  160. dev_err(&lcdev->dev, "Couldn't send SPI data\n");
  161. if (txlen)
  162. kfree(local_txbuf);
  163. return ret;
  164. }
  165. static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
  166. u8 *value, u8 len)
  167. {
  168. return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
  169. }
  170. static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
  171. u8 value)
  172. {
  173. return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
  174. }
  175. static int hx8357_enter_standby(struct lcd_device *lcdev)
  176. {
  177. int ret;
  178. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
  179. if (ret < 0)
  180. return ret;
  181. usleep_range(10000, 12000);
  182. ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
  183. if (ret < 0)
  184. return ret;
  185. msleep(120);
  186. return 0;
  187. }
  188. static int hx8357_exit_standby(struct lcd_device *lcdev)
  189. {
  190. int ret;
  191. ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
  192. if (ret < 0)
  193. return ret;
  194. msleep(120);
  195. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
  196. if (ret < 0)
  197. return ret;
  198. return 0;
  199. }
  200. static int hx8357_lcd_init(struct lcd_device *lcdev)
  201. {
  202. struct hx8357_data *lcd = lcd_get_data(lcdev);
  203. int ret;
  204. /*
  205. * Set the interface selection pins to SPI mode, with three
  206. * wires
  207. */
  208. gpio_set_value_cansleep(lcd->im_pins[0], 1);
  209. gpio_set_value_cansleep(lcd->im_pins[1], 0);
  210. gpio_set_value_cansleep(lcd->im_pins[2], 1);
  211. /* Reset the screen */
  212. gpio_set_value(lcd->reset, 1);
  213. usleep_range(10000, 12000);
  214. gpio_set_value(lcd->reset, 0);
  215. usleep_range(10000, 12000);
  216. gpio_set_value(lcd->reset, 1);
  217. msleep(120);
  218. ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
  219. ARRAY_SIZE(hx8357_seq_power));
  220. if (ret < 0)
  221. return ret;
  222. ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
  223. ARRAY_SIZE(hx8357_seq_vcom));
  224. if (ret < 0)
  225. return ret;
  226. ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
  227. ARRAY_SIZE(hx8357_seq_power_normal));
  228. if (ret < 0)
  229. return ret;
  230. ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
  231. ARRAY_SIZE(hx8357_seq_panel_driving));
  232. if (ret < 0)
  233. return ret;
  234. ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
  235. ARRAY_SIZE(hx8357_seq_display_frame));
  236. if (ret < 0)
  237. return ret;
  238. ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
  239. ARRAY_SIZE(hx8357_seq_panel_related));
  240. if (ret < 0)
  241. return ret;
  242. ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
  243. ARRAY_SIZE(hx8357_seq_undefined1));
  244. if (ret < 0)
  245. return ret;
  246. ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
  247. ARRAY_SIZE(hx8357_seq_undefined2));
  248. if (ret < 0)
  249. return ret;
  250. ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
  251. ARRAY_SIZE(hx8357_seq_gamma));
  252. if (ret < 0)
  253. return ret;
  254. ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
  255. ARRAY_SIZE(hx8357_seq_address_mode));
  256. if (ret < 0)
  257. return ret;
  258. ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
  259. ARRAY_SIZE(hx8357_seq_pixel_format));
  260. if (ret < 0)
  261. return ret;
  262. ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
  263. ARRAY_SIZE(hx8357_seq_column_address));
  264. if (ret < 0)
  265. return ret;
  266. ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
  267. ARRAY_SIZE(hx8357_seq_page_address));
  268. if (ret < 0)
  269. return ret;
  270. ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
  271. ARRAY_SIZE(hx8357_seq_rgb));
  272. if (ret < 0)
  273. return ret;
  274. ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
  275. ARRAY_SIZE(hx8357_seq_display_mode));
  276. if (ret < 0)
  277. return ret;
  278. ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
  279. if (ret < 0)
  280. return ret;
  281. msleep(120);
  282. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
  283. if (ret < 0)
  284. return ret;
  285. usleep_range(5000, 7000);
  286. ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
  287. if (ret < 0)
  288. return ret;
  289. return 0;
  290. }
  291. #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
  292. static int hx8357_set_power(struct lcd_device *lcdev, int power)
  293. {
  294. struct hx8357_data *lcd = lcd_get_data(lcdev);
  295. int ret = 0;
  296. if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
  297. ret = hx8357_exit_standby(lcdev);
  298. else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
  299. ret = hx8357_enter_standby(lcdev);
  300. if (ret == 0)
  301. lcd->state = power;
  302. else
  303. dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
  304. return ret;
  305. }
  306. static int hx8357_get_power(struct lcd_device *lcdev)
  307. {
  308. struct hx8357_data *lcd = lcd_get_data(lcdev);
  309. return lcd->state;
  310. }
  311. static struct lcd_ops hx8357_ops = {
  312. .set_power = hx8357_set_power,
  313. .get_power = hx8357_get_power,
  314. };
  315. static int hx8357_probe(struct spi_device *spi)
  316. {
  317. struct lcd_device *lcdev;
  318. struct hx8357_data *lcd;
  319. int i, ret;
  320. lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
  321. if (!lcd) {
  322. dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n");
  323. return -ENOMEM;
  324. }
  325. ret = spi_setup(spi);
  326. if (ret < 0) {
  327. dev_err(&spi->dev, "SPI setup failed.\n");
  328. return ret;
  329. }
  330. lcd->spi = spi;
  331. lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
  332. if (!gpio_is_valid(lcd->reset)) {
  333. dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
  334. return -EINVAL;
  335. }
  336. ret = devm_gpio_request_one(&spi->dev, lcd->reset,
  337. GPIOF_OUT_INIT_HIGH,
  338. "hx8357-reset");
  339. if (ret) {
  340. dev_err(&spi->dev,
  341. "failed to request gpio %d: %d\n",
  342. lcd->reset, ret);
  343. return -EINVAL;
  344. }
  345. for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
  346. lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
  347. "im-gpios", i);
  348. if (lcd->im_pins[i] == -EPROBE_DEFER) {
  349. dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
  350. return -EPROBE_DEFER;
  351. }
  352. if (!gpio_is_valid(lcd->im_pins[i])) {
  353. dev_err(&spi->dev, "Missing dt property: im-gpios\n");
  354. return -EINVAL;
  355. }
  356. ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
  357. GPIOF_OUT_INIT_LOW, "im_pins");
  358. if (ret) {
  359. dev_err(&spi->dev, "failed to request gpio %d: %d\n",
  360. lcd->im_pins[i], ret);
  361. return -EINVAL;
  362. }
  363. }
  364. lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops);
  365. if (IS_ERR(lcdev)) {
  366. ret = PTR_ERR(lcdev);
  367. return ret;
  368. }
  369. spi_set_drvdata(spi, lcdev);
  370. ret = hx8357_lcd_init(lcdev);
  371. if (ret) {
  372. dev_err(&spi->dev, "Couldn't initialize panel\n");
  373. goto init_error;
  374. }
  375. dev_info(&spi->dev, "Panel probed\n");
  376. return 0;
  377. init_error:
  378. lcd_device_unregister(lcdev);
  379. return ret;
  380. }
  381. static int hx8357_remove(struct spi_device *spi)
  382. {
  383. struct lcd_device *lcdev = spi_get_drvdata(spi);
  384. lcd_device_unregister(lcdev);
  385. return 0;
  386. }
  387. static const struct of_device_id hx8357_dt_ids[] = {
  388. { .compatible = "himax,hx8357" },
  389. {},
  390. };
  391. MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
  392. static struct spi_driver hx8357_driver = {
  393. .probe = hx8357_probe,
  394. .remove = hx8357_remove,
  395. .driver = {
  396. .name = "hx8357",
  397. .of_match_table = of_match_ptr(hx8357_dt_ids),
  398. },
  399. };
  400. module_spi_driver(hx8357_driver);
  401. MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
  402. MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
  403. MODULE_LICENSE("GPL");