dp_audio.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
  6. #include <linux/of_platform.h>
  7. #include <linux/msm_ext_display.h>
  8. #include <drm/drm_dp_helper.h>
  9. #include "dp_catalog.h"
  10. #include "dp_audio.h"
  11. #include "dp_panel.h"
  12. struct dp_audio_private {
  13. struct platform_device *ext_pdev;
  14. struct platform_device *pdev;
  15. struct dp_catalog_audio *catalog;
  16. struct msm_ext_disp_init_data ext_audio_data;
  17. struct dp_panel *panel;
  18. bool ack_enabled;
  19. atomic_t session_on;
  20. bool engine_on;
  21. u32 channels;
  22. struct completion hpd_comp;
  23. struct workqueue_struct *notify_workqueue;
  24. struct delayed_work notify_delayed_work;
  25. struct mutex ops_lock;
  26. struct dp_audio dp_audio;
  27. atomic_t acked;
  28. };
  29. static u32 dp_audio_get_header(struct dp_catalog_audio *catalog,
  30. enum dp_catalog_audio_sdp_type sdp,
  31. enum dp_catalog_audio_header_type header)
  32. {
  33. catalog->sdp_type = sdp;
  34. catalog->sdp_header = header;
  35. catalog->get_header(catalog);
  36. return catalog->data;
  37. }
  38. static void dp_audio_set_header(struct dp_catalog_audio *catalog,
  39. u32 data,
  40. enum dp_catalog_audio_sdp_type sdp,
  41. enum dp_catalog_audio_header_type header)
  42. {
  43. catalog->sdp_type = sdp;
  44. catalog->sdp_header = header;
  45. catalog->data = data;
  46. catalog->set_header(catalog);
  47. }
  48. static void dp_audio_stream_sdp(struct dp_audio_private *audio)
  49. {
  50. struct dp_catalog_audio *catalog = audio->catalog;
  51. u32 value, new_value;
  52. u8 parity_byte;
  53. /* Config header and parity byte 1 */
  54. value = dp_audio_get_header(catalog,
  55. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
  56. value &= 0x0000ffff;
  57. new_value = 0x02;
  58. parity_byte = dp_header_get_parity(new_value);
  59. value |= ((new_value << HEADER_BYTE_1_BIT)
  60. | (parity_byte << PARITY_BYTE_1_BIT));
  61. pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
  62. value, parity_byte);
  63. dp_audio_set_header(catalog, value,
  64. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
  65. /* Config header and parity byte 2 */
  66. value = dp_audio_get_header(catalog,
  67. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
  68. value &= 0xffff0000;
  69. new_value = 0x0;
  70. parity_byte = dp_header_get_parity(new_value);
  71. value |= ((new_value << HEADER_BYTE_2_BIT)
  72. | (parity_byte << PARITY_BYTE_2_BIT));
  73. pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
  74. value, parity_byte);
  75. dp_audio_set_header(catalog, value,
  76. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
  77. /* Config header and parity byte 3 */
  78. value = dp_audio_get_header(catalog,
  79. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
  80. value &= 0x0000ffff;
  81. new_value = audio->channels - 1;
  82. parity_byte = dp_header_get_parity(new_value);
  83. value |= ((new_value << HEADER_BYTE_3_BIT)
  84. | (parity_byte << PARITY_BYTE_3_BIT));
  85. pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
  86. value, parity_byte);
  87. dp_audio_set_header(catalog, value,
  88. DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
  89. }
  90. static void dp_audio_timestamp_sdp(struct dp_audio_private *audio)
  91. {
  92. struct dp_catalog_audio *catalog = audio->catalog;
  93. u32 value, new_value;
  94. u8 parity_byte;
  95. /* Config header and parity byte 1 */
  96. value = dp_audio_get_header(catalog,
  97. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
  98. value &= 0x0000ffff;
  99. new_value = 0x1;
  100. parity_byte = dp_header_get_parity(new_value);
  101. value |= ((new_value << HEADER_BYTE_1_BIT)
  102. | (parity_byte << PARITY_BYTE_1_BIT));
  103. pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
  104. value, parity_byte);
  105. dp_audio_set_header(catalog, value,
  106. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
  107. /* Config header and parity byte 2 */
  108. value = dp_audio_get_header(catalog,
  109. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
  110. value &= 0xffff0000;
  111. new_value = 0x17;
  112. parity_byte = dp_header_get_parity(new_value);
  113. value |= ((new_value << HEADER_BYTE_2_BIT)
  114. | (parity_byte << PARITY_BYTE_2_BIT));
  115. pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
  116. value, parity_byte);
  117. dp_audio_set_header(catalog, value,
  118. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
  119. /* Config header and parity byte 3 */
  120. value = dp_audio_get_header(catalog,
  121. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
  122. value &= 0x0000ffff;
  123. new_value = (0x0 | (0x11 << 2));
  124. parity_byte = dp_header_get_parity(new_value);
  125. value |= ((new_value << HEADER_BYTE_3_BIT)
  126. | (parity_byte << PARITY_BYTE_3_BIT));
  127. pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
  128. value, parity_byte);
  129. dp_audio_set_header(catalog, value,
  130. DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
  131. }
  132. static void dp_audio_infoframe_sdp(struct dp_audio_private *audio)
  133. {
  134. struct dp_catalog_audio *catalog = audio->catalog;
  135. u32 value, new_value;
  136. u8 parity_byte;
  137. /* Config header and parity byte 1 */
  138. value = dp_audio_get_header(catalog,
  139. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
  140. value &= 0x0000ffff;
  141. new_value = 0x84;
  142. parity_byte = dp_header_get_parity(new_value);
  143. value |= ((new_value << HEADER_BYTE_1_BIT)
  144. | (parity_byte << PARITY_BYTE_1_BIT));
  145. pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
  146. value, parity_byte);
  147. dp_audio_set_header(catalog, value,
  148. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
  149. /* Config header and parity byte 2 */
  150. value = dp_audio_get_header(catalog,
  151. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
  152. value &= 0xffff0000;
  153. new_value = 0x1b;
  154. parity_byte = dp_header_get_parity(new_value);
  155. value |= ((new_value << HEADER_BYTE_2_BIT)
  156. | (parity_byte << PARITY_BYTE_2_BIT));
  157. pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
  158. value, parity_byte);
  159. dp_audio_set_header(catalog, value,
  160. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
  161. /* Config header and parity byte 3 */
  162. value = dp_audio_get_header(catalog,
  163. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
  164. value &= 0x0000ffff;
  165. new_value = (0x0 | (0x11 << 2));
  166. parity_byte = dp_header_get_parity(new_value);
  167. value |= ((new_value << HEADER_BYTE_3_BIT)
  168. | (parity_byte << PARITY_BYTE_3_BIT));
  169. pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
  170. new_value, parity_byte);
  171. dp_audio_set_header(catalog, value,
  172. DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
  173. }
  174. static void dp_audio_copy_management_sdp(struct dp_audio_private *audio)
  175. {
  176. struct dp_catalog_audio *catalog = audio->catalog;
  177. u32 value, new_value;
  178. u8 parity_byte;
  179. /* Config header and parity byte 1 */
  180. value = dp_audio_get_header(catalog,
  181. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
  182. value &= 0x0000ffff;
  183. new_value = 0x05;
  184. parity_byte = dp_header_get_parity(new_value);
  185. value |= ((new_value << HEADER_BYTE_1_BIT)
  186. | (parity_byte << PARITY_BYTE_1_BIT));
  187. pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
  188. value, parity_byte);
  189. dp_audio_set_header(catalog, value,
  190. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
  191. /* Config header and parity byte 2 */
  192. value = dp_audio_get_header(catalog,
  193. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
  194. value &= 0xffff0000;
  195. new_value = 0x0F;
  196. parity_byte = dp_header_get_parity(new_value);
  197. value |= ((new_value << HEADER_BYTE_2_BIT)
  198. | (parity_byte << PARITY_BYTE_2_BIT));
  199. pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
  200. value, parity_byte);
  201. dp_audio_set_header(catalog, value,
  202. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
  203. /* Config header and parity byte 3 */
  204. value = dp_audio_get_header(catalog,
  205. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
  206. value &= 0x0000ffff;
  207. new_value = 0x0;
  208. parity_byte = dp_header_get_parity(new_value);
  209. value |= ((new_value << HEADER_BYTE_3_BIT)
  210. | (parity_byte << PARITY_BYTE_3_BIT));
  211. pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
  212. value, parity_byte);
  213. dp_audio_set_header(catalog, value,
  214. DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
  215. }
  216. static void dp_audio_isrc_sdp(struct dp_audio_private *audio)
  217. {
  218. struct dp_catalog_audio *catalog = audio->catalog;
  219. u32 value, new_value;
  220. u8 parity_byte;
  221. /* Config header and parity byte 1 */
  222. value = dp_audio_get_header(catalog,
  223. DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
  224. value &= 0x0000ffff;
  225. new_value = 0x06;
  226. parity_byte = dp_header_get_parity(new_value);
  227. value |= ((new_value << HEADER_BYTE_1_BIT)
  228. | (parity_byte << PARITY_BYTE_1_BIT));
  229. pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
  230. value, parity_byte);
  231. dp_audio_set_header(catalog, value,
  232. DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
  233. /* Config header and parity byte 2 */
  234. value = dp_audio_get_header(catalog,
  235. DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
  236. value &= 0xffff0000;
  237. new_value = 0x0F;
  238. parity_byte = dp_header_get_parity(new_value);
  239. value |= ((new_value << HEADER_BYTE_2_BIT)
  240. | (parity_byte << PARITY_BYTE_2_BIT));
  241. pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
  242. value, parity_byte);
  243. dp_audio_set_header(catalog, value,
  244. DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
  245. }
  246. static void dp_audio_setup_sdp(struct dp_audio_private *audio)
  247. {
  248. if (!atomic_read(&audio->session_on)) {
  249. pr_warn("session inactive\n");
  250. return;
  251. }
  252. /* always program stream 0 first before actual stream cfg */
  253. audio->catalog->stream_id = DP_STREAM_0;
  254. audio->catalog->config_sdp(audio->catalog);
  255. if (audio->panel->stream_id == DP_STREAM_1) {
  256. audio->catalog->stream_id = DP_STREAM_1;
  257. audio->catalog->config_sdp(audio->catalog);
  258. }
  259. dp_audio_stream_sdp(audio);
  260. dp_audio_timestamp_sdp(audio);
  261. dp_audio_infoframe_sdp(audio);
  262. dp_audio_copy_management_sdp(audio);
  263. dp_audio_isrc_sdp(audio);
  264. }
  265. static void dp_audio_setup_acr(struct dp_audio_private *audio)
  266. {
  267. u32 select = 0;
  268. struct dp_catalog_audio *catalog = audio->catalog;
  269. if (!atomic_read(&audio->session_on)) {
  270. pr_warn("session inactive\n");
  271. return;
  272. }
  273. switch (audio->dp_audio.bw_code) {
  274. case DP_LINK_BW_1_62:
  275. select = 0;
  276. break;
  277. case DP_LINK_BW_2_7:
  278. select = 1;
  279. break;
  280. case DP_LINK_BW_5_4:
  281. select = 2;
  282. break;
  283. case DP_LINK_BW_8_1:
  284. select = 3;
  285. break;
  286. default:
  287. pr_debug("Unknown link rate\n");
  288. select = 0;
  289. break;
  290. }
  291. catalog->data = select;
  292. catalog->config_acr(catalog);
  293. }
  294. static void dp_audio_enable(struct dp_audio_private *audio, bool enable)
  295. {
  296. struct dp_catalog_audio *catalog = audio->catalog;
  297. audio->engine_on = enable;
  298. if (!atomic_read(&audio->session_on)) {
  299. pr_warn("session inactive. enable=%d\n", enable);
  300. return;
  301. }
  302. catalog->data = enable;
  303. catalog->enable(catalog);
  304. }
  305. static struct dp_audio_private *dp_audio_get_data(struct platform_device *pdev)
  306. {
  307. struct msm_ext_disp_data *ext_data;
  308. struct dp_audio *dp_audio;
  309. if (!pdev) {
  310. pr_err("invalid input\n");
  311. return ERR_PTR(-ENODEV);
  312. }
  313. ext_data = platform_get_drvdata(pdev);
  314. if (!ext_data) {
  315. pr_err("invalid ext disp data\n");
  316. return ERR_PTR(-EINVAL);
  317. }
  318. dp_audio = ext_data->intf_data;
  319. if (!ext_data) {
  320. pr_err("invalid intf data\n");
  321. return ERR_PTR(-EINVAL);
  322. }
  323. return container_of(dp_audio, struct dp_audio_private, dp_audio);
  324. }
  325. static int dp_audio_info_setup(struct platform_device *pdev,
  326. struct msm_ext_disp_audio_setup_params *params)
  327. {
  328. int rc = 0;
  329. struct dp_audio_private *audio;
  330. audio = dp_audio_get_data(pdev);
  331. if (IS_ERR(audio)) {
  332. rc = PTR_ERR(audio);
  333. return rc;
  334. }
  335. mutex_lock(&audio->ops_lock);
  336. audio->channels = params->num_of_channels;
  337. if (audio->panel->stream_id >= DP_STREAM_MAX) {
  338. pr_err("invalid stream id: %d\n", audio->panel->stream_id);
  339. rc = -EINVAL;
  340. mutex_unlock(&audio->ops_lock);
  341. return rc;
  342. }
  343. dp_audio_setup_sdp(audio);
  344. dp_audio_setup_acr(audio);
  345. dp_audio_enable(audio, true);
  346. mutex_unlock(&audio->ops_lock);
  347. return rc;
  348. }
  349. static int dp_audio_get_edid_blk(struct platform_device *pdev,
  350. struct msm_ext_disp_audio_edid_blk *blk)
  351. {
  352. int rc = 0;
  353. struct dp_audio_private *audio;
  354. struct sde_edid_ctrl *edid;
  355. audio = dp_audio_get_data(pdev);
  356. if (IS_ERR(audio)) {
  357. rc = PTR_ERR(audio);
  358. goto end;
  359. }
  360. if (!audio->panel || !audio->panel->edid_ctrl) {
  361. pr_err("invalid panel data\n");
  362. rc = -EINVAL;
  363. goto end;
  364. }
  365. edid = audio->panel->edid_ctrl;
  366. blk->audio_data_blk = edid->audio_data_block;
  367. blk->audio_data_blk_size = edid->adb_size;
  368. blk->spk_alloc_data_blk = edid->spkr_alloc_data_block;
  369. blk->spk_alloc_data_blk_size = edid->sadb_size;
  370. end:
  371. return rc;
  372. }
  373. static int dp_audio_get_cable_status(struct platform_device *pdev, u32 vote)
  374. {
  375. int rc = 0;
  376. struct dp_audio_private *audio;
  377. audio = dp_audio_get_data(pdev);
  378. if (IS_ERR(audio)) {
  379. rc = PTR_ERR(audio);
  380. goto end;
  381. }
  382. return atomic_read(&audio->session_on);
  383. end:
  384. return rc;
  385. }
  386. static int dp_audio_get_intf_id(struct platform_device *pdev)
  387. {
  388. int rc = 0;
  389. struct dp_audio_private *audio;
  390. audio = dp_audio_get_data(pdev);
  391. if (IS_ERR(audio)) {
  392. rc = PTR_ERR(audio);
  393. goto end;
  394. }
  395. return EXT_DISPLAY_TYPE_DP;
  396. end:
  397. return rc;
  398. }
  399. static void dp_audio_teardown_done(struct platform_device *pdev)
  400. {
  401. struct dp_audio_private *audio;
  402. audio = dp_audio_get_data(pdev);
  403. if (IS_ERR(audio))
  404. return;
  405. mutex_lock(&audio->ops_lock);
  406. dp_audio_enable(audio, false);
  407. mutex_unlock(&audio->ops_lock);
  408. atomic_set(&audio->acked, 1);
  409. complete_all(&audio->hpd_comp);
  410. pr_debug("audio engine disabled\n");
  411. }
  412. static int dp_audio_ack_done(struct platform_device *pdev, u32 ack)
  413. {
  414. int rc = 0, ack_hpd;
  415. struct dp_audio_private *audio;
  416. audio = dp_audio_get_data(pdev);
  417. if (IS_ERR(audio)) {
  418. rc = PTR_ERR(audio);
  419. goto end;
  420. }
  421. if (ack & AUDIO_ACK_SET_ENABLE) {
  422. audio->ack_enabled = ack & AUDIO_ACK_ENABLE ?
  423. true : false;
  424. pr_debug("audio ack feature %s\n",
  425. audio->ack_enabled ? "enabled" : "disabled");
  426. goto end;
  427. }
  428. if (!audio->ack_enabled)
  429. goto end;
  430. ack_hpd = ack & AUDIO_ACK_CONNECT;
  431. pr_debug("acknowledging audio (%d)\n", ack_hpd);
  432. if (!audio->engine_on) {
  433. atomic_set(&audio->acked, 1);
  434. complete_all(&audio->hpd_comp);
  435. }
  436. end:
  437. return rc;
  438. }
  439. static int dp_audio_codec_ready(struct platform_device *pdev)
  440. {
  441. int rc = 0;
  442. struct dp_audio_private *audio;
  443. audio = dp_audio_get_data(pdev);
  444. if (IS_ERR(audio)) {
  445. pr_err("invalid input\n");
  446. rc = PTR_ERR(audio);
  447. goto end;
  448. }
  449. queue_delayed_work(audio->notify_workqueue,
  450. &audio->notify_delayed_work, HZ/4);
  451. end:
  452. return rc;
  453. }
  454. static int dp_audio_register_ext_disp(struct dp_audio_private *audio)
  455. {
  456. int rc = 0;
  457. struct device_node *pd = NULL;
  458. const char *phandle = "qcom,ext-disp";
  459. struct msm_ext_disp_init_data *ext;
  460. struct msm_ext_disp_audio_codec_ops *ops;
  461. ext = &audio->ext_audio_data;
  462. ops = &ext->codec_ops;
  463. ext->codec.type = EXT_DISPLAY_TYPE_DP;
  464. ext->codec.ctrl_id = 0;
  465. ext->codec.stream_id = audio->panel->stream_id;
  466. ext->pdev = audio->pdev;
  467. ext->intf_data = &audio->dp_audio;
  468. ops->audio_info_setup = dp_audio_info_setup;
  469. ops->get_audio_edid_blk = dp_audio_get_edid_blk;
  470. ops->cable_status = dp_audio_get_cable_status;
  471. ops->get_intf_id = dp_audio_get_intf_id;
  472. ops->teardown_done = dp_audio_teardown_done;
  473. ops->acknowledge = dp_audio_ack_done;
  474. ops->ready = dp_audio_codec_ready;
  475. if (!audio->pdev->dev.of_node) {
  476. pr_err("cannot find audio dev.of_node\n");
  477. rc = -ENODEV;
  478. goto end;
  479. }
  480. pd = of_parse_phandle(audio->pdev->dev.of_node, phandle, 0);
  481. if (!pd) {
  482. pr_err("cannot parse %s handle\n", phandle);
  483. rc = -ENODEV;
  484. goto end;
  485. }
  486. audio->ext_pdev = of_find_device_by_node(pd);
  487. if (!audio->ext_pdev) {
  488. pr_err("cannot find %s pdev\n", phandle);
  489. rc = -ENODEV;
  490. goto end;
  491. }
  492. #if defined(CONFIG_MSM_EXT_DISPLAY)
  493. rc = msm_ext_disp_register_intf(audio->ext_pdev, ext);
  494. if (rc)
  495. pr_err("failed to register disp\n");
  496. #endif
  497. end:
  498. if (pd)
  499. of_node_put(pd);
  500. return rc;
  501. }
  502. static int dp_audio_deregister_ext_disp(struct dp_audio_private *audio)
  503. {
  504. int rc = 0;
  505. struct device_node *pd = NULL;
  506. const char *phandle = "qcom,ext-disp";
  507. struct msm_ext_disp_init_data *ext;
  508. ext = &audio->ext_audio_data;
  509. if (!audio->pdev->dev.of_node) {
  510. pr_err("cannot find audio dev.of_node\n");
  511. rc = -ENODEV;
  512. goto end;
  513. }
  514. pd = of_parse_phandle(audio->pdev->dev.of_node, phandle, 0);
  515. if (!pd) {
  516. pr_err("cannot parse %s handle\n", phandle);
  517. rc = -ENODEV;
  518. goto end;
  519. }
  520. audio->ext_pdev = of_find_device_by_node(pd);
  521. if (!audio->ext_pdev) {
  522. pr_err("cannot find %s pdev\n", phandle);
  523. rc = -ENODEV;
  524. goto end;
  525. }
  526. #if defined(CONFIG_MSM_EXT_DISPLAY)
  527. rc = msm_ext_disp_deregister_intf(audio->ext_pdev, ext);
  528. if (rc)
  529. pr_err("failed to deregister disp\n");
  530. #endif
  531. end:
  532. return rc;
  533. }
  534. static int dp_audio_notify(struct dp_audio_private *audio, u32 state)
  535. {
  536. int rc = 0;
  537. struct msm_ext_disp_init_data *ext = &audio->ext_audio_data;
  538. atomic_set(&audio->acked, 0);
  539. if (!ext->intf_ops.audio_notify) {
  540. pr_err("audio notify not defined\n");
  541. goto end;
  542. }
  543. reinit_completion(&audio->hpd_comp);
  544. rc = ext->intf_ops.audio_notify(audio->ext_pdev,
  545. &ext->codec, state);
  546. if (rc)
  547. goto end;
  548. if (atomic_read(&audio->acked))
  549. goto end;
  550. if (state == EXT_DISPLAY_CABLE_CONNECT)
  551. goto end;
  552. rc = wait_for_completion_timeout(&audio->hpd_comp, HZ * 4);
  553. if (!rc) {
  554. pr_err("timeout. state=%d err=%d\n", state, rc);
  555. rc = -ETIMEDOUT;
  556. goto end;
  557. }
  558. pr_debug("success\n");
  559. end:
  560. return rc;
  561. }
  562. static int dp_audio_config(struct dp_audio_private *audio, u32 state)
  563. {
  564. int rc = 0;
  565. struct msm_ext_disp_init_data *ext = &audio->ext_audio_data;
  566. if (!ext || !ext->intf_ops.audio_config) {
  567. pr_err("audio_config not defined\n");
  568. goto end;
  569. }
  570. /*
  571. * DP Audio sets default STREAM_0 only, other streams are
  572. * set by audio driver based on the hardware/software support.
  573. */
  574. if (audio->panel->stream_id == DP_STREAM_0) {
  575. rc = ext->intf_ops.audio_config(audio->ext_pdev,
  576. &ext->codec, state);
  577. if (rc)
  578. pr_err("failed to config audio, err=%d\n", rc);
  579. }
  580. end:
  581. return rc;
  582. }
  583. static int dp_audio_on(struct dp_audio *dp_audio)
  584. {
  585. int rc = 0;
  586. struct dp_audio_private *audio;
  587. struct msm_ext_disp_init_data *ext;
  588. if (!dp_audio) {
  589. pr_err("invalid input\n");
  590. return -EINVAL;
  591. }
  592. audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
  593. if (IS_ERR(audio)) {
  594. pr_err("invalid input\n");
  595. return -EINVAL;
  596. }
  597. dp_audio_register_ext_disp(audio);
  598. ext = &audio->ext_audio_data;
  599. atomic_set(&audio->session_on, 1);
  600. rc = dp_audio_config(audio, EXT_DISPLAY_CABLE_CONNECT);
  601. if (rc)
  602. goto end;
  603. rc = dp_audio_notify(audio, EXT_DISPLAY_CABLE_CONNECT);
  604. if (rc)
  605. goto end;
  606. pr_debug("success\n");
  607. end:
  608. return rc;
  609. }
  610. static int dp_audio_off(struct dp_audio *dp_audio)
  611. {
  612. int rc = 0;
  613. struct dp_audio_private *audio;
  614. struct msm_ext_disp_init_data *ext;
  615. bool work_pending = false;
  616. if (!dp_audio) {
  617. pr_err("invalid input\n");
  618. return -EINVAL;
  619. }
  620. audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
  621. ext = &audio->ext_audio_data;
  622. work_pending = cancel_delayed_work_sync(&audio->notify_delayed_work);
  623. if (work_pending)
  624. pr_debug("pending notification work completed\n");
  625. rc = dp_audio_notify(audio, EXT_DISPLAY_CABLE_DISCONNECT);
  626. if (rc)
  627. goto end;
  628. pr_debug("success\n");
  629. end:
  630. dp_audio_config(audio, EXT_DISPLAY_CABLE_DISCONNECT);
  631. atomic_set(&audio->session_on, 0);
  632. audio->engine_on = false;
  633. dp_audio_deregister_ext_disp(audio);
  634. return rc;
  635. }
  636. static void dp_audio_notify_work_fn(struct work_struct *work)
  637. {
  638. struct dp_audio_private *audio;
  639. struct delayed_work *dw = to_delayed_work(work);
  640. audio = container_of(dw, struct dp_audio_private, notify_delayed_work);
  641. dp_audio_notify(audio, EXT_DISPLAY_CABLE_CONNECT);
  642. }
  643. static int dp_audio_create_notify_workqueue(struct dp_audio_private *audio)
  644. {
  645. audio->notify_workqueue = create_workqueue("sdm_dp_audio_notify");
  646. if (IS_ERR_OR_NULL(audio->notify_workqueue)) {
  647. pr_err("Error creating notify_workqueue\n");
  648. return -EPERM;
  649. }
  650. INIT_DELAYED_WORK(&audio->notify_delayed_work, dp_audio_notify_work_fn);
  651. return 0;
  652. }
  653. static void dp_audio_destroy_notify_workqueue(struct dp_audio_private *audio)
  654. {
  655. if (audio->notify_workqueue)
  656. destroy_workqueue(audio->notify_workqueue);
  657. }
  658. struct dp_audio *dp_audio_get(struct platform_device *pdev,
  659. struct dp_panel *panel,
  660. struct dp_catalog_audio *catalog)
  661. {
  662. int rc = 0;
  663. struct dp_audio_private *audio;
  664. struct dp_audio *dp_audio;
  665. if (!pdev || !panel || !catalog) {
  666. pr_err("invalid input\n");
  667. rc = -EINVAL;
  668. goto error;
  669. }
  670. audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
  671. if (!audio) {
  672. rc = -ENOMEM;
  673. goto error;
  674. }
  675. rc = dp_audio_create_notify_workqueue(audio);
  676. if (rc)
  677. goto error_notify_workqueue;
  678. init_completion(&audio->hpd_comp);
  679. audio->pdev = pdev;
  680. audio->panel = panel;
  681. audio->catalog = catalog;
  682. atomic_set(&audio->acked, 0);
  683. dp_audio = &audio->dp_audio;
  684. mutex_init(&audio->ops_lock);
  685. dp_audio->on = dp_audio_on;
  686. dp_audio->off = dp_audio_off;
  687. catalog->init(catalog);
  688. return dp_audio;
  689. error_notify_workqueue:
  690. devm_kfree(&pdev->dev, audio);
  691. error:
  692. return ERR_PTR(rc);
  693. }
  694. void dp_audio_put(struct dp_audio *dp_audio)
  695. {
  696. struct dp_audio_private *audio;
  697. if (!dp_audio)
  698. return;
  699. audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
  700. mutex_destroy(&audio->ops_lock);
  701. dp_audio_destroy_notify_workqueue(audio);
  702. devm_kfree(&audio->pdev->dev, audio);
  703. }