summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/Kconfig11
-rw-r--r--sound/firewire/Makefile1
-rw-r--r--sound/firewire/tascam/Makefile2
-rw-r--r--sound/firewire/tascam/tascam.c155
-rw-r--r--sound/firewire/tascam/tascam.h33
5 files changed, 202 insertions, 0 deletions
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index e61445e2ceaa..bb3f2610c6e9 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -135,4 +135,15 @@ config SND_FIREWIRE_DIGI00X
 	 To compile this driver as a module, choose M here: the module
 	 will be called snd-firewire-digi00x.
 
+config SND_FIREWIRE_TASCAM
+	tristate "TASCAM FireWire series support"
+	select SND_FIREWIRE_LIB
+	help
+	 Say Y here to include support for TASCAM.
+	  * FW-1884
+	  * FW-1082
+
+	 To compile this driver as a module, choose M here: the module
+	 will be called snd-firewire-tascam.
+
 endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 5325d15d7018..6ae50f50db62 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o
 obj-$(CONFIG_SND_FIREWORKS) += fireworks/
 obj-$(CONFIG_SND_BEBOB) += bebob/
 obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/
+obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/
diff --git a/sound/firewire/tascam/Makefile b/sound/firewire/tascam/Makefile
new file mode 100644
index 000000000000..627129b98a5c
--- /dev/null
+++ b/sound/firewire/tascam/Makefile
@@ -0,0 +1,2 @@
+snd-firewire-tascam-objs := tascam.o
+obj-$(CONFIG_SND_FIREWIRE_TASCAM) += snd-firewire-tascam.o
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
new file mode 100644
index 000000000000..9f2d2a33f58a
--- /dev/null
+++ b/sound/firewire/tascam/tascam.c
@@ -0,0 +1,155 @@
+/*
+ * tascam.c - a part of driver for TASCAM FireWire series
+ *
+ * Copyright (c) 2015 Takashi Sakamoto
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include "tascam.h"
+
+MODULE_DESCRIPTION("TASCAM FireWire series Driver");
+MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
+MODULE_LICENSE("GPL v2");
+
+static int check_name(struct snd_tscm *tscm)
+{
+	struct fw_device *fw_dev = fw_parent_device(tscm->unit);
+	char vendor[8];
+	char model[8];
+	__u32 data;
+
+	/* Retrieve model name. */
+	data = be32_to_cpu(fw_dev->config_rom[28]);
+	memcpy(model, &data, 4);
+	data = be32_to_cpu(fw_dev->config_rom[29]);
+	memcpy(model + 4, &data, 4);
+	model[7] = '\0';
+
+	/* Retrieve vendor name. */
+	data = be32_to_cpu(fw_dev->config_rom[23]);
+	memcpy(vendor, &data, 4);
+	data = be32_to_cpu(fw_dev->config_rom[24]);
+	memcpy(vendor + 4, &data, 4);
+	vendor[7] = '\0';
+
+	strcpy(tscm->card->driver, "FW-TASCAM");
+	strcpy(tscm->card->shortname, model);
+	strcpy(tscm->card->mixername, model);
+	snprintf(tscm->card->longname, sizeof(tscm->card->longname),
+		 "%s %s, GUID %08x%08x at %s, S%d", vendor, model,
+		 cpu_to_be32(fw_dev->config_rom[3]),
+		 cpu_to_be32(fw_dev->config_rom[4]),
+		 dev_name(&tscm->unit->device), 100 << fw_dev->max_speed);
+
+	return 0;
+}
+
+static void tscm_card_free(struct snd_card *card)
+{
+	struct snd_tscm *tscm = card->private_data;
+
+	fw_unit_put(tscm->unit);
+
+	mutex_destroy(&tscm->mutex);
+}
+
+static int snd_tscm_probe(struct fw_unit *unit,
+			   const struct ieee1394_device_id *entry)
+{
+	struct snd_card *card;
+	struct snd_tscm *tscm;
+	int err;
+
+	/* create card */
+	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
+			   sizeof(struct snd_tscm), &card);
+	if (err < 0)
+		return err;
+	card->private_free = tscm_card_free;
+
+	/* initialize myself */
+	tscm = card->private_data;
+	tscm->card = card;
+	tscm->unit = fw_unit_get(unit);
+
+	mutex_init(&tscm->mutex);
+
+	err = check_name(tscm);
+	if (err < 0)
+		goto error;
+
+	err = snd_card_register(card);
+	if (err < 0)
+		goto error;
+
+	dev_set_drvdata(&unit->device, tscm);
+
+	return err;
+error:
+	snd_card_free(card);
+	return err;
+}
+
+static void snd_tscm_update(struct fw_unit *unit)
+{
+	return;
+}
+
+static void snd_tscm_remove(struct fw_unit *unit)
+{
+	struct snd_tscm *tscm = dev_get_drvdata(&unit->device);
+
+	/* No need to wait for releasing card object in this context. */
+	snd_card_free_when_closed(tscm->card);
+}
+
+static const struct ieee1394_device_id snd_tscm_id_table[] = {
+	/* FW-1082 */
+	{
+		.match_flags = IEEE1394_MATCH_VENDOR_ID |
+			       IEEE1394_MATCH_SPECIFIER_ID |
+			       IEEE1394_MATCH_VERSION,
+		.vendor_id = 0x00022e,
+		.specifier_id = 0x00022e,
+		.version = 0x800003,
+	},
+	/* FW-1884 */
+	{
+		.match_flags = IEEE1394_MATCH_VENDOR_ID |
+			       IEEE1394_MATCH_SPECIFIER_ID |
+			       IEEE1394_MATCH_VERSION,
+		.vendor_id = 0x00022e,
+		.specifier_id = 0x00022e,
+		.version = 0x800000,
+	},
+	/* FW-1804 mey be supported if IDs are clear. */
+	/* FE-08 requires reverse-engineering because it just has faders. */
+	{}
+};
+MODULE_DEVICE_TABLE(ieee1394, snd_tscm_id_table);
+
+static struct fw_driver tscm_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "snd-firewire-tascam",
+		.bus = &fw_bus_type,
+	},
+	.probe    = snd_tscm_probe,
+	.update   = snd_tscm_update,
+	.remove   = snd_tscm_remove,
+	.id_table = snd_tscm_id_table,
+};
+
+static int __init snd_tscm_init(void)
+{
+	return driver_register(&tscm_driver.driver);
+}
+
+static void __exit snd_tscm_exit(void)
+{
+	driver_unregister(&tscm_driver.driver);
+}
+
+module_init(snd_tscm_init);
+module_exit(snd_tscm_exit);
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
new file mode 100644
index 000000000000..d2f4f67cf636
--- /dev/null
+++ b/sound/firewire/tascam/tascam.h
@@ -0,0 +1,33 @@
+/*
+ * tascam.h - a part of driver for TASCAM FireWire series
+ *
+ * Copyright (c) 2015 Takashi Sakamoto
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#ifndef SOUND_TASCAM_H_INCLUDED
+#define SOUND_TASCAM_H_INCLUDED
+
+#include <linux/device.h>
+#include <linux/firewire.h>
+#include <linux/firewire-constants.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/compat.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+#include "../lib.h"
+
+struct snd_tscm {
+	struct snd_card *card;
+	struct fw_unit *unit;
+
+	struct mutex mutex;
+};
+
+#endif