1e2786ca6STakashi Sakamoto /*
2e2786ca6STakashi Sakamoto  * oxfw_stream.c - a part of driver for OXFW970/971 based devices
3e2786ca6STakashi Sakamoto  *
4e2786ca6STakashi Sakamoto  * Copyright (c) 2014 Takashi Sakamoto
5e2786ca6STakashi Sakamoto  *
6e2786ca6STakashi Sakamoto  * Licensed under the terms of the GNU General Public License, version 2.
7e2786ca6STakashi Sakamoto  */
8e2786ca6STakashi Sakamoto 
9e2786ca6STakashi Sakamoto #include "oxfw.h"
10e2786ca6STakashi Sakamoto 
11e2786ca6STakashi Sakamoto int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw)
12e2786ca6STakashi Sakamoto {
13e2786ca6STakashi Sakamoto 	int err;
14e2786ca6STakashi Sakamoto 
15e2786ca6STakashi Sakamoto 	err = cmp_connection_init(&oxfw->in_conn, oxfw->unit,
16e2786ca6STakashi Sakamoto 				  CMP_INPUT, 0);
17e2786ca6STakashi Sakamoto 	if (err < 0)
18e2786ca6STakashi Sakamoto 		goto end;
19e2786ca6STakashi Sakamoto 
20e2786ca6STakashi Sakamoto 	err = amdtp_stream_init(&oxfw->rx_stream, oxfw->unit,
21e2786ca6STakashi Sakamoto 				AMDTP_OUT_STREAM, CIP_NONBLOCKING);
22e2786ca6STakashi Sakamoto 	if (err < 0) {
23e2786ca6STakashi Sakamoto 		amdtp_stream_destroy(&oxfw->rx_stream);
24e2786ca6STakashi Sakamoto 		cmp_connection_destroy(&oxfw->in_conn);
25e2786ca6STakashi Sakamoto 	}
26e2786ca6STakashi Sakamoto end:
27e2786ca6STakashi Sakamoto 	return err;
28e2786ca6STakashi Sakamoto }
29e2786ca6STakashi Sakamoto 
30e2786ca6STakashi Sakamoto static void stop_stream(struct snd_oxfw *oxfw)
31e2786ca6STakashi Sakamoto {
32e2786ca6STakashi Sakamoto 	amdtp_stream_pcm_abort(&oxfw->rx_stream);
33e2786ca6STakashi Sakamoto 	amdtp_stream_stop(&oxfw->rx_stream);
34e2786ca6STakashi Sakamoto 	cmp_connection_break(&oxfw->in_conn);
35e2786ca6STakashi Sakamoto }
36e2786ca6STakashi Sakamoto 
37e2786ca6STakashi Sakamoto int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw)
38e2786ca6STakashi Sakamoto {
39e2786ca6STakashi Sakamoto 	int err = 0;
40e2786ca6STakashi Sakamoto 
41e2786ca6STakashi Sakamoto 	if (amdtp_streaming_error(&oxfw->rx_stream))
42e2786ca6STakashi Sakamoto 		stop_stream(oxfw);
43e2786ca6STakashi Sakamoto 
44e2786ca6STakashi Sakamoto 	if (amdtp_stream_running(&oxfw->rx_stream))
45e2786ca6STakashi Sakamoto 		goto end;
46e2786ca6STakashi Sakamoto 
47e2786ca6STakashi Sakamoto 	err = cmp_connection_establish(&oxfw->in_conn,
48e2786ca6STakashi Sakamoto 			amdtp_stream_get_max_payload(&oxfw->rx_stream));
49e2786ca6STakashi Sakamoto 	if (err < 0)
50e2786ca6STakashi Sakamoto 		goto end;
51e2786ca6STakashi Sakamoto 
52e2786ca6STakashi Sakamoto 	err = amdtp_stream_start(&oxfw->rx_stream,
53e2786ca6STakashi Sakamoto 				 oxfw->in_conn.resources.channel,
54e2786ca6STakashi Sakamoto 				 oxfw->in_conn.speed);
55e2786ca6STakashi Sakamoto 	if (err < 0)
56e2786ca6STakashi Sakamoto 		stop_stream(oxfw);
57e2786ca6STakashi Sakamoto end:
58e2786ca6STakashi Sakamoto 	return err;
59e2786ca6STakashi Sakamoto }
60e2786ca6STakashi Sakamoto 
61e2786ca6STakashi Sakamoto void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw)
62e2786ca6STakashi Sakamoto {
63e2786ca6STakashi Sakamoto 	stop_stream(oxfw);
64e2786ca6STakashi Sakamoto }
65e2786ca6STakashi Sakamoto 
66e2786ca6STakashi Sakamoto void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw)
67e2786ca6STakashi Sakamoto {
68e2786ca6STakashi Sakamoto 	stop_stream(oxfw);
69e2786ca6STakashi Sakamoto 
70e2786ca6STakashi Sakamoto 	amdtp_stream_destroy(&oxfw->rx_stream);
71e2786ca6STakashi Sakamoto 	cmp_connection_destroy(&oxfw->in_conn);
72e2786ca6STakashi Sakamoto }
73e2786ca6STakashi Sakamoto 
74e2786ca6STakashi Sakamoto void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw)
75e2786ca6STakashi Sakamoto {
76e2786ca6STakashi Sakamoto 	if (cmp_connection_update(&oxfw->in_conn) < 0)
77e2786ca6STakashi Sakamoto 		stop_stream(oxfw);
78e2786ca6STakashi Sakamoto 	else
79e2786ca6STakashi Sakamoto 		amdtp_stream_update(&oxfw->rx_stream);
80e2786ca6STakashi Sakamoto }
81