linux/drivers/staging/greybus/audio_gb.c
<<
>>
Prefs
   1/*
   2 * Greybus Audio Device Class Protocol helpers
   3 *
   4 * Copyright 2015-2016 Google Inc.
   5 *
   6 * Released under the GPLv2 only.
   7 */
   8
   9#include "greybus.h"
  10#include "greybus_protocols.h"
  11#include "operation.h"
  12#include "audio_codec.h"
  13
  14/* TODO: Split into separate calls */
  15int gb_audio_gb_get_topology(struct gb_connection *connection,
  16                             struct gb_audio_topology **topology)
  17{
  18        struct gb_audio_get_topology_size_response size_resp;
  19        struct gb_audio_topology *topo;
  20        u16 size;
  21        int ret;
  22
  23        ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY_SIZE,
  24                                NULL, 0, &size_resp, sizeof(size_resp));
  25        if (ret)
  26                return ret;
  27
  28        size = le16_to_cpu(size_resp.size);
  29        if (size < sizeof(*topo))
  30                return -ENODATA;
  31
  32        topo = kzalloc(size, GFP_KERNEL);
  33        if (!topo)
  34                return -ENOMEM;
  35
  36        ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY, NULL, 0,
  37                                topo, size);
  38        if (ret) {
  39                kfree(topo);
  40                return ret;
  41        }
  42
  43        *topology = topo;
  44
  45        return 0;
  46}
  47EXPORT_SYMBOL_GPL(gb_audio_gb_get_topology);
  48
  49int gb_audio_gb_get_control(struct gb_connection *connection,
  50                            u8 control_id, u8 index,
  51                            struct gb_audio_ctl_elem_value *value)
  52{
  53        struct gb_audio_get_control_request req;
  54        struct gb_audio_get_control_response resp;
  55        int ret;
  56
  57        req.control_id = control_id;
  58        req.index = index;
  59
  60        ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_CONTROL,
  61                                &req, sizeof(req), &resp, sizeof(resp));
  62        if (ret)
  63                return ret;
  64
  65        memcpy(value, &resp.value, sizeof(*value));
  66
  67        return 0;
  68}
  69EXPORT_SYMBOL_GPL(gb_audio_gb_get_control);
  70
  71int gb_audio_gb_set_control(struct gb_connection *connection,
  72                            u8 control_id, u8 index,
  73                            struct gb_audio_ctl_elem_value *value)
  74{
  75        struct gb_audio_set_control_request req;
  76
  77        req.control_id = control_id;
  78        req.index = index;
  79        memcpy(&req.value, value, sizeof(req.value));
  80
  81        return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_CONTROL,
  82                                 &req, sizeof(req), NULL, 0);
  83}
  84EXPORT_SYMBOL_GPL(gb_audio_gb_set_control);
  85
  86int gb_audio_gb_enable_widget(struct gb_connection *connection,
  87                              u8 widget_id)
  88{
  89        struct gb_audio_enable_widget_request req;
  90
  91        req.widget_id = widget_id;
  92
  93        return gb_operation_sync(connection, GB_AUDIO_TYPE_ENABLE_WIDGET,
  94                                 &req, sizeof(req), NULL, 0);
  95}
  96EXPORT_SYMBOL_GPL(gb_audio_gb_enable_widget);
  97
  98int gb_audio_gb_disable_widget(struct gb_connection *connection,
  99                               u8 widget_id)
 100{
 101        struct gb_audio_disable_widget_request req;
 102
 103        req.widget_id = widget_id;
 104
 105        return gb_operation_sync(connection, GB_AUDIO_TYPE_DISABLE_WIDGET,
 106                                 &req, sizeof(req), NULL, 0);
 107}
 108EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget);
 109
 110int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport,
 111                        u32 *format, u32 *rate, u8 *channels,
 112                        u8 *sig_bits)
 113{
 114        struct gb_audio_get_pcm_request req;
 115        struct gb_audio_get_pcm_response resp;
 116        int ret;
 117
 118        req.data_cport = cpu_to_le16(data_cport);
 119
 120        ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_PCM,
 121                                &req, sizeof(req), &resp, sizeof(resp));
 122        if (ret)
 123                return ret;
 124
 125        *format = le32_to_cpu(resp.format);
 126        *rate = le32_to_cpu(resp.rate);
 127        *channels = resp.channels;
 128        *sig_bits = resp.sig_bits;
 129
 130        return 0;
 131}
 132EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm);
 133
 134int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport,
 135                        u32 format, u32 rate, u8 channels,
 136                        u8 sig_bits)
 137{
 138        struct gb_audio_set_pcm_request req;
 139
 140        req.data_cport = cpu_to_le16(data_cport);
 141        req.format = cpu_to_le32(format);
 142        req.rate = cpu_to_le32(rate);
 143        req.channels = channels;
 144        req.sig_bits = sig_bits;
 145
 146        return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_PCM,
 147                                 &req, sizeof(req), NULL, 0);
 148}
 149EXPORT_SYMBOL_GPL(gb_audio_gb_set_pcm);
 150
 151int gb_audio_gb_set_tx_data_size(struct gb_connection *connection,
 152                                 u16 data_cport, u16 size)
 153{
 154        struct gb_audio_set_tx_data_size_request req;
 155
 156        req.data_cport = cpu_to_le16(data_cport);
 157        req.size = cpu_to_le16(size);
 158
 159        return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_TX_DATA_SIZE,
 160                                 &req, sizeof(req), NULL, 0);
 161}
 162EXPORT_SYMBOL_GPL(gb_audio_gb_set_tx_data_size);
 163
 164int gb_audio_gb_activate_tx(struct gb_connection *connection,
 165                            u16 data_cport)
 166{
 167        struct gb_audio_activate_tx_request req;
 168
 169        req.data_cport = cpu_to_le16(data_cport);
 170
 171        return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_TX,
 172                                 &req, sizeof(req), NULL, 0);
 173}
 174EXPORT_SYMBOL_GPL(gb_audio_gb_activate_tx);
 175
 176int gb_audio_gb_deactivate_tx(struct gb_connection *connection,
 177                              u16 data_cport)
 178{
 179        struct gb_audio_deactivate_tx_request req;
 180
 181        req.data_cport = cpu_to_le16(data_cport);
 182
 183        return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_TX,
 184                                 &req, sizeof(req), NULL, 0);
 185}
 186EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_tx);
 187
 188int gb_audio_gb_set_rx_data_size(struct gb_connection *connection,
 189                                 u16 data_cport, u16 size)
 190{
 191        struct gb_audio_set_rx_data_size_request req;
 192
 193        req.data_cport = cpu_to_le16(data_cport);
 194        req.size = cpu_to_le16(size);
 195
 196        return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_RX_DATA_SIZE,
 197                                 &req, sizeof(req), NULL, 0);
 198}
 199EXPORT_SYMBOL_GPL(gb_audio_gb_set_rx_data_size);
 200
 201int gb_audio_gb_activate_rx(struct gb_connection *connection,
 202                            u16 data_cport)
 203{
 204        struct gb_audio_activate_rx_request req;
 205
 206        req.data_cport = cpu_to_le16(data_cport);
 207
 208        return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_RX,
 209                                 &req, sizeof(req), NULL, 0);
 210}
 211EXPORT_SYMBOL_GPL(gb_audio_gb_activate_rx);
 212
 213int gb_audio_gb_deactivate_rx(struct gb_connection *connection,
 214                              u16 data_cport)
 215{
 216        struct gb_audio_deactivate_rx_request req;
 217
 218        req.data_cport = cpu_to_le16(data_cport);
 219
 220        return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_RX,
 221                                 &req, sizeof(req), NULL, 0);
 222}
 223EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_rx);
 224
 225MODULE_LICENSE("GPL v2");
 226MODULE_ALIAS("greybus:audio-gb");
 227MODULE_DESCRIPTION("Greybus Audio Device Class Protocol library");
 228MODULE_AUTHOR("Mark Greer <mgreer@animalcreek.com>");
 229