From: Takashi Iwai Date: Tue, 22 Jul 2003 13:42:50 +0000 (+0000) Subject: added mixartloader X-Git-Tag: v1.0.3~66 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=c6b79b46893da0907e73b8da4ea4bd9ad4eb85d6;p=alsa-tools.git added mixartloader --- diff --git a/Makefile b/Makefile index 2f40671..34f1186 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -VERSION = 0.9.5 +VERSION = 0.9.6 TOP = . SUBDIRS = ac3dec as10k1 envy24control hdsploader hdspconf \ - rmedigicontrol sb16_csp seq sscape_ctl vxloader + mixartloader rmedigicontrol sb16_csp seq sscape_ctl vxloader all: @for i in $(SUBDIRS); do cd $(TOP)/$$i; ./cvscompile; cd ..; make -C $$i; done @@ -11,7 +11,7 @@ alsa-dist: @mkdir -p $(TOP)/distdir @for i in $(SUBDIRS); do cd $(TOP)/$$i; ./cvscompile; cd ..; make -C $$i alsa-dist; done @mv distdir alsa-tools-$(VERSION) - @tar cIf alsa-tools-$(VERSION).tar.bz2 alsa-tools-$(VERSION) + @tar cjf alsa-tools-$(VERSION).tar.bz2 alsa-tools-$(VERSION) @mv alsa-tools-$(VERSION) distdir clean: diff --git a/mixartloader/Makefile.am b/mixartloader/Makefile.am new file mode 100644 index 0000000..0221949 --- /dev/null +++ b/mixartloader/Makefile.am @@ -0,0 +1,18 @@ +# # Process this file with automake to produce Makefile.in. +AUTOMAKE_OPTIONS = 1.3 foreign + +AM_CFLAGS = -DDATAPATH=\"$(datadir)/alsa/firmware\" + +SUBDIRS = firmware + +bin_PROGRAMS = mixartloader + +mixartloader_SOURCES = mixartloader.c + +EXTRA_DIST = depcomp + +alsa-dist: distdir + @rm -rf ../distdir/mixartloader + @mkdir -p ../distdir/mixartloader + @cp -RLpv $(distdir)/* ../distdir/mixartloader + @rm -rf $(distdir) diff --git a/mixartloader/README b/mixartloader/README new file mode 100644 index 0000000..2571549 --- /dev/null +++ b/mixartloader/README @@ -0,0 +1,54 @@ + mixartloader - Firmware loader for Digigram miXart soundcards + Digigram + + +GENERAL +======= + +mixartloader is a helper program to load the firmware binaries +onto the Digigram's miXart board sound drivers. +The following modules require this program: + snd-mixart +These drivers don't work properly at all until the certain firmwares +are loaded, i.e. no PCM nor mixer devices will appear. + + +USAGE +===== + +When mixartloader is invoked without options, it will probe all existing +soundcards until a valid miXart-driver is found. If a valid miXart-driver is +found, mixartloader reads the board type from the driver. The corresponding +firmware binaries are then read and transferred to the driver. +Finally, mixartloader initializes the PCM and the mixer devices on the +driver for making the soundcard full functional. + +Instead of auto-probing, you can specify the card number or the hwdep +device name via -c and -D options, respectively. + + % mixartloader -c 1 + % mixartloader -D hw:0 + +For loading the firmware automatically after the module is loaded, use +the post-install command. For example, add the following entry to +/etc/modules.conf for miXart driver: + + post-install snd-mixart /usr/bin/mixartloader + +FILES +===== + +The firmware binaries are installed on /usr/share/alsa/firmware +(or /usr/local/share/alsa/firmware, depending to the prefix option of +configure). There will be *.conf files, which define the dsp image +files for each different card type. + + +COPYRIGHT +========= + +Copyright (c) 2003 Digigram SA +Distributalbe under GPL. + +The firmware files included in firmware sub-directory are copyright +by Digigram SA diff --git a/mixartloader/configure.in b/mixartloader/configure.in new file mode 100644 index 0000000..6e288ff --- /dev/null +++ b/mixartloader/configure.in @@ -0,0 +1,11 @@ +AC_INIT(mixartloader.c) +AM_INIT_AUTOMAKE(mixartloader, 1.0) +AC_PROG_CC +AC_PROG_INSTALL +AC_HEADER_STDC +AM_PATH_ALSA(0.9.2) + +CFLAGS="$CFLAGS $ALSA_CFLAGS" +LDFLAGS="$LDFLAGS $ALSA_LIBS" + +AC_OUTPUT(Makefile firmware/Makefile) diff --git a/mixartloader/cvscompile b/mixartloader/cvscompile new file mode 100644 index 0000000..5daa701 --- /dev/null +++ b/mixartloader/cvscompile @@ -0,0 +1,11 @@ +#!/bin/bash + +aclocal $ACLOCAL_FLAGS +automake --foreign --add-missing +autoconf +export CFLAGS='-O2 -Wall -pipe -g' +echo "CFLAGS=$CFLAGS" +echo "./configure $@" +./configure $@ +unset CFLAGS +make diff --git a/mixartloader/firmware/Makefile.am b/mixartloader/firmware/Makefile.am new file mode 100644 index 0000000..c1a25ea --- /dev/null +++ b/mixartloader/firmware/Makefile.am @@ -0,0 +1,10 @@ +cfg_files = miXart.conf \ + miXart8AES.xlx \ + miXart8.elf \ + miXart8.xlx + +EXTRA_DIST = $(cfg_files) + +firmwaredir = $(datadir)/alsa/firmware +firmware_DATA = $(cfg_files) + diff --git a/mixartloader/firmware/miXart8.elf b/mixartloader/firmware/miXart8.elf new file mode 100644 index 0000000..ca5515c Binary files /dev/null and b/mixartloader/firmware/miXart8.elf differ diff --git a/mixartloader/firmware/miXart8.xlx b/mixartloader/firmware/miXart8.xlx new file mode 100644 index 0000000..95dee08 Binary files /dev/null and b/mixartloader/firmware/miXart8.xlx differ diff --git a/mixartloader/firmware/miXart8AES.xlx b/mixartloader/firmware/miXart8AES.xlx new file mode 100644 index 0000000..b233438 Binary files /dev/null and b/mixartloader/firmware/miXart8AES.xlx differ diff --git a/mixartloader/mixartloader.c b/mixartloader/mixartloader.c new file mode 100644 index 0000000..663ca32 --- /dev/null +++ b/mixartloader/mixartloader.c @@ -0,0 +1,288 @@ +/* + * Firmware Loaderfor Digigram miXart soundcards + * + * Copyright (c) 2003 by Digigram + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PROGNAME "mixartloader" + + +/* max. number of cards (shouldn't be in the public header?) */ +#define SND_CARDS 8 + + +static int verbose = 0; + +static void usage(void) +{ + printf("Boot loader for Digigram miXart cards\n"); + printf("version %s\n", VERSION); + printf("usage: mixartloader [-c card] [-D device]\n"); +} + +static void error(const char *fmt, ...) +{ + if (verbose) { + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s: ", PROGNAME); + vfprintf(stderr, fmt, ap); + va_end(ap); + } +} + +/* + * parse the index file and get the file to read from the key + */ + +#define MAX_PATH 128 + +static int get_file_name(const char *key, unsigned int idx, char *fname) +{ + FILE *fp; + char buf[128]; + char temp[32], *p; + int len; + + snprintf(buf, sizeof(buf), "%s/%s.conf", DATAPATH, key); + if ((fp = fopen(buf, "r")) == NULL) { + error("cannot open the index file %s\n", buf); + return -ENODEV; + } + + sprintf(temp, "dsp%d", idx); + len = strlen(temp); + + while (fgets(buf, sizeof(buf), fp)) { + if (strncmp(buf, temp, len)) + continue; + for (p = buf + len; *p && isspace(*p); p++) + ; + if (*p == '/') { + strncpy(fname, p, MAX_PATH); + } else { + snprintf(fname, MAX_PATH, "%s/%s", DATAPATH, p); + } + fname[MAX_PATH-1] = 0; + /* chop the last linefeed */ + for (p = fname; *p && *p != '\n'; p++) + ; + *p = 0; + fclose(fp); + return 0; + } + fclose(fp); + error("cannot find the file entry for %s\n", temp); + return -ENODEV; +} + + +/* + * read and transfer the firmware binary + */ +static int load_firmware(snd_hwdep_t *hw, const char *id, unsigned int idx) +{ + int err; + char fname[MAX_PATH]; + snd_hwdep_dsp_image_t *dsp; + struct stat st; + int fd, length; + unsigned char *imgbuf; + + if (get_file_name(id, idx, fname) < 0) + return -EINVAL; + + snd_hwdep_dsp_image_alloca(&dsp); + + snd_hwdep_dsp_image_set_name(dsp, fname); + if (stat(fname, &st) < 0) { + error("cannot call stat %s\n", fname); + return -ENODEV; + } + + length = st.st_size; + if (length == 0) { + error("zero file size %s\n", fname); + return -EINVAL; + } + + imgbuf = malloc(st.st_size); + if (! imgbuf) { + error("cannot malloc %d bytes\n", length); + return -ENOMEM; + } + snd_hwdep_dsp_image_set_length(dsp, length); + snd_hwdep_dsp_image_set_image(dsp, imgbuf); + + fd = open(fname, O_RDONLY); + if (fd < 0) { + error("cannot open %s\n", fname); + return -ENODEV; + } + if (read(fd, imgbuf, length) != length) { + error("cannot read %d bytes from %s\n", length, fname); + close(fd); + return -EINVAL; + } + + close(fd); + + snd_hwdep_dsp_image_set_index(dsp, idx); + + err = snd_hwdep_dsp_load(hw, dsp); + if (err < 0) + error("error in loading %s\n", fname); + + printf("%s loaded (%d bytes).\n",fname,length); + return err; +} + + +/* + * check the name id of the given hwdep handle + */ +static int check_hwinfo(snd_hwdep_t *hw, const char *id) +{ + snd_hwdep_info_t *info; + int err; + + snd_hwdep_info_alloca(&info); + if ((err = snd_hwdep_info(hw, info)) < 0) + return err; + if (strcmp(snd_hwdep_info_get_id(info), id)) + return -ENODEV; + return 0; /* ok */ +} + +/* + * load the firmware binaries + */ +static int miXart_boot(const char *devname) +{ + snd_hwdep_t *hw; + const char *id; + int err; + unsigned int idx, dsps, loaded; + snd_hwdep_dsp_status_t *stat; + + if ((err = snd_hwdep_open(&hw, devname, O_RDWR)) < 0) { + error("cannot open hwdep %s\n", devname); + return err; + } + + /* check hwdep ID string */ + if (check_hwinfo(hw, "miXart Loader") < 0) { + error("invalid hwdep ID string %s\n", devname); + snd_hwdep_close(hw); + return -ENODEV; + } + + snd_hwdep_dsp_status_alloca(&stat); + /* get the current status (number of files to load = 3)*/ + if ((err = snd_hwdep_dsp_status(hw, stat)) < 0) { + printf("cannot get version for %s\n", devname); + snd_hwdep_close(hw); + return err; + } + + if (snd_hwdep_dsp_status_get_chip_ready(stat)) + { + printf("nothing to do for device %s.\n", devname); + return 0; /* already loaded */ + } + + /* get "miXart" string */ + id = snd_hwdep_dsp_status_get_id(stat); + dsps = snd_hwdep_dsp_status_get_num_dsps(stat); + loaded = snd_hwdep_dsp_status_get_dsp_loaded(stat); + + for (idx = 0; idx < dsps; idx++) { + if (loaded & (1 << idx)) + { + printf("%d already loaded (loaded = %d).\n", idx, loaded); + continue; + } + if ((err = load_firmware(hw, id, idx)) < 0) { + snd_hwdep_close(hw); + return err; + } + } + + snd_hwdep_close(hw); + return 0; +} + + +int main(int argc, char **argv) +{ + int c; + int card = -1; + char *device_name = NULL; + char name[64]; + + while ((c = getopt(argc, argv, "c:D:")) != -1) { + switch (c) { + case 'c': + card = atoi(optarg); + break; + case 'D': + device_name = optarg; + break; + default: + usage(); + return 1; + } + } + + if (device_name) { + verbose = 1; + return miXart_boot(device_name) != 0; + } + if (card >= 0) { + sprintf(name, "hw:%d", card); + verbose = 1; + return miXart_boot(name) != 0; + } + + /* probe the all cards */ + for (c = 0; c < SND_CARDS; c++) { + sprintf(name, "hw:%d", c); + if (! miXart_boot(name)) + card = c; + } + if (card < 0) { + fprintf(stderr, PROGNAME ": no miXart-compatible card found\n"); + return 1; + } + return 0; +}