panel-dsi-cm.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457
  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 int 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 int 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 int 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 device *dev = &ddata->pdev->dev;
  582. struct omap_dss_device *in;
  583. int r;
  584. if (omapdss_device_is_connected(dssdev))
  585. return 0;
  586. in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
  587. if (IS_ERR(in)) {
  588. dev_err(dssdev->dev, "failed to find video source\n");
  589. return PTR_ERR(in);
  590. }
  591. r = in->ops.dsi->connect(in, dssdev);
  592. if (r) {
  593. dev_err(dev, "Failed to connect to video source\n");
  594. goto err_connect;
  595. }
  596. r = in->ops.dsi->request_vc(in, &ddata->channel);
  597. if (r) {
  598. dev_err(dev, "failed to get virtual channel\n");
  599. goto err_req_vc;
  600. }
  601. r = in->ops.dsi->set_vc_id(in, ddata->channel, TCH);
  602. if (r) {
  603. dev_err(dev, "failed to set VC_ID\n");
  604. goto err_vc_id;
  605. }
  606. ddata->in = in;
  607. return 0;
  608. err_vc_id:
  609. in->ops.dsi->release_vc(in, ddata->channel);
  610. err_req_vc:
  611. in->ops.dsi->disconnect(in, dssdev);
  612. err_connect:
  613. omap_dss_put_device(in);
  614. return r;
  615. }
  616. static void dsicm_disconnect(struct omap_dss_device *dssdev)
  617. {
  618. struct panel_drv_data *ddata = to_panel_data(dssdev);
  619. struct omap_dss_device *in = ddata->in;
  620. if (!omapdss_device_is_connected(dssdev))
  621. return;
  622. in->ops.dsi->release_vc(in, ddata->channel);
  623. in->ops.dsi->disconnect(in, dssdev);
  624. omap_dss_put_device(in);
  625. ddata->in = NULL;
  626. }
  627. static int dsicm_enable(struct omap_dss_device *dssdev)
  628. {
  629. struct panel_drv_data *ddata = to_panel_data(dssdev);
  630. struct omap_dss_device *in = ddata->in;
  631. int r;
  632. dev_dbg(&ddata->pdev->dev, "enable\n");
  633. mutex_lock(&ddata->lock);
  634. if (!omapdss_device_is_connected(dssdev)) {
  635. r = -ENODEV;
  636. goto err;
  637. }
  638. if (omapdss_device_is_enabled(dssdev)) {
  639. r = 0;
  640. goto err;
  641. }
  642. in->ops.dsi->bus_lock(in);
  643. r = dsicm_power_on(ddata);
  644. in->ops.dsi->bus_unlock(in);
  645. if (r)
  646. goto err;
  647. dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
  648. mutex_unlock(&ddata->lock);
  649. dsicm_bl_power(ddata, true);
  650. return 0;
  651. err:
  652. dev_dbg(&ddata->pdev->dev, "enable failed\n");
  653. mutex_unlock(&ddata->lock);
  654. return r;
  655. }
  656. static void dsicm_disable(struct omap_dss_device *dssdev)
  657. {
  658. struct panel_drv_data *ddata = to_panel_data(dssdev);
  659. struct omap_dss_device *in = ddata->in;
  660. int r;
  661. dev_dbg(&ddata->pdev->dev, "disable\n");
  662. dsicm_bl_power(ddata, false);
  663. mutex_lock(&ddata->lock);
  664. dsicm_cancel_ulps_work(ddata);
  665. in->ops.dsi->bus_lock(in);
  666. if (omapdss_device_is_enabled(dssdev)) {
  667. r = dsicm_wake_up(ddata);
  668. if (!r)
  669. dsicm_power_off(ddata);
  670. }
  671. in->ops.dsi->bus_unlock(in);
  672. dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
  673. mutex_unlock(&ddata->lock);
  674. }
  675. static void dsicm_framedone_cb(int err, void *data)
  676. {
  677. struct panel_drv_data *ddata = data;
  678. struct omap_dss_device *in = ddata->in;
  679. dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
  680. in->ops.dsi->bus_unlock(ddata->in);
  681. }
  682. static irqreturn_t dsicm_te_isr(int irq, void *data)
  683. {
  684. struct panel_drv_data *ddata = data;
  685. struct omap_dss_device *in = ddata->in;
  686. int old;
  687. int r;
  688. old = atomic_cmpxchg(&ddata->do_update, 1, 0);
  689. if (old) {
  690. cancel_delayed_work(&ddata->te_timeout_work);
  691. r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
  692. ddata);
  693. if (r)
  694. goto err;
  695. }
  696. return IRQ_HANDLED;
  697. err:
  698. dev_err(&ddata->pdev->dev, "start update failed\n");
  699. in->ops.dsi->bus_unlock(in);
  700. return IRQ_HANDLED;
  701. }
  702. static void dsicm_te_timeout_work_callback(struct work_struct *work)
  703. {
  704. struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
  705. te_timeout_work.work);
  706. struct omap_dss_device *in = ddata->in;
  707. dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
  708. atomic_set(&ddata->do_update, 0);
  709. in->ops.dsi->bus_unlock(in);
  710. }
  711. static int dsicm_update(struct omap_dss_device *dssdev,
  712. u16 x, u16 y, u16 w, u16 h)
  713. {
  714. struct panel_drv_data *ddata = to_panel_data(dssdev);
  715. struct omap_dss_device *in = ddata->in;
  716. int r;
  717. dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
  718. mutex_lock(&ddata->lock);
  719. in->ops.dsi->bus_lock(in);
  720. r = dsicm_wake_up(ddata);
  721. if (r)
  722. goto err;
  723. if (!ddata->enabled) {
  724. r = 0;
  725. goto err;
  726. }
  727. /* XXX no need to send this every frame, but dsi break if not done */
  728. r = dsicm_set_update_window(ddata, 0, 0,
  729. dssdev->panel.vm.hactive,
  730. dssdev->panel.vm.vactive);
  731. if (r)
  732. goto err;
  733. if (ddata->te_enabled && ddata->ext_te_gpio) {
  734. schedule_delayed_work(&ddata->te_timeout_work,
  735. msecs_to_jiffies(250));
  736. atomic_set(&ddata->do_update, 1);
  737. } else {
  738. r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
  739. ddata);
  740. if (r)
  741. goto err;
  742. }
  743. /* note: no bus_unlock here. unlock is in framedone_cb */
  744. mutex_unlock(&ddata->lock);
  745. return 0;
  746. err:
  747. in->ops.dsi->bus_unlock(in);
  748. mutex_unlock(&ddata->lock);
  749. return r;
  750. }
  751. static int dsicm_sync(struct omap_dss_device *dssdev)
  752. {
  753. struct panel_drv_data *ddata = to_panel_data(dssdev);
  754. struct omap_dss_device *in = ddata->in;
  755. dev_dbg(&ddata->pdev->dev, "sync\n");
  756. mutex_lock(&ddata->lock);
  757. in->ops.dsi->bus_lock(in);
  758. in->ops.dsi->bus_unlock(in);
  759. mutex_unlock(&ddata->lock);
  760. dev_dbg(&ddata->pdev->dev, "sync done\n");
  761. return 0;
  762. }
  763. static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
  764. {
  765. struct omap_dss_device *in = ddata->in;
  766. int r;
  767. if (enable)
  768. r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
  769. else
  770. r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
  771. if (!ddata->ext_te_gpio)
  772. in->ops.dsi->enable_te(in, enable);
  773. /* possible panel bug */
  774. msleep(100);
  775. return r;
  776. }
  777. static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
  778. {
  779. struct panel_drv_data *ddata = to_panel_data(dssdev);
  780. struct omap_dss_device *in = ddata->in;
  781. int r;
  782. mutex_lock(&ddata->lock);
  783. if (ddata->te_enabled == enable)
  784. goto end;
  785. in->ops.dsi->bus_lock(in);
  786. if (ddata->enabled) {
  787. r = dsicm_wake_up(ddata);
  788. if (r)
  789. goto err;
  790. r = _dsicm_enable_te(ddata, enable);
  791. if (r)
  792. goto err;
  793. }
  794. ddata->te_enabled = enable;
  795. in->ops.dsi->bus_unlock(in);
  796. end:
  797. mutex_unlock(&ddata->lock);
  798. return 0;
  799. err:
  800. in->ops.dsi->bus_unlock(in);
  801. mutex_unlock(&ddata->lock);
  802. return r;
  803. }
  804. static int dsicm_get_te(struct omap_dss_device *dssdev)
  805. {
  806. struct panel_drv_data *ddata = to_panel_data(dssdev);
  807. int r;
  808. mutex_lock(&ddata->lock);
  809. r = ddata->te_enabled;
  810. mutex_unlock(&ddata->lock);
  811. return r;
  812. }
  813. static int dsicm_memory_read(struct omap_dss_device *dssdev,
  814. void *buf, size_t size,
  815. u16 x, u16 y, u16 w, u16 h)
  816. {
  817. struct panel_drv_data *ddata = to_panel_data(dssdev);
  818. struct omap_dss_device *in = ddata->in;
  819. int r;
  820. int first = 1;
  821. int plen;
  822. unsigned int buf_used = 0;
  823. if (size < w * h * 3)
  824. return -ENOMEM;
  825. mutex_lock(&ddata->lock);
  826. if (!ddata->enabled) {
  827. r = -ENODEV;
  828. goto err1;
  829. }
  830. size = min((u32)w * h * 3,
  831. dssdev->panel.vm.hactive * dssdev->panel.vm.vactive * 3);
  832. in->ops.dsi->bus_lock(in);
  833. r = dsicm_wake_up(ddata);
  834. if (r)
  835. goto err2;
  836. /* plen 1 or 2 goes into short packet. until checksum error is fixed,
  837. * use short packets. plen 32 works, but bigger packets seem to cause
  838. * an error. */
  839. if (size % 2)
  840. plen = 1;
  841. else
  842. plen = 2;
  843. dsicm_set_update_window(ddata, x, y, w, h);
  844. r = in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, plen);
  845. if (r)
  846. goto err2;
  847. while (buf_used < size) {
  848. u8 dcs_cmd = first ? 0x2e : 0x3e;
  849. first = 0;
  850. r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd,
  851. buf + buf_used, size - buf_used);
  852. if (r < 0) {
  853. dev_err(dssdev->dev, "read error\n");
  854. goto err3;
  855. }
  856. buf_used += r;
  857. if (r < plen) {
  858. dev_err(&ddata->pdev->dev, "short read\n");
  859. break;
  860. }
  861. if (signal_pending(current)) {
  862. dev_err(&ddata->pdev->dev, "signal pending, "
  863. "aborting memory read\n");
  864. r = -ERESTARTSYS;
  865. goto err3;
  866. }
  867. }
  868. r = buf_used;
  869. err3:
  870. in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1);
  871. err2:
  872. in->ops.dsi->bus_unlock(in);
  873. err1:
  874. mutex_unlock(&ddata->lock);
  875. return r;
  876. }
  877. static void dsicm_ulps_work(struct work_struct *work)
  878. {
  879. struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
  880. ulps_work.work);
  881. struct omap_dss_device *dssdev = &ddata->dssdev;
  882. struct omap_dss_device *in = ddata->in;
  883. mutex_lock(&ddata->lock);
  884. if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
  885. mutex_unlock(&ddata->lock);
  886. return;
  887. }
  888. in->ops.dsi->bus_lock(in);
  889. dsicm_enter_ulps(ddata);
  890. in->ops.dsi->bus_unlock(in);
  891. mutex_unlock(&ddata->lock);
  892. }
  893. static void dsicm_get_timings(struct omap_dss_device *dssdev,
  894. struct videomode *vm)
  895. {
  896. struct panel_drv_data *ddata = to_panel_data(dssdev);
  897. *vm = ddata->vm;
  898. }
  899. static int dsicm_check_timings(struct omap_dss_device *dssdev,
  900. struct videomode *vm)
  901. {
  902. struct panel_drv_data *ddata = to_panel_data(dssdev);
  903. int ret = 0;
  904. if (vm->hactive != ddata->vm.hactive)
  905. ret = -EINVAL;
  906. if (vm->vactive != ddata->vm.vactive)
  907. ret = -EINVAL;
  908. if (ret) {
  909. dev_warn(dssdev->dev, "wrong resolution: %d x %d",
  910. vm->hactive, vm->vactive);
  911. dev_warn(dssdev->dev, "panel resolution: %d x %d",
  912. ddata->vm.hactive, ddata->vm.vactive);
  913. }
  914. return ret;
  915. }
  916. static void dsicm_get_size(struct omap_dss_device *dssdev,
  917. unsigned int *width, unsigned int *height)
  918. {
  919. struct panel_drv_data *ddata = to_panel_data(dssdev);
  920. *width = ddata->width_mm;
  921. *height = ddata->height_mm;
  922. }
  923. static struct omap_dss_driver dsicm_ops = {
  924. .connect = dsicm_connect,
  925. .disconnect = dsicm_disconnect,
  926. .enable = dsicm_enable,
  927. .disable = dsicm_disable,
  928. .update = dsicm_update,
  929. .sync = dsicm_sync,
  930. .get_timings = dsicm_get_timings,
  931. .check_timings = dsicm_check_timings,
  932. .get_size = dsicm_get_size,
  933. .enable_te = dsicm_enable_te,
  934. .get_te = dsicm_get_te,
  935. .memory_read = dsicm_memory_read,
  936. };
  937. static int dsicm_probe_of(struct platform_device *pdev)
  938. {
  939. struct device_node *node = pdev->dev.of_node;
  940. struct device_node *backlight;
  941. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  942. struct display_timing timing;
  943. int err;
  944. ddata->reset_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
  945. if (IS_ERR(ddata->reset_gpio)) {
  946. err = PTR_ERR(ddata->reset_gpio);
  947. dev_err(&pdev->dev, "reset gpio request failed: %d", err);
  948. return err;
  949. }
  950. ddata->ext_te_gpio = devm_gpiod_get_optional(&pdev->dev, "te",
  951. GPIOD_IN);
  952. if (IS_ERR(ddata->ext_te_gpio)) {
  953. err = PTR_ERR(ddata->ext_te_gpio);
  954. dev_err(&pdev->dev, "TE gpio request failed: %d", err);
  955. return err;
  956. }
  957. err = of_get_display_timing(node, "panel-timing", &timing);
  958. if (!err) {
  959. videomode_from_timing(&timing, &ddata->vm);
  960. if (!ddata->vm.pixelclock)
  961. ddata->vm.pixelclock =
  962. ddata->vm.hactive * ddata->vm.vactive * 60;
  963. } else {
  964. dev_warn(&pdev->dev,
  965. "failed to get video timing, using defaults\n");
  966. }
  967. ddata->width_mm = 0;
  968. of_property_read_u32(node, "width-mm", &ddata->width_mm);
  969. ddata->height_mm = 0;
  970. of_property_read_u32(node, "height-mm", &ddata->height_mm);
  971. ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
  972. if (IS_ERR(ddata->vpnl)) {
  973. err = PTR_ERR(ddata->vpnl);
  974. if (err == -EPROBE_DEFER)
  975. return err;
  976. ddata->vpnl = NULL;
  977. }
  978. ddata->vddi = devm_regulator_get_optional(&pdev->dev, "vddi");
  979. if (IS_ERR(ddata->vddi)) {
  980. err = PTR_ERR(ddata->vddi);
  981. if (err == -EPROBE_DEFER)
  982. return err;
  983. ddata->vddi = NULL;
  984. }
  985. backlight = of_parse_phandle(node, "backlight", 0);
  986. if (backlight) {
  987. ddata->extbldev = of_find_backlight_by_node(backlight);
  988. of_node_put(backlight);
  989. if (!ddata->extbldev)
  990. return -EPROBE_DEFER;
  991. } else {
  992. /* assume native backlight support */
  993. ddata->use_dsi_backlight = true;
  994. }
  995. /* TODO: ulps */
  996. return 0;
  997. }
  998. static int dsicm_probe(struct platform_device *pdev)
  999. {
  1000. struct panel_drv_data *ddata;
  1001. struct backlight_device *bldev = NULL;
  1002. struct device *dev = &pdev->dev;
  1003. struct omap_dss_device *dssdev;
  1004. int r;
  1005. dev_dbg(dev, "probe\n");
  1006. ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
  1007. if (!ddata)
  1008. return -ENOMEM;
  1009. platform_set_drvdata(pdev, ddata);
  1010. ddata->pdev = pdev;
  1011. ddata->vm.hactive = 864;
  1012. ddata->vm.vactive = 480;
  1013. ddata->vm.pixelclock = 864 * 480 * 60;
  1014. r = dsicm_probe_of(pdev);
  1015. if (r)
  1016. return r;
  1017. dssdev = &ddata->dssdev;
  1018. dssdev->dev = dev;
  1019. dssdev->driver = &dsicm_ops;
  1020. dssdev->panel.vm = ddata->vm;
  1021. dssdev->type = OMAP_DISPLAY_TYPE_DSI;
  1022. dssdev->owner = THIS_MODULE;
  1023. dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
  1024. dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
  1025. OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
  1026. r = omapdss_register_display(dssdev);
  1027. if (r) {
  1028. dev_err(dev, "Failed to register panel\n");
  1029. goto err_reg;
  1030. }
  1031. mutex_init(&ddata->lock);
  1032. atomic_set(&ddata->do_update, 0);
  1033. if (ddata->ext_te_gpio) {
  1034. r = devm_request_irq(dev, gpiod_to_irq(ddata->ext_te_gpio),
  1035. dsicm_te_isr,
  1036. IRQF_TRIGGER_RISING,
  1037. "taal vsync", ddata);
  1038. if (r) {
  1039. dev_err(dev, "IRQ request failed\n");
  1040. goto err_reg;
  1041. }
  1042. INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
  1043. dsicm_te_timeout_work_callback);
  1044. dev_dbg(dev, "Using GPIO TE\n");
  1045. }
  1046. ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
  1047. if (!ddata->workqueue) {
  1048. r = -ENOMEM;
  1049. goto err_reg;
  1050. }
  1051. INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
  1052. dsicm_hw_reset(ddata);
  1053. if (ddata->use_dsi_backlight) {
  1054. struct backlight_properties props = { 0 };
  1055. props.max_brightness = 255;
  1056. props.type = BACKLIGHT_RAW;
  1057. bldev = devm_backlight_device_register(dev, dev_name(dev),
  1058. dev, ddata, &dsicm_bl_ops, &props);
  1059. if (IS_ERR(bldev)) {
  1060. r = PTR_ERR(bldev);
  1061. goto err_bl;
  1062. }
  1063. ddata->bldev = bldev;
  1064. }
  1065. r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
  1066. if (r) {
  1067. dev_err(dev, "failed to create sysfs files\n");
  1068. goto err_bl;
  1069. }
  1070. return 0;
  1071. err_bl:
  1072. destroy_workqueue(ddata->workqueue);
  1073. err_reg:
  1074. if (ddata->extbldev)
  1075. put_device(&ddata->extbldev->dev);
  1076. return r;
  1077. }
  1078. static int __exit dsicm_remove(struct platform_device *pdev)
  1079. {
  1080. struct panel_drv_data *ddata = platform_get_drvdata(pdev);
  1081. struct omap_dss_device *dssdev = &ddata->dssdev;
  1082. dev_dbg(&pdev->dev, "remove\n");
  1083. omapdss_unregister_display(dssdev);
  1084. dsicm_disable(dssdev);
  1085. dsicm_disconnect(dssdev);
  1086. sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
  1087. if (ddata->extbldev)
  1088. put_device(&ddata->extbldev->dev);
  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");