![Greg Kroah-Hartman](/assets/img/avatar_default.png)
Now that the SPDX tag is in all greybus files, that identifies the license in a specific and legally-defined manner. So the extra GPL text wording can be removed as it is no longer needed at all. This is done on a quest to remove the 700+ different ways that files in the kernel describe the GPL license text. And there's unneeded stuff like the address (sometimes incorrect) for the FSF which is never needed. No copyright headers or other non-license-description text was removed. Cc: Vaibhav Hiremath <hvaibhav.linux@gmail.com> Reviewed-by: Alex Elder <elder@linaro.org> Acked-by: Vaibhav Agarwal <vaibhav.sr@gmail.com> Acked-by: David Lin <dtwlin@gmail.com> Acked-by: Johan Hovold <johan@kernel.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Mark Greer <mgreer@animalcreek.com> Acked-by: Rui Miguel Silva <rmfrfs@gmail.com> Acked-by: "Bryan O'Donoghue" <pure.logic@nexus-software.ie> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
228 lines
5.7 KiB
C
228 lines
5.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Greybus Audio Device Class Protocol helpers
|
|
*
|
|
* Copyright 2015-2016 Google Inc.
|
|
*/
|
|
|
|
#include "greybus.h"
|
|
#include "greybus_protocols.h"
|
|
#include "operation.h"
|
|
#include "audio_codec.h"
|
|
|
|
/* TODO: Split into separate calls */
|
|
int gb_audio_gb_get_topology(struct gb_connection *connection,
|
|
struct gb_audio_topology **topology)
|
|
{
|
|
struct gb_audio_get_topology_size_response size_resp;
|
|
struct gb_audio_topology *topo;
|
|
u16 size;
|
|
int ret;
|
|
|
|
ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY_SIZE,
|
|
NULL, 0, &size_resp, sizeof(size_resp));
|
|
if (ret)
|
|
return ret;
|
|
|
|
size = le16_to_cpu(size_resp.size);
|
|
if (size < sizeof(*topo))
|
|
return -ENODATA;
|
|
|
|
topo = kzalloc(size, GFP_KERNEL);
|
|
if (!topo)
|
|
return -ENOMEM;
|
|
|
|
ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY, NULL, 0,
|
|
topo, size);
|
|
if (ret) {
|
|
kfree(topo);
|
|
return ret;
|
|
}
|
|
|
|
*topology = topo;
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_get_topology);
|
|
|
|
int gb_audio_gb_get_control(struct gb_connection *connection,
|
|
u8 control_id, u8 index,
|
|
struct gb_audio_ctl_elem_value *value)
|
|
{
|
|
struct gb_audio_get_control_request req;
|
|
struct gb_audio_get_control_response resp;
|
|
int ret;
|
|
|
|
req.control_id = control_id;
|
|
req.index = index;
|
|
|
|
ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_CONTROL,
|
|
&req, sizeof(req), &resp, sizeof(resp));
|
|
if (ret)
|
|
return ret;
|
|
|
|
memcpy(value, &resp.value, sizeof(*value));
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_get_control);
|
|
|
|
int gb_audio_gb_set_control(struct gb_connection *connection,
|
|
u8 control_id, u8 index,
|
|
struct gb_audio_ctl_elem_value *value)
|
|
{
|
|
struct gb_audio_set_control_request req;
|
|
|
|
req.control_id = control_id;
|
|
req.index = index;
|
|
memcpy(&req.value, value, sizeof(req.value));
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_CONTROL,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_set_control);
|
|
|
|
int gb_audio_gb_enable_widget(struct gb_connection *connection,
|
|
u8 widget_id)
|
|
{
|
|
struct gb_audio_enable_widget_request req;
|
|
|
|
req.widget_id = widget_id;
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_ENABLE_WIDGET,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_enable_widget);
|
|
|
|
int gb_audio_gb_disable_widget(struct gb_connection *connection,
|
|
u8 widget_id)
|
|
{
|
|
struct gb_audio_disable_widget_request req;
|
|
|
|
req.widget_id = widget_id;
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_DISABLE_WIDGET,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget);
|
|
|
|
int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport,
|
|
u32 *format, u32 *rate, u8 *channels,
|
|
u8 *sig_bits)
|
|
{
|
|
struct gb_audio_get_pcm_request req;
|
|
struct gb_audio_get_pcm_response resp;
|
|
int ret;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
|
|
ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_PCM,
|
|
&req, sizeof(req), &resp, sizeof(resp));
|
|
if (ret)
|
|
return ret;
|
|
|
|
*format = le32_to_cpu(resp.format);
|
|
*rate = le32_to_cpu(resp.rate);
|
|
*channels = resp.channels;
|
|
*sig_bits = resp.sig_bits;
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm);
|
|
|
|
int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport,
|
|
u32 format, u32 rate, u8 channels,
|
|
u8 sig_bits)
|
|
{
|
|
struct gb_audio_set_pcm_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
req.format = cpu_to_le32(format);
|
|
req.rate = cpu_to_le32(rate);
|
|
req.channels = channels;
|
|
req.sig_bits = sig_bits;
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_PCM,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_set_pcm);
|
|
|
|
int gb_audio_gb_set_tx_data_size(struct gb_connection *connection,
|
|
u16 data_cport, u16 size)
|
|
{
|
|
struct gb_audio_set_tx_data_size_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
req.size = cpu_to_le16(size);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_TX_DATA_SIZE,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_set_tx_data_size);
|
|
|
|
int gb_audio_gb_activate_tx(struct gb_connection *connection,
|
|
u16 data_cport)
|
|
{
|
|
struct gb_audio_activate_tx_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_TX,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_activate_tx);
|
|
|
|
int gb_audio_gb_deactivate_tx(struct gb_connection *connection,
|
|
u16 data_cport)
|
|
{
|
|
struct gb_audio_deactivate_tx_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_TX,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_tx);
|
|
|
|
int gb_audio_gb_set_rx_data_size(struct gb_connection *connection,
|
|
u16 data_cport, u16 size)
|
|
{
|
|
struct gb_audio_set_rx_data_size_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
req.size = cpu_to_le16(size);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_RX_DATA_SIZE,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_set_rx_data_size);
|
|
|
|
int gb_audio_gb_activate_rx(struct gb_connection *connection,
|
|
u16 data_cport)
|
|
{
|
|
struct gb_audio_activate_rx_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_RX,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_activate_rx);
|
|
|
|
int gb_audio_gb_deactivate_rx(struct gb_connection *connection,
|
|
u16 data_cport)
|
|
{
|
|
struct gb_audio_deactivate_rx_request req;
|
|
|
|
req.data_cport = cpu_to_le16(data_cport);
|
|
|
|
return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_RX,
|
|
&req, sizeof(req), NULL, 0);
|
|
}
|
|
EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_rx);
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
MODULE_ALIAS("greybus:audio-gb");
|
|
MODULE_DESCRIPTION("Greybus Audio Device Class Protocol library");
|
|
MODULE_AUTHOR("Mark Greer <mgreer@animalcreek.com>");
|