]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/greybus/audio-gb-cmds.c
greybus: audio: Drop get_version support
[karo-tx-linux.git] / drivers / staging / greybus / audio-gb-cmds.c
1 /*
2  * Greybus audio commands
3  *
4  * Copyright 2015 Google Inc.
5  * Copyright 2015 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/kernel.h>
11
12 #include "greybus.h"
13 #include "audio.h"
14
15 /***********************************
16  * GB I2S helper functions
17  ***********************************/
18 int gb_i2s_mgmt_activate_cport(struct gb_connection *connection,
19                                       uint16_t cport)
20 {
21         struct gb_i2s_mgmt_activate_cport_request request;
22
23         memset(&request, 0, sizeof(request));
24         request.cport = cpu_to_le16(cport);
25
26         return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_ACTIVATE_CPORT,
27                                  &request, sizeof(request), NULL, 0);
28 }
29
30 int gb_i2s_mgmt_deactivate_cport(struct gb_connection *connection,
31                                         uint16_t cport)
32 {
33         struct gb_i2s_mgmt_deactivate_cport_request request;
34
35         memset(&request, 0, sizeof(request));
36         request.cport = cpu_to_le16(cport);
37
38         return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT,
39                                  &request, sizeof(request), NULL, 0);
40 }
41
42 int gb_i2s_mgmt_get_supported_configurations(
43         struct gb_connection *connection,
44         struct gb_i2s_mgmt_get_supported_configurations_response *get_cfg,
45         size_t size)
46 {
47         return gb_operation_sync(connection,
48                                  GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS,
49                                  NULL, 0, get_cfg, size);
50 }
51
52 int gb_i2s_mgmt_set_configuration(struct gb_connection *connection,
53                         struct gb_i2s_mgmt_set_configuration_request *set_cfg)
54 {
55         return gb_operation_sync(connection, GB_I2S_MGMT_TYPE_SET_CONFIGURATION,
56                                  set_cfg, sizeof(*set_cfg), NULL, 0);
57 }
58
59 int gb_i2s_mgmt_set_samples_per_message(
60                                 struct gb_connection *connection,
61                                 uint16_t samples_per_message)
62 {
63         struct gb_i2s_mgmt_set_samples_per_message_request request;
64
65         memset(&request, 0, sizeof(request));
66         request.samples_per_message = cpu_to_le16(samples_per_message);
67
68         return gb_operation_sync(connection,
69                                  GB_I2S_MGMT_TYPE_SET_SAMPLES_PER_MESSAGE,
70                                  &request, sizeof(request), NULL, 0);
71 }
72
73 int gb_i2s_mgmt_get_cfgs(struct gb_snd *snd_dev,
74                          struct gb_connection *connection)
75 {
76         struct gb_i2s_mgmt_get_supported_configurations_response *get_cfg;
77         size_t size;
78         int ret;
79
80         size = sizeof(*get_cfg) +
81                (CONFIG_COUNT_MAX * sizeof(get_cfg->config[0]));
82
83         get_cfg = kzalloc(size, GFP_KERNEL);
84         if (!get_cfg)
85                 return -ENOMEM;
86
87         ret = gb_i2s_mgmt_get_supported_configurations(connection, get_cfg,
88                                                        size);
89         if (ret) {
90                 pr_err("get_supported_config failed: %d\n", ret);
91                 goto err_free_get_cfg;
92         }
93
94         snd_dev->i2s_configs = get_cfg;
95
96         return 0;
97
98 err_free_get_cfg:
99         kfree(get_cfg);
100         return ret;
101 }
102
103 void gb_i2s_mgmt_free_cfgs(struct gb_snd *snd_dev)
104 {
105         kfree(snd_dev->i2s_configs);
106         snd_dev->i2s_configs = NULL;
107 }
108
109 int gb_i2s_mgmt_set_cfg(struct gb_snd *snd_dev, int rate, int chans,
110                         int bytes_per_chan, int is_le)
111 {
112         struct gb_i2s_mgmt_set_configuration_request set_cfg;
113         struct gb_i2s_mgmt_configuration *cfg;
114         int i, ret;
115         u8 byte_order = GB_I2S_MGMT_BYTE_ORDER_NA;
116
117         if (bytes_per_chan > 1) {
118                 if (is_le)
119                         byte_order = GB_I2S_MGMT_BYTE_ORDER_LE;
120                 else
121                         byte_order = GB_I2S_MGMT_BYTE_ORDER_BE;
122         }
123
124         for (i = 0, cfg = snd_dev->i2s_configs->config;
125              i < CONFIG_COUNT_MAX;
126              i++, cfg++) {
127                 if ((cfg->sample_frequency == cpu_to_le32(rate)) &&
128                     (cfg->num_channels == chans) &&
129                     (cfg->bytes_per_channel == bytes_per_chan) &&
130                     (cfg->byte_order & byte_order) &&
131                     (cfg->ll_protocol &
132                              cpu_to_le32(GB_I2S_MGMT_PROTOCOL_I2S)) &&
133                     (cfg->ll_mclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
134                     (cfg->ll_bclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
135                     (cfg->ll_wclk_role & GB_I2S_MGMT_ROLE_MASTER) &&
136                     (cfg->ll_wclk_polarity & GB_I2S_MGMT_POLARITY_NORMAL) &&
137                     (cfg->ll_wclk_change_edge & GB_I2S_MGMT_EDGE_FALLING) &&
138                     (cfg->ll_wclk_tx_edge & GB_I2S_MGMT_EDGE_RISING) &&
139                     (cfg->ll_wclk_rx_edge & GB_I2S_MGMT_EDGE_FALLING) &&
140                     (cfg->ll_data_offset == 1))
141                         break;
142         }
143
144         if (i >= CONFIG_COUNT_MAX) {
145                 pr_err("No valid configuration\n");
146                 return -EINVAL;
147         }
148
149         memcpy(&set_cfg, cfg, sizeof(set_cfg));
150         set_cfg.config.byte_order = byte_order;
151         set_cfg.config.ll_protocol = cpu_to_le32(GB_I2S_MGMT_PROTOCOL_I2S);
152         set_cfg.config.ll_mclk_role = GB_I2S_MGMT_ROLE_MASTER;
153         set_cfg.config.ll_bclk_role = GB_I2S_MGMT_ROLE_MASTER;
154         set_cfg.config.ll_wclk_role = GB_I2S_MGMT_ROLE_MASTER;
155         set_cfg.config.ll_wclk_polarity = GB_I2S_MGMT_POLARITY_NORMAL;
156         set_cfg.config.ll_wclk_change_edge = GB_I2S_MGMT_EDGE_FALLING;
157         set_cfg.config.ll_wclk_tx_edge = GB_I2S_MGMT_EDGE_RISING;
158         set_cfg.config.ll_wclk_rx_edge = GB_I2S_MGMT_EDGE_FALLING;
159
160         ret = gb_i2s_mgmt_set_configuration(snd_dev->mgmt_connection, &set_cfg);
161         if (ret)
162                 pr_err("set_configuration failed: %d\n", ret);
163
164         return ret;
165 }
166
167 int gb_i2s_send_data(struct gb_connection *connection,
168                                         void *req_buf, void *source_addr,
169                                         size_t len, int sample_num)
170 {
171         struct gb_i2s_send_data_request *gb_req;
172         int ret;
173
174         gb_req = req_buf;
175         gb_req->sample_number = cpu_to_le32(sample_num);
176
177         memcpy((void *)&gb_req->data[0], source_addr, len);
178
179         if (len < MAX_SEND_DATA_LEN)
180                 for (; len < MAX_SEND_DATA_LEN; len++)
181                         gb_req->data[len] = gb_req->data[len - SAMPLE_SIZE];
182
183         gb_req->size = cpu_to_le32(len);
184
185         ret = gb_operation_sync(connection, GB_I2S_DATA_TYPE_SEND_DATA,
186                                 (void *) gb_req, SEND_DATA_BUF_LEN, NULL, 0);
187         return ret;
188 }