panel-dsi-cm.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. /*
  2. * Generic DSI Command Mode panel driver
  3. *
  4. * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
  5. * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation.
  10. */
  11. /* #define DEBUG */
  12. #include <linux/backlight.h>
  13. #include <linux/delay.h>
  14. #include <linux/gpio/consumer.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/jiffies.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/sched/signal.h>
  20. #include <linux/slab.h>
  21. #include <linux/workqueue.h>
  22. #include <linux/of_device.h>
  23. #include <linux/regulator/consumer.h>
  24. #include <video/mipi_display.h>
  25. #include <video/of_display_timing.h>
  26. #include "../dss/omapdss.h"
  27. /* DSI Virtual channel. Hardcoded for now. */
  28. #define TCH 0
  29. #define DCS_READ_NUM_ERRORS 0x05
  30. #define DCS_BRIGHTNESS 0x51
  31. #define DCS_CTRL_DISPLAY 0x53
  32. #define DCS_GET_ID1 0xda
  33. #define DCS_GET_ID2 0xdb
  34. #define DCS_GET_ID3 0xdc
  35. struct panel_drv_data {
  36. struct omap_dss_device dssdev;
  37. struct omap_dss_device *in;
  38. struct videomode vm;
  39. struct platform_device *pdev;
  40. struct mutex lock;
  41. struct backlight_device *bldev;
  42. struct backlight_device *extbldev;
  43. unsigned long hw_guard_end; /* next value of jiffies when we can
  44. * issue the next sleep in/out command
  45. */
  46. unsigned long hw_guard_wait; /* max guard time in jiffies */
  47. /* panel HW configuration from DT or platform data */
  48. struct gpio_desc *reset_gpio;
  49. struct gpio_desc *ext_te_gpio;
  50. struct regulator *vpnl;
  51. struct regulator *vddi;
  52. bool use_dsi_backlight;
  53. int width_mm;
  54. int height_mm;
  55. struct omap_dsi_pin_config pin_config;
  56. /* runtime variables */
  57. bool enabled;
  58. bool te_enabled;
  59. atomic_t do_update;
  60. int channel;
  61. struct delayed_work te_timeout_work;
  62. bool intro_printed;
  63. struct workqueue_struct *workqueue;
  64. bool ulps_enabled;
  65. unsigned ulps_timeout;
  66. struct delayed_work ulps_work;
  67. };
  68. #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
  69. static irqreturn_t dsicm_te_isr(int irq, void *data);
  70. static void dsicm_te_timeout_work_callback(struct work_struct *work);
  71. static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
  72. static int dsicm_panel_reset(struct panel_drv_data *ddata);
  73. static void dsicm_ulps_work(struct work_struct *work);
  74. static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
  75. {
  76. struct backlight_device *backlight;
  77. if (ddata->bldev)
  78. backlight = ddata->bldev;
  79. else if (ddata->extbldev)
  80. backlight = ddata->extbldev;
  81. else
  82. return;
  83. if (enable) {
  84. backlight->props.fb_blank = FB_BLANK_UNBLANK;
  85. backlight->props.state = ~(BL_CORE_FBBLANK | BL_CORE_SUSPENDED);
  86. backlight->props.power = FB_BLANK_UNBLANK;
  87. } else {
  88. backlight->props.fb_blank = FB_BLANK_NORMAL;
  89. backlight->props.power = FB_BLANK_POWERDOWN;
  90. backlight->props.state |= BL_CORE_FBBLANK | BL_CORE_SUSPENDED;
  91. }
  92. backlight_update_status(backlight);
  93. }
  94. static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
  95. {
  96. ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
  97. ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
  98. }
  99. static void hw_guard_wait(struct panel_drv_data *ddata)
  100. {
  101. unsigned long wait = ddata->hw_guard_end - jiffies;
  102. if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
  103. set_current_state(TASK_UNINTERRUPTIBLE);
  104. schedule_timeout(wait);
  105. }
  106. }
  107. static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
  108. {
  109. struct omap_dss_device *in = ddata->in;
  110. int r;
  111. u8 buf[1];
  112. r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd, buf, 1);
  113. if (r < 0)
  114. return r;
  115. *data = buf[0];
  116. return 0;
  117. }
  118. static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
  119. {
  120. struct omap_dss_device *in = ddata->in;
  121. return in->ops.dsi->dcs_write(in, ddata->channel, &dcs_cmd, 1);
  122. }
  123. static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
  124. {
  125. struct omap_dss_device *in = ddata->in;
  126. u8 buf[2] = { dcs_cmd, param };
  127. return in->ops.dsi->dcs_write(in, ddata->channel, buf, 2);
  128. }
  129. static int dsicm_sleep_in(struct panel_drv_data *ddata)
  130. {
  131. struct omap_dss_device *in = ddata->in;
  132. u8 cmd;
  133. int r;
  134. hw_guard_wait(ddata);
  135. cmd = MIPI_DCS_ENTER_SLEEP_MODE;
  136. r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, &cmd, 1);
  137. if (r)
  138. return r;
  139. hw_guard_start(ddata, 120);
  140. usleep_range(5000, 10000);
  141. return 0;
  142. }
  143. static int dsicm_sleep_out(struct panel_drv_data *ddata)
  144. {
  145. int r;
  146. hw_guard_wait(ddata);
  147. r = dsicm_dcs_write_0(ddata, MIPI_DCS_EXIT_SLEEP_MODE);
  148. if (r)
  149. return r;
  150. hw_guard_start(ddata, 120);
  151. usleep_range(5000, 10000);
  152. return 0;
  153. }
  154. static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
  155. {
  156. int r;
  157. r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
  158. if (r)
  159. return r;
  160. r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
  161. if (r)
  162. return r;
  163. r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
  164. if (r)
  165. return r;
  166. return 0;
  167. }
  168. static int dsicm_set_update_window(struct panel_drv_data *ddata,
  169. u16 x, u16 y, u16 w, u16 h)
  170. {
  171. struct omap_dss_device *in = ddata->in;
  172. int r;
  173. u16 x1 = x;
  174. u16 x2 = x + w - 1;
  175. u16 y1 = y;
  176. u16 y2 = y + h - 1;
  177. u8 buf[5];
  178. buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
  179. buf[1] = (x1 >> 8) & 0xff;
  180. buf[2] = (x1 >> 0) & 0xff;
  181. buf[3] = (x2 >> 8) & 0xff;
  182. buf[4] = (x2 >> 0) & 0xff;
  183. r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
  184. if (r)
  185. return r;
  186. buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
  187. buf[1] = (y1 >> 8) & 0xff;
  188. buf[2] = (y1 >> 0) & 0xff;
  189. buf[3] = (y2 >> 8) & 0xff;
  190. buf[4] = (y2 >> 0) & 0xff;
  191. r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
  192. if (r)
  193. return r;
  194. in->ops.dsi->bta_sync(in, ddata->channel);
  195. return r;
  196. }
  197. static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
  198. {
  199. if (ddata->ulps_timeout > 0)
  200. queue_delayed_work(ddata->workqueue, &ddata->ulps_work,
  201. msecs_to_jiffies(ddata->ulps_timeout));
  202. }
  203. static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata)
  204. {
  205. cancel_delayed_work(&ddata->ulps_work);
  206. }
  207. static int dsicm_enter_ulps(struct panel_drv_data *ddata)
  208. {
  209. struct omap_dss_device *in = ddata->in;
  210. int r;
  211. if (ddata->ulps_enabled)
  212. return 0;
  213. dsicm_cancel_ulps_work(ddata);
  214. r = _dsicm_enable_te(ddata, false);
  215. if (r)
  216. goto err;
  217. if (ddata->ext_te_gpio)
  218. disable_irq(gpiod_to_irq(ddata->ext_te_gpio));
  219. in->ops.dsi->disable(in, false, true);
  220. ddata->ulps_enabled = true;
  221. return 0;
  222. err:
  223. dev_err(&ddata->pdev->dev, "enter ULPS failed");
  224. dsicm_panel_reset(ddata);
  225. ddata->ulps_enabled = false;
  226. dsicm_queue_ulps_work(ddata);
  227. return r;
  228. }
  229. static int dsicm_exit_ulps(struct panel_drv_data *ddata)
  230. {
  231. struct omap_dss_device *in = ddata->in;
  232. int r;
  233. if (!ddata->ulps_enabled)
  234. return 0;
  235. r = in->ops.dsi->enable(in);
  236. if (r) {
  237. dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
  238. goto err1;
  239. }
  240. in->ops.dsi->enable_hs(in, ddata->channel, true);
  241. r = _dsicm_enable_te(ddata, true);
  242. if (r) {
  243. dev_err(&ddata->pdev->dev, "failed to re-enable TE");
  244. goto err2;
  245. }
  246. if (ddata->ext_te_gpio)
  247. enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
  248. dsicm_queue_ulps_work(ddata);
  249. ddata->ulps_enabled = false;
  250. return 0;
  251. err2:
  252. dev_err(&ddata->pdev->dev, "failed to exit ULPS");
  253. r = dsicm_panel_reset(ddata);
  254. if (!r) {
  255. if (ddata->ext_te_gpio)
  256. enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
  257. ddata->ulps_enabled = false;
  258. }
  259. err1:
  260. dsicm_queue_ulps_work(ddata);
  261. return r;
  262. }
  263. static int dsicm_wake_up(struct panel_drv_data *ddata)
  264. {
  265. if (ddata->ulps_enabled)
  266. return dsicm_exit_ulps(ddata);
  267. dsicm_cancel_ulps_work(ddata);
  268. dsicm_queue_ulps_work(ddata);
  269. return 0;
  270. }
  271. static int dsicm_bl_update_status(struct backlight_device *dev)
  272. {
  273. struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
  274. struct omap_dss_device *in = ddata->in;
  275. int r = 0;
  276. int level;
  277. if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
  278. dev->props.power == FB_BLANK_UNBLANK)
  279. level = dev->props.brightness;
  280. else
  281. level = 0;
  282. dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level);
  283. mutex_lock(&ddata->lock);
  284. if (ddata->enabled) {
  285. in->ops.dsi->bus_lock(in);
  286. r = dsicm_wake_up(ddata);
  287. if (!r)
  288. r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level);
  289. in->ops.dsi->bus_unlock(in);
  290. }
  291. mutex_unlock(&ddata->lock);
  292. return r;
  293. }
  294. static int dsicm_bl_get_intensity(struct backlight_device *dev)
  295. {
  296. if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
  297. dev->props.power == FB_BLANK_UNBLANK)
  298. return dev->props.brightness;
  299. return 0;
  300. }
  301. static const struct backlight_ops dsicm_bl_ops = {
  302. .get_brightness = dsicm_bl_get_intensity,
  303. .update_status = dsicm_bl_update_status,
  304. };
  305. static ssize_t dsicm_num_errors_show(struct device *dev,
  306. struct device_attribute *attr, char *buf)
  307. {
  308. struct platform_device *pdev = to_platform_device(dev);
  309. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  310. struct omap_dss_device *in = ddata->in;
  311. u8 errors = 0;
  312. int r;
  313. mutex_lock(&ddata->lock);
  314. if (ddata->enabled) {
  315. in->ops.dsi->bus_lock(in);
  316. r = dsicm_wake_up(ddata);
  317. if (!r)
  318. r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
  319. &errors);
  320. in->ops.dsi->bus_unlock(in);
  321. } else {
  322. r = -ENODEV;
  323. }
  324. mutex_unlock(&ddata->lock);
  325. if (r)
  326. return r;
  327. return snprintf(buf, PAGE_SIZE, "%d\n", errors);
  328. }
  329. static ssize_t dsicm_hw_revision_show(struct device *dev,
  330. struct device_attribute *attr, char *buf)
  331. {
  332. struct platform_device *pdev = to_platform_device(dev);
  333. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  334. struct omap_dss_device *in = ddata->in;
  335. u8 id1, id2, id3;
  336. int r;
  337. mutex_lock(&ddata->lock);
  338. if (ddata->enabled) {
  339. in->ops.dsi->bus_lock(in);
  340. r = dsicm_wake_up(ddata);
  341. if (!r)
  342. r = dsicm_get_id(ddata, &id1, &id2, &id3);
  343. in->ops.dsi->bus_unlock(in);
  344. } else {
  345. r = -ENODEV;
  346. }
  347. mutex_unlock(&ddata->lock);
  348. if (r)
  349. return r;
  350. return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3);
  351. }
  352. static ssize_t dsicm_store_ulps(struct device *dev,
  353. struct device_attribute *attr,
  354. const char *buf, size_t count)
  355. {
  356. struct platform_device *pdev = to_platform_device(dev);
  357. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  358. struct omap_dss_device *in = ddata->in;
  359. unsigned long t;
  360. int r;
  361. r = kstrtoul(buf, 0, &t);
  362. if (r)
  363. return r;
  364. mutex_lock(&ddata->lock);
  365. if (ddata->enabled) {
  366. in->ops.dsi->bus_lock(in);
  367. if (t)
  368. r = dsicm_enter_ulps(ddata);
  369. else
  370. r = dsicm_wake_up(ddata);
  371. in->ops.dsi->bus_unlock(in);
  372. }
  373. mutex_unlock(&ddata->lock);
  374. if (r)
  375. return r;
  376. return count;
  377. }
  378. static ssize_t dsicm_show_ulps(struct device *dev,
  379. struct device_attribute *attr,
  380. char *buf)
  381. {
  382. struct platform_device *pdev = to_platform_device(dev);
  383. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  384. unsigned t;
  385. mutex_lock(&ddata->lock);
  386. t = ddata->ulps_enabled;
  387. mutex_unlock(&ddata->lock);
  388. return snprintf(buf, PAGE_SIZE, "%u\n", t);
  389. }
  390. static ssize_t dsicm_store_ulps_timeout(struct device *dev,
  391. struct device_attribute *attr,
  392. const char *buf, size_t count)
  393. {
  394. struct platform_device *pdev = to_platform_device(dev);
  395. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  396. struct omap_dss_device *in = ddata->in;
  397. unsigned long t;
  398. int r;
  399. r = kstrtoul(buf, 0, &t);
  400. if (r)
  401. return r;
  402. mutex_lock(&ddata->lock);
  403. ddata->ulps_timeout = t;
  404. if (ddata->enabled) {
  405. /* dsicm_wake_up will restart the timer */
  406. in->ops.dsi->bus_lock(in);
  407. r = dsicm_wake_up(ddata);
  408. in->ops.dsi->bus_unlock(in);
  409. }
  410. mutex_unlock(&ddata->lock);
  411. if (r)
  412. return r;
  413. return count;
  414. }
  415. static ssize_t dsicm_show_ulps_timeout(struct device *dev,
  416. struct device_attribute *attr,
  417. char *buf)
  418. {
  419. struct platform_device *pdev = to_platform_device(dev);
  420. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  421. unsigned t;
  422. mutex_lock(&ddata->lock);
  423. t = ddata->ulps_timeout;
  424. mutex_unlock(&ddata->lock);
  425. return snprintf(buf, PAGE_SIZE, "%u\n", t);
  426. }
  427. static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
  428. static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
  429. static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
  430. dsicm_show_ulps, dsicm_store_ulps);
  431. static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
  432. dsicm_show_ulps_timeout, dsicm_store_ulps_timeout);
  433. static struct attribute *dsicm_attrs[] = {
  434. &dev_attr_num_dsi_errors.attr,
  435. &dev_attr_hw_revision.attr,
  436. &dev_attr_ulps.attr,
  437. &dev_attr_ulps_timeout.attr,
  438. NULL,
  439. };
  440. static const struct attribute_group dsicm_attr_group = {
  441. .attrs = dsicm_attrs,
  442. };
  443. static void dsicm_hw_reset(struct panel_drv_data *ddata)
  444. {
  445. gpiod_set_value(ddata->reset_gpio, 1);
  446. udelay(10);
  447. /* reset the panel */
  448. gpiod_set_value(ddata->reset_gpio, 0);
  449. /* assert reset */
  450. udelay(10);
  451. gpiod_set_value(ddata->reset_gpio, 1);
  452. /* wait after releasing reset */
  453. usleep_range(5000, 10000);
  454. }
  455. static int dsicm_power_on(struct panel_drv_data *ddata)
  456. {
  457. struct omap_dss_device *in = ddata->in;
  458. u8 id1, id2, id3;
  459. int r;
  460. struct omap_dss_dsi_config dsi_config = {
  461. .mode = OMAP_DSS_DSI_CMD_MODE,
  462. .pixel_format = OMAP_DSS_DSI_FMT_RGB888,
  463. .vm = &ddata->vm,
  464. .hs_clk_min = 150000000,
  465. .hs_clk_max = 300000000,
  466. .lp_clk_min = 7000000,
  467. .lp_clk_max = 10000000,
  468. };
  469. if (ddata->vpnl) {
  470. r = regulator_enable(ddata->vpnl);
  471. if (r) {
  472. dev_err(&ddata->pdev->dev,
  473. "failed to enable VPNL: %d\n", r);
  474. return r;
  475. }
  476. }
  477. if (ddata->vddi) {
  478. r = regulator_enable(ddata->vddi);
  479. if (r) {
  480. dev_err(&ddata->pdev->dev,
  481. "failed to enable VDDI: %d\n", r);
  482. goto err_vpnl;
  483. }
  484. }
  485. if (ddata->pin_config.num_pins > 0) {
  486. r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
  487. if (r) {
  488. dev_err(&ddata->pdev->dev,
  489. "failed to configure DSI pins\n");
  490. goto err_vddi;
  491. }
  492. }
  493. r = in->ops.dsi->set_config(in, &dsi_config);
  494. if (r) {
  495. dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
  496. goto err_vddi;
  497. }
  498. r = in->ops.dsi->enable(in);
  499. if (r) {
  500. dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
  501. goto err_vddi;
  502. }
  503. dsicm_hw_reset(ddata);
  504. in->ops.dsi->enable_hs(in, ddata->channel, false);
  505. r = dsicm_sleep_out(ddata);
  506. if (r)
  507. goto err;
  508. r = dsicm_get_id(ddata, &id1, &id2, &id3);
  509. if (r)
  510. goto err;
  511. r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, 0xff);
  512. if (r)
  513. goto err;
  514. r = dsicm_dcs_write_1(ddata, DCS_CTRL_DISPLAY,
  515. (1<<2) | (1<<5)); /* BL | BCTRL */
  516. if (r)
  517. goto err;
  518. r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_PIXEL_FORMAT,
  519. MIPI_DCS_PIXEL_FMT_24BIT);
  520. if (r)
  521. goto err;
  522. r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_ON);
  523. if (r)
  524. goto err;
  525. r = _dsicm_enable_te(ddata, ddata->te_enabled);
  526. if (r)
  527. goto err;
  528. r = in->ops.dsi->enable_video_output(in, ddata->channel);
  529. if (r)
  530. goto err;
  531. ddata->enabled = 1;
  532. if (!ddata->intro_printed) {
  533. dev_info(&ddata->pdev->dev, "panel revision %02x.%02x.%02x\n",
  534. id1, id2, id3);
  535. ddata->intro_printed = true;
  536. }
  537. in->ops.dsi->enable_hs(in, ddata->channel, true);
  538. return 0;
  539. err:
  540. dev_err(&ddata->pdev->dev, "error while enabling panel, issuing HW reset\n");
  541. dsicm_hw_reset(ddata);
  542. in->ops.dsi->disable(in, true, false);
  543. err_vddi:
  544. if (ddata->vddi)
  545. regulator_disable(ddata->vddi);
  546. err_vpnl:
  547. if (ddata->vpnl)
  548. regulator_disable(ddata->vpnl);
  549. return r;
  550. }
  551. static void dsicm_power_off(struct panel_drv_data *ddata)
  552. {
  553. struct omap_dss_device *in = ddata->in;
  554. int r;
  555. in->ops.dsi->disable_video_output(in, ddata->channel);
  556. r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_OFF);
  557. if (!r)
  558. r = dsicm_sleep_in(ddata);
  559. if (r) {
  560. dev_err(&ddata->pdev->dev,
  561. "error disabling panel, issuing HW reset\n");
  562. dsicm_hw_reset(ddata);
  563. }
  564. in->ops.dsi->disable(in, true, false);
  565. if (ddata->vddi)
  566. regulator_disable(ddata->vddi);
  567. if (ddata->vpnl)
  568. regulator_disable(ddata->vpnl);
  569. ddata->enabled = 0;
  570. }
  571. static int dsicm_panel_reset(struct panel_drv_data *ddata)
  572. {
  573. dev_err(&ddata->pdev->dev, "performing LCD reset\n");
  574. dsicm_power_off(ddata);
  575. dsicm_hw_reset(ddata);
  576. return dsicm_power_on(ddata);
  577. }
  578. static int dsicm_connect(struct omap_dss_device *dssdev)
  579. {
  580. struct panel_drv_data *ddata = to_panel_data(dssdev);
  581. struct omap_dss_device *in = ddata->in;
  582. struct device *dev = &ddata->pdev->dev;
  583. int r;
  584. if (omapdss_device_is_connected(dssdev))
  585. return 0;
  586. r = in->ops.dsi->connect(in, dssdev);
  587. if (r) {
  588. dev_err(dev, "Failed to connect to video source\n");
  589. return r;
  590. }
  591. r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
  592. if (r) {
  593. dev_err(dev, "failed to get virtual channel\n");
  594. goto err_req_vc;
  595. }
  596. r = in->ops.dsi->set_vc_id(ddata->in, ddata->channel, TCH);
  597. if (r) {
  598. dev_err(dev, "failed to set VC_ID\n");
  599. goto err_vc_id;
  600. }
  601. return 0;
  602. err_vc_id:
  603. in->ops.dsi->release_vc(ddata->in, ddata->channel);
  604. err_req_vc:
  605. in->ops.dsi->disconnect(in, dssdev);
  606. return r;
  607. }
  608. static void dsicm_disconnect(struct omap_dss_device *dssdev)
  609. {
  610. struct panel_drv_data *ddata = to_panel_data(dssdev);
  611. struct omap_dss_device *in = ddata->in;
  612. if (!omapdss_device_is_connected(dssdev))
  613. return;
  614. in->ops.dsi->release_vc(in, ddata->channel);
  615. in->ops.dsi->disconnect(in, dssdev);
  616. }
  617. static int dsicm_enable(struct omap_dss_device *dssdev)
  618. {
  619. struct panel_drv_data *ddata = to_panel_data(dssdev);
  620. struct omap_dss_device *in = ddata->in;
  621. int r;
  622. dev_dbg(&ddata->pdev->dev, "enable\n");
  623. mutex_lock(&ddata->lock);
  624. if (!omapdss_device_is_connected(dssdev)) {
  625. r = -ENODEV;
  626. goto err;
  627. }
  628. if (omapdss_device_is_enabled(dssdev)) {
  629. r = 0;
  630. goto err;
  631. }
  632. in->ops.dsi->bus_lock(in);
  633. r = dsicm_power_on(ddata);
  634. in->ops.dsi->bus_unlock(in);
  635. if (r)
  636. goto err;
  637. dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
  638. mutex_unlock(&ddata->lock);
  639. dsicm_bl_power(ddata, true);
  640. return 0;
  641. err:
  642. dev_dbg(&ddata->pdev->dev, "enable failed\n");
  643. mutex_unlock(&ddata->lock);
  644. return r;
  645. }
  646. static void dsicm_disable(struct omap_dss_device *dssdev)
  647. {
  648. struct panel_drv_data *ddata = to_panel_data(dssdev);
  649. struct omap_dss_device *in = ddata->in;
  650. int r;
  651. dev_dbg(&ddata->pdev->dev, "disable\n");
  652. dsicm_bl_power(ddata, false);
  653. mutex_lock(&ddata->lock);
  654. dsicm_cancel_ulps_work(ddata);
  655. in->ops.dsi->bus_lock(in);
  656. if (omapdss_device_is_enabled(dssdev)) {
  657. r = dsicm_wake_up(ddata);
  658. if (!r)
  659. dsicm_power_off(ddata);
  660. }
  661. in->ops.dsi->bus_unlock(in);
  662. dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
  663. mutex_unlock(&ddata->lock);
  664. }
  665. static void dsicm_framedone_cb(int err, void *data)
  666. {
  667. struct panel_drv_data *ddata = data;
  668. struct omap_dss_device *in = ddata->in;
  669. dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
  670. in->ops.dsi->bus_unlock(ddata->in);
  671. }
  672. static irqreturn_t dsicm_te_isr(int irq, void *data)
  673. {
  674. struct panel_drv_data *ddata = data;
  675. struct omap_dss_device *in = ddata->in;
  676. int old;
  677. int r;
  678. old = atomic_cmpxchg(&ddata->do_update, 1, 0);
  679. if (old) {
  680. cancel_delayed_work(&ddata->te_timeout_work);
  681. r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
  682. ddata);
  683. if (r)
  684. goto err;
  685. }
  686. return IRQ_HANDLED;
  687. err:
  688. dev_err(&ddata->pdev->dev, "start update failed\n");
  689. in->ops.dsi->bus_unlock(in);
  690. return IRQ_HANDLED;
  691. }
  692. static void dsicm_te_timeout_work_callback(struct work_struct *work)
  693. {
  694. struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
  695. te_timeout_work.work);
  696. struct omap_dss_device *in = ddata->in;
  697. dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
  698. atomic_set(&ddata->do_update, 0);
  699. in->ops.dsi->bus_unlock(in);
  700. }
  701. static int dsicm_update(struct omap_dss_device *dssdev,
  702. u16 x, u16 y, u16 w, u16 h)
  703. {
  704. struct panel_drv_data *ddata = to_panel_data(dssdev);
  705. struct omap_dss_device *in = ddata->in;
  706. int r;
  707. dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
  708. mutex_lock(&ddata->lock);
  709. in->ops.dsi->bus_lock(in);
  710. r = dsicm_wake_up(ddata);
  711. if (r)
  712. goto err;
  713. if (!ddata->enabled) {
  714. r = 0;
  715. goto err;
  716. }
  717. /* XXX no need to send this every frame, but dsi break if not done */
  718. r = dsicm_set_update_window(ddata, 0, 0,
  719. dssdev->panel.vm.hactive,
  720. dssdev->panel.vm.vactive);
  721. if (r)
  722. goto err;
  723. if (ddata->te_enabled && ddata->ext_te_gpio) {
  724. schedule_delayed_work(&ddata->te_timeout_work,
  725. msecs_to_jiffies(250));
  726. atomic_set(&ddata->do_update, 1);
  727. } else {
  728. r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
  729. ddata);
  730. if (r)
  731. goto err;
  732. }
  733. /* note: no bus_unlock here. unlock is in framedone_cb */
  734. mutex_unlock(&ddata->lock);
  735. return 0;
  736. err:
  737. in->ops.dsi->bus_unlock(in);
  738. mutex_unlock(&ddata->lock);
  739. return r;
  740. }
  741. static int dsicm_sync(struct omap_dss_device *dssdev)
  742. {
  743. struct panel_drv_data *ddata = to_panel_data(dssdev);
  744. struct omap_dss_device *in = ddata->in;
  745. dev_dbg(&ddata->pdev->dev, "sync\n");
  746. mutex_lock(&ddata->lock);
  747. in->ops.dsi->bus_lock(in);
  748. in->ops.dsi->bus_unlock(in);
  749. mutex_unlock(&ddata->lock);
  750. dev_dbg(&ddata->pdev->dev, "sync done\n");
  751. return 0;
  752. }
  753. static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
  754. {
  755. struct omap_dss_device *in = ddata->in;
  756. int r;
  757. if (enable)
  758. r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
  759. else
  760. r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
  761. if (!ddata->ext_te_gpio)
  762. in->ops.dsi->enable_te(in, enable);
  763. /* possible panel bug */
  764. msleep(100);
  765. return r;
  766. }
  767. static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
  768. {
  769. struct panel_drv_data *ddata = to_panel_data(dssdev);
  770. struct omap_dss_device *in = ddata->in;
  771. int r;
  772. mutex_lock(&ddata->lock);
  773. if (ddata->te_enabled == enable)
  774. goto end;
  775. in->ops.dsi->bus_lock(in);
  776. if (ddata->enabled) {
  777. r = dsicm_wake_up(ddata);
  778. if (r)
  779. goto err;
  780. r = _dsicm_enable_te(ddata, enable);
  781. if (r)
  782. goto err;
  783. }
  784. ddata->te_enabled = enable;
  785. in->ops.dsi->bus_unlock(in);
  786. end:
  787. mutex_unlock(&ddata->lock);
  788. return 0;
  789. err:
  790. in->ops.dsi->bus_unlock(in);
  791. mutex_unlock(&ddata->lock);
  792. return r;
  793. }
  794. static int dsicm_get_te(struct omap_dss_device *dssdev)
  795. {
  796. struct panel_drv_data *ddata = to_panel_data(dssdev);
  797. int r;
  798. mutex_lock(&ddata->lock);
  799. r = ddata->te_enabled;
  800. mutex_unlock(&ddata->lock);
  801. return r;
  802. }
  803. static int dsicm_memory_read(struct omap_dss_device *dssdev,
  804. void *buf, size_t size,
  805. u16 x, u16 y, u16 w, u16 h)
  806. {
  807. struct panel_drv_data *ddata = to_panel_data(dssdev);
  808. struct omap_dss_device *in = ddata->in;
  809. int r;
  810. int first = 1;
  811. int plen;
  812. unsigned buf_used = 0;
  813. if (size < w * h * 3)
  814. return -ENOMEM;
  815. mutex_lock(&ddata->lock);
  816. if (!ddata->enabled) {
  817. r = -ENODEV;
  818. goto err1;
  819. }
  820. size = min((u32)w * h * 3,
  821. dssdev->panel.vm.hactive * dssdev->panel.vm.vactive * 3);
  822. in->ops.dsi->bus_lock(in);
  823. r = dsicm_wake_up(ddata);
  824. if (r)
  825. goto err2;
  826. /* plen 1 or 2 goes into short packet. until checksum error is fixed,
  827. * use short packets. plen 32 works, but bigger packets seem to cause
  828. * an error. */
  829. if (size % 2)
  830. plen = 1;
  831. else
  832. plen = 2;
  833. dsicm_set_update_window(ddata, x, y, w, h);
  834. r = in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, plen);
  835. if (r)
  836. goto err2;
  837. while (buf_used < size) {
  838. u8 dcs_cmd = first ? 0x2e : 0x3e;
  839. first = 0;
  840. r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd,
  841. buf + buf_used, size - buf_used);
  842. if (r < 0) {
  843. dev_err(dssdev->dev, "read error\n");
  844. goto err3;
  845. }
  846. buf_used += r;
  847. if (r < plen) {
  848. dev_err(&ddata->pdev->dev, "short read\n");
  849. break;
  850. }
  851. if (signal_pending(current)) {
  852. dev_err(&ddata->pdev->dev, "signal pending, "
  853. "aborting memory read\n");
  854. r = -ERESTARTSYS;
  855. goto err3;
  856. }
  857. }
  858. r = buf_used;
  859. err3:
  860. in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1);
  861. err2:
  862. in->ops.dsi->bus_unlock(in);
  863. err1:
  864. mutex_unlock(&ddata->lock);
  865. return r;
  866. }
  867. static void dsicm_ulps_work(struct work_struct *work)
  868. {
  869. struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
  870. ulps_work.work);
  871. struct omap_dss_device *dssdev = &ddata->dssdev;
  872. struct omap_dss_device *in = ddata->in;
  873. mutex_lock(&ddata->lock);
  874. if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
  875. mutex_unlock(&ddata->lock);
  876. return;
  877. }
  878. in->ops.dsi->bus_lock(in);
  879. dsicm_enter_ulps(ddata);
  880. in->ops.dsi->bus_unlock(in);
  881. mutex_unlock(&ddata->lock);
  882. }
  883. static void dsicm_get_timings(struct omap_dss_device *dssdev,
  884. struct videomode *vm)
  885. {
  886. struct panel_drv_data *ddata = to_panel_data(dssdev);
  887. *vm = ddata->vm;
  888. }
  889. static int dsicm_check_timings(struct omap_dss_device *dssdev,
  890. struct videomode *vm)
  891. {
  892. struct panel_drv_data *ddata = to_panel_data(dssdev);
  893. int ret = 0;
  894. if (vm->hactive != ddata->vm.hactive)
  895. ret = -EINVAL;
  896. if (vm->vactive != ddata->vm.vactive)
  897. ret = -EINVAL;
  898. if (ret) {
  899. dev_warn(dssdev->dev, "wrong resolution: %d x %d",
  900. vm->hactive, vm->vactive);
  901. dev_warn(dssdev->dev, "panel resolution: %d x %d",
  902. ddata->vm.hactive, ddata->vm.vactive);
  903. }
  904. return ret;
  905. }
  906. static void dsicm_get_size(struct omap_dss_device *dssdev,
  907. unsigned int *width, unsigned int *height)
  908. {
  909. struct panel_drv_data *ddata = to_panel_data(dssdev);
  910. *width = ddata->width_mm;
  911. *height = ddata->height_mm;
  912. }
  913. static struct omap_dss_driver dsicm_ops = {
  914. .connect = dsicm_connect,
  915. .disconnect = dsicm_disconnect,
  916. .enable = dsicm_enable,
  917. .disable = dsicm_disable,
  918. .update = dsicm_update,
  919. .sync = dsicm_sync,
  920. .get_timings = dsicm_get_timings,
  921. .check_timings = dsicm_check_timings,
  922. .get_size = dsicm_get_size,
  923. .enable_te = dsicm_enable_te,
  924. .get_te = dsicm_get_te,
  925. .memory_read = dsicm_memory_read,
  926. };
  927. static int dsicm_probe_of(struct platform_device *pdev)
  928. {
  929. struct device_node *node = pdev->dev.of_node;
  930. struct device_node *backlight;
  931. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  932. struct omap_dss_device *in;
  933. struct display_timing timing;
  934. int err;
  935. ddata->reset_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
  936. if (IS_ERR(ddata->reset_gpio)) {
  937. err = PTR_ERR(ddata->reset_gpio);
  938. dev_err(&pdev->dev, "reset gpio request failed: %d", err);
  939. return err;
  940. }
  941. ddata->ext_te_gpio = devm_gpiod_get_optional(&pdev->dev, "te",
  942. GPIOD_IN);
  943. if (IS_ERR(ddata->ext_te_gpio)) {
  944. err = PTR_ERR(ddata->ext_te_gpio);
  945. dev_err(&pdev->dev, "TE gpio request failed: %d", err);
  946. return err;
  947. }
  948. err = of_get_display_timing(node, "panel-timing", &timing);
  949. if (!err) {
  950. videomode_from_timing(&timing, &ddata->vm);
  951. if (!ddata->vm.pixelclock)
  952. ddata->vm.pixelclock =
  953. ddata->vm.hactive * ddata->vm.vactive * 60;
  954. } else {
  955. dev_warn(&pdev->dev,
  956. "failed to get video timing, using defaults\n");
  957. }
  958. ddata->width_mm = 0;
  959. of_property_read_u32(node, "width-mm", &ddata->width_mm);
  960. ddata->height_mm = 0;
  961. of_property_read_u32(node, "height-mm", &ddata->height_mm);
  962. in = omapdss_of_find_source_for_first_ep(node);
  963. if (IS_ERR(in)) {
  964. dev_err(&pdev->dev, "failed to find video source\n");
  965. return PTR_ERR(in);
  966. }
  967. ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
  968. if (IS_ERR(ddata->vpnl)) {
  969. err = PTR_ERR(ddata->vpnl);
  970. if (err == -EPROBE_DEFER)
  971. return err;
  972. ddata->vpnl = NULL;
  973. }
  974. ddata->vddi = devm_regulator_get_optional(&pdev->dev, "vddi");
  975. if (IS_ERR(ddata->vddi)) {
  976. err = PTR_ERR(ddata->vddi);
  977. if (err == -EPROBE_DEFER)
  978. return err;
  979. ddata->vddi = NULL;
  980. }
  981. ddata->in = in;
  982. backlight = of_parse_phandle(node, "backlight", 0);
  983. if (backlight) {
  984. ddata->extbldev = of_find_backlight_by_node(backlight);
  985. of_node_put(backlight);
  986. if (!ddata->extbldev)
  987. return -EPROBE_DEFER;
  988. } else {
  989. /* assume native backlight support */
  990. ddata->use_dsi_backlight = true;
  991. }
  992. /* TODO: ulps */
  993. return 0;
  994. }
  995. static int dsicm_probe(struct platform_device *pdev)
  996. {
  997. struct panel_drv_data *ddata;
  998. struct backlight_device *bldev = NULL;
  999. struct device *dev = &pdev->dev;
  1000. struct omap_dss_device *dssdev;
  1001. int r;
  1002. dev_dbg(dev, "probe\n");
  1003. ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
  1004. if (!ddata)
  1005. return -ENOMEM;
  1006. platform_set_drvdata(pdev, ddata);
  1007. ddata->pdev = pdev;
  1008. if (!pdev->dev.of_node)
  1009. return -ENODEV;
  1010. ddata->vm.hactive = 864;
  1011. ddata->vm.vactive = 480;
  1012. ddata->vm.pixelclock = 864 * 480 * 60;
  1013. r = dsicm_probe_of(pdev);
  1014. if (r)
  1015. return r;
  1016. dssdev = &ddata->dssdev;
  1017. dssdev->dev = dev;
  1018. dssdev->driver = &dsicm_ops;
  1019. dssdev->panel.vm = ddata->vm;
  1020. dssdev->type = OMAP_DISPLAY_TYPE_DSI;
  1021. dssdev->owner = THIS_MODULE;
  1022. dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
  1023. dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
  1024. OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
  1025. r = omapdss_register_display(dssdev);
  1026. if (r) {
  1027. dev_err(dev, "Failed to register panel\n");
  1028. goto err_reg;
  1029. }
  1030. mutex_init(&ddata->lock);
  1031. atomic_set(&ddata->do_update, 0);
  1032. if (ddata->ext_te_gpio) {
  1033. r = devm_request_irq(dev, gpiod_to_irq(ddata->ext_te_gpio),
  1034. dsicm_te_isr,
  1035. IRQF_TRIGGER_RISING,
  1036. "taal vsync", ddata);
  1037. if (r) {
  1038. dev_err(dev, "IRQ request failed\n");
  1039. goto err_reg;
  1040. }
  1041. INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
  1042. dsicm_te_timeout_work_callback);
  1043. dev_dbg(dev, "Using GPIO TE\n");
  1044. }
  1045. ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
  1046. if (!ddata->workqueue) {
  1047. r = -ENOMEM;
  1048. goto err_reg;
  1049. }
  1050. INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
  1051. dsicm_hw_reset(ddata);
  1052. if (ddata->use_dsi_backlight) {
  1053. struct backlight_properties props = { 0 };
  1054. props.max_brightness = 255;
  1055. props.type = BACKLIGHT_RAW;
  1056. bldev = devm_backlight_device_register(dev, dev_name(dev),
  1057. dev, ddata, &dsicm_bl_ops, &props);
  1058. if (IS_ERR(bldev)) {
  1059. r = PTR_ERR(bldev);
  1060. goto err_bl;
  1061. }
  1062. ddata->bldev = bldev;
  1063. }
  1064. r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
  1065. if (r) {
  1066. dev_err(dev, "failed to create sysfs files\n");
  1067. goto err_bl;
  1068. }
  1069. return 0;
  1070. err_bl:
  1071. destroy_workqueue(ddata->workqueue);
  1072. err_reg:
  1073. if (ddata->extbldev)
  1074. put_device(&ddata->extbldev->dev);
  1075. return r;
  1076. }
  1077. static int __exit dsicm_remove(struct platform_device *pdev)
  1078. {
  1079. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  1080. struct omap_dss_device *dssdev = &ddata->dssdev;
  1081. dev_dbg(&pdev->dev, "remove\n");
  1082. omapdss_unregister_display(dssdev);
  1083. dsicm_disable(dssdev);
  1084. dsicm_disconnect(dssdev);
  1085. sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
  1086. if (ddata->extbldev)
  1087. put_device(&ddata->extbldev->dev);
  1088. omap_dss_put_device(ddata->in);
  1089. dsicm_cancel_ulps_work(ddata);
  1090. destroy_workqueue(ddata->workqueue);
  1091. /* reset, to be sure that the panel is in a valid state */
  1092. dsicm_hw_reset(ddata);
  1093. return 0;
  1094. }
  1095. static const struct of_device_id dsicm_of_match[] = {
  1096. { .compatible = "omapdss,panel-dsi-cm", },
  1097. {},
  1098. };
  1099. MODULE_DEVICE_TABLE(of, dsicm_of_match);
  1100. static struct platform_driver dsicm_driver = {
  1101. .probe = dsicm_probe,
  1102. .remove = __exit_p(dsicm_remove),
  1103. .driver = {
  1104. .name = "panel-dsi-cm",
  1105. .of_match_table = dsicm_of_match,
  1106. .suppress_bind_attrs = true,
  1107. },
  1108. };
  1109. module_platform_driver(dsicm_driver);
  1110. MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
  1111. MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
  1112. MODULE_LICENSE("GPL");