blob: 34e63b554c312d590c46d1194f53b7d4b28b8e66 [file] [log] [blame]
Mike Frysingere359dc22011-03-22 16:34:40 -07001/*
2 * Load Analog Devices SigmaStudio firmware files
3 *
Lars-Peter Clausend48b0882014-11-19 18:29:05 +01004 * Copyright 2009-2014 Analog Devices Inc.
Mike Frysingere359dc22011-03-22 16:34:40 -07005 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/crc32.h>
Mike Frysingere359dc22011-03-22 16:34:40 -070010#include <linux/firmware.h>
11#include <linux/kernel.h>
12#include <linux/i2c.h>
Lars-Peter Clausen38fd54e2011-11-28 09:44:20 +010013#include <linux/regmap.h>
Randy Dunlap27c46a252011-07-25 17:13:21 -070014#include <linux/module.h>
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010015#include <linux/slab.h>
16
17#include <sound/soc.h>
Lars-Peter Clausen40216ce2011-11-28 09:44:17 +010018
19#include "sigmadsp.h"
Mike Frysingere359dc22011-03-22 16:34:40 -070020
Lars-Peter Clausena4c1d7e2011-11-28 09:44:19 +010021#define SIGMA_MAGIC "ADISIGM"
22
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010023struct sigmadsp_data {
24 struct list_head head;
25 unsigned int addr;
26 unsigned int length;
27 uint8_t data[];
28};
29
Lars-Peter Clausena4c1d7e2011-11-28 09:44:19 +010030struct sigma_firmware_header {
31 unsigned char magic[7];
32 u8 version;
33 __le32 crc;
34} __packed;
35
36enum {
37 SIGMA_ACTION_WRITEXBYTES = 0,
38 SIGMA_ACTION_WRITESINGLE,
39 SIGMA_ACTION_WRITESAFELOAD,
Lars-Peter Clausena4c1d7e2011-11-28 09:44:19 +010040 SIGMA_ACTION_END,
41};
42
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010043struct sigma_action {
44 u8 instr;
45 u8 len_hi;
46 __le16 len;
47 __be16 addr;
48 unsigned char payload[];
49} __packed;
50
51static int sigmadsp_write(struct sigmadsp *sigmadsp, unsigned int addr,
52 const uint8_t data[], size_t len)
53{
54 return sigmadsp->write(sigmadsp->control_data, addr, data, len);
55}
56
Lars-Peter Clausena4c1d7e2011-11-28 09:44:19 +010057static inline u32 sigma_action_len(struct sigma_action *sa)
58{
59 return (sa->len_hi << 16) | le16_to_cpu(sa->len);
60}
61
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +010062static size_t sigma_action_size(struct sigma_action *sa)
Mike Frysingere359dc22011-03-22 16:34:40 -070063{
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +010064 size_t payload = 0;
65
66 switch (sa->instr) {
67 case SIGMA_ACTION_WRITEXBYTES:
68 case SIGMA_ACTION_WRITESINGLE:
69 case SIGMA_ACTION_WRITESAFELOAD:
70 payload = sigma_action_len(sa);
71 break;
72 default:
73 break;
74 }
75
76 payload = ALIGN(payload, 2);
77
78 return payload + sizeof(struct sigma_action);
79}
80
81/*
82 * Returns a negative error value in case of an error, 0 if processing of
83 * the firmware should be stopped after this action, 1 otherwise.
84 */
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010085static int process_sigma_action(struct sigmadsp *sigmadsp,
86 struct sigma_action *sa)
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +010087{
Mike Frysingere359dc22011-03-22 16:34:40 -070088 size_t len = sigma_action_len(sa);
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010089 struct sigmadsp_data *data;
Mike Frysingere359dc22011-03-22 16:34:40 -070090
91 pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
92 sa->instr, sa->addr, len);
93
94 switch (sa->instr) {
95 case SIGMA_ACTION_WRITEXBYTES:
96 case SIGMA_ACTION_WRITESINGLE:
97 case SIGMA_ACTION_WRITESAFELOAD:
Lars-Peter Clausend48b0882014-11-19 18:29:05 +010098 if (len < 3)
Mike Frysingere359dc22011-03-22 16:34:40 -070099 return -EINVAL;
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100100
101 data = kzalloc(sizeof(*data) + len - 2, GFP_KERNEL);
102 if (!data)
103 return -ENOMEM;
104
105 data->addr = be16_to_cpu(sa->addr);
106 data->length = len - 2;
107 memcpy(data->data, sa->payload, data->length);
108 list_add_tail(&data->head, &sigmadsp->data_list);
Mike Frysingere359dc22011-03-22 16:34:40 -0700109 break;
Mike Frysingere359dc22011-03-22 16:34:40 -0700110 case SIGMA_ACTION_END:
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100111 return 0;
Mike Frysingere359dc22011-03-22 16:34:40 -0700112 default:
113 return -EINVAL;
114 }
115
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100116 return 1;
Mike Frysingere359dc22011-03-22 16:34:40 -0700117}
118
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100119static int sigmadsp_fw_load_v1(struct sigmadsp *sigmadsp,
120 const struct firmware *fw)
Mike Frysingere359dc22011-03-22 16:34:40 -0700121{
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100122 struct sigma_action *sa;
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100123 size_t size, pos;
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100124 int ret;
Mike Frysingere359dc22011-03-22 16:34:40 -0700125
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100126 pos = sizeof(struct sigma_firmware_header);
127
128 while (pos + sizeof(*sa) <= fw->size) {
129 sa = (struct sigma_action *)(fw->data + pos);
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100130
131 size = sigma_action_size(sa);
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100132 pos += size;
133 if (pos > fw->size || size == 0)
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100134 break;
135
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100136 ret = process_sigma_action(sigmadsp, sa);
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100137
Mike Frysingere359dc22011-03-22 16:34:40 -0700138 pr_debug("%s: action returned %i\n", __func__, ret);
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100139
140 if (ret <= 0)
Mike Frysingere359dc22011-03-22 16:34:40 -0700141 return ret;
142 }
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100143
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100144 if (pos != fw->size)
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100145 return -EINVAL;
146
147 return 0;
Mike Frysingere359dc22011-03-22 16:34:40 -0700148}
149
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100150static void sigmadsp_firmware_release(struct sigmadsp *sigmadsp)
Mike Frysingere359dc22011-03-22 16:34:40 -0700151{
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100152 struct sigmadsp_data *data, *_data;
153
154 list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head)
155 kfree(data);
156
157 INIT_LIST_HEAD(&sigmadsp->data_list);
158}
159
160static void devm_sigmadsp_release(struct device *dev, void *res)
161{
162 sigmadsp_firmware_release((struct sigmadsp *)res);
163}
164
165static int sigmadsp_firmware_load(struct sigmadsp *sigmadsp, const char *name)
166{
167 const struct sigma_firmware_header *ssfw_head;
Mike Frysingere359dc22011-03-22 16:34:40 -0700168 const struct firmware *fw;
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100169 int ret;
Mike Frysingere359dc22011-03-22 16:34:40 -0700170 u32 crc;
171
Mike Frysingere359dc22011-03-22 16:34:40 -0700172 /* first load the blob */
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100173 ret = request_firmware(&fw, name, sigmadsp->dev);
Mike Frysingere359dc22011-03-22 16:34:40 -0700174 if (ret) {
175 pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100176 goto done;
Mike Frysingere359dc22011-03-22 16:34:40 -0700177 }
Mike Frysingere359dc22011-03-22 16:34:40 -0700178
179 /* then verify the header */
180 ret = -EINVAL;
Lars-Peter Clausen4f718a22011-11-28 09:44:14 +0100181
182 /*
183 * Reject too small or unreasonable large files. The upper limit has been
184 * chosen a bit arbitrarily, but it should be enough for all practical
185 * purposes and having the limit makes it easier to avoid integer
186 * overflows later in the loading process.
187 */
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100188 if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) {
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100189 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid size\n");
Mike Frysingere359dc22011-03-22 16:34:40 -0700190 goto done;
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100191 }
Mike Frysingere359dc22011-03-22 16:34:40 -0700192
193 ssfw_head = (void *)fw->data;
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100194 if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) {
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100195 dev_err(sigmadsp->dev, "Failed to load firmware: Invalid magic\n");
Lars-Peter Clausen50c0f212014-11-19 18:29:02 +0100196 goto done;
197 }
198
Lars-Peter Clausenc56935b2011-11-28 09:44:15 +0100199 crc = crc32(0, fw->data + sizeof(*ssfw_head),
200 fw->size - sizeof(*ssfw_head));
Mike Frysingere359dc22011-03-22 16:34:40 -0700201 pr_debug("%s: crc=%x\n", __func__, crc);
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100202 if (crc != le32_to_cpu(ssfw_head->crc)) {
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100203 dev_err(sigmadsp->dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n",
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100204 le32_to_cpu(ssfw_head->crc), crc);
Mike Frysingere359dc22011-03-22 16:34:40 -0700205 goto done;
Lars-Peter Clausen48afc522011-11-28 09:44:18 +0100206 }
Mike Frysingere359dc22011-03-22 16:34:40 -0700207
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100208 switch (ssfw_head->version) {
209 case 1:
210 ret = sigmadsp_fw_load_v1(sigmadsp, fw);
211 break;
212 default:
213 dev_err(sigmadsp->dev,
214 "Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n",
215 ssfw_head->version);
216 ret = -EINVAL;
217 break;
218 }
Mike Frysingere359dc22011-03-22 16:34:40 -0700219
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100220 if (ret)
221 sigmadsp_firmware_release(sigmadsp);
Mike Frysingere359dc22011-03-22 16:34:40 -0700222
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100223done:
Mike Frysingere359dc22011-03-22 16:34:40 -0700224 release_firmware(fw);
225
Mike Frysingere359dc22011-03-22 16:34:40 -0700226 return ret;
227}
Lars-Peter Clausend48b0882014-11-19 18:29:05 +0100228
229static int sigmadsp_init(struct sigmadsp *sigmadsp, struct device *dev,
230 const struct sigmadsp_ops *ops, const char *firmware_name)
231{
232 sigmadsp->ops = ops;
233 sigmadsp->dev = dev;
234
235 INIT_LIST_HEAD(&sigmadsp->data_list);
236
237 return sigmadsp_firmware_load(sigmadsp, firmware_name);
238}
239
240/**
241 * devm_sigmadsp_init() - Initialize SigmaDSP instance
242 * @dev: The parent device
243 * @ops: The sigmadsp_ops to use for this instance
244 * @firmware_name: Name of the firmware file to load
245 *
246 * Allocates a SigmaDSP instance and loads the specified firmware file.
247 *
248 * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error.
249 */
250struct sigmadsp *devm_sigmadsp_init(struct device *dev,
251 const struct sigmadsp_ops *ops, const char *firmware_name)
252{
253 struct sigmadsp *sigmadsp;
254 int ret;
255
256 sigmadsp = devres_alloc(devm_sigmadsp_release, sizeof(*sigmadsp),
257 GFP_KERNEL);
258 if (!sigmadsp)
259 return ERR_PTR(-ENOMEM);
260
261 ret = sigmadsp_init(sigmadsp, dev, ops, firmware_name);
262 if (ret) {
263 devres_free(sigmadsp);
264 return ERR_PTR(ret);
265 }
266
267 devres_add(dev, sigmadsp);
268
269 return sigmadsp;
270}
271EXPORT_SYMBOL_GPL(devm_sigmadsp_init);
272
273/**
274 * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component
275 * @sigmadsp: The sigmadsp instance to attach
276 * @component: The component to attach to
277 *
278 * Typically called in the components probe callback.
279 *
280 * Note, once this function has been called the firmware must not be released
281 * until after the ALSA snd_card that the component belongs to has been
282 * disconnected, even if sigmadsp_attach() returns an error.
283 */
284int sigmadsp_attach(struct sigmadsp *sigmadsp,
285 struct snd_soc_component *component)
286{
287 sigmadsp->component = component;
288
289 return 0;
290}
291EXPORT_SYMBOL_GPL(sigmadsp_attach);
292
293/**
294 * sigmadsp_setup() - Setup the DSP for the specified samplerate
295 * @sigmadsp: The sigmadsp instance to configure
296 * @samplerate: The samplerate the DSP should be configured for
297 *
298 * Loads the appropriate firmware program and parameter memory (if not already
299 * loaded) and enables the controls for the specified samplerate. Any control
300 * parameter changes that have been made previously will be restored.
301 *
302 * Returns 0 on success, a negative error code otherwise.
303 */
304int sigmadsp_setup(struct sigmadsp *sigmadsp, unsigned int samplerate)
305{
306 struct sigmadsp_data *data;
307 int ret;
308
309 if (sigmadsp->current_samplerate == samplerate)
310 return 0;
311
312 list_for_each_entry(data, &sigmadsp->data_list, head) {
313 ret = sigmadsp_write(sigmadsp, data->addr, data->data,
314 data->length);
315 if (ret)
316 goto err;
317 }
318
319 sigmadsp->current_samplerate = samplerate;
320
321 return 0;
322err:
323 sigmadsp_reset(sigmadsp);
324
325 return ret;
326}
327EXPORT_SYMBOL_GPL(sigmadsp_setup);
328
329/**
330 * sigmadsp_reset() - Notify the sigmadsp instance that the DSP has been reset
331 * @sigmadsp: The sigmadsp instance to reset
332 *
333 * Should be called whenever the DSP has been reset and parameter and program
334 * memory need to be re-loaded.
335 */
336void sigmadsp_reset(struct sigmadsp *sigmadsp)
337{
338 sigmadsp->current_samplerate = 0;
339}
340EXPORT_SYMBOL_GPL(sigmadsp_reset);
341
342/**
343 * sigmadsp_restrict_params() - Applies DSP firmware specific constraints
344 * @sigmadsp: The sigmadsp instance
345 * @substream: The substream to restrict
346 *
347 * Applies samplerate constraints that may be required by the firmware Should
348 * typically be called from the CODEC/component drivers startup callback.
349 *
350 * Returns 0 on success, a negative error code otherwise.
351 */
352int sigmadsp_restrict_params(struct sigmadsp *sigmadsp,
353 struct snd_pcm_substream *substream)
354{
355 return 0;
356}
357EXPORT_SYMBOL_GPL(sigmadsp_restrict_params);
Lars-Peter Clausen38fd54e2011-11-28 09:44:20 +0100358
Randy Dunlap27c46a252011-07-25 17:13:21 -0700359MODULE_LICENSE("GPL");