ALSA: oxfw: Split PCM functionality to a new file
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 28 Nov 2014 15:59:28 +0000 (00:59 +0900)
committerTakashi Iwai <tiwai@suse.de>
Sat, 29 Nov 2014 19:22:22 +0000 (20:22 +0100)
This is a help for works in followed patches.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/oxfw/Makefile
sound/firewire/oxfw/oxfw-pcm.c [new file with mode: 0644]
sound/firewire/oxfw/oxfw.c
sound/firewire/oxfw/oxfw.h

index e15c4c07b49df06aa4e4cb3ca942a655d481c311..7fb4d09a5f07274a039c90160bbcf286f73dd981 100644 (file)
@@ -1,2 +1,2 @@
-snd-oxfw-objs := oxfw-stream.o oxfw.o
+snd-oxfw-objs := oxfw-stream.o oxfw-pcm.o oxfw.o
 obj-m += snd-oxfw.o
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
new file mode 100644 (file)
index 0000000..d39f17a
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * oxfw_pcm.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.
+ */
+
+#include "oxfw.h"
+
+static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
+                                   struct snd_pcm_hw_rule *rule)
+{
+       static unsigned int stereo_rates[] = { 48000, 96000 };
+       struct snd_interval *channels =
+                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       struct snd_interval *rate =
+                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+
+       /* two channels work only at 48/96 kHz */
+       if (snd_interval_max(channels) < 6)
+               return snd_interval_list(rate, 2, stereo_rates, 0);
+       return 0;
+}
+
+static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
+                                       struct snd_pcm_hw_rule *rule)
+{
+       static const struct snd_interval all_channels = { .min = 6, .max = 6 };
+       struct snd_interval *rate =
+                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval *channels =
+                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+       /* 32/44.1 kHz work only with all six channels */
+       if (snd_interval_max(rate) < 48000)
+               return snd_interval_refine(channels, &all_channels);
+       return 0;
+}
+
+int firewave_constraints(struct snd_pcm_runtime *runtime)
+{
+       static unsigned int channels_list[] = { 2, 6 };
+       static struct snd_pcm_hw_constraint_list channels_list_constraint = {
+               .count = 2,
+               .list = channels_list,
+       };
+       int err;
+
+       runtime->hw.rates = SNDRV_PCM_RATE_32000 |
+                           SNDRV_PCM_RATE_44100 |
+                           SNDRV_PCM_RATE_48000 |
+                           SNDRV_PCM_RATE_96000;
+       runtime->hw.channels_max = 6;
+
+       err = snd_pcm_hw_constraint_list(runtime, 0,
+                                        SNDRV_PCM_HW_PARAM_CHANNELS,
+                                        &channels_list_constraint);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                 firewave_rate_constraint, NULL,
+                                 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                 firewave_channels_constraint, NULL,
+                                 SNDRV_PCM_HW_PARAM_RATE, -1);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
+{
+       runtime->hw.rates = SNDRV_PCM_RATE_32000 |
+                           SNDRV_PCM_RATE_44100 |
+                           SNDRV_PCM_RATE_48000 |
+                           SNDRV_PCM_RATE_88200 |
+                           SNDRV_PCM_RATE_96000;
+
+       return 0;
+}
+
+static int pcm_open(struct snd_pcm_substream *substream)
+{
+       static const struct snd_pcm_hardware hardware = {
+               .info = SNDRV_PCM_INFO_MMAP |
+                       SNDRV_PCM_INFO_MMAP_VALID |
+                       SNDRV_PCM_INFO_BATCH |
+                       SNDRV_PCM_INFO_INTERLEAVED |
+                       SNDRV_PCM_INFO_BLOCK_TRANSFER,
+               .formats = AMDTP_OUT_PCM_FORMAT_BITS,
+               .channels_min = 2,
+               .channels_max = 2,
+               .buffer_bytes_max = 4 * 1024 * 1024,
+               .period_bytes_min = 1,
+               .period_bytes_max = UINT_MAX,
+               .periods_min = 1,
+               .periods_max = UINT_MAX,
+       };
+       struct snd_oxfw *oxfw = substream->private_data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       bool used;
+       int err;
+
+       err = cmp_connection_check_used(&oxfw->in_conn, &used);
+       if ((err < 0) || used)
+               goto end;
+
+       runtime->hw = hardware;
+
+       err = oxfw->device_info->pcm_constraints(runtime);
+       if (err < 0)
+               goto end;
+       err = snd_pcm_limit_hw_rates(runtime);
+       if (err < 0)
+               goto end;
+
+       err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime);
+end:
+       return err;
+}
+
+static int pcm_close(struct snd_pcm_substream *substream)
+{
+       return 0;
+}
+
+static int pcm_hw_params(struct snd_pcm_substream *substream,
+                        struct snd_pcm_hw_params *hw_params)
+{
+       struct snd_oxfw *oxfw = substream->private_data;
+       int err;
+
+       mutex_lock(&oxfw->mutex);
+
+       snd_oxfw_stream_stop_simplex(oxfw);
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               goto error;
+
+       amdtp_stream_set_parameters(&oxfw->rx_stream,
+                                   params_rate(hw_params),
+                                   params_channels(hw_params),
+                                   0);
+
+       amdtp_stream_set_pcm_format(&oxfw->rx_stream,
+                                   params_format(hw_params));
+
+       err = avc_general_set_sig_fmt(oxfw->unit, params_rate(hw_params),
+                                     AVC_GENERAL_PLUG_DIR_IN, 0);
+       if (err < 0) {
+               dev_err(&oxfw->unit->device, "failed to set sample rate\n");
+               goto err_buffer;
+       }
+
+       return 0;
+
+err_buffer:
+       snd_pcm_lib_free_vmalloc_buffer(substream);
+error:
+       mutex_unlock(&oxfw->mutex);
+       return err;
+}
+
+static int pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       struct snd_oxfw *oxfw = substream->private_data;
+
+       mutex_lock(&oxfw->mutex);
+       snd_oxfw_stream_stop_simplex(oxfw);
+       mutex_unlock(&oxfw->mutex);
+
+       return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static int pcm_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_oxfw *oxfw = substream->private_data;
+       int err;
+
+       mutex_lock(&oxfw->mutex);
+
+       snd_oxfw_stream_stop_simplex(oxfw);
+
+       err = snd_oxfw_stream_start_simplex(oxfw);
+       if (err < 0)
+               goto end;
+
+       amdtp_stream_pcm_prepare(&oxfw->rx_stream);
+end:
+       mutex_unlock(&oxfw->mutex);
+       return err;
+}
+
+static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_oxfw *oxfw = substream->private_data;
+       struct snd_pcm_substream *pcm;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               pcm = substream;
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               pcm = NULL;
+               break;
+       default:
+               return -EINVAL;
+       }
+       amdtp_stream_pcm_trigger(&oxfw->rx_stream, pcm);
+       return 0;
+}
+
+static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_oxfw *oxfw = substream->private_data;
+
+       return amdtp_stream_pcm_pointer(&oxfw->rx_stream);
+}
+
+int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
+{
+       static struct snd_pcm_ops ops = {
+               .open      = pcm_open,
+               .close     = pcm_close,
+               .ioctl     = snd_pcm_lib_ioctl,
+               .hw_params = pcm_hw_params,
+               .hw_free   = pcm_hw_free,
+               .prepare   = pcm_prepare,
+               .trigger   = pcm_trigger,
+               .pointer   = pcm_pointer,
+               .page      = snd_pcm_lib_get_vmalloc_page,
+               .mmap      = snd_pcm_lib_mmap_vmalloc,
+       };
+       struct snd_pcm *pcm;
+       int err;
+
+       err = snd_pcm_new(oxfw->card, oxfw->card->driver, 0, 1, 0, &pcm);
+       if (err < 0)
+               return err;
+       pcm->private_data = oxfw;
+       strcpy(pcm->name, oxfw->card->shortname);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
+       return 0;
+}
index 40556677ea07ee1890a4294ec088b21c562d3ec8..24bb6dff23cca59bed9810007367ce6792e318be 100644 (file)
@@ -25,244 +25,6 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("snd-firewire-speakers");
 
-static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
-                                   struct snd_pcm_hw_rule *rule)
-{
-       static unsigned int stereo_rates[] = { 48000, 96000 };
-       struct snd_interval *channels =
-                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-       struct snd_interval *rate =
-                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-
-       /* two channels work only at 48/96 kHz */
-       if (snd_interval_max(channels) < 6)
-               return snd_interval_list(rate, 2, stereo_rates, 0);
-       return 0;
-}
-
-static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
-                                       struct snd_pcm_hw_rule *rule)
-{
-       static const struct snd_interval all_channels = { .min = 6, .max = 6 };
-       struct snd_interval *rate =
-                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-       struct snd_interval *channels =
-                       hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-
-       /* 32/44.1 kHz work only with all six channels */
-       if (snd_interval_max(rate) < 48000)
-               return snd_interval_refine(channels, &all_channels);
-       return 0;
-}
-
-static int firewave_constraints(struct snd_pcm_runtime *runtime)
-{
-       static unsigned int channels_list[] = { 2, 6 };
-       static struct snd_pcm_hw_constraint_list channels_list_constraint = {
-               .count = 2,
-               .list = channels_list,
-       };
-       int err;
-
-       runtime->hw.rates = SNDRV_PCM_RATE_32000 |
-                           SNDRV_PCM_RATE_44100 |
-                           SNDRV_PCM_RATE_48000 |
-                           SNDRV_PCM_RATE_96000;
-       runtime->hw.channels_max = 6;
-
-       err = snd_pcm_hw_constraint_list(runtime, 0,
-                                        SNDRV_PCM_HW_PARAM_CHANNELS,
-                                        &channels_list_constraint);
-       if (err < 0)
-               return err;
-       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                                 firewave_rate_constraint, NULL,
-                                 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-       if (err < 0)
-               return err;
-       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                                 firewave_channels_constraint, NULL,
-                                 SNDRV_PCM_HW_PARAM_RATE, -1);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
-static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
-{
-       runtime->hw.rates = SNDRV_PCM_RATE_32000 |
-                           SNDRV_PCM_RATE_44100 |
-                           SNDRV_PCM_RATE_48000 |
-                           SNDRV_PCM_RATE_88200 |
-                           SNDRV_PCM_RATE_96000;
-
-       return 0;
-}
-
-static int oxfw_open(struct snd_pcm_substream *substream)
-{
-       static const struct snd_pcm_hardware hardware = {
-               .info = SNDRV_PCM_INFO_MMAP |
-                       SNDRV_PCM_INFO_MMAP_VALID |
-                       SNDRV_PCM_INFO_BATCH |
-                       SNDRV_PCM_INFO_INTERLEAVED |
-                       SNDRV_PCM_INFO_BLOCK_TRANSFER,
-               .formats = AMDTP_OUT_PCM_FORMAT_BITS,
-               .channels_min = 2,
-               .channels_max = 2,
-               .buffer_bytes_max = 4 * 1024 * 1024,
-               .period_bytes_min = 1,
-               .period_bytes_max = UINT_MAX,
-               .periods_min = 1,
-               .periods_max = UINT_MAX,
-       };
-       struct snd_oxfw *oxfw = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       int err;
-
-       runtime->hw = hardware;
-
-       err = oxfw->device_info->pcm_constraints(runtime);
-       if (err < 0)
-               return err;
-       err = snd_pcm_limit_hw_rates(runtime);
-       if (err < 0)
-               return err;
-
-       err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
-static int oxfw_close(struct snd_pcm_substream *substream)
-{
-       return 0;
-}
-
-static int oxfw_hw_params(struct snd_pcm_substream *substream,
-                          struct snd_pcm_hw_params *hw_params)
-{
-       struct snd_oxfw *oxfw = substream->private_data;
-       int err;
-
-       mutex_lock(&oxfw->mutex);
-
-       snd_oxfw_stream_stop_simplex(oxfw);
-
-       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                              params_buffer_bytes(hw_params));
-       if (err < 0)
-               goto error;
-
-       amdtp_stream_set_parameters(&oxfw->rx_stream,
-                                   params_rate(hw_params),
-                                   params_channels(hw_params),
-                                   0);
-
-       amdtp_stream_set_pcm_format(&oxfw->rx_stream,
-                                   params_format(hw_params));
-
-       err = avc_general_set_sig_fmt(oxfw->unit, params_rate(hw_params),
-                                     AVC_GENERAL_PLUG_DIR_IN, 0);
-       if (err < 0) {
-               dev_err(&oxfw->unit->device, "failed to set sample rate\n");
-               goto err_buffer;
-       }
-
-       return 0;
-
-err_buffer:
-       snd_pcm_lib_free_vmalloc_buffer(substream);
-error:
-       mutex_unlock(&oxfw->mutex);
-       return err;
-}
-
-static int oxfw_hw_free(struct snd_pcm_substream *substream)
-{
-       struct snd_oxfw *oxfw = substream->private_data;
-
-       mutex_lock(&oxfw->mutex);
-       snd_oxfw_stream_stop_simplex(oxfw);
-       mutex_unlock(&oxfw->mutex);
-
-       return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int oxfw_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_oxfw *oxfw = substream->private_data;
-       int err;
-
-       mutex_lock(&oxfw->mutex);
-
-       snd_oxfw_stream_stop_simplex(oxfw);
-
-       err = snd_oxfw_stream_start_simplex(oxfw);
-       if (err < 0)
-               goto end;
-
-       amdtp_stream_pcm_prepare(&oxfw->rx_stream);
-end:
-       mutex_unlock(&oxfw->mutex);
-       return err;
-}
-
-static int oxfw_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_oxfw *oxfw = substream->private_data;
-       struct snd_pcm_substream *pcm;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               pcm = substream;
-               break;
-       case SNDRV_PCM_TRIGGER_STOP:
-               pcm = NULL;
-               break;
-       default:
-               return -EINVAL;
-       }
-       amdtp_stream_pcm_trigger(&oxfw->rx_stream, pcm);
-       return 0;
-}
-
-static snd_pcm_uframes_t oxfw_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_oxfw *oxfw = substream->private_data;
-
-       return amdtp_stream_pcm_pointer(&oxfw->rx_stream);
-}
-
-static int oxfw_create_pcm(struct snd_oxfw *oxfw)
-{
-       static struct snd_pcm_ops ops = {
-               .open      = oxfw_open,
-               .close     = oxfw_close,
-               .ioctl     = snd_pcm_lib_ioctl,
-               .hw_params = oxfw_hw_params,
-               .hw_free   = oxfw_hw_free,
-               .prepare   = oxfw_prepare,
-               .trigger   = oxfw_trigger,
-               .pointer   = oxfw_pointer,
-               .page      = snd_pcm_lib_get_vmalloc_page,
-               .mmap      = snd_pcm_lib_mmap_vmalloc,
-       };
-       struct snd_pcm *pcm;
-       int err;
-
-       err = snd_pcm_new(oxfw->card, "OXFW", 0, 1, 0, &pcm);
-       if (err < 0)
-               return err;
-       pcm->private_data = oxfw;
-       strcpy(pcm->name, oxfw->device_info->short_name);
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
-       return 0;
-}
-
 enum control_action { CTL_READ, CTL_WRITE };
 enum control_attribute {
        CTL_MIN         = 0x02,
@@ -587,7 +349,7 @@ static int oxfw_probe(struct fw_unit *unit,
                 dev_name(&unit->device), 100 << fw_dev->max_speed);
        strcpy(card->mixername, "OXFW");
 
-       err = oxfw_create_pcm(oxfw);
+       err = snd_oxfw_create_pcm(oxfw);
        if (err < 0)
                goto error;
 
index e5836e02b48cff36787cac98aeb1773fdb3ce459..1196db8a63001f0da2e59436631c52326569461d 100644 (file)
@@ -54,3 +54,7 @@ int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw);
 void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw);
 void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw);
 void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw);
+
+int firewave_constraints(struct snd_pcm_runtime *runtime);
+int lacie_speakers_constraints(struct snd_pcm_runtime *runtime);
+int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);