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