hx8357.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  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. bool use_im_pins;
  76. };
  77. static u8 hx8357_seq_power[] = {
  78. HX8357_SET_POWER, 0x44, 0x41, 0x06,
  79. };
  80. static u8 hx8357_seq_vcom[] = {
  81. HX8357_SET_VCOM, 0x40, 0x10,
  82. };
  83. static u8 hx8357_seq_power_normal[] = {
  84. HX8357_SET_POWER_NORMAL, 0x05, 0x12,
  85. };
  86. static u8 hx8357_seq_panel_driving[] = {
  87. HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
  88. };
  89. static u8 hx8357_seq_display_frame[] = {
  90. HX8357_SET_DISPLAY_FRAME, 0x0c,
  91. };
  92. static u8 hx8357_seq_panel_related[] = {
  93. HX8357_SET_PANEL_RELATED, 0x01,
  94. };
  95. static u8 hx8357_seq_undefined1[] = {
  96. 0xea, 0x03, 0x00, 0x00,
  97. };
  98. static u8 hx8357_seq_undefined2[] = {
  99. 0xeb, 0x40, 0x54, 0x26, 0xdb,
  100. };
  101. static u8 hx8357_seq_gamma[] = {
  102. HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
  103. 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
  104. };
  105. static u8 hx8357_seq_address_mode[] = {
  106. HX8357_SET_ADDRESS_MODE, 0xc0,
  107. };
  108. static u8 hx8357_seq_pixel_format[] = {
  109. HX8357_SET_PIXEL_FORMAT,
  110. HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
  111. HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
  112. };
  113. static u8 hx8357_seq_column_address[] = {
  114. HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
  115. };
  116. static u8 hx8357_seq_page_address[] = {
  117. HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
  118. };
  119. static u8 hx8357_seq_rgb[] = {
  120. HX8357_SET_RGB, 0x02,
  121. };
  122. static u8 hx8357_seq_display_mode[] = {
  123. HX8357_SET_DISPLAY_MODE,
  124. HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
  125. HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
  126. };
  127. static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
  128. u8 *txbuf, u16 txlen,
  129. u8 *rxbuf, u16 rxlen)
  130. {
  131. struct hx8357_data *lcd = lcd_get_data(lcdev);
  132. struct spi_message msg;
  133. struct spi_transfer xfer[2];
  134. u16 *local_txbuf = NULL;
  135. int ret = 0;
  136. memset(xfer, 0, sizeof(xfer));
  137. spi_message_init(&msg);
  138. if (txlen) {
  139. int i;
  140. local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
  141. if (!local_txbuf)
  142. return -ENOMEM;
  143. for (i = 0; i < txlen; i++) {
  144. local_txbuf[i] = txbuf[i];
  145. if (i > 0)
  146. local_txbuf[i] |= 1 << 8;
  147. }
  148. xfer[0].len = 2 * txlen;
  149. xfer[0].bits_per_word = 9;
  150. xfer[0].tx_buf = local_txbuf;
  151. spi_message_add_tail(&xfer[0], &msg);
  152. }
  153. if (rxlen) {
  154. xfer[1].len = rxlen;
  155. xfer[1].bits_per_word = 8;
  156. xfer[1].rx_buf = rxbuf;
  157. spi_message_add_tail(&xfer[1], &msg);
  158. }
  159. ret = spi_sync(lcd->spi, &msg);
  160. if (ret < 0)
  161. dev_err(&lcdev->dev, "Couldn't send SPI data\n");
  162. if (txlen)
  163. kfree(local_txbuf);
  164. return ret;
  165. }
  166. static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
  167. u8 *value, u8 len)
  168. {
  169. return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
  170. }
  171. static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
  172. u8 value)
  173. {
  174. return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
  175. }
  176. static int hx8357_enter_standby(struct lcd_device *lcdev)
  177. {
  178. int ret;
  179. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
  180. if (ret < 0)
  181. return ret;
  182. usleep_range(10000, 12000);
  183. ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
  184. if (ret < 0)
  185. return ret;
  186. msleep(120);
  187. return 0;
  188. }
  189. static int hx8357_exit_standby(struct lcd_device *lcdev)
  190. {
  191. int ret;
  192. ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
  193. if (ret < 0)
  194. return ret;
  195. msleep(120);
  196. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
  197. if (ret < 0)
  198. return ret;
  199. return 0;
  200. }
  201. static int hx8357_lcd_init(struct lcd_device *lcdev)
  202. {
  203. struct hx8357_data *lcd = lcd_get_data(lcdev);
  204. int ret;
  205. /*
  206. * Set the interface selection pins to SPI mode, with three
  207. * wires
  208. */
  209. if (lcd->use_im_pins) {
  210. gpio_set_value_cansleep(lcd->im_pins[0], 1);
  211. gpio_set_value_cansleep(lcd->im_pins[1], 0);
  212. gpio_set_value_cansleep(lcd->im_pins[2], 1);
  213. }
  214. /* Reset the screen */
  215. gpio_set_value(lcd->reset, 1);
  216. usleep_range(10000, 12000);
  217. gpio_set_value(lcd->reset, 0);
  218. usleep_range(10000, 12000);
  219. gpio_set_value(lcd->reset, 1);
  220. msleep(120);
  221. ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
  222. ARRAY_SIZE(hx8357_seq_power));
  223. if (ret < 0)
  224. return ret;
  225. ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
  226. ARRAY_SIZE(hx8357_seq_vcom));
  227. if (ret < 0)
  228. return ret;
  229. ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
  230. ARRAY_SIZE(hx8357_seq_power_normal));
  231. if (ret < 0)
  232. return ret;
  233. ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
  234. ARRAY_SIZE(hx8357_seq_panel_driving));
  235. if (ret < 0)
  236. return ret;
  237. ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
  238. ARRAY_SIZE(hx8357_seq_display_frame));
  239. if (ret < 0)
  240. return ret;
  241. ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
  242. ARRAY_SIZE(hx8357_seq_panel_related));
  243. if (ret < 0)
  244. return ret;
  245. ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
  246. ARRAY_SIZE(hx8357_seq_undefined1));
  247. if (ret < 0)
  248. return ret;
  249. ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
  250. ARRAY_SIZE(hx8357_seq_undefined2));
  251. if (ret < 0)
  252. return ret;
  253. ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
  254. ARRAY_SIZE(hx8357_seq_gamma));
  255. if (ret < 0)
  256. return ret;
  257. ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
  258. ARRAY_SIZE(hx8357_seq_address_mode));
  259. if (ret < 0)
  260. return ret;
  261. ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
  262. ARRAY_SIZE(hx8357_seq_pixel_format));
  263. if (ret < 0)
  264. return ret;
  265. ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
  266. ARRAY_SIZE(hx8357_seq_column_address));
  267. if (ret < 0)
  268. return ret;
  269. ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
  270. ARRAY_SIZE(hx8357_seq_page_address));
  271. if (ret < 0)
  272. return ret;
  273. ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
  274. ARRAY_SIZE(hx8357_seq_rgb));
  275. if (ret < 0)
  276. return ret;
  277. ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
  278. ARRAY_SIZE(hx8357_seq_display_mode));
  279. if (ret < 0)
  280. return ret;
  281. ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
  282. if (ret < 0)
  283. return ret;
  284. msleep(120);
  285. ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
  286. if (ret < 0)
  287. return ret;
  288. usleep_range(5000, 7000);
  289. ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
  290. if (ret < 0)
  291. return ret;
  292. return 0;
  293. }
  294. #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
  295. static int hx8357_set_power(struct lcd_device *lcdev, int power)
  296. {
  297. struct hx8357_data *lcd = lcd_get_data(lcdev);
  298. int ret = 0;
  299. if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
  300. ret = hx8357_exit_standby(lcdev);
  301. else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
  302. ret = hx8357_enter_standby(lcdev);
  303. if (ret == 0)
  304. lcd->state = power;
  305. else
  306. dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
  307. return ret;
  308. }
  309. static int hx8357_get_power(struct lcd_device *lcdev)
  310. {
  311. struct hx8357_data *lcd = lcd_get_data(lcdev);
  312. return lcd->state;
  313. }
  314. static struct lcd_ops hx8357_ops = {
  315. .set_power = hx8357_set_power,
  316. .get_power = hx8357_get_power,
  317. };
  318. static int hx8357_probe(struct spi_device *spi)
  319. {
  320. struct lcd_device *lcdev;
  321. struct hx8357_data *lcd;
  322. int i, ret;
  323. lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
  324. if (!lcd) {
  325. dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n");
  326. return -ENOMEM;
  327. }
  328. ret = spi_setup(spi);
  329. if (ret < 0) {
  330. dev_err(&spi->dev, "SPI setup failed.\n");
  331. return ret;
  332. }
  333. lcd->spi = spi;
  334. lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
  335. if (!gpio_is_valid(lcd->reset)) {
  336. dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
  337. return -EINVAL;
  338. }
  339. ret = devm_gpio_request_one(&spi->dev, lcd->reset,
  340. GPIOF_OUT_INIT_HIGH,
  341. "hx8357-reset");
  342. if (ret) {
  343. dev_err(&spi->dev,
  344. "failed to request gpio %d: %d\n",
  345. lcd->reset, ret);
  346. return -EINVAL;
  347. }
  348. if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) {
  349. lcd->use_im_pins = 1;
  350. for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
  351. lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
  352. "im-gpios", i);
  353. if (lcd->im_pins[i] == -EPROBE_DEFER) {
  354. dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
  355. return -EPROBE_DEFER;
  356. }
  357. if (!gpio_is_valid(lcd->im_pins[i])) {
  358. dev_err(&spi->dev, "Missing dt property: im-gpios\n");
  359. return -EINVAL;
  360. }
  361. ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
  362. GPIOF_OUT_INIT_LOW,
  363. "im_pins");
  364. if (ret) {
  365. dev_err(&spi->dev, "failed to request gpio %d: %d\n",
  366. lcd->im_pins[i], ret);
  367. return -EINVAL;
  368. }
  369. }
  370. } else {
  371. lcd->use_im_pins = 0;
  372. }
  373. lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops);
  374. if (IS_ERR(lcdev)) {
  375. ret = PTR_ERR(lcdev);
  376. return ret;
  377. }
  378. spi_set_drvdata(spi, lcdev);
  379. ret = hx8357_lcd_init(lcdev);
  380. if (ret) {
  381. dev_err(&spi->dev, "Couldn't initialize panel\n");
  382. goto init_error;
  383. }
  384. dev_info(&spi->dev, "Panel probed\n");
  385. return 0;
  386. init_error:
  387. lcd_device_unregister(lcdev);
  388. return ret;
  389. }
  390. static int hx8357_remove(struct spi_device *spi)
  391. {
  392. struct lcd_device *lcdev = spi_get_drvdata(spi);
  393. lcd_device_unregister(lcdev);
  394. return 0;
  395. }
  396. static const struct of_device_id hx8357_dt_ids[] = {
  397. { .compatible = "himax,hx8357" },
  398. {},
  399. };
  400. MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
  401. static struct spi_driver hx8357_driver = {
  402. .probe = hx8357_probe,
  403. .remove = hx8357_remove,
  404. .driver = {
  405. .name = "hx8357",
  406. .of_match_table = of_match_ptr(hx8357_dt_ids),
  407. },
  408. };
  409. module_spi_driver(hx8357_driver);
  410. MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
  411. MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
  412. MODULE_LICENSE("GPL");