Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 342611
b: refs/heads/master
c: 90caaef
h: refs/heads/master
i:
  342609: e2a2672
  342607: 6ee7997
v: v3
  • Loading branch information
Takashi Iwai committed Nov 22, 2012
1 parent 7304e2f commit 278caee
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7009fa568b126a07b2de8ead103e378534453830
refs/heads/master: 90caaef6a1ce2ec6675b1dc5afd57767954ab7e8
1 change: 1 addition & 0 deletions trunk/sound/pci/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ source "sound/pci/hda/Kconfig"

config SND_HDSP
tristate "RME Hammerfall DSP Audio"
select FW_LOADER
select SND_HWDEP
select SND_RAWMIDI
select SND_PCM
Expand Down
62 changes: 34 additions & 28 deletions trunk/sound/pci/rme9652/hdsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
"{RME HDSP-9652},"
"{RME HDSP-9632}}");
#ifdef HDSP_FW_LOADER
MODULE_FIRMWARE("rpm_firmware.bin");
MODULE_FIRMWARE("multiface_firmware.bin");
MODULE_FIRMWARE("multiface_firmware_rev11.bin");
MODULE_FIRMWARE("digiface_firmware.bin");
MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#endif

#define HDSP_MAX_CHANNELS 26
#define HDSP_MAX_DS_CHANNELS 14
Expand Down Expand Up @@ -423,12 +421,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)

/* use hotplug firmware loader? */
#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
#if !defined(HDSP_USE_HWDEP_LOADER)
#define HDSP_FW_LOADER
#endif
#endif
#define HDSP_FIRMWARE_SIZE (24413 * 4)

struct hdsp_9632_meters {
u32 input_peak[16];
Expand Down Expand Up @@ -475,7 +468,8 @@ struct hdsp {
enum HDSP_IO_Type io_type; /* ditto, but for code use */
unsigned short firmware_rev;
unsigned short state; /* stores state bits */
u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
const struct firmware *firmware;
u32 *fw_uploaded;
size_t period_bytes; /* guess what this is */
unsigned char max_channels;
unsigned char qs_in_channels; /* quad speed mode for H9632 */
Expand Down Expand Up @@ -712,6 +706,17 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {

int i;
unsigned long flags;
const u32 *cache;

if (hdsp->fw_uploaded)
cache = hdsp->fw_uploaded;
else {
if (!hdsp->firmware)
return -ENODEV;
cache = (u32 *)hdsp->firmware->data;
if (!cache)
return -ENODEV;
}

if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {

Expand All @@ -727,8 +732,8 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {

hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);

for (i = 0; i < 24413; ++i) {
hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
for (i = 0; i < HDSP_FIRMWARE_SIZE / 4; ++i) {
hdsp_write(hdsp, HDSP_fifoData, cache[i]);
if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
return -EIO;
Expand Down Expand Up @@ -798,9 +803,7 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
}


#ifdef HDSP_FW_LOADER
static int hdsp_request_fw_loader(struct hdsp *hdsp);
#endif

static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
{
Expand All @@ -813,10 +816,8 @@ static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
/* try to load firmware */
if (! (hdsp->state & HDSP_FirmwareCached)) {
#ifdef HDSP_FW_LOADER
if (! hdsp_request_fw_loader(hdsp))
return 0;
#endif
snd_printk(KERN_ERR
"Hammerfall-DSP: No firmware loaded nor "
"cached, please upload firmware.\n");
Expand Down Expand Up @@ -3673,9 +3674,7 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
}
} else {
int err = -EINVAL;
#ifdef HDSP_FW_LOADER
err = hdsp_request_fw_loader(hdsp);
#endif
if (err < 0) {
snd_iprintf(buffer,
"No firmware loaded nor cached, "
Expand Down Expand Up @@ -5100,8 +5099,18 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
if (hdsp_check_for_iobox (hdsp))
return -EIO;

if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
if (!hdsp->fw_uploaded) {
hdsp->fw_uploaded = vmalloc(HDSP_FIRMWARE_SIZE);
if (!hdsp->fw_uploaded)
return -ENOMEM;
}

if (copy_from_user(hdsp->fw_uploaded, firmware_data,
HDSP_FIRMWARE_SIZE)) {
vfree(hdsp->fw_uploaded);
hdsp->fw_uploaded = NULL;
return -EFAULT;
}

hdsp->state |= HDSP_FirmwareCached;

Expand Down Expand Up @@ -5330,7 +5339,6 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
return 0;
}

#ifdef HDSP_FW_LOADER
/* load firmware via hotplug fw loader */
static int hdsp_request_fw_loader(struct hdsp *hdsp)
{
Expand Down Expand Up @@ -5373,16 +5381,13 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
return -ENOENT;
}
if (fw->size < sizeof(hdsp->firmware_cache)) {
if (fw->size < HDSP_FIRMWARE_SIZE) {
snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
(int)fw->size, (int)sizeof(hdsp->firmware_cache));
release_firmware(fw);
(int)fw->size, HDSP_FIRMWARE_SIZE);
return -EINVAL;
}

memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));

release_firmware(fw);
hdsp->firmware = fw;

hdsp->state |= HDSP_FirmwareCached;

Expand All @@ -5406,7 +5411,6 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
}
return 0;
}
#endif

static int __devinit snd_hdsp_create(struct snd_card *card,
struct hdsp *hdsp)
Expand Down Expand Up @@ -5504,7 +5508,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
return err;

if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
#ifdef HDSP_FW_LOADER
if ((err = hdsp_request_fw_loader(hdsp)) < 0)
/* we don't fail as this can happen
if userspace is not ready for
Expand All @@ -5514,7 +5517,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
else
/* init is complete, we return */
return 0;
#endif
/* we defer initialization */
snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
Expand Down Expand Up @@ -5568,6 +5570,10 @@ static int snd_hdsp_free(struct hdsp *hdsp)

snd_hdsp_free_buffers(hdsp);

if (hdsp->firmware)
release_firmware(hdsp->firmware);
vfree(hdsp->fw_uploaded);

if (hdsp->iobase)
iounmap(hdsp->iobase);

Expand Down

0 comments on commit 278caee

Please sign in to comment.