drm_mipi_dsi.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937
  1. /*
  2. * MIPI DSI Bus
  3. *
  4. * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
  5. * Andrzej Hajda <a.hajda@samsung.com>
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sub license, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice (including the
  16. * next paragraph) shall be included in all copies or substantial portions
  17. * of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  23. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  24. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  25. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. */
  27. #include <linux/device.h>
  28. #include <linux/module.h>
  29. #include <linux/of.h>
  30. #include <linux/of_device.h>
  31. #include <linux/pm_runtime.h>
  32. #include <linux/slab.h>
  33. #include <drm/display/drm_dsc.h>
  34. #include <drm/drm_mipi_dsi.h>
  35. #include <drm/drm_print.h>
  36. #include <video/mipi_display.h>
  37. /**
  38. * DOC: dsi helpers
  39. *
  40. * These functions contain some common logic and helpers to deal with MIPI DSI
  41. * peripherals.
  42. *
  43. * Helpers are provided for a number of standard MIPI DSI command as well as a
  44. * subset of the MIPI DCS command set.
  45. */
  46. static int mipi_dsi_device_match(struct device *dev, const struct device_driver *drv)
  47. {
  48. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  49. /* attempt OF style match */
  50. if (of_driver_match_device(dev, drv))
  51. return 1;
  52. /* compare DSI device and driver names */
  53. if (!strcmp(dsi->name, drv->name))
  54. return 1;
  55. return 0;
  56. }
  57. static int mipi_dsi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  58. {
  59. const struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  60. int err;
  61. err = of_device_uevent_modalias(dev, env);
  62. if (err != -ENODEV)
  63. return err;
  64. add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX,
  65. dsi->name);
  66. return 0;
  67. }
  68. static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
  69. .runtime_suspend = pm_generic_runtime_suspend,
  70. .runtime_resume = pm_generic_runtime_resume,
  71. .suspend = pm_generic_suspend,
  72. .resume = pm_generic_resume,
  73. .freeze = pm_generic_freeze,
  74. .thaw = pm_generic_thaw,
  75. .poweroff = pm_generic_poweroff,
  76. .restore = pm_generic_restore,
  77. };
  78. static const struct bus_type mipi_dsi_bus_type = {
  79. .name = "mipi-dsi",
  80. .match = mipi_dsi_device_match,
  81. .uevent = mipi_dsi_uevent,
  82. .pm = &mipi_dsi_device_pm_ops,
  83. };
  84. /**
  85. * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
  86. * device tree node
  87. * @np: device tree node
  88. *
  89. * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
  90. * such device exists (or has not been registered yet).
  91. */
  92. struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
  93. {
  94. struct device *dev;
  95. dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
  96. return dev ? to_mipi_dsi_device(dev) : NULL;
  97. }
  98. EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
  99. static void mipi_dsi_dev_release(struct device *dev)
  100. {
  101. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  102. of_node_put(dev->of_node);
  103. kfree(dsi);
  104. }
  105. static const struct device_type mipi_dsi_device_type = {
  106. .release = mipi_dsi_dev_release,
  107. };
  108. static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
  109. {
  110. struct mipi_dsi_device *dsi;
  111. dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
  112. if (!dsi)
  113. return ERR_PTR(-ENOMEM);
  114. dsi->host = host;
  115. dsi->dev.bus = &mipi_dsi_bus_type;
  116. dsi->dev.parent = host->dev;
  117. dsi->dev.type = &mipi_dsi_device_type;
  118. device_initialize(&dsi->dev);
  119. return dsi;
  120. }
  121. static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
  122. {
  123. struct mipi_dsi_host *host = dsi->host;
  124. dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), dsi->channel);
  125. return device_add(&dsi->dev);
  126. }
  127. #if IS_ENABLED(CONFIG_OF)
  128. static struct mipi_dsi_device *
  129. of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
  130. {
  131. struct mipi_dsi_device_info info = { };
  132. int ret;
  133. u32 reg;
  134. if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
  135. drm_err(host, "modalias failure on %pOF\n", node);
  136. return ERR_PTR(-EINVAL);
  137. }
  138. ret = of_property_read_u32(node, "reg", &reg);
  139. if (ret) {
  140. drm_err(host, "device node %pOF has no valid reg property: %d\n",
  141. node, ret);
  142. return ERR_PTR(-EINVAL);
  143. }
  144. info.channel = reg;
  145. info.node = of_node_get(node);
  146. return mipi_dsi_device_register_full(host, &info);
  147. }
  148. #else
  149. static struct mipi_dsi_device *
  150. of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
  151. {
  152. return ERR_PTR(-ENODEV);
  153. }
  154. #endif
  155. /**
  156. * mipi_dsi_device_register_full - create a MIPI DSI device
  157. * @host: DSI host to which this device is connected
  158. * @info: pointer to template containing DSI device information
  159. *
  160. * Create a MIPI DSI device by using the device information provided by
  161. * mipi_dsi_device_info template
  162. *
  163. * Returns:
  164. * A pointer to the newly created MIPI DSI device, or, a pointer encoded
  165. * with an error
  166. */
  167. struct mipi_dsi_device *
  168. mipi_dsi_device_register_full(struct mipi_dsi_host *host,
  169. const struct mipi_dsi_device_info *info)
  170. {
  171. struct mipi_dsi_device *dsi;
  172. int ret;
  173. if (!info) {
  174. drm_err(host, "invalid mipi_dsi_device_info pointer\n");
  175. return ERR_PTR(-EINVAL);
  176. }
  177. if (info->channel > 3) {
  178. drm_err(host, "invalid virtual channel: %u\n", info->channel);
  179. return ERR_PTR(-EINVAL);
  180. }
  181. dsi = mipi_dsi_device_alloc(host);
  182. if (IS_ERR(dsi)) {
  183. drm_err(host, "failed to allocate DSI device %ld\n",
  184. PTR_ERR(dsi));
  185. return dsi;
  186. }
  187. device_set_node(&dsi->dev, of_fwnode_handle(info->node));
  188. dsi->channel = info->channel;
  189. strscpy(dsi->name, info->type, sizeof(dsi->name));
  190. ret = mipi_dsi_device_add(dsi);
  191. if (ret) {
  192. drm_err(host, "failed to add DSI device %d\n", ret);
  193. kfree(dsi);
  194. return ERR_PTR(ret);
  195. }
  196. return dsi;
  197. }
  198. EXPORT_SYMBOL(mipi_dsi_device_register_full);
  199. /**
  200. * mipi_dsi_device_unregister - unregister MIPI DSI device
  201. * @dsi: DSI peripheral device
  202. */
  203. void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
  204. {
  205. device_unregister(&dsi->dev);
  206. }
  207. EXPORT_SYMBOL(mipi_dsi_device_unregister);
  208. static void devm_mipi_dsi_device_unregister(void *arg)
  209. {
  210. struct mipi_dsi_device *dsi = arg;
  211. mipi_dsi_device_unregister(dsi);
  212. }
  213. /**
  214. * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
  215. * @dev: device to tie the MIPI-DSI device lifetime to
  216. * @host: DSI host to which this device is connected
  217. * @info: pointer to template containing DSI device information
  218. *
  219. * Create a MIPI DSI device by using the device information provided by
  220. * mipi_dsi_device_info template
  221. *
  222. * This is the managed version of mipi_dsi_device_register_full() which
  223. * automatically calls mipi_dsi_device_unregister() when @dev is
  224. * unbound.
  225. *
  226. * Returns:
  227. * A pointer to the newly created MIPI DSI device, or, a pointer encoded
  228. * with an error
  229. */
  230. struct mipi_dsi_device *
  231. devm_mipi_dsi_device_register_full(struct device *dev,
  232. struct mipi_dsi_host *host,
  233. const struct mipi_dsi_device_info *info)
  234. {
  235. struct mipi_dsi_device *dsi;
  236. int ret;
  237. dsi = mipi_dsi_device_register_full(host, info);
  238. if (IS_ERR(dsi))
  239. return dsi;
  240. ret = devm_add_action_or_reset(dev,
  241. devm_mipi_dsi_device_unregister,
  242. dsi);
  243. if (ret)
  244. return ERR_PTR(ret);
  245. return dsi;
  246. }
  247. EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
  248. static DEFINE_MUTEX(host_lock);
  249. static LIST_HEAD(host_list);
  250. /**
  251. * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
  252. * device tree node
  253. * @node: device tree node
  254. *
  255. * Returns:
  256. * A pointer to the MIPI DSI host corresponding to @node or NULL if no
  257. * such device exists (or has not been registered yet).
  258. */
  259. struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
  260. {
  261. struct mipi_dsi_host *host;
  262. mutex_lock(&host_lock);
  263. list_for_each_entry(host, &host_list, list) {
  264. if (host->dev->of_node == node) {
  265. mutex_unlock(&host_lock);
  266. return host;
  267. }
  268. }
  269. mutex_unlock(&host_lock);
  270. return NULL;
  271. }
  272. EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
  273. int mipi_dsi_host_register(struct mipi_dsi_host *host)
  274. {
  275. struct device_node *node;
  276. for_each_available_child_of_node(host->dev->of_node, node) {
  277. /* skip nodes without reg property */
  278. if (!of_property_present(node, "reg"))
  279. continue;
  280. of_mipi_dsi_device_add(host, node);
  281. }
  282. mutex_lock(&host_lock);
  283. list_add_tail(&host->list, &host_list);
  284. mutex_unlock(&host_lock);
  285. return 0;
  286. }
  287. EXPORT_SYMBOL(mipi_dsi_host_register);
  288. static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
  289. {
  290. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  291. if (dsi->attached)
  292. mipi_dsi_detach(dsi);
  293. mipi_dsi_device_unregister(dsi);
  294. return 0;
  295. }
  296. void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
  297. {
  298. device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
  299. mutex_lock(&host_lock);
  300. list_del_init(&host->list);
  301. mutex_unlock(&host_lock);
  302. }
  303. EXPORT_SYMBOL(mipi_dsi_host_unregister);
  304. /**
  305. * mipi_dsi_attach - attach a DSI device to its DSI host
  306. * @dsi: DSI peripheral
  307. */
  308. int mipi_dsi_attach(struct mipi_dsi_device *dsi)
  309. {
  310. const struct mipi_dsi_host_ops *ops = dsi->host->ops;
  311. int ret;
  312. if (!ops || !ops->attach)
  313. return -ENOSYS;
  314. ret = ops->attach(dsi->host, dsi);
  315. if (ret)
  316. return ret;
  317. dsi->attached = true;
  318. return 0;
  319. }
  320. EXPORT_SYMBOL(mipi_dsi_attach);
  321. /**
  322. * mipi_dsi_detach - detach a DSI device from its DSI host
  323. * @dsi: DSI peripheral
  324. */
  325. int mipi_dsi_detach(struct mipi_dsi_device *dsi)
  326. {
  327. const struct mipi_dsi_host_ops *ops = dsi->host->ops;
  328. if (WARN_ON(!dsi->attached))
  329. return -EINVAL;
  330. if (!ops || !ops->detach)
  331. return -ENOSYS;
  332. dsi->attached = false;
  333. return ops->detach(dsi->host, dsi);
  334. }
  335. EXPORT_SYMBOL(mipi_dsi_detach);
  336. static void devm_mipi_dsi_detach(void *arg)
  337. {
  338. struct mipi_dsi_device *dsi = arg;
  339. mipi_dsi_detach(dsi);
  340. }
  341. /**
  342. * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
  343. * @dev: device to tie the MIPI-DSI device attachment lifetime to
  344. * @dsi: DSI peripheral
  345. *
  346. * This is the managed version of mipi_dsi_attach() which automatically
  347. * calls mipi_dsi_detach() when @dev is unbound.
  348. *
  349. * Returns:
  350. * 0 on success, a negative error code on failure.
  351. */
  352. int devm_mipi_dsi_attach(struct device *dev,
  353. struct mipi_dsi_device *dsi)
  354. {
  355. int ret;
  356. ret = mipi_dsi_attach(dsi);
  357. if (ret)
  358. return ret;
  359. ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
  360. if (ret)
  361. return ret;
  362. return 0;
  363. }
  364. EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
  365. static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
  366. struct mipi_dsi_msg *msg)
  367. {
  368. const struct mipi_dsi_host_ops *ops = dsi->host->ops;
  369. if (!ops || !ops->transfer)
  370. return -ENOSYS;
  371. if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
  372. msg->flags |= MIPI_DSI_MSG_USE_LPM;
  373. return ops->transfer(dsi->host, msg);
  374. }
  375. /**
  376. * mipi_dsi_packet_format_is_short - check if a packet is of the short format
  377. * @type: MIPI DSI data type of the packet
  378. *
  379. * Return: true if the packet for the given data type is a short packet, false
  380. * otherwise.
  381. */
  382. bool mipi_dsi_packet_format_is_short(u8 type)
  383. {
  384. switch (type) {
  385. case MIPI_DSI_V_SYNC_START:
  386. case MIPI_DSI_V_SYNC_END:
  387. case MIPI_DSI_H_SYNC_START:
  388. case MIPI_DSI_H_SYNC_END:
  389. case MIPI_DSI_COMPRESSION_MODE:
  390. case MIPI_DSI_END_OF_TRANSMISSION:
  391. case MIPI_DSI_COLOR_MODE_OFF:
  392. case MIPI_DSI_COLOR_MODE_ON:
  393. case MIPI_DSI_SHUTDOWN_PERIPHERAL:
  394. case MIPI_DSI_TURN_ON_PERIPHERAL:
  395. case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
  396. case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
  397. case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
  398. case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
  399. case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
  400. case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
  401. case MIPI_DSI_DCS_SHORT_WRITE:
  402. case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
  403. case MIPI_DSI_DCS_READ:
  404. case MIPI_DSI_EXECUTE_QUEUE:
  405. case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
  406. return true;
  407. }
  408. return false;
  409. }
  410. EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
  411. /**
  412. * mipi_dsi_packet_format_is_long - check if a packet is of the long format
  413. * @type: MIPI DSI data type of the packet
  414. *
  415. * Return: true if the packet for the given data type is a long packet, false
  416. * otherwise.
  417. */
  418. bool mipi_dsi_packet_format_is_long(u8 type)
  419. {
  420. switch (type) {
  421. case MIPI_DSI_NULL_PACKET:
  422. case MIPI_DSI_BLANKING_PACKET:
  423. case MIPI_DSI_GENERIC_LONG_WRITE:
  424. case MIPI_DSI_DCS_LONG_WRITE:
  425. case MIPI_DSI_PICTURE_PARAMETER_SET:
  426. case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
  427. case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
  428. case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
  429. case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
  430. case MIPI_DSI_PACKED_PIXEL_STREAM_30:
  431. case MIPI_DSI_PACKED_PIXEL_STREAM_36:
  432. case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
  433. case MIPI_DSI_PACKED_PIXEL_STREAM_16:
  434. case MIPI_DSI_PACKED_PIXEL_STREAM_18:
  435. case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
  436. case MIPI_DSI_PACKED_PIXEL_STREAM_24:
  437. return true;
  438. }
  439. return false;
  440. }
  441. EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
  442. /**
  443. * mipi_dsi_create_packet - create a packet from a message according to the
  444. * DSI protocol
  445. * @packet: pointer to a DSI packet structure
  446. * @msg: message to translate into a packet
  447. *
  448. * Return: 0 on success or a negative error code on failure.
  449. */
  450. int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
  451. const struct mipi_dsi_msg *msg)
  452. {
  453. if (!packet || !msg)
  454. return -EINVAL;
  455. /* do some minimum sanity checking */
  456. if (!mipi_dsi_packet_format_is_short(msg->type) &&
  457. !mipi_dsi_packet_format_is_long(msg->type))
  458. return -EINVAL;
  459. if (msg->channel > 3)
  460. return -EINVAL;
  461. memset(packet, 0, sizeof(*packet));
  462. packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
  463. /* TODO: compute ECC if hardware support is not available */
  464. /*
  465. * Long write packets contain the word count in header bytes 1 and 2.
  466. * The payload follows the header and is word count bytes long.
  467. *
  468. * Short write packets encode up to two parameters in header bytes 1
  469. * and 2.
  470. */
  471. if (mipi_dsi_packet_format_is_long(msg->type)) {
  472. packet->header[1] = (msg->tx_len >> 0) & 0xff;
  473. packet->header[2] = (msg->tx_len >> 8) & 0xff;
  474. packet->payload_length = msg->tx_len;
  475. packet->payload = msg->tx_buf;
  476. } else {
  477. const u8 *tx = msg->tx_buf;
  478. packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
  479. packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
  480. }
  481. packet->size = sizeof(packet->header) + packet->payload_length;
  482. return 0;
  483. }
  484. EXPORT_SYMBOL(mipi_dsi_create_packet);
  485. /**
  486. * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
  487. * @dsi: DSI peripheral device
  488. *
  489. * Return: 0 on success or a negative error code on failure.
  490. */
  491. int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
  492. {
  493. struct mipi_dsi_msg msg = {
  494. .channel = dsi->channel,
  495. .type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
  496. .tx_buf = (u8 [2]) { 0, 0 },
  497. .tx_len = 2,
  498. };
  499. int ret = mipi_dsi_device_transfer(dsi, &msg);
  500. return (ret < 0) ? ret : 0;
  501. }
  502. EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
  503. /**
  504. * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
  505. * @dsi: DSI peripheral device
  506. *
  507. * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() instead.
  508. *
  509. * Return: 0 on success or a negative error code on failure.
  510. */
  511. int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
  512. {
  513. struct mipi_dsi_msg msg = {
  514. .channel = dsi->channel,
  515. .type = MIPI_DSI_TURN_ON_PERIPHERAL,
  516. .tx_buf = (u8 [2]) { 0, 0 },
  517. .tx_len = 2,
  518. };
  519. int ret = mipi_dsi_device_transfer(dsi, &msg);
  520. return (ret < 0) ? ret : 0;
  521. }
  522. EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
  523. /*
  524. * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of
  525. * the payload in a long packet transmitted from the peripheral back to the
  526. * host processor
  527. * @dsi: DSI peripheral device
  528. * @value: the maximum size of the payload
  529. *
  530. * Return: 0 on success or a negative error code on failure.
  531. */
  532. int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
  533. u16 value)
  534. {
  535. u8 tx[2] = { value & 0xff, value >> 8 };
  536. struct mipi_dsi_msg msg = {
  537. .channel = dsi->channel,
  538. .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
  539. .tx_len = sizeof(tx),
  540. .tx_buf = tx,
  541. };
  542. int ret = mipi_dsi_device_transfer(dsi, &msg);
  543. return (ret < 0) ? ret : 0;
  544. }
  545. EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
  546. /**
  547. * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral
  548. * @dsi: DSI peripheral device
  549. * @enable: Whether to enable or disable the DSC
  550. * @algo: Selected compression algorithm
  551. * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
  552. *
  553. * Enable or disable Display Stream Compression on the peripheral.
  554. * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() instead.
  555. *
  556. * Return: 0 on success or a negative error code on failure.
  557. */
  558. int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
  559. enum mipi_dsi_compression_algo algo,
  560. unsigned int pps_selector)
  561. {
  562. u8 tx[2] = { };
  563. struct mipi_dsi_msg msg = {
  564. .channel = dsi->channel,
  565. .type = MIPI_DSI_COMPRESSION_MODE,
  566. .tx_len = sizeof(tx),
  567. .tx_buf = tx,
  568. };
  569. int ret;
  570. if (algo > 3 || pps_selector > 3)
  571. return -EINVAL;
  572. tx[0] = (enable << 0) |
  573. (algo << 1) |
  574. (pps_selector << 4);
  575. ret = mipi_dsi_device_transfer(dsi, &msg);
  576. return (ret < 0) ? ret : 0;
  577. }
  578. EXPORT_SYMBOL(mipi_dsi_compression_mode_ext);
  579. /**
  580. * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
  581. * @dsi: DSI peripheral device
  582. * @enable: Whether to enable or disable the DSC
  583. *
  584. * Enable or disable Display Stream Compression on the peripheral using the
  585. * default Picture Parameter Set and VESA DSC 1.1 algorithm.
  586. *
  587. * Return: 0 on success or a negative error code on failure.
  588. */
  589. int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
  590. {
  591. return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0);
  592. }
  593. EXPORT_SYMBOL(mipi_dsi_compression_mode);
  594. /**
  595. * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
  596. * @dsi: DSI peripheral device
  597. * @pps: VESA DSC 1.1 Picture Parameter Set
  598. *
  599. * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
  600. * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() instead.
  601. *
  602. * Return: 0 on success or a negative error code on failure.
  603. */
  604. int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
  605. const struct drm_dsc_picture_parameter_set *pps)
  606. {
  607. struct mipi_dsi_msg msg = {
  608. .channel = dsi->channel,
  609. .type = MIPI_DSI_PICTURE_PARAMETER_SET,
  610. .tx_len = sizeof(*pps),
  611. .tx_buf = pps,
  612. };
  613. int ret = mipi_dsi_device_transfer(dsi, &msg);
  614. return (ret < 0) ? ret : 0;
  615. }
  616. EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
  617. /**
  618. * mipi_dsi_generic_write() - transmit data using a generic write packet
  619. * @dsi: DSI peripheral device
  620. * @payload: buffer containing the payload
  621. * @size: size of payload buffer
  622. *
  623. * This function will automatically choose the right data type depending on
  624. * the payload length.
  625. *
  626. * Return: The number of bytes transmitted on success or a negative error code
  627. * on failure.
  628. */
  629. ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
  630. size_t size)
  631. {
  632. struct mipi_dsi_msg msg = {
  633. .channel = dsi->channel,
  634. .tx_buf = payload,
  635. .tx_len = size
  636. };
  637. switch (size) {
  638. case 0:
  639. msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
  640. break;
  641. case 1:
  642. msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
  643. break;
  644. case 2:
  645. msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
  646. break;
  647. default:
  648. msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
  649. break;
  650. }
  651. return mipi_dsi_device_transfer(dsi, &msg);
  652. }
  653. EXPORT_SYMBOL(mipi_dsi_generic_write);
  654. /**
  655. * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
  656. * @dsi: DSI peripheral device
  657. * @payload: buffer containing the payload
  658. * @size: size of payload buffer
  659. *
  660. * Like mipi_dsi_generic_write() but includes a dev_err()
  661. * call for you and returns 0 upon success, not the number of bytes sent.
  662. *
  663. * Return: 0 on success or a negative error code on failure.
  664. */
  665. int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
  666. const void *payload, size_t size)
  667. {
  668. struct device *dev = &dsi->dev;
  669. ssize_t ret;
  670. ret = mipi_dsi_generic_write(dsi, payload, size);
  671. if (ret < 0) {
  672. dev_err(dev, "sending generic data %*ph failed: %zd\n",
  673. (int)size, payload, ret);
  674. return ret;
  675. }
  676. return 0;
  677. }
  678. EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
  679. /**
  680. * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err
  681. * @ctx: Context for multiple DSI transactions
  682. * @payload: buffer containing the payload
  683. * @size: size of payload buffer
  684. *
  685. * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
  686. * makes it convenient to make several calls in a row.
  687. */
  688. void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
  689. const void *payload, size_t size)
  690. {
  691. struct mipi_dsi_device *dsi = ctx->dsi;
  692. struct device *dev = &dsi->dev;
  693. ssize_t ret;
  694. if (ctx->accum_err)
  695. return;
  696. ret = mipi_dsi_generic_write(dsi, payload, size);
  697. if (ret < 0) {
  698. ctx->accum_err = ret;
  699. dev_err(dev, "sending generic data %*ph failed: %d\n",
  700. (int)size, payload, ctx->accum_err);
  701. }
  702. }
  703. EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
  704. /**
  705. * mipi_dsi_generic_read() - receive data using a generic read packet
  706. * @dsi: DSI peripheral device
  707. * @params: buffer containing the request parameters
  708. * @num_params: number of request parameters
  709. * @data: buffer in which to return the received data
  710. * @size: size of receive buffer
  711. *
  712. * This function will automatically choose the right data type depending on
  713. * the number of parameters passed in.
  714. *
  715. * Return: The number of bytes successfully read or a negative error code on
  716. * failure.
  717. */
  718. ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
  719. size_t num_params, void *data, size_t size)
  720. {
  721. struct mipi_dsi_msg msg = {
  722. .channel = dsi->channel,
  723. .tx_len = num_params,
  724. .tx_buf = params,
  725. .rx_len = size,
  726. .rx_buf = data
  727. };
  728. switch (num_params) {
  729. case 0:
  730. msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
  731. break;
  732. case 1:
  733. msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
  734. break;
  735. case 2:
  736. msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
  737. break;
  738. default:
  739. return -EINVAL;
  740. }
  741. return mipi_dsi_device_transfer(dsi, &msg);
  742. }
  743. EXPORT_SYMBOL(mipi_dsi_generic_read);
  744. /**
  745. * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
  746. * @dsi: DSI peripheral device
  747. * @data: buffer containing data to be transmitted
  748. * @len: size of transmission buffer
  749. *
  750. * This function will automatically choose the right data type depending on
  751. * the command payload length.
  752. *
  753. * Return: The number of bytes successfully transmitted or a negative error
  754. * code on failure.
  755. */
  756. ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
  757. const void *data, size_t len)
  758. {
  759. struct mipi_dsi_msg msg = {
  760. .channel = dsi->channel,
  761. .tx_buf = data,
  762. .tx_len = len
  763. };
  764. switch (len) {
  765. case 0:
  766. return -EINVAL;
  767. case 1:
  768. msg.type = MIPI_DSI_DCS_SHORT_WRITE;
  769. break;
  770. case 2:
  771. msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
  772. break;
  773. default:
  774. msg.type = MIPI_DSI_DCS_LONG_WRITE;
  775. break;
  776. }
  777. return mipi_dsi_device_transfer(dsi, &msg);
  778. }
  779. EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
  780. /**
  781. * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log
  782. * @dsi: DSI peripheral device
  783. * @data: buffer containing data to be transmitted
  784. * @len: size of transmission buffer
  785. *
  786. * Like mipi_dsi_dcs_write_buffer() but includes a dev_err()
  787. * call for you and returns 0 upon success, not the number of bytes sent.
  788. *
  789. * Return: 0 on success or a negative error code on failure.
  790. */
  791. int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
  792. const void *data, size_t len)
  793. {
  794. struct device *dev = &dsi->dev;
  795. ssize_t ret;
  796. ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
  797. if (ret < 0) {
  798. dev_err(dev, "sending dcs data %*ph failed: %zd\n",
  799. (int)len, data, ret);
  800. return ret;
  801. }
  802. return 0;
  803. }
  804. EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
  805. /**
  806. * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err
  807. * @ctx: Context for multiple DSI transactions
  808. * @data: buffer containing data to be transmitted
  809. * @len: size of transmission buffer
  810. *
  811. * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
  812. * makes it convenient to make several calls in a row.
  813. */
  814. void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
  815. const void *data, size_t len)
  816. {
  817. struct mipi_dsi_device *dsi = ctx->dsi;
  818. struct device *dev = &dsi->dev;
  819. ssize_t ret;
  820. if (ctx->accum_err)
  821. return;
  822. ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
  823. if (ret < 0) {
  824. ctx->accum_err = ret;
  825. dev_err(dev, "sending dcs data %*ph failed: %d\n",
  826. (int)len, data, ctx->accum_err);
  827. }
  828. }
  829. EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
  830. /**
  831. * mipi_dsi_dcs_write() - send DCS write command
  832. * @dsi: DSI peripheral device
  833. * @cmd: DCS command
  834. * @data: buffer containing the command payload
  835. * @len: command payload length
  836. *
  837. * This function will automatically choose the right data type depending on
  838. * the command payload length.
  839. *
  840. * Return: The number of bytes successfully transmitted or a negative error
  841. * code on failure.
  842. */
  843. ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
  844. const void *data, size_t len)
  845. {
  846. ssize_t err;
  847. size_t size;
  848. u8 stack_tx[8];
  849. u8 *tx;
  850. size = 1 + len;
  851. if (len > ARRAY_SIZE(stack_tx) - 1) {
  852. tx = kmalloc(size, GFP_KERNEL);
  853. if (!tx)
  854. return -ENOMEM;
  855. } else {
  856. tx = stack_tx;
  857. }
  858. /* concatenate the DCS command byte and the payload */
  859. tx[0] = cmd;
  860. if (data)
  861. memcpy(&tx[1], data, len);
  862. err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
  863. if (tx != stack_tx)
  864. kfree(tx);
  865. return err;
  866. }
  867. EXPORT_SYMBOL(mipi_dsi_dcs_write);
  868. /**
  869. * mipi_dsi_dcs_read() - send DCS read request command
  870. * @dsi: DSI peripheral device
  871. * @cmd: DCS command
  872. * @data: buffer in which to receive data
  873. * @len: size of receive buffer
  874. *
  875. * Return: The number of bytes read or a negative error code on failure.
  876. */
  877. ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
  878. size_t len)
  879. {
  880. struct mipi_dsi_msg msg = {
  881. .channel = dsi->channel,
  882. .type = MIPI_DSI_DCS_READ,
  883. .tx_buf = &cmd,
  884. .tx_len = 1,
  885. .rx_buf = data,
  886. .rx_len = len
  887. };
  888. return mipi_dsi_device_transfer(dsi, &msg);
  889. }
  890. EXPORT_SYMBOL(mipi_dsi_dcs_read);
  891. /**
  892. * mipi_dsi_dcs_nop() - send DCS nop packet
  893. * @dsi: DSI peripheral device
  894. *
  895. * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead.
  896. *
  897. * Return: 0 on success or a negative error code on failure.
  898. */
  899. int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
  900. {
  901. ssize_t err;
  902. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
  903. if (err < 0)
  904. return err;
  905. return 0;
  906. }
  907. EXPORT_SYMBOL(mipi_dsi_dcs_nop);
  908. /**
  909. * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
  910. * @dsi: DSI peripheral device
  911. *
  912. * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead.
  913. *
  914. * Return: 0 on success or a negative error code on failure.
  915. */
  916. int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
  917. {
  918. ssize_t err;
  919. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
  920. if (err < 0)
  921. return err;
  922. return 0;
  923. }
  924. EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
  925. /**
  926. * mipi_dsi_dcs_get_power_mode() - query the display module's current power
  927. * mode
  928. * @dsi: DSI peripheral device
  929. * @mode: return location for the current power mode
  930. *
  931. * Return: 0 on success or a negative error code on failure.
  932. */
  933. int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
  934. {
  935. ssize_t err;
  936. err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
  937. sizeof(*mode));
  938. if (err <= 0) {
  939. if (err == 0)
  940. err = -ENODATA;
  941. return err;
  942. }
  943. return 0;
  944. }
  945. EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
  946. /**
  947. * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
  948. * data used by the interface
  949. * @dsi: DSI peripheral device
  950. * @format: return location for the pixel format
  951. *
  952. * Return: 0 on success or a negative error code on failure.
  953. */
  954. int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
  955. {
  956. ssize_t err;
  957. err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
  958. sizeof(*format));
  959. if (err <= 0) {
  960. if (err == 0)
  961. err = -ENODATA;
  962. return err;
  963. }
  964. return 0;
  965. }
  966. EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
  967. /**
  968. * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
  969. * display module except interface communication
  970. * @dsi: DSI peripheral device
  971. *
  972. * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() instead.
  973. *
  974. * Return: 0 on success or a negative error code on failure.
  975. */
  976. int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
  977. {
  978. ssize_t err;
  979. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
  980. if (err < 0)
  981. return err;
  982. return 0;
  983. }
  984. EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
  985. /**
  986. * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
  987. * module
  988. * @dsi: DSI peripheral device
  989. *
  990. * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() instead.
  991. *
  992. * Return: 0 on success or a negative error code on failure.
  993. */
  994. int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
  995. {
  996. ssize_t err;
  997. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
  998. if (err < 0)
  999. return err;
  1000. return 0;
  1001. }
  1002. EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
  1003. /**
  1004. * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
  1005. * display device
  1006. * @dsi: DSI peripheral device
  1007. *
  1008. * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() instead.
  1009. *
  1010. * Return: 0 on success or a negative error code on failure.
  1011. */
  1012. int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
  1013. {
  1014. ssize_t err;
  1015. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
  1016. if (err < 0)
  1017. return err;
  1018. return 0;
  1019. }
  1020. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
  1021. /**
  1022. * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
  1023. * display device
  1024. * @dsi: DSI peripheral device
  1025. *
  1026. * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() instead.
  1027. *
  1028. * Return: 0 on success or a negative error code on failure
  1029. */
  1030. int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
  1031. {
  1032. ssize_t err;
  1033. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
  1034. if (err < 0)
  1035. return err;
  1036. return 0;
  1037. }
  1038. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
  1039. /**
  1040. * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
  1041. * memory accessed by the host processor
  1042. * @dsi: DSI peripheral device
  1043. * @start: first column of frame memory
  1044. * @end: last column of frame memory
  1045. *
  1046. * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi()
  1047. * instead.
  1048. *
  1049. * Return: 0 on success or a negative error code on failure.
  1050. */
  1051. int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
  1052. u16 end)
  1053. {
  1054. u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
  1055. ssize_t err;
  1056. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
  1057. sizeof(payload));
  1058. if (err < 0)
  1059. return err;
  1060. return 0;
  1061. }
  1062. EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
  1063. /**
  1064. * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
  1065. * memory accessed by the host processor
  1066. * @dsi: DSI peripheral device
  1067. * @start: first page of frame memory
  1068. * @end: last page of frame memory
  1069. *
  1070. * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi()
  1071. * instead.
  1072. *
  1073. * Return: 0 on success or a negative error code on failure.
  1074. */
  1075. int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
  1076. u16 end)
  1077. {
  1078. u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
  1079. ssize_t err;
  1080. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
  1081. sizeof(payload));
  1082. if (err < 0)
  1083. return err;
  1084. return 0;
  1085. }
  1086. EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
  1087. /**
  1088. * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
  1089. * output signal on the TE signal line
  1090. * @dsi: DSI peripheral device
  1091. *
  1092. * Return: 0 on success or a negative error code on failure
  1093. */
  1094. int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
  1095. {
  1096. ssize_t err;
  1097. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
  1098. if (err < 0)
  1099. return err;
  1100. return 0;
  1101. }
  1102. EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
  1103. /**
  1104. * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
  1105. * output signal on the TE signal line.
  1106. * @dsi: DSI peripheral device
  1107. * @mode: the Tearing Effect Output Line mode
  1108. *
  1109. * This function is deprecated. Use mipi_dsi_dcs_set_tear_on_multi() instead.
  1110. *
  1111. * Return: 0 on success or a negative error code on failure
  1112. */
  1113. int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
  1114. enum mipi_dsi_dcs_tear_mode mode)
  1115. {
  1116. u8 value = mode;
  1117. ssize_t err;
  1118. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
  1119. sizeof(value));
  1120. if (err < 0)
  1121. return err;
  1122. return 0;
  1123. }
  1124. EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
  1125. /**
  1126. * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
  1127. * data used by the interface
  1128. * @dsi: DSI peripheral device
  1129. * @format: pixel format
  1130. *
  1131. * This function is deprecated. Use mipi_dsi_dcs_set_pixel_format_multi()
  1132. * instead.
  1133. *
  1134. * Return: 0 on success or a negative error code on failure.
  1135. */
  1136. int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
  1137. {
  1138. ssize_t err;
  1139. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
  1140. sizeof(format));
  1141. if (err < 0)
  1142. return err;
  1143. return 0;
  1144. }
  1145. EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
  1146. /**
  1147. * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
  1148. * the Tearing Effect output signal of the display module
  1149. * @dsi: DSI peripheral device
  1150. * @scanline: scanline to use as trigger
  1151. *
  1152. * This function is deprecated. Use mipi_dsi_dcs_set_tear_scanline_multi()
  1153. * instead.
  1154. *
  1155. * Return: 0 on success or a negative error code on failure
  1156. */
  1157. int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
  1158. {
  1159. u8 payload[2] = { scanline >> 8, scanline & 0xff };
  1160. ssize_t err;
  1161. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload,
  1162. sizeof(payload));
  1163. if (err < 0)
  1164. return err;
  1165. return 0;
  1166. }
  1167. EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
  1168. /**
  1169. * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
  1170. * display
  1171. * @dsi: DSI peripheral device
  1172. * @brightness: brightness value
  1173. *
  1174. * This function is deprecated. Use mipi_dsi_dcs_set_display_brightness_multi()
  1175. * instead.
  1176. *
  1177. * Return: 0 on success or a negative error code on failure.
  1178. */
  1179. int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
  1180. u16 brightness)
  1181. {
  1182. u8 payload[2] = { brightness & 0xff, brightness >> 8 };
  1183. ssize_t err;
  1184. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
  1185. payload, sizeof(payload));
  1186. if (err < 0)
  1187. return err;
  1188. return 0;
  1189. }
  1190. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness);
  1191. /**
  1192. * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
  1193. * of the display
  1194. * @dsi: DSI peripheral device
  1195. * @brightness: brightness value
  1196. *
  1197. * Return: 0 on success or a negative error code on failure.
  1198. */
  1199. int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
  1200. u16 *brightness)
  1201. {
  1202. ssize_t err;
  1203. err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
  1204. brightness, sizeof(*brightness));
  1205. if (err <= 0) {
  1206. if (err == 0)
  1207. err = -ENODATA;
  1208. return err;
  1209. }
  1210. return 0;
  1211. }
  1212. EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
  1213. /**
  1214. * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
  1215. * of the display
  1216. * @dsi: DSI peripheral device
  1217. * @brightness: brightness value
  1218. *
  1219. * Return: 0 on success or a negative error code on failure.
  1220. */
  1221. int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
  1222. u16 brightness)
  1223. {
  1224. u8 payload[2] = { brightness >> 8, brightness & 0xff };
  1225. ssize_t err;
  1226. err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
  1227. payload, sizeof(payload));
  1228. if (err < 0)
  1229. return err;
  1230. return 0;
  1231. }
  1232. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
  1233. /**
  1234. * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
  1235. * brightness value of the display
  1236. * @dsi: DSI peripheral device
  1237. * @brightness: brightness value
  1238. *
  1239. * Return: 0 on success or a negative error code on failure.
  1240. */
  1241. int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
  1242. u16 *brightness)
  1243. {
  1244. u8 brightness_be[2];
  1245. ssize_t err;
  1246. err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
  1247. brightness_be, sizeof(brightness_be));
  1248. if (err <= 0) {
  1249. if (err == 0)
  1250. err = -ENODATA;
  1251. return err;
  1252. }
  1253. *brightness = (brightness_be[0] << 8) | brightness_be[1];
  1254. return 0;
  1255. }
  1256. EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
  1257. /**
  1258. * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
  1259. * @ctx: Context for multiple DSI transactions
  1260. * @pps: VESA DSC 1.1 Picture Parameter Set
  1261. *
  1262. * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
  1263. * makes it convenient to make several calls in a row.
  1264. */
  1265. void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
  1266. const struct drm_dsc_picture_parameter_set *pps)
  1267. {
  1268. struct mipi_dsi_device *dsi = ctx->dsi;
  1269. struct device *dev = &dsi->dev;
  1270. ssize_t ret;
  1271. if (ctx->accum_err)
  1272. return;
  1273. ret = mipi_dsi_picture_parameter_set(dsi, pps);
  1274. if (ret < 0) {
  1275. ctx->accum_err = ret;
  1276. dev_err(dev, "sending PPS failed: %d\n",
  1277. ctx->accum_err);
  1278. }
  1279. }
  1280. EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
  1281. /**
  1282. * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
  1283. * @ctx: Context for multiple DSI transactions
  1284. * @enable: Whether to enable or disable the DSC
  1285. * @algo: Selected compression algorithm
  1286. * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
  1287. *
  1288. * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
  1289. * makes it convenient to make several calls in a row.
  1290. */
  1291. void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
  1292. bool enable,
  1293. enum mipi_dsi_compression_algo algo,
  1294. unsigned int pps_selector)
  1295. {
  1296. struct mipi_dsi_device *dsi = ctx->dsi;
  1297. struct device *dev = &dsi->dev;
  1298. ssize_t ret;
  1299. if (ctx->accum_err)
  1300. return;
  1301. ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
  1302. if (ret < 0) {
  1303. ctx->accum_err = ret;
  1304. dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
  1305. ctx->accum_err);
  1306. }
  1307. }
  1308. EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
  1309. /**
  1310. * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
  1311. * @ctx: Context for multiple DSI transactions
  1312. *
  1313. * Like mipi_dsi_dcs_nop() but deals with errors in a way that
  1314. * makes it convenient to make several calls in a row.
  1315. */
  1316. void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
  1317. {
  1318. struct mipi_dsi_device *dsi = ctx->dsi;
  1319. struct device *dev = &dsi->dev;
  1320. ssize_t ret;
  1321. if (ctx->accum_err)
  1322. return;
  1323. ret = mipi_dsi_dcs_nop(dsi);
  1324. if (ret < 0) {
  1325. ctx->accum_err = ret;
  1326. dev_err(dev, "sending DCS NOP failed: %d\n",
  1327. ctx->accum_err);
  1328. }
  1329. }
  1330. EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
  1331. /**
  1332. * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet
  1333. * @ctx: Context for multiple DSI transactions
  1334. *
  1335. * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
  1336. * makes it convenient to make several calls in a row.
  1337. */
  1338. void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
  1339. {
  1340. struct mipi_dsi_device *dsi = ctx->dsi;
  1341. struct device *dev = &dsi->dev;
  1342. ssize_t ret;
  1343. if (ctx->accum_err)
  1344. return;
  1345. ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
  1346. if (ret < 0) {
  1347. ctx->accum_err = ret;
  1348. dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
  1349. ctx->accum_err);
  1350. }
  1351. }
  1352. EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
  1353. /**
  1354. * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
  1355. * @ctx: Context for multiple DSI transactions
  1356. *
  1357. * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
  1358. * makes it convenient to make several calls in a row.
  1359. */
  1360. void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
  1361. {
  1362. struct mipi_dsi_device *dsi = ctx->dsi;
  1363. struct device *dev = &dsi->dev;
  1364. ssize_t ret;
  1365. if (ctx->accum_err)
  1366. return;
  1367. ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
  1368. if (ret < 0) {
  1369. ctx->accum_err = ret;
  1370. dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
  1371. ctx->accum_err);
  1372. }
  1373. }
  1374. EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
  1375. /**
  1376. * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
  1377. * @ctx: Context for multiple DSI transactions
  1378. *
  1379. * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
  1380. * makes it convenient to make several calls in a row.
  1381. */
  1382. void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
  1383. {
  1384. struct mipi_dsi_device *dsi = ctx->dsi;
  1385. struct device *dev = &dsi->dev;
  1386. ssize_t ret;
  1387. if (ctx->accum_err)
  1388. return;
  1389. ret = mipi_dsi_dcs_set_display_off(dsi);
  1390. if (ret < 0) {
  1391. ctx->accum_err = ret;
  1392. dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
  1393. ctx->accum_err);
  1394. }
  1395. }
  1396. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
  1397. /**
  1398. * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
  1399. * @ctx: Context for multiple DSI transactions
  1400. *
  1401. * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
  1402. * makes it convenient to make several calls in a row.
  1403. */
  1404. void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
  1405. {
  1406. struct mipi_dsi_device *dsi = ctx->dsi;
  1407. struct device *dev = &dsi->dev;
  1408. ssize_t ret;
  1409. if (ctx->accum_err)
  1410. return;
  1411. ret = mipi_dsi_dcs_set_display_on(dsi);
  1412. if (ret < 0) {
  1413. ctx->accum_err = ret;
  1414. dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
  1415. ctx->accum_err);
  1416. }
  1417. }
  1418. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
  1419. /**
  1420. * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
  1421. * @ctx: Context for multiple DSI transactions
  1422. * @mode: the Tearing Effect Output Line mode
  1423. *
  1424. * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
  1425. * makes it convenient to make several calls in a row.
  1426. */
  1427. void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
  1428. enum mipi_dsi_dcs_tear_mode mode)
  1429. {
  1430. struct mipi_dsi_device *dsi = ctx->dsi;
  1431. struct device *dev = &dsi->dev;
  1432. ssize_t ret;
  1433. if (ctx->accum_err)
  1434. return;
  1435. ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
  1436. if (ret < 0) {
  1437. ctx->accum_err = ret;
  1438. dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
  1439. ctx->accum_err);
  1440. }
  1441. }
  1442. EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
  1443. /**
  1444. * mipi_dsi_turn_on_peripheral_multi() - sends a Turn On Peripheral command
  1445. * @ctx: Context for multiple DSI transactions
  1446. *
  1447. * Like mipi_dsi_turn_on_peripheral() but deals with errors in a way that
  1448. * makes it convenient to make several calls in a row.
  1449. */
  1450. void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx)
  1451. {
  1452. struct mipi_dsi_device *dsi = ctx->dsi;
  1453. struct device *dev = &dsi->dev;
  1454. int ret;
  1455. if (ctx->accum_err)
  1456. return;
  1457. ret = mipi_dsi_turn_on_peripheral(dsi);
  1458. if (ret < 0) {
  1459. ctx->accum_err = ret;
  1460. dev_err(dev, "Failed to turn on peripheral: %d\n",
  1461. ctx->accum_err);
  1462. }
  1463. }
  1464. EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi);
  1465. /**
  1466. * mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module
  1467. * @ctx: Context for multiple DSI transactions
  1468. *
  1469. * Like mipi_dsi_dcs_soft_reset() but deals with errors in a way that
  1470. * makes it convenient to make several calls in a row.
  1471. */
  1472. void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx)
  1473. {
  1474. struct mipi_dsi_device *dsi = ctx->dsi;
  1475. struct device *dev = &dsi->dev;
  1476. int ret;
  1477. if (ctx->accum_err)
  1478. return;
  1479. ret = mipi_dsi_dcs_soft_reset(dsi);
  1480. if (ret < 0) {
  1481. ctx->accum_err = ret;
  1482. dev_err(dev, "Failed to mipi_dsi_dcs_soft_reset: %d\n",
  1483. ctx->accum_err);
  1484. }
  1485. }
  1486. EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset_multi);
  1487. /**
  1488. * mipi_dsi_dcs_set_display_brightness_multi() - sets the brightness value of
  1489. * the display
  1490. * @ctx: Context for multiple DSI transactions
  1491. * @brightness: brightness value
  1492. *
  1493. * Like mipi_dsi_dcs_set_display_brightness() but deals with errors in a way that
  1494. * makes it convenient to make several calls in a row.
  1495. */
  1496. void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx,
  1497. u16 brightness)
  1498. {
  1499. struct mipi_dsi_device *dsi = ctx->dsi;
  1500. struct device *dev = &dsi->dev;
  1501. int ret;
  1502. if (ctx->accum_err)
  1503. return;
  1504. ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
  1505. if (ret < 0) {
  1506. ctx->accum_err = ret;
  1507. dev_err(dev, "Failed to write display brightness: %d\n",
  1508. ctx->accum_err);
  1509. }
  1510. }
  1511. EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_multi);
  1512. /**
  1513. * mipi_dsi_dcs_set_pixel_format_multi() - sets the pixel format for the RGB image
  1514. * data used by the interface
  1515. * @ctx: Context for multiple DSI transactions
  1516. * @format: pixel format
  1517. *
  1518. * Like mipi_dsi_dcs_set_pixel_format() but deals with errors in a way that
  1519. * makes it convenient to make several calls in a row.
  1520. */
  1521. void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx,
  1522. u8 format)
  1523. {
  1524. struct mipi_dsi_device *dsi = ctx->dsi;
  1525. struct device *dev = &dsi->dev;
  1526. int ret;
  1527. if (ctx->accum_err)
  1528. return;
  1529. ret = mipi_dsi_dcs_set_pixel_format(dsi, format);
  1530. if (ret < 0) {
  1531. ctx->accum_err = ret;
  1532. dev_err(dev, "Failed to set pixel format: %d\n",
  1533. ctx->accum_err);
  1534. }
  1535. }
  1536. EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format_multi);
  1537. /**
  1538. * mipi_dsi_dcs_set_column_address_multi() - define the column extent of the
  1539. * frame memory accessed by the host processor
  1540. * @ctx: Context for multiple DSI transactions
  1541. * @start: first column of frame memory
  1542. * @end: last column of frame memory
  1543. *
  1544. * Like mipi_dsi_dcs_set_column_address() but deals with errors in a way that
  1545. * makes it convenient to make several calls in a row.
  1546. */
  1547. void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx,
  1548. u16 start, u16 end)
  1549. {
  1550. struct mipi_dsi_device *dsi = ctx->dsi;
  1551. struct device *dev = &dsi->dev;
  1552. int ret;
  1553. if (ctx->accum_err)
  1554. return;
  1555. ret = mipi_dsi_dcs_set_column_address(dsi, start, end);
  1556. if (ret < 0) {
  1557. ctx->accum_err = ret;
  1558. dev_err(dev, "Failed to set column address: %d\n",
  1559. ctx->accum_err);
  1560. }
  1561. }
  1562. EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address_multi);
  1563. /**
  1564. * mipi_dsi_dcs_set_page_address_multi() - define the page extent of the
  1565. * frame memory accessed by the host processor
  1566. * @ctx: Context for multiple DSI transactions
  1567. * @start: first page of frame memory
  1568. * @end: last page of frame memory
  1569. *
  1570. * Like mipi_dsi_dcs_set_page_address() but deals with errors in a way that
  1571. * makes it convenient to make several calls in a row.
  1572. */
  1573. void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx,
  1574. u16 start, u16 end)
  1575. {
  1576. struct mipi_dsi_device *dsi = ctx->dsi;
  1577. struct device *dev = &dsi->dev;
  1578. int ret;
  1579. if (ctx->accum_err)
  1580. return;
  1581. ret = mipi_dsi_dcs_set_page_address(dsi, start, end);
  1582. if (ret < 0) {
  1583. ctx->accum_err = ret;
  1584. dev_err(dev, "Failed to set page address: %d\n",
  1585. ctx->accum_err);
  1586. }
  1587. }
  1588. EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address_multi);
  1589. /**
  1590. * mipi_dsi_dcs_set_tear_scanline_multi() - set the scanline to use as trigger for
  1591. * the Tearing Effect output signal of the display module
  1592. * @ctx: Context for multiple DSI transactions
  1593. * @scanline: scanline to use as trigger
  1594. *
  1595. * Like mipi_dsi_dcs_set_tear_scanline() but deals with errors in a way that
  1596. * makes it convenient to make several calls in a row.
  1597. */
  1598. void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx,
  1599. u16 scanline)
  1600. {
  1601. struct mipi_dsi_device *dsi = ctx->dsi;
  1602. struct device *dev = &dsi->dev;
  1603. int ret;
  1604. if (ctx->accum_err)
  1605. return;
  1606. ret = mipi_dsi_dcs_set_tear_scanline(dsi, scanline);
  1607. if (ret < 0) {
  1608. ctx->accum_err = ret;
  1609. dev_err(dev, "Failed to set tear scanline: %d\n",
  1610. ctx->accum_err);
  1611. }
  1612. }
  1613. EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline_multi);
  1614. static int mipi_dsi_drv_probe(struct device *dev)
  1615. {
  1616. struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
  1617. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  1618. return drv->probe(dsi);
  1619. }
  1620. static int mipi_dsi_drv_remove(struct device *dev)
  1621. {
  1622. struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
  1623. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  1624. drv->remove(dsi);
  1625. return 0;
  1626. }
  1627. static void mipi_dsi_drv_shutdown(struct device *dev)
  1628. {
  1629. struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
  1630. struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
  1631. drv->shutdown(dsi);
  1632. }
  1633. /**
  1634. * mipi_dsi_driver_register_full() - register a driver for DSI devices
  1635. * @drv: DSI driver structure
  1636. * @owner: owner module
  1637. *
  1638. * Return: 0 on success or a negative error code on failure.
  1639. */
  1640. int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
  1641. struct module *owner)
  1642. {
  1643. drv->driver.bus = &mipi_dsi_bus_type;
  1644. drv->driver.owner = owner;
  1645. if (drv->probe)
  1646. drv->driver.probe = mipi_dsi_drv_probe;
  1647. if (drv->remove)
  1648. drv->driver.remove = mipi_dsi_drv_remove;
  1649. if (drv->shutdown)
  1650. drv->driver.shutdown = mipi_dsi_drv_shutdown;
  1651. return driver_register(&drv->driver);
  1652. }
  1653. EXPORT_SYMBOL(mipi_dsi_driver_register_full);
  1654. /**
  1655. * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
  1656. * @drv: DSI driver structure
  1657. *
  1658. * Return: 0 on success or a negative error code on failure.
  1659. */
  1660. void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
  1661. {
  1662. driver_unregister(&drv->driver);
  1663. }
  1664. EXPORT_SYMBOL(mipi_dsi_driver_unregister);
  1665. static int __init mipi_dsi_bus_init(void)
  1666. {
  1667. return bus_register(&mipi_dsi_bus_type);
  1668. }
  1669. postcore_initcall(mipi_dsi_bus_init);
  1670. MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
  1671. MODULE_DESCRIPTION("MIPI DSI Bus");
  1672. MODULE_LICENSE("GPL and additional rights");