1 /***********************************************************************/
4 AudioScience HPI driver
5 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
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
9 published by the Free Software Foundation;
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 Functions for reading DSP code using
22 hotplug firmware loader from individual dsp code files
24 /***********************************************************************/
25 #define SOURCEFILE_NAME "hpidspcd.c"
29 struct dsp_code_private
{
30 /** Firmware descriptor */
31 const struct firmware
*firmware
;
35 #define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
36 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
38 /*-------------------------------------------------------------------*/
39 short hpi_dsp_code_open(u32 adapter
, void *os_data
, struct dsp_code
*dsp_code
,
42 const struct firmware
*firmware
;
43 struct pci_dev
*dev
= os_data
;
44 struct code_header header
;
46 short err_ret
= HPI_ERROR_DSP_FILE_NOT_FOUND
;
49 sprintf(fw_name
, "asihpi/dsp%04x.bin", adapter
);
51 err
= request_firmware(&firmware
, fw_name
, &dev
->dev
);
53 if (err
|| !firmware
) {
54 dev_printk(KERN_ERR
, &dev
->dev
,
55 "%d, request_firmware failed for %s\n", err
,
59 if (firmware
->size
< sizeof(header
)) {
60 dev_printk(KERN_ERR
, &dev
->dev
, "Header size too small %s\n",
64 memcpy(&header
, firmware
->data
, sizeof(header
));
66 if ((header
.type
!= 0x45444F43) || /* "CODE" */
67 (header
.adapter
!= adapter
)
68 || (header
.size
!= firmware
->size
)) {
69 dev_printk(KERN_ERR
, &dev
->dev
, "Invalid firmware file\n");
73 if ((header
.version
/ 100 & ~1) != (HPI_VER_DECIMAL
/ 100 & ~1)) {
74 dev_printk(KERN_ERR
, &dev
->dev
,
75 "Incompatible firmware version "
76 "DSP image %d != Driver %d\n", header
.version
,
81 if (header
.version
!= HPI_VER_DECIMAL
) {
82 dev_printk(KERN_WARNING
, &dev
->dev
,
83 "Firmware: release version mismatch DSP image %d != Driver %d\n",
84 header
.version
, HPI_VER_DECIMAL
);
87 HPI_DEBUG_LOG(DEBUG
, "dsp code %s opened\n", fw_name
);
88 dsp_code
->pvt
= kmalloc(sizeof(*dsp_code
->pvt
), GFP_KERNEL
);
90 err_ret
= HPI_ERROR_MEMORY_ALLOC
;
94 dsp_code
->pvt
->dev
= dev
;
95 dsp_code
->pvt
->firmware
= firmware
;
96 dsp_code
->header
= header
;
97 dsp_code
->block_length
= header
.size
/ sizeof(u32
);
98 dsp_code
->word_count
= sizeof(header
) / sizeof(u32
);
102 release_firmware(firmware
);
104 dsp_code
->block_length
= 0;
108 /*-------------------------------------------------------------------*/
109 void hpi_dsp_code_close(struct dsp_code
*dsp_code
)
111 if (dsp_code
->pvt
->firmware
) {
112 HPI_DEBUG_LOG(DEBUG
, "dsp code closed\n");
113 release_firmware(dsp_code
->pvt
->firmware
);
114 dsp_code
->pvt
->firmware
= NULL
;
116 kfree(dsp_code
->pvt
);
119 /*-------------------------------------------------------------------*/
120 void hpi_dsp_code_rewind(struct dsp_code
*dsp_code
)
122 /* Go back to start of data, after header */
123 dsp_code
->word_count
= sizeof(struct code_header
) / sizeof(u32
);
126 /*-------------------------------------------------------------------*/
127 short hpi_dsp_code_read_word(struct dsp_code
*dsp_code
, u32
*pword
)
129 if (dsp_code
->word_count
+ 1 > dsp_code
->block_length
)
130 return HPI_ERROR_DSP_FILE_FORMAT
;
132 *pword
= ((u32
*)(dsp_code
->pvt
->firmware
->data
))[dsp_code
->
134 dsp_code
->word_count
++;
138 /*-------------------------------------------------------------------*/
139 short hpi_dsp_code_read_block(size_t words_requested
,
140 struct dsp_code
*dsp_code
, u32
**ppblock
)
142 if (dsp_code
->word_count
+ words_requested
> dsp_code
->block_length
)
143 return HPI_ERROR_DSP_FILE_FORMAT
;
146 ((u32
*)(dsp_code
->pvt
->firmware
->data
)) +
147 dsp_code
->word_count
;
148 dsp_code
->word_count
+= words_requested
;