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>"); 207