GNU Linux-libre 4.19.295-gnu1
[releases.git] / drivers / staging / greybus / audio_apbridgea.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Greybus Audio Device Class Protocol helpers
4  *
5  * Copyright 2015-2016 Google Inc.
6  */
7
8 #include "greybus.h"
9 #include "greybus_protocols.h"
10 #include "audio_apbridgea.h"
11 #include "audio_codec.h"
12
13 int gb_audio_apbridgea_set_config(struct gb_connection *connection,
14                                   __u16 i2s_port, __u32 format, __u32 rate,
15                                   __u32 mclk_freq)
16 {
17         struct audio_apbridgea_set_config_request req;
18
19         req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_CONFIG;
20         req.hdr.i2s_port = cpu_to_le16(i2s_port);
21         req.format = cpu_to_le32(format);
22         req.rate = cpu_to_le32(rate);
23         req.mclk_freq = cpu_to_le32(mclk_freq);
24
25         return gb_hd_output(connection->hd, &req, sizeof(req),
26                             GB_APB_REQUEST_AUDIO_CONTROL, true);
27 }
28 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_config);
29
30 int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
31                                       __u16 i2s_port, __u16 cportid,
32                                       __u8 direction)
33 {
34         struct audio_apbridgea_register_cport_request req;
35         int ret;
36
37         req.hdr.type = AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT;
38         req.hdr.i2s_port = cpu_to_le16(i2s_port);
39         req.cport = cpu_to_le16(cportid);
40         req.direction = direction;
41
42         ret = gb_pm_runtime_get_sync(connection->bundle);
43         if (ret)
44                 return ret;
45
46         return gb_hd_output(connection->hd, &req, sizeof(req),
47                             GB_APB_REQUEST_AUDIO_CONTROL, true);
48 }
49 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_register_cport);
50
51 int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
52                                         __u16 i2s_port, __u16 cportid,
53                                         __u8 direction)
54 {
55         struct audio_apbridgea_unregister_cport_request req;
56         int ret;
57
58         req.hdr.type = AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT;
59         req.hdr.i2s_port = cpu_to_le16(i2s_port);
60         req.cport = cpu_to_le16(cportid);
61         req.direction = direction;
62
63         ret = gb_hd_output(connection->hd, &req, sizeof(req),
64                            GB_APB_REQUEST_AUDIO_CONTROL, true);
65
66         gb_pm_runtime_put_autosuspend(connection->bundle);
67
68         return ret;
69 }
70 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_unregister_cport);
71
72 int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
73                                         __u16 i2s_port, __u16 size)
74 {
75         struct audio_apbridgea_set_tx_data_size_request req;
76
77         req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_TX_DATA_SIZE;
78         req.hdr.i2s_port = cpu_to_le16(i2s_port);
79         req.size = cpu_to_le16(size);
80
81         return gb_hd_output(connection->hd, &req, sizeof(req),
82                             GB_APB_REQUEST_AUDIO_CONTROL, true);
83 }
84 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_tx_data_size);
85
86 int gb_audio_apbridgea_prepare_tx(struct gb_connection *connection,
87                                   __u16 i2s_port)
88 {
89         struct audio_apbridgea_prepare_tx_request req;
90
91         req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_TX;
92         req.hdr.i2s_port = cpu_to_le16(i2s_port);
93
94         return gb_hd_output(connection->hd, &req, sizeof(req),
95                             GB_APB_REQUEST_AUDIO_CONTROL, true);
96 }
97 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_tx);
98
99 int gb_audio_apbridgea_start_tx(struct gb_connection *connection,
100                                 __u16 i2s_port, __u64 timestamp)
101 {
102         struct audio_apbridgea_start_tx_request req;
103
104         req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_TX;
105         req.hdr.i2s_port = cpu_to_le16(i2s_port);
106         req.timestamp = cpu_to_le64(timestamp);
107
108         return gb_hd_output(connection->hd, &req, sizeof(req),
109                             GB_APB_REQUEST_AUDIO_CONTROL, true);
110 }
111 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_tx);
112
113 int gb_audio_apbridgea_stop_tx(struct gb_connection *connection, __u16 i2s_port)
114 {
115         struct audio_apbridgea_stop_tx_request req;
116
117         req.hdr.type = AUDIO_APBRIDGEA_TYPE_STOP_TX;
118         req.hdr.i2s_port = cpu_to_le16(i2s_port);
119
120         return gb_hd_output(connection->hd, &req, sizeof(req),
121                             GB_APB_REQUEST_AUDIO_CONTROL, true);
122 }
123 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_stop_tx);
124
125 int gb_audio_apbridgea_shutdown_tx(struct gb_connection *connection,
126                                    __u16 i2s_port)
127 {
128         struct audio_apbridgea_shutdown_tx_request req;
129
130         req.hdr.type = AUDIO_APBRIDGEA_TYPE_SHUTDOWN_TX;
131         req.hdr.i2s_port = cpu_to_le16(i2s_port);
132
133         return gb_hd_output(connection->hd, &req, sizeof(req),
134                             GB_APB_REQUEST_AUDIO_CONTROL, true);
135 }
136 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_shutdown_tx);
137
138 int gb_audio_apbridgea_set_rx_data_size(struct gb_connection *connection,
139                                         __u16 i2s_port, __u16 size)
140 {
141         struct audio_apbridgea_set_rx_data_size_request req;
142
143         req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_RX_DATA_SIZE;
144         req.hdr.i2s_port = cpu_to_le16(i2s_port);
145         req.size = cpu_to_le16(size);
146
147         return gb_hd_output(connection->hd, &req, sizeof(req),
148                             GB_APB_REQUEST_AUDIO_CONTROL, true);
149 }
150 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_rx_data_size);
151
152 int gb_audio_apbridgea_prepare_rx(struct gb_connection *connection,
153                                   __u16 i2s_port)
154 {
155         struct audio_apbridgea_prepare_rx_request req;
156
157         req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_RX;
158         req.hdr.i2s_port = cpu_to_le16(i2s_port);
159
160         return gb_hd_output(connection->hd, &req, sizeof(req),
161                             GB_APB_REQUEST_AUDIO_CONTROL, true);
162 }
163 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_rx);
164
165 int gb_audio_apbridgea_start_rx(struct gb_connection *connection,
166                                 __u16 i2s_port)
167 {
168         struct audio_apbridgea_start_rx_request req;
169
170         req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_RX;
171         req.hdr.i2s_port = cpu_to_le16(i2s_port);
172
173         return gb_hd_output(connection->hd, &req, sizeof(req),
174                             GB_APB_REQUEST_AUDIO_CONTROL, true);
175 }
176 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_rx);
177
178 int gb_audio_apbridgea_stop_rx(struct gb_connection *connection, __u16 i2s_port)
179 {
180         struct audio_apbridgea_stop_rx_request req;
181
182         req.hdr.type = AUDIO_APBRIDGEA_TYPE_STOP_RX;
183         req.hdr.i2s_port = cpu_to_le16(i2s_port);
184
185         return gb_hd_output(connection->hd, &req, sizeof(req),
186                             GB_APB_REQUEST_AUDIO_CONTROL, true);
187 }
188 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_stop_rx);
189
190 int gb_audio_apbridgea_shutdown_rx(struct gb_connection *connection,
191                                    __u16 i2s_port)
192 {
193         struct audio_apbridgea_shutdown_rx_request req;
194
195         req.hdr.type = AUDIO_APBRIDGEA_TYPE_SHUTDOWN_RX;
196         req.hdr.i2s_port = cpu_to_le16(i2s_port);
197
198         return gb_hd_output(connection->hd, &req, sizeof(req),
199                             GB_APB_REQUEST_AUDIO_CONTROL, true);
200 }
201 EXPORT_SYMBOL_GPL(gb_audio_apbridgea_shutdown_rx);
202
203 MODULE_LICENSE("GPL v2");
204 MODULE_ALIAS("greybus:audio-apbridgea");
205 MODULE_DESCRIPTION("Greybus Special APBridgeA Audio Protocol library");
206 MODULE_AUTHOR("Mark Greer <mgreer@animalcreek.com>");