panel-ili9881d.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * ILI9881D panel driver
  4. *
  5. * Copyright (c) 2020 Seeed Studio
  6. */
  7. #include "panel-ili9881d.h"
  8. #include <linux/version.h>
  9. #define ILI9881_PAGE(_page) DSI_DCS_WRITE(dsi, 0xff, 0x98, 0x81, _page)
  10. #define IILI9881_COMMAND(_cmd, _data...) DSI_DCS_WRITE(dsi, _cmd, _data)
  11. #define DCS_CMD_READ_ID1 0xDA
  12. #define ILI_9881D_I2C_ADAPTER 1
  13. #define ILI_9881D_I2C_ADDR 0x45
  14. #define GOODIX_STATUS_SIZE 2
  15. #define GOODIX_CONTACT_SIZE 8
  16. #define GOODIX_BUFFER_STATUS_READY (((uint32_t)0x01) << 7)//BIT(7)
  17. #define GOODIX_HAVE_KEY (((uint32_t)0x01) << 4)//BIT(4)
  18. #define TP_DEFAULT_WIDTH 1280
  19. #define TP_DEFAULT_HEIGHT 720
  20. #define TP_MAX_POINTS 5
  21. #define TP_POLL_INTERVAL 15
  22. static struct i2c_mipi_dsi *ili9881d_mipi_dsi;
  23. static int goodix_ts_read_input_report(struct i2c_mipi_dsi *md, u8 *data)
  24. {
  25. int header = GOODIX_STATUS_SIZE + GOODIX_CONTACT_SIZE;
  26. int i, ret, touch_num;
  27. for (i = 0; i < 2; i++) {
  28. ret = i2c_md_read(md, REG_TP_STATUS, data, header);
  29. if (ret < 0)
  30. return -EIO;
  31. if (data[0] & GOODIX_BUFFER_STATUS_READY) {
  32. touch_num = data[0] & 0x0f;
  33. if (touch_num > TP_MAX_POINTS)
  34. return -EPROTO;
  35. if (touch_num > 1) {
  36. ret = i2c_md_read(md, REG_TP_POINT, data+header, (touch_num-1)*GOODIX_CONTACT_SIZE);
  37. if (ret < 0)
  38. return -EIO;
  39. }
  40. return touch_num;
  41. }
  42. usleep_range(3000, 5000); /* Poll every 3 - 5 ms */
  43. }
  44. /*
  45. * The Goodix panel will send spurious interrupts after a
  46. * 'finger up' event, which will always cause a timeout.
  47. */
  48. return -ENOMSG;
  49. }
  50. //TODO
  51. //need more work for it's compatibility
  52. static void x_y_rotate(int *x, int *y)
  53. {
  54. int temp_x, temp_y;
  55. int temp;
  56. if (*x < 0 || *y < 0) {
  57. pr_err("%s<%d> parameter error\n", __func__, __LINE__);
  58. return;
  59. }
  60. //1 move rectangle center to (0,0)
  61. temp_x = *x - TP_DEFAULT_WIDTH/2;
  62. temp_y = *y - TP_DEFAULT_HEIGHT/2;
  63. //2 rotate the point anti-clockwise for 90 degree
  64. temp = temp_x;
  65. temp_x = temp_y;
  66. temp_y = temp;
  67. temp_x *= (-1);
  68. temp_y *= 1;
  69. //3 zoom
  70. temp_x = temp_x * TP_DEFAULT_WIDTH / TP_DEFAULT_HEIGHT;
  71. temp_y = temp_y * TP_DEFAULT_HEIGHT / TP_DEFAULT_WIDTH;
  72. //4 move rectangle center back to (TP_DEFAULT_WIDTH/2, TP_DEFAULT_HEIGHT/2)
  73. temp_x += TP_DEFAULT_WIDTH/2;
  74. temp_y += TP_DEFAULT_HEIGHT/2;
  75. *x = temp_x;
  76. *y = temp_y;
  77. }
  78. static void goodix_ts_report_touch_8b(struct i2c_mipi_dsi *md, u8 *coor_data)
  79. {
  80. struct input_dev *input_dev = md->input;
  81. int id = coor_data[7];
  82. int input_x = 0;
  83. int input_y = 0;
  84. int input_w = coor_data[4];
  85. input_x = coor_data[1];
  86. input_x <<= 8;
  87. input_x += coor_data[0];
  88. input_y = coor_data[3];
  89. input_y <<= 8;
  90. input_y += coor_data[2];
  91. if (md->tp_point_rotate)
  92. x_y_rotate(&input_x, &input_y);
  93. input_mt_slot(input_dev, id);
  94. input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, true);
  95. touchscreen_report_pos(input_dev, &md->prop, input_x, input_y, true);
  96. input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, input_w);
  97. input_report_abs(input_dev, ABS_MT_WIDTH_MAJOR, input_w);
  98. }
  99. static void tp_poll_func(struct input_dev *input)
  100. {
  101. struct i2c_mipi_dsi *md = (struct i2c_mipi_dsi *)input_get_drvdata(input);
  102. u8 point_data[GOODIX_STATUS_SIZE + TP_MAX_POINTS * GOODIX_CONTACT_SIZE] = { 0 };
  103. int touch_num;
  104. int i;
  105. touch_num = goodix_ts_read_input_report(md, point_data);
  106. if (touch_num < 0)
  107. return;
  108. for (i = 0; i < touch_num; i++)
  109. goodix_ts_report_touch_8b(md, &point_data[GOODIX_STATUS_SIZE + i*GOODIX_CONTACT_SIZE]);
  110. input_mt_sync_frame(input);
  111. input_sync(input);
  112. }
  113. int tp_init(struct i2c_mipi_dsi *md)
  114. {
  115. struct i2c_client *i2c = md->i2c;
  116. struct device *dev = &i2c->dev;
  117. struct input_dev *input;
  118. int ret;
  119. input = devm_input_allocate_device(dev);
  120. if (!input) {
  121. dev_err(dev, "Failed to allocate input device\n");
  122. return -ENOMEM;
  123. }
  124. md->input = input;
  125. input_set_drvdata(input, md);
  126. input->dev.parent = dev;
  127. input->name = "seeed-tp";
  128. input->id.bustype = BUS_I2C;
  129. input->id.vendor = 0x1234;
  130. input->id.product = 0x1001;
  131. input->id.version = 0x0100;
  132. input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
  133. input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
  134. input_set_abs_params(input, ABS_MT_POSITION_X, 0, TP_DEFAULT_WIDTH, 0, 0);
  135. input_set_abs_params(input, ABS_MT_POSITION_Y, 0, TP_DEFAULT_HEIGHT, 0, 0);
  136. ret = input_mt_init_slots(input, TP_MAX_POINTS, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
  137. if (ret) {
  138. dev_err(dev, "could not init mt slots, %d\n", ret);
  139. return ret;
  140. }
  141. ret = input_setup_polling(input, tp_poll_func);
  142. if (ret) {
  143. dev_err(dev, "could not set up polling mode, %d\n", ret);
  144. return ret;
  145. }
  146. input_set_poll_interval(input, TP_POLL_INTERVAL);
  147. ret = input_register_device(input);
  148. if (ret) {
  149. dev_err(dev, "could not register input device, %d\n", ret);
  150. return ret;
  151. }
  152. return 0;
  153. }
  154. int tp_deinit(struct i2c_mipi_dsi *md)
  155. {
  156. input_unregister_device(md->input);
  157. return 0;
  158. }
  159. static const struct drm_display_mode ili9881d_modes = {
  160. .clock = 76000,
  161. .hdisplay = 800,
  162. .hsync_start = 800 + 60,
  163. .hsync_end = 800 + 60 + 40,
  164. .htotal = 800 + 60 + 40 + 60,
  165. .vdisplay = 1280,
  166. .vsync_start = 1280 + 16,
  167. .vsync_end = 1280 + 16 + 8,
  168. .vtotal = 1280 + 16 + 8 + 16,
  169. .width_mm = 62,
  170. .height_mm = 110,
  171. .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
  172. };
  173. static int ili9881d_get_modes(struct drm_panel *panel, struct drm_connector *connector)
  174. {
  175. struct drm_display_mode *mode;
  176. mode = drm_mode_duplicate(connector->dev, &ili9881d_modes);
  177. if (!mode) {
  178. dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
  179. mode->hdisplay, mode->vdisplay,
  180. drm_mode_vrefresh(mode));
  181. return -ENOMEM;
  182. }
  183. mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
  184. drm_mode_set_name(mode);
  185. connector->display_info.width_mm = mode->width_mm;
  186. connector->display_info.height_mm = mode->height_mm;
  187. drm_mode_probed_add(connector, mode);
  188. return 1;
  189. }
  190. static int ili9881d_read_id(struct mipi_dsi_device *dsi, u8 *id1)
  191. {
  192. int ret;
  193. ret = mipi_dsi_dcs_read(dsi, DCS_CMD_READ_ID1, id1, 1);
  194. if (ret < 0) {
  195. dev_err(&dsi->dev, "could not read ID1\n");
  196. return ret;
  197. }
  198. dev_info(&dsi->dev, "ID1 : %02x\n", *id1);
  199. return 0;
  200. }
  201. static int ili9881d_enable(struct drm_panel *panel)
  202. {
  203. struct mipi_dsi_device *dsi = ili9881d_mipi_dsi->dsi;
  204. int ret = 0;
  205. u8 id1;
  206. DBG_FUNC();
  207. if (!dsi)
  208. return -1;
  209. dsi->mode_flags |= MIPI_DSI_MODE_LPM;
  210. ILI9881_PAGE(0x00);
  211. mipi_dsi_set_maximum_return_packet_size(dsi, 1);
  212. ret = ili9881d_read_id(dsi, &id1);
  213. if (ret < 0) {
  214. dev_info(&dsi->dev, "No LCD connected,pls check your hardware! ret:%d\n", ret);
  215. return -ENODEV;
  216. }
  217. ILI9881_PAGE(0x01);
  218. IILI9881_COMMAND(0x91,0x00);
  219. IILI9881_COMMAND(0x92,0x00);
  220. IILI9881_COMMAND(0x93,0x72);
  221. IILI9881_COMMAND(0x94,0x00);
  222. IILI9881_COMMAND(0x95,0x00);
  223. IILI9881_COMMAND(0x96,0x09);
  224. IILI9881_COMMAND(0x97,0x00);
  225. IILI9881_COMMAND(0x98,0x00);
  226. IILI9881_COMMAND(0x09,0x01);
  227. IILI9881_COMMAND(0x0a,0x00);
  228. IILI9881_COMMAND(0x0b,0x00);
  229. IILI9881_COMMAND(0x0c,0x01);
  230. IILI9881_COMMAND(0x0d,0x00);
  231. IILI9881_COMMAND(0x0e,0x00);
  232. IILI9881_COMMAND(0x0f,0x1D);
  233. IILI9881_COMMAND(0x10,0x1D);
  234. IILI9881_COMMAND(0x11,0x00);
  235. IILI9881_COMMAND(0x12,0x00);
  236. IILI9881_COMMAND(0x13,0x00);
  237. IILI9881_COMMAND(0x14,0x00);
  238. IILI9881_COMMAND(0x15,0x00);
  239. IILI9881_COMMAND(0x16,0x00);
  240. IILI9881_COMMAND(0x17,0x00);
  241. IILI9881_COMMAND(0x18,0x00);
  242. IILI9881_COMMAND(0x19,0x00);
  243. IILI9881_COMMAND(0x1a,0x00);
  244. IILI9881_COMMAND(0x1b,0x00);
  245. IILI9881_COMMAND(0x1c,0x00);
  246. IILI9881_COMMAND(0x1d,0x00);
  247. IILI9881_COMMAND(0x1e,0xc0);
  248. IILI9881_COMMAND(0x1f,0x00);
  249. IILI9881_COMMAND(0x20,0x06);
  250. IILI9881_COMMAND(0x21,0x02);
  251. IILI9881_COMMAND(0x22,0x00);
  252. IILI9881_COMMAND(0x23,0x00);
  253. IILI9881_COMMAND(0x24,0x00);
  254. IILI9881_COMMAND(0x25,0x00);
  255. IILI9881_COMMAND(0x26,0x00);
  256. IILI9881_COMMAND(0x27,0x00);
  257. IILI9881_COMMAND(0x28,0x33);
  258. IILI9881_COMMAND(0x29,0x03);
  259. IILI9881_COMMAND(0x2a,0x00);
  260. IILI9881_COMMAND(0x2b,0x00);
  261. IILI9881_COMMAND(0x2c,0x00);
  262. IILI9881_COMMAND(0x2d,0x00);
  263. IILI9881_COMMAND(0x2e,0x00);
  264. IILI9881_COMMAND(0x2f,0x00);
  265. IILI9881_COMMAND(0x30,0x00);
  266. IILI9881_COMMAND(0x31,0x00);
  267. IILI9881_COMMAND(0x32,0x00);
  268. IILI9881_COMMAND(0x33,0x00);
  269. IILI9881_COMMAND(0x34,0x04);
  270. IILI9881_COMMAND(0x35,0x00);
  271. IILI9881_COMMAND(0x36,0x00);
  272. IILI9881_COMMAND(0x37,0x00);
  273. IILI9881_COMMAND(0x38,0x3C);
  274. IILI9881_COMMAND(0x39,0x07);
  275. IILI9881_COMMAND(0x3a,0x00);
  276. IILI9881_COMMAND(0x3b,0x00);
  277. IILI9881_COMMAND(0x3c,0x00);
  278. IILI9881_COMMAND(0x40,0x03);
  279. IILI9881_COMMAND(0x41,0x20);
  280. IILI9881_COMMAND(0x42,0x00);
  281. IILI9881_COMMAND(0x43,0x00);
  282. IILI9881_COMMAND(0x44,0x03);
  283. IILI9881_COMMAND(0x45,0x00);
  284. IILI9881_COMMAND(0x46,0x01);
  285. IILI9881_COMMAND(0x47,0x08);
  286. IILI9881_COMMAND(0x48,0x00);
  287. IILI9881_COMMAND(0x49,0x00);
  288. IILI9881_COMMAND(0x4a,0x00);
  289. IILI9881_COMMAND(0x4b,0x00);
  290. // ==== GL[3OUT=
  291. IILI9881_COMMAND(0x4c,0x01);
  292. IILI9881_COMMAND(0x4d,0x54);
  293. IILI9881_COMMAND(0x4e,0x57);
  294. IILI9881_COMMAND(0x4f,0x9b);
  295. IILI9881_COMMAND(0x50,0xf9);
  296. IILI9881_COMMAND(0x51,0x27);
  297. IILI9881_COMMAND(0x52,0x2f);
  298. IILI9881_COMMAND(0x53,0xf2);
  299. IILI9881_COMMAND(0x54,0xff);
  300. IILI9881_COMMAND(0x55,0xff);
  301. IILI9881_COMMAND(0x56,0xff);
  302. // ==== GR[3OUT==
  303. IILI9881_COMMAND(0x57,0x01);
  304. IILI9881_COMMAND(0x58,0x54);
  305. IILI9881_COMMAND(0x59,0x46);
  306. IILI9881_COMMAND(0x5a,0x8a);
  307. IILI9881_COMMAND(0x5b,0xf8);
  308. IILI9881_COMMAND(0x5c,0x26);
  309. IILI9881_COMMAND(0x5d,0x2f);
  310. IILI9881_COMMAND(0x5e,0xf2);
  311. IILI9881_COMMAND(0x5f,0xff);
  312. IILI9881_COMMAND(0x60,0xff);
  313. IILI9881_COMMAND(0x61,0xff);
  314. IILI9881_COMMAND(0x62,0x06);
  315. // == GOUT:4]_BWUTL[5:0]==
  316. IILI9881_COMMAND(0x63,0x01);
  317. IILI9881_COMMAND(0x64,0x00);
  318. IILI9881_COMMAND(0x65,0xa4);
  319. IILI9881_COMMAND(0x66,0xa5);
  320. IILI9881_COMMAND(0x67,0x58);
  321. IILI9881_COMMAND(0x68,0x5a);
  322. IILI9881_COMMAND(0x69,0x54);
  323. IILI9881_COMMAND(0x6a,0x56);
  324. IILI9881_COMMAND(0x6b,0x06);
  325. IILI9881_COMMAND(0x6c,0xff);
  326. IILI9881_COMMAND(0x6d,0x08);
  327. IILI9881_COMMAND(0x6e,0x02);
  328. IILI9881_COMMAND(0x6f,0xff);
  329. IILI9881_COMMAND(0x70,0x02);
  330. IILI9881_COMMAND(0x71,0x02);
  331. IILI9881_COMMAND(0x72,0xff);
  332. IILI9881_COMMAND(0x73,0xff);
  333. IILI9881_COMMAND(0x74,0xff);
  334. IILI9881_COMMAND(0x75,0xff);
  335. IILI9881_COMMAND(0x76,0xff);
  336. IILI9881_COMMAND(0x77,0xff);
  337. IILI9881_COMMAND(0x78,0xff);
  338. // == GOUT:4]_BWUTR[5:0]==
  339. IILI9881_COMMAND(0x79,0x01);
  340. IILI9881_COMMAND(0x7a,0x00);
  341. IILI9881_COMMAND(0x7b,0xa4);
  342. IILI9881_COMMAND(0x7c,0xa5);
  343. IILI9881_COMMAND(0x7d,0x59);
  344. IILI9881_COMMAND(0x7e,0x5b);
  345. IILI9881_COMMAND(0x7f,0x55);
  346. IILI9881_COMMAND(0x80,0x57);
  347. IILI9881_COMMAND(0x81,0x07);
  348. IILI9881_COMMAND(0x82,0xff);
  349. IILI9881_COMMAND(0x83,0x09);
  350. IILI9881_COMMAND(0x84,0x02);
  351. IILI9881_COMMAND(0x85,0xff);
  352. IILI9881_COMMAND(0x86,0x02);
  353. IILI9881_COMMAND(0x87,0x02);
  354. IILI9881_COMMAND(0x88,0xff);
  355. IILI9881_COMMAND(0x89,0xff);
  356. IILI9881_COMMAND(0x8a,0xff);
  357. IILI9881_COMMAND(0x8b,0xff);
  358. IILI9881_COMMAND(0x8c,0xff);
  359. IILI9881_COMMAND(0x8d,0xff);
  360. IILI9881_COMMAND(0x8e,0xff);
  361. IILI9881_COMMAND(0x8f,0x00);
  362. IILI9881_COMMAND(0x90,0x00);
  363. IILI9881_COMMAND(0x9d,0x00);
  364. IILI9881_COMMAND(0x9e,0x00);
  365. IILI9881_COMMAND(0xa0,0x35);
  366. IILI9881_COMMAND(0xa1,0x00);
  367. IILI9881_COMMAND(0xa2,0x00);
  368. IILI9881_COMMAND(0xa3,0x00);
  369. IILI9881_COMMAND(0xa4,0x00);
  370. IILI9881_COMMAND(0xa5,0x00);
  371. IILI9881_COMMAND(0xa6,0x08);
  372. IILI9881_COMMAND(0xa7,0x00);
  373. IILI9881_COMMAND(0xa8,0x00);
  374. IILI9881_COMMAND(0xa9,0x00);
  375. IILI9881_COMMAND(0xaa,0x00);
  376. IILI9881_COMMAND(0xab,0x00);
  377. IILI9881_COMMAND(0xac,0x00);
  378. IILI9881_COMMAND(0xad,0x00);
  379. IILI9881_COMMAND(0xae,0xff);
  380. IILI9881_COMMAND(0xaf,0x00);
  381. IILI9881_COMMAND(0xb0,0x00);
  382. ILI9881_PAGE(0x02);
  383. IILI9881_COMMAND(0x08,0x11);
  384. IILI9881_COMMAND(0x0a,0x0c);
  385. IILI9881_COMMAND(0x0f,0x06);
  386. IILI9881_COMMAND(0xA0,0x00,0x26,0x35,0x16,0x19,0x2C,0x1F,0x1F,0x96,0x1C,0x28,0x80,0x1A,0x18,0x4C,0x21,0x27,0x55,0x65,0x39);
  387. IILI9881_COMMAND(0xC0,0x00,0x26,0x35,0x16,0x19,0x2C,0x1F,0x1F,0x96,0x1C,0x28,0x80,0x1A,0x18,0x4C,0x21,0x27,0x55,0x65,0x39);
  388. //===== GIP code finish =====//
  389. IILI9881_COMMAND(0x4C,0xA4); // PS_EN on ,0x default :A4
  390. IILI9881_COMMAND(0x18,0xF4); // SH on ,0x default E4
  391. //=========================//
  392. ILI9881_PAGE(0x04);
  393. IILI9881_COMMAND(0x5D,0xAF); // VREG1 5.5V
  394. IILI9881_COMMAND(0x5E,0xAF); // VREG2 5.5V
  395. IILI9881_COMMAND(0x60,0x9B); // VCM1
  396. IILI9881_COMMAND(0x62,0x9B); // VCM2
  397. IILI9881_COMMAND(0x82,0x38); // VREF_VGH_MOD_CLPSEL 16V
  398. IILI9881_COMMAND(0x84,0x38); // VREF_VGH_DC 16V
  399. IILI9881_COMMAND(0x86,0x18); // VREF_VGL_CLPSEL -10V
  400. IILI9881_COMMAND(0x66,0xC4); // VGH_AC x4 ,0xdefault :04
  401. IILI9881_COMMAND(0xC1,0xF0); // VGH_DC x4 ,0xdefault :70
  402. IILI9881_COMMAND(0x70,0x60);
  403. IILI9881_COMMAND(0x71,0x00);
  404. //=========================//
  405. IILI9881_COMMAND(0x5B,0x33); // vcore_sel Voltage
  406. IILI9881_COMMAND(0x6C,0x10); // vcore bias L
  407. IILI9881_COMMAND(0x77,0x03); // vcore_sel Voltage
  408. IILI9881_COMMAND(0x7B,0x02); // vcore bias R
  409. //=========================//
  410. ILI9881_PAGE(0x01);
  411. IILI9881_COMMAND(0xF0,0x00); // 1280 Gate NL
  412. IILI9881_COMMAND(0xF1,0xC8); // 1280 Gate NL
  413. ILI9881_PAGE(0x05);
  414. IILI9881_COMMAND(0x22,0x3A); // RGB to BGR
  415. ILI9881_PAGE(0x00);
  416. IILI9881_COMMAND(0x35,0x00);
  417. IILI9881_COMMAND(0x11);
  418. msleep(120);
  419. IILI9881_COMMAND(0x29);
  420. return 0;
  421. }
  422. static const struct drm_panel_funcs ili9881d_funcs = {
  423. .get_modes = ili9881d_get_modes,
  424. .enable = ili9881d_enable,
  425. };
  426. static void ili9881d_set_dsi(struct mipi_dsi_device *dsi)
  427. {
  428. dsi->mode_flags = (MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM);
  429. dsi->format = MIPI_DSI_FMT_RGB888;
  430. dsi->lanes = 4;
  431. }
  432. const struct panel_data ili9881d_data = {
  433. .set_dsi = ili9881d_set_dsi,
  434. .funcs = &ili9881d_funcs,
  435. };
  436. static int i2c_md_read(struct i2c_mipi_dsi *md, u8 reg, u8 *buf, int len)
  437. {
  438. struct i2c_client *client = md->i2c;
  439. struct i2c_msg msgs[1];
  440. u8 addr_buf[1] = { reg };
  441. u8 data_buf[1] = { 0, };
  442. int ret;
  443. mutex_lock(&md->mutex);
  444. /* Write register address */
  445. msgs[0].addr = client->addr;
  446. msgs[0].flags = 0;
  447. msgs[0].len = ARRAY_SIZE(addr_buf);
  448. msgs[0].buf = addr_buf;
  449. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  450. if (ret != ARRAY_SIZE(msgs)) {
  451. mutex_unlock(&md->mutex);
  452. return -EIO;
  453. }
  454. usleep_range(1000, 1500);
  455. /* Read data from register */
  456. msgs[0].addr = client->addr;
  457. msgs[0].flags = I2C_M_RD;
  458. if (buf == NULL) {
  459. msgs[0].len = 1;
  460. msgs[0].buf = data_buf;
  461. } else {
  462. msgs[0].len = len;
  463. msgs[0].buf = buf;
  464. }
  465. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  466. if (ret != ARRAY_SIZE(msgs)) {
  467. mutex_unlock(&md->mutex);
  468. return -EIO;
  469. }
  470. mutex_unlock(&md->mutex);
  471. if (buf == NULL)
  472. return data_buf[0];
  473. else
  474. return ret;
  475. }
  476. static void i2c_md_write(struct i2c_mipi_dsi *md, u8 reg, u8 val)
  477. {
  478. struct i2c_client *client = md->i2c;
  479. int ret;
  480. mutex_lock(&md->mutex);
  481. ret = i2c_smbus_write_byte_data(client, reg, val);
  482. if (ret)
  483. dev_err(&client->dev, "I2C write failed: %d\n", ret);
  484. usleep_range(1000, 1500);
  485. mutex_unlock(&md->mutex);
  486. }
  487. /* panel_funcs */
  488. static int panel_prepare(struct drm_panel *panel)
  489. {
  490. int ret = 0;
  491. struct i2c_mipi_dsi *md = panel_to_md(panel);
  492. const struct drm_panel_funcs *funcs = md->panel_data->funcs;
  493. DBG_FUNC("");
  494. /* i2c */
  495. /* reset pin */
  496. i2c_md_write(md, REG_LCD_RST, 0);
  497. msleep(20);
  498. i2c_md_write(md, REG_LCD_RST, 1);
  499. msleep(20);
  500. /* panel */
  501. if (funcs && funcs->prepare) {
  502. ret = funcs->prepare(panel);
  503. if (ret < 0) {
  504. i2c_md_write(md, REG_POWERON, 0);
  505. i2c_md_write(md, REG_LCD_RST, 0);
  506. i2c_md_write(md, REG_PWM, 0);
  507. return ret;
  508. }
  509. }
  510. return ret;
  511. }
  512. static int panel_unprepare(struct drm_panel *panel)
  513. {
  514. int ret = 0;
  515. struct i2c_mipi_dsi *md = panel_to_md(panel);
  516. const struct drm_panel_funcs *funcs = md->panel_data->funcs;
  517. DBG_FUNC("");
  518. if (funcs && funcs->unprepare) {
  519. ret = funcs->unprepare(panel);
  520. if (ret < 0)
  521. return ret;
  522. }
  523. return ret;
  524. }
  525. static int panel_enable(struct drm_panel *panel)
  526. {
  527. int ret = 0;
  528. struct i2c_mipi_dsi *md = panel_to_md(panel);
  529. const struct drm_panel_funcs *funcs = md->panel_data->funcs;
  530. DBG_FUNC("");
  531. /* panel */
  532. if (funcs && funcs->enable) {
  533. ret = funcs->enable(panel);
  534. if (ret < 0)
  535. return ret;
  536. }
  537. /* i2c */
  538. i2c_md_write(md, REG_PWM, md->brightness);
  539. return ret;
  540. }
  541. static int panel_disable(struct drm_panel *panel)
  542. {
  543. int ret = 0;
  544. struct i2c_mipi_dsi *md = panel_to_md(panel);
  545. const struct drm_panel_funcs *funcs = md->panel_data->funcs;
  546. DBG_FUNC("");
  547. /* i2c */
  548. i2c_md_write(md, REG_PWM, 0);
  549. i2c_md_write(md, REG_LCD_RST, 0);
  550. /* panel */
  551. if (funcs && funcs->disable) {
  552. ret = funcs->disable(panel);
  553. if (ret < 0)
  554. return ret;
  555. }
  556. return ret;
  557. }
  558. static int panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)
  559. {
  560. int ret = 0;
  561. struct i2c_mipi_dsi *md = panel_to_md(panel);
  562. const struct drm_panel_funcs *funcs = md->panel_data->funcs;
  563. if (funcs && funcs->get_modes) {
  564. ret = funcs->get_modes(panel, connector);
  565. if (ret < 0)
  566. return ret;
  567. }
  568. return ret;
  569. }
  570. static const struct drm_panel_funcs panel_funcs = {
  571. .prepare = panel_prepare,
  572. .unprepare = panel_unprepare,
  573. .enable = panel_enable,
  574. .disable = panel_disable,
  575. .get_modes = panel_get_modes,
  576. };
  577. /* backlight */
  578. static int backlight_update(struct backlight_device *bd)
  579. {
  580. struct i2c_mipi_dsi *md = bl_get_data(bd);
  581. int brightness = bd->props.brightness;
  582. if (bd->props.power != FB_BLANK_UNBLANK ||
  583. bd->props.fb_blank != FB_BLANK_UNBLANK ||
  584. (bd->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))) {
  585. brightness = 0;
  586. }
  587. md->brightness = brightness;
  588. i2c_md_write(md, REG_PWM, brightness);
  589. return 0;
  590. }
  591. static const struct backlight_ops backlight_ops = {
  592. .options = BL_CORE_SUSPENDRESUME,
  593. .update_status = backlight_update,
  594. };
  595. static int backlight_init(struct i2c_mipi_dsi *md)
  596. {
  597. struct device *dev = &md->i2c->dev;
  598. struct backlight_properties props;
  599. struct backlight_device *bd;
  600. memset(&props, 0, sizeof(props));
  601. props.type = BACKLIGHT_RAW;
  602. props.max_brightness = 255;
  603. bd = devm_backlight_device_register(dev, dev_name(dev),
  604. dev, md, &backlight_ops,
  605. &props);
  606. if (IS_ERR(bd)) {
  607. dev_err(dev, "failed to register backlight\n");
  608. return PTR_ERR(bd);
  609. }
  610. bd->props.brightness = 255;
  611. backlight_update_status(bd);
  612. return 0;
  613. }
  614. static int i2c_md_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
  615. {
  616. struct device *dev = &i2c->dev;
  617. struct i2c_mipi_dsi *md = ili9881d_mipi_dsi;
  618. int ret = 0;
  619. DBG_FUNC("start");
  620. i2c_set_clientdata(i2c, md);
  621. mutex_init(&md->mutex);
  622. md->i2c = i2c;
  623. md->panel_data = &ili9881d_data;
  624. if (!md->panel_data) {
  625. dev_err(dev, "No valid panel data.\n");
  626. return -ENODEV;
  627. }
  628. ret = i2c_md_read(md, REG_ID, NULL, 0);
  629. if (ret != 0xC3) {
  630. dev_err(dev, "Unknown chip id: 0x%02x\n", ret);
  631. return -ENODEV;
  632. }
  633. dev_info(dev, "I2C Address:0x%x read id: 0x%x\n", i2c->addr, ret);
  634. /* Turn on */
  635. i2c_md_write(md, REG_POWERON, 1);
  636. DBG_FUNC("finished.");
  637. return 0;
  638. }
  639. static int i2c_md_remove(struct i2c_client *i2c)
  640. {
  641. struct i2c_mipi_dsi *md = i2c_get_clientdata(i2c);
  642. DBG_FUNC();
  643. tp_deinit(md);
  644. /* Turn off power */
  645. i2c_md_write(md, REG_POWERON, 0);
  646. i2c_md_write(md, REG_LCD_RST, 0);
  647. i2c_md_write(md, REG_PWM, 0);
  648. mipi_dsi_detach(md->dsi);
  649. drm_panel_remove(&md->panel);
  650. return 0;
  651. }
  652. static void i2c_md_shutdown(struct i2c_client *i2c)
  653. {
  654. struct i2c_mipi_dsi *md = i2c_get_clientdata(i2c);
  655. DBG_FUNC();
  656. tp_deinit(md);
  657. /* Turn off power */
  658. i2c_md_write(md, REG_POWERON, 0);
  659. i2c_md_write(md, REG_LCD_RST, 0);
  660. i2c_md_write(md, REG_PWM, 0);
  661. mipi_dsi_detach(md->dsi);
  662. drm_panel_remove(&md->panel);
  663. }
  664. static const struct of_device_id i2c_md_of_ids[] = {
  665. {
  666. .compatible = "ili9881d",
  667. },
  668. { }
  669. };
  670. MODULE_DEVICE_TABLE(of, i2c_md_of_ids);
  671. static struct i2c_driver i2c_md_driver = {
  672. .driver = {
  673. .name = "i2c_mipi_dsi",
  674. .of_match_table = i2c_md_of_ids,
  675. },
  676. .probe = i2c_md_probe,
  677. .remove = i2c_md_remove,
  678. .shutdown = i2c_md_shutdown,
  679. };
  680. static int ili9881d_hack_create_device(void)
  681. {
  682. struct i2c_adapter *adapter;
  683. struct i2c_client *client;
  684. struct i2c_board_info info = {
  685. .type = "ili9881d",
  686. .addr = ILI_9881D_I2C_ADDR,
  687. };
  688. adapter = i2c_get_adapter(ILI_9881D_I2C_ADAPTER);
  689. if (!adapter) {
  690. pr_err("%s: i2c_get_adapter(%d) failed\n", __func__,
  691. ILI_9881D_I2C_ADAPTER);
  692. return -EINVAL;
  693. }
  694. client = i2c_new_client_device(adapter, &info);
  695. if (IS_ERR(client)) {
  696. pr_err("%s: creating I2C device failed\n", __func__);
  697. i2c_put_adapter(adapter);
  698. return PTR_ERR(client);
  699. }
  700. return 0;
  701. }
  702. static int ili9881d_dsi_probe(struct mipi_dsi_device *dsi)
  703. {
  704. int ret;
  705. struct i2c_mipi_dsi *ctx;
  706. ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL);
  707. if (!ctx)
  708. return -ENOMEM;
  709. ili9881d_mipi_dsi = ctx;
  710. ili9881d_hack_create_device();
  711. ret = i2c_add_driver(&i2c_md_driver);
  712. if (ret < 0) {
  713. dev_err(&dsi->dev, "i2c_add_driver ret:%d\n", ret);
  714. return ret;
  715. }
  716. mipi_dsi_set_drvdata(dsi, ctx);
  717. ctx->dsi = dsi;
  718. ctx->panel_data->set_dsi(ctx->dsi);
  719. drm_panel_init(&ctx->panel, &dsi->dev, &panel_funcs, DRM_MODE_CONNECTOR_DSI);
  720. drm_panel_add(&ctx->panel);
  721. tp_init(ctx);
  722. backlight_init(ctx);
  723. ret = device_property_read_u32(&dsi->dev, "mcu_auto_reset_enable", &ctx->mcu_auto_reset);
  724. if (ret < 0)
  725. dev_err(&dsi->dev, "Can't get the data of mcu_auto_reset!\n");
  726. i2c_md_write(ctx, REG_MCU_AUTO_RESET, (ctx->mcu_auto_reset&0xff));
  727. ret = device_property_read_u32(&dsi->dev, "tp_point_rotate", &ctx->tp_point_rotate);
  728. if (ret < 0)
  729. dev_err(&dsi->dev, "Can't get the data of tp_point_rotate!\n");
  730. return mipi_dsi_attach(dsi);
  731. }
  732. static int ili9881d_dsi_remove(struct mipi_dsi_device *dsi)
  733. {
  734. struct i2c_mipi_dsi *ctx = mipi_dsi_get_drvdata(dsi);
  735. mipi_dsi_detach(dsi);
  736. drm_panel_remove(&ctx->panel);
  737. return 0;
  738. }
  739. static const struct of_device_id ili9881d_of_match[] = {
  740. { .compatible = "i2c_dsi,ili9881d", },
  741. { }
  742. };
  743. MODULE_DEVICE_TABLE(of, ili9881d_of_match);
  744. static struct mipi_dsi_driver ili9881d_dsi_driver = {
  745. .probe = ili9881d_dsi_probe,
  746. .remove = ili9881d_dsi_remove,
  747. .driver = {
  748. .name = "ili9881d-dsi",
  749. .of_match_table = ili9881d_of_match,
  750. },
  751. };
  752. module_mipi_dsi_driver(ili9881d_dsi_driver);
  753. MODULE_DESCRIPTION("Ilitek ILI9881D Controller Driver");
  754. MODULE_LICENSE("GPL v2");