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 
9 #include "oxfw.h"
10 
11 int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw)
12 {
13 	int err;
14 
15 	err = cmp_connection_init(&oxfw->in_conn, oxfw->unit,
16 				  CMP_INPUT, 0);
17 	if (err < 0)
18 		goto end;
19 
20 	err = amdtp_stream_init(&oxfw->rx_stream, oxfw->unit,
21 				AMDTP_OUT_STREAM, CIP_NONBLOCKING);
22 	if (err < 0) {
23 		amdtp_stream_destroy(&oxfw->rx_stream);
24 		cmp_connection_destroy(&oxfw->in_conn);
25 	}
26 end:
27 	return err;
28 }
29 
30 static void stop_stream(struct snd_oxfw *oxfw)
31 {
32 	amdtp_stream_pcm_abort(&oxfw->rx_stream);
33 	amdtp_stream_stop(&oxfw->rx_stream);
34 	cmp_connection_break(&oxfw->in_conn);
35 }
36 
37 int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw)
38 {
39 	int err = 0;
40 
41 	if (amdtp_streaming_error(&oxfw->rx_stream))
42 		stop_stream(oxfw);
43 
44 	if (amdtp_stream_running(&oxfw->rx_stream))
45 		goto end;
46 
47 	err = cmp_connection_establish(&oxfw->in_conn,
48 			amdtp_stream_get_max_payload(&oxfw->rx_stream));
49 	if (err < 0)
50 		goto end;
51 
52 	err = amdtp_stream_start(&oxfw->rx_stream,
53 				 oxfw->in_conn.resources.channel,
54 				 oxfw->in_conn.speed);
55 	if (err < 0)
56 		stop_stream(oxfw);
57 end:
58 	return err;
59 }
60 
61 void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw)
62 {
63 	stop_stream(oxfw);
64 }
65 
66 void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw)
67 {
68 	stop_stream(oxfw);
69 
70 	amdtp_stream_destroy(&oxfw->rx_stream);
71 	cmp_connection_destroy(&oxfw->in_conn);
72 }
73 
74 void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw)
75 {
76 	if (cmp_connection_update(&oxfw->in_conn) < 0)
77 		stop_stream(oxfw);
78 	else
79 		amdtp_stream_update(&oxfw->rx_stream);
80 }
81