oxfw-stream.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /*
  2. * oxfw_stream.c - a part of driver for OXFW970/971 based devices
  3. *
  4. * Copyright (c) 2014 Takashi Sakamoto
  5. *
  6. * Licensed under the terms of the GNU General Public License, version 2.
  7. */
  8. #include "oxfw.h"
  9. #include <linux/delay.h>
  10. #define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
  11. #define CALLBACK_TIMEOUT 200
  12. /*
  13. * According to datasheet of Oxford Semiconductor:
  14. * OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
  15. * OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
  16. */
  17. static const unsigned int oxfw_rate_table[] = {
  18. [0] = 32000,
  19. [1] = 44100,
  20. [2] = 48000,
  21. [3] = 88200,
  22. [4] = 96000,
  23. [5] = 192000,
  24. };
  25. /*
  26. * See Table 5.7 – Sampling frequency for Multi-bit Audio
  27. * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
  28. */
  29. static const unsigned int avc_stream_rate_table[] = {
  30. [0] = 0x02,
  31. [1] = 0x03,
  32. [2] = 0x04,
  33. [3] = 0x0a,
  34. [4] = 0x05,
  35. [5] = 0x07,
  36. };
  37. static int set_rate(struct snd_oxfw *oxfw, unsigned int rate)
  38. {
  39. int err;
  40. err = avc_general_set_sig_fmt(oxfw->unit, rate,
  41. AVC_GENERAL_PLUG_DIR_IN, 0);
  42. if (err < 0)
  43. goto end;
  44. if (oxfw->has_output)
  45. err = avc_general_set_sig_fmt(oxfw->unit, rate,
  46. AVC_GENERAL_PLUG_DIR_OUT, 0);
  47. end:
  48. return err;
  49. }
  50. static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
  51. unsigned int rate, unsigned int pcm_channels)
  52. {
  53. u8 **formats;
  54. struct snd_oxfw_stream_formation formation;
  55. enum avc_general_plug_dir dir;
  56. unsigned int len;
  57. int i, err;
  58. if (s == &oxfw->tx_stream) {
  59. formats = oxfw->tx_stream_formats;
  60. dir = AVC_GENERAL_PLUG_DIR_OUT;
  61. } else {
  62. formats = oxfw->rx_stream_formats;
  63. dir = AVC_GENERAL_PLUG_DIR_IN;
  64. }
  65. /* Seek stream format for requirements. */
  66. for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
  67. err = snd_oxfw_stream_parse_format(formats[i], &formation);
  68. if (err < 0)
  69. return err;
  70. if ((formation.rate == rate) && (formation.pcm == pcm_channels))
  71. break;
  72. }
  73. if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
  74. return -EINVAL;
  75. /* If assumed, just change rate. */
  76. if (oxfw->assumed)
  77. return set_rate(oxfw, rate);
  78. /* Calculate format length. */
  79. len = 5 + formats[i][4] * 2;
  80. err = avc_stream_set_format(oxfw->unit, dir, 0, formats[i], len);
  81. if (err < 0)
  82. return err;
  83. /* Some requests just after changing format causes freezing. */
  84. msleep(100);
  85. return 0;
  86. }
  87. static void stop_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
  88. {
  89. amdtp_stream_pcm_abort(stream);
  90. amdtp_stream_stop(stream);
  91. if (stream == &oxfw->tx_stream)
  92. cmp_connection_break(&oxfw->out_conn);
  93. else
  94. cmp_connection_break(&oxfw->in_conn);
  95. }
  96. static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream,
  97. unsigned int rate, unsigned int pcm_channels)
  98. {
  99. u8 **formats;
  100. struct cmp_connection *conn;
  101. struct snd_oxfw_stream_formation formation;
  102. unsigned int i, midi_ports;
  103. int err;
  104. if (stream == &oxfw->rx_stream) {
  105. formats = oxfw->rx_stream_formats;
  106. conn = &oxfw->in_conn;
  107. } else {
  108. formats = oxfw->tx_stream_formats;
  109. conn = &oxfw->out_conn;
  110. }
  111. /* Get stream format */
  112. for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
  113. if (formats[i] == NULL)
  114. break;
  115. err = snd_oxfw_stream_parse_format(formats[i], &formation);
  116. if (err < 0)
  117. goto end;
  118. if (rate != formation.rate)
  119. continue;
  120. if (pcm_channels == 0 || pcm_channels == formation.pcm)
  121. break;
  122. }
  123. if (i == SND_OXFW_STREAM_FORMAT_ENTRIES) {
  124. err = -EINVAL;
  125. goto end;
  126. }
  127. pcm_channels = formation.pcm;
  128. midi_ports = formation.midi * 8;
  129. /* The stream should have one pcm channels at least */
  130. if (pcm_channels == 0) {
  131. err = -EINVAL;
  132. goto end;
  133. }
  134. err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports,
  135. false);
  136. if (err < 0)
  137. goto end;
  138. err = cmp_connection_establish(conn,
  139. amdtp_stream_get_max_payload(stream));
  140. if (err < 0)
  141. goto end;
  142. err = amdtp_stream_start(stream,
  143. conn->resources.channel,
  144. conn->speed);
  145. if (err < 0) {
  146. cmp_connection_break(conn);
  147. goto end;
  148. }
  149. /* Wait first packet */
  150. if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
  151. stop_stream(oxfw, stream);
  152. err = -ETIMEDOUT;
  153. }
  154. end:
  155. return err;
  156. }
  157. static int check_connection_used_by_others(struct snd_oxfw *oxfw,
  158. struct amdtp_stream *stream)
  159. {
  160. struct cmp_connection *conn;
  161. bool used;
  162. int err;
  163. if (stream == &oxfw->tx_stream)
  164. conn = &oxfw->out_conn;
  165. else
  166. conn = &oxfw->in_conn;
  167. err = cmp_connection_check_used(conn, &used);
  168. if ((err >= 0) && used && !amdtp_stream_running(stream)) {
  169. dev_err(&oxfw->unit->device,
  170. "Connection established by others: %cPCR[%d]\n",
  171. (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
  172. conn->pcr_index);
  173. err = -EBUSY;
  174. }
  175. return err;
  176. }
  177. int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw,
  178. struct amdtp_stream *stream)
  179. {
  180. struct cmp_connection *conn;
  181. enum cmp_direction c_dir;
  182. enum amdtp_stream_direction s_dir;
  183. int err;
  184. if (stream == &oxfw->tx_stream) {
  185. conn = &oxfw->out_conn;
  186. c_dir = CMP_OUTPUT;
  187. s_dir = AMDTP_IN_STREAM;
  188. } else {
  189. conn = &oxfw->in_conn;
  190. c_dir = CMP_INPUT;
  191. s_dir = AMDTP_OUT_STREAM;
  192. }
  193. err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
  194. if (err < 0)
  195. goto end;
  196. err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
  197. if (err < 0) {
  198. amdtp_stream_destroy(stream);
  199. cmp_connection_destroy(conn);
  200. goto end;
  201. }
  202. /*
  203. * OXFW starts to transmit packets with non-zero dbc.
  204. * OXFW postpone transferring packets till handling any asynchronous
  205. * packets. As a result, next isochronous packet includes more data
  206. * blocks than IEC 61883-6 defines.
  207. */
  208. if (stream == &oxfw->tx_stream) {
  209. oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
  210. if (oxfw->wrong_dbs)
  211. oxfw->tx_stream.flags |= CIP_WRONG_DBS;
  212. }
  213. end:
  214. return err;
  215. }
  216. int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw,
  217. struct amdtp_stream *stream,
  218. unsigned int rate, unsigned int pcm_channels)
  219. {
  220. struct amdtp_stream *opposite;
  221. struct snd_oxfw_stream_formation formation;
  222. enum avc_general_plug_dir dir;
  223. unsigned int substreams, opposite_substreams;
  224. int err = 0;
  225. if (stream == &oxfw->tx_stream) {
  226. substreams = oxfw->capture_substreams;
  227. opposite = &oxfw->rx_stream;
  228. opposite_substreams = oxfw->playback_substreams;
  229. dir = AVC_GENERAL_PLUG_DIR_OUT;
  230. } else {
  231. substreams = oxfw->playback_substreams;
  232. opposite_substreams = oxfw->capture_substreams;
  233. if (oxfw->has_output)
  234. opposite = &oxfw->rx_stream;
  235. else
  236. opposite = NULL;
  237. dir = AVC_GENERAL_PLUG_DIR_IN;
  238. }
  239. if (substreams == 0)
  240. goto end;
  241. /*
  242. * Considering JACK/FFADO streaming:
  243. * TODO: This can be removed hwdep functionality becomes popular.
  244. */
  245. err = check_connection_used_by_others(oxfw, stream);
  246. if (err < 0)
  247. goto end;
  248. /* packet queueing error */
  249. if (amdtp_streaming_error(stream))
  250. stop_stream(oxfw, stream);
  251. err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
  252. if (err < 0)
  253. goto end;
  254. if (rate == 0)
  255. rate = formation.rate;
  256. if (pcm_channels == 0)
  257. pcm_channels = formation.pcm;
  258. if ((formation.rate != rate) || (formation.pcm != pcm_channels)) {
  259. if (opposite != NULL) {
  260. err = check_connection_used_by_others(oxfw, opposite);
  261. if (err < 0)
  262. goto end;
  263. stop_stream(oxfw, opposite);
  264. }
  265. stop_stream(oxfw, stream);
  266. err = set_stream_format(oxfw, stream, rate, pcm_channels);
  267. if (err < 0) {
  268. dev_err(&oxfw->unit->device,
  269. "fail to set stream format: %d\n", err);
  270. goto end;
  271. }
  272. /* Start opposite stream if needed. */
  273. if (opposite && !amdtp_stream_running(opposite) &&
  274. (opposite_substreams > 0)) {
  275. err = start_stream(oxfw, opposite, rate, 0);
  276. if (err < 0) {
  277. dev_err(&oxfw->unit->device,
  278. "fail to restart stream: %d\n", err);
  279. goto end;
  280. }
  281. }
  282. }
  283. /* Start requested stream. */
  284. if (!amdtp_stream_running(stream)) {
  285. err = start_stream(oxfw, stream, rate, pcm_channels);
  286. if (err < 0)
  287. dev_err(&oxfw->unit->device,
  288. "fail to start stream: %d\n", err);
  289. }
  290. end:
  291. return err;
  292. }
  293. void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw,
  294. struct amdtp_stream *stream)
  295. {
  296. if (((stream == &oxfw->tx_stream) && (oxfw->capture_substreams > 0)) ||
  297. ((stream == &oxfw->rx_stream) && (oxfw->playback_substreams > 0)))
  298. return;
  299. stop_stream(oxfw, stream);
  300. }
  301. /*
  302. * This function should be called before starting the stream or after stopping
  303. * the streams.
  304. */
  305. void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw,
  306. struct amdtp_stream *stream)
  307. {
  308. struct cmp_connection *conn;
  309. if (stream == &oxfw->tx_stream)
  310. conn = &oxfw->out_conn;
  311. else
  312. conn = &oxfw->in_conn;
  313. amdtp_stream_destroy(stream);
  314. cmp_connection_destroy(conn);
  315. }
  316. void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw,
  317. struct amdtp_stream *stream)
  318. {
  319. struct cmp_connection *conn;
  320. if (stream == &oxfw->tx_stream)
  321. conn = &oxfw->out_conn;
  322. else
  323. conn = &oxfw->in_conn;
  324. if (cmp_connection_update(conn) < 0)
  325. stop_stream(oxfw, stream);
  326. else
  327. amdtp_stream_update(stream);
  328. }
  329. int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
  330. enum avc_general_plug_dir dir,
  331. struct snd_oxfw_stream_formation *formation)
  332. {
  333. u8 *format;
  334. unsigned int len;
  335. int err;
  336. len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
  337. format = kmalloc(len, GFP_KERNEL);
  338. if (format == NULL)
  339. return -ENOMEM;
  340. err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
  341. if (err < 0)
  342. goto end;
  343. if (len < 3) {
  344. err = -EIO;
  345. goto end;
  346. }
  347. err = snd_oxfw_stream_parse_format(format, formation);
  348. end:
  349. kfree(format);
  350. return err;
  351. }
  352. /*
  353. * See Table 6.16 - AM824 Stream Format
  354. * Figure 6.19 - format_information field for AM824 Compound
  355. * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
  356. * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
  357. */
  358. int snd_oxfw_stream_parse_format(u8 *format,
  359. struct snd_oxfw_stream_formation *formation)
  360. {
  361. unsigned int i, e, channels, type;
  362. memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
  363. /*
  364. * this module can support a hierarchy combination that:
  365. * Root: Audio and Music (0x90)
  366. * Level 1: AM824 Compound (0x40)
  367. */
  368. if ((format[0] != 0x90) || (format[1] != 0x40))
  369. return -ENOSYS;
  370. /* check the sampling rate */
  371. for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
  372. if (format[2] == avc_stream_rate_table[i])
  373. break;
  374. }
  375. if (i == ARRAY_SIZE(avc_stream_rate_table))
  376. return -ENOSYS;
  377. formation->rate = oxfw_rate_table[i];
  378. for (e = 0; e < format[4]; e++) {
  379. channels = format[5 + e * 2];
  380. type = format[6 + e * 2];
  381. switch (type) {
  382. /* IEC 60958 Conformant, currently handled as MBLA */
  383. case 0x00:
  384. /* Multi Bit Linear Audio (Raw) */
  385. case 0x06:
  386. formation->pcm += channels;
  387. break;
  388. /* MIDI Conformant */
  389. case 0x0d:
  390. formation->midi = channels;
  391. break;
  392. /* IEC 61937-3 to 7 */
  393. case 0x01:
  394. case 0x02:
  395. case 0x03:
  396. case 0x04:
  397. case 0x05:
  398. /* Multi Bit Linear Audio */
  399. case 0x07: /* DVD-Audio */
  400. case 0x0c: /* High Precision */
  401. /* One Bit Audio */
  402. case 0x08: /* (Plain) Raw */
  403. case 0x09: /* (Plain) SACD */
  404. case 0x0a: /* (Encoded) Raw */
  405. case 0x0b: /* (Encoded) SACD */
  406. /* SMPTE Time-Code conformant */
  407. case 0x0e:
  408. /* Sample Count */
  409. case 0x0f:
  410. /* Anciliary Data */
  411. case 0x10:
  412. /* Synchronization Stream (Stereo Raw audio) */
  413. case 0x40:
  414. /* Don't care */
  415. case 0xff:
  416. default:
  417. return -ENOSYS; /* not supported */
  418. }
  419. }
  420. if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
  421. formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
  422. return -ENOSYS;
  423. return 0;
  424. }
  425. static int
  426. assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
  427. unsigned int pid, u8 *buf, unsigned int *len,
  428. u8 **formats)
  429. {
  430. struct snd_oxfw_stream_formation formation;
  431. unsigned int i, eid;
  432. int err;
  433. /* get format at current sampling rate */
  434. err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
  435. if (err < 0) {
  436. dev_err(&oxfw->unit->device,
  437. "fail to get current stream format for isoc %s plug %d:%d\n",
  438. (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
  439. pid, err);
  440. goto end;
  441. }
  442. /* parse and set stream format */
  443. eid = 0;
  444. err = snd_oxfw_stream_parse_format(buf, &formation);
  445. if (err < 0)
  446. goto end;
  447. formats[eid] = kmemdup(buf, *len, GFP_KERNEL);
  448. if (formats[eid] == NULL) {
  449. err = -ENOMEM;
  450. goto end;
  451. }
  452. /* apply the format for each available sampling rate */
  453. for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
  454. if (formation.rate == oxfw_rate_table[i])
  455. continue;
  456. err = avc_general_inquiry_sig_fmt(oxfw->unit,
  457. oxfw_rate_table[i],
  458. dir, pid);
  459. if (err < 0)
  460. continue;
  461. eid++;
  462. formats[eid] = kmemdup(buf, *len, GFP_KERNEL);
  463. if (formats[eid] == NULL) {
  464. err = -ENOMEM;
  465. goto end;
  466. }
  467. formats[eid][2] = avc_stream_rate_table[i];
  468. }
  469. err = 0;
  470. oxfw->assumed = true;
  471. end:
  472. return err;
  473. }
  474. static int fill_stream_formats(struct snd_oxfw *oxfw,
  475. enum avc_general_plug_dir dir,
  476. unsigned short pid)
  477. {
  478. u8 *buf, **formats;
  479. unsigned int len, eid = 0;
  480. struct snd_oxfw_stream_formation dummy;
  481. int err;
  482. buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
  483. if (buf == NULL)
  484. return -ENOMEM;
  485. if (dir == AVC_GENERAL_PLUG_DIR_OUT)
  486. formats = oxfw->tx_stream_formats;
  487. else
  488. formats = oxfw->rx_stream_formats;
  489. /* get first entry */
  490. len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
  491. err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
  492. if (err == -ENOSYS) {
  493. /* LIST subfunction is not implemented */
  494. len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
  495. err = assume_stream_formats(oxfw, dir, pid, buf, &len,
  496. formats);
  497. goto end;
  498. } else if (err < 0) {
  499. dev_err(&oxfw->unit->device,
  500. "fail to get stream format %d for isoc %s plug %d:%d\n",
  501. eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
  502. pid, err);
  503. goto end;
  504. }
  505. /* LIST subfunction is implemented */
  506. while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
  507. /* The format is too short. */
  508. if (len < 3) {
  509. err = -EIO;
  510. break;
  511. }
  512. /* parse and set stream format */
  513. err = snd_oxfw_stream_parse_format(buf, &dummy);
  514. if (err < 0)
  515. break;
  516. formats[eid] = kmemdup(buf, len, GFP_KERNEL);
  517. if (formats[eid] == NULL) {
  518. err = -ENOMEM;
  519. break;
  520. }
  521. /* get next entry */
  522. len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
  523. err = avc_stream_get_format_list(oxfw->unit, dir, 0,
  524. buf, &len, ++eid);
  525. /* No entries remained. */
  526. if (err == -EINVAL) {
  527. err = 0;
  528. break;
  529. } else if (err < 0) {
  530. dev_err(&oxfw->unit->device,
  531. "fail to get stream format %d for isoc %s plug %d:%d\n",
  532. eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
  533. "out",
  534. pid, err);
  535. break;
  536. }
  537. }
  538. end:
  539. kfree(buf);
  540. return err;
  541. }
  542. int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
  543. {
  544. u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
  545. struct snd_oxfw_stream_formation formation;
  546. u8 *format;
  547. unsigned int i;
  548. int err;
  549. /* the number of plugs for isoc in/out, ext in/out */
  550. err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
  551. if (err < 0) {
  552. dev_err(&oxfw->unit->device,
  553. "fail to get info for isoc/external in/out plugs: %d\n",
  554. err);
  555. goto end;
  556. } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
  557. err = -ENOSYS;
  558. goto end;
  559. }
  560. /* use oPCR[0] if exists */
  561. if (plugs[1] > 0) {
  562. err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
  563. if (err < 0)
  564. goto end;
  565. for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
  566. format = oxfw->tx_stream_formats[i];
  567. if (format == NULL)
  568. continue;
  569. err = snd_oxfw_stream_parse_format(format, &formation);
  570. if (err < 0)
  571. continue;
  572. /* Add one MIDI port. */
  573. if (formation.midi > 0)
  574. oxfw->midi_input_ports = 1;
  575. }
  576. oxfw->has_output = true;
  577. }
  578. /* use iPCR[0] if exists */
  579. if (plugs[0] > 0) {
  580. err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
  581. if (err < 0)
  582. goto end;
  583. for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
  584. format = oxfw->rx_stream_formats[i];
  585. if (format == NULL)
  586. continue;
  587. err = snd_oxfw_stream_parse_format(format, &formation);
  588. if (err < 0)
  589. continue;
  590. /* Add one MIDI port. */
  591. if (formation.midi > 0)
  592. oxfw->midi_output_ports = 1;
  593. }
  594. }
  595. end:
  596. return err;
  597. }
  598. void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
  599. {
  600. oxfw->dev_lock_changed = true;
  601. wake_up(&oxfw->hwdep_wait);
  602. }
  603. int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
  604. {
  605. int err;
  606. spin_lock_irq(&oxfw->lock);
  607. /* user land lock this */
  608. if (oxfw->dev_lock_count < 0) {
  609. err = -EBUSY;
  610. goto end;
  611. }
  612. /* this is the first time */
  613. if (oxfw->dev_lock_count++ == 0)
  614. snd_oxfw_stream_lock_changed(oxfw);
  615. err = 0;
  616. end:
  617. spin_unlock_irq(&oxfw->lock);
  618. return err;
  619. }
  620. void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
  621. {
  622. spin_lock_irq(&oxfw->lock);
  623. if (WARN_ON(oxfw->dev_lock_count <= 0))
  624. goto end;
  625. if (--oxfw->dev_lock_count == 0)
  626. snd_oxfw_stream_lock_changed(oxfw);
  627. end:
  628. spin_unlock_irq(&oxfw->lock);
  629. }