aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-12 11:00:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-12 11:00:30 -0500
commita429638cac1e5c656818a45aaff78df7b743004e (patch)
tree0465e0d7a431bff97a3dd5a1f91d9b30c69ae0d8 /drivers/firmware
parent5cf9a4e69c1ff0ccdd1d2b7404f95c0531355274 (diff)
parent9e4ce164ee3a1d07580f017069c25d180b0aa785 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (526 commits) ASoC: twl6040 - Add method to query optimum PDM_DL1 gain ALSA: hda - Fix the lost power-setup of seconary pins after PM resume ALSA: usb-audio: add Yamaha MOX6/MOX8 support ALSA: virtuoso: add S/PDIF input support for all Xonars ALSA: ice1724 - Support for ooAoo SQ210a ALSA: ice1724 - Allow card info based on model only ALSA: ice1724 - Create capture pcm only for ADC-enabled configurations ALSA: hdspm - Provide unique driver id based on card serial ASoC: Dynamically allocate the rtd device for a non-empty release() ASoC: Fix recursive dependency due to select ATMEL_SSC in SND_ATMEL_SOC_SSC ALSA: hda - Fix the detection of "Loopback Mixing" control for VIA codecs ALSA: hda - Return the error from get_wcaps_type() for invalid NIDs ALSA: hda - Use auto-parser for HP laptops with cx20459 codec ALSA: asihpi - Fix potential Oops in snd_asihpi_cmode_info() ALSA: hdsp - Fix potential Oops in snd_hdsp_info_pref_sync_ref() ALSA: hda/cirrus - support for iMac12,2 model ASoC: cx20442: add bias control over a platform provided regulator ALSA: usb-audio - Avoid flood of frame-active debug messages ALSA: snd-usb-us122l: Delete calls to preempt_disable mfd: Put WM8994 into cache only mode when suspending ... Fix up trivial conflicts in: - arch/arm/mach-s3c64xx/mach-crag6410.c: renamed speyside_wm8962 to tobermory, added littlemill right next to it - drivers/base/regmap/{regcache.c,regmap.c}: duplicate diff that had already come in with other changes in the regmap tree
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/Kconfig12
-rw-r--r--drivers/firmware/Makefile1
-rw-r--r--drivers/firmware/sigma.c153
3 files changed, 0 insertions, 166 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index efba163595db..9b00072a020f 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -145,18 +145,6 @@ config ISCSI_IBFT
145 detect iSCSI boot parameters dynamically during system boot, say Y. 145 detect iSCSI boot parameters dynamically during system boot, say Y.
146 Otherwise, say N. 146 Otherwise, say N.
147 147
148config SIGMA
149 tristate "SigmaStudio firmware loader"
150 depends on I2C
151 select CRC32
152 default n
153 help
154 Enable helper functions for working with Analog Devices SigmaDSP
155 parts and binary firmwares produced by Analog Devices SigmaStudio.
156
157 If unsure, say N here. Drivers that need these helpers will select
158 this option automatically.
159
160source "drivers/firmware/google/Kconfig" 148source "drivers/firmware/google/Kconfig"
161 149
162endmenu 150endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 47338c979126..5a7e27399729 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -12,6 +12,5 @@ obj-$(CONFIG_DMIID) += dmi-id.o
12obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o 12obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
13obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o 13obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o 14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
15obj-$(CONFIG_SIGMA) += sigma.o
16 15
17obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ 16obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c
deleted file mode 100644
index 1eedb6f7fdab..000000000000
--- a/drivers/firmware/sigma.c
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Load Analog Devices SigmaStudio firmware files
3 *
4 * Copyright 2009-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/crc32.h>
10#include <linux/delay.h>
11#include <linux/firmware.h>
12#include <linux/kernel.h>
13#include <linux/i2c.h>
14#include <linux/module.h>
15#include <linux/sigma.h>
16
17static size_t sigma_action_size(struct sigma_action *sa)
18{
19 size_t payload = 0;
20
21 switch (sa->instr) {
22 case SIGMA_ACTION_WRITEXBYTES:
23 case SIGMA_ACTION_WRITESINGLE:
24 case SIGMA_ACTION_WRITESAFELOAD:
25 payload = sigma_action_len(sa);
26 break;
27 default:
28 break;
29 }
30
31 payload = ALIGN(payload, 2);
32
33 return payload + sizeof(struct sigma_action);
34}
35
36/*
37 * Returns a negative error value in case of an error, 0 if processing of
38 * the firmware should be stopped after this action, 1 otherwise.
39 */
40static int
41process_sigma_action(struct i2c_client *client, struct sigma_action *sa)
42{
43 size_t len = sigma_action_len(sa);
44 int ret;
45
46 pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
47 sa->instr, sa->addr, len);
48
49 switch (sa->instr) {
50 case SIGMA_ACTION_WRITEXBYTES:
51 case SIGMA_ACTION_WRITESINGLE:
52 case SIGMA_ACTION_WRITESAFELOAD:
53 ret = i2c_master_send(client, (void *)&sa->addr, len);
54 if (ret < 0)
55 return -EINVAL;
56 break;
57 case SIGMA_ACTION_DELAY:
58 udelay(len);
59 len = 0;
60 break;
61 case SIGMA_ACTION_END:
62 return 0;
63 default:
64 return -EINVAL;
65 }
66
67 return 1;
68}
69
70static int
71process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
72{
73 struct sigma_action *sa;
74 size_t size;
75 int ret;
76
77 while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
78 sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
79
80 size = sigma_action_size(sa);
81 ssfw->pos += size;
82 if (ssfw->pos > ssfw->fw->size || size == 0)
83 break;
84
85 ret = process_sigma_action(client, sa);
86
87 pr_debug("%s: action returned %i\n", __func__, ret);
88
89 if (ret <= 0)
90 return ret;
91 }
92
93 if (ssfw->pos != ssfw->fw->size)
94 return -EINVAL;
95
96 return 0;
97}
98
99int process_sigma_firmware(struct i2c_client *client, const char *name)
100{
101 int ret;
102 struct sigma_firmware_header *ssfw_head;
103 struct sigma_firmware ssfw;
104 const struct firmware *fw;
105 u32 crc;
106
107 pr_debug("%s: loading firmware %s\n", __func__, name);
108
109 /* first load the blob */
110 ret = request_firmware(&fw, name, &client->dev);
111 if (ret) {
112 pr_debug("%s: request_firmware() failed with %i\n", __func__, ret);
113 return ret;
114 }
115 ssfw.fw = fw;
116
117 /* then verify the header */
118 ret = -EINVAL;
119
120 /*
121 * Reject too small or unreasonable large files. The upper limit has been
122 * chosen a bit arbitrarily, but it should be enough for all practical
123 * purposes and having the limit makes it easier to avoid integer
124 * overflows later in the loading process.
125 */
126 if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000)
127 goto done;
128
129 ssfw_head = (void *)fw->data;
130 if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
131 goto done;
132
133 crc = crc32(0, fw->data + sizeof(*ssfw_head),
134 fw->size - sizeof(*ssfw_head));
135 pr_debug("%s: crc=%x\n", __func__, crc);
136 if (crc != le32_to_cpu(ssfw_head->crc))
137 goto done;
138
139 ssfw.pos = sizeof(*ssfw_head);
140
141 /* finally process all of the actions */
142 ret = process_sigma_actions(client, &ssfw);
143
144 done:
145 release_firmware(fw);
146
147 pr_debug("%s: loaded %s\n", __func__, name);
148
149 return ret;
150}
151EXPORT_SYMBOL(process_sigma_firmware);
152
153MODULE_LICENSE("GPL");