/*
 * Greybus Audio Device Class Protocol helpers
 *
 * Copyright 2015-2016 Google Inc.
 *
 * Released under the GPLv2 only.
 */

#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,
			uint32_t *format, uint32_t *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,
			uint32_t format, uint32_t 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>");
