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