]> git.alsa-project.org Git - alsa-tools.git/commitdiff
added mixartloader
authorTakashi Iwai <tiwai@suse.de>
Tue, 22 Jul 2003 13:42:50 +0000 (13:42 +0000)
committerTakashi Iwai <tiwai@suse.de>
Tue, 22 Jul 2003 13:42:50 +0000 (13:42 +0000)
Makefile
mixartloader/Makefile.am [new file with mode: 0644]
mixartloader/README [new file with mode: 0644]
mixartloader/configure.in [new file with mode: 0644]
mixartloader/cvscompile [new file with mode: 0644]
mixartloader/firmware/Makefile.am [new file with mode: 0644]
mixartloader/firmware/miXart8.elf [new file with mode: 0644]
mixartloader/firmware/miXart8.xlx [new file with mode: 0644]
mixartloader/firmware/miXart8AES.xlx [new file with mode: 0644]
mixartloader/mixartloader.c [new file with mode: 0644]

index 2f4067113d446764b28dbc8018c7dbb6d2b447e6..34f1186cf2fb7e2688e24e3af8573a7465ceb9d7 100644 (file)
--- 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 (file)
index 0000000..0221949
--- /dev/null
@@ -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 (file)
index 0000000..2571549
--- /dev/null
@@ -0,0 +1,54 @@
+    mixartloader - Firmware loader for Digigram miXart soundcards
+           Digigram <alsa@digigram.com>
+
+
+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 <alsa@digigram.com>
+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 (file)
index 0000000..6e288ff
--- /dev/null
@@ -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 (file)
index 0000000..5daa701
--- /dev/null
@@ -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 (file)
index 0000000..c1a25ea
--- /dev/null
@@ -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 (file)
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 (file)
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 (file)
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 (file)
index 0000000..663ca32
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Firmware Loaderfor Digigram miXart soundcards
+ *
+ * Copyright (c) 2003 by Digigram <alsa@digigram.com>
+ *
+ *   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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdarg.h>
+#include <alsa/asoundlib.h>
+
+
+#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;
+}