summaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/oxfw/Makefile4
-rw-r--r--sound/firewire/oxfw/oxfw-spkr.c (renamed from sound/firewire/oxfw/oxfw-control.c)80
-rw-r--r--sound/firewire/oxfw/oxfw.c59
-rw-r--r--sound/firewire/oxfw/oxfw.h6
4 files changed, 86 insertions, 63 deletions
diff --git a/sound/firewire/oxfw/Makefile b/sound/firewire/oxfw/Makefile
index 06ff50f4e6c0..4e54ba9f4394 100644
--- a/sound/firewire/oxfw/Makefile
+++ b/sound/firewire/oxfw/Makefile
@@ -1,3 +1,3 @@
-snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-control.o oxfw-pcm.o \
- oxfw-proc.o oxfw-midi.o oxfw-hwdep.o oxfw.o
+snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-pcm.o oxfw-proc.o \
+ oxfw-midi.o oxfw-hwdep.o oxfw-spkr.o oxfw.o
obj-$(CONFIG_SND_OXFW) += snd-oxfw.o
diff --git a/sound/firewire/oxfw/oxfw-control.c b/sound/firewire/oxfw/oxfw-spkr.c
index 02a1cb90f20d..d733a15cdec7 100644
--- a/sound/firewire/oxfw/oxfw-control.c
+++ b/sound/firewire/oxfw/oxfw-spkr.c
@@ -1,5 +1,5 @@
/*
- * oxfw_stream.c - a part of driver for OXFW970/971 based devices
+ * oxfw-spkr.c - a part of driver for OXFW970/971 based devices
*
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
* Licensed under the terms of the GNU General Public License, version 2.
@@ -14,8 +14,8 @@ enum control_attribute {
CTL_CURRENT = 0x10,
};
-static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
- enum control_action action)
+static int avc_audio_feature_mute(struct fw_unit *unit, u8 fb_id, bool *value,
+ enum control_action action)
{
u8 *buf;
u8 response_ok;
@@ -35,7 +35,7 @@ static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
buf[1] = 0x08; /* audio unit 0 */
buf[2] = 0xb8; /* FUNCTION BLOCK */
buf[3] = 0x81; /* function block type: feature */
- buf[4] = oxfw->device_info->mute_fb_id; /* function block ID */
+ buf[4] = fb_id; /* function block ID */
buf[5] = 0x10; /* control attribute: current */
buf[6] = 0x02; /* selector length */
buf[7] = 0x00; /* audio channel number */
@@ -46,16 +46,16 @@ static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
else
buf[10] = *value ? 0x70 : 0x60;
- err = fcp_avc_transaction(oxfw->unit, buf, 11, buf, 11, 0x3fe);
+ err = fcp_avc_transaction(unit, buf, 11, buf, 11, 0x3fe);
if (err < 0)
goto error;
if (err < 11) {
- dev_err(&oxfw->unit->device, "short FCP response\n");
+ dev_err(&unit->device, "short FCP response\n");
err = -EIO;
goto error;
}
if (buf[0] != response_ok) {
- dev_err(&oxfw->unit->device, "mute command failed\n");
+ dev_err(&unit->device, "mute command failed\n");
err = -EIO;
goto error;
}
@@ -70,10 +70,10 @@ error:
return err;
}
-static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
- unsigned int channel,
- enum control_attribute attribute,
- enum control_action action)
+static int avc_audio_feature_volume(struct fw_unit *unit, u8 fb_id, s16 *value,
+ unsigned int channel,
+ enum control_attribute attribute,
+ enum control_action action)
{
u8 *buf;
u8 response_ok;
@@ -93,7 +93,7 @@ static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
buf[1] = 0x08; /* audio unit 0 */
buf[2] = 0xb8; /* FUNCTION BLOCK */
buf[3] = 0x81; /* function block type: feature */
- buf[4] = oxfw->device_info->volume_fb_id; /* function block ID */
+ buf[4] = fb_id; /* function block ID */
buf[5] = attribute; /* control attribute */
buf[6] = 0x02; /* selector length */
buf[7] = channel; /* audio channel number */
@@ -107,16 +107,16 @@ static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
buf[11] = *value;
}
- err = fcp_avc_transaction(oxfw->unit, buf, 12, buf, 12, 0x3fe);
+ err = fcp_avc_transaction(unit, buf, 12, buf, 12, 0x3fe);
if (err < 0)
goto error;
if (err < 12) {
- dev_err(&oxfw->unit->device, "short FCP response\n");
+ dev_err(&unit->device, "short FCP response\n");
err = -EIO;
goto error;
}
if (buf[0] != response_ok) {
- dev_err(&oxfw->unit->device, "volume command failed\n");
+ dev_err(&unit->device, "volume command failed\n");
err = -EIO;
goto error;
}
@@ -131,7 +131,7 @@ error:
return err;
}
-static int oxfw_mute_get(struct snd_kcontrol *control,
+static int spkr_mute_get(struct snd_kcontrol *control,
struct snd_ctl_elem_value *value)
{
struct snd_oxfw *oxfw = control->private_data;
@@ -141,7 +141,7 @@ static int oxfw_mute_get(struct snd_kcontrol *control,
return 0;
}
-static int oxfw_mute_put(struct snd_kcontrol *control,
+static int spkr_mute_put(struct snd_kcontrol *control,
struct snd_ctl_elem_value *value)
{
struct snd_oxfw *oxfw = control->private_data;
@@ -153,7 +153,8 @@ static int oxfw_mute_put(struct snd_kcontrol *control,
if (mute == oxfw->mute)
return 0;
- err = oxfw_mute_command(oxfw, &mute, CTL_WRITE);
+ err = avc_audio_feature_mute(oxfw->unit, oxfw->device_info->mute_fb_id,
+ &mute, CTL_WRITE);
if (err < 0)
return err;
oxfw->mute = mute;
@@ -161,7 +162,7 @@ static int oxfw_mute_put(struct snd_kcontrol *control,
return 1;
}
-static int oxfw_volume_info(struct snd_kcontrol *control,
+static int spkr_volume_info(struct snd_kcontrol *control,
struct snd_ctl_elem_info *info)
{
struct snd_oxfw *oxfw = control->private_data;
@@ -176,7 +177,7 @@ static int oxfw_volume_info(struct snd_kcontrol *control,
static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
-static int oxfw_volume_get(struct snd_kcontrol *control,
+static int spkr_volume_get(struct snd_kcontrol *control,
struct snd_ctl_elem_value *value)
{
struct snd_oxfw *oxfw = control->private_data;
@@ -188,7 +189,7 @@ static int oxfw_volume_get(struct snd_kcontrol *control,
return 0;
}
-static int oxfw_volume_put(struct snd_kcontrol *control,
+static int spkr_volume_put(struct snd_kcontrol *control,
struct snd_ctl_elem_value *value)
{
struct snd_oxfw *oxfw = control->private_data;
@@ -218,8 +219,10 @@ static int oxfw_volume_put(struct snd_kcontrol *control,
for (i = 0; i <= oxfw->device_info->mixer_channels; ++i) {
volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
if (changed_channels & (1 << i)) {
- err = oxfw_volume_command(oxfw, &volume, i,
- CTL_CURRENT, CTL_WRITE);
+ err = avc_audio_feature_volume(oxfw->unit,
+ oxfw->device_info->mute_fb_id,
+ &volume,
+ i, CTL_CURRENT, CTL_WRITE);
if (err < 0)
return err;
}
@@ -230,44 +233,49 @@ static int oxfw_volume_put(struct snd_kcontrol *control,
return changed_channels != 0;
}
-int snd_oxfw_create_mixer(struct snd_oxfw *oxfw)
+int snd_oxfw_add_spkr(struct snd_oxfw *oxfw)
{
static const struct snd_kcontrol_new controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Switch",
.info = snd_ctl_boolean_mono_info,
- .get = oxfw_mute_get,
- .put = oxfw_mute_put,
+ .get = spkr_mute_get,
+ .put = spkr_mute_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Volume",
- .info = oxfw_volume_info,
- .get = oxfw_volume_get,
- .put = oxfw_volume_put,
+ .info = spkr_volume_info,
+ .get = spkr_volume_get,
+ .put = spkr_volume_put,
},
};
unsigned int i, first_ch;
int err;
- err = oxfw_volume_command(oxfw, &oxfw->volume_min,
- 0, CTL_MIN, CTL_READ);
+ err = avc_audio_feature_volume(oxfw->unit,
+ oxfw->device_info->volume_fb_id,
+ &oxfw->volume_min, 0, CTL_MIN, CTL_READ);
if (err < 0)
return err;
- err = oxfw_volume_command(oxfw, &oxfw->volume_max,
- 0, CTL_MAX, CTL_READ);
+ err = avc_audio_feature_volume(oxfw->unit,
+ oxfw->device_info->volume_fb_id,
+ &oxfw->volume_max, 0, CTL_MAX, CTL_READ);
if (err < 0)
return err;
- err = oxfw_mute_command(oxfw, &oxfw->mute, CTL_READ);
+ err = avc_audio_feature_mute(oxfw->unit, oxfw->device_info->mute_fb_id,
+ &oxfw->mute, CTL_READ);
if (err < 0)
return err;
first_ch = oxfw->device_info->mixer_channels == 1 ? 0 : 1;
for (i = 0; i < oxfw->device_info->mixer_channels; ++i) {
- err = oxfw_volume_command(oxfw, &oxfw->volume[i],
- first_ch + i, CTL_CURRENT, CTL_READ);
+ err = avc_audio_feature_volume(oxfw->unit,
+ oxfw->device_info->volume_fb_id,
+ &oxfw->volume[i],
+ first_ch + i, CTL_CURRENT, CTL_READ);
if (err < 0)
return err;
}
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 588b93f20c2e..d4fb3c10163a 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -59,6 +59,7 @@ static bool detect_loud_models(struct fw_unit *unit)
static int name_card(struct snd_oxfw *oxfw)
{
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
+ const struct device_info *info;
char vendor[24];
char model[32];
const char *d, *v, *m;
@@ -84,10 +85,12 @@ static int name_card(struct snd_oxfw *oxfw)
be32_to_cpus(&firmware);
/* to apply card definitions */
- if (oxfw->device_info) {
- d = oxfw->device_info->driver_name;
- v = oxfw->device_info->vendor_name;
- m = oxfw->device_info->model_name;
+ if (oxfw->entry->vendor_id == VENDOR_GRIFFIN ||
+ oxfw->entry->vendor_id == VENDOR_LACIE) {
+ info = (const struct device_info *)oxfw->entry->driver_data;
+ d = info->driver_name;
+ v = info->vendor_name;
+ m = info->model_name;
} else {
d = "OXFW";
v = vendor;
@@ -132,13 +135,34 @@ static void oxfw_card_free(struct snd_card *card)
mutex_destroy(&oxfw->mutex);
}
-static void detect_quirks(struct snd_oxfw *oxfw)
+static int detect_quirks(struct snd_oxfw *oxfw)
{
struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
struct fw_csr_iterator it;
int key, val;
int vendor, model;
+ /*
+ * Add ALSA control elements for two models to keep compatibility to
+ * old firewire-speaker module.
+ */
+ if (oxfw->entry->vendor_id == VENDOR_GRIFFIN ||
+ oxfw->entry->vendor_id == VENDOR_LACIE) {
+ oxfw->device_info =
+ (const struct device_info *)oxfw->entry->driver_data;
+ return snd_oxfw_add_spkr(oxfw);
+ }
+
+ /*
+ * TASCAM FireOne has physical control and requires a pair of additional
+ * MIDI ports.
+ */
+ if (oxfw->entry->vendor_id == VENDOR_TASCAM) {
+ oxfw->midi_input_ports++;
+ oxfw->midi_output_ports++;
+ return 0;
+ }
+
/* Seek from Root Directory of Config ROM. */
vendor = model = 0;
fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
@@ -156,24 +180,17 @@ static void detect_quirks(struct snd_oxfw *oxfw)
if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
oxfw->wrong_dbs = true;
- /*
- * TASCAM FireOne has physical control and requires a pair of additional
- * MIDI ports.
- */
- if (vendor == VENDOR_TASCAM) {
- oxfw->midi_input_ports++;
- oxfw->midi_output_ports++;
- }
+ return 0;
}
static int oxfw_probe(struct fw_unit *unit,
- const struct ieee1394_device_id *id)
+ const struct ieee1394_device_id *entry)
{
struct snd_card *card;
struct snd_oxfw *oxfw;
int err;
- if ((id->vendor_id == VENDOR_LOUD) && !detect_loud_models(unit))
+ if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit))
return -ENODEV;
err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
@@ -186,7 +203,7 @@ static int oxfw_probe(struct fw_unit *unit,
oxfw->card = card;
mutex_init(&oxfw->mutex);
oxfw->unit = fw_unit_get(unit);
- oxfw->device_info = (const struct device_info *)id->driver_data;
+ oxfw->entry = entry;
spin_lock_init(&oxfw->lock);
init_waitqueue_head(&oxfw->hwdep_wait);
@@ -194,7 +211,9 @@ static int oxfw_probe(struct fw_unit *unit,
if (err < 0)
goto error;
- detect_quirks(oxfw);
+ err = detect_quirks(oxfw);
+ if (err < 0)
+ goto error;
err = name_card(oxfw);
if (err < 0)
@@ -204,12 +223,6 @@ static int oxfw_probe(struct fw_unit *unit,
if (err < 0)
goto error;
- if (oxfw->device_info) {
- err = snd_oxfw_create_mixer(oxfw);
- if (err < 0)
- goto error;
- }
-
snd_oxfw_proc_init(oxfw);
err = snd_oxfw_create_midi(oxfw);
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index 8392c424ad1d..f3e14fff4ba0 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -72,6 +72,8 @@ struct snd_oxfw {
int dev_lock_count;
bool dev_lock_changed;
wait_queue_head_t hwdep_wait;
+
+ const struct ieee1394_device_id *entry;
};
/*
@@ -138,10 +140,10 @@ void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw);
int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);
-int snd_oxfw_create_mixer(struct snd_oxfw *oxfw);
-
void snd_oxfw_proc_init(struct snd_oxfw *oxfw);
int snd_oxfw_create_midi(struct snd_oxfw *oxfw);
int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw);
+
+int snd_oxfw_add_spkr(struct snd_oxfw *oxfw);