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
gb_audio_apbridgea_set_config(struct gb_connection * connection,__u16 i2s_port,__u32 format,__u32 rate,__u32 mclk_freq)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
gb_audio_apbridgea_register_cport(struct gb_connection * connection,__u16 i2s_port,__u16 cportid,__u8 direction)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
gb_audio_apbridgea_unregister_cport(struct gb_connection * connection,__u16 i2s_port,__u16 cportid,__u8 direction)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
gb_audio_apbridgea_set_tx_data_size(struct gb_connection * connection,__u16 i2s_port,__u16 size)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
gb_audio_apbridgea_prepare_tx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_start_tx(struct gb_connection * connection,__u16 i2s_port,__u64 timestamp)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
gb_audio_apbridgea_stop_tx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_shutdown_tx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_set_rx_data_size(struct gb_connection * connection,__u16 i2s_port,__u16 size)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
gb_audio_apbridgea_prepare_rx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_start_rx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_stop_rx(struct gb_connection * connection,__u16 i2s_port)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
gb_audio_apbridgea_shutdown_rx(struct gb_connection * connection,__u16 i2s_port)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>");
207