aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ymfpci/ymfpci_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ymfpci/ymfpci_main.c')
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c125
1 files changed, 102 insertions, 23 deletions
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 7881944a1957..5bde816cd5c4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2,12 +2,6 @@
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of YMF724/740/744/754 chips 3 * Routines for control of YMF724/740/744/754 chips
4 * 4 *
5 * BUGS:
6 * --
7 *
8 * TODO:
9 * --
10 *
11 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; either version 2 of the License, or
@@ -26,6 +20,7 @@
26 20
27#include <sound/driver.h> 21#include <sound/driver.h>
28#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/firmware.h>
29#include <linux/init.h> 24#include <linux/init.h>
30#include <linux/interrupt.h> 25#include <linux/interrupt.h>
31#include <linux/pci.h> 26#include <linux/pci.h>
@@ -42,10 +37,7 @@
42#include <sound/mpu401.h> 37#include <sound/mpu401.h>
43 38
44#include <asm/io.h> 39#include <asm/io.h>
45 40#include <asm/byteorder.h>
46/*
47 * constants
48 */
49 41
50/* 42/*
51 * common I/O routines 43 * common I/O routines
@@ -1971,13 +1963,94 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
1971 } 1963 }
1972} 1964}
1973 1965
1966#define FIRMWARE_IN_THE_KERNEL
1967
1968#ifdef FIRMWARE_IN_THE_KERNEL
1969
1974#include "ymfpci_image.h" 1970#include "ymfpci_image.h"
1975 1971
1972static struct firmware snd_ymfpci_dsp_microcode = {
1973 .size = YDSXG_DSPLENGTH,
1974 .data = (u8 *)DspInst,
1975};
1976static struct firmware snd_ymfpci_controller_microcode = {
1977 .size = YDSXG_CTRLLENGTH,
1978 .data = (u8 *)CntrlInst,
1979};
1980static struct firmware snd_ymfpci_controller_1e_microcode = {
1981 .size = YDSXG_CTRLLENGTH,
1982 .data = (u8 *)CntrlInst1E,
1983};
1984#endif
1985
1986#ifdef __LITTLE_ENDIAN
1987static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { }
1988#else
1989static void snd_ymfpci_convert_from_le(const struct firmware *fw)
1990{
1991 int i;
1992 u32 *data = (u32 *)fw->data;
1993
1994 for (i = 0; i < fw->size / 4; ++i)
1995 le32_to_cpus(&data[i]);
1996}
1997#endif
1998
1999static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
2000{
2001 int err, is_1e;
2002 const char *name;
2003
2004 err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw",
2005 &chip->pci->dev);
2006 if (err >= 0) {
2007 if (chip->dsp_microcode->size == YDSXG_DSPLENGTH)
2008 snd_ymfpci_convert_from_le(chip->dsp_microcode);
2009 else {
2010 snd_printk(KERN_ERR "DSP microcode has wrong size\n");
2011 err = -EINVAL;
2012 }
2013 }
2014 if (err < 0) {
2015#ifdef FIRMWARE_IN_THE_KERNEL
2016 chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
2017#else
2018 return err;
2019#endif
2020 }
2021 is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
2022 chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
2023 chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
2024 chip->device_id == PCI_DEVICE_ID_YAMAHA_754;
2025 name = is_1e ? "yamaha/ds1e_ctrl.fw" : "yamaha/ds1_ctrl.fw";
2026 err = request_firmware(&chip->controller_microcode, name,
2027 &chip->pci->dev);
2028 if (err >= 0) {
2029 if (chip->controller_microcode->size == YDSXG_CTRLLENGTH)
2030 snd_ymfpci_convert_from_le(chip->controller_microcode);
2031 else {
2032 snd_printk(KERN_ERR "controller microcode"
2033 " has wrong size\n");
2034 err = -EINVAL;
2035 }
2036 }
2037 if (err < 0) {
2038#ifdef FIRMWARE_IN_THE_KERNEL
2039 chip->controller_microcode =
2040 is_1e ? &snd_ymfpci_controller_1e_microcode
2041 : &snd_ymfpci_controller_microcode;
2042#else
2043 return err;
2044#endif
2045 }
2046 return 0;
2047}
2048
1976static void snd_ymfpci_download_image(struct snd_ymfpci *chip) 2049static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
1977{ 2050{
1978 int i; 2051 int i;
1979 u16 ctrl; 2052 u16 ctrl;
1980 unsigned long *inst; 2053 u32 *inst;
1981 2054
1982 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000); 2055 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
1983 snd_ymfpci_disable_dsp(chip); 2056 snd_ymfpci_disable_dsp(chip);
@@ -1992,21 +2065,12 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
1992 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); 2065 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
1993 2066
1994 /* setup DSP instruction code */ 2067 /* setup DSP instruction code */
2068 inst = (u32 *)chip->dsp_microcode->data;
1995 for (i = 0; i < YDSXG_DSPLENGTH / 4; i++) 2069 for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
1996 snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]); 2070 snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]);
1997 2071
1998 /* setup control instruction code */ 2072 /* setup control instruction code */
1999 switch (chip->device_id) { 2073 inst = (u32 *)chip->controller_microcode->data;
2000 case PCI_DEVICE_ID_YAMAHA_724F:
2001 case PCI_DEVICE_ID_YAMAHA_740C:
2002 case PCI_DEVICE_ID_YAMAHA_744:
2003 case PCI_DEVICE_ID_YAMAHA_754:
2004 inst = CntrlInst1E;
2005 break;
2006 default:
2007 inst = CntrlInst;
2008 break;
2009 }
2010 for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) 2074 for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
2011 snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]); 2075 snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);
2012 2076
@@ -2160,6 +2224,15 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
2160 pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); 2224 pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
2161 2225
2162 pci_disable_device(chip->pci); 2226 pci_disable_device(chip->pci);
2227#ifdef FIRMWARE_IN_THE_KERNEL
2228 if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode)
2229#endif
2230 release_firmware(chip->dsp_microcode);
2231#ifdef FIRMWARE_IN_THE_KERNEL
2232 if (chip->controller_microcode != &snd_ymfpci_controller_microcode &&
2233 chip->controller_microcode != &snd_ymfpci_controller_1e_microcode)
2234#endif
2235 release_firmware(chip->controller_microcode);
2163 kfree(chip); 2236 kfree(chip);
2164 return 0; 2237 return 0;
2165} 2238}
@@ -2315,6 +2388,12 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
2315 return -EIO; 2388 return -EIO;
2316 } 2389 }
2317 2390
2391 err = snd_ymfpci_request_firmware(chip);
2392 if (err < 0) {
2393 snd_printk(KERN_ERR "firmware request failed: %d\n", err);
2394 snd_ymfpci_free(chip);
2395 return err;
2396 }
2318 snd_ymfpci_download_image(chip); 2397 snd_ymfpci_download_image(chip);
2319 2398
2320 udelay(100); /* seems we need a delay after downloading image.. */ 2399 udelay(100); /* seems we need a delay after downloading image.. */