digi00x-stream.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /*
  2. * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family
  3. *
  4. * Copyright (c) 2014-2015 Takashi Sakamoto
  5. *
  6. * Licensed under the terms of the GNU General Public License, version 2.
  7. */
  8. #include "digi00x.h"
  9. #define CALLBACK_TIMEOUT 500
  10. const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT] = {
  11. [SND_DG00X_RATE_44100] = 44100,
  12. [SND_DG00X_RATE_48000] = 48000,
  13. [SND_DG00X_RATE_88200] = 88200,
  14. [SND_DG00X_RATE_96000] = 96000,
  15. };
  16. /* Multi Bit Linear Audio data channels for each sampling transfer frequency. */
  17. const unsigned int
  18. snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT] = {
  19. /* Analog/ADAT/SPDIF */
  20. [SND_DG00X_RATE_44100] = (8 + 8 + 2),
  21. [SND_DG00X_RATE_48000] = (8 + 8 + 2),
  22. /* Analog/SPDIF */
  23. [SND_DG00X_RATE_88200] = (8 + 2),
  24. [SND_DG00X_RATE_96000] = (8 + 2),
  25. };
  26. int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, unsigned int *rate)
  27. {
  28. u32 data;
  29. __be32 reg;
  30. int err;
  31. err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
  32. DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
  33. &reg, sizeof(reg), 0);
  34. if (err < 0)
  35. return err;
  36. data = be32_to_cpu(reg) & 0x0f;
  37. if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
  38. *rate = snd_dg00x_stream_rates[data];
  39. else
  40. err = -EIO;
  41. return err;
  42. }
  43. int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate)
  44. {
  45. __be32 reg;
  46. unsigned int i;
  47. for (i = 0; i < ARRAY_SIZE(snd_dg00x_stream_rates); i++) {
  48. if (rate == snd_dg00x_stream_rates[i])
  49. break;
  50. }
  51. if (i == ARRAY_SIZE(snd_dg00x_stream_rates))
  52. return -EINVAL;
  53. reg = cpu_to_be32(i);
  54. return snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
  55. DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
  56. &reg, sizeof(reg), 0);
  57. }
  58. int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x,
  59. enum snd_dg00x_clock *clock)
  60. {
  61. __be32 reg;
  62. int err;
  63. err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
  64. DG00X_ADDR_BASE + DG00X_OFFSET_CLOCK_SOURCE,
  65. &reg, sizeof(reg), 0);
  66. if (err < 0)
  67. return err;
  68. *clock = be32_to_cpu(reg) & 0x0f;
  69. if (*clock >= SND_DG00X_CLOCK_COUNT)
  70. err = -EIO;
  71. return err;
  72. }
  73. int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, bool *detect)
  74. {
  75. __be32 reg;
  76. int err;
  77. err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
  78. DG00X_ADDR_BASE + DG00X_OFFSET_DETECT_EXTERNAL,
  79. &reg, sizeof(reg), 0);
  80. if (err >= 0)
  81. *detect = be32_to_cpu(reg) > 0;
  82. return err;
  83. }
  84. int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x,
  85. unsigned int *rate)
  86. {
  87. u32 data;
  88. __be32 reg;
  89. int err;
  90. err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
  91. DG00X_ADDR_BASE + DG00X_OFFSET_EXTERNAL_RATE,
  92. &reg, sizeof(reg), 0);
  93. if (err < 0)
  94. return err;
  95. data = be32_to_cpu(reg) & 0x0f;
  96. if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
  97. *rate = snd_dg00x_stream_rates[data];
  98. /* This means desync. */
  99. else
  100. err = -EBUSY;
  101. return err;
  102. }
  103. static void finish_session(struct snd_dg00x *dg00x)
  104. {
  105. __be32 data = cpu_to_be32(0x00000003);
  106. snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
  107. DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_SET,
  108. &data, sizeof(data), 0);
  109. }
  110. static int begin_session(struct snd_dg00x *dg00x)
  111. {
  112. __be32 data;
  113. u32 curr;
  114. int err;
  115. err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
  116. DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_STATE,
  117. &data, sizeof(data), 0);
  118. if (err < 0)
  119. goto error;
  120. curr = be32_to_cpu(data);
  121. if (curr == 0)
  122. curr = 2;
  123. curr--;
  124. while (curr > 0) {
  125. data = cpu_to_be32(curr);
  126. err = snd_fw_transaction(dg00x->unit,
  127. TCODE_WRITE_QUADLET_REQUEST,
  128. DG00X_ADDR_BASE +
  129. DG00X_OFFSET_STREAMING_SET,
  130. &data, sizeof(data), 0);
  131. if (err < 0)
  132. goto error;
  133. msleep(20);
  134. curr--;
  135. }
  136. return 0;
  137. error:
  138. finish_session(dg00x);
  139. return err;
  140. }
  141. static void release_resources(struct snd_dg00x *dg00x)
  142. {
  143. __be32 data = 0;
  144. /* Unregister isochronous channels for both direction. */
  145. snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
  146. DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
  147. &data, sizeof(data), 0);
  148. /* Release isochronous resources. */
  149. fw_iso_resources_free(&dg00x->tx_resources);
  150. fw_iso_resources_free(&dg00x->rx_resources);
  151. }
  152. static int keep_resources(struct snd_dg00x *dg00x, unsigned int rate)
  153. {
  154. unsigned int i;
  155. __be32 data;
  156. int err;
  157. /* Check sampling rate. */
  158. for (i = 0; i < SND_DG00X_RATE_COUNT; i++) {
  159. if (snd_dg00x_stream_rates[i] == rate)
  160. break;
  161. }
  162. if (i == SND_DG00X_RATE_COUNT)
  163. return -EINVAL;
  164. /* Keep resources for out-stream. */
  165. err = amdtp_dot_set_parameters(&dg00x->rx_stream, rate,
  166. snd_dg00x_stream_pcm_channels[i]);
  167. if (err < 0)
  168. return err;
  169. err = fw_iso_resources_allocate(&dg00x->rx_resources,
  170. amdtp_stream_get_max_payload(&dg00x->rx_stream),
  171. fw_parent_device(dg00x->unit)->max_speed);
  172. if (err < 0)
  173. return err;
  174. /* Keep resources for in-stream. */
  175. err = amdtp_dot_set_parameters(&dg00x->tx_stream, rate,
  176. snd_dg00x_stream_pcm_channels[i]);
  177. if (err < 0)
  178. return err;
  179. err = fw_iso_resources_allocate(&dg00x->tx_resources,
  180. amdtp_stream_get_max_payload(&dg00x->tx_stream),
  181. fw_parent_device(dg00x->unit)->max_speed);
  182. if (err < 0)
  183. goto error;
  184. /* Register isochronous channels for both direction. */
  185. data = cpu_to_be32((dg00x->tx_resources.channel << 16) |
  186. dg00x->rx_resources.channel);
  187. err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
  188. DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
  189. &data, sizeof(data), 0);
  190. if (err < 0)
  191. goto error;
  192. return 0;
  193. error:
  194. release_resources(dg00x);
  195. return err;
  196. }
  197. int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x)
  198. {
  199. int err;
  200. /* For out-stream. */
  201. err = fw_iso_resources_init(&dg00x->rx_resources, dg00x->unit);
  202. if (err < 0)
  203. goto error;
  204. err = amdtp_dot_init(&dg00x->rx_stream, dg00x->unit, AMDTP_OUT_STREAM);
  205. if (err < 0)
  206. goto error;
  207. /* For in-stream. */
  208. err = fw_iso_resources_init(&dg00x->tx_resources, dg00x->unit);
  209. if (err < 0)
  210. goto error;
  211. err = amdtp_dot_init(&dg00x->tx_stream, dg00x->unit, AMDTP_IN_STREAM);
  212. if (err < 0)
  213. goto error;
  214. return 0;
  215. error:
  216. snd_dg00x_stream_destroy_duplex(dg00x);
  217. return err;
  218. }
  219. /*
  220. * This function should be called before starting streams or after stopping
  221. * streams.
  222. */
  223. void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x)
  224. {
  225. amdtp_stream_destroy(&dg00x->rx_stream);
  226. fw_iso_resources_destroy(&dg00x->rx_resources);
  227. amdtp_stream_destroy(&dg00x->tx_stream);
  228. fw_iso_resources_destroy(&dg00x->tx_resources);
  229. }
  230. int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x, unsigned int rate)
  231. {
  232. unsigned int curr_rate;
  233. int err = 0;
  234. if (dg00x->substreams_counter == 0)
  235. goto end;
  236. /* Check current sampling rate. */
  237. err = snd_dg00x_stream_get_local_rate(dg00x, &curr_rate);
  238. if (err < 0)
  239. goto error;
  240. if (rate == 0)
  241. rate = curr_rate;
  242. if (curr_rate != rate ||
  243. amdtp_streaming_error(&dg00x->tx_stream) ||
  244. amdtp_streaming_error(&dg00x->rx_stream)) {
  245. finish_session(dg00x);
  246. amdtp_stream_stop(&dg00x->tx_stream);
  247. amdtp_stream_stop(&dg00x->rx_stream);
  248. release_resources(dg00x);
  249. }
  250. /*
  251. * No packets are transmitted without receiving packets, reagardless of
  252. * which source of clock is used.
  253. */
  254. if (!amdtp_stream_running(&dg00x->rx_stream)) {
  255. err = snd_dg00x_stream_set_local_rate(dg00x, rate);
  256. if (err < 0)
  257. goto error;
  258. err = keep_resources(dg00x, rate);
  259. if (err < 0)
  260. goto error;
  261. err = begin_session(dg00x);
  262. if (err < 0)
  263. goto error;
  264. err = amdtp_stream_start(&dg00x->rx_stream,
  265. dg00x->rx_resources.channel,
  266. fw_parent_device(dg00x->unit)->max_speed);
  267. if (err < 0)
  268. goto error;
  269. if (!amdtp_stream_wait_callback(&dg00x->rx_stream,
  270. CALLBACK_TIMEOUT)) {
  271. err = -ETIMEDOUT;
  272. goto error;
  273. }
  274. }
  275. /*
  276. * The value of SYT field in transmitted packets is always 0x0000. Thus,
  277. * duplex streams with timestamp synchronization cannot be built.
  278. */
  279. if (!amdtp_stream_running(&dg00x->tx_stream)) {
  280. err = amdtp_stream_start(&dg00x->tx_stream,
  281. dg00x->tx_resources.channel,
  282. fw_parent_device(dg00x->unit)->max_speed);
  283. if (err < 0)
  284. goto error;
  285. if (!amdtp_stream_wait_callback(&dg00x->tx_stream,
  286. CALLBACK_TIMEOUT)) {
  287. err = -ETIMEDOUT;
  288. goto error;
  289. }
  290. }
  291. end:
  292. return err;
  293. error:
  294. finish_session(dg00x);
  295. amdtp_stream_stop(&dg00x->tx_stream);
  296. amdtp_stream_stop(&dg00x->rx_stream);
  297. release_resources(dg00x);
  298. return err;
  299. }
  300. void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x)
  301. {
  302. if (dg00x->substreams_counter > 0)
  303. return;
  304. amdtp_stream_stop(&dg00x->tx_stream);
  305. amdtp_stream_stop(&dg00x->rx_stream);
  306. finish_session(dg00x);
  307. release_resources(dg00x);
  308. /*
  309. * Just after finishing the session, the device may lost transmitting
  310. * functionality for a short time.
  311. */
  312. msleep(50);
  313. }
  314. void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x)
  315. {
  316. fw_iso_resources_update(&dg00x->tx_resources);
  317. fw_iso_resources_update(&dg00x->rx_resources);
  318. amdtp_stream_update(&dg00x->tx_stream);
  319. amdtp_stream_update(&dg00x->rx_stream);
  320. }
  321. void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x)
  322. {
  323. dg00x->dev_lock_changed = true;
  324. wake_up(&dg00x->hwdep_wait);
  325. }
  326. int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x)
  327. {
  328. int err;
  329. spin_lock_irq(&dg00x->lock);
  330. /* user land lock this */
  331. if (dg00x->dev_lock_count < 0) {
  332. err = -EBUSY;
  333. goto end;
  334. }
  335. /* this is the first time */
  336. if (dg00x->dev_lock_count++ == 0)
  337. snd_dg00x_stream_lock_changed(dg00x);
  338. err = 0;
  339. end:
  340. spin_unlock_irq(&dg00x->lock);
  341. return err;
  342. }
  343. void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x)
  344. {
  345. spin_lock_irq(&dg00x->lock);
  346. if (WARN_ON(dg00x->dev_lock_count <= 0))
  347. goto end;
  348. if (--dg00x->dev_lock_count == 0)
  349. snd_dg00x_stream_lock_changed(dg00x);
  350. end:
  351. spin_unlock_irq(&dg00x->lock);
  352. }