aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorEliot Blennerhassett <eblennerhassett@audioscience.com>2011-07-21 23:52:42 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-22 01:49:23 -0400
commit95a4c6e785bf7e2e5cde7f92c9252877b4fcea46 (patch)
tree9215aad12e57eca88581390571630c29a1a3fcbc /sound
parent58fbf77ff5d258a15a4084940e08219d7ee6f449 (diff)
ALSA: asihpi - DSP code loader API now independent of OS
The loader API has been revised so that OS specific data is kept local to hpidspcd.c, and the public API is unchanged across OSes. Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/asihpi/hpi6000.c7
-rw-r--r--sound/pci/asihpi/hpi6205.c5
-rw-r--r--sound/pci/asihpi/hpidspcd.c135
-rw-r--r--sound/pci/asihpi/hpidspcd.h72
4 files changed, 97 insertions, 122 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index c8db36e90979..3cc6f11c20aa 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -946,11 +946,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
946 } 946 }
947 947
948 /* write the DSP code down into the DSPs memory */ 948 /* write the DSP code down into the DSPs memory */
949 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 949 error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
950 dsp_code.ps_dev = pao->pci.pci_dev; 950 &dsp_code, pos_error_code);
951
952 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
953 pos_error_code);
954 951
955 if (error) 952 if (error)
956 return error; 953 return error;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index d011932c952f..3e31a3f3708e 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -1371,9 +1371,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1371 return err; 1371 return err;
1372 1372
1373 /* write the DSP code down into the DSPs memory */ 1373 /* write the DSP code down into the DSPs memory */
1374 dsp_code.ps_dev = pao->pci.pci_dev; 1374 err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
1375 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, 1375 &dsp_code, pos_error_code);
1376 pos_error_code);
1377 if (err) 1376 if (err)
1378 return err; 1377 return err;
1379 1378
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 5c6ea113d219..987538819b24 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -1,8 +1,8 @@
1/***********************************************************************/ 1/***********************************************************************/
2/*! 2/**
3 3
4 AudioScience HPI driver 4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as 8 it under the terms of version 2 of the GNU General Public License as
@@ -18,90 +18,60 @@
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20\file 20\file
21Functions for reading DSP code to load into DSP 21Functions for reading DSP code using
22
23(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
24hotplug firmware loader from individual dsp code files 22hotplug firmware loader from individual dsp code files
25 23*/
26If neither of the above is defined, code is read from linked arrays.
27DSPCODE_ARRAY is defined.
28
29HPI_INCLUDE_**** must be defined
30and the appropriate hzz?????.c or hex?????.c linked in
31
32 */
33/***********************************************************************/ 24/***********************************************************************/
34#define SOURCEFILE_NAME "hpidspcd.c" 25#define SOURCEFILE_NAME "hpidspcd.c"
35#include "hpidspcd.h" 26#include "hpidspcd.h"
36#include "hpidebug.h" 27#include "hpidebug.h"
37 28
38/** 29struct dsp_code_private {
39 Header structure for binary dsp code file (see asidsp.doc) 30 /** Firmware descriptor */
40 This structure must match that used in s2bin.c for generation of asidsp.bin 31 const struct firmware *firmware;
41 */ 32 struct pci_dev *dev;
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47struct code_header {
48 u32 size;
49 char type[4];
50 u32 adapter;
51 u32 version;
52 u32 crc;
53}; 33};
54 34
55#ifndef DISABLE_PRAGMA_PACK1
56#pragma pack(pop)
57#endif
58
59#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ 35#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) 36 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61 37
62/***********************************************************************/
63#include <linux/pci.h> 38#include <linux/pci.h>
64/*-------------------------------------------------------------------*/ 39/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, 40short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
66 u32 *pos_error_code) 41 u32 *os_error_code)
67{ 42{
68 const struct firmware *ps_firmware = ps_dsp_code->ps_firmware; 43 const struct firmware *firmware;
44 struct pci_dev *dev = os_data;
69 struct code_header header; 45 struct code_header header;
70 char fw_name[20]; 46 char fw_name[20];
71 int err; 47 int err;
72 48
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); 49 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 50
75 err = request_firmware(&ps_firmware, fw_name, 51 err = request_firmware(&firmware, fw_name, &dev->dev);
76 &ps_dsp_code->ps_dev->dev);
77 52
78 if (err != 0) { 53 if (err || !firmware) {
79 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 54 dev_printk(KERN_ERR, &dev->dev,
80 "%d, request_firmware failed for %s\n", err, 55 "%d, request_firmware failed for %s\n", err,
81 fw_name); 56 fw_name);
82 goto error1; 57 goto error1;
83 } 58 }
84 if (ps_firmware->size < sizeof(header)) { 59 if (firmware->size < sizeof(header)) {
85 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 60 dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
86 "Header size too small %s\n", fw_name); 61 fw_name);
87 goto error2;
88 }
89 memcpy(&header, ps_firmware->data, sizeof(header));
90 if (header.adapter != adapter) {
91 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
92 "Adapter type incorrect %4x != %4x\n", header.adapter,
93 adapter);
94 goto error2; 62 goto error2;
95 } 63 }
96 if (header.size != ps_firmware->size) { 64 memcpy(&header, firmware->data, sizeof(header));
97 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 65
98 "Code size wrong %d != %ld\n", header.size, 66 if ((header.type != 0x45444F43) || /* "CODE" */
99 (unsigned long)ps_firmware->size); 67 (header.adapter != adapter)
68 || (header.size != firmware->size)) {
69 dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
100 goto error2; 70 goto error2;
101 } 71 }
102 72
103 if (header.version / 100 != HPI_VER_DECIMAL / 100) { 73 if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
104 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev, 74 dev_printk(KERN_ERR, &dev->dev,
105 "Incompatible firmware version " 75 "Incompatible firmware version "
106 "DSP image %d != Driver %d\n", header.version, 76 "DSP image %d != Driver %d\n", header.version,
107 HPI_VER_DECIMAL); 77 HPI_VER_DECIMAL);
@@ -109,67 +79,70 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
109 } 79 }
110 80
111 if (header.version != HPI_VER_DECIMAL) { 81 if (header.version != HPI_VER_DECIMAL) {
112 dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev, 82 dev_printk(KERN_WARNING, &dev->dev,
113 "Firmware: release version mismatch DSP image %d != Driver %d\n", 83 "Firmware: release version mismatch DSP image %d != Driver %d\n",
114 header.version, HPI_VER_DECIMAL); 84 header.version, HPI_VER_DECIMAL);
115 } 85 }
116 86
117 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); 87 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
118 ps_dsp_code->ps_firmware = ps_firmware; 88 dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
119 ps_dsp_code->block_length = header.size / sizeof(u32); 89 if (!dsp_code->pvt)
120 ps_dsp_code->word_count = sizeof(header) / sizeof(u32); 90 return HPI_ERROR_MEMORY_ALLOC;
121 ps_dsp_code->version = header.version; 91
122 ps_dsp_code->crc = header.crc; 92 dsp_code->pvt->dev = dev;
93 dsp_code->pvt->firmware = firmware;
94 dsp_code->header = header;
95 dsp_code->block_length = header.size / sizeof(u32);
96 dsp_code->word_count = sizeof(header) / sizeof(u32);
123 return 0; 97 return 0;
124 98
125error2: 99error2:
126 release_firmware(ps_firmware); 100 release_firmware(firmware);
127error1: 101error1:
128 ps_dsp_code->ps_firmware = NULL; 102 dsp_code->block_length = 0;
129 ps_dsp_code->block_length = 0;
130 return HPI_ERROR_DSP_FILE_NOT_FOUND; 103 return HPI_ERROR_DSP_FILE_NOT_FOUND;
131} 104}
132 105
133/*-------------------------------------------------------------------*/ 106/*-------------------------------------------------------------------*/
134void hpi_dsp_code_close(struct dsp_code *ps_dsp_code) 107void hpi_dsp_code_close(struct dsp_code *dsp_code)
135{ 108{
136 if (ps_dsp_code->ps_firmware != NULL) { 109 if (dsp_code->pvt->firmware) {
137 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); 110 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
138 release_firmware(ps_dsp_code->ps_firmware); 111 release_firmware(dsp_code->pvt->firmware);
139 ps_dsp_code->ps_firmware = NULL; 112 dsp_code->pvt->firmware = NULL;
140 } 113 }
114 kfree(dsp_code->pvt);
141} 115}
142 116
143/*-------------------------------------------------------------------*/ 117/*-------------------------------------------------------------------*/
144void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code) 118void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
145{ 119{
146 /* Go back to start of data, after header */ 120 /* Go back to start of data, after header */
147 ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32); 121 dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
148} 122}
149 123
150/*-------------------------------------------------------------------*/ 124/*-------------------------------------------------------------------*/
151short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword) 125short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
152{ 126{
153 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length) 127 if (dsp_code->word_count + 1 > dsp_code->block_length)
154 return HPI_ERROR_DSP_FILE_FORMAT; 128 return HPI_ERROR_DSP_FILE_FORMAT;
155 129
156 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code-> 130 *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
157 word_count]; 131 word_count];
158 ps_dsp_code->word_count++; 132 dsp_code->word_count++;
159 return 0; 133 return 0;
160} 134}
161 135
162/*-------------------------------------------------------------------*/ 136/*-------------------------------------------------------------------*/
163short hpi_dsp_code_read_block(size_t words_requested, 137short hpi_dsp_code_read_block(size_t words_requested,
164 struct dsp_code *ps_dsp_code, u32 **ppblock) 138 struct dsp_code *dsp_code, u32 **ppblock)
165{ 139{
166 if (ps_dsp_code->word_count + words_requested > 140 if (dsp_code->word_count + words_requested > dsp_code->block_length)
167 ps_dsp_code->block_length)
168 return HPI_ERROR_DSP_FILE_FORMAT; 141 return HPI_ERROR_DSP_FILE_FORMAT;
169 142
170 *ppblock = 143 *ppblock =
171 ((u32 *)(ps_dsp_code->ps_firmware->data)) + 144 ((u32 *)(dsp_code->pvt->firmware->data)) +
172 ps_dsp_code->word_count; 145 dsp_code->word_count;
173 ps_dsp_code->word_count += words_requested; 146 dsp_code->word_count += words_requested;
174 return 0; 147 return 0;
175} 148}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index 65f0ca732704..b22881122f19 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -2,7 +2,7 @@
2/** 2/**
3 3
4 AudioScience HPI driver 4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> 5 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as 8 it under the terms of version 2 of the GNU General Public License as
@@ -20,19 +20,6 @@
20\file 20\file
21Functions for reading DSP code to load into DSP 21Functions for reading DSP code to load into DSP
22 22
23 hpi_dspcode_defines HPI DSP code loading method
24Define exactly one of these to select how the DSP code is supplied to
25the adapter.
26
27End users writing applications that use the HPI interface do not have to
28use any of the below defines; they are only necessary for building drivers
29
30HPI_DSPCODE_FILE:
31DSP code is supplied as a file that is opened and read from by the driver.
32
33HPI_DSPCODE_FIRMWARE:
34DSP code is read using the hotplug firmware loader module.
35 Only valid when compiling the HPI kernel driver under Linux.
36*/ 23*/
37/***********************************************************************/ 24/***********************************************************************/
38#ifndef _HPIDSPCD_H_ 25#ifndef _HPIDSPCD_H_
@@ -40,37 +27,56 @@ DSP code is read using the hotplug firmware loader module.
40 27
41#include "hpi_internal.h" 28#include "hpi_internal.h"
42 29
43#ifndef DISABLE_PRAGMA_PACK1 30/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
44#pragma pack(push, 1) 31#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
45#endif 32HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
33
34/** Header structure for dsp firmware file
35 This structure must match that used in s2bin.c for generation of asidsp.bin
36 */
37/*#ifndef DISABLE_PRAGMA_PACK1 */
38/*#pragma pack(push, 1) */
39/*#endif */
40struct code_header {
41 /** Size in bytes including header */
42 u32 size;
43 /** File type tag "CODE" == 0x45444F43 */
44 u32 type;
45 /** Adapter model number */
46 u32 adapter;
47 /** Firmware version*/
48 u32 version;
49 /** Data checksum */
50 u32 checksum;
51};
52/*#ifndef DISABLE_PRAGMA_PACK1 */
53/*#pragma pack(pop) */
54/*#endif */
55
56/*? Don't need the pragmas? */
57compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
46 58
47/** Descriptor for dspcode from firmware loader */ 59/** Descriptor for dspcode from firmware loader */
48struct dsp_code { 60struct dsp_code {
49 /** Firmware descriptor */ 61 /** copy of file header */
50 const struct firmware *ps_firmware; 62 struct code_header header;
51 struct pci_dev *ps_dev;
52 /** Expected number of words in the whole dsp code,INCL header */ 63 /** Expected number of words in the whole dsp code,INCL header */
53 long int block_length; 64 u32 block_length;
54 /** Number of words read so far */ 65 /** Number of words read so far */
55 long int word_count; 66 u32 word_count;
56 /** Version read from dsp code file */
57 u32 version;
58 /** CRC read from dsp code file */
59 u32 crc;
60};
61 67
62#ifndef DISABLE_PRAGMA_PACK1 68 /** internal state of DSP code reader */
63#pragma pack(pop) 69 struct dsp_code_private *pvt;
64#endif 70};
65 71
66/** Prepare *psDspCode to refer to the requuested adapter. 72/** Prepare *psDspCode to refer to the requested adapter's firmware.
67 Searches the file, or selects the appropriate linked array 73Code file name is obtained from HpiOs_GetDspCodePath
68 74
69\return 0 for success, or error code if requested code is not available 75\return 0 for success, or error code if requested code is not available
70*/ 76*/
71short hpi_dsp_code_open( 77short hpi_dsp_code_open(
72 /** Code identifier, usually adapter family */ 78 /** Code identifier, usually adapter family */
73 u32 adapter, 79 u32 adapter, void *pci_dev,
74 /** Pointer to DSP code control structure */ 80 /** Pointer to DSP code control structure */
75 struct dsp_code *ps_dsp_code, 81 struct dsp_code *ps_dsp_code,
76 /** Pointer to dword to receive OS specific error code */ 82 /** Pointer to dword to receive OS specific error code */