[patch 10/32] greybus: audio driver

2016-09-16 Thread Greg KH
This driver implements the Greybus audio protocol.

Signed-off-by: Greg Kroah-Hartman 
---
 drivers/greybus/audio_apbridgea.c   |  207 
 drivers/greybus/audio_apbridgea.h   |  156 +++
 drivers/greybus/audio_codec.c   | 1132 +
 drivers/greybus/audio_codec.h   |  283 ++
 drivers/greybus/audio_gb.c  |  228 +
 drivers/greybus/audio_manager.c |  184 
 drivers/greybus/audio_manager.h |   83 +
 drivers/greybus/audio_manager_module.c  |  258 +
 drivers/greybus/audio_manager_private.h |   28 
 drivers/greybus/audio_manager_sysfs.c   |  102 ++
 drivers/greybus/audio_module.c  |  482 ++
 drivers/greybus/audio_topology.c| 1442 
 12 files changed, 4585 insertions(+)

--- /dev/null
+++ b/drivers/greybus/audio_apbridgea.c
@@ -0,0 +1,207 @@
+/*
+ * Greybus Audio Device Class Protocol helpers
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+#include "audio_apbridgea.h"
+#include "audio_codec.h"
+
+int gb_audio_apbridgea_set_config(struct gb_connection *connection,
+ __u16 i2s_port, __u32 format, __u32 rate,
+ __u32 mclk_freq)
+{
+   struct audio_apbridgea_set_config_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_CONFIG;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.format = cpu_to_le32(format);
+   req.rate = cpu_to_le32(rate);
+   req.mclk_freq = cpu_to_le32(mclk_freq);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_config);
+
+int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction)
+{
+   struct audio_apbridgea_register_cport_request req;
+   int ret;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.cport = cpu_to_le16(cportid);
+   req.direction = direction;
+
+   ret = gb_pm_runtime_get_sync(connection->bundle);
+   if (ret)
+   return ret;
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_register_cport);
+
+int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
+   __u16 i2s_port, __u16 cportid,
+   __u8 direction)
+{
+   struct audio_apbridgea_unregister_cport_request req;
+   int ret;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.cport = cpu_to_le16(cportid);
+   req.direction = direction;
+
+   ret = gb_hd_output(connection->hd, , sizeof(req),
+  GB_APB_REQUEST_AUDIO_CONTROL, true);
+
+   gb_pm_runtime_put_autosuspend(connection->bundle);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_unregister_cport);
+
+int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
+   __u16 i2s_port, __u16 size)
+{
+   struct audio_apbridgea_set_tx_data_size_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_TX_DATA_SIZE;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.size = cpu_to_le16(size);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_tx_data_size);
+
+int gb_audio_apbridgea_prepare_tx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+   struct audio_apbridgea_prepare_tx_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_TX;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_tx);
+
+int gb_audio_apbridgea_start_tx(struct gb_connection *connection,
+   __u16 i2s_port, __u64 timestamp)
+{
+   struct audio_apbridgea_start_tx_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_TX;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.timestamp = cpu_to_le64(timestamp);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_tx);
+
+int gb_audio_apbridgea_stop_tx(struct gb_connection *connection, __u16 
i2s_port)
+{
+   struct 

[patch 10/32] greybus: audio driver

2016-09-16 Thread Greg KH
This driver implements the Greybus audio protocol.

Signed-off-by: Greg Kroah-Hartman 
---
 drivers/greybus/audio_apbridgea.c   |  207 
 drivers/greybus/audio_apbridgea.h   |  156 +++
 drivers/greybus/audio_codec.c   | 1132 +
 drivers/greybus/audio_codec.h   |  283 ++
 drivers/greybus/audio_gb.c  |  228 +
 drivers/greybus/audio_manager.c |  184 
 drivers/greybus/audio_manager.h |   83 +
 drivers/greybus/audio_manager_module.c  |  258 +
 drivers/greybus/audio_manager_private.h |   28 
 drivers/greybus/audio_manager_sysfs.c   |  102 ++
 drivers/greybus/audio_module.c  |  482 ++
 drivers/greybus/audio_topology.c| 1442 
 12 files changed, 4585 insertions(+)

--- /dev/null
+++ b/drivers/greybus/audio_apbridgea.c
@@ -0,0 +1,207 @@
+/*
+ * Greybus Audio Device Class Protocol helpers
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+#include "audio_apbridgea.h"
+#include "audio_codec.h"
+
+int gb_audio_apbridgea_set_config(struct gb_connection *connection,
+ __u16 i2s_port, __u32 format, __u32 rate,
+ __u32 mclk_freq)
+{
+   struct audio_apbridgea_set_config_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_CONFIG;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.format = cpu_to_le32(format);
+   req.rate = cpu_to_le32(rate);
+   req.mclk_freq = cpu_to_le32(mclk_freq);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_config);
+
+int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction)
+{
+   struct audio_apbridgea_register_cport_request req;
+   int ret;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.cport = cpu_to_le16(cportid);
+   req.direction = direction;
+
+   ret = gb_pm_runtime_get_sync(connection->bundle);
+   if (ret)
+   return ret;
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_register_cport);
+
+int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
+   __u16 i2s_port, __u16 cportid,
+   __u8 direction)
+{
+   struct audio_apbridgea_unregister_cport_request req;
+   int ret;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.cport = cpu_to_le16(cportid);
+   req.direction = direction;
+
+   ret = gb_hd_output(connection->hd, , sizeof(req),
+  GB_APB_REQUEST_AUDIO_CONTROL, true);
+
+   gb_pm_runtime_put_autosuspend(connection->bundle);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_unregister_cport);
+
+int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
+   __u16 i2s_port, __u16 size)
+{
+   struct audio_apbridgea_set_tx_data_size_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_TX_DATA_SIZE;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.size = cpu_to_le16(size);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_tx_data_size);
+
+int gb_audio_apbridgea_prepare_tx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+   struct audio_apbridgea_prepare_tx_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_TX;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_tx);
+
+int gb_audio_apbridgea_start_tx(struct gb_connection *connection,
+   __u16 i2s_port, __u64 timestamp)
+{
+   struct audio_apbridgea_start_tx_request req;
+
+   req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_TX;
+   req.hdr.i2s_port = cpu_to_le16(i2s_port);
+   req.timestamp = cpu_to_le64(timestamp);
+
+   return gb_hd_output(connection->hd, , sizeof(req),
+   GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_tx);
+
+int gb_audio_apbridgea_stop_tx(struct gb_connection *connection, __u16 
i2s_port)
+{
+   struct audio_apbridgea_stop_tx_request req;
+
+