Merge branch 'topic/ak411x-fix' into for-next
authorTakashi Iwai <tiwai@suse.de>
Wed, 28 Jan 2015 21:32:10 +0000 (22:32 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 28 Jan 2015 21:32:10 +0000 (22:32 +0100)
295 files changed:
Documentation/devicetree/bindings/sound/pcm512x.txt
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/line6/Kconfig [deleted file]
drivers/staging/line6/Makefile [deleted file]
drivers/staging/line6/audio.c [deleted file]
drivers/staging/line6/audio.h [deleted file]
drivers/staging/line6/capture.c [deleted file]
drivers/staging/line6/capture.h [deleted file]
drivers/staging/line6/driver.c [deleted file]
drivers/staging/line6/driver.h [deleted file]
drivers/staging/line6/midi.c [deleted file]
drivers/staging/line6/midi.h [deleted file]
drivers/staging/line6/midibuf.c [deleted file]
drivers/staging/line6/midibuf.h [deleted file]
drivers/staging/line6/pcm.c [deleted file]
drivers/staging/line6/pcm.h [deleted file]
drivers/staging/line6/playback.c [deleted file]
drivers/staging/line6/playback.h [deleted file]
drivers/staging/line6/pod.c [deleted file]
drivers/staging/line6/pod.h [deleted file]
drivers/staging/line6/podhd.c [deleted file]
drivers/staging/line6/podhd.h [deleted file]
drivers/staging/line6/revision.h [deleted file]
drivers/staging/line6/toneport.c [deleted file]
drivers/staging/line6/toneport.h [deleted file]
drivers/staging/line6/usbdefs.h [deleted file]
drivers/staging/line6/variax.c [deleted file]
drivers/staging/line6/variax.h [deleted file]
include/drm/i915_component.h [new file with mode: 0644]
include/drm/i915_powerwell.h [deleted file]
include/sound/ad1816a.h
include/sound/compress_driver.h
include/sound/emu10k1.h
include/sound/es1688.h
include/sound/gus.h
include/sound/pcm.h
include/sound/pcm_params.h
include/sound/sb.h
include/sound/seq_kernel.h
include/sound/soc-dapm.h
include/sound/wss.h
include/uapi/sound/asound.h
include/uapi/sound/usb_stream.h [new file with mode: 0644]
sound/aoa/soundbus/i2sbus/control.c
sound/aoa/soundbus/i2sbus/core.c
sound/aoa/soundbus/i2sbus/pcm.c
sound/arm/aaci.c
sound/atmel/ac97c.c
sound/core/memory.c
sound/core/oss/pcm_oss.c
sound/core/pcm_lib.c
sound/core/pcm_memory.c
sound/core/pcm_native.c
sound/core/seq/oss/seq_oss_midi.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_midi.c
sound/core/seq/seq_ports.c
sound/core/seq/seq_ports.h
sound/core/timer.c
sound/drivers/aloop.c
sound/drivers/dummy.c
sound/drivers/ml403-ac97cr.c
sound/drivers/mpu401/mpu401_uart.c
sound/drivers/mtpav.c
sound/drivers/opl3/opl3_lib.c
sound/drivers/opl3/opl3_midi.c
sound/drivers/opl3/opl3_seq.c
sound/drivers/opl4/opl4_lib.c
sound/drivers/opl4/opl4_synth.c
sound/drivers/pcsp/pcsp.c
sound/drivers/pcsp/pcsp_input.c
sound/drivers/pcsp/pcsp_lib.c
sound/drivers/serial-u16550.c
sound/drivers/vx/vx_core.c
sound/i2c/other/ak4117.c
sound/i2c/other/ak4xxx-adda.c
sound/isa/ad1816a/ad1816a.c
sound/isa/ad1816a/ad1816a_lib.c
sound/isa/ad1848/ad1848.c
sound/isa/als100.c
sound/isa/azt2320.c
sound/isa/cmi8328.c
sound/isa/cs423x/cs4231.c
sound/isa/cs423x/cs4236.c
sound/isa/cs423x/cs4236_lib.c
sound/isa/es1688/es1688.c
sound/isa/es1688/es1688_lib.c
sound/isa/es18xx.c
sound/isa/galaxy/galaxy.c
sound/isa/gus/gus_instr.c [deleted file]
sound/isa/gus/gus_pcm.c
sound/isa/gus/gus_uart.c
sound/isa/gus/gusclassic.c
sound/isa/gus/gusextreme.c
sound/isa/gus/gusmax.c
sound/isa/gus/interwave.c
sound/isa/msnd/msnd.c
sound/isa/msnd/msnd.h
sound/isa/msnd/msnd_pinnacle.c
sound/isa/opl3sa2.c
sound/isa/opti9xx/miro.c
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/sb/emu8000.c
sound/isa/sb/emu8000_patch.c
sound/isa/sb/emu8000_pcm.c
sound/isa/sb/emu8000_synth.c
sound/isa/sb/jazz16.c
sound/isa/sb/sb16.c
sound/isa/sb/sb16_main.c
sound/isa/sb/sb8.c
sound/isa/sb/sb8_main.c
sound/isa/sb/sb8_midi.c
sound/isa/sb/sb_common.c
sound/isa/sb/sb_mixer.c
sound/isa/sc6000.c
sound/isa/sscape.c
sound/isa/wavefront/wavefront.c
sound/isa/wavefront/wavefront_fx.c
sound/isa/wavefront/wavefront_midi.c
sound/isa/wavefront/wavefront_synth.c
sound/isa/wss/wss_lib.c
sound/oss/msnd_pinnacle.c
sound/oss/pss.c
sound/oss/swarm_cs4297a.c
sound/oss/trix.c
sound/parisc/harmony.c
sound/pci/Kconfig
sound/pci/ad1889.c
sound/pci/ali5451/ali5451.c
sound/pci/als300.c
sound/pci/als4000.c
sound/pci/asihpi/asihpi.c
sound/pci/asihpi/hpi6000.c
sound/pci/asihpi/hpioctl.c
sound/pci/atiixp.c
sound/pci/atiixp_modem.c
sound/pci/au88x0/au88x0.h
sound/pci/aw2/aw2-alsa.c
sound/pci/aw2/aw2-saa7146.c
sound/pci/azt3328.c
sound/pci/bt87x.c
sound/pci/ca0106/ca0106_main.c
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_proc.c
sound/pci/cmipci.c
sound/pci/cs4281.c
sound/pci/cs46xx/cs46xx.c
sound/pci/cs46xx/cs46xx.h
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/dsp_spos.c
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/cs5530.c
sound/pci/cs5535audio/cs5535audio.c
sound/pci/cs5535audio/cs5535audio_pm.c
sound/pci/ctxfi/cthw20k1.c
sound/pci/ctxfi/cthw20k2.c
sound/pci/echoaudio/darla20.c
sound/pci/echoaudio/darla24.c
sound/pci/echoaudio/echo3g.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/gina20.c
sound/pci/echoaudio/gina24.c
sound/pci/echoaudio/indigo.c
sound/pci/echoaudio/indigodj.c
sound/pci/echoaudio/indigoio.c
sound/pci/echoaudio/layla20.c
sound/pci/echoaudio/layla24.c
sound/pci/echoaudio/mia.c
sound/pci/echoaudio/midi.c
sound/pci/echoaudio/mona.c
sound/pci/emu10k1/emu10k1.c
sound/pci/emu10k1/emu10k1x.c
sound/pci/emu10k1/emufx.c
sound/pci/emu10k1/emupcm.c
sound/pci/emu10k1/p16v.c
sound/pci/ens1370.c
sound/pci/es1938.c
sound/pci/es1968.c
sound/pci/fm801.c
sound/pci/hda/Kconfig
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_i915.c
sound/pci/hda/hda_i915.h [deleted file]
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.h [new file with mode: 0644]
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/ak4xxx.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1724.c
sound/pci/ice1712/wm8766.c
sound/pci/ice1712/wm8766.h
sound/pci/ice1712/wm8776.c
sound/pci/ice1712/wm8776.h
sound/pci/intel8x0.c
sound/pci/intel8x0m.c
sound/pci/korg1212/korg1212.c
sound/pci/lola/lola.c
sound/pci/maestro3.c
sound/pci/mixart/mixart.c
sound/pci/mixart/mixart_core.c
sound/pci/mixart/mixart_hwdep.c
sound/pci/nm256/nm256.c
sound/pci/oxygen/Makefile
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen_io.c
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/oxygen_mixer.c
sound/pci/oxygen/oxygen_pcm.c
sound/pci/oxygen/se6x.c [new file with mode: 0644]
sound/pci/pcxhr/pcxhr_core.c
sound/pci/pcxhr/pcxhr_hwdep.c
sound/pci/riptide/riptide.c
sound/pci/rme32.c
sound/pci/rme96.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/pci/sis7019.c
sound/pci/sonicvibes.c
sound/pci/trident/trident.c
sound/pci/trident/trident.h
sound/pci/trident/trident_main.c
sound/pci/trident/trident_memory.c
sound/pci/via82xx.c
sound/pci/via82xx_modem.c
sound/pci/vx222/vx222.c
sound/pci/vx222/vx222_ops.c
sound/pci/ymfpci/ymfpci.c
sound/pci/ymfpci/ymfpci.h
sound/pci/ymfpci/ymfpci_main.c
sound/ppc/awacs.c
sound/ppc/beep.c
sound/ppc/burgundy.c
sound/ppc/pmac.c
sound/ppc/snd_ps3.c
sound/ppc/tumbler.c
sound/sh/aica.c
sound/soc/codecs/pcm512x-i2c.c
sound/soc/codecs/pcm512x-spi.c
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5677.c
sound/soc/codecs/wm8750.c
sound/soc/dwc/designware_i2s.c
sound/soc/intel/Kconfig
sound/soc/intel/bytcr_dpcm_rt5640.c
sound/soc/intel/cht_bsw_rt5672.c
sound/soc/intel/sst-firmware.c
sound/soc/intel/sst/sst_acpi.c
sound/soc/omap/omap-hdmi-audio.c
sound/soc/pxa/spitz.c
sound/soc/rockchip/rockchip_i2s.c
sound/soc/samsung/arndale_rt5631.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-pcm.c
sound/sparc/amd7930.c
sound/synth/emux/emux.c
sound/synth/emux/emux_hwdep.c
sound/synth/emux/emux_oss.c
sound/synth/emux/emux_synth.c
sound/synth/emux/soundfont.c
sound/usb/Kconfig
sound/usb/Makefile
sound/usb/line6/Kconfig [new file with mode: 0644]
sound/usb/line6/Makefile [new file with mode: 0644]
sound/usb/line6/capture.c [new file with mode: 0644]
sound/usb/line6/capture.h [new file with mode: 0644]
sound/usb/line6/driver.c [new file with mode: 0644]
sound/usb/line6/driver.h [new file with mode: 0644]
sound/usb/line6/midi.c [new file with mode: 0644]
sound/usb/line6/midi.h [new file with mode: 0644]
sound/usb/line6/midibuf.c [new file with mode: 0644]
sound/usb/line6/midibuf.h [new file with mode: 0644]
sound/usb/line6/pcm.c [new file with mode: 0644]
sound/usb/line6/pcm.h [new file with mode: 0644]
sound/usb/line6/playback.c [new file with mode: 0644]
sound/usb/line6/playback.h [new file with mode: 0644]
sound/usb/line6/pod.c [new file with mode: 0644]
sound/usb/line6/podhd.c [new file with mode: 0644]
sound/usb/line6/revision.h [new file with mode: 0644]
sound/usb/line6/toneport.c [new file with mode: 0644]
sound/usb/line6/usbdefs.h [new file with mode: 0644]
sound/usb/line6/variax.c [new file with mode: 0644]
sound/usb/midi.c
sound/usb/quirks-table.h
sound/usb/usx2y/usb_stream.h

index faff75e..98e0d34 100644 (file)
@@ -5,7 +5,8 @@ on the board).
 
 Required properties:
 
-  - compatible : One of "ti,pcm5121" or "ti,pcm5122"
+  - compatible : One of "ti,pcm5121", "ti,pcm5122", "ti,pcm5141" or
+                 "ti,pcm5142"
 
   - reg : the I2C address of the device for I2C, the chip select
           number for SPI.
index ecee3bc..26b3199 100644 (file)
@@ -830,6 +830,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        intel_runtime_pm_enable(dev_priv);
 
+       i915_audio_component_init(dev_priv);
+
        return 0;
 
 out_power_well:
@@ -870,6 +872,8 @@ int i915_driver_unload(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
+       i915_audio_component_cleanup(dev_priv);
+
        ret = i915_gem_suspend(dev);
        if (ret) {
                DRM_ERROR("failed to idle hardware: %d\n", ret);
index 574057c..cbbd23f 100644 (file)
@@ -940,8 +940,7 @@ static int i915_pm_suspend(struct device *dev)
 
 static int i915_pm_suspend_late(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       struct drm_device *drm_dev = dev_to_i915(dev)->dev;
 
        /*
         * We have a suspedn ordering issue with the snd-hda driver also
@@ -960,8 +959,7 @@ static int i915_pm_suspend_late(struct device *dev)
 
 static int i915_pm_resume_early(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       struct drm_device *drm_dev = dev_to_i915(dev)->dev;
 
        if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
@@ -971,8 +969,7 @@ static int i915_pm_resume_early(struct device *dev)
 
 static int i915_pm_resume(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       struct drm_device *drm_dev = dev_to_i915(dev)->dev;
 
        if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
index e9f891c..176afc5 100644 (file)
@@ -1698,6 +1698,9 @@ struct drm_i915_private {
        struct drm_property *broadcast_rgb_property;
        struct drm_property *force_audio_property;
 
+       /* hda/i915 audio component */
+       bool audio_component_registered;
+
        uint32_t hw_context_size;
        struct list_head context_list;
 
@@ -1781,6 +1784,11 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
        return dev->dev_private;
 }
 
+static inline struct drm_i915_private *dev_to_i915(struct device *dev)
+{
+       return to_i915(dev_get_drvdata(dev));
+}
+
 /* Iterate over initialised rings */
 #define for_each_ring(ring__, dev_priv__, i__) \
        for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
index 2c7ed5c..ee41b88 100644 (file)
@@ -22,6 +22,9 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/component.h>
+#include <drm/i915_component.h>
+#include "intel_drv.h"
 
 #include <drm/drmP.h>
 #include <drm/drm_edid.h>
@@ -461,3 +464,110 @@ void intel_init_audio(struct drm_device *dev)
                dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
        }
 }
+
+static void i915_audio_component_get_power(struct device *dev)
+{
+       intel_display_power_get(dev_to_i915(dev), POWER_DOMAIN_AUDIO);
+}
+
+static void i915_audio_component_put_power(struct device *dev)
+{
+       intel_display_power_put(dev_to_i915(dev), POWER_DOMAIN_AUDIO);
+}
+
+/* Get CDCLK in kHz  */
+static int i915_audio_component_get_cdclk_freq(struct device *dev)
+{
+       struct drm_i915_private *dev_priv = dev_to_i915(dev);
+       int ret;
+
+       if (WARN_ON_ONCE(!HAS_DDI(dev_priv)))
+               return -ENODEV;
+
+       intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
+       ret = intel_ddi_get_cdclk_freq(dev_priv);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
+
+       return ret;
+}
+
+static const struct i915_audio_component_ops i915_audio_component_ops = {
+       .owner          = THIS_MODULE,
+       .get_power      = i915_audio_component_get_power,
+       .put_power      = i915_audio_component_put_power,
+       .get_cdclk_freq = i915_audio_component_get_cdclk_freq,
+};
+
+static int i915_audio_component_bind(struct device *i915_dev,
+                                    struct device *hda_dev, void *data)
+{
+       struct i915_audio_component *acomp = data;
+
+       if (WARN_ON(acomp->ops || acomp->dev))
+               return -EEXIST;
+
+       acomp->ops = &i915_audio_component_ops;
+       acomp->dev = i915_dev;
+
+       return 0;
+}
+
+static void i915_audio_component_unbind(struct device *i915_dev,
+                                       struct device *hda_dev, void *data)
+{
+       struct i915_audio_component *acomp = data;
+
+       acomp->ops = NULL;
+       acomp->dev = NULL;
+}
+
+static const struct component_ops i915_audio_component_bind_ops = {
+       .bind   = i915_audio_component_bind,
+       .unbind = i915_audio_component_unbind,
+};
+
+/**
+ * i915_audio_component_init - initialize and register the audio component
+ * @dev_priv: i915 device instance
+ *
+ * This will register with the component framework a child component which
+ * will bind dynamically to the snd_hda_intel driver's corresponding master
+ * component when the latter is registered. During binding the child
+ * initializes an instance of struct i915_audio_component which it receives
+ * from the master. The master can then start to use the interface defined by
+ * this struct. Each side can break the binding at any point by deregistering
+ * its own component after which each side's component unbind callback is
+ * called.
+ *
+ * We ignore any error during registration and continue with reduced
+ * functionality (i.e. without HDMI audio).
+ */
+void i915_audio_component_init(struct drm_i915_private *dev_priv)
+{
+       int ret;
+
+       ret = component_add(dev_priv->dev->dev, &i915_audio_component_bind_ops);
+       if (ret < 0) {
+               DRM_ERROR("failed to add audio component (%d)\n", ret);
+               /* continue with reduced functionality */
+               return;
+       }
+
+       dev_priv->audio_component_registered = true;
+}
+
+/**
+ * i915_audio_component_cleanup - deregister the audio component
+ * @dev_priv: i915 device instance
+ *
+ * Deregisters the audio component, breaking any existing binding to the
+ * corresponding snd_hda_intel driver's master component.
+ */
+void i915_audio_component_cleanup(struct drm_i915_private *dev_priv)
+{
+       if (!dev_priv->audio_component_registered)
+               return;
+
+       component_del(dev_priv->dev->dev, &i915_audio_component_bind_ops);
+       dev_priv->audio_component_registered = false;
+}
index 3b40a17..29ba962 100644 (file)
@@ -873,6 +873,8 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);
 void intel_init_audio(struct drm_device *dev);
 void intel_audio_codec_enable(struct intel_encoder *encoder);
 void intel_audio_codec_disable(struct intel_encoder *encoder);
+void i915_audio_component_init(struct drm_i915_private *dev_priv);
+void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
 
 /* intel_display.c */
 const char *intel_output_name(int output);
index ac6da71..39ddf40 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "i915_drv.h"
 #include "intel_drv.h"
-#include <drm/i915_powerwell.h>
 
 /**
  * DOC: runtime pm
@@ -50,8 +49,6 @@
  * present for a given platform.
  */
 
-static struct i915_power_domains *hsw_pwr;
-
 #define for_each_power_well(i, power_well, domain_mask, power_domains) \
        for (i = 0;                                                     \
             i < (power_domains)->power_well_count &&                   \
@@ -1071,10 +1068,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
         */
        if (IS_HASWELL(dev_priv->dev)) {
                set_power_wells(power_domains, hsw_power_wells);
-               hsw_pwr = power_domains;
        } else if (IS_BROADWELL(dev_priv->dev)) {
                set_power_wells(power_domains, bdw_power_wells);
-               hsw_pwr = power_domains;
        } else if (IS_CHERRYVIEW(dev_priv->dev)) {
                set_power_wells(power_domains, chv_power_wells);
        } else if (IS_VALLEYVIEW(dev_priv->dev)) {
@@ -1118,8 +1113,6 @@ void intel_power_domains_fini(struct drm_i915_private *dev_priv)
         * the power well is not enabled, so just enable it in case
         * we're going to unload/reload. */
        intel_display_set_init_power(dev_priv, true);
-
-       hsw_pwr = NULL;
 }
 
 static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
@@ -1328,52 +1321,3 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv)
        pm_runtime_put_autosuspend(device);
 }
 
-/* Display audio driver power well request */
-int i915_request_power_well(void)
-{
-       struct drm_i915_private *dev_priv;
-
-       if (!hsw_pwr)
-               return -ENODEV;
-
-       dev_priv = container_of(hsw_pwr, struct drm_i915_private,
-                               power_domains);
-       intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(i915_request_power_well);
-
-/* Display audio driver power well release */
-int i915_release_power_well(void)
-{
-       struct drm_i915_private *dev_priv;
-
-       if (!hsw_pwr)
-               return -ENODEV;
-
-       dev_priv = container_of(hsw_pwr, struct drm_i915_private,
-                               power_domains);
-       intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(i915_release_power_well);
-
-/*
- * Private interface for the audio driver to get CDCLK in kHz.
- *
- * Caller must request power well using i915_request_power_well() prior to
- * making the call.
- */
-int i915_get_cdclk_freq(void)
-{
-       struct drm_i915_private *dev_priv;
-
-       if (!hsw_pwr)
-               return -ENODEV;
-
-       dev_priv = container_of(hsw_pwr, struct drm_i915_private,
-                               power_domains);
-
-       return intel_ddi_get_cdclk_freq(dev_priv);
-}
-EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
index 815de37..9049dd9 100644 (file)
@@ -46,8 +46,6 @@ source "drivers/staging/rtl8723au/Kconfig"
 
 source "drivers/staging/rts5208/Kconfig"
 
-source "drivers/staging/line6/Kconfig"
-
 source "drivers/staging/octeon/Kconfig"
 
 source "drivers/staging/octeon-usb/Kconfig"
index 33c640b..fe26ff1 100644 (file)
@@ -15,7 +15,6 @@ obj-$(CONFIG_R8712U)          += rtl8712/
 obj-$(CONFIG_R8188EU)          += rtl8188eu/
 obj-$(CONFIG_R8723AU)          += rtl8723au/
 obj-$(CONFIG_RTS5208)          += rts5208/
-obj-$(CONFIG_LINE6_USB)                += line6/
 obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
 obj-$(CONFIG_OCTEON_ETHERNET)  += octeon/
 obj-$(CONFIG_OCTEON_USB)       += octeon-usb/
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
deleted file mode 100644 (file)
index 4f1219b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-menuconfig LINE6_USB
-       tristate "Line6 USB support"
-       depends on USB && SND
-       select SND_RAWMIDI
-       select SND_PCM
-       help
-         This is a driver for the guitar amp, cab, and effects modeller
-         PODxt Pro by Line6 (and similar devices), supporting the
-         following features:
-           * Reading/writing individual parameters
-           * Reading/writing complete channel, effects setup, and amp
-             setup data
-           * Channel switching
-           * Virtual MIDI interface
-           * Tuner access
-           * Playback/capture/mixer device for any ALSA-compatible PCM
-             audio application
-           * Signal routing (record clean/processed guitar signal,
-             re-amping)
-
-         Preliminary support for the Variax Workbench and TonePort
-         devices is included.
-
-if LINE6_USB
-
-config LINE6_USB_IMPULSE_RESPONSE
-       bool "measure impulse response"
-       default n
-       help
-         Say Y here to add code to measure the impulse response of a Line6
-         device. This is more accurate than user-space methods since it
-         bypasses any PCM data buffering (e.g., by ALSA or jack). This is
-         useful for assessing the performance of new devices, but is not
-         required for normal operation.
-
-         If unsure, say N.
-
-endif # LINE6_USB
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
deleted file mode 100644 (file)
index ae5c374..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-obj-$(CONFIG_LINE6_USB)                += line6usb.o
-
-line6usb-y :=          \
-               audio.o         \
-               capture.o       \
-               driver.o        \
-               midi.o          \
-               midibuf.o       \
-               pcm.o           \
-               playback.o      \
-               pod.o           \
-               toneport.o      \
-               variax.o        \
-               podhd.o
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
deleted file mode 100644 (file)
index 171d80c..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <linux/export.h>
-
-#include "driver.h"
-#include "audio.h"
-
-/*
-       Initialize the Line6 USB audio system.
-*/
-int line6_init_audio(struct usb_line6 *line6)
-{
-       struct snd_card *card;
-       int err;
-
-       err = snd_card_new(line6->ifcdev,
-                          SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-                          THIS_MODULE, 0, &card);
-       if (err < 0)
-               return err;
-
-       line6->card = card;
-
-       strcpy(card->id, line6->properties->id);
-       strcpy(card->driver, DRIVER_NAME);
-       strcpy(card->shortname, line6->properties->name);
-       /* longname is 80 chars - see asound.h */
-       sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
-               dev_name(line6->ifcdev));
-       return 0;
-}
-
-/*
-       Register the Line6 USB audio system.
-*/
-int line6_register_audio(struct usb_line6 *line6)
-{
-       int err;
-
-       err = snd_card_register(line6->card);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
-/*
-       Cleanup the Line6 USB audio system.
-*/
-void line6_cleanup_audio(struct usb_line6 *line6)
-{
-       struct snd_card *card = line6->card;
-
-       if (card == NULL)
-               return;
-
-       snd_card_disconnect(card);
-       snd_card_free(card);
-       line6->card = NULL;
-}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
deleted file mode 100644 (file)
index 5f8a09a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef AUDIO_H
-#define AUDIO_H
-
-#include "driver.h"
-
-extern void line6_cleanup_audio(struct usb_line6 *);
-extern int line6_init_audio(struct usb_line6 *);
-extern int line6_register_audio(struct usb_line6 *);
-
-#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
deleted file mode 100644 (file)
index e6ca631..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "pcm.h"
-#include "pod.h"
-
-/*
-       Find a free URB and submit it.
-*/
-static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
-{
-       int index;
-       unsigned long flags;
-       int i, urb_size;
-       int ret;
-       struct urb *urb_in;
-
-       spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
-       index =
-           find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
-
-       if (index < 0 || index >= LINE6_ISO_BUFFERS) {
-               spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
-               dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
-               return -EINVAL;
-       }
-
-       urb_in = line6pcm->urb_audio_in[index];
-       urb_size = 0;
-
-       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-               struct usb_iso_packet_descriptor *fin =
-                   &urb_in->iso_frame_desc[i];
-               fin->offset = urb_size;
-               fin->length = line6pcm->max_packet_size;
-               urb_size += line6pcm->max_packet_size;
-       }
-
-       urb_in->transfer_buffer =
-           line6pcm->buffer_in +
-           index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
-       urb_in->transfer_buffer_length = urb_size;
-       urb_in->context = line6pcm;
-
-       ret = usb_submit_urb(urb_in, GFP_ATOMIC);
-
-       if (ret == 0)
-               set_bit(index, &line6pcm->active_urb_in);
-       else
-               dev_err(line6pcm->line6->ifcdev,
-                       "URB in #%d submission failed (%d)\n", index, ret);
-
-       spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
-       return 0;
-}
-
-/*
-       Submit all currently available capture URBs.
-*/
-int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int ret, i;
-
-       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
-               ret = submit_audio_in_urb(line6pcm);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-/*
-       Unlink all currently active capture URBs.
-*/
-void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       unsigned int i;
-
-       for (i = LINE6_ISO_BUFFERS; i--;) {
-               if (test_bit(i, &line6pcm->active_urb_in)) {
-                       if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
-                               struct urb *u = line6pcm->urb_audio_in[i];
-
-                               usb_unlink_urb(u);
-                       }
-               }
-       }
-}
-
-/*
-       Wait until unlinking of all currently active capture URBs has been
-       finished.
-*/
-void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int timeout = HZ;
-       unsigned int i;
-       int alive;
-
-       do {
-               alive = 0;
-               for (i = LINE6_ISO_BUFFERS; i--;) {
-                       if (test_bit(i, &line6pcm->active_urb_in))
-                               alive++;
-               }
-               if (!alive)
-                       break;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-       } while (--timeout > 0);
-       if (alive)
-               snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-}
-
-/*
-       Unlink all currently active capture URBs, and wait for finishing.
-*/
-void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       line6_unlink_audio_in_urbs(line6pcm);
-       line6_wait_clear_audio_in_urbs(line6pcm);
-}
-
-/*
-       Copy data into ALSA capture buffer.
-*/
-void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
-{
-       struct snd_pcm_substream *substream =
-           get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
-       int frames = fsize / bytes_per_frame;
-
-       if (runtime == NULL)
-               return;
-
-       if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
-               /*
-                  The transferred area goes over buffer boundary,
-                  copy two separate chunks.
-                */
-               int len;
-
-               len = runtime->buffer_size - line6pcm->pos_in_done;
-
-               if (len > 0) {
-                       memcpy(runtime->dma_area +
-                              line6pcm->pos_in_done * bytes_per_frame, fbuf,
-                              len * bytes_per_frame);
-                       memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
-                              (frames - len) * bytes_per_frame);
-               } else {
-                       /* this is somewhat paranoid */
-                       dev_err(line6pcm->line6->ifcdev,
-                               "driver bug: len = %d\n", len);
-               }
-       } else {
-               /* copy single chunk */
-               memcpy(runtime->dma_area +
-                      line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize);
-       }
-
-       line6pcm->pos_in_done += frames;
-       if (line6pcm->pos_in_done >= runtime->buffer_size)
-               line6pcm->pos_in_done -= runtime->buffer_size;
-}
-
-void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
-{
-       struct snd_pcm_substream *substream =
-           get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
-
-       line6pcm->bytes_in += length;
-       if (line6pcm->bytes_in >= line6pcm->period_in) {
-               line6pcm->bytes_in %= line6pcm->period_in;
-               snd_pcm_period_elapsed(substream);
-       }
-}
-
-void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
-{
-       kfree(line6pcm->buffer_in);
-       line6pcm->buffer_in = NULL;
-}
-
-/*
- * Callback for completed capture URB.
- */
-static void audio_in_callback(struct urb *urb)
-{
-       int i, index, length = 0, shutdown = 0;
-       unsigned long flags;
-
-       struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
-
-       line6pcm->last_frame_in = urb->start_frame;
-
-       /* find index of URB */
-       for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
-               if (urb == line6pcm->urb_audio_in[index])
-                       break;
-
-       spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
-
-       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-               char *fbuf;
-               int fsize;
-               struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
-
-               if (fin->status == -EXDEV) {
-                       shutdown = 1;
-                       break;
-               }
-
-               fbuf = urb->transfer_buffer + fin->offset;
-               fsize = fin->actual_length;
-
-               if (fsize > line6pcm->max_packet_size) {
-                       dev_err(line6pcm->line6->ifcdev,
-                               "driver and/or device bug: packet too large (%d > %d)\n",
-                               fsize, line6pcm->max_packet_size);
-               }
-
-               length += fsize;
-
-               /* the following assumes LINE6_ISO_PACKETS == 1: */
-               line6pcm->prev_fbuf = fbuf;
-               line6pcm->prev_fsize = fsize;
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-               if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
-#endif
-                       if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
-                                    &line6pcm->flags) && (fsize > 0))
-                               line6_capture_copy(line6pcm, fbuf, fsize);
-       }
-
-       clear_bit(index, &line6pcm->active_urb_in);
-
-       if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
-               shutdown = 1;
-
-       spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
-
-       if (!shutdown) {
-               submit_audio_in_urb(line6pcm);
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-               if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
-#endif
-                       if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
-                                    &line6pcm->flags))
-                               line6_capture_check_period(line6pcm, length);
-       }
-}
-
-/* open capture callback */
-static int snd_line6_capture_open(struct snd_pcm_substream *substream)
-{
-       int err;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       err = snd_pcm_hw_constraint_ratdens(runtime, 0,
-                                           SNDRV_PCM_HW_PARAM_RATE,
-                                           (&line6pcm->
-                                            properties->snd_line6_rates));
-       if (err < 0)
-               return err;
-
-       runtime->hw = line6pcm->properties->snd_line6_capture_hw;
-       return 0;
-}
-
-/* close capture callback */
-static int snd_line6_capture_close(struct snd_pcm_substream *substream)
-{
-       return 0;
-}
-
-/* hw_params capture callback */
-static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
-                                      struct snd_pcm_hw_params *hw_params)
-{
-       int ret;
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       /* -- Florian Demski [FD] */
-       /* don't ask me why, but this fixes the bug on my machine */
-       if (line6pcm == NULL) {
-               if (substream->pcm == NULL)
-                       return -ENOMEM;
-               if (substream->pcm->private_data == NULL)
-                       return -ENOMEM;
-               substream->private_data = substream->pcm->private_data;
-               line6pcm = snd_pcm_substream_chip(substream);
-       }
-       /* -- [FD] end */
-
-       ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
-
-       if (ret < 0)
-               return ret;
-
-       ret = snd_pcm_lib_malloc_pages(substream,
-                                      params_buffer_bytes(hw_params));
-       if (ret < 0) {
-               line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
-               return ret;
-       }
-
-       line6pcm->period_in = params_period_bytes(hw_params);
-       return 0;
-}
-
-/* hw_free capture callback */
-static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
-       return snd_pcm_lib_free_pages(substream);
-}
-
-/* trigger callback */
-int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
-{
-       int err;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-#ifdef CONFIG_PM
-       case SNDRV_PCM_TRIGGER_RESUME:
-#endif
-               err = line6_pcm_acquire(line6pcm,
-                                       LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
-
-               if (err < 0)
-                       return err;
-
-               break;
-
-       case SNDRV_PCM_TRIGGER_STOP:
-#ifdef CONFIG_PM
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-#endif
-               err = line6_pcm_release(line6pcm,
-                                       LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
-
-               if (err < 0)
-                       return err;
-
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* capture pointer callback */
-static snd_pcm_uframes_t
-snd_line6_capture_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       return line6pcm->pos_in_done;
-}
-
-/* capture operators */
-struct snd_pcm_ops snd_line6_capture_ops = {
-       .open = snd_line6_capture_open,
-       .close = snd_line6_capture_close,
-       .ioctl = snd_pcm_lib_ioctl,
-       .hw_params = snd_line6_capture_hw_params,
-       .hw_free = snd_line6_capture_hw_free,
-       .prepare = snd_line6_prepare,
-       .trigger = snd_line6_trigger,
-       .pointer = snd_line6_capture_pointer,
-};
-
-int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int i;
-
-       /* create audio URBs and fill in constant values: */
-       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
-               struct urb *urb;
-
-               /* URB for audio in: */
-               urb = line6pcm->urb_audio_in[i] =
-                   usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
-
-               if (urb == NULL) {
-                       dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
-                       return -ENOMEM;
-               }
-
-               urb->dev = line6pcm->line6->usbdev;
-               urb->pipe =
-                   usb_rcvisocpipe(line6pcm->line6->usbdev,
-                                   line6pcm->ep_audio_read &
-                                   USB_ENDPOINT_NUMBER_MASK);
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->start_frame = -1;
-               urb->number_of_packets = LINE6_ISO_PACKETS;
-               urb->interval = LINE6_ISO_INTERVAL;
-               urb->error_count = 0;
-               urb->complete = audio_in_callback;
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
deleted file mode 100644 (file)
index 4157bcb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef CAPTURE_H
-#define CAPTURE_H
-
-#include <sound/pcm.h>
-
-#include "driver.h"
-#include "pcm.h"
-
-extern struct snd_pcm_ops snd_line6_capture_ops;
-
-extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
-                              int fsize);
-extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
-                                      int length);
-extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm);
-extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
-                                                 *line6pcm);
-extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
-
-#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
deleted file mode 100644 (file)
index 503b2d7..0000000
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "midi.h"
-#include "playback.h"
-#include "pod.h"
-#include "podhd.h"
-#include "revision.h"
-#include "toneport.h"
-#include "usbdefs.h"
-#include "variax.h"
-
-#define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
-#define DRIVER_DESC    "Line6 USB Driver"
-#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
-
-/* table of devices that work with this driver */
-static const struct usb_device_id line6_id_table[] = {
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)},
-       {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)},
-       {},
-};
-
-MODULE_DEVICE_TABLE(usb, line6_id_table);
-
-#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\
-       {.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\
-        .name = dev_name, .capabilities = LINE6_BIT_##dev_cap}
-
-/* *INDENT-OFF* */
-static const struct line6_properties line6_properties_table[] = {
-       L6PROP(BASSPODXT,     "BassPODxt",     "BassPODxt",        CTRL_PCM_HW),
-       L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live",   CTRL_PCM_HW),
-       L6PROP(BASSPODXTPRO,  "BassPODxtPro",  "BassPODxt Pro",    CTRL_PCM_HW),
-       L6PROP(GUITARPORT,    "GuitarPort",    "GuitarPort",       PCM),
-       L6PROP(POCKETPOD,     "PocketPOD",     "Pocket POD",       CONTROL),
-       L6PROP(PODHD300,      "PODHD300",      "POD HD300",        CTRL_PCM_HW),
-       L6PROP(PODHD400,      "PODHD400",      "POD HD400",        CTRL_PCM_HW),
-       L6PROP(PODHD500,      "PODHD500",      "POD HD500",        CTRL_PCM_HW),
-       L6PROP(PODSTUDIO_GX,  "PODStudioGX",   "POD Studio GX",    PCM),
-       L6PROP(PODSTUDIO_UX1, "PODStudioUX1",  "POD Studio UX1",   PCM),
-       L6PROP(PODSTUDIO_UX2, "PODStudioUX2",  "POD Studio UX2",   PCM),
-       L6PROP(PODX3,         "PODX3",         "POD X3",           PCM),
-       L6PROP(PODX3LIVE,     "PODX3Live",     "POD X3 Live",      PCM),
-       L6PROP(PODXT,         "PODxt",         "PODxt",            CTRL_PCM_HW),
-       L6PROP(PODXTLIVE,     "PODxtLive",     "PODxt Live",       CTRL_PCM_HW),
-       L6PROP(PODXTPRO,      "PODxtPro",      "PODxt Pro",        CTRL_PCM_HW),
-       L6PROP(TONEPORT_GX,   "TonePortGX",    "TonePort GX",      PCM),
-       L6PROP(TONEPORT_UX1,  "TonePortUX1",   "TonePort UX1",     PCM),
-       L6PROP(TONEPORT_UX2,  "TonePortUX2",   "TonePort UX2",     PCM),
-       L6PROP(VARIAX,        "Variax",        "Variax Workbench", CONTROL),
-};
-/* *INDENT-ON* */
-
-/*
-       This is Line6's MIDI manufacturer ID.
-*/
-const unsigned char line6_midi_id[] = {
-       0x00, 0x01, 0x0c
-};
-
-/*
-       Code to request version of POD, Variax interface
-       (and maybe other devices).
-*/
-static const char line6_request_version[] = {
-       0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
-};
-
-/**
-        Class for asynchronous messages.
-*/
-struct message {
-       struct usb_line6 *line6;
-       const char *buffer;
-       int size;
-       int done;
-};
-
-/*
-       Forward declarations.
-*/
-static void line6_data_received(struct urb *urb);
-static int line6_send_raw_message_async_part(struct message *msg,
-                                            struct urb *urb);
-
-/*
-       Start to listen on endpoint.
-*/
-static int line6_start_listen(struct usb_line6 *line6)
-{
-       int err;
-
-       usb_fill_int_urb(line6->urb_listen, line6->usbdev,
-                        usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
-                        line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
-                        line6_data_received, line6, line6->interval);
-       line6->urb_listen->actual_length = 0;
-       err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
-       return err;
-}
-
-/*
-       Stop listening on endpoint.
-*/
-static void line6_stop_listen(struct usb_line6 *line6)
-{
-       usb_kill_urb(line6->urb_listen);
-}
-
-/*
-       Send raw message in pieces of wMaxPacketSize bytes.
-*/
-int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
-                          int size)
-{
-       int i, done = 0;
-
-       for (i = 0; i < size; i += line6->max_packet_size) {
-               int partial;
-               const char *frag_buf = buffer + i;
-               int frag_size = min(line6->max_packet_size, size - i);
-               int retval;
-
-               retval = usb_interrupt_msg(line6->usbdev,
-                                       usb_sndintpipe(line6->usbdev,
-                                               line6->ep_control_write),
-                                       (char *)frag_buf, frag_size,
-                                       &partial, LINE6_TIMEOUT * HZ);
-
-               if (retval) {
-                       dev_err(line6->ifcdev,
-                               "usb_interrupt_msg failed (%d)\n", retval);
-                       break;
-               }
-
-               done += frag_size;
-       }
-
-       return done;
-}
-
-/*
-       Notification of completion of asynchronous request transmission.
-*/
-static void line6_async_request_sent(struct urb *urb)
-{
-       struct message *msg = (struct message *)urb->context;
-
-       if (msg->done >= msg->size) {
-               usb_free_urb(urb);
-               kfree(msg);
-       } else
-               line6_send_raw_message_async_part(msg, urb);
-}
-
-/*
-       Asynchronously send part of a raw message.
-*/
-static int line6_send_raw_message_async_part(struct message *msg,
-                                            struct urb *urb)
-{
-       int retval;
-       struct usb_line6 *line6 = msg->line6;
-       int done = msg->done;
-       int bytes = min(msg->size - done, line6->max_packet_size);
-
-       usb_fill_int_urb(urb, line6->usbdev,
-                        usb_sndintpipe(line6->usbdev, line6->ep_control_write),
-                        (char *)msg->buffer + done, bytes,
-                        line6_async_request_sent, msg, line6->interval);
-
-       msg->done += bytes;
-       retval = usb_submit_urb(urb, GFP_ATOMIC);
-
-       if (retval < 0) {
-               dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
-                       __func__, retval);
-               usb_free_urb(urb);
-               kfree(msg);
-               return retval;
-       }
-
-       return 0;
-}
-
-/*
-       Setup and start timer.
-*/
-void line6_start_timer(struct timer_list *timer, unsigned int msecs,
-                      void (*function)(unsigned long), unsigned long data)
-{
-       setup_timer(timer, function, data);
-       timer->expires = jiffies + msecs * HZ / 1000;
-       add_timer(timer);
-}
-
-/*
-       Asynchronously send raw message.
-*/
-int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
-                                int size)
-{
-       struct message *msg;
-       struct urb *urb;
-
-       /* create message: */
-       msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
-       if (msg == NULL)
-               return -ENOMEM;
-
-       /* create URB: */
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-
-       if (urb == NULL) {
-               kfree(msg);
-               dev_err(line6->ifcdev, "Out of memory\n");
-               return -ENOMEM;
-       }
-
-       /* set message data: */
-       msg->line6 = line6;
-       msg->buffer = buffer;
-       msg->size = size;
-       msg->done = 0;
-
-       /* start sending: */
-       return line6_send_raw_message_async_part(msg, urb);
-}
-
-/*
-       Send asynchronous device version request.
-*/
-int line6_version_request_async(struct usb_line6 *line6)
-{
-       char *buffer;
-       int retval;
-
-       buffer = kmemdup(line6_request_version,
-                       sizeof(line6_request_version), GFP_ATOMIC);
-       if (buffer == NULL) {
-               dev_err(line6->ifcdev, "Out of memory");
-               return -ENOMEM;
-       }
-
-       retval = line6_send_raw_message_async(line6, buffer,
-                                             sizeof(line6_request_version));
-       kfree(buffer);
-       return retval;
-}
-
-/*
-       Send sysex message in pieces of wMaxPacketSize bytes.
-*/
-int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
-                            int size)
-{
-       return line6_send_raw_message(line6, buffer,
-                                     size + SYSEX_EXTRA_SIZE) -
-           SYSEX_EXTRA_SIZE;
-}
-
-/*
-       Allocate buffer for sysex message and prepare header.
-       @param code sysex message code
-       @param size number of bytes between code and sysex end
-*/
-char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
-                              int size)
-{
-       char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
-
-       if (!buffer)
-               return NULL;
-
-       buffer[0] = LINE6_SYSEX_BEGIN;
-       memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
-       buffer[sizeof(line6_midi_id) + 1] = code1;
-       buffer[sizeof(line6_midi_id) + 2] = code2;
-       buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
-       return buffer;
-}
-
-/*
-       Notification of data received from the Line6 device.
-*/
-static void line6_data_received(struct urb *urb)
-{
-       struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
-       struct midi_buffer *mb = &line6->line6midi->midibuf_in;
-       int done;
-
-       if (urb->status == -ESHUTDOWN)
-               return;
-
-       done =
-           line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
-
-       if (done < urb->actual_length) {
-               line6_midibuf_ignore(mb, done);
-               dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
-                       done, urb->actual_length);
-       }
-
-       for (;;) {
-               done =
-                   line6_midibuf_read(mb, line6->buffer_message,
-                                      LINE6_MESSAGE_MAXLEN);
-
-               if (done == 0)
-                       break;
-
-               line6->message_length = done;
-               line6_midi_receive(line6, line6->buffer_message, done);
-
-               switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
-               case LINE6_DEVID_BASSPODXT:
-               case LINE6_DEVID_BASSPODXTLIVE:
-               case LINE6_DEVID_BASSPODXTPRO:
-               case LINE6_DEVID_PODXT:
-               case LINE6_DEVID_PODXTPRO:
-               case LINE6_DEVID_POCKETPOD:
-                       line6_pod_process_message((struct usb_line6_pod *)
-                                                 line6);
-                       break;
-
-               case LINE6_DEVID_PODHD300:
-               case LINE6_DEVID_PODHD400:
-               case LINE6_DEVID_PODHD500:
-                       break; /* let userspace handle MIDI */
-
-               case LINE6_DEVID_PODXTLIVE:
-                       switch (line6->interface_number) {
-                       case PODXTLIVE_INTERFACE_POD:
-                               line6_pod_process_message((struct usb_line6_pod
-                                                          *)line6);
-                               break;
-
-                       case PODXTLIVE_INTERFACE_VARIAX:
-                               line6_variax_process_message((struct
-                                                             usb_line6_variax
-                                                             *)line6);
-                               break;
-
-                       default:
-                               dev_err(line6->ifcdev,
-                                       "PODxt Live interface %d not supported\n",
-                                       line6->interface_number);
-                       }
-                       break;
-
-               case LINE6_DEVID_VARIAX:
-                       line6_variax_process_message((struct usb_line6_variax *)
-                                                    line6);
-                       break;
-
-               default:
-                       MISSING_CASE;
-               }
-       }
-
-       line6_start_listen(line6);
-}
-
-/*
-       Send channel number (i.e., switch to a different sound).
-*/
-int line6_send_program(struct usb_line6 *line6, u8 value)
-{
-       int retval;
-       unsigned char *buffer;
-       int partial;
-
-       buffer = kmalloc(2, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
-       buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
-       buffer[1] = value;
-
-       retval = usb_interrupt_msg(line6->usbdev,
-                                  usb_sndintpipe(line6->usbdev,
-                                                 line6->ep_control_write),
-                                  buffer, 2, &partial, LINE6_TIMEOUT * HZ);
-
-       if (retval)
-               dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
-                       retval);
-
-       kfree(buffer);
-       return retval;
-}
-
-/*
-       Transmit Line6 control parameter.
-*/
-int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value)
-{
-       int retval;
-       unsigned char *buffer;
-       int partial;
-
-       buffer = kmalloc(3, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-
-       buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
-       buffer[1] = param;
-       buffer[2] = value;
-
-       retval = usb_interrupt_msg(line6->usbdev,
-                                  usb_sndintpipe(line6->usbdev,
-                                                 line6->ep_control_write),
-                                  buffer, 3, &partial, LINE6_TIMEOUT * HZ);
-
-       if (retval)
-               dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
-                       retval);
-
-       kfree(buffer);
-       return retval;
-}
-
-/*
-       Read data from device.
-*/
-int line6_read_data(struct usb_line6 *line6, int address, void *data,
-                   size_t datalen)
-{
-       struct usb_device *usbdev = line6->usbdev;
-       int ret;
-       unsigned char len;
-
-       /* query the serial number: */
-       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
-                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                             (datalen << 8) | 0x21, address,
-                             NULL, 0, LINE6_TIMEOUT * HZ);
-
-       if (ret < 0) {
-               dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
-               return ret;
-       }
-
-       /* Wait for data length. We'll get 0xff until length arrives. */
-       do {
-               ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
-                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
-                                     USB_DIR_IN,
-                                     0x0012, 0x0000, &len, 1,
-                                     LINE6_TIMEOUT * HZ);
-               if (ret < 0) {
-                       dev_err(line6->ifcdev,
-                               "receive length failed (error %d)\n", ret);
-                       return ret;
-               }
-       } while (len == 0xff);
-
-       if (len != datalen) {
-               /* should be equal or something went wrong */
-               dev_err(line6->ifcdev,
-                       "length mismatch (expected %d, got %d)\n",
-                       (int)datalen, (int)len);
-               return -EINVAL;
-       }
-
-       /* receive the result: */
-       ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
-                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                             0x0013, 0x0000, data, datalen,
-                             LINE6_TIMEOUT * HZ);
-
-       if (ret < 0) {
-               dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
-       Write data to device.
-*/
-int line6_write_data(struct usb_line6 *line6, int address, void *data,
-                    size_t datalen)
-{
-       struct usb_device *usbdev = line6->usbdev;
-       int ret;
-       unsigned char status;
-
-       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
-                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                             0x0022, address, data, datalen,
-                             LINE6_TIMEOUT * HZ);
-
-       if (ret < 0) {
-               dev_err(line6->ifcdev,
-                       "write request failed (error %d)\n", ret);
-               return ret;
-       }
-
-       do {
-               ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
-                                     0x67,
-                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
-                                     USB_DIR_IN,
-                                     0x0012, 0x0000,
-                                     &status, 1, LINE6_TIMEOUT * HZ);
-
-               if (ret < 0) {
-                       dev_err(line6->ifcdev,
-                               "receiving status failed (error %d)\n", ret);
-                       return ret;
-               }
-       } while (status == 0xff);
-
-       if (status != 0) {
-               dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
-       Read Line6 device serial number.
-       (POD, TonePort, GuitarPort)
-*/
-int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
-{
-       return line6_read_data(line6, 0x80d0, serial_number,
-                              sizeof(*serial_number));
-}
-
-/*
-       No operation (i.e., unsupported).
-*/
-ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
-                      char *buf)
-{
-       return 0;
-}
-
-/*
-       Generic destructor.
-*/
-static void line6_destruct(struct usb_interface *interface)
-{
-       struct usb_line6 *line6;
-
-       if (interface == NULL)
-               return;
-       line6 = usb_get_intfdata(interface);
-       if (line6 == NULL)
-               return;
-
-       /* free buffer memory first: */
-       kfree(line6->buffer_message);
-       kfree(line6->buffer_listen);
-
-       /* then free URBs: */
-       usb_free_urb(line6->urb_listen);
-
-       /* make sure the device isn't destructed twice: */
-       usb_set_intfdata(interface, NULL);
-
-       /* free interface data: */
-       kfree(line6);
-}
-
-/*
-       Probe USB device.
-*/
-static int line6_probe(struct usb_interface *interface,
-                      const struct usb_device_id *id)
-{
-       int devtype;
-       struct usb_device *usbdev;
-       struct usb_line6 *line6;
-       const struct line6_properties *properties;
-       int interface_number, alternate = 0;
-       int product;
-       int size = 0;
-       int ep_read = 0, ep_write = 0;
-       int ret;
-
-       if (interface == NULL)
-               return -ENODEV;
-       usbdev = interface_to_usbdev(interface);
-       if (usbdev == NULL)
-               return -ENODEV;
-
-       /* we don't handle multiple configurations */
-       if (usbdev->descriptor.bNumConfigurations != 1) {
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       /* check vendor and product id */
-       for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) {
-               u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor);
-               u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
-
-               if (idVendor == line6_id_table[devtype].idVendor &&
-                   idProduct == line6_id_table[devtype].idProduct)
-                       break;
-       }
-
-       if (devtype < 0) {
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       /* initialize device info: */
-       properties = &line6_properties_table[devtype];
-       dev_info(&interface->dev, "Line6 %s found\n", properties->name);
-       product = le16_to_cpu(usbdev->descriptor.idProduct);
-
-       /* query interface number */
-       interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
-
-       switch (product) {
-       case LINE6_DEVID_BASSPODXTLIVE:
-       case LINE6_DEVID_PODXTLIVE:
-       case LINE6_DEVID_VARIAX:
-               alternate = 1;
-               break;
-
-       case LINE6_DEVID_POCKETPOD:
-               switch (interface_number) {
-               case 0:
-                       return -ENODEV; /* this interface has no endpoints */
-               case 1:
-                       alternate = 0;
-                       break;
-               default:
-                       MISSING_CASE;
-               }
-               break;
-
-       case LINE6_DEVID_PODHD500:
-       case LINE6_DEVID_PODX3:
-       case LINE6_DEVID_PODX3LIVE:
-               switch (interface_number) {
-               case 0:
-                       alternate = 1;
-                       break;
-               case 1:
-                       alternate = 0;
-                       break;
-               default:
-                       MISSING_CASE;
-               }
-               break;
-
-       case LINE6_DEVID_BASSPODXT:
-       case LINE6_DEVID_BASSPODXTPRO:
-       case LINE6_DEVID_PODXT:
-       case LINE6_DEVID_PODXTPRO:
-       case LINE6_DEVID_PODHD300:
-       case LINE6_DEVID_PODHD400:
-               alternate = 5;
-               break;
-
-       case LINE6_DEVID_GUITARPORT:
-       case LINE6_DEVID_PODSTUDIO_GX:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_TONEPORT_GX:
-       case LINE6_DEVID_TONEPORT_UX1:
-               alternate = 2;  /* 1..4 seem to be ok */
-               break;
-
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-               switch (interface_number) {
-               case 0:
-                       /* defaults to 44.1kHz, 16-bit */
-                       alternate = 2;
-                       break;
-               case 1:
-                       /* don't know yet what this is ...
-                          alternate = 1;
-                          break;
-                        */
-                       return -ENODEV;
-               default:
-                       MISSING_CASE;
-               }
-               break;
-
-       default:
-               MISSING_CASE;
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       ret = usb_set_interface(usbdev, interface_number, alternate);
-       if (ret < 0) {
-               dev_err(&interface->dev, "set_interface failed\n");
-               goto err_put;
-       }
-
-       /* initialize device data based on product id: */
-       switch (product) {
-       case LINE6_DEVID_BASSPODXT:
-       case LINE6_DEVID_BASSPODXTLIVE:
-       case LINE6_DEVID_BASSPODXTPRO:
-       case LINE6_DEVID_PODXT:
-       case LINE6_DEVID_PODXTPRO:
-               size = sizeof(struct usb_line6_pod);
-               ep_read = 0x84;
-               ep_write = 0x03;
-               break;
-
-       case LINE6_DEVID_PODHD300:
-       case LINE6_DEVID_PODHD400:
-               size = sizeof(struct usb_line6_podhd);
-               ep_read = 0x84;
-               ep_write = 0x03;
-               break;
-
-       case LINE6_DEVID_PODHD500:
-               size = sizeof(struct usb_line6_podhd);
-               ep_read = 0x81;
-               ep_write = 0x01;
-               break;
-
-       case LINE6_DEVID_POCKETPOD:
-               size = sizeof(struct usb_line6_pod);
-               ep_read = 0x82;
-               ep_write = 0x02;
-               break;
-
-       case LINE6_DEVID_PODX3:
-       case LINE6_DEVID_PODX3LIVE:
-               /* currently unused! */
-               size = sizeof(struct usb_line6_pod);
-               ep_read = 0x81;
-               ep_write = 0x01;
-               break;
-
-       case LINE6_DEVID_PODSTUDIO_GX:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-       case LINE6_DEVID_TONEPORT_GX:
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_GUITARPORT:
-               size = sizeof(struct usb_line6_toneport);
-               /* these don't have a control channel */
-               break;
-
-       case LINE6_DEVID_PODXTLIVE:
-               switch (interface_number) {
-               case PODXTLIVE_INTERFACE_POD:
-                       size = sizeof(struct usb_line6_pod);
-                       ep_read = 0x84;
-                       ep_write = 0x03;
-                       break;
-
-               case PODXTLIVE_INTERFACE_VARIAX:
-                       size = sizeof(struct usb_line6_variax);
-                       ep_read = 0x86;
-                       ep_write = 0x05;
-                       break;
-
-               default:
-                       ret = -ENODEV;
-                       goto err_put;
-               }
-               break;
-
-       case LINE6_DEVID_VARIAX:
-               size = sizeof(struct usb_line6_variax);
-               ep_read = 0x82;
-               ep_write = 0x01;
-               break;
-
-       default:
-               MISSING_CASE;
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       if (size == 0) {
-               dev_err(&interface->dev,
-                       "driver bug: interface data size not set\n");
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       line6 = kzalloc(size, GFP_KERNEL);
-       if (line6 == NULL) {
-               ret = -ENODEV;
-               goto err_put;
-       }
-
-       /* store basic data: */
-       line6->interface_number = interface_number;
-       line6->properties = properties;
-       line6->usbdev = usbdev;
-       line6->ifcdev = &interface->dev;
-       line6->ep_control_read = ep_read;
-       line6->ep_control_write = ep_write;
-       line6->product = product;
-
-       /* get data from endpoint descriptor (see usb_maxpacket): */
-       {
-               struct usb_host_endpoint *ep;
-               unsigned epnum =
-                   usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
-               ep = usbdev->ep_in[epnum];
-
-               if (ep != NULL) {
-                       line6->interval = ep->desc.bInterval;
-                       line6->max_packet_size =
-                           le16_to_cpu(ep->desc.wMaxPacketSize);
-               } else {
-                       line6->interval = LINE6_FALLBACK_INTERVAL;
-                       line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
-                       dev_err(line6->ifcdev,
-                               "endpoint not available, using fallback values");
-               }
-       }
-
-       usb_set_intfdata(interface, line6);
-
-       if (properties->capabilities & LINE6_BIT_CONTROL) {
-               /* initialize USB buffers: */
-               line6->buffer_listen =
-                   kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
-               if (line6->buffer_listen == NULL) {
-                       ret = -ENOMEM;
-                       goto err_destruct;
-               }
-
-               line6->buffer_message =
-                   kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
-               if (line6->buffer_message == NULL) {
-                       ret = -ENOMEM;
-                       goto err_destruct;
-               }
-
-               line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
-
-               if (line6->urb_listen == NULL) {
-                       dev_err(&interface->dev, "Out of memory\n");
-                       line6_destruct(interface);
-                       ret = -ENOMEM;
-                       goto err_destruct;
-               }
-
-               ret = line6_start_listen(line6);
-               if (ret < 0) {
-                       dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
-                               __func__);
-                       goto err_destruct;
-               }
-       }
-
-       /* initialize device data based on product id: */
-       switch (product) {
-       case LINE6_DEVID_BASSPODXT:
-       case LINE6_DEVID_BASSPODXTLIVE:
-       case LINE6_DEVID_BASSPODXTPRO:
-       case LINE6_DEVID_POCKETPOD:
-       case LINE6_DEVID_PODX3:
-       case LINE6_DEVID_PODX3LIVE:
-       case LINE6_DEVID_PODXT:
-       case LINE6_DEVID_PODXTPRO:
-               ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);
-               break;
-
-       case LINE6_DEVID_PODHD300:
-       case LINE6_DEVID_PODHD400:
-       case LINE6_DEVID_PODHD500:
-               ret = line6_podhd_init(interface,
-                                      (struct usb_line6_podhd *)line6);
-               break;
-
-       case LINE6_DEVID_PODXTLIVE:
-               switch (interface_number) {
-               case PODXTLIVE_INTERFACE_POD:
-                       ret =
-                           line6_pod_init(interface,
-                                          (struct usb_line6_pod *)line6);
-                       break;
-
-               case PODXTLIVE_INTERFACE_VARIAX:
-                       ret =
-                           line6_variax_init(interface,
-                                             (struct usb_line6_variax *)line6);
-                       break;
-
-               default:
-                       dev_err(&interface->dev,
-                               "PODxt Live interface %d not supported\n",
-                               interface_number);
-                       ret = -ENODEV;
-               }
-
-               break;
-
-       case LINE6_DEVID_VARIAX:
-               ret =
-                   line6_variax_init(interface,
-                                     (struct usb_line6_variax *)line6);
-               break;
-
-       case LINE6_DEVID_PODSTUDIO_GX:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-       case LINE6_DEVID_TONEPORT_GX:
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_GUITARPORT:
-               ret =
-                   line6_toneport_init(interface,
-                                       (struct usb_line6_toneport *)line6);
-               break;
-
-       default:
-               MISSING_CASE;
-               ret = -ENODEV;
-       }
-
-       if (ret < 0)
-               goto err_destruct;
-
-       ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
-                               "usb_device");
-       if (ret < 0)
-               goto err_destruct;
-
-       /* creation of additional special files should go here */
-
-       dev_info(&interface->dev, "Line6 %s now attached\n",
-                line6->properties->name);
-
-       switch (product) {
-       case LINE6_DEVID_PODX3:
-       case LINE6_DEVID_PODX3LIVE:
-               dev_info(&interface->dev,
-                        "NOTE: the Line6 %s is detected, but not yet supported\n",
-                        line6->properties->name);
-       }
-
-       /* increment reference counters: */
-       usb_get_intf(interface);
-       usb_get_dev(usbdev);
-
-       return 0;
-
-err_destruct:
-       line6_destruct(interface);
-err_put:
-       return ret;
-}
-
-/*
-       Line6 device disconnected.
-*/
-static void line6_disconnect(struct usb_interface *interface)
-{
-       struct usb_line6 *line6;
-       struct usb_device *usbdev;
-       int interface_number;
-
-       if (interface == NULL)
-               return;
-       usbdev = interface_to_usbdev(interface);
-       if (usbdev == NULL)
-               return;
-
-       /* removal of additional special files should go here */
-
-       sysfs_remove_link(&interface->dev.kobj, "usb_device");
-
-       interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
-       line6 = usb_get_intfdata(interface);
-
-       if (line6 != NULL) {
-               if (line6->urb_listen != NULL)
-                       line6_stop_listen(line6);
-
-               if (usbdev != line6->usbdev)
-                       dev_err(line6->ifcdev,
-                               "driver bug: inconsistent usb device\n");
-
-               switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
-               case LINE6_DEVID_BASSPODXT:
-               case LINE6_DEVID_BASSPODXTLIVE:
-               case LINE6_DEVID_BASSPODXTPRO:
-               case LINE6_DEVID_POCKETPOD:
-               case LINE6_DEVID_PODX3:
-               case LINE6_DEVID_PODX3LIVE:
-               case LINE6_DEVID_PODXT:
-               case LINE6_DEVID_PODXTPRO:
-                       line6_pod_disconnect(interface);
-                       break;
-
-               case LINE6_DEVID_PODHD300:
-               case LINE6_DEVID_PODHD400:
-               case LINE6_DEVID_PODHD500:
-                       line6_podhd_disconnect(interface);
-                       break;
-
-               case LINE6_DEVID_PODXTLIVE:
-                       switch (interface_number) {
-                       case PODXTLIVE_INTERFACE_POD:
-                               line6_pod_disconnect(interface);
-                               break;
-
-                       case PODXTLIVE_INTERFACE_VARIAX:
-                               line6_variax_disconnect(interface);
-                               break;
-                       }
-
-                       break;
-
-               case LINE6_DEVID_VARIAX:
-                       line6_variax_disconnect(interface);
-                       break;
-
-               case LINE6_DEVID_PODSTUDIO_GX:
-               case LINE6_DEVID_PODSTUDIO_UX1:
-               case LINE6_DEVID_PODSTUDIO_UX2:
-               case LINE6_DEVID_TONEPORT_GX:
-               case LINE6_DEVID_TONEPORT_UX1:
-               case LINE6_DEVID_TONEPORT_UX2:
-               case LINE6_DEVID_GUITARPORT:
-                       line6_toneport_disconnect(interface);
-                       break;
-
-               default:
-                       MISSING_CASE;
-               }
-
-               dev_info(&interface->dev, "Line6 %s now disconnected\n",
-                        line6->properties->name);
-       }
-
-       line6_destruct(interface);
-
-       /* decrement reference counters: */
-       usb_put_intf(interface);
-       usb_put_dev(usbdev);
-}
-
-#ifdef CONFIG_PM
-
-/*
-       Suspend Line6 device.
-*/
-static int line6_suspend(struct usb_interface *interface, pm_message_t message)
-{
-       struct usb_line6 *line6 = usb_get_intfdata(interface);
-       struct snd_line6_pcm *line6pcm = line6->line6pcm;
-
-       snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
-
-       if (line6->properties->capabilities & LINE6_BIT_CONTROL)
-               line6_stop_listen(line6);
-
-       if (line6pcm != NULL) {
-               snd_pcm_suspend_all(line6pcm->pcm);
-               line6_pcm_disconnect(line6pcm);
-               line6pcm->flags = 0;
-       }
-
-       return 0;
-}
-
-/*
-       Resume Line6 device.
-*/
-static int line6_resume(struct usb_interface *interface)
-{
-       struct usb_line6 *line6 = usb_get_intfdata(interface);
-
-       if (line6->properties->capabilities & LINE6_BIT_CONTROL)
-               line6_start_listen(line6);
-
-       snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
-       return 0;
-}
-
-/*
-       Resume Line6 device after reset.
-*/
-static int line6_reset_resume(struct usb_interface *interface)
-{
-       struct usb_line6 *line6 = usb_get_intfdata(interface);
-
-       switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) {
-       case LINE6_DEVID_PODSTUDIO_GX:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-       case LINE6_DEVID_TONEPORT_GX:
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_GUITARPORT:
-               line6_toneport_reset_resume((struct usb_line6_toneport *)line6);
-       }
-
-       return line6_resume(interface);
-}
-
-#endif /* CONFIG_PM */
-
-static struct usb_driver line6_driver = {
-       .name = DRIVER_NAME,
-       .probe = line6_probe,
-       .disconnect = line6_disconnect,
-#ifdef CONFIG_PM
-       .suspend = line6_suspend,
-       .resume = line6_resume,
-       .reset_resume = line6_reset_resume,
-#endif
-       .id_table = line6_id_table,
-};
-
-module_usb_driver(line6_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
deleted file mode 100644 (file)
index 16e3fc2..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef DRIVER_H
-#define DRIVER_H
-
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-
-#include "midi.h"
-
-#define DRIVER_NAME "line6usb"
-
-#define LINE6_TIMEOUT 1
-#define LINE6_BUFSIZE_LISTEN 32
-#define LINE6_MESSAGE_MAXLEN 256
-
-/*
-       Line6 MIDI control commands
-*/
-#define LINE6_PARAM_CHANGE   0xb0
-#define LINE6_PROGRAM_CHANGE 0xc0
-#define LINE6_SYSEX_BEGIN    0xf0
-#define LINE6_SYSEX_END      0xf7
-#define LINE6_RESET          0xff
-
-/*
-       MIDI channel for messages initiated by the host
-       (and eventually echoed back by the device)
-*/
-#define LINE6_CHANNEL_HOST   0x00
-
-/*
-       MIDI channel for messages initiated by the device
-*/
-#define LINE6_CHANNEL_DEVICE 0x02
-
-#define LINE6_CHANNEL_UNKNOWN 5        /* don't know yet what this is good for */
-
-#define LINE6_CHANNEL_MASK 0x0f
-
-#define MISSING_CASE   \
-       pr_err("line6usb driver bug: missing case in %s:%d\n", \
-               __FILE__, __LINE__)
-
-#define CHECK_RETURN(x)                \
-do {                           \
-       err = x;                \
-       if (err < 0)            \
-               return err;     \
-} while (0)
-
-#define CHECK_STARTUP_PROGRESS(x, n)   \
-do {                                   \
-       if ((x) >= (n))                 \
-               return;                 \
-       x = (n);                        \
-} while (0)
-
-extern const unsigned char line6_midi_id[3];
-
-static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
-static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
-
-/**
-        Common properties of Line6 devices.
-*/
-struct line6_properties {
-       /**
-                Bit identifying this device in the line6usb driver.
-       */
-       int device_bit;
-
-       /**
-                Card id string (maximum 16 characters).
-                This can be used to address the device in ALSA programs as
-                "default:CARD=<id>"
-       */
-       const char *id;
-
-       /**
-                Card short name (maximum 32 characters).
-       */
-       const char *name;
-
-       /**
-                Bit vector defining this device's capabilities in the
-                line6usb driver.
-       */
-       int capabilities;
-};
-
-/**
-        Common data shared by all Line6 devices.
-        Corresponds to a pair of USB endpoints.
-*/
-struct usb_line6 {
-       /**
-                USB device.
-       */
-       struct usb_device *usbdev;
-
-       /**
-                Product id.
-       */
-       int product;
-
-       /**
-                Properties.
-       */
-       const struct line6_properties *properties;
-
-       /**
-                Interface number.
-       */
-       int interface_number;
-
-       /**
-                Interval (ms).
-       */
-       int interval;
-
-       /**
-                Maximum size of USB packet.
-       */
-       int max_packet_size;
-
-       /**
-                Device representing the USB interface.
-       */
-       struct device *ifcdev;
-
-       /**
-                Line6 sound card data structure.
-                Each device has at least MIDI or PCM.
-       */
-       struct snd_card *card;
-
-       /**
-                Line6 PCM device data structure.
-       */
-       struct snd_line6_pcm *line6pcm;
-
-       /**
-                Line6 MIDI device data structure.
-       */
-       struct snd_line6_midi *line6midi;
-
-       /**
-                USB endpoint for listening to control commands.
-       */
-       int ep_control_read;
-
-       /**
-                USB endpoint for writing control commands.
-       */
-       int ep_control_write;
-
-       /**
-                URB for listening to PODxt Pro control endpoint.
-       */
-       struct urb *urb_listen;
-
-       /**
-                Buffer for listening to PODxt Pro control endpoint.
-       */
-       unsigned char *buffer_listen;
-
-       /**
-                Buffer for message to be processed.
-       */
-       unsigned char *buffer_message;
-
-       /**
-                Length of message to be processed.
-       */
-       int message_length;
-};
-
-extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
-                                     int code2, int size);
-extern ssize_t line6_nop_read(struct device *dev,
-                             struct device_attribute *attr, char *buf);
-extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
-                          size_t datalen);
-extern int line6_read_serial_number(struct usb_line6 *line6,
-                                   int *serial_number);
-extern int line6_send_program(struct usb_line6 *line6, u8 value);
-extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
-                                 int size);
-extern int line6_send_raw_message_async(struct usb_line6 *line6,
-                                       const char *buffer, int size);
-extern int line6_send_sysex_message(struct usb_line6 *line6,
-                                   const char *buffer, int size);
-extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
-                            const char *buf, size_t count);
-extern void line6_start_timer(struct timer_list *timer, unsigned int msecs,
-                             void (*function)(unsigned long),
-                             unsigned long data);
-extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
-                                   u8 value);
-extern int line6_version_request_async(struct usb_line6 *line6);
-extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
-                           size_t datalen);
-
-#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
deleted file mode 100644 (file)
index 1ac343b..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/rawmidi.h>
-
-#include "audio.h"
-#include "driver.h"
-#include "midi.h"
-#include "pod.h"
-#include "usbdefs.h"
-
-#define line6_rawmidi_substream_midi(substream) \
-       ((struct snd_line6_midi *)((substream)->rmidi->private_data))
-
-static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
-                          int length);
-
-/*
-       Pass data received via USB to MIDI.
-*/
-void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
-                       int length)
-{
-       if (line6->line6midi->substream_receive)
-               snd_rawmidi_receive(line6->line6midi->substream_receive,
-                                   data, length);
-}
-
-/*
-       Read data from MIDI buffer and transmit them via USB.
-*/
-static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
-{
-       struct usb_line6 *line6 =
-           line6_rawmidi_substream_midi(substream)->line6;
-       struct snd_line6_midi *line6midi = line6->line6midi;
-       struct midi_buffer *mb = &line6midi->midibuf_out;
-       unsigned long flags;
-       unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];
-       int req, done;
-
-       spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
-
-       for (;;) {
-               req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
-               done = snd_rawmidi_transmit_peek(substream, chunk, req);
-
-               if (done == 0)
-                       break;
-
-               line6_midibuf_write(mb, chunk, done);
-               snd_rawmidi_transmit_ack(substream, done);
-       }
-
-       for (;;) {
-               done = line6_midibuf_read(mb, chunk,
-                                         LINE6_FALLBACK_MAXPACKETSIZE);
-
-               if (done == 0)
-                       break;
-
-               send_midi_async(line6, chunk, done);
-       }
-
-       spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
-}
-
-/*
-       Notification of completion of MIDI transmission.
-*/
-static void midi_sent(struct urb *urb)
-{
-       unsigned long flags;
-       int status;
-       int num;
-       struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
-
-       status = urb->status;
-       kfree(urb->transfer_buffer);
-       usb_free_urb(urb);
-
-       if (status == -ESHUTDOWN)
-               return;
-
-       spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
-       num = --line6->line6midi->num_active_send_urbs;
-
-       if (num == 0) {
-               line6_midi_transmit(line6->line6midi->substream_transmit);
-               num = line6->line6midi->num_active_send_urbs;
-       }
-
-       if (num == 0)
-               wake_up(&line6->line6midi->send_wait);
-
-       spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
-}
-
-/*
-       Send an asynchronous MIDI message.
-       Assumes that line6->line6midi->send_urb_lock is held
-       (i.e., this function is serialized).
-*/
-static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
-                          int length)
-{
-       struct urb *urb;
-       int retval;
-       unsigned char *transfer_buffer;
-
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-
-       if (urb == NULL) {
-               dev_err(line6->ifcdev, "Out of memory\n");
-               return -ENOMEM;
-       }
-
-       transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
-
-       if (transfer_buffer == NULL) {
-               usb_free_urb(urb);
-               dev_err(line6->ifcdev, "Out of memory\n");
-               return -ENOMEM;
-       }
-
-       usb_fill_int_urb(urb, line6->usbdev,
-                        usb_sndbulkpipe(line6->usbdev,
-                                        line6->ep_control_write),
-                        transfer_buffer, length, midi_sent, line6,
-                        line6->interval);
-       urb->actual_length = 0;
-       retval = usb_submit_urb(urb, GFP_ATOMIC);
-
-       if (retval < 0) {
-               dev_err(line6->ifcdev, "usb_submit_urb failed\n");
-               usb_free_urb(urb);
-               return retval;
-       }
-
-       ++line6->line6midi->num_active_send_urbs;
-       return 0;
-}
-
-static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
-{
-       return 0;
-}
-
-static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
-{
-       return 0;
-}
-
-static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
-                                     int up)
-{
-       unsigned long flags;
-       struct usb_line6 *line6 =
-           line6_rawmidi_substream_midi(substream)->line6;
-
-       line6->line6midi->substream_transmit = substream;
-       spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
-
-       if (line6->line6midi->num_active_send_urbs == 0)
-               line6_midi_transmit(substream);
-
-       spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
-}
-
-static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
-{
-       struct usb_line6 *line6 =
-           line6_rawmidi_substream_midi(substream)->line6;
-       struct snd_line6_midi *midi = line6->line6midi;
-
-       wait_event_interruptible(midi->send_wait,
-                                midi->num_active_send_urbs == 0);
-}
-
-static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
-{
-       return 0;
-}
-
-static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
-{
-       return 0;
-}
-
-static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
-                                    int up)
-{
-       struct usb_line6 *line6 =
-           line6_rawmidi_substream_midi(substream)->line6;
-
-       if (up)
-               line6->line6midi->substream_receive = substream;
-       else
-               line6->line6midi->substream_receive = NULL;
-}
-
-static struct snd_rawmidi_ops line6_midi_output_ops = {
-       .open = line6_midi_output_open,
-       .close = line6_midi_output_close,
-       .trigger = line6_midi_output_trigger,
-       .drain = line6_midi_output_drain,
-};
-
-static struct snd_rawmidi_ops line6_midi_input_ops = {
-       .open = line6_midi_input_open,
-       .close = line6_midi_input_close,
-       .trigger = line6_midi_input_trigger,
-};
-
-/*
-       Cleanup the Line6 MIDI device.
-*/
-static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
-{
-}
-
-/* Create a MIDI device */
-static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
-{
-       struct snd_rawmidi *rmidi;
-       int err;
-
-       err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1,
-                             &rmidi);
-       if (err < 0)
-               return err;
-
-       rmidi->private_data = line6midi;
-       rmidi->private_free = line6_cleanup_midi;
-       strcpy(rmidi->id, line6midi->line6->properties->id);
-       strcpy(rmidi->name, line6midi->line6->properties->name);
-
-       rmidi->info_flags =
-           SNDRV_RAWMIDI_INFO_OUTPUT |
-           SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
-
-       snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
-                           &line6_midi_output_ops);
-       snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
-                           &line6_midi_input_ops);
-       return 0;
-}
-
-/* MIDI device destructor */
-static int snd_line6_midi_free(struct snd_device *device)
-{
-       struct snd_line6_midi *line6midi = device->device_data;
-
-       line6_midibuf_destroy(&line6midi->midibuf_in);
-       line6_midibuf_destroy(&line6midi->midibuf_out);
-       return 0;
-}
-
-/*
-       Initialize the Line6 MIDI subsystem.
-*/
-int line6_init_midi(struct usb_line6 *line6)
-{
-       static struct snd_device_ops midi_ops = {
-               .dev_free = snd_line6_midi_free,
-       };
-
-       int err;
-       struct snd_line6_midi *line6midi;
-
-       if (!(line6->properties->capabilities & LINE6_BIT_CONTROL)) {
-               /* skip MIDI initialization and report success */
-               return 0;
-       }
-
-       line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
-
-       if (line6midi == NULL)
-               return -ENOMEM;
-
-       err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
-       if (err < 0) {
-               kfree(line6midi);
-               return err;
-       }
-
-       err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
-       if (err < 0) {
-               kfree(line6midi->midibuf_in.buf);
-               kfree(line6midi);
-               return err;
-       }
-
-       line6midi->line6 = line6;
-       line6->line6midi = line6midi;
-
-       err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
-                            &midi_ops);
-       if (err < 0)
-               return err;
-
-       err = snd_line6_new_midi(line6midi);
-       if (err < 0)
-               return err;
-
-       init_waitqueue_head(&line6midi->send_wait);
-       spin_lock_init(&line6midi->send_urb_lock);
-       spin_lock_init(&line6midi->midi_transmit_lock);
-       return 0;
-}
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
deleted file mode 100644 (file)
index 78f903f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef MIDI_H
-#define MIDI_H
-
-#include <sound/rawmidi.h>
-
-#include "midibuf.h"
-
-#define MIDI_BUFFER_SIZE 1024
-
-struct snd_line6_midi {
-       /**
-                Pointer back to the Line6 driver data structure.
-       */
-       struct usb_line6 *line6;
-
-       /**
-                MIDI substream for receiving (or NULL if not active).
-       */
-       struct snd_rawmidi_substream *substream_receive;
-
-       /**
-                MIDI substream for transmitting (or NULL if not active).
-       */
-       struct snd_rawmidi_substream *substream_transmit;
-
-       /**
-                Number of currently active MIDI send URBs.
-       */
-       int num_active_send_urbs;
-
-       /**
-                Spin lock to protect updates of send_urb.
-       */
-       spinlock_t send_urb_lock;
-
-       /**
-                Spin lock to protect MIDI buffer handling.
-       */
-       spinlock_t midi_transmit_lock;
-
-       /**
-                Wait queue for MIDI transmission.
-       */
-       wait_queue_head_t send_wait;
-
-       /**
-                Buffer for incoming MIDI stream.
-       */
-       struct midi_buffer midibuf_in;
-
-       /**
-                Buffer for outgoing MIDI stream.
-       */
-       struct midi_buffer midibuf_out;
-};
-
-extern int line6_init_midi(struct usb_line6 *line6);
-extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
-                              int length);
-
-#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
deleted file mode 100644 (file)
index 1ff8569..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-
-#include "midibuf.h"
-
-static int midibuf_message_length(unsigned char code)
-{
-       int message_length;
-
-       if (code < 0x80)
-               message_length = -1;
-       else if (code < 0xf0) {
-               static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
-
-               message_length = length[(code >> 4) - 8];
-       } else {
-               /*
-                  Note that according to the MIDI specification 0xf2 is
-                  the "Song Position Pointer", but this is used by Line6
-                  to send sysex messages to the host.
-                */
-               static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
-                       1, 1, 1, -1, 1, 1
-               };
-               message_length = length[code & 0x0f];
-       }
-
-       return message_length;
-}
-
-static int midibuf_is_empty(struct midi_buffer *this)
-{
-       return (this->pos_read == this->pos_write) && !this->full;
-}
-
-static int midibuf_is_full(struct midi_buffer *this)
-{
-       return this->full;
-}
-
-void line6_midibuf_reset(struct midi_buffer *this)
-{
-       this->pos_read = this->pos_write = this->full = 0;
-       this->command_prev = -1;
-}
-
-int line6_midibuf_init(struct midi_buffer *this, int size, int split)
-{
-       this->buf = kmalloc(size, GFP_KERNEL);
-
-       if (this->buf == NULL)
-               return -ENOMEM;
-
-       this->size = size;
-       this->split = split;
-       line6_midibuf_reset(this);
-       return 0;
-}
-
-void line6_midibuf_status(struct midi_buffer *this)
-{
-       pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n",
-                this->size, this->split, this->pos_read, this->pos_write,
-                this->full, this->command_prev);
-}
-
-int line6_midibuf_bytes_free(struct midi_buffer *this)
-{
-       return
-           midibuf_is_full(this) ?
-           0 :
-           (this->pos_read - this->pos_write + this->size - 1) % this->size +
-           1;
-}
-
-int line6_midibuf_bytes_used(struct midi_buffer *this)
-{
-       return
-           midibuf_is_empty(this) ?
-           0 :
-           (this->pos_write - this->pos_read + this->size - 1) % this->size +
-           1;
-}
-
-int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
-                       int length)
-{
-       int bytes_free;
-       int length1, length2;
-       int skip_active_sense = 0;
-
-       if (midibuf_is_full(this) || (length <= 0))
-               return 0;
-
-       /* skip trailing active sense */
-       if (data[length - 1] == 0xfe) {
-               --length;
-               skip_active_sense = 1;
-       }
-
-       bytes_free = line6_midibuf_bytes_free(this);
-
-       if (length > bytes_free)
-               length = bytes_free;
-
-       if (length > 0) {
-               length1 = this->size - this->pos_write;
-
-               if (length < length1) {
-                       /* no buffer wraparound */
-                       memcpy(this->buf + this->pos_write, data, length);
-                       this->pos_write += length;
-               } else {
-                       /* buffer wraparound */
-                       length2 = length - length1;
-                       memcpy(this->buf + this->pos_write, data, length1);
-                       memcpy(this->buf, data + length1, length2);
-                       this->pos_write = length2;
-               }
-
-               if (this->pos_write == this->pos_read)
-                       this->full = 1;
-       }
-
-       return length + skip_active_sense;
-}
-
-int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
-                      int length)
-{
-       int bytes_used;
-       int length1, length2;
-       int command;
-       int midi_length;
-       int repeat = 0;
-       int i;
-
-       /* we need to be able to store at least a 3 byte MIDI message */
-       if (length < 3)
-               return -EINVAL;
-
-       if (midibuf_is_empty(this))
-               return 0;
-
-       bytes_used = line6_midibuf_bytes_used(this);
-
-       if (length > bytes_used)
-               length = bytes_used;
-
-       length1 = this->size - this->pos_read;
-
-       /* check MIDI command length */
-       command = this->buf[this->pos_read];
-
-       if (command & 0x80) {
-               midi_length = midibuf_message_length(command);
-               this->command_prev = command;
-       } else {
-               if (this->command_prev > 0) {
-                       int midi_length_prev =
-                           midibuf_message_length(this->command_prev);
-
-                       if (midi_length_prev > 0) {
-                               midi_length = midi_length_prev - 1;
-                               repeat = 1;
-                       } else
-                               midi_length = -1;
-               } else
-                       midi_length = -1;
-       }
-
-       if (midi_length < 0) {
-               /* search for end of message */
-               if (length < length1) {
-                       /* no buffer wraparound */
-                       for (i = 1; i < length; ++i)
-                               if (this->buf[this->pos_read + i] & 0x80)
-                                       break;
-
-                       midi_length = i;
-               } else {
-                       /* buffer wraparound */
-                       length2 = length - length1;
-
-                       for (i = 1; i < length1; ++i)
-                               if (this->buf[this->pos_read + i] & 0x80)
-                                       break;
-
-                       if (i < length1)
-                               midi_length = i;
-                       else {
-                               for (i = 0; i < length2; ++i)
-                                       if (this->buf[i] & 0x80)
-                                               break;
-
-                               midi_length = length1 + i;
-                       }
-               }
-
-               if (midi_length == length)
-                       midi_length = -1;       /* end of message not found */
-       }
-
-       if (midi_length < 0) {
-               if (!this->split)
-                       return 0;       /* command is not yet complete */
-       } else {
-               if (length < midi_length)
-                       return 0;       /* command is not yet complete */
-
-               length = midi_length;
-       }
-
-       if (length < length1) {
-               /* no buffer wraparound */
-               memcpy(data + repeat, this->buf + this->pos_read, length);
-               this->pos_read += length;
-       } else {
-               /* buffer wraparound */
-               length2 = length - length1;
-               memcpy(data + repeat, this->buf + this->pos_read, length1);
-               memcpy(data + repeat + length1, this->buf, length2);
-               this->pos_read = length2;
-       }
-
-       if (repeat)
-               data[0] = this->command_prev;
-
-       this->full = 0;
-       return length + repeat;
-}
-
-int line6_midibuf_ignore(struct midi_buffer *this, int length)
-{
-       int bytes_used = line6_midibuf_bytes_used(this);
-
-       if (length > bytes_used)
-               length = bytes_used;
-
-       this->pos_read = (this->pos_read + length) % this->size;
-       this->full = 0;
-       return length;
-}
-
-int line6_midibuf_skip_message(struct midi_buffer *this, unsigned short mask)
-{
-       int cmd = this->command_prev;
-
-       if ((cmd >= 0x80) && (cmd < 0xf0))
-               if ((mask & (1 << (cmd & 0x0f))) == 0)
-                       return 1;
-
-       return 0;
-}
-
-void line6_midibuf_destroy(struct midi_buffer *this)
-{
-       kfree(this->buf);
-       this->buf = NULL;
-}
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
deleted file mode 100644 (file)
index 707482b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef MIDIBUF_H
-#define MIDIBUF_H
-
-struct midi_buffer {
-       unsigned char *buf;
-       int size;
-       int split;
-       int pos_read, pos_write;
-       int full;
-       int command_prev;
-};
-
-extern int line6_midibuf_bytes_used(struct midi_buffer *mb);
-extern int line6_midibuf_bytes_free(struct midi_buffer *mb);
-extern void line6_midibuf_destroy(struct midi_buffer *mb);
-extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
-extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
-extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
-                             int length);
-extern void line6_midibuf_reset(struct midi_buffer *mb);
-extern int line6_midibuf_skip_message(struct midi_buffer *mb,
-                                     unsigned short mask);
-extern void line6_midibuf_status(struct midi_buffer *mb);
-extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
-                              int length);
-
-#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
deleted file mode 100644 (file)
index a3136b1..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "playback.h"
-#include "pod.h"
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-
-static struct snd_line6_pcm *dev2pcm(struct device *dev)
-{
-       struct usb_interface *interface = to_usb_interface(dev);
-       struct usb_line6 *line6 = usb_get_intfdata(interface);
-       struct snd_line6_pcm *line6pcm = line6->line6pcm;
-       return line6pcm;
-}
-
-/*
-       "read" request on "impulse_volume" special file.
-*/
-static ssize_t impulse_volume_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
-{
-       return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);
-}
-
-/*
-       "write" request on "impulse_volume" special file.
-*/
-static ssize_t impulse_volume_store(struct device *dev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t count)
-{
-       struct snd_line6_pcm *line6pcm = dev2pcm(dev);
-       int value;
-       int ret;
-
-       ret = kstrtoint(buf, 10, &value);
-       if (ret < 0)
-               return ret;
-
-       line6pcm->impulse_volume = value;
-
-       if (value > 0)
-               line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);
-       else
-               line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);
-
-       return count;
-}
-static DEVICE_ATTR_RW(impulse_volume);
-
-/*
-       "read" request on "impulse_period" special file.
-*/
-static ssize_t impulse_period_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
-{
-       return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);
-}
-
-/*
-       "write" request on "impulse_period" special file.
-*/
-static ssize_t impulse_period_store(struct device *dev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t count)
-{
-       int value;
-       int ret;
-
-       ret = kstrtoint(buf, 10, &value);
-       if (ret < 0)
-               return ret;
-
-       dev2pcm(dev)->impulse_period = value;
-       return count;
-}
-static DEVICE_ATTR_RW(impulse_period);
-
-#endif
-
-static bool test_flags(unsigned long flags0, unsigned long flags1,
-                      unsigned long mask)
-{
-       return ((flags0 & mask) == 0) && ((flags1 & mask) != 0);
-}
-
-int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
-{
-       unsigned long flags_old, flags_new, flags_final;
-       int err;
-
-       do {
-               flags_old = ACCESS_ONCE(line6pcm->flags);
-               flags_new = flags_old | channels;
-       } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
-
-       flags_final = flags_old;
-
-       line6pcm->prev_fbuf = NULL;
-
-       if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
-               /* Invoked multiple times in a row so allocate once only */
-               if (!line6pcm->buffer_in) {
-                       line6pcm->buffer_in =
-                               kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-                                       line6pcm->max_packet_size, GFP_KERNEL);
-                       if (!line6pcm->buffer_in) {
-                               err = -ENOMEM;
-                               goto pcm_acquire_error;
-                       }
-
-                       flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
-               }
-       }
-
-       if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {
-               /*
-                  Waiting for completion of active URBs in the stop handler is
-                  a bug, we therefore report an error if capturing is restarted
-                  too soon.
-                */
-               if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) {
-                       dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
-                       return -EBUSY;
-               }
-
-               line6pcm->count_in = 0;
-               line6pcm->prev_fsize = 0;
-               err = line6_submit_audio_in_all_urbs(line6pcm);
-
-               if (err < 0)
-                       goto pcm_acquire_error;
-
-               flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
-       }
-
-       if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
-               /* Invoked multiple times in a row so allocate once only */
-               if (!line6pcm->buffer_out) {
-                       line6pcm->buffer_out =
-                               kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-                                       line6pcm->max_packet_size, GFP_KERNEL);
-                       if (!line6pcm->buffer_out) {
-                               err = -ENOMEM;
-                               goto pcm_acquire_error;
-                       }
-
-                       flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
-               }
-       }
-
-       if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
-               /*
-                 See comment above regarding PCM restart.
-               */
-               if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) {
-                       dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
-                       return -EBUSY;
-               }
-
-               line6pcm->count_out = 0;
-               err = line6_submit_audio_out_all_urbs(line6pcm);
-
-               if (err < 0)
-                       goto pcm_acquire_error;
-
-               flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM;
-       }
-
-       return 0;
-
-pcm_acquire_error:
-       /*
-          If not all requested resources/streams could be obtained, release
-          those which were successfully obtained (if any).
-       */
-       line6_pcm_release(line6pcm, flags_final & channels);
-       return err;
-}
-
-int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
-{
-       unsigned long flags_old, flags_new;
-
-       do {
-               flags_old = ACCESS_ONCE(line6pcm->flags);
-               flags_new = flags_old & ~channels;
-       } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
-
-       if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
-               line6_unlink_audio_in_urbs(line6pcm);
-
-       if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) {
-               line6_wait_clear_audio_in_urbs(line6pcm);
-               line6_free_capture_buffer(line6pcm);
-       }
-
-       if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
-               line6_unlink_audio_out_urbs(line6pcm);
-
-       if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) {
-               line6_wait_clear_audio_out_urbs(line6pcm);
-               line6_free_playback_buffer(line6pcm);
-       }
-
-       return 0;
-}
-
-/* trigger callback */
-int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-       struct snd_pcm_substream *s;
-       int err;
-       unsigned long flags;
-
-       spin_lock_irqsave(&line6pcm->lock_trigger, flags);
-       clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
-
-       snd_pcm_group_for_each_entry(s, substream) {
-               switch (s->stream) {
-               case SNDRV_PCM_STREAM_PLAYBACK:
-                       err = snd_line6_playback_trigger(line6pcm, cmd);
-
-                       if (err < 0) {
-                               spin_unlock_irqrestore(&line6pcm->lock_trigger,
-                                                      flags);
-                               return err;
-                       }
-
-                       break;
-
-               case SNDRV_PCM_STREAM_CAPTURE:
-                       err = snd_line6_capture_trigger(line6pcm, cmd);
-
-                       if (err < 0) {
-                               spin_unlock_irqrestore(&line6pcm->lock_trigger,
-                                                      flags);
-                               return err;
-                       }
-
-                       break;
-
-               default:
-                       dev_err(line6pcm->line6->ifcdev,
-                               "Unknown stream direction %d\n", s->stream);
-               }
-       }
-
-       spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
-       return 0;
-}
-
-/* control info callback */
-static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
-                                          struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       uinfo->count = 2;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 256;
-       return 0;
-}
-
-/* control get callback */
-static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
-                                         struct snd_ctl_elem_value *ucontrol)
-{
-       int i;
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-
-       for (i = 2; i--;)
-               ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
-
-       return 0;
-}
-
-/* control put callback */
-static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
-                                         struct snd_ctl_elem_value *ucontrol)
-{
-       int i, changed = 0;
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-
-       for (i = 2; i--;)
-               if (line6pcm->volume_playback[i] !=
-                   ucontrol->value.integer.value[i]) {
-                       line6pcm->volume_playback[i] =
-                           ucontrol->value.integer.value[i];
-                       changed = 1;
-               }
-
-       return changed;
-}
-
-/* control definition */
-static struct snd_kcontrol_new line6_control_playback = {
-       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name = "PCM Playback Volume",
-       .index = 0,
-       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-       .info = snd_line6_control_playback_info,
-       .get = snd_line6_control_playback_get,
-       .put = snd_line6_control_playback_put
-};
-
-/*
-       Cleanup the PCM device.
-*/
-static void line6_cleanup_pcm(struct snd_pcm *pcm)
-{
-       int i;
-       struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_volume);
-       device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_period);
-#endif
-
-       for (i = LINE6_ISO_BUFFERS; i--;) {
-               if (line6pcm->urb_audio_out[i]) {
-                       usb_kill_urb(line6pcm->urb_audio_out[i]);
-                       usb_free_urb(line6pcm->urb_audio_out[i]);
-               }
-               if (line6pcm->urb_audio_in[i]) {
-                       usb_kill_urb(line6pcm->urb_audio_in[i]);
-                       usb_free_urb(line6pcm->urb_audio_in[i]);
-               }
-       }
-}
-
-/* create a PCM device */
-static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
-{
-       struct snd_pcm *pcm;
-       int err;
-
-       err = snd_pcm_new(line6pcm->line6->card,
-                         (char *)line6pcm->line6->properties->name,
-                         0, 1, 1, &pcm);
-       if (err < 0)
-               return err;
-
-       pcm->private_data = line6pcm;
-       pcm->private_free = line6_cleanup_pcm;
-       line6pcm->pcm = pcm;
-       strcpy(pcm->name, line6pcm->line6->properties->name);
-
-       /* set operators */
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                       &snd_line6_playback_ops);
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
-
-       /* pre-allocation of buffers */
-       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
-                                             snd_dma_continuous_data
-                                             (GFP_KERNEL), 64 * 1024,
-                                             128 * 1024);
-
-       return 0;
-}
-
-/* PCM device destructor */
-static int snd_line6_pcm_free(struct snd_device *device)
-{
-       return 0;
-}
-
-/*
-       Stop substream if still running.
-*/
-static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
-{
-       if (substream->runtime && snd_pcm_running(substream)) {
-               snd_pcm_stream_lock_irq(substream);
-               snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
-               snd_pcm_stream_unlock_irq(substream);
-       }
-}
-
-/*
-       Stop PCM stream.
-*/
-void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
-{
-       pcm_disconnect_substream(get_substream
-                                (line6pcm, SNDRV_PCM_STREAM_CAPTURE));
-       pcm_disconnect_substream(get_substream
-                                (line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
-       line6_unlink_wait_clear_audio_out_urbs(line6pcm);
-       line6_unlink_wait_clear_audio_in_urbs(line6pcm);
-}
-
-/*
-       Create and register the PCM device and mixer entries.
-       Create URBs for playback and capture.
-*/
-int line6_init_pcm(struct usb_line6 *line6,
-                  struct line6_pcm_properties *properties)
-{
-       static struct snd_device_ops pcm_ops = {
-               .dev_free = snd_line6_pcm_free,
-       };
-
-       int err;
-       int ep_read = 0, ep_write = 0;
-       struct snd_line6_pcm *line6pcm;
-
-       if (!(line6->properties->capabilities & LINE6_BIT_PCM))
-               return 0;       /* skip PCM initialization and report success */
-
-       /* initialize PCM subsystem based on product id: */
-       switch (line6->product) {
-       case LINE6_DEVID_BASSPODXT:
-       case LINE6_DEVID_BASSPODXTLIVE:
-       case LINE6_DEVID_BASSPODXTPRO:
-       case LINE6_DEVID_PODXT:
-       case LINE6_DEVID_PODXTLIVE:
-       case LINE6_DEVID_PODXTPRO:
-       case LINE6_DEVID_PODHD300:
-       case LINE6_DEVID_PODHD400:
-               ep_read = 0x82;
-               ep_write = 0x01;
-               break;
-
-       case LINE6_DEVID_PODHD500:
-       case LINE6_DEVID_PODX3:
-       case LINE6_DEVID_PODX3LIVE:
-               ep_read = 0x86;
-               ep_write = 0x02;
-               break;
-
-       case LINE6_DEVID_POCKETPOD:
-               ep_read = 0x82;
-               ep_write = 0x02;
-               break;
-
-       case LINE6_DEVID_GUITARPORT:
-       case LINE6_DEVID_PODSTUDIO_GX:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-       case LINE6_DEVID_TONEPORT_GX:
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-               ep_read = 0x82;
-               ep_write = 0x01;
-               break;
-
-       /* this is for interface_number == 1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-               ep_read  = 0x87;
-               ep_write = 0x00;
-               break; */
-
-       default:
-               MISSING_CASE;
-       }
-
-       line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
-
-       if (line6pcm == NULL)
-               return -ENOMEM;
-
-       line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
-       line6pcm->volume_monitor = 255;
-       line6pcm->line6 = line6;
-       line6pcm->ep_audio_read = ep_read;
-       line6pcm->ep_audio_write = ep_write;
-
-       /* Read and write buffers are sized identically, so choose minimum */
-       line6pcm->max_packet_size = min(
-                       usb_maxpacket(line6->usbdev,
-                               usb_rcvisocpipe(line6->usbdev, ep_read), 0),
-                       usb_maxpacket(line6->usbdev,
-                               usb_sndisocpipe(line6->usbdev, ep_write), 1));
-
-       line6pcm->properties = properties;
-       line6->line6pcm = line6pcm;
-
-       /* PCM device: */
-       err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
-       if (err < 0)
-               return err;
-
-       err = snd_line6_new_pcm(line6pcm);
-       if (err < 0)
-               return err;
-
-       spin_lock_init(&line6pcm->lock_audio_out);
-       spin_lock_init(&line6pcm->lock_audio_in);
-       spin_lock_init(&line6pcm->lock_trigger);
-
-       err = line6_create_audio_out_urbs(line6pcm);
-       if (err < 0)
-               return err;
-
-       err = line6_create_audio_in_urbs(line6pcm);
-       if (err < 0)
-               return err;
-
-       /* mixer: */
-       err =
-           snd_ctl_add(line6->card,
-                       snd_ctl_new1(&line6_control_playback, line6pcm));
-       if (err < 0)
-               return err;
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       /* impulse response test: */
-       err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume);
-       if (err < 0)
-               return err;
-
-       err = device_create_file(line6->ifcdev, &dev_attr_impulse_period);
-       if (err < 0)
-               return err;
-
-       line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
-#endif
-
-       return 0;
-}
-
-/* prepare pcm callback */
-int snd_line6_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       switch (substream->stream) {
-       case SNDRV_PCM_STREAM_PLAYBACK:
-               if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0)
-                       line6_unlink_wait_clear_audio_out_urbs(line6pcm);
-
-               break;
-
-       case SNDRV_PCM_STREAM_CAPTURE:
-               if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0)
-                       line6_unlink_wait_clear_audio_in_urbs(line6pcm);
-
-               break;
-
-       default:
-               MISSING_CASE;
-       }
-
-       if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
-               line6pcm->count_out = 0;
-               line6pcm->pos_out = 0;
-               line6pcm->pos_out_done = 0;
-               line6pcm->bytes_out = 0;
-               line6pcm->count_in = 0;
-               line6pcm->pos_in_done = 0;
-               line6pcm->bytes_in = 0;
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
deleted file mode 100644 (file)
index 6aa0d46..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-/*
-       PCM interface to POD series devices.
-*/
-
-#ifndef PCM_H
-#define PCM_H
-
-#include <sound/pcm.h>
-
-#include "driver.h"
-#include "usbdefs.h"
-
-/* number of URBs */
-#define LINE6_ISO_BUFFERS      2
-
-/*
-       number of USB frames per URB
-       The Line6 Windows driver always transmits two frames per packet, but
-       the Linux driver performs significantly better (i.e., lower latency)
-       with only one frame per packet.
-*/
-#define LINE6_ISO_PACKETS      1
-
-/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
-#define LINE6_ISO_INTERVAL     1
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-#define LINE6_IMPULSE_DEFAULT_PERIOD 100
-#endif
-
-/*
-       Get substream from Line6 PCM data structure
-*/
-#define get_substream(line6pcm, stream)        \
-               (line6pcm->pcm->streams[stream].substream)
-
-/*
-       PCM mode bits.
-
-       There are several features of the Line6 USB driver which require PCM
-       data to be exchanged with the device:
-       *) PCM playback and capture via ALSA
-       *) software monitoring (for devices without hardware monitoring)
-       *) optional impulse response measurement
-       However, from the device's point of view, there is just a single
-       capture and playback stream, which must be shared between these
-       subsystems. It is therefore necessary to maintain the state of the
-       subsystems with respect to PCM usage. We define several constants of
-       the form LINE6_BIT_PCM_<subsystem>_<direction>_<resource> with the
-       following meanings:
-       *) <subsystem> is one of
-       -) ALSA: PCM playback and capture via ALSA
-       -) MONITOR: software monitoring
-       -) IMPULSE: optional impulse response measurement
-       *) <direction> is one of
-       -) PLAYBACK: audio output (from host to device)
-       -) CAPTURE: audio input (from device to host)
-       *) <resource> is one of
-       -) BUFFER: buffer required by PCM data stream
-       -) STREAM: actual PCM data stream
-
-       The subsystems call line6_pcm_acquire() to acquire the (shared)
-       resources needed for a particular operation (e.g., allocate the buffer
-       for ALSA playback or start the capture stream for software monitoring).
-       When a resource is no longer needed, it is released by calling
-       line6_pcm_release(). Buffer allocation and stream startup are handled
-       separately to allow the ALSA kernel driver to perform them at
-       appropriate places (since the callback which starts a PCM stream is not
-       allowed to sleep).
-*/
-enum {
-       /* individual bit indices: */
-       LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER,
-       LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM,
-       LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER,
-       LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
-       LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER,
-       LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM,
-       LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER,
-       LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM,
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER,
-       LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM,
-       LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER,
-       LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM,
-#endif
-       LINE6_INDEX_PAUSE_PLAYBACK,
-       LINE6_INDEX_PREPARED,
-
-       /* individual bit masks: */
-       LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER),
-       LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM),
-       LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER),
-       LINE6_BIT(PCM_ALSA_CAPTURE_STREAM),
-       LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER),
-       LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM),
-       LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER),
-       LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM),
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER),
-       LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM),
-       LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER),
-       LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM),
-#endif
-       LINE6_BIT(PAUSE_PLAYBACK),
-       LINE6_BIT(PREPARED),
-
-       /* combined bit masks (by operation): */
-       LINE6_BITS_PCM_ALSA_BUFFER =
-           LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
-           LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER,
-
-       LINE6_BITS_PCM_ALSA_STREAM =
-           LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
-           LINE6_BIT_PCM_ALSA_CAPTURE_STREAM,
-
-       LINE6_BITS_PCM_MONITOR =
-           LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER |
-           LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM |
-           LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER |
-           LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       LINE6_BITS_PCM_IMPULSE =
-           LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
-           LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
-           LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
-           LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM,
-#endif
-
-       /* combined bit masks (by direction): */
-       LINE6_BITS_PLAYBACK_BUFFER =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-           LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
-#endif
-           LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
-           LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER ,
-
-       LINE6_BITS_PLAYBACK_STREAM =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-           LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
-#endif
-           LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
-           LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM ,
-
-       LINE6_BITS_CAPTURE_BUFFER =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-           LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
-#endif
-           LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER |
-           LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER ,
-
-       LINE6_BITS_CAPTURE_STREAM =
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-           LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM |
-#endif
-           LINE6_BIT_PCM_ALSA_CAPTURE_STREAM |
-           LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
-
-       LINE6_BITS_STREAM =
-           LINE6_BITS_PLAYBACK_STREAM |
-           LINE6_BITS_CAPTURE_STREAM
-};
-
-struct line6_pcm_properties {
-       struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
-       struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
-       int bytes_per_frame;
-};
-
-struct snd_line6_pcm {
-       /**
-                Pointer back to the Line6 driver data structure.
-       */
-       struct usb_line6 *line6;
-
-       /**
-                Properties.
-       */
-       struct line6_pcm_properties *properties;
-
-       /**
-                ALSA pcm stream
-       */
-       struct snd_pcm *pcm;
-
-       /**
-                URBs for audio playback.
-       */
-       struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
-
-       /**
-                URBs for audio capture.
-       */
-       struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
-
-       /**
-                Temporary buffer for playback.
-                Since the packet size is not known in advance, this buffer is
-                large enough to store maximum size packets.
-       */
-       unsigned char *buffer_out;
-
-       /**
-                Temporary buffer for capture.
-                Since the packet size is not known in advance, this buffer is
-                large enough to store maximum size packets.
-       */
-       unsigned char *buffer_in;
-
-       /**
-                Previously captured frame (for software monitoring).
-       */
-       unsigned char *prev_fbuf;
-
-       /**
-                Size of previously captured frame (for software monitoring).
-       */
-       int prev_fsize;
-
-       /**
-                Free frame position in the playback buffer.
-       */
-       snd_pcm_uframes_t pos_out;
-
-       /**
-                Count processed bytes for playback.
-                This is modulo period size (to determine when a period is
-                finished).
-       */
-       unsigned bytes_out;
-
-       /**
-                Counter to create desired playback sample rate.
-       */
-       unsigned count_out;
-
-       /**
-                Playback period size in bytes
-       */
-       unsigned period_out;
-
-       /**
-                Processed frame position in the playback buffer.
-                The contents of the output ring buffer have been consumed by
-                the USB subsystem (i.e., sent to the USB device) up to this
-                position.
-       */
-       snd_pcm_uframes_t pos_out_done;
-
-       /**
-                Count processed bytes for capture.
-                This is modulo period size (to determine when a period is
-                finished).
-       */
-       unsigned bytes_in;
-
-       /**
-                Counter to create desired capture sample rate.
-       */
-       unsigned count_in;
-
-       /**
-                Capture period size in bytes
-       */
-       unsigned period_in;
-
-       /**
-                Processed frame position in the capture buffer.
-                The contents of the output ring buffer have been consumed by
-                the USB subsystem (i.e., sent to the USB device) up to this
-                position.
-       */
-       snd_pcm_uframes_t pos_in_done;
-
-       /**
-                Bit mask of active playback URBs.
-       */
-       unsigned long active_urb_out;
-
-       /**
-                Maximum size of USB packet.
-       */
-       int max_packet_size;
-
-       /**
-                USB endpoint for listening to audio data.
-       */
-       int ep_audio_read;
-
-       /**
-                USB endpoint for writing audio data.
-       */
-       int ep_audio_write;
-
-       /**
-                Bit mask of active capture URBs.
-       */
-       unsigned long active_urb_in;
-
-       /**
-                Bit mask of playback URBs currently being unlinked.
-       */
-       unsigned long unlink_urb_out;
-
-       /**
-                Bit mask of capture URBs currently being unlinked.
-       */
-       unsigned long unlink_urb_in;
-
-       /**
-                Spin lock to protect updates of the playback buffer positions (not
-                contents!)
-       */
-       spinlock_t lock_audio_out;
-
-       /**
-                Spin lock to protect updates of the capture buffer positions (not
-                contents!)
-       */
-       spinlock_t lock_audio_in;
-
-       /**
-                Spin lock to protect trigger.
-       */
-       spinlock_t lock_trigger;
-
-       /**
-                PCM playback volume (left and right).
-       */
-       int volume_playback[2];
-
-       /**
-                PCM monitor volume.
-       */
-       int volume_monitor;
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-       /**
-                Volume of impulse response test signal (if zero, test is disabled).
-       */
-       int impulse_volume;
-
-       /**
-                Period of impulse response test signal.
-       */
-       int impulse_period;
-
-       /**
-                Counter for impulse response test signal.
-       */
-       int impulse_count;
-#endif
-
-       /**
-                Several status bits (see LINE6_BIT_*).
-       */
-       unsigned long flags;
-
-       int last_frame_in, last_frame_out;
-};
-
-extern int line6_init_pcm(struct usb_line6 *line6,
-                         struct line6_pcm_properties *properties);
-extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
-extern int snd_line6_prepare(struct snd_pcm_substream *substream);
-extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
-extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels);
-extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels);
-
-#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
deleted file mode 100644 (file)
index 2ca8900..0000000
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "pcm.h"
-#include "pod.h"
-#include "playback.h"
-
-/*
-       Software stereo volume control.
-*/
-static void change_volume(struct urb *urb_out, int volume[],
-                         int bytes_per_frame)
-{
-       int chn = 0;
-
-       if (volume[0] == 256 && volume[1] == 256)
-               return;         /* maximum volume - no change */
-
-       if (bytes_per_frame == 4) {
-               short *p, *buf_end;
-
-               p = (short *)urb_out->transfer_buffer;
-               buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
-
-               for (; p < buf_end; ++p) {
-                       *p = (*p * volume[chn & 1]) >> 8;
-                       ++chn;
-               }
-       } else if (bytes_per_frame == 6) {
-               unsigned char *p, *buf_end;
-
-               p = (unsigned char *)urb_out->transfer_buffer;
-               buf_end = p + urb_out->transfer_buffer_length;
-
-               for (; p < buf_end; p += 3) {
-                       int val;
-
-                       val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
-                       val = (val * volume[chn & 1]) >> 8;
-                       p[0] = val;
-                       p[1] = val >> 8;
-                       p[2] = val >> 16;
-                       ++chn;
-               }
-       }
-}
-
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-
-/*
-       Create signal for impulse response test.
-*/
-static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
-                                      struct urb *urb_out, int bytes_per_frame)
-{
-       int frames = urb_out->transfer_buffer_length / bytes_per_frame;
-
-       if (bytes_per_frame == 4) {
-               int i;
-               short *pi = (short *)line6pcm->prev_fbuf;
-               short *po = (short *)urb_out->transfer_buffer;
-
-               for (i = 0; i < frames; ++i) {
-                       po[0] = pi[0];
-                       po[1] = 0;
-                       pi += 2;
-                       po += 2;
-               }
-       } else if (bytes_per_frame == 6) {
-               int i, j;
-               unsigned char *pi = line6pcm->prev_fbuf;
-               unsigned char *po = urb_out->transfer_buffer;
-
-               for (i = 0; i < frames; ++i) {
-                       for (j = 0; j < bytes_per_frame / 2; ++j)
-                               po[j] = pi[j];
-
-                       for (; j < bytes_per_frame; ++j)
-                               po[j] = 0;
-
-                       pi += bytes_per_frame;
-                       po += bytes_per_frame;
-               }
-       }
-       if (--line6pcm->impulse_count <= 0) {
-               ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
-                                                             1] =
-                   line6pcm->impulse_volume;
-               line6pcm->impulse_count = line6pcm->impulse_period;
-       }
-}
-
-#endif
-
-/*
-       Add signal to buffer for software monitoring.
-*/
-static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
-                              int volume, int bytes_per_frame)
-{
-       if (volume == 0)
-               return;         /* zero volume - no change */
-
-       if (bytes_per_frame == 4) {
-               short *pi, *po, *buf_end;
-
-               pi = (short *)signal;
-               po = (short *)urb_out->transfer_buffer;
-               buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
-
-               for (; po < buf_end; ++pi, ++po)
-                       *po += (*pi * volume) >> 8;
-       }
-
-       /*
-          We don't need to handle devices with 6 bytes per frame here
-          since they all support hardware monitoring.
-        */
-}
-
-/*
-       Find a free URB, prepare audio data, and submit URB.
-*/
-static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
-{
-       int index;
-       unsigned long flags;
-       int i, urb_size, urb_frames;
-       int ret;
-       const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
-       const int frame_increment =
-           line6pcm->properties->snd_line6_rates.rats[0].num_min;
-       const int frame_factor =
-           line6pcm->properties->snd_line6_rates.rats[0].den *
-           (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
-       struct urb *urb_out;
-
-       spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
-       index =
-           find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
-
-       if (index < 0 || index >= LINE6_ISO_BUFFERS) {
-               spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
-               dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
-               return -EINVAL;
-       }
-
-       urb_out = line6pcm->urb_audio_out[index];
-       urb_size = 0;
-
-       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
-               /* compute frame size for given sampling rate */
-               int fsize = 0;
-               struct usb_iso_packet_descriptor *fout =
-                   &urb_out->iso_frame_desc[i];
-
-               if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)
-                       fsize = line6pcm->prev_fsize;
-
-               if (fsize == 0) {
-                       int n;
-
-                       line6pcm->count_out += frame_increment;
-                       n = line6pcm->count_out / frame_factor;
-                       line6pcm->count_out -= n * frame_factor;
-                       fsize = n * bytes_per_frame;
-               }
-
-               fout->offset = urb_size;
-               fout->length = fsize;
-               urb_size += fsize;
-       }
-
-       if (urb_size == 0) {
-               /* can't determine URB size */
-               spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
-               dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
-               return -EINVAL;
-       }
-
-       urb_frames = urb_size / bytes_per_frame;
-       urb_out->transfer_buffer =
-           line6pcm->buffer_out +
-           index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
-       urb_out->transfer_buffer_length = urb_size;
-       urb_out->context = line6pcm;
-
-       if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) &&
-           !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) {
-               struct snd_pcm_runtime *runtime =
-                   get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
-
-               if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
-                       /*
-                          The transferred area goes over buffer boundary,
-                          copy the data to the temp buffer.
-                        */
-                       int len;
-
-                       len = runtime->buffer_size - line6pcm->pos_out;
-
-                       if (len > 0) {
-                               memcpy(urb_out->transfer_buffer,
-                                      runtime->dma_area +
-                                      line6pcm->pos_out * bytes_per_frame,
-                                      len * bytes_per_frame);
-                               memcpy(urb_out->transfer_buffer +
-                                      len * bytes_per_frame, runtime->dma_area,
-                                      (urb_frames - len) * bytes_per_frame);
-                       } else
-                               dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n",
-                                       len);
-               } else {
-                       memcpy(urb_out->transfer_buffer,
-                              runtime->dma_area +
-                              line6pcm->pos_out * bytes_per_frame,
-                              urb_out->transfer_buffer_length);
-               }
-
-               line6pcm->pos_out += urb_frames;
-               if (line6pcm->pos_out >= runtime->buffer_size)
-                       line6pcm->pos_out -= runtime->buffer_size;
-       } else {
-               memset(urb_out->transfer_buffer, 0,
-                      urb_out->transfer_buffer_length);
-       }
-
-       change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame);
-
-       if (line6pcm->prev_fbuf != NULL) {
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-               if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {
-                       create_impulse_test_signal(line6pcm, urb_out,
-                                                  bytes_per_frame);
-                       if (line6pcm->flags &
-                           LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {
-                               line6_capture_copy(line6pcm,
-                                                  urb_out->transfer_buffer,
-                                                  urb_out->
-                                                  transfer_buffer_length);
-                               line6_capture_check_period(line6pcm,
-                                       urb_out->transfer_buffer_length);
-                       }
-               } else {
-#endif
-                       if (!
-                           (line6pcm->line6->
-                            properties->capabilities & LINE6_BIT_HWMON)
-                           && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM)
-                           && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM))
-                               add_monitor_signal(urb_out, line6pcm->prev_fbuf,
-                                                  line6pcm->volume_monitor,
-                                                  bytes_per_frame);
-#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-               }
-#endif
-       }
-
-       ret = usb_submit_urb(urb_out, GFP_ATOMIC);
-
-       if (ret == 0)
-               set_bit(index, &line6pcm->active_urb_out);
-       else
-               dev_err(line6pcm->line6->ifcdev,
-                       "URB out #%d submission failed (%d)\n", index, ret);
-
-       spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
-       return 0;
-}
-
-/*
-       Submit all currently available playback URBs.
-*/
-int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int ret, i;
-
-       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
-               ret = submit_audio_out_urb(line6pcm);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-/*
-       Unlink all currently active playback URBs.
-*/
-void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       unsigned int i;
-
-       for (i = LINE6_ISO_BUFFERS; i--;) {
-               if (test_bit(i, &line6pcm->active_urb_out)) {
-                       if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
-                               struct urb *u = line6pcm->urb_audio_out[i];
-
-                               usb_unlink_urb(u);
-                       }
-               }
-       }
-}
-
-/*
-       Wait until unlinking of all currently active playback URBs has been
-       finished.
-*/
-void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int timeout = HZ;
-       unsigned int i;
-       int alive;
-
-       do {
-               alive = 0;
-               for (i = LINE6_ISO_BUFFERS; i--;) {
-                       if (test_bit(i, &line6pcm->active_urb_out))
-                               alive++;
-               }
-               if (!alive)
-                       break;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-       } while (--timeout > 0);
-       if (alive)
-               snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-}
-
-/*
-       Unlink all currently active playback URBs, and wait for finishing.
-*/
-void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       line6_unlink_audio_out_urbs(line6pcm);
-       line6_wait_clear_audio_out_urbs(line6pcm);
-}
-
-void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
-{
-       kfree(line6pcm->buffer_out);
-       line6pcm->buffer_out = NULL;
-}
-
-/*
-       Callback for completed playback URB.
-*/
-static void audio_out_callback(struct urb *urb)
-{
-       int i, index, length = 0, shutdown = 0;
-       unsigned long flags;
-       struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
-       struct snd_pcm_substream *substream =
-           get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
-
-#if USE_CLEAR_BUFFER_WORKAROUND
-       memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
-#endif
-
-       line6pcm->last_frame_out = urb->start_frame;
-
-       /* find index of URB */
-       for (index = LINE6_ISO_BUFFERS; index--;)
-               if (urb == line6pcm->urb_audio_out[index])
-                       break;
-
-       if (index < 0)
-               return;         /* URB has been unlinked asynchronously */
-
-       for (i = LINE6_ISO_PACKETS; i--;)
-               length += urb->iso_frame_desc[i].length;
-
-       spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
-
-       if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {
-               struct snd_pcm_runtime *runtime = substream->runtime;
-
-               line6pcm->pos_out_done +=
-                   length / line6pcm->properties->bytes_per_frame;
-
-               if (line6pcm->pos_out_done >= runtime->buffer_size)
-                       line6pcm->pos_out_done -= runtime->buffer_size;
-       }
-
-       clear_bit(index, &line6pcm->active_urb_out);
-
-       for (i = LINE6_ISO_PACKETS; i--;)
-               if (urb->iso_frame_desc[i].status == -EXDEV) {
-                       shutdown = 1;
-                       break;
-               }
-
-       if (test_and_clear_bit(index, &line6pcm->unlink_urb_out))
-               shutdown = 1;
-
-       spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
-
-       if (!shutdown) {
-               submit_audio_out_urb(line6pcm);
-
-               if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM,
-                            &line6pcm->flags)) {
-                       line6pcm->bytes_out += length;
-                       if (line6pcm->bytes_out >= line6pcm->period_out) {
-                               line6pcm->bytes_out %= line6pcm->period_out;
-                               snd_pcm_period_elapsed(substream);
-                       }
-               }
-       }
-}
-
-/* open playback callback */
-static int snd_line6_playback_open(struct snd_pcm_substream *substream)
-{
-       int err;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                                           (&line6pcm->
-                                            properties->snd_line6_rates));
-       if (err < 0)
-               return err;
-
-       runtime->hw = line6pcm->properties->snd_line6_playback_hw;
-       return 0;
-}
-
-/* close playback callback */
-static int snd_line6_playback_close(struct snd_pcm_substream *substream)
-{
-       return 0;
-}
-
-/* hw_params playback callback */
-static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
-                                       struct snd_pcm_hw_params *hw_params)
-{
-       int ret;
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       /* -- Florian Demski [FD] */
-       /* don't ask me why, but this fixes the bug on my machine */
-       if (line6pcm == NULL) {
-               if (substream->pcm == NULL)
-                       return -ENOMEM;
-               if (substream->pcm->private_data == NULL)
-                       return -ENOMEM;
-               substream->private_data = substream->pcm->private_data;
-               line6pcm = snd_pcm_substream_chip(substream);
-       }
-       /* -- [FD] end */
-
-       ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
-
-       if (ret < 0)
-               return ret;
-
-       ret = snd_pcm_lib_malloc_pages(substream,
-                                      params_buffer_bytes(hw_params));
-       if (ret < 0) {
-               line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
-               return ret;
-       }
-
-       line6pcm->period_out = params_period_bytes(hw_params);
-       return 0;
-}
-
-/* hw_free playback callback */
-static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
-       return snd_pcm_lib_free_pages(substream);
-}
-
-/* trigger playback callback */
-int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
-{
-       int err;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-#ifdef CONFIG_PM
-       case SNDRV_PCM_TRIGGER_RESUME:
-#endif
-               err = line6_pcm_acquire(line6pcm,
-                                       LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
-
-               if (err < 0)
-                       return err;
-
-               break;
-
-       case SNDRV_PCM_TRIGGER_STOP:
-#ifdef CONFIG_PM
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-#endif
-               err = line6_pcm_release(line6pcm,
-                                       LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
-
-               if (err < 0)
-                       return err;
-
-               break;
-
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
-               break;
-
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* playback pointer callback */
-static snd_pcm_uframes_t
-snd_line6_playback_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-       return line6pcm->pos_out_done;
-}
-
-/* playback operators */
-struct snd_pcm_ops snd_line6_playback_ops = {
-       .open = snd_line6_playback_open,
-       .close = snd_line6_playback_close,
-       .ioctl = snd_pcm_lib_ioctl,
-       .hw_params = snd_line6_playback_hw_params,
-       .hw_free = snd_line6_playback_hw_free,
-       .prepare = snd_line6_prepare,
-       .trigger = snd_line6_trigger,
-       .pointer = snd_line6_playback_pointer,
-};
-
-int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int i;
-
-       /* create audio URBs and fill in constant values: */
-       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
-               struct urb *urb;
-
-               /* URB for audio out: */
-               urb = line6pcm->urb_audio_out[i] =
-                   usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
-
-               if (urb == NULL) {
-                       dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
-                       return -ENOMEM;
-               }
-
-               urb->dev = line6pcm->line6->usbdev;
-               urb->pipe =
-                   usb_sndisocpipe(line6pcm->line6->usbdev,
-                                   line6pcm->ep_audio_write &
-                                   USB_ENDPOINT_NUMBER_MASK);
-               urb->transfer_flags = URB_ISO_ASAP;
-               urb->start_frame = -1;
-               urb->number_of_packets = LINE6_ISO_PACKETS;
-               urb->interval = LINE6_ISO_INTERVAL;
-               urb->error_count = 0;
-               urb->complete = audio_out_callback;
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
deleted file mode 100644 (file)
index 743bd6f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef PLAYBACK_H
-#define PLAYBACK_H
-
-#include <sound/pcm.h>
-
-#include "driver.h"
-
-/*
- * When the TonePort is used with jack in full duplex mode and the outputs are
- * not connected, the software monitor produces an ugly noise since everything
- * written to the output buffer (i.e., the input signal) will be repeated in
- * the next period (sounds like a delay effect). As a workaround, the output
- * buffer is cleared after the data have been read, but there must be a better
- * solution. Until one is found, this workaround can be used to fix the
- * problem.
- */
-#define USE_CLEAR_BUFFER_WORKAROUND 1
-
-extern struct snd_pcm_ops snd_line6_playback_ops;
-
-extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
-extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
-                                                  *line6pcm);
-extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
-
-#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
deleted file mode 100644 (file)
index 44f4b2f..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <sound/control.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "playback.h"
-#include "pod.h"
-
-#define POD_SYSEX_CODE 3
-#define POD_BYTES_PER_FRAME 6  /* 24bit audio (stereo) */
-
-/* *INDENT-OFF* */
-
-enum {
-       POD_SYSEX_SAVE      = 0x24,
-       POD_SYSEX_SYSTEM    = 0x56,
-       POD_SYSEX_SYSTEMREQ = 0x57,
-       /* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
-       POD_SYSEX_STORE     = 0x71,
-       POD_SYSEX_FINISH    = 0x72,
-       POD_SYSEX_DUMPMEM   = 0x73,
-       POD_SYSEX_DUMP      = 0x74,
-       POD_SYSEX_DUMPREQ   = 0x75
-
-       /* dumps entire internal memory of PODxt Pro */
-       /* POD_SYSEX_DUMPMEM2  = 0x76 */
-};
-
-enum {
-       POD_MONITOR_LEVEL  = 0x04,
-       POD_SYSTEM_INVALID = 0x10000
-};
-
-/* *INDENT-ON* */
-
-enum {
-       POD_DUMP_MEMORY = 2
-};
-
-enum {
-       POD_BUSY_READ,
-       POD_BUSY_WRITE,
-       POD_CHANNEL_DIRTY,
-       POD_SAVE_PRESSED,
-       POD_BUSY_MIDISEND
-};
-
-static struct snd_ratden pod_ratden = {
-       .num_min = 78125,
-       .num_max = 78125,
-       .num_step = 1,
-       .den = 2
-};
-
-static struct line6_pcm_properties pod_pcm_properties = {
-       .snd_line6_playback_hw = {
-                                 .info = (SNDRV_PCM_INFO_MMAP |
-                                          SNDRV_PCM_INFO_INTERLEAVED |
-                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                          SNDRV_PCM_INFO_MMAP_VALID |
-                                          SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-                                          SNDRV_PCM_INFO_RESUME |
-#endif
-                                          SNDRV_PCM_INFO_SYNC_START),
-                                 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-                                 .rates = SNDRV_PCM_RATE_KNOT,
-                                 .rate_min = 39062,
-                                 .rate_max = 39063,
-                                 .channels_min = 2,
-                                 .channels_max = 2,
-                                 .buffer_bytes_max = 60000,
-                                 .period_bytes_min = 64,
-                                 .period_bytes_max = 8192,
-                                 .periods_min = 1,
-                                 .periods_max = 1024},
-       .snd_line6_capture_hw = {
-                                .info = (SNDRV_PCM_INFO_MMAP |
-                                         SNDRV_PCM_INFO_INTERLEAVED |
-                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                         SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-                                         SNDRV_PCM_INFO_RESUME |
-#endif
-                                         SNDRV_PCM_INFO_SYNC_START),
-                                .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-                                .rates = SNDRV_PCM_RATE_KNOT,
-                                .rate_min = 39062,
-                                .rate_max = 39063,
-                                .channels_min = 2,
-                                .channels_max = 2,
-                                .buffer_bytes_max = 60000,
-                                .period_bytes_min = 64,
-                                .period_bytes_max = 8192,
-                                .periods_min = 1,
-                                .periods_max = 1024},
-       .snd_line6_rates = {
-                           .nrats = 1,
-                           .rats = &pod_ratden},
-       .bytes_per_frame = POD_BYTES_PER_FRAME
-};
-
-static const char pod_version_header[] = {
-       0xf2, 0x7e, 0x7f, 0x06, 0x02
-};
-
-/* forward declarations: */
-static void pod_startup2(unsigned long data);
-static void pod_startup3(struct usb_line6_pod *pod);
-
-static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
-                                   int size)
-{
-       return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
-                                       size);
-}
-
-/*
-       Process a completely received message.
-*/
-void line6_pod_process_message(struct usb_line6_pod *pod)
-{
-       const unsigned char *buf = pod->line6.buffer_message;
-
-       if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
-               pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
-               pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
-                                (int) buf[10];
-               pod_startup3(pod);
-               return;
-       }
-
-       /* Only look for sysex messages from this device */
-       if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
-           buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
-               return;
-       }
-       if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
-               return;
-
-       if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
-               short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
-                             ((int)buf[9] << 4) | (int)buf[10];
-               pod->monitor_level = value;
-       }
-}
-
-/*
-       Transmit PODxt Pro control parameter.
-*/
-void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
-                                 u8 value)
-{
-       line6_transmit_parameter(&pod->line6, param, value);
-}
-
-/*
-       Send system parameter (from integer).
-*/
-static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
-                                   int code)
-{
-       char *sysex;
-       static const int size = 5;
-
-       sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
-       if (!sysex)
-               return -ENOMEM;
-       sysex[SYSEX_DATA_OFS] = code;
-       sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
-       sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
-       sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
-       sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
-       line6_send_sysex_message(&pod->line6, sysex, size);
-       kfree(sysex);
-       return 0;
-}
-
-/*
-       "read" request on "serial_number" special file.
-*/
-static ssize_t serial_number_show(struct device *dev,
-                                 struct device_attribute *attr, char *buf)
-{
-       struct usb_interface *interface = to_usb_interface(dev);
-       struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
-       return sprintf(buf, "%d\n", pod->serial_number);
-}
-
-/*
-       "read" request on "firmware_version" special file.
-*/
-static ssize_t firmware_version_show(struct device *dev,
-                                    struct device_attribute *attr, char *buf)
-{
-       struct usb_interface *interface = to_usb_interface(dev);
-       struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
-       return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
-                      pod->firmware_version % 100);
-}
-
-/*
-       "read" request on "device_id" special file.
-*/
-static ssize_t device_id_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
-{
-       struct usb_interface *interface = to_usb_interface(dev);
-       struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
-       return sprintf(buf, "%d\n", pod->device_id);
-}
-
-/*
-       POD startup procedure.
-       This is a sequence of functions with special requirements (e.g., must
-       not run immediately after initialization, must not run in interrupt
-       context). After the last one has finished, the device is ready to use.
-*/
-
-static void pod_startup1(struct usb_line6_pod *pod)
-{
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
-
-       /* delay startup procedure: */
-       line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
-                         (unsigned long)pod);
-}
-
-static void pod_startup2(unsigned long data)
-{
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
-       struct usb_line6 *line6 = &pod->line6;
-
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
-
-       /* request firmware version: */
-       line6_version_request_async(line6);
-}
-
-static void pod_startup3(struct usb_line6_pod *pod)
-{
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
-
-       /* schedule work for global work queue: */
-       schedule_work(&pod->startup_work);
-}
-
-static void pod_startup4(struct work_struct *work)
-{
-       struct usb_line6_pod *pod =
-           container_of(work, struct usb_line6_pod, startup_work);
-       struct usb_line6 *line6 = &pod->line6;
-
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
-
-       /* serial number: */
-       line6_read_serial_number(&pod->line6, &pod->serial_number);
-
-       /* ALSA audio interface: */
-       line6_register_audio(line6);
-}
-
-/* POD special files: */
-static DEVICE_ATTR_RO(device_id);
-static DEVICE_ATTR_RO(firmware_version);
-static DEVICE_ATTR_RO(serial_number);
-
-/* control info callback */
-static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
-                                       struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 65535;
-       return 0;
-}
-
-/* control get callback */
-static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
-                                      struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
-
-       ucontrol->value.integer.value[0] = pod->monitor_level;
-       return 0;
-}
-
-/* control put callback */
-static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
-                                      struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
-
-       if (ucontrol->value.integer.value[0] == pod->monitor_level)
-               return 0;
-
-       pod->monitor_level = ucontrol->value.integer.value[0];
-       pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
-                                POD_MONITOR_LEVEL);
-       return 1;
-}
-
-/* control definition */
-static struct snd_kcontrol_new pod_control_monitor = {
-       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name = "Monitor Playback Volume",
-       .index = 0,
-       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-       .info = snd_pod_control_monitor_info,
-       .get = snd_pod_control_monitor_get,
-       .put = snd_pod_control_monitor_put
-};
-
-/*
-       POD destructor.
-*/
-static void pod_destruct(struct usb_interface *interface)
-{
-       struct usb_line6_pod *pod = usb_get_intfdata(interface);
-
-       if (pod == NULL)
-               return;
-       line6_cleanup_audio(&pod->line6);
-
-       del_timer(&pod->startup_timer);
-       cancel_work_sync(&pod->startup_work);
-}
-
-/*
-       Create sysfs entries.
-*/
-static int pod_create_files2(struct device *dev)
-{
-       int err;
-
-       CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
-       CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
-       CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
-       return 0;
-}
-
-/*
-        Try to init POD device.
-*/
-static int pod_try_init(struct usb_interface *interface,
-                       struct usb_line6_pod *pod)
-{
-       int err;
-       struct usb_line6 *line6 = &pod->line6;
-
-       init_timer(&pod->startup_timer);
-       INIT_WORK(&pod->startup_work, pod_startup4);
-
-       if ((interface == NULL) || (pod == NULL))
-               return -ENODEV;
-
-       /* create sysfs entries: */
-       err = pod_create_files2(&interface->dev);
-       if (err < 0)
-               return err;
-
-       /* initialize audio system: */
-       err = line6_init_audio(line6);
-       if (err < 0)
-               return err;
-
-       /* initialize MIDI subsystem: */
-       err = line6_init_midi(line6);
-       if (err < 0)
-               return err;
-
-       /* initialize PCM subsystem: */
-       err = line6_init_pcm(line6, &pod_pcm_properties);
-       if (err < 0)
-               return err;
-
-       /* register monitor control: */
-       err = snd_ctl_add(line6->card,
-                         snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
-       if (err < 0)
-               return err;
-
-       /*
-          When the sound card is registered at this point, the PODxt Live
-          displays "Invalid Code Error 07", so we do it later in the event
-          handler.
-        */
-
-       if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
-               pod->monitor_level = POD_SYSTEM_INVALID;
-
-               /* initiate startup procedure: */
-               pod_startup1(pod);
-       }
-
-       return 0;
-}
-
-/*
-        Init POD device (and clean up in case of failure).
-*/
-int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
-{
-       int err = pod_try_init(interface, pod);
-
-       if (err < 0)
-               pod_destruct(interface);
-
-       return err;
-}
-
-/*
-       POD device disconnected.
-*/
-void line6_pod_disconnect(struct usb_interface *interface)
-{
-       struct usb_line6_pod *pod;
-
-       if (interface == NULL)
-               return;
-       pod = usb_get_intfdata(interface);
-
-       if (pod != NULL) {
-               struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
-               struct device *dev = &interface->dev;
-
-               if (line6pcm != NULL)
-                       line6_pcm_disconnect(line6pcm);
-
-               if (dev != NULL) {
-                       /* remove sysfs entries: */
-                       device_remove_file(dev, &dev_attr_device_id);
-                       device_remove_file(dev, &dev_attr_firmware_version);
-                       device_remove_file(dev, &dev_attr_serial_number);
-               }
-       }
-
-       pod_destruct(interface);
-}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
deleted file mode 100644 (file)
index 3e3f167..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef POD_H
-#define POD_H
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-
-#include <sound/core.h>
-
-#include "driver.h"
-
-/*
-       PODxt Live interfaces
-*/
-#define PODXTLIVE_INTERFACE_POD    0
-#define PODXTLIVE_INTERFACE_VARIAX 1
-
-/*
-       Locate name in binary program dump
-*/
-#define        POD_NAME_OFFSET 0
-#define        POD_NAME_LENGTH 16
-
-/*
-       Other constants
-*/
-#define POD_CONTROL_SIZE 0x80
-#define POD_BUFSIZE_DUMPREQ 7
-#define POD_STARTUP_DELAY 1000
-
-/*
-       Stages of POD startup procedure
-*/
-enum {
-       POD_STARTUP_INIT = 1,
-       POD_STARTUP_VERSIONREQ,
-       POD_STARTUP_WORKQUEUE,
-       POD_STARTUP_SETUP,
-       POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
-};
-
-struct usb_line6_pod {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Instrument monitor level.
-       */
-       int monitor_level;
-
-       /**
-               Timer for device initializaton.
-       */
-       struct timer_list startup_timer;
-
-       /**
-               Work handler for device initializaton.
-       */
-       struct work_struct startup_work;
-
-       /**
-               Current progress in startup procedure.
-       */
-       int startup_progress;
-
-       /**
-               Serial number of device.
-       */
-       int serial_number;
-
-       /**
-               Firmware version (x 100).
-       */
-       int firmware_version;
-
-       /**
-               Device ID.
-       */
-       int device_id;
-};
-
-extern void line6_pod_disconnect(struct usb_interface *interface);
-extern int line6_pod_init(struct usb_interface *interface,
-                         struct usb_line6_pod *pod);
-extern void line6_pod_process_message(struct usb_line6_pod *pod);
-extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
-                                        u8 value);
-
-#endif
diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c
deleted file mode 100644 (file)
index 7ef4543..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Line6 Pod HD
- *
- * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.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, version 2.
- *
- */
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "audio.h"
-#include "driver.h"
-#include "pcm.h"
-#include "podhd.h"
-
-#define PODHD_BYTES_PER_FRAME 6        /* 24bit audio (stereo) */
-
-static struct snd_ratden podhd_ratden = {
-       .num_min = 48000,
-       .num_max = 48000,
-       .num_step = 1,
-       .den = 1,
-};
-
-static struct line6_pcm_properties podhd_pcm_properties = {
-       .snd_line6_playback_hw = {
-                                 .info = (SNDRV_PCM_INFO_MMAP |
-                                          SNDRV_PCM_INFO_INTERLEAVED |
-                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                          SNDRV_PCM_INFO_MMAP_VALID |
-                                          SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-                                          SNDRV_PCM_INFO_RESUME |
-#endif
-                                          SNDRV_PCM_INFO_SYNC_START),
-                                 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-                                 .rates = SNDRV_PCM_RATE_48000,
-                                 .rate_min = 48000,
-                                 .rate_max = 48000,
-                                 .channels_min = 2,
-                                 .channels_max = 2,
-                                 .buffer_bytes_max = 60000,
-                                 .period_bytes_min = 64,
-                                 .period_bytes_max = 8192,
-                                 .periods_min = 1,
-                                 .periods_max = 1024},
-       .snd_line6_capture_hw = {
-                                .info = (SNDRV_PCM_INFO_MMAP |
-                                         SNDRV_PCM_INFO_INTERLEAVED |
-                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                         SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-                                         SNDRV_PCM_INFO_RESUME |
-#endif
-                                         SNDRV_PCM_INFO_SYNC_START),
-                                .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-                                .rates = SNDRV_PCM_RATE_48000,
-                                .rate_min = 48000,
-                                .rate_max = 48000,
-                                .channels_min = 2,
-                                .channels_max = 2,
-                                .buffer_bytes_max = 60000,
-                                .period_bytes_min = 64,
-                                .period_bytes_max = 8192,
-                                .periods_min = 1,
-                                .periods_max = 1024},
-       .snd_line6_rates = {
-                           .nrats = 1,
-                           .rats = &podhd_ratden},
-       .bytes_per_frame = PODHD_BYTES_PER_FRAME
-};
-
-/*
-       POD HD destructor.
-*/
-static void podhd_destruct(struct usb_interface *interface)
-{
-       struct usb_line6_podhd *podhd = usb_get_intfdata(interface);
-
-       if (podhd == NULL)
-               return;
-       line6_cleanup_audio(&podhd->line6);
-}
-
-/*
-       Try to init POD HD device.
-*/
-static int podhd_try_init(struct usb_interface *interface,
-                         struct usb_line6_podhd *podhd)
-{
-       int err;
-       struct usb_line6 *line6 = &podhd->line6;
-
-       if ((interface == NULL) || (podhd == NULL))
-               return -ENODEV;
-
-       /* initialize audio system: */
-       err = line6_init_audio(line6);
-       if (err < 0)
-               return err;
-
-       /* initialize MIDI subsystem: */
-       err = line6_init_midi(line6);
-       if (err < 0)
-               return err;
-
-       /* initialize PCM subsystem: */
-       err = line6_init_pcm(line6, &podhd_pcm_properties);
-       if (err < 0)
-               return err;
-
-       /* register USB audio system: */
-       err = line6_register_audio(line6);
-       return err;
-}
-
-/*
-       Init POD HD device (and clean up in case of failure).
-*/
-int line6_podhd_init(struct usb_interface *interface,
-                    struct usb_line6_podhd *podhd)
-{
-       int err = podhd_try_init(interface, podhd);
-
-       if (err < 0)
-               podhd_destruct(interface);
-
-       return err;
-}
-
-/*
-       POD HD device disconnected.
-*/
-void line6_podhd_disconnect(struct usb_interface *interface)
-{
-       struct usb_line6_podhd *podhd;
-
-       if (interface == NULL)
-               return;
-       podhd = usb_get_intfdata(interface);
-
-       if (podhd != NULL) {
-               struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
-
-               if (line6pcm != NULL)
-                       line6_pcm_disconnect(line6pcm);
-       }
-
-       podhd_destruct(interface);
-}
diff --git a/drivers/staging/line6/podhd.h b/drivers/staging/line6/podhd.h
deleted file mode 100644 (file)
index 652f740..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Line6 Pod HD
- *
- * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.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, version 2.
- *
- */
-
-#ifndef PODHD_H
-#define PODHD_H
-
-#include <linux/usb.h>
-
-#include "driver.h"
-
-struct usb_line6_podhd {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-};
-
-extern void line6_podhd_disconnect(struct usb_interface *interface);
-extern int line6_podhd_init(struct usb_interface *interface,
-                           struct usb_line6_podhd *podhd);
-
-#endif /* PODHD_H */
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
deleted file mode 100644 (file)
index b4eee2b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef DRIVER_REVISION
-/* current subversion revision */
-#define DRIVER_REVISION " (904)"
-#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
deleted file mode 100644 (file)
index 6943715..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *                         Emil Myhrman (emil.myhrman@gmail.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, version 2.
- *
- */
-
-#include <linux/wait.h>
-#include <sound/control.h>
-
-#include "audio.h"
-#include "capture.h"
-#include "driver.h"
-#include "playback.h"
-#include "toneport.h"
-
-static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
-
-#define TONEPORT_PCM_DELAY 1
-
-static struct snd_ratden toneport_ratden = {
-       .num_min = 44100,
-       .num_max = 44100,
-       .num_step = 1,
-       .den = 1
-};
-
-static struct line6_pcm_properties toneport_pcm_properties = {
-       .snd_line6_playback_hw = {
-                                 .info = (SNDRV_PCM_INFO_MMAP |
-                                          SNDRV_PCM_INFO_INTERLEAVED |
-                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                          SNDRV_PCM_INFO_MMAP_VALID |
-                                          SNDRV_PCM_INFO_PAUSE |
-#ifdef CONFIG_PM
-                                          SNDRV_PCM_INFO_RESUME |
-#endif
-                                          SNDRV_PCM_INFO_SYNC_START),
-                                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
-                                 .rates = SNDRV_PCM_RATE_KNOT,
-                                 .rate_min = 44100,
-                                 .rate_max = 44100,
-                                 .channels_min = 2,
-                                 .channels_max = 2,
-                                 .buffer_bytes_max = 60000,
-                                 .period_bytes_min = 64,
-                                 .period_bytes_max = 8192,
-                                 .periods_min = 1,
-                                 .periods_max = 1024},
-       .snd_line6_capture_hw = {
-                                .info = (SNDRV_PCM_INFO_MMAP |
-                                         SNDRV_PCM_INFO_INTERLEAVED |
-                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                         SNDRV_PCM_INFO_MMAP_VALID |
-#ifdef CONFIG_PM
-                                         SNDRV_PCM_INFO_RESUME |
-#endif
-                                         SNDRV_PCM_INFO_SYNC_START),
-                                .formats = SNDRV_PCM_FMTBIT_S16_LE,
-                                .rates = SNDRV_PCM_RATE_KNOT,
-                                .rate_min = 44100,
-                                .rate_max = 44100,
-                                .channels_min = 2,
-                                .channels_max = 2,
-                                .buffer_bytes_max = 60000,
-                                .period_bytes_min = 64,
-                                .period_bytes_max = 8192,
-                                .periods_min = 1,
-                                .periods_max = 1024},
-       .snd_line6_rates = {
-                           .nrats = 1,
-                           .rats = &toneport_ratden},
-       .bytes_per_frame = 4
-};
-
-/*
-       For the led on Guitarport.
-       Brightness goes from 0x00 to 0x26. Set a value above this to have led
-       blink.
-       (void cmd_0x02(byte red, byte green)
-*/
-static int led_red = 0x00;
-static int led_green = 0x26;
-
-static const struct {
-       const char *name;
-       int code;
-} toneport_source_info[] = {
-       {"Microphone", 0x0a01},
-       {"Line", 0x0801},
-       {"Instrument", 0x0b01},
-       {"Inst & Mic", 0x0901}
-};
-
-static bool toneport_has_led(short product)
-{
-       return
-           (product == LINE6_DEVID_GUITARPORT) ||
-           (product == LINE6_DEVID_TONEPORT_GX);
-       /* add your device here if you are missing support for the LEDs */
-}
-
-static void toneport_update_led(struct device *dev)
-{
-       struct usb_interface *interface = to_usb_interface(dev);
-       struct usb_line6_toneport *tp = usb_get_intfdata(interface);
-       struct usb_line6 *line6;
-
-       if (!tp)
-               return;
-
-       line6 = &tp->line6;
-       if (line6)
-               toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
-                                 led_green);
-}
-
-static ssize_t toneport_set_led_red(struct device *dev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t count)
-{
-       int retval;
-
-       retval = kstrtoint(buf, 10, &led_red);
-       if (retval)
-               return retval;
-
-       toneport_update_led(dev);
-       return count;
-}
-
-static ssize_t toneport_set_led_green(struct device *dev,
-                                     struct device_attribute *attr,
-                                     const char *buf, size_t count)
-{
-       int retval;
-
-       retval = kstrtoint(buf, 10, &led_green);
-       if (retval)
-               return retval;
-
-       toneport_update_led(dev);
-       return count;
-}
-
-static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
-                  toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
-                  toneport_set_led_green);
-
-static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
-{
-       int ret;
-
-       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
-                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                             cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
-
-       if (ret < 0) {
-               dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-/* monitor info callback */
-static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol,
-                                    struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 256;
-       return 0;
-}
-
-/* monitor get callback */
-static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,
-                                   struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-
-       ucontrol->value.integer.value[0] = line6pcm->volume_monitor;
-       return 0;
-}
-
-/* monitor put callback */
-static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
-                                   struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-
-       if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
-               return 0;
-
-       line6pcm->volume_monitor = ucontrol->value.integer.value[0];
-
-       if (line6pcm->volume_monitor > 0)
-               line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);
-       else
-               line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
-
-       return 1;
-}
-
-/* source info callback */
-static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
-                                   struct snd_ctl_elem_info *uinfo)
-{
-       const int size = ARRAY_SIZE(toneport_source_info);
-
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-       uinfo->count = 1;
-       uinfo->value.enumerated.items = size;
-
-       if (uinfo->value.enumerated.item >= size)
-               uinfo->value.enumerated.item = size - 1;
-
-       strcpy(uinfo->value.enumerated.name,
-              toneport_source_info[uinfo->value.enumerated.item].name);
-
-       return 0;
-}
-
-/* source get callback */
-static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
-                                  struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_toneport *toneport =
-           (struct usb_line6_toneport *)line6pcm->line6;
-       ucontrol->value.enumerated.item[0] = toneport->source;
-       return 0;
-}
-
-/* source put callback */
-static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
-                                  struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_toneport *toneport =
-           (struct usb_line6_toneport *)line6pcm->line6;
-       unsigned int source;
-
-       source = ucontrol->value.enumerated.item[0];
-       if (source >= ARRAY_SIZE(toneport_source_info))
-               return -EINVAL;
-       if (source == toneport->source)
-               return 0;
-
-       toneport->source = source;
-       toneport_send_cmd(toneport->line6.usbdev,
-                         toneport_source_info[source].code, 0x0000);
-       return 1;
-}
-
-static void toneport_start_pcm(unsigned long arg)
-{
-       struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
-       struct usb_line6 *line6 = &toneport->line6;
-
-       line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);
-}
-
-/* control definition */
-static struct snd_kcontrol_new toneport_control_monitor = {
-       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name = "Monitor Playback Volume",
-       .index = 0,
-       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-       .info = snd_toneport_monitor_info,
-       .get = snd_toneport_monitor_get,
-       .put = snd_toneport_monitor_put
-};
-
-/* source selector definition */
-static struct snd_kcontrol_new toneport_control_source = {
-       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name = "PCM Capture Source",
-       .index = 0,
-       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-       .info = snd_toneport_source_info,
-       .get = snd_toneport_source_get,
-       .put = snd_toneport_source_put
-};
-
-/*
-       Toneport destructor.
-*/
-static void toneport_destruct(struct usb_interface *interface)
-{
-       struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
-
-       if (toneport == NULL)
-               return;
-       line6_cleanup_audio(&toneport->line6);
-}
-
-/*
-       Setup Toneport device.
-*/
-static void toneport_setup(struct usb_line6_toneport *toneport)
-{
-       int ticks;
-       struct usb_line6 *line6 = &toneport->line6;
-       struct usb_device *usbdev = line6->usbdev;
-       u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
-
-       /* sync time on device with host: */
-       ticks = (int)get_seconds();
-       line6_write_data(line6, 0x80c6, &ticks, 4);
-
-       /* enable device: */
-       toneport_send_cmd(usbdev, 0x0301, 0x0000);
-
-       /* initialize source select: */
-       switch (le16_to_cpu(usbdev->descriptor.idProduct)) {
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-               toneport_send_cmd(usbdev,
-                                 toneport_source_info[toneport->source].code,
-                                 0x0000);
-       }
-
-       if (toneport_has_led(idProduct))
-               toneport_update_led(&usbdev->dev);
-}
-
-/*
-        Try to init Toneport device.
-*/
-static int toneport_try_init(struct usb_interface *interface,
-                            struct usb_line6_toneport *toneport)
-{
-       int err;
-       struct usb_line6 *line6 = &toneport->line6;
-       struct usb_device *usbdev = line6->usbdev;
-       u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
-
-       if ((interface == NULL) || (toneport == NULL))
-               return -ENODEV;
-
-       /* initialize audio system: */
-       err = line6_init_audio(line6);
-       if (err < 0)
-               return err;
-
-       /* initialize PCM subsystem: */
-       err = line6_init_pcm(line6, &toneport_pcm_properties);
-       if (err < 0)
-               return err;
-
-       /* register monitor control: */
-       err = snd_ctl_add(line6->card,
-                         snd_ctl_new1(&toneport_control_monitor,
-                                      line6->line6pcm));
-       if (err < 0)
-               return err;
-
-       /* register source select control: */
-       switch (le16_to_cpu(usbdev->descriptor.idProduct)) {
-       case LINE6_DEVID_TONEPORT_UX1:
-       case LINE6_DEVID_TONEPORT_UX2:
-       case LINE6_DEVID_PODSTUDIO_UX1:
-       case LINE6_DEVID_PODSTUDIO_UX2:
-               err =
-                   snd_ctl_add(line6->card,
-                               snd_ctl_new1(&toneport_control_source,
-                                            line6->line6pcm));
-               if (err < 0)
-                       return err;
-       }
-
-       /* register audio system: */
-       err = line6_register_audio(line6);
-       if (err < 0)
-               return err;
-
-       line6_read_serial_number(line6, &toneport->serial_number);
-       line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
-
-       if (toneport_has_led(idProduct)) {
-               CHECK_RETURN(device_create_file
-                            (&interface->dev, &dev_attr_led_red));
-               CHECK_RETURN(device_create_file
-                            (&interface->dev, &dev_attr_led_green));
-       }
-
-       toneport_setup(toneport);
-
-       init_timer(&toneport->timer);
-       toneport->timer.expires = jiffies + TONEPORT_PCM_DELAY * HZ;
-       toneport->timer.function = toneport_start_pcm;
-       toneport->timer.data = (unsigned long)toneport;
-       add_timer(&toneport->timer);
-
-       return 0;
-}
-
-/*
-        Init Toneport device (and clean up in case of failure).
-*/
-int line6_toneport_init(struct usb_interface *interface,
-                       struct usb_line6_toneport *toneport)
-{
-       int err = toneport_try_init(interface, toneport);
-
-       if (err < 0)
-               toneport_destruct(interface);
-
-       return err;
-}
-
-/*
-       Resume Toneport device after reset.
-*/
-void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)
-{
-       toneport_setup(toneport);
-}
-
-/*
-       Toneport device disconnected.
-*/
-void line6_toneport_disconnect(struct usb_interface *interface)
-{
-       struct usb_line6_toneport *toneport;
-       u16 idProduct;
-
-       if (interface == NULL)
-               return;
-
-       toneport = usb_get_intfdata(interface);
-       del_timer_sync(&toneport->timer);
-       idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct);
-
-       if (toneport_has_led(idProduct)) {
-               device_remove_file(&interface->dev, &dev_attr_led_red);
-               device_remove_file(&interface->dev, &dev_attr_led_green);
-       }
-
-       if (toneport != NULL) {
-               struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
-
-               if (line6pcm != NULL) {
-                       line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
-                       line6_pcm_disconnect(line6pcm);
-               }
-       }
-
-       toneport_destruct(interface);
-}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
deleted file mode 100644 (file)
index 8576b72..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef TONEPORT_H
-#define TONEPORT_H
-
-#include <linux/usb.h>
-#include <sound/core.h>
-
-#include "driver.h"
-
-struct usb_line6_toneport {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Source selector.
-       */
-       int source;
-
-       /**
-               Serial number of device.
-       */
-       int serial_number;
-
-       /**
-               Firmware version (x 100).
-       */
-       int firmware_version;
-
-       /**
-                Timer for delayed PCM startup.
-       */
-       struct timer_list timer;
-};
-
-extern void line6_toneport_disconnect(struct usb_interface *interface);
-extern int line6_toneport_init(struct usb_interface *interface,
-                              struct usb_line6_toneport *toneport);
-extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport);
-
-#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
deleted file mode 100644 (file)
index 2d1cc47..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef USBDEFS_H
-#define USBDEFS_H
-
-#define LINE6_VENDOR_ID  0x0e41
-
-#define USB_INTERVALS_PER_SECOND 1000
-
-/*
-       Device ids.
-*/
-#define LINE6_DEVID_BASSPODXT     0x4250
-#define LINE6_DEVID_BASSPODXTLIVE 0x4642
-#define LINE6_DEVID_BASSPODXTPRO  0x4252
-#define LINE6_DEVID_GUITARPORT    0x4750
-#define LINE6_DEVID_POCKETPOD     0x5051
-#define LINE6_DEVID_PODHD300      0x5057
-#define LINE6_DEVID_PODHD400      0x5058
-#define LINE6_DEVID_PODHD500      0x414D
-#define LINE6_DEVID_PODSTUDIO_GX  0x4153
-#define LINE6_DEVID_PODSTUDIO_UX1 0x4150
-#define LINE6_DEVID_PODSTUDIO_UX2 0x4151
-#define LINE6_DEVID_PODX3         0x414a
-#define LINE6_DEVID_PODX3LIVE     0x414b
-#define LINE6_DEVID_PODXT         0x5044
-#define LINE6_DEVID_PODXTLIVE     0x4650
-#define LINE6_DEVID_PODXTPRO      0x5050
-#define LINE6_DEVID_TONEPORT_GX   0x4147
-#define LINE6_DEVID_TONEPORT_UX1  0x4141
-#define LINE6_DEVID_TONEPORT_UX2  0x4142
-#define LINE6_DEVID_VARIAX        0x534d
-
-#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x
-
-enum {
-       LINE6_INDEX_BASSPODXT,
-       LINE6_INDEX_BASSPODXTLIVE,
-       LINE6_INDEX_BASSPODXTPRO,
-       LINE6_INDEX_GUITARPORT,
-       LINE6_INDEX_POCKETPOD,
-       LINE6_INDEX_PODHD300,
-       LINE6_INDEX_PODHD400,
-       LINE6_INDEX_PODHD500,
-       LINE6_INDEX_PODSTUDIO_GX,
-       LINE6_INDEX_PODSTUDIO_UX1,
-       LINE6_INDEX_PODSTUDIO_UX2,
-       LINE6_INDEX_PODX3,
-       LINE6_INDEX_PODX3LIVE,
-       LINE6_INDEX_PODXT,
-       LINE6_INDEX_PODXTLIVE,
-       LINE6_INDEX_PODXTPRO,
-       LINE6_INDEX_TONEPORT_GX,
-       LINE6_INDEX_TONEPORT_UX1,
-       LINE6_INDEX_TONEPORT_UX2,
-       LINE6_INDEX_VARIAX,
-
-       LINE6_BIT(BASSPODXT),
-       LINE6_BIT(BASSPODXTLIVE),
-       LINE6_BIT(BASSPODXTPRO),
-       LINE6_BIT(GUITARPORT),
-       LINE6_BIT(POCKETPOD),
-       LINE6_BIT(PODHD300),
-       LINE6_BIT(PODHD400),
-       LINE6_BIT(PODHD500),
-       LINE6_BIT(PODSTUDIO_GX),
-       LINE6_BIT(PODSTUDIO_UX1),
-       LINE6_BIT(PODSTUDIO_UX2),
-       LINE6_BIT(PODX3),
-       LINE6_BIT(PODX3LIVE),
-       LINE6_BIT(PODXT),
-       LINE6_BIT(PODXTLIVE),
-       LINE6_BIT(PODXTPRO),
-       LINE6_BIT(TONEPORT_GX),
-       LINE6_BIT(TONEPORT_UX1),
-       LINE6_BIT(TONEPORT_UX2),
-       LINE6_BIT(VARIAX),
-
-       LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO,
-       LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE |
-                         LINE6_BIT_PODX3LIVE,
-       LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE |
-                             LINE6_BIT_PODXTPRO,
-       LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE,
-       LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 |
-                             LINE6_BIT_PODHD400 |
-                             LINE6_BIT_PODHD500,
-       LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT |
-                                 LINE6_BIT_BASSPODXTLIVE |
-                                 LINE6_BIT_BASSPODXTPRO
-};
-
-/* device supports settings parameter via USB */
-#define LINE6_BIT_CONTROL (1 << 0)
-/* device supports PCM input/output via USB */
-#define LINE6_BIT_PCM (1 << 1)
-/* device support hardware monitoring */
-#define LINE6_BIT_HWMON (1 << 2)
-
-#define LINE6_BIT_CTRL_PCM_HW  (LINE6_BIT_CONTROL |    \
-                                        LINE6_BIT_PCM |        \
-                                        LINE6_BIT_HWMON)
-
-#define LINE6_FALLBACK_INTERVAL 10
-#define LINE6_FALLBACK_MAXPACKETSIZE 16
-
-#endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
deleted file mode 100644 (file)
index ae2be99..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#include <linux/slab.h>
-
-#include "audio.h"
-#include "driver.h"
-#include "variax.h"
-
-#define VARIAX_OFFSET_ACTIVATE 7
-
-/*
-       This message is sent by the device during initialization and identifies
-       the connected guitar version.
-*/
-static const char variax_init_version[] = {
-       0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
-       0x07, 0x00, 0x00, 0x00
-};
-
-/*
-       This message is the last one sent by the device during initialization.
-*/
-static const char variax_init_done[] = {
-       0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
-};
-
-static const char variax_activate[] = {
-       0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
-       0xf7
-};
-
-/* forward declarations: */
-static void variax_startup2(unsigned long data);
-static void variax_startup4(unsigned long data);
-static void variax_startup5(unsigned long data);
-
-static void variax_activate_async(struct usb_line6_variax *variax, int a)
-{
-       variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
-       line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
-                                    sizeof(variax_activate));
-}
-
-/*
-       Variax startup procedure.
-       This is a sequence of functions with special requirements (e.g., must
-       not run immediately after initialization, must not run in interrupt
-       context). After the last one has finished, the device is ready to use.
-*/
-
-static void variax_startup1(struct usb_line6_variax *variax)
-{
-       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
-
-       /* delay startup procedure: */
-       line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
-                         variax_startup2, (unsigned long)variax);
-}
-
-static void variax_startup2(unsigned long data)
-{
-       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
-       struct usb_line6 *line6 = &variax->line6;
-
-       /* schedule another startup procedure until startup is complete: */
-       if (variax->startup_progress >= VARIAX_STARTUP_LAST)
-               return;
-
-       variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
-       line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
-                         variax_startup2, (unsigned long)variax);
-
-       /* request firmware version: */
-       line6_version_request_async(line6);
-}
-
-static void variax_startup3(struct usb_line6_variax *variax)
-{
-       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
-
-       /* delay startup procedure: */
-       line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
-                         variax_startup4, (unsigned long)variax);
-}
-
-static void variax_startup4(unsigned long data)
-{
-       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
-
-       CHECK_STARTUP_PROGRESS(variax->startup_progress,
-                              VARIAX_STARTUP_ACTIVATE);
-
-       /* activate device: */
-       variax_activate_async(variax, 1);
-       line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
-                         variax_startup5, (unsigned long)variax);
-}
-
-static void variax_startup5(unsigned long data)
-{
-       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
-
-       CHECK_STARTUP_PROGRESS(variax->startup_progress,
-                              VARIAX_STARTUP_WORKQUEUE);
-
-       /* schedule work for global work queue: */
-       schedule_work(&variax->startup_work);
-}
-
-static void variax_startup6(struct work_struct *work)
-{
-       struct usb_line6_variax *variax =
-           container_of(work, struct usb_line6_variax, startup_work);
-
-       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
-
-       /* ALSA audio interface: */
-       line6_register_audio(&variax->line6);
-}
-
-/*
-       Process a completely received message.
-*/
-void line6_variax_process_message(struct usb_line6_variax *variax)
-{
-       const unsigned char *buf = variax->line6.buffer_message;
-
-       switch (buf[0]) {
-       case LINE6_RESET:
-               dev_info(variax->line6.ifcdev, "VARIAX reset\n");
-               break;
-
-       case LINE6_SYSEX_BEGIN:
-               if (memcmp(buf + 1, variax_init_version + 1,
-                          sizeof(variax_init_version) - 1) == 0) {
-                       variax_startup3(variax);
-               } else if (memcmp(buf + 1, variax_init_done + 1,
-                                 sizeof(variax_init_done) - 1) == 0) {
-                       /* notify of complete initialization: */
-                       variax_startup4((unsigned long)variax);
-               }
-               break;
-       }
-}
-
-/*
-       Variax destructor.
-*/
-static void variax_destruct(struct usb_interface *interface)
-{
-       struct usb_line6_variax *variax = usb_get_intfdata(interface);
-
-       if (variax == NULL)
-               return;
-       line6_cleanup_audio(&variax->line6);
-
-       del_timer(&variax->startup_timer1);
-       del_timer(&variax->startup_timer2);
-       cancel_work_sync(&variax->startup_work);
-
-       kfree(variax->buffer_activate);
-}
-
-/*
-        Try to init workbench device.
-*/
-static int variax_try_init(struct usb_interface *interface,
-                          struct usb_line6_variax *variax)
-{
-       int err;
-
-       init_timer(&variax->startup_timer1);
-       init_timer(&variax->startup_timer2);
-       INIT_WORK(&variax->startup_work, variax_startup6);
-
-       if ((interface == NULL) || (variax == NULL))
-               return -ENODEV;
-
-       /* initialize USB buffers: */
-       variax->buffer_activate = kmemdup(variax_activate,
-                                         sizeof(variax_activate), GFP_KERNEL);
-
-       if (variax->buffer_activate == NULL) {
-               dev_err(&interface->dev, "Out of memory\n");
-               return -ENOMEM;
-       }
-
-       /* initialize audio system: */
-       err = line6_init_audio(&variax->line6);
-       if (err < 0)
-               return err;
-
-       /* initialize MIDI subsystem: */
-       err = line6_init_midi(&variax->line6);
-       if (err < 0)
-               return err;
-
-       /* initiate startup procedure: */
-       variax_startup1(variax);
-       return 0;
-}
-
-/*
-        Init workbench device (and clean up in case of failure).
-*/
-int line6_variax_init(struct usb_interface *interface,
-                     struct usb_line6_variax *variax)
-{
-       int err = variax_try_init(interface, variax);
-
-       if (err < 0)
-               variax_destruct(interface);
-
-       return err;
-}
-
-/*
-       Workbench device disconnected.
-*/
-void line6_variax_disconnect(struct usb_interface *interface)
-{
-       if (interface == NULL)
-               return;
-
-       variax_destruct(interface);
-}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
deleted file mode 100644 (file)
index 24de796..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- *     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, version 2.
- *
- */
-
-#ifndef VARIAX_H
-#define VARIAX_H
-
-#include <linux/spinlock.h>
-#include <linux/usb.h>
-#include <linux/wait.h>
-#include <sound/core.h>
-
-#include "driver.h"
-
-#define VARIAX_STARTUP_DELAY1 1000
-#define VARIAX_STARTUP_DELAY3 100
-#define VARIAX_STARTUP_DELAY4 100
-
-/*
-       Stages of Variax startup procedure
-*/
-enum {
-       VARIAX_STARTUP_INIT = 1,
-       VARIAX_STARTUP_VERSIONREQ,
-       VARIAX_STARTUP_WAIT,
-       VARIAX_STARTUP_ACTIVATE,
-       VARIAX_STARTUP_WORKQUEUE,
-       VARIAX_STARTUP_SETUP,
-       VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
-};
-
-struct usb_line6_variax {
-       /**
-               Generic Line6 USB data.
-       */
-       struct usb_line6 line6;
-
-       /**
-               Buffer for activation code.
-       */
-       unsigned char *buffer_activate;
-
-       /**
-               Handler for device initializaton.
-       */
-       struct work_struct startup_work;
-
-       /**
-               Timers for device initializaton.
-       */
-       struct timer_list startup_timer1;
-       struct timer_list startup_timer2;
-
-       /**
-               Current progress in startup procedure.
-       */
-       int startup_progress;
-};
-
-extern void line6_variax_disconnect(struct usb_interface *interface);
-extern int line6_variax_init(struct usb_interface *interface,
-                            struct usb_line6_variax *variax);
-extern void line6_variax_process_message(struct usb_line6_variax *variax);
-
-#endif
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
new file mode 100644 (file)
index 0000000..3e2f22e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright Â© 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _I915_COMPONENT_H_
+#define _I915_COMPONENT_H_
+
+struct i915_audio_component {
+       struct device *dev;
+
+       const struct i915_audio_component_ops {
+               struct module *owner;
+               void (*get_power)(struct device *);
+               void (*put_power)(struct device *);
+               int (*get_cdclk_freq)(struct device *);
+       } *ops;
+};
+
+#endif /* _I915_COMPONENT_H_ */
diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h
deleted file mode 100644 (file)
index baa6f11..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2013 Intel Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *
- **************************************************************************/
-
-#ifndef _I915_POWERWELL_H_
-#define _I915_POWERWELL_H_
-
-/* For use by hda_i915 driver */
-extern int i915_request_power_well(void);
-extern int i915_release_power_well(void);
-extern int i915_get_cdclk_freq(void);
-
-#endif                         /* _I915_POWERWELL_H_ */
index abdf609..f2d3a6d 100644 (file)
@@ -170,10 +170,9 @@ extern int snd_ad1816a_create(struct snd_card *card, unsigned long port,
                              int irq, int dma1, int dma2,
                              struct snd_ad1816a *chip);
 
-extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
+extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device);
 extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
-extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
-                            struct snd_timer **rtimer);
+extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device);
 #ifdef CONFIG_PM
 extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
 extern void snd_ad1816a_resume(struct snd_ad1816a *chip);
index 396e8f7..1e25310 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <sound/core.h>
 #include <sound/compress_offload.h>
 #include <sound/asound.h>
 #include <sound/pcm.h>
index c46908c..0de95cc 100644 (file)
@@ -33,8 +33,8 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <uapi/sound/emu10k1.h>
 
 /* ------------------- DEFINES -------------------- */
@@ -1809,17 +1809,17 @@ int snd_emu10k1_create(struct snd_card *card,
                       uint subsystem,
                       struct snd_emu10k1 ** remu);
 
-int snd_emu10k1_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
-int snd_emu10k1_pcm_mic(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
-int snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
-int snd_p16v_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device);
+int snd_p16v_pcm(struct snd_emu10k1 *emu, int device);
 int snd_p16v_free(struct snd_emu10k1 * emu);
 int snd_p16v_mixer(struct snd_emu10k1 * emu);
-int snd_emu10k1_pcm_multi(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
-int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 *emu, int device);
 int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device);
 int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device);
-int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep);
+int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device);
 
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id);
 
index 1d636a2..b34f23a 100644 (file)
@@ -115,8 +115,7 @@ int snd_es1688_create(struct snd_card *card,
                      int mpu_irq,
                      int dma8,
                      unsigned short hardware);
-int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device,
-                  struct snd_pcm **rpcm);
+int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device);
 int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip);
 int snd_es1688_reset(struct snd_es1688 *chip);
 
index 42905d8..07c116f 100644 (file)
@@ -27,7 +27,7 @@
 #include <sound/timer.h>
 #include <sound/seq_midi_emul.h>
 #include <sound/seq_device.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* IO ports */
 
@@ -591,7 +591,7 @@ int snd_gf1_new_mixer(struct snd_gus_card * gus);
 
 /* gus_pcm.c */
 
-int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm);
+int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index);
 
 #ifdef CONFIG_SND_DEBUG
 extern void snd_gf1_print_voice_registers(struct snd_gus_card * gus);
@@ -620,7 +620,7 @@ void snd_gus_irq_profile_init(struct snd_gus_card *gus);
 
 /* gus_uart.c */
 
-int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi **rrawmidi);
+int snd_gf1_rawmidi_new(struct snd_gus_card *gus, int device);
 
 /* gus_dram.c */
 int snd_gus_dram_write(struct snd_gus_card *gus, char __user *ptr,
index b429b73..cd09c1b 100644 (file)
@@ -94,9 +94,6 @@ struct snd_pcm_ops {
 #define SNDRV_PCM_DEVICES      8
 #endif
 
-#define SNDRV_PCM_IOCTL1_FALSE         ((void *)0)
-#define SNDRV_PCM_IOCTL1_TRUE          ((void *)1)
-
 #define SNDRV_PCM_IOCTL1_RESET         0
 #define SNDRV_PCM_IOCTL1_INFO          1
 #define SNDRV_PCM_IOCTL1_CHANNEL_INFO  2
@@ -109,6 +106,7 @@ struct snd_pcm_ops {
 #define SNDRV_PCM_TRIGGER_PAUSE_RELEASE        4
 #define SNDRV_PCM_TRIGGER_SUSPEND      5
 #define SNDRV_PCM_TRIGGER_RESUME       6
+#define SNDRV_PCM_TRIGGER_DRAIN                7
 
 #define SNDRV_PCM_POS_XRUN             ((snd_pcm_uframes_t)-1)
 
@@ -520,7 +518,6 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream);
 int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, struct file *file,
                             struct snd_pcm_substream **rsubstream);
 void snd_pcm_detach_substream(struct snd_pcm_substream *substream);
-void snd_pcm_vma_notify_data(void *client, void *data);
 int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
 
 
@@ -986,21 +983,15 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format);               /* in bits */
 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
-snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsigned, int big_endian);
 
 void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
                     const struct snd_pcm_ops *ops);
 void snd_pcm_set_sync(struct snd_pcm_substream *substream);
-int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream);
 int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
                      unsigned int cmd, void *arg);                      
 int snd_pcm_update_state(struct snd_pcm_substream *substream,
                         struct snd_pcm_runtime *runtime);
 int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
-int snd_pcm_playback_xrun_check(struct snd_pcm_substream *substream);
-int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream);
-int snd_pcm_playback_xrun_asap(struct snd_pcm_substream *substream);
-int snd_pcm_capture_xrun_asap(struct snd_pcm_substream *substream);
 void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr);
 void snd_pcm_period_elapsed(struct snd_pcm_substream *substream);
 snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream,
index 6b1c78f..3c45f39 100644 (file)
@@ -38,31 +38,6 @@ int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
 #define MASK_OFS(i)    ((i) >> 5)
 #define MASK_BIT(i)    (1U << ((i) & 31))
 
-static inline unsigned int ld2(u_int32_t v)
-{
-        unsigned r = 0;
-
-        if (v >= 0x10000) {
-                v >>= 16;
-                r += 16;
-        }
-        if (v >= 0x100) {
-                v >>= 8;
-                r += 8;
-        }
-        if (v >= 0x10) {
-                v >>= 4;
-                r += 4;
-        }
-        if (v >= 4) {
-                v >>= 2;
-                r += 2;
-        }
-        if (v >= 2)
-                r++;
-        return r;
-}
-
 static inline size_t snd_mask_sizeof(void)
 {
        return sizeof(struct snd_mask);
@@ -92,7 +67,7 @@ static inline unsigned int snd_mask_min(const struct snd_mask *mask)
        int i;
        for (i = 0; i < SNDRV_MASK_SIZE; i++) {
                if (mask->bits[i])
-                       return ffs(mask->bits[i]) - 1 + (i << 5);
+                       return __ffs(mask->bits[i]) + (i << 5);
        }
        return 0;
 }
@@ -102,7 +77,7 @@ static inline unsigned int snd_mask_max(const struct snd_mask *mask)
        int i;
        for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
                if (mask->bits[i])
-                       return ld2(mask->bits[i]) + (i << 5);
+                       return __fls(mask->bits[i]) + (i << 5);
        }
        return 0;
 }
@@ -325,43 +300,68 @@ static inline int snd_interval_eq(const struct snd_interval *i1, const struct sn
                i1->max == i2->max && i1->openmax == i2->openmax;
 }
 
-static inline unsigned int add(unsigned int a, unsigned int b)
+/**
+ * params_access - get the access type from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
 {
-       if (a >= UINT_MAX - b)
-               return UINT_MAX;
-       return a + b;
+       return (__force snd_pcm_access_t)snd_mask_min(hw_param_mask_c(p,
+               SNDRV_PCM_HW_PARAM_ACCESS));
 }
 
-static inline unsigned int sub(unsigned int a, unsigned int b)
+/**
+ * params_format - get the sample format from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
 {
-       if (a > b)
-               return a - b;
-       return 0;
+       return (__force snd_pcm_format_t)snd_mask_min(hw_param_mask_c(p,
+               SNDRV_PCM_HW_PARAM_FORMAT));
 }
 
-#define params_access(p) ((__force snd_pcm_access_t)\
-               snd_mask_min(hw_param_mask_c((p), SNDRV_PCM_HW_PARAM_ACCESS)))
-#define params_format(p) ((__force snd_pcm_format_t)\
-               snd_mask_min(hw_param_mask_c((p), SNDRV_PCM_HW_PARAM_FORMAT)))
-#define params_subformat(p) \
-       snd_mask_min(hw_param_mask_c((p), SNDRV_PCM_HW_PARAM_SUBFORMAT))
+/**
+ * params_subformat - get the sample subformat from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_subformat_t
+params_subformat(const struct snd_pcm_hw_params *p)
+{
+       return (__force snd_pcm_subformat_t)snd_mask_min(hw_param_mask_c(p,
+               SNDRV_PCM_HW_PARAM_SUBFORMAT));
+}
 
+/**
+ * params_period_bytes - get the period size (in bytes) from the hw params
+ * @p: hw params
+ */
 static inline unsigned int
 params_period_bytes(const struct snd_pcm_hw_params *p)
 {
-       return (params_period_size(p) *
-               snd_pcm_format_physical_width(params_format(p)) *
-               params_channels(p)) / 8;
+       return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->min;
 }
 
-static inline int
-params_width(const struct snd_pcm_hw_params *p)
+/**
+ * params_width - get the number of bits of the sample format from the hw params
+ * @p: hw params
+ *
+ * This function returns the number of bits per sample that the selected sample
+ * format of the hw params has.
+ */
+static inline int params_width(const struct snd_pcm_hw_params *p)
 {
        return snd_pcm_format_width(params_format(p));
 }
 
-static inline int
-params_physical_width(const struct snd_pcm_hw_params *p)
+/*
+ * params_physical_width - get the storage size of the sample format from the hw params
+ * @p: hw params
+ *
+ * This functions returns the number of bits per sample that the selected sample
+ * format of the hw params takes up in memory. This will be equal or larger than
+ * params_width().
+ */
+static inline int params_physical_width(const struct snd_pcm_hw_params *p)
 {
        return snd_pcm_format_physical_width(params_format(p));
 }
index ba39603..bacefae 100644 (file)
@@ -25,7 +25,7 @@
 #include <sound/pcm.h>
 #include <sound/rawmidi.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 enum sb_hw_type {
        SB_HW_AUTO,
@@ -308,7 +308,7 @@ void snd_sbmixer_resume(struct snd_sb *chip);
 #endif
 
 /* sb8_init.c */
-int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
+int snd_sb8dsp_pcm(struct snd_sb *chip, int device);
 /* sb8.c */
 irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip);
 int snd_sb8_playback_open(struct snd_pcm_substream *substream);
@@ -317,10 +317,10 @@ int snd_sb8_playback_close(struct snd_pcm_substream *substream);
 int snd_sb8_capture_close(struct snd_pcm_substream *substream);
 /* midi8.c */
 irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip);
-int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi);
+int snd_sb8dsp_midi(struct snd_sb *chip, int device);
 
 /* sb16_init.c */
-int snd_sb16dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
+int snd_sb16dsp_pcm(struct snd_sb *chip, int device);
 const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction);
 int snd_sb16dsp_configure(struct snd_sb *chip);
 /* sb16.c */
index eea5400..18a2ac5 100644 (file)
 typedef struct snd_seq_real_time snd_seq_real_time_t;
 typedef union snd_seq_timestamp snd_seq_timestamp_t;
 
-/* maximum number of events dequeued per schedule interval */
-#define SNDRV_SEQ_MAX_DEQUEUE          50
-
 /* maximum number of queues */
-#define SNDRV_SEQ_MAX_QUEUES           8
+#define SNDRV_SEQ_MAX_QUEUES           32
 
 /* max number of concurrent clients */
 #define SNDRV_SEQ_MAX_CLIENTS          192
@@ -42,9 +39,6 @@ typedef union snd_seq_timestamp snd_seq_timestamp_t;
 /* max number of events in memory pool */
 #define SNDRV_SEQ_MAX_EVENTS           2000
 
-/* default number of events in memory chunk */
-#define SNDRV_SEQ_DEFAULT_CHUNK_EVENTS 64
-
 /* default number of events in memory pool */
 #define SNDRV_SEQ_DEFAULT_EVENTS       500
 
@@ -70,7 +64,6 @@ struct snd_seq_port_callback {
        int (*unuse)(void *private_data, struct snd_seq_port_subscribe *info);
        int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
        void (*private_free)(void *private_data);
-       unsigned int callback_all;      /* call subscribe callbacks at each connection/disconnection */
        /*...*/
 };
 
index 89823cf..ecffecc 100644 (file)
@@ -431,7 +431,6 @@ int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
                                           const char *pin);
 int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
                                const char *pin);
-void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card);
 unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
 
 /* Mostly internal - should not normally be used */
index 0c7f034..1823e3a 100644 (file)
@@ -154,8 +154,8 @@ int snd_wss_create(struct snd_card *card,
                      unsigned short hardware,
                      unsigned short hwshare,
                      struct snd_wss **rchip);
-int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
-int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer);
+int snd_wss_pcm(struct snd_wss *chip, int device);
+int snd_wss_timer(struct snd_wss *chip, int device);
 int snd_wss_mixer(struct snd_wss *chip);
 
 const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction);
@@ -167,7 +167,7 @@ int snd_cs4236_create(struct snd_card *card,
                      unsigned short hardware,
                      unsigned short hwshare,
                      struct snd_wss **rchip);
-int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
+int snd_cs4236_pcm(struct snd_wss *chip, int device);
 int snd_cs4236_mixer(struct snd_wss *chip);
 
 /*
index 1f23cd6..0e88e7a 100644 (file)
@@ -268,6 +268,7 @@ typedef int __bitwise snd_pcm_subformat_t;
 #define SNDRV_PCM_INFO_SYNC_START      0x00400000      /* pcm support some kind of sync go */
 #define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP        0x00800000      /* period wakeup can be disabled */
 #define SNDRV_PCM_INFO_HAS_WALL_CLOCK   0x01000000      /* has audio wall clock for audio/system time sync */
+#define SNDRV_PCM_INFO_DRAIN_TRIGGER   0x40000000              /* internal kernel flag - trigger in drain */
 #define SNDRV_PCM_INFO_FIFO_IN_FRAMES  0x80000000      /* internal kernel flag - FIFO size is in frames */
 
 typedef int __bitwise snd_pcm_state_t;
diff --git a/include/uapi/sound/usb_stream.h b/include/uapi/sound/usb_stream.h
new file mode 100644 (file)
index 0000000..cfe8fba
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _UAPI__SOUND_USB_STREAM_H
+#define _UAPI__SOUND_USB_STREAM_H
+
+#define USB_STREAM_INTERFACE_VERSION 2
+
+#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
+       _IOW('H', 0x90, struct usb_stream_config)
+
+struct usb_stream_packet {
+       unsigned offset;
+       unsigned length;
+};
+
+
+struct usb_stream_config {
+       unsigned version;
+       unsigned sample_rate;
+       unsigned period_frames;
+       unsigned frame_size;
+};
+
+struct usb_stream {
+       struct usb_stream_config cfg;
+       unsigned read_size;
+       unsigned write_size;
+
+       int period_size;
+
+       unsigned state;
+
+       int idle_insize;
+       int idle_outsize;
+       int sync_packet;
+       unsigned insize_done;
+       unsigned periods_done;
+       unsigned periods_polled;
+
+       struct usb_stream_packet outpacket[2];
+       unsigned                 inpackets;
+       unsigned                 inpacket_head;
+       unsigned                 inpacket_split;
+       unsigned                 inpacket_split_at;
+       unsigned                 next_inpacket_split;
+       unsigned                 next_inpacket_split_at;
+       struct usb_stream_packet inpacket[0];
+};
+
+enum usb_stream_state {
+       usb_stream_invalid,
+       usb_stream_stopped,
+       usb_stream_sync0,
+       usb_stream_sync1,
+       usb_stream_ready,
+       usb_stream_running,
+       usb_stream_xrun,
+};
+
+#endif /* _UAPI__SOUND_USB_STREAM_H */
index 4dc9b49..f4495de 100644 (file)
@@ -9,8 +9,8 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/macio.h>
 #include <asm/pmac_feature.h>
index 4e2b4fb..b9737fa 100644 (file)
@@ -74,10 +74,9 @@ static void i2sbus_release_dev(struct device *dev)
        int i;
 
        i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);
-
-       if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
-       if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
-       if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
+       iounmap(i2sdev->intfregs);
+       iounmap(i2sdev->out.dbdma);
+       iounmap(i2sdev->in.dbdma);
        for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
                release_and_free_resource(i2sdev->allocated_resource[i]);
        free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
@@ -318,9 +317,9 @@ static int i2sbus_add_dev(struct macio_dev *macio,
                        free_irq(dev->interrupts[i], dev);
        free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
        free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
-       if (dev->intfregs) iounmap(dev->intfregs);
-       if (dev->out.dbdma) iounmap(dev->out.dbdma);
-       if (dev->in.dbdma) iounmap(dev->in.dbdma);
+       iounmap(dev->intfregs);
+       iounmap(dev->out.dbdma);
+       iounmap(dev->in.dbdma);
        for (i=0;i<3;i++)
                release_and_free_resource(dev->allocated_resource[i]);
        mutex_destroy(&dev->lock);
@@ -381,10 +380,8 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
 
        list_for_each_entry(i2sdev, &control->list, item) {
                /* Notify Alsa */
-               if (i2sdev->sound.pcm) {
-                       /* Suspend PCM streams */
-                       snd_pcm_suspend_all(i2sdev->sound.pcm);
-               }
+               /* Suspend PCM streams */
+               snd_pcm_suspend_all(i2sdev->sound.pcm);
 
                /* Notify codecs */
                list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
index 7b74a4b..4177d97 100644 (file)
@@ -6,7 +6,7 @@
  * GPL v2, can be found in COPYING.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 0e83a73..4140b1b 100644 (file)
@@ -889,8 +889,8 @@ static int aaci_probe_ac97(struct aaci *aaci)
 static void aaci_free_card(struct snd_card *card)
 {
        struct aaci *aaci = card->private_data;
-       if (aaci->base)
-               iounmap(aaci->base);
+
+       iounmap(aaci->base);
 }
 
 static struct aaci *aaci_init_card(struct amba_device *dev)
index 4f6b14d..cf4cedf 100644 (file)
@@ -22,6 +22,9 @@
 #include <linux/gpio.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <linux/platform_data/dma-dw.h>
 #include <linux/dma/dw.h>
 
+#ifdef CONFIG_AVR32
 #include <mach/cpu.h>
-
-#ifdef CONFIG_ARCH_AT91
-#include <mach/hardware.h>
+#else
+#define cpu_is_at32ap7000() 0
 #endif
 
 #include "ac97c.h"
@@ -902,6 +905,40 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip)
        }
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id atmel_ac97c_dt_ids[] = {
+       { .compatible = "atmel,at91sam9263-ac97c", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids);
+
+static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
+{
+       struct ac97c_platform_data *pdata;
+       struct device_node *node = dev->of_node;
+       const struct of_device_id *match;
+
+       if (!node) {
+               dev_err(dev, "Device does not have associated DT data\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return ERR_PTR(-ENOMEM);
+
+       pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
+
+       return pdata;
+}
+#else
+static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
+{
+       dev_err(dev, "no platform data defined\n");
+       return ERR_PTR(-ENXIO);
+}
+#endif
+
 static int atmel_ac97c_probe(struct platform_device *pdev)
 {
        struct snd_card                 *card;
@@ -922,10 +959,11 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       pdata = pdev->dev.platform_data;
+       pdata = dev_get_platdata(&pdev->dev);
        if (!pdata) {
-               dev_dbg(&pdev->dev, "no platform data\n");
-               return -ENXIO;
+               pdata = atmel_ac97c_probe_dt(&pdev->dev);
+               if (IS_ERR(pdata))
+                       return PTR_ERR(pdata);
        }
 
        irq = platform_get_irq(pdev, 0);
@@ -1204,6 +1242,7 @@ static struct platform_driver atmel_ac97c_driver = {
        .driver         = {
                .name   = "atmel_ac97c",
                .pm     = ATMEL_AC97C_PM_OPS,
+               .of_match_table = of_match_ptr(atmel_ac97c_dt_ids),
        },
 };
 module_platform_driver(atmel_ac97c_driver);
index 36c0f1a..4cd664e 100644 (file)
@@ -21,8 +21,8 @@
  */
 
 #include <linux/export.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <sound/core.h>
 
 /**
index ada69d7..80423a4 100644 (file)
@@ -719,7 +719,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
 
        oss_buffer_size = snd_pcm_plug_client_size(substream,
                                                   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
-       oss_buffer_size = 1 << ld2(oss_buffer_size);
+       oss_buffer_size = rounddown_pow_of_two(oss_buffer_size);
        if (atomic_read(&substream->mmap_count)) {
                if (oss_buffer_size > runtime->oss.mmap_bytes)
                        oss_buffer_size = runtime->oss.mmap_bytes;
@@ -755,14 +755,14 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
        min_period_size = snd_pcm_plug_client_size(substream,
                                                   snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
        min_period_size *= oss_frame_size;
-       min_period_size = 1 << (ld2(min_period_size - 1) + 1);
+       min_period_size = roundup_pow_of_two(min_period_size);
        if (oss_period_size < min_period_size)
                oss_period_size = min_period_size;
 
        max_period_size = snd_pcm_plug_client_size(substream,
                                                   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
        max_period_size *= oss_frame_size;
-       max_period_size = 1 << ld2(max_period_size);
+       max_period_size = rounddown_pow_of_two(max_period_size);
        if (oss_period_size > max_period_size)
                oss_period_size = max_period_size;
 
index ec9e786..db05e04 100644 (file)
@@ -1299,8 +1299,14 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
        int width = l & 0xffff;
        unsigned int msbits = l >> 16;
        struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
-       if (snd_interval_single(i) && snd_interval_value(i) == width)
-               params->msbits = msbits;
+
+       if (!snd_interval_single(i))
+               return 0;
+
+       if ((snd_interval_value(i) == width) ||
+           (width == 0 && snd_interval_value(i) > msbits))
+               params->msbits = min_not_zero(params->msbits, msbits);
+
        return 0;
 }
 
@@ -1311,6 +1317,11 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
  * @width: sample bits width
  * @msbits: msbits width
  *
+ * This constraint will set the number of most significant bits (msbits) if a
+ * sample format with the specified width has been select. If width is set to 0
+ * the msbits will be set for any sample format with a width larger than the
+ * specified msbits.
+ *
  * Return: Zero if successful, or a negative error code on failure.
  */
 int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 
index 54debc0..b45f6aa 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/slab.h>
index 095d957..932234d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/time.h>
 #include <linux/pm_qos.h>
 #include <linux/aio.h>
+#include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/control.h>
@@ -34,7 +35,6 @@
 #include <sound/pcm_params.h>
 #include <sound/timer.h>
 #include <sound/minors.h>
-#include <asm/io.h>
 
 /*
  *  Compatibility
@@ -420,7 +420,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
 
        hw = &substream->runtime->hw;
        if (!params->info) {
-               params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
+               params->info = hw->info & ~(SNDRV_PCM_INFO_FIFO_IN_FRAMES |
+                                           SNDRV_PCM_INFO_DRAIN_TRIGGER);
                if (!hw_support_mmap(substream))
                        params->info &= ~(SNDRV_PCM_INFO_MMAP |
                                          SNDRV_PCM_INFO_MMAP_VALID);
@@ -1566,6 +1567,13 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
                        snd_pcm_post_stop(substream, new_state);
                }
        }
+
+       if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
+           runtime->trigger_master == substream &&
+           (runtime->hw.info & SNDRV_PCM_INFO_DRAIN_TRIGGER))
+               return substream->ops->trigger(substream,
+                                              SNDRV_PCM_TRIGGER_DRAIN);
+
        return 0;
 }
 
index 3a45696..e79cc44 100644 (file)
@@ -237,8 +237,7 @@ snd_seq_oss_midi_check_exit_port(int client, int port)
                spin_unlock_irqrestore(&register_lock, flags);
                snd_use_lock_free(&mdev->use_lock);
                snd_use_lock_sync(&mdev->use_lock);
-               if (mdev->coder)
-                       snd_midi_event_free(mdev->coder);
+               snd_midi_event_free(mdev->coder);
                kfree(mdev);
        }
        spin_lock_irqsave(&register_lock, flags);
@@ -265,8 +264,7 @@ snd_seq_oss_midi_clear_all(void)
        spin_lock_irqsave(&register_lock, flags);
        for (i = 0; i < max_midi_devs; i++) {
                if ((mdev = midi_devs[i]) != NULL) {
-                       if (mdev->coder)
-                               snd_midi_event_free(mdev->coder);
+                       snd_midi_event_free(mdev->coder);
                        kfree(mdev);
                        midi_devs[i] = NULL;
                }
index 225c731..29182f5 100644 (file)
@@ -1133,7 +1133,7 @@ static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void __user
        /* fill the info fields */
        info.queues = SNDRV_SEQ_MAX_QUEUES;
        info.clients = SNDRV_SEQ_MAX_CLIENTS;
-       info.ports = 256;       /* fixed limit */
+       info.ports = SNDRV_SEQ_MAX_PORTS;
        info.channels = 256;    /* fixed limit */
        info.cur_clients = client_usage.cur;
        info.cur_queues = snd_seq_queue_get_cur_queues();
@@ -1279,7 +1279,6 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
                                port->owner = callback->owner;
                        port->private_data = callback->private_data;
                        port->private_free = callback->private_free;
-                       port->callback_all = callback->callback_all;
                        port->event_input = callback->event_input;
                        port->c_src.open = callback->subscribe;
                        port->c_src.close = callback->unsubscribe;
index a1fd77a..68fec77 100644 (file)
@@ -268,8 +268,7 @@ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
                snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port);
        }
 
-       if (msynth->parser)
-               snd_midi_event_free(msynth->parser);
+       snd_midi_event_free(msynth->parser);
 }
 
 /* register new midi synth port */
index 794a341..46ff593 100644 (file)
@@ -134,7 +134,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
        if (snd_BUG_ON(!client))
                return NULL;
 
-       if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) {
+       if (client->num_ports >= SNDRV_SEQ_MAX_PORTS) {
                pr_warn("ALSA: seq: too many ports for client %d\n", client->number);
                return NULL;
        }
@@ -411,9 +411,6 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port,
  * invoked.
  * This feature is useful if these callbacks are associated with
  * initialization or termination of devices (see seq_midi.c).
- *
- * If callback_all option is set, the callback function is invoked
- * at each connection/disconnection. 
  */
 
 static int subscribe_port(struct snd_seq_client *client,
@@ -427,7 +424,7 @@ static int subscribe_port(struct snd_seq_client *client,
        if (!try_module_get(port->owner))
                return -EFAULT;
        grp->count++;
-       if (grp->open && (port->callback_all || grp->count == 1)) {
+       if (grp->open && grp->count == 1) {
                err = grp->open(port->private_data, info);
                if (err < 0) {
                        module_put(port->owner);
@@ -452,7 +449,7 @@ static int unsubscribe_port(struct snd_seq_client *client,
        if (! grp->count)
                return -EINVAL;
        grp->count--;
-       if (grp->close && (port->callback_all || grp->count == 0))
+       if (grp->close && grp->count == 0)
                err = grp->close(port->private_data, info);
        if (send_ack && client->type == USER_CLIENT)
                snd_seq_client_notify_subscription(port->addr.client, port->addr.port,
index 9d71171..26bd71f 100644 (file)
@@ -73,7 +73,6 @@ struct snd_seq_client_port {
                           int atomic, int hop);
        void (*private_free)(void *private_data);
        void *private_data;
-       unsigned int callback_all : 1;
        unsigned int closing : 1;
        unsigned int timestamping: 1;
        unsigned int time_real: 1;
index 777a45e..a442355 100644 (file)
@@ -1030,9 +1030,7 @@ static int snd_timer_register_system(void)
                snd_timer_free(timer);
                return -ENOMEM;
        }
-       init_timer(&priv->tlist);
-       priv->tlist.function = snd_timer_s_function;
-       priv->tlist.data = (unsigned long) timer;
+       setup_timer(&priv->tlist, snd_timer_s_function, (unsigned long) timer);
        timer->private_data = priv;
        timer->private_free = snd_timer_free_system;
        return snd_timer_global_register(timer);
index 7ea5339..7f9126e 100644 (file)
@@ -181,8 +181,7 @@ static void loopback_timer_start(struct loopback_pcm *dpcm)
        }
        tick = dpcm->period_size_frac - dpcm->irq_pos;
        tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
-       dpcm->timer.expires = jiffies + tick;
-       add_timer(&dpcm->timer);
+       mod_timer(&dpcm->timer, jiffies + tick);
 }
 
 /* call in cable->lock */
index 5d0dfb7..d11baaf 100644 (file)
@@ -245,9 +245,8 @@ struct dummy_systimer_pcm {
 
 static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
 {
-       dpcm->timer.expires = jiffies +
-               (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate;
-       add_timer(&dpcm->timer);
+       mod_timer(&dpcm->timer, jiffies +
+               (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
 }
 
 static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
@@ -340,9 +339,8 @@ static int dummy_systimer_create(struct snd_pcm_substream *substream)
        if (!dpcm)
                return -ENOMEM;
        substream->runtime->private_data = dpcm;
-       init_timer(&dpcm->timer);
-       dpcm->timer.data = (unsigned long) dpcm;
-       dpcm->timer.function = dummy_systimer_callback;
+       setup_timer(&dpcm->timer, dummy_systimer_callback,
+                       (unsigned long) dpcm);
        spin_lock_init(&dpcm->lock);
        dpcm->substream = substream;
        return 0;
index bcca825..bdcb572 100644 (file)
@@ -1094,8 +1094,7 @@ static int snd_ml403_ac97cr_free(struct snd_ml403_ac97cr *ml403_ac97cr)
        if (ml403_ac97cr->capture_irq >= 0)
                free_irq(ml403_ac97cr->capture_irq, ml403_ac97cr);
        /* give back "port" */
-       if (ml403_ac97cr->port != NULL)
-               iounmap(ml403_ac97cr->port);
+       iounmap(ml403_ac97cr->port);
        kfree(ml403_ac97cr);
        PDEBUG(INIT_INFO, "free(): (done)\n");
        return 0;
@@ -1238,14 +1237,11 @@ snd_ml403_ac97cr_mixer(struct snd_ml403_ac97cr *ml403_ac97cr)
 }
 
 static int
-snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device,
-                    struct snd_pcm **rpcm)
+snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ml403_ac97cr->card, "ML403AC97CR/1", device, 1, 1,
                          &pcm);
        if (err < 0)
@@ -1263,8 +1259,6 @@ snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device,
                                          snd_dma_continuous_data(GFP_KERNEL),
                                          64 * 1024,
                                          128 * 1024);
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1298,7 +1292,7 @@ static int snd_ml403_ac97cr_probe(struct platform_device *pfdev)
                return err;
        }
        PDEBUG(INIT_INFO, "probe(): mixer done\n");
-       err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0, NULL);
+       err = snd_ml403_ac97cr_pcm(ml403_ac97cr, 0);
        if (err < 0) {
                snd_card_free(card);
                return err;
index e3a90d0..776596b 100644 (file)
@@ -28,7 +28,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -176,8 +176,7 @@ static void snd_mpu401_uart_timer(unsigned long data)
 
        spin_lock_irqsave(&mpu->timer_lock, flags);
        /*mpu->mode |= MPU401_MODE_TIMER;*/
-       mpu->timer.expires = 1 + jiffies;
-       add_timer(&mpu->timer);
+       mod_timer(&mpu->timer,  1 + jiffies);
        spin_unlock_irqrestore(&mpu->timer_lock, flags);
        if (mpu->rmidi)
                _snd_mpu401_uart_interrupt(mpu);
@@ -192,11 +191,9 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
 
        spin_lock_irqsave (&mpu->timer_lock, flags);
        if (mpu->timer_invoked == 0) {
-               init_timer(&mpu->timer);
-               mpu->timer.data = (unsigned long)mpu;
-               mpu->timer.function = snd_mpu401_uart_timer;
-               mpu->timer.expires = 1 + jiffies;
-               add_timer(&mpu->timer);
+               setup_timer(&mpu->timer, snd_mpu401_uart_timer,
+                           (unsigned long)mpu);
+               mod_timer(&mpu->timer, 1 + jiffies);
        } 
        mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
                MPU401_MODE_OUTPUT_TIMER;
index 1576944..30e8a1d 100644 (file)
@@ -414,8 +414,7 @@ static void snd_mtpav_output_timer(unsigned long data)
 
        spin_lock_irqsave(&chip->spinlock, flags);
        /* reprogram timer */
-       chip->timer.expires = 1 + jiffies;
-       add_timer(&chip->timer);
+       mod_timer(&chip->timer, 1 + jiffies);
        /* process each port */
        for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
                struct mtpav_port *portp = &chip->ports[p];
@@ -428,8 +427,7 @@ static void snd_mtpav_output_timer(unsigned long data)
 /* spinlock held! */
 static void snd_mtpav_add_output_timer(struct mtpav *chip)
 {
-       chip->timer.expires = 1 + jiffies;
-       add_timer(&chip->timer);
+       mod_timer(&chip->timer, 1 + jiffies);
 }
 
 /* spinlock held! */
@@ -704,15 +702,13 @@ static int snd_mtpav_probe(struct platform_device *dev)
 
        mtp_card = card->private_data;
        spin_lock_init(&mtp_card->spinlock);
-       init_timer(&mtp_card->timer);
        mtp_card->card = card;
        mtp_card->irq = -1;
        mtp_card->share_irq = 0;
        mtp_card->inmidistate = 0;
        mtp_card->outmidihwport = 0xffffffff;
-       init_timer(&mtp_card->timer);
-       mtp_card->timer.function = snd_mtpav_output_timer;
-       mtp_card->timer.data = (unsigned long) mtp_card;
+       setup_timer(&mtp_card->timer, snd_mtpav_output_timer,
+                   (unsigned long) mtp_card);
 
        card->private_free = snd_mtpav_free;
 
index f66af58..369cef2 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include <sound/opl3.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/init.h>
index 6c6d09a..f62780e 100644 (file)
@@ -258,12 +258,10 @@ void snd_opl3_timer_func(unsigned long data)
        spin_unlock_irqrestore(&opl3->voice_lock, flags);
 
        spin_lock_irqsave(&opl3->sys_timer_lock, flags);
-       if (again) {
-               opl3->tlist.expires = jiffies + 1;      /* invoke again */
-               add_timer(&opl3->tlist);
-       } else {
+       if (again)
+               mod_timer(&opl3->tlist, jiffies + 1);   /* invoke again */
+       else
                opl3->sys_timer_status = 0;
-       }
        spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
 }
 
@@ -275,8 +273,7 @@ static void snd_opl3_start_timer(struct snd_opl3 *opl3)
        unsigned long flags;
        spin_lock_irqsave(&opl3->sys_timer_lock, flags);
        if (! opl3->sys_timer_status) {
-               opl3->tlist.expires = jiffies + 1;
-               add_timer(&opl3->tlist);
+               mod_timer(&opl3->tlist, jiffies + 1);
                opl3->sys_timer_status = 1;
        }
        spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
index 6839953..a9f618e 100644 (file)
@@ -247,9 +247,7 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
        }
 
        /* setup system timer */
-       init_timer(&opl3->tlist);
-       opl3->tlist.function = snd_opl3_timer_func;
-       opl3->tlist.data = (unsigned long) opl3;
+       setup_timer(&opl3->tlist, snd_opl3_timer_func, (unsigned long) opl3);
        spin_lock_init(&opl3->sys_timer_lock);
        opl3->sys_timer_status = 0;
 
index b953fb4..3b0ee42 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
 MODULE_DESCRIPTION("OPL4 driver");
index 4b91adc..7bc1e58 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "opl4_local.h"
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/asoundef.h>
 
 /* GM2 controllers */
index 2adc754..d9647bd 100644 (file)
@@ -13,7 +13,7 @@
 #include <sound/pcm.h>
 #include <linux/input.h>
 #include <linux/delay.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include "pcsp_input.h"
 #include "pcsp.h"
 
index 0ecf8a4..bfc2581 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/init.h>
 #include <linux/input.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "pcsp.h"
 #include "pcsp_input.h"
 
index 29ebaa4..3689f5f 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/gfp.h>
 #include <linux/moduleparam.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <sound/pcm.h>
-#include <asm/io.h>
 #include "pcsp.h"
 
 static bool nforce_wa;
index 13a34e3..1927b89 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #include <sound/initval.h>
@@ -44,8 +45,6 @@
 #include <linux/serial_reg.h>
 #include <linux/jiffies.h>
 
-#include <asm/io.h>
-
 MODULE_DESCRIPTION("MIDI serial u16550");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ALSA, MIDI serial u16550}}");
@@ -174,9 +173,8 @@ static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart)
 {
        if (!uart->timer_running) {
                /* timer 38600bps * 10bit * 16byte */
-               uart->buffer_timer.expires = jiffies + (HZ+255)/256;
+               mod_timer(&uart->buffer_timer, jiffies + (HZ + 255) / 256);
                uart->timer_running = 1;
-               add_timer(&uart->buffer_timer);
        }
 }
 
@@ -830,9 +828,8 @@ static int snd_uart16550_create(struct snd_card *card,
        uart->prev_in = 0;
        uart->rstatus = 0;
        memset(uart->prev_status, 0x80, sizeof(unsigned char) * SNDRV_SERIAL_MAX_OUTS);
-       init_timer(&uart->buffer_timer);
-       uart->buffer_timer.function = snd_uart16550_buffer_timer;
-       uart->buffer_timer.data = (unsigned long)uart;
+       setup_timer(&uart->buffer_timer, snd_uart16550_buffer_timer,
+                   (unsigned long)uart);
        uart->timer_running = 0;
 
        /* Register device */
index fc05a37..289f041 100644 (file)
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/asoundef.h>
 #include <sound/info.h>
-#include <asm/io.h>
 #include <sound/vx_core.h>
 #include "vx_cmd.h"
 
index 88452e8..4884890 100644 (file)
@@ -91,9 +91,7 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t
        chip->read = read;
        chip->write = write;
        chip->private_data = private_data;
-       init_timer(&chip->timer);
-       chip->timer.data = (unsigned long)chip;
-       chip->timer.function = snd_ak4117_timer;
+       setup_timer(&chip->timer, snd_ak4117_timer, (unsigned long)chip);
 
        for (reg = 0; reg < 5; reg++)
                chip->regmap[reg] = pgm[reg];
@@ -139,8 +137,7 @@ void snd_ak4117_reinit(struct ak4117 *chip)
        /* release powerdown, everything is initialized now */
        reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN);
        chip->init = 0;
-       chip->timer.expires = 1 + jiffies;
-       add_timer(&chip->timer);
+       mod_timer(&chip->timer, 1 + jiffies);
 }
 
 static unsigned int external_rate(unsigned char rcs1)
@@ -540,8 +537,7 @@ static void snd_ak4117_timer(unsigned long data)
        if (chip->init)
                return;
        snd_ak4117_check_rate_and_errors(chip, 0);
-       chip->timer.expires = 1 + jiffies;
-       add_timer(&chip->timer);
+       mod_timer(&chip->timer, 1 + jiffies);
 }
 
 EXPORT_SYMBOL(snd_ak4117_create);
index 67dbfde..c657310 100644 (file)
@@ -21,7 +21,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
index f481a41..7692265 100644 (file)
@@ -142,7 +142,6 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
        struct snd_card *card;
        struct snd_ad1816a *chip;
        struct snd_opl3 *opl3;
-       struct snd_timer *timer;
 
        error = snd_card_new(&pcard->card->dev,
                             index[dev], id[dev], THIS_MODULE,
@@ -172,7 +171,7 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
        sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d",
                card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
 
-       if ((error = snd_ad1816a_pcm(chip, 0, NULL)) < 0) {
+       if ((error = snd_ad1816a_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return error;
        }
@@ -182,7 +181,7 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
                return error;
        }
 
-       error = snd_ad1816a_timer(chip, 0, &timer);
+       error = snd_ad1816a_timer(chip, 0);
        if (error < 0) {
                snd_card_free(card);
                return error;
index 01a0798..5c815f5 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
 #include <sound/ad1816a.h>
 
-#include <asm/io.h>
 #include <asm/dma.h>
 
 static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip)
@@ -675,7 +675,7 @@ static struct snd_pcm_ops snd_ad1816a_capture_ops = {
        .pointer =      snd_ad1816a_capture_pointer,
 };
 
-int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
+int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device)
 {
        int error;
        struct snd_pcm *pcm;
@@ -697,13 +697,10 @@ int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
                                              64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
 
        chip->pcm = pcm;
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
-int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
-                     struct snd_timer **rtimer)
+int snd_ad1816a_timer(struct snd_ad1816a *chip, int device)
 {
        struct snd_timer *timer;
        struct snd_timer_id tid;
@@ -720,8 +717,6 @@ int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
        timer->private_data = chip;
        chip->timer = timer;
        timer->hw = snd_ad1816a_timer_table;
-       if (rtimer)
-               *rtimer = timer;
        return 0;
 }
 
index 093f22a..f159da4 100644 (file)
@@ -88,7 +88,6 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
 {
        struct snd_card *card;
        struct snd_wss *chip;
-       struct snd_pcm *pcm;
        int error;
 
        error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
@@ -103,7 +102,7 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
 
        card->private_data = chip;
 
-       error = snd_wss_pcm(chip, 0, &pcm);
+       error = snd_wss_pcm(chip, 0);
        if (error < 0)
                goto out;
 
@@ -112,10 +111,10 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
                goto out;
 
        strcpy(card->driver, "AD1848");
-       strcpy(card->shortname, pcm->name);
+       strcpy(card->shortname, chip->pcm->name);
 
        sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-               pcm->name, chip->port, irq[n], dma1[n]);
+               chip->pcm->name, chip->port, irq[n], dma1[n]);
        if (thinkpad[n])
                strcat(card->longname, " [Thinkpad]");
 
index 32d0152..bc9ea30 100644 (file)
@@ -233,7 +233,7 @@ static int snd_card_als100_probe(int dev,
                        irq[dev], dma8[dev], dma16[dev]);
        }
 
-       if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) {
+       if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return error;
        }
index 0ea75fc..fff186f 100644 (file)
@@ -29,7 +29,7 @@
     activation method (full-duplex audio!).
 */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/time.h>
@@ -215,7 +215,7 @@ static int snd_card_azt2320_probe(int dev,
        sprintf(card->longname, "%s, WSS at 0x%lx, irq %i, dma %i&%i",
                card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
 
-       error = snd_wss_pcm(chip, 0, NULL);
+       error = snd_wss_pcm(chip, 0);
        if (error < 0) {
                snd_card_free(card);
                return error;
@@ -225,7 +225,7 @@ static int snd_card_azt2320_probe(int dev,
                snd_card_free(card);
                return error;
        }
-       error = snd_wss_timer(chip, 0, NULL);
+       error = snd_wss_timer(chip, 0);
        if (error < 0) {
                snd_card_free(card);
                return error;
index 4778852..2c89d95 100644 (file)
@@ -307,7 +307,7 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
        if (err < 0)
                goto error;
 
-       err = snd_wss_pcm(cmi->wss, 0, NULL);
+       err = snd_wss_pcm(cmi->wss, 0);
        if (err < 0)
                goto error;
 
@@ -318,7 +318,7 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
        if (err < 0)
                goto error;
 
-       if (snd_wss_timer(cmi->wss, 0, NULL) < 0)
+       if (snd_wss_timer(cmi->wss, 0) < 0)
                snd_printk(KERN_WARNING "error initializing WSS timer\n");
 
        if (mpuport[ndev] == SNDRV_AUTO_PORT) {
index 7dba07a..282cd75 100644 (file)
@@ -92,7 +92,6 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
 {
        struct snd_card *card;
        struct snd_wss *chip;
-       struct snd_pcm *pcm;
        int error;
 
        error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
@@ -106,15 +105,15 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
 
        card->private_data = chip;
 
-       error = snd_wss_pcm(chip, 0, &pcm);
+       error = snd_wss_pcm(chip, 0);
        if (error < 0)
                goto out;
 
        strcpy(card->driver, "CS4231");
-       strcpy(card->shortname, pcm->name);
+       strcpy(card->shortname, chip->pcm->name);
 
        sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-               pcm->name, chip->port, irq[n], dma1[n]);
+               chip->pcm->name, chip->port, irq[n], dma1[n]);
        if (dma2[n] >= 0)
                sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
 
@@ -122,7 +121,7 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
        if (error < 0)
                goto out;
 
-       error = snd_wss_timer(chip, 0, NULL);
+       error = snd_wss_timer(chip, 0);
        if (error < 0)
                goto out;
 
index 750f51c..9d7582c 100644 (file)
@@ -382,7 +382,6 @@ static int snd_cs423x_card_new(struct device *pdev, int dev,
 static int snd_cs423x_probe(struct snd_card *card, int dev)
 {
        struct snd_card_cs4236 *acard;
-       struct snd_pcm *pcm;
        struct snd_wss *chip;
        struct snd_opl3 *opl3;
        int err;
@@ -404,7 +403,7 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
        acard->chip = chip;
        if (chip->hardware & WSS_HW_CS4236B_MASK) {
 
-               err = snd_cs4236_pcm(chip, 0, &pcm);
+               err = snd_cs4236_pcm(chip, 0);
                if (err < 0)
                        return err;
 
@@ -412,7 +411,7 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
                if (err < 0)
                        return err;
        } else {
-               err = snd_wss_pcm(chip, 0, &pcm);
+               err = snd_wss_pcm(chip, 0);
                if (err < 0)
                        return err;
 
@@ -420,17 +419,17 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
                if (err < 0)
                        return err;
        }
-       strcpy(card->driver, pcm->name);
-       strcpy(card->shortname, pcm->name);
+       strcpy(card->driver, chip->pcm->name);
+       strcpy(card->shortname, chip->pcm->name);
        sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
-               pcm->name,
+               chip->pcm->name,
                chip->port,
                irq[dev],
                dma1[dev]);
        if (dma2[dev] >= 0)
                sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
 
-       err = snd_wss_timer(chip, 0, NULL);
+       err = snd_wss_timer(chip, 0);
        if (err < 0)
                return err;
 
index c5adca3..2b7cc59 100644 (file)
@@ -79,7 +79,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/time.h>
@@ -376,17 +376,14 @@ int snd_cs4236_create(struct snd_card *card,
        return 0;
 }
 
-int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
+int snd_cs4236_pcm(struct snd_wss *chip, int device)
 {
-       struct snd_pcm *pcm;
        int err;
        
-       err = snd_wss_pcm(chip, device, &pcm);
+       err = snd_wss_pcm(chip, device);
        if (err < 0)
                return err;
-       pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX;
-       if (rpcm)
-               *rpcm = pcm;
+       chip->pcm->info_flags &= ~SNDRV_PCM_INFO_JOINT_DUPLEX;
        return 0;
 }
 
index 76001fe..1901c2b 100644 (file)
@@ -138,10 +138,9 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n)
 {
        struct snd_es1688 *chip = card->private_data;
        struct snd_opl3 *opl3;
-       struct snd_pcm *pcm;
        int error;
 
-       error = snd_es1688_pcm(card, chip, 0, &pcm);
+       error = snd_es1688_pcm(card, chip, 0);
        if (error < 0)
                return error;
 
@@ -150,9 +149,9 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n)
                return error;
 
        strlcpy(card->driver, "ES1688", sizeof(card->driver));
-       strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
+       strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
        snprintf(card->longname, sizeof(card->longname),
-               "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
+               "%s at 0x%lx, irq %i, dma %i", chip->pcm->name, chip->port,
                 chip->irq, chip->dma8);
 
        if (fm_port[n] == SNDRV_AUTO_PORT)
index b545014..e2cf508 100644 (file)
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/es1688.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
 #include <asm/dma.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -728,8 +728,7 @@ static struct snd_pcm_ops snd_es1688_capture_ops = {
        .pointer =              snd_es1688_capture_pointer,
 };
 
-int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
-                  int device, struct snd_pcm **rpcm)
+int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
@@ -749,9 +748,6 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_isa_data(),
                                              64*1024, 64*1024);
-
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
index b481bb8..5094b62 100644 (file)
@@ -84,8 +84,8 @@
 #include <linux/isapnp.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/control.h>
@@ -1687,16 +1687,13 @@ static struct snd_pcm_ops snd_es18xx_capture_ops = {
        .pointer =      snd_es18xx_capture_pointer,
 };
 
-static int snd_es18xx_pcm(struct snd_card *card, int device,
-                         struct snd_pcm **rpcm)
+static int snd_es18xx_pcm(struct snd_card *card, int device)
 {
        struct snd_es18xx *chip = card->private_data;
         struct snd_pcm *pcm;
        char str[16];
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        sprintf(str, "ES%x", chip->version);
        if (chip->caps & ES18XX_PCM2)
                err = snd_pcm_new(card, str, device, 2, 1, &pcm);
@@ -1722,9 +1719,6 @@ static int snd_es18xx_pcm(struct snd_card *card, int device,
                                              snd_dma_isa_data(),
                                              64*1024,
                                              chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
-
-        if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -2154,7 +2148,7 @@ static int snd_audiodrive_probe(struct snd_card *card, int dev)
                        chip->port,
                        irq[dev], dma1[dev]);
 
-       err = snd_es18xx_pcm(card, 0, NULL);
+       err = snd_es18xx_pcm(card, 0);
        if (err < 0)
                return err;
 
index 1eb2b1e..3227884 100644 (file)
@@ -569,7 +569,7 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n)
        if (err < 0)
                goto error;
 
-       err = snd_wss_pcm(chip, 0, NULL);
+       err = snd_wss_pcm(chip, 0);
        if (err < 0)
                goto error;
 
@@ -577,7 +577,7 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n)
        if (err < 0)
                goto error;
 
-       err = snd_wss_timer(chip, 0, NULL);
+       err = snd_wss_timer(chip, 0);
        if (err < 0)
                goto error;
 
diff --git a/sound/isa/gus/gus_instr.c b/sound/isa/gus/gus_instr.c
deleted file mode 100644 (file)
index 4dc9caf..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- *  Routines for Gravis UltraSound soundcards - Synthesizer
- *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
- *
- *
- *   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 <linux/time.h>
-#include <sound/core.h>
-#include <sound/gus.h>
-
-/*
- *
- */
-
-int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
-                             char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-       struct snd_gf1_mem_block *block;
-       int err;
-
-       if (wave->format & IWFFFF_WAVE_ROM)
-               return 0;       /* it's probably ok - verify the address? */
-       if (wave->format & IWFFFF_WAVE_STEREO)
-               return -EINVAL; /* not supported */
-       block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
-                                 SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF,
-                                 NULL, wave->size,
-                                 wave->format & IWFFFF_WAVE_16BIT, 1,
-                                 wave->share_id);
-       if (block == NULL)
-               return -ENOMEM;
-       err = snd_gus_dram_write(gus, data,
-                                block->ptr, wave->size);
-       if (err < 0) {
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
-               snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
-               return err;
-       }
-       wave->address.memory = block->ptr;
-       return 0;
-}
-
-int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
-                             char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       return snd_gus_dram_read(gus, data, wave->address.memory, wave->size,
-                                wave->format & IWFFFF_WAVE_ROM ? 1 : 0);
-}
-
-int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
-                                int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       if (wave->format & IWFFFF_WAVE_ROM)
-               return 0;       /* it's probably ok - verify the address? */    
-       return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
-}
-
-/*
- *
- */
-
-int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
-                          char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-       struct snd_gf1_mem_block *block;
-       int err;
-
-       if (wave->format & GF1_WAVE_STEREO)
-               return -EINVAL; /* not supported */
-       block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
-                                 SNDRV_GF1_MEM_OWNER_WAVE_GF1,
-                                 NULL, wave->size,
-                                 wave->format & GF1_WAVE_16BIT, 1,
-                                 wave->share_id);
-       if (block == NULL)
-               return -ENOMEM;
-       err = snd_gus_dram_write(gus, data,
-                                block->ptr, wave->size);
-       if (err < 0) {
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
-               snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
-               return err;
-       }
-       wave->address.memory = block->ptr;
-       return 0;
-}
-
-int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
-                          char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0);
-}
-
-int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
-                             int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
-}
-
-/*
- *
- */
-
-int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
-                             char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-       struct snd_gf1_mem_block *block;
-       int err;
-
-       if (instr->format & SIMPLE_WAVE_STEREO)
-               return -EINVAL; /* not supported */
-       block = snd_gf1_mem_alloc(&gus->gf1.mem_alloc,
-                                 SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE,
-                                 NULL, instr->size,
-                                 instr->format & SIMPLE_WAVE_16BIT, 1,
-                                 instr->share_id);
-       if (block == NULL)
-               return -ENOMEM;
-       err = snd_gus_dram_write(gus, data, block->ptr, instr->size);
-       if (err < 0) {
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 0);
-               snd_gf1_mem_xfree(&gus->gf1.mem_alloc, block);
-               snd_gf1_mem_lock(&gus->gf1.mem_alloc, 1);
-               return err;
-       }
-       instr->address.memory = block->ptr;
-       return 0;
-}
-
-int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
-                             char __user *data, long len, int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0);
-}
-
-int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
-                                int atomic)
-{
-       struct snd_gus_card *gus = private_data;
-
-       return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory);
-}
index 2dcf45b..25f6788 100644 (file)
@@ -849,7 +849,7 @@ static struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
        .pointer =      snd_gf1_pcm_capture_pointer,
 };
 
-int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm)
+int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index)
 {
        struct snd_card *card;
        struct snd_kcontrol *kctl;
@@ -857,8 +857,6 @@ int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, s
        struct snd_pcm_substream *substream;
        int capture, err;
 
-       if (rpcm)
-               *rpcm = NULL;
        card = gus->card;
        capture = !gus->interwave && !gus->ess_flag && !gus->ace_flag ? 1 : 0;
        err = snd_pcm_new(card,
@@ -903,8 +901,6 @@ int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, s
                return err;
        kctl->id.index = control_index;
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
index 21cc42e..3992912 100644 (file)
@@ -241,13 +241,11 @@ static struct snd_rawmidi_ops snd_gf1_uart_input =
        .trigger =      snd_gf1_uart_input_trigger,
 };
 
-int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi ** rrawmidi)
+int snd_gf1_rawmidi_new(struct snd_gus_card *gus, int device)
 {
        struct snd_rawmidi *rmidi;
        int err;
 
-       if (rrawmidi)
-               *rrawmidi = NULL;
        if ((err = snd_rawmidi_new(gus->card, "GF1", device, 1, 1, &rmidi)) < 0)
                return err;
        strcpy(rmidi->name, gus->interwave ? "AMD InterWave" : "GF1");
@@ -256,7 +254,5 @@ int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmid
        rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
        rmidi->private_data = gus;
        gus->midi_uart = rmidi;
-       if (rrawmidi)
-               *rrawmidi = rmidi;
        return err;
 }
index 7ce29ff..f001971 100644 (file)
@@ -181,12 +181,12 @@ static int snd_gusclassic_probe(struct device *dev, unsigned int n)
        if (error < 0)
                goto out;
 
-       error = snd_gf1_pcm_new(gus, 0, 0, NULL);
+       error = snd_gf1_pcm_new(gus, 0, 0);
        if (error < 0)
                goto out;
 
        if (!gus->ace_flag) {
-               error = snd_gf1_rawmidi_new(gus, 0, NULL);
+               error = snd_gf1_rawmidi_new(gus, 0);
                if (error < 0)
                        goto out;
        }
index 28a1693..693d95f 100644 (file)
@@ -284,7 +284,7 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
        }
        gus->codec_flag = 1;
 
-       error = snd_es1688_pcm(card, es1688, 0, NULL);
+       error = snd_es1688_pcm(card, es1688, 0);
        if (error < 0)
                goto out;
 
@@ -295,7 +295,7 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
        snd_component_add(card, "ES1688");
 
        if (pcm_channels[n] > 0) {
-               error = snd_gf1_pcm_new(gus, 1, 1, NULL);
+               error = snd_gf1_pcm_new(gus, 1, 1);
                if (error < 0)
                        goto out;
        }
index 39df36c..8216e8d 100644 (file)
@@ -309,7 +309,7 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
        if (err < 0)
                goto _err;
 
-       err = snd_wss_pcm(wss, 0, NULL);
+       err = snd_wss_pcm(wss, 0);
        if (err < 0)
                goto _err;
 
@@ -317,19 +317,19 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
        if (err < 0)
                goto _err;
 
-       err = snd_wss_timer(wss, 2, NULL);
+       err = snd_wss_timer(wss, 2);
        if (err < 0)
                goto _err;
 
        if (pcm_channels[dev] > 0) {
-               if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+               if ((err = snd_gf1_pcm_new(gus, 1, 1)) < 0)
                        goto _err;
        }
        err = snd_gusmax_mixer(wss);
        if (err < 0)
                goto _err;
 
-       err = snd_gf1_rawmidi_new(gus, 0, NULL);
+       err = snd_gf1_rawmidi_new(gus, 0);
        if (err < 0)
                goto _err;
 
index ad55e5c..70d0040 100644 (file)
@@ -647,7 +647,6 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
 #ifdef SNDRV_STB
        struct snd_i2c_bus *i2c_bus;
 #endif
-       struct snd_pcm *pcm;
        char *str;
        int err;
 
@@ -695,14 +694,15 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
        if (err < 0)
                return err;
 
-       err = snd_wss_pcm(wss, 0, &pcm);
+       err = snd_wss_pcm(wss, 0);
        if (err < 0)
                return err;
 
-       sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
-       strcat(pcm->name, " (codec)");
+       sprintf(wss->pcm->name + strlen(wss->pcm->name), " rev %c",
+               gus->revision + 'A');
+       strcat(wss->pcm->name, " (codec)");
 
-       err = snd_wss_timer(wss, 2, NULL);
+       err = snd_wss_timer(wss, 2);
        if (err < 0)
                return err;
 
@@ -711,7 +711,7 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
                return err;
 
        if (pcm_channels[dev] > 0) {
-               err = snd_gf1_pcm_new(gus, 1, 1, NULL);
+               err = snd_gf1_pcm_new(gus, 1, 1);
                if (err < 0)
                        return err;
        }
@@ -740,7 +740,7 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
 #endif
 
        gus->uart_enable = midi[dev];
-       if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+       if ((err = snd_gf1_rawmidi_new(gus, 0)) < 0)
                return err;
 
 #ifndef SNDRV_STB
index 1cee18f..835d4aa 100644 (file)
@@ -679,8 +679,7 @@ static struct snd_pcm_ops snd_msnd_capture_ops = {
 };
 
 
-int snd_msnd_pcm(struct snd_card *card, int device,
-                       struct snd_pcm **rpcm)
+int snd_msnd_pcm(struct snd_card *card, int device)
 {
        struct snd_msnd *chip = card->private_data;
        struct snd_pcm  *pcm;
@@ -696,9 +695,6 @@ int snd_msnd_pcm(struct snd_card *card, int device,
        pcm->private_data = chip;
        strcpy(pcm->name, "Hurricane");
 
-
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 EXPORT_SYMBOL(snd_msnd_pcm);
index dbac3a4..5f3c7dc 100644 (file)
@@ -297,7 +297,7 @@ int snd_msnd_disable_irq(struct snd_msnd *chip);
 void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file);
 int snd_msnd_DAPQ(struct snd_msnd *chip, int start);
 int snd_msnd_DARQ(struct snd_msnd *chip, int start);
-int snd_msnd_pcm(struct snd_card *card, int device, struct snd_pcm **rpcm);
+int snd_msnd_pcm(struct snd_card *card, int device);
 
 int snd_msndmidi_new(struct snd_card *card, int device);
 void snd_msndmidi_input_read(void *mpu);
index 5016bf9..4c07266 100644 (file)
@@ -582,7 +582,7 @@ static int snd_msnd_attach(struct snd_card *card)
        if (err < 0)
                goto err_release_region;
 
-       err = snd_msnd_pcm(card, 0, NULL);
+       err = snd_msnd_pcm(card, 0);
        if (err < 0) {
                printk(KERN_ERR LOGNAME ": error creating new PCM device\n");
                goto err_release_region;
@@ -627,8 +627,7 @@ static int snd_msnd_attach(struct snd_card *card)
        return 0;
 
 err_release_region:
-       if (chip->mappedbase)
-               iounmap(chip->mappedbase);
+       iounmap(chip->mappedbase);
        release_mem_region(chip->base, BUFFSIZE);
        release_region(chip->io, DSP_NUMIO);
        free_irq(chip->irq, chip);
index a219bc3..ae13363 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pm.h>
 #include <linux/pnp.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/mpu401.h>
@@ -33,8 +34,6 @@
 #include <sound/initval.h>
 #include <sound/tlv.h>
 
-#include <asm/io.h>
-
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("Yamaha OPL3SA2+");
 MODULE_LICENSE("GPL");
@@ -684,7 +683,7 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev)
                return err;
        }
        chip->wss = wss;
-       err = snd_wss_pcm(wss, 0, NULL);
+       err = snd_wss_pcm(wss, 0);
        if (err < 0)
                return err;
        err = snd_wss_mixer(wss);
@@ -693,7 +692,7 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev)
        err = snd_opl3sa2_mixer(card);
        if (err < 0)
                return err;
-       err = snd_wss_timer(wss, 0, NULL);
+       err = snd_wss_timer(wss, 0);
        if (err < 0)
                return err;
        if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
index c2ca681..3a9067d 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/wss.h>
@@ -1270,8 +1270,6 @@ static int snd_miro_probe(struct snd_card *card)
        int error;
        struct snd_miro *miro = card->private_data;
        struct snd_wss *codec;
-       struct snd_timer *timer;
-       struct snd_pcm *pcm;
        struct snd_rawmidi *rmidi;
 
        if (!miro->res_mc_base) {
@@ -1310,7 +1308,7 @@ static int snd_miro_probe(struct snd_card *card)
        if (error < 0)
                return error;
 
-       error = snd_wss_pcm(codec, 0, &pcm);
+       error = snd_wss_pcm(codec, 0);
        if (error < 0)
                return error;
 
@@ -1318,11 +1316,11 @@ static int snd_miro_probe(struct snd_card *card)
        if (error < 0)
                return error;
 
-       error = snd_wss_timer(codec, 0, &timer);
+       error = snd_wss_timer(codec, 0);
        if (error < 0)
                return error;
 
-       miro->pcm = pcm;
+       miro->pcm = codec->pcm;
 
        error = snd_miro_mixer(card, miro);
        if (error < 0)
@@ -1356,8 +1354,8 @@ static int snd_miro_probe(struct snd_card *card)
 
        strcpy(card->driver, "miro");
        sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
-               card->shortname, miro->name, pcm->name, miro->wss_base + 4,
-               miro->irq, miro->dma1, miro->dma2);
+               card->shortname, miro->name, codec->pcm->name,
+               miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2);
 
        if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
                rmidi = NULL;
index c9b5828..0a52660 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/delay.h>
 #include <linux/pnp.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
@@ -820,10 +820,6 @@ static int snd_opti9xx_probe(struct snd_card *card)
        int xdma2;
        struct snd_opti9xx *chip = card->private_data;
        struct snd_wss *codec;
-#ifdef CS4231
-       struct snd_timer *timer;
-#endif
-       struct snd_pcm *pcm;
        struct snd_rawmidi *rmidi;
        struct snd_hwdep *synth;
 
@@ -855,7 +851,7 @@ static int snd_opti9xx_probe(struct snd_card *card)
        if (error < 0)
                return error;
        chip->codec = codec;
-       error = snd_wss_pcm(codec, 0, &pcm);
+       error = snd_wss_pcm(codec, 0);
        if (error < 0)
                return error;
        error = snd_wss_mixer(codec);
@@ -867,7 +863,7 @@ static int snd_opti9xx_probe(struct snd_card *card)
                return error;
 #endif
 #ifdef CS4231
-       error = snd_wss_timer(codec, 0, &timer);
+       error = snd_wss_timer(codec, 0);
        if (error < 0)
                return error;
 #endif
@@ -884,11 +880,12 @@ static int snd_opti9xx_probe(struct snd_card *card)
        sprintf(card->shortname, "OPTi %s", card->driver);
 #if defined(CS4231) || defined(OPTi93X)
        sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
-               card->shortname, pcm->name,
+               card->shortname, codec->pcm->name,
                chip->wss_base + 4, irq, dma1, xdma2);
 #else
        sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
-               card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
+               card->shortname, codec->pcm->name, chip->wss_base + 4, irq,
+               dma1);
 #endif /* CS4231 || OPTi93X */
 
        if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
index 45fcdff..94c4112 100644 (file)
 #include <linux/ioport.h>
 #include <linux/export.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/emu8000.h>
 #include <sound/emu8000_reg.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/init.h>
 #include <sound/control.h>
 #include <sound/initval.h>
@@ -378,13 +378,12 @@ init_arrays(struct snd_emu8000 *emu)
 static void
 size_dram(struct snd_emu8000 *emu)
 {
-       int i, size, detected_size;
+       int i, size;
 
        if (emu->dram_checked)
                return;
 
        size = 0;
-       detected_size = 0;
 
        /* write out a magic number */
        snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
@@ -392,10 +391,19 @@ size_dram(struct snd_emu8000 *emu)
        EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);
        EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);
        snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */
+       snd_emu8000_write_wait(emu);
 
-       while (size < EMU8000_MAX_DRAM) {
+       /*
+        * Detect first 512 KiB.  If a write succeeds at the beginning of a
+        * 512 KiB page we assume that the whole page is there.
+        */
+       EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
+       EMU8000_SMLD_READ(emu); /* discard stale data  */
+       if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
+               goto skip_detect;   /* No RAM */
+       snd_emu8000_read_wait(emu);
 
-               size += 512 * 1024;  /* increment 512kbytes */
+       for (size = 512 * 1024; size < EMU8000_MAX_DRAM; size += 512 * 1024) {
 
                /* Write a unique data on the test address.
                 * if the address is out of range, the data is written on
@@ -431,18 +439,9 @@ size_dram(struct snd_emu8000 *emu)
                snd_emu8000_read_wait(emu);
 
                /* Otherwise, it's valid memory. */
-               detected_size = size + 512 * 1024;
-       }
-
-       /* Distinguish 512 KiB from 0. */
-       if (detected_size == 0) {
-               snd_emu8000_read_wait(emu);
-               EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
-               EMU8000_SMLD_READ(emu); /* discard stale data  */
-               if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1)
-                       detected_size = 512 * 1024;
        }
 
+skip_detect:
        /* wait until FULL bit in SMAxW register is false */
        for (i = 0; i < 10000; i++) {
                if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
@@ -454,10 +453,10 @@ size_dram(struct snd_emu8000 *emu)
        snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);
        snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
 
-       snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",
-                   emu->port1, detected_size/1024);
+       pr_info("EMU8000 [0x%lx]: %d KiB on-board DRAM detected\n",
+                   emu->port1, size/1024);
 
-       emu->mem_size = detected_size;
+       emu->mem_size = size;
        emu->dram_checked = 1;
 }
 
index c99c607..71d13c0 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include "emu8000_local.h"
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/moduleparam.h>
 
 static int emu8000_reset_addr;
index 2f85c66..250fd00 100644 (file)
@@ -207,8 +207,7 @@ static void emu8k_pcm_timer_func(unsigned long data)
        rec->last_ptr = ptr;
 
        /* reprogram timer */
-       rec->timer.expires = jiffies + 1;
-       add_timer(&rec->timer);
+       mod_timer(&rec->timer, jiffies + 1);
 
        /* update period */
        if (rec->period_pos >= (int)rec->period_size) {
@@ -240,9 +239,7 @@ static int emu8k_pcm_open(struct snd_pcm_substream *subs)
        runtime->private_data = rec;
 
        spin_lock_init(&rec->timer_lock);
-       init_timer(&rec->timer);
-       rec->timer.function = emu8k_pcm_timer_func;
-       rec->timer.data = (unsigned long)rec;
+       setup_timer(&rec->timer, emu8k_pcm_timer_func, (unsigned long)rec);
 
        runtime->hw = emu8k_pcm_hw;
        runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3;
@@ -359,8 +356,7 @@ static void start_voice(struct snd_emu8k_pcm *rec, int ch)
        /* start timer */
        spin_lock_irqsave(&rec->timer_lock, flags);
        if (! rec->timer_running) {
-               rec->timer.expires = jiffies + 1;
-               add_timer(&rec->timer);
+               mod_timer(&rec->timer, jiffies + 1);
                rec->timer_running = 1;
        }
        spin_unlock_irqrestore(&rec->timer_lock, flags);
index 95b39be..72332df 100644 (file)
@@ -103,8 +103,7 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev)
        hw = dev->driver_data;
        if (hw->pcm)
                snd_device_free(dev->card, hw->pcm);
-       if (hw->emu)
-               snd_emux_free(hw->emu);
+       snd_emux_free(hw->emu);
        snd_util_memhdr_free(hw->memhdr);
        hw->emu = NULL;
        hw->memhdr = NULL;
index 90d2eba..6b4884d 100644 (file)
@@ -297,7 +297,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
                "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
                port[dev], xirq, xdma8, xdma16);
 
-       err = snd_sb8dsp_pcm(chip, 0, NULL);
+       err = snd_sb8dsp_pcm(chip, 0);
        if (err < 0)
                goto err_free;
        err = snd_sbmixer_new(chip);
index 3f69454..4a7d7c8 100644 (file)
@@ -374,7 +374,7 @@ static int snd_sb16_probe(struct snd_card *card, int dev)
        if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
                return err;
 
-       if ((err = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0)
+       if ((err = snd_sb16dsp_pcm(chip, 0)) < 0)
                return err;
 
        strcpy(card->driver,
index 72b10f4..8b2d6c6 100644 (file)
@@ -33,7 +33,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/time.h>
@@ -860,19 +860,18 @@ static struct snd_pcm_ops snd_sb16_capture_ops = {
        .pointer =      snd_sb16_capture_pointer,
 };
 
-int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm)
+int snd_sb16dsp_pcm(struct snd_sb *chip, int device)
 {
        struct snd_card *card = chip->card;
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(card, "SB16 DSP", device, 1, 1, &pcm)) < 0)
                return err;
        sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
        pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
        pcm->private_data = chip;
+       chip->pcm = pcm;
 
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops);
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops);
@@ -885,9 +884,6 @@ int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm)
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_isa_data(),
                                              64*1024, 128*1024);
-
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
index 6c32b3a..b8e2391 100644 (file)
@@ -157,7 +157,7 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
                goto _err;
        }
 
-       if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0)
+       if ((err = snd_sb8dsp_pcm(chip, 0)) < 0)
                goto _err;
 
        if ((err = snd_sbmixer_new(chip)) < 0)
@@ -182,7 +182,7 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
                        goto _err;
        }
 
-       if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0)
+       if ((err = snd_sb8dsp_midi(chip, 0)) < 0)
                goto _err;
 
        strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
index 24d4121..9043397 100644 (file)
@@ -30,7 +30,7 @@
  *   Cleaned up and rewrote lowlevel routines.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/time.h>
@@ -594,15 +594,13 @@ static struct snd_pcm_ops snd_sb8_capture_ops = {
        .pointer =              snd_sb8_capture_pointer,
 };
 
-int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
+int snd_sb8dsp_pcm(struct snd_sb *chip, int device)
 {
        struct snd_card *card = chip->card;
        struct snd_pcm *pcm;
        int err;
        size_t max_prealloc = 64 * 1024;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(card, "SB8 DSP", device, 1, 1, &pcm)) < 0)
                return err;
        sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
@@ -618,8 +616,6 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
                                              snd_dma_isa_data(),
                                              64*1024, max_prealloc);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
index 988a8b7..d551c50 100644 (file)
@@ -26,7 +26,7 @@
  *   Added full duplex UART mode for DSP version 2.0 and later.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/sb.h>
@@ -216,8 +216,7 @@ static void snd_sb8dsp_midi_output_timer(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&chip->open_lock, flags);
-       chip->midi_timer.expires = 1 + jiffies;
-       add_timer(&chip->midi_timer);
+       mod_timer(&chip->midi_timer, 1 + jiffies);
        spin_unlock_irqrestore(&chip->open_lock, flags);        
        snd_sb8dsp_midi_output_write(substream);
 }
@@ -231,11 +230,10 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
        spin_lock_irqsave(&chip->open_lock, flags);
        if (up) {
                if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
-                       init_timer(&chip->midi_timer);
-                       chip->midi_timer.function = snd_sb8dsp_midi_output_timer;
-                       chip->midi_timer.data = (unsigned long) substream;
-                       chip->midi_timer.expires = 1 + jiffies;
-                       add_timer(&chip->midi_timer);
+                       setup_timer(&chip->midi_timer,
+                                   snd_sb8dsp_midi_output_timer,
+                                   (unsigned long) substream);
+                       mod_timer(&chip->midi_timer, 1 + jiffies);
                        chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
                }
        } else {
@@ -263,13 +261,11 @@ static struct snd_rawmidi_ops snd_sb8dsp_midi_input =
        .trigger =      snd_sb8dsp_midi_input_trigger,
 };
 
-int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi)
+int snd_sb8dsp_midi(struct snd_sb *chip, int device)
 {
        struct snd_rawmidi *rmidi;
        int err;
 
-       if (rrawmidi)
-               *rrawmidi = NULL;
        if ((err = snd_rawmidi_new(chip->card, "SB8 MIDI", device, 1, 1, &rmidi)) < 0)
                return err;
        strcpy(rmidi->name, "SB8 MIDI");
@@ -280,7 +276,5 @@ int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawm
                rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
        rmidi->private_data = chip;
        chip->rmidi = rmidi;
-       if (rrawmidi)
-               *rrawmidi = rmidi;
        return 0;
 }
index f22b448..787a4ad 100644 (file)
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
 #include <asm/dma.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
index e403334..add1d3f 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <sound/core.h>
index 15a152e..51cfa76 100644 (file)
@@ -625,7 +625,7 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
        if (err < 0)
                goto err_unmap2;
 
-       err = snd_wss_pcm(chip, 0, NULL);
+       err = snd_wss_pcm(chip, 0);
        if (err < 0) {
                snd_printk(KERN_ERR PFX
                           "error creating new WSS PCM device\n");
index 44405df..7b248cd 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/io.h>
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
@@ -877,7 +878,6 @@ static int create_ad1845(struct snd_card *card, unsigned port,
                             codec_type, WSS_HWSHARE_DMA1, &chip);
        if (!err) {
                unsigned long flags;
-               struct snd_pcm *pcm;
 
                if (sscape->type != SSCAPE_VIVO) {
                        /*
@@ -893,7 +893,7 @@ static int create_ad1845(struct snd_card *card, unsigned port,
 
                }
 
-               err = snd_wss_pcm(chip, 0, &pcm);
+               err = snd_wss_pcm(chip, 0);
                if (err < 0) {
                        snd_printk(KERN_ERR "sscape: No PCM device "
                                            "for AD1845 chip\n");
@@ -907,7 +907,7 @@ static int create_ad1845(struct snd_card *card, unsigned port,
                        goto _error;
                }
                if (chip->hardware != WSS_HW_AD1848) {
-                       err = snd_wss_timer(chip, 0, NULL);
+                       err = snd_wss_timer(chip, 0);
                        if (err < 0) {
                                snd_printk(KERN_ERR "sscape: No timer device "
                                                    "for AD1845 chip\n");
index bfbf38c..a0987a5 100644 (file)
@@ -380,11 +380,11 @@ snd_wavefront_probe (struct snd_card *card, int dev)
                return err;
        }
 
-       err = snd_wss_pcm(chip, 0, NULL);
+       err = snd_wss_pcm(chip, 0);
        if (err < 0)
                return err;
 
-       err = snd_wss_timer(chip, 0, NULL);
+       err = snd_wss_timer(chip, 0);
        if (err < 0)
                return err;
 
index b77883c..b5a1970 100644 (file)
@@ -16,7 +16,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/wait.h>
index 7dc9916..8a80fc6 100644 (file)
@@ -47,7 +47,7 @@
  *  
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/wait.h>
@@ -356,8 +356,7 @@ static void snd_wavefront_midi_output_timer(unsigned long data)
        unsigned long flags;
        
        spin_lock_irqsave (&midi->virtual, flags);
-       midi->timer.expires = 1 + jiffies;
-       add_timer(&midi->timer);
+       mod_timer(&midi->timer, 1 + jiffies);
        spin_unlock_irqrestore (&midi->virtual, flags);
        snd_wavefront_midi_output_write(card);
 }
@@ -384,11 +383,10 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs
        if (up) {
                if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) {
                        if (!midi->istimer) {
-                               init_timer(&midi->timer);
-                               midi->timer.function = snd_wavefront_midi_output_timer;
-                               midi->timer.data = (unsigned long) substream->rmidi->card->private_data;
-                               midi->timer.expires = 1 + jiffies;
-                               add_timer(&midi->timer);
+                               setup_timer(&midi->timer,
+                                           snd_wavefront_midi_output_timer,
+                                           (unsigned long) substream->rmidi->card->private_data);
+                               mod_timer(&midi->timer, 1 + jiffies);
                        }
                        midi->istimer++;
                        midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER;
index e5db001..33f5ec1 100644 (file)
@@ -20,7 +20,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 347bb1b..913b731 100644 (file)
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/pcm_params.h>
 #include <sound/tlv.h>
 
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 
@@ -1923,7 +1923,7 @@ static struct snd_pcm_ops snd_wss_capture_ops = {
        .pointer =      snd_wss_capture_pointer,
 };
 
-int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
+int snd_wss_pcm(struct snd_wss *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
@@ -1949,8 +1949,6 @@ int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
                                              64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
 
        chip->pcm = pcm;
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 EXPORT_SYMBOL(snd_wss_pcm);
@@ -1961,7 +1959,7 @@ static void snd_wss_timer_free(struct snd_timer *timer)
        chip->timer = NULL;
 }
 
-int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
+int snd_wss_timer(struct snd_wss *chip, int device)
 {
        struct snd_timer *timer;
        struct snd_timer_id tid;
@@ -1980,8 +1978,6 @@ int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
        timer->private_free = snd_wss_timer_free;
        timer->hw = snd_wss_timer_table;
        chip->timer = timer;
-       if (rtimer)
-               *rtimer = timer;
        return 0;
 }
 EXPORT_SYMBOL(snd_wss_timer);
index c23f9f9..a8ceef8 100644 (file)
@@ -675,7 +675,7 @@ static void dsp_write_flush(void)
                timeout);
        clear_bit(F_WRITEFLUSH, &dev.flags);
        if (!signal_pending(current)) {
-               current->state = TASK_INTERRUPTIBLE;
+               __set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE));
        }
        clear_bit(F_WRITING, &dev.flags);
@@ -1288,7 +1288,7 @@ static int __init calibrate_adc(WORD srate)
                       & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags);
        if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
            chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) {
-               current->state = TASK_INTERRUPTIBLE;
+               __set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(HZ / 3);
                return 0;
        }
index ca0d6e9..81314f9 100644 (file)
@@ -1228,7 +1228,7 @@ static void __exit cleanup_pss(void)
 {
        if(!pss_no_sound)
        {
-               if(fw_load && pss_synth)
+               if (fw_load)
                        vfree(pss_synth);
                if(pssmss)
                        unload_pss_mss(&cfg2);
index a33e8ce..213a416 100644 (file)
@@ -1654,7 +1654,7 @@ static int drain_dac(struct cs4297a_state *s, int nonblock)
         s->dma_dac.hwptr = s->dma_dac.swptr = hwptr;
         spin_unlock_irqrestore(&s->lock, flags);
        remove_wait_queue(&s->dma_dac.wait, &wait);
-       current->state = TASK_RUNNING;
+       __set_current_state(TASK_RUNNING);
        return 0;
 }
 
index 944e0c0..3c494dc 100644 (file)
@@ -487,7 +487,7 @@ static int __init init_trix(void)
 
 static void __exit cleanup_trix(void)
 {
-       if (fw_load && trix_boot)
+       if (fw_load)
                vfree(trix_boot);
        if (sb)
                unload_trix_sb(&cfg2);
index 29604a2..99b64cb 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -52,7 +53,6 @@
 #include <sound/initval.h>
 #include <sound/info.h>
 
-#include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/parisc-device.h>
 
@@ -893,9 +893,7 @@ snd_harmony_free(struct snd_harmony *h)
        if (h->irq >= 0)
                free_irq(h->irq, h);
 
-       if (h->iobase)
-               iounmap(h->iobase);
-
+       iounmap(h->iobase);
        kfree(h);
        return 0;
 }
index 50dd008..edfc1b8 100644 (file)
@@ -793,6 +793,15 @@ config SND_RME9652
          To compile this driver as a module, choose M here: the module
          will be called snd-rme9652.
 
+config SND_SE6X
+       tristate "Studio Evolution SE6X"
+       depends on SND_OXYGEN=n && SND_VIRTUOSO=n  # PCI ID conflict
+       select SND_OXYGEN_LIB
+       select SND_PCM
+       select SND_MPU401_UART
+       help
+         Say Y or M here only if you actually have this sound card.
+
 config SND_SIS7019
        tristate "SiS 7019 Audio Accelerator"
        depends on X86_32
index 1610c38..850a8c9 100644 (file)
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
 #include <sound/ac97_codec.h>
 
-#include <asm/io.h>
-
 #include "ad1889.h"
 #include "ac97/ac97_id.h"
 
@@ -623,14 +622,11 @@ snd_ad1889_interrupt(int irq, void *dev_id)
 }
 
 static int
-snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
+snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device)
 {
        int err;
        struct snd_pcm *pcm;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm);
        if (err < 0)
                return err;
@@ -658,9 +654,6 @@ snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
                return err;
        }
        
-       if (rpcm)
-               *rpcm = pcm;
-       
        return 0;
 }
 
@@ -859,12 +852,9 @@ snd_ad1889_free(struct snd_ad1889 *chip)
                free_irq(chip->irq, chip);
 
 skip_hw:
-       if (chip->iobase)
-               iounmap(chip->iobase);
-
+       iounmap(chip->iobase);
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
-
        kfree(chip);
        return 0;
 }
@@ -1016,7 +1006,7 @@ snd_ad1889_probe(struct pci_dev *pci,
        if (err < 0)
                goto free_and_ret;
        
-       err = snd_ad1889_pcm_init(chip, 0, NULL);
+       err = snd_ad1889_pcm_init(chip, 0);
        if (err < 0)
                goto free_and_ret;
 
index af89e42..c8d4995 100644 (file)
@@ -25,7 +25,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1873,7 +1873,6 @@ static int snd_ali_mixer(struct snd_ali *codec)
 #ifdef CONFIG_PM_SLEEP
 static int ali_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ali *chip = card->private_data;
        struct snd_ali_image *im;
@@ -1914,16 +1913,11 @@ static int ali_suspend(struct device *dev)
        outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
        spin_unlock_irq(&chip->reg_lock);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int ali_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ali *chip = card->private_data;
        struct snd_ali_image *im;
@@ -1933,15 +1927,6 @@ static int ali_resume(struct device *dev)
        if (!im)
                return 0;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        spin_lock_irq(&chip->reg_lock);
        
        for (i = 0; i < ALI_CHANNELS; i++) {
index 7bb6ac5..57e034f 100644 (file)
@@ -37,8 +37,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -728,35 +727,20 @@ static int snd_als300_create(struct snd_card *card,
 #ifdef CONFIG_PM_SLEEP
 static int snd_als300_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_als300 *chip = card->private_data;
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_als300_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_als300 *chip = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_als300_init(chip);
        snd_ac97_resume(chip->ac97);
 
index d3e6424..a3dea46 100644 (file)
@@ -65,7 +65,7 @@
  * - power management? (card can do voice wakeup according to datasheet!!)
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/gameport.h>
@@ -988,7 +988,6 @@ static void snd_card_als4000_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_als4000_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_card_als4000 *acard = card->private_data;
        struct snd_sb *chip = acard->chip;
@@ -997,29 +996,15 @@ static int snd_als4000_suspend(struct device *dev)
        
        snd_pcm_suspend_all(chip->pcm);
        snd_sbmixer_suspend(chip);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_als4000_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_card_als4000 *acard = card->private_data;
        struct snd_sb *chip = acard->chip;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_als4000_configure(chip);
        snd_sbdsp_reset(chip);
        snd_sbmixer_resume(chip);
index e9273fb..e5cd7be 100644 (file)
@@ -540,9 +540,8 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
        expiry = HZ / 200;
 
        expiry = max(expiry, 1); /* don't let it be zero! */
-       dpcm->timer.expires = jiffies + expiry;
+       mod_timer(&dpcm->timer, jiffies + expiry);
        dpcm->respawn_timer = 1;
-       add_timer(&dpcm->timer);
 }
 
 static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
@@ -1064,9 +1063,8 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
            If internal and other stream playing, can't switch
        */
 
-       init_timer(&dpcm->timer);
-       dpcm->timer.data = (unsigned long) dpcm;
-       dpcm->timer.function = snd_card_asihpi_timer_function;
+       setup_timer(&dpcm->timer, snd_card_asihpi_timer_function,
+                   (unsigned long) dpcm);
        dpcm->substream = substream;
        runtime->private_data = dpcm;
        runtime->private_free = snd_card_asihpi_runtime_free;
@@ -1246,9 +1244,8 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
        if (err)
                return -EIO;
 
-       init_timer(&dpcm->timer);
-       dpcm->timer.data = (unsigned long) dpcm;
-       dpcm->timer.function = snd_card_asihpi_timer_function;
+       setup_timer(&dpcm->timer, snd_card_asihpi_timer_function,
+                   (unsigned long) dpcm);
        dpcm->substream = substream;
        runtime->private_data = dpcm;
        runtime->private_free = snd_card_asihpi_runtime_free;
@@ -2832,14 +2829,11 @@ static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
 /* results in /dev/snd/hwC#D0 file for each card with index #
    also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
 */
-static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
-                             int device, struct snd_hwdep **rhwdep)
+static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device)
 {
        struct snd_hwdep *hw;
        int err;
 
-       if (rhwdep)
-               *rhwdep = NULL;
        err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
        if (err < 0)
                return err;
@@ -2849,8 +2843,6 @@ static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
        hw->ops.ioctl = snd_asihpi_hpi_ioctl;
        hw->ops.release = snd_asihpi_hpi_release;
        hw->private_data = asihpi;
-       if (rhwdep)
-               *rhwdep = hw;
        return 0;
 }
 
@@ -2993,7 +2985,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev,
 
        /* always create, can be enabled or disabled dynamically
            by enable_hwdep  module param*/
-       snd_asihpi_hpi_new(asihpi, 0, NULL);
+       snd_asihpi_hpi_new(asihpi, 0);
 
        strcpy(card->driver, "ASIHPI");
 
index 2414d7a..2d63648 100644 (file)
@@ -47,7 +47,7 @@
 
 /* operational/messaging errors */
 #define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT             901
-
+#define HPI6000_ERROR_RESP_GET_LEN                      902
 #define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK             903
 #define HPI6000_ERROR_MSG_GET_ADR                       904
 #define HPI6000_ERROR_RESP_GET_ADR                      905
@@ -1365,7 +1365,10 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
                length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
        } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
        if (!timeout)
-               length = sizeof(struct hpi_response);
+               return HPI6000_ERROR_RESP_GET_LEN;
+
+       if (length > phr->size)
+               return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
 
        /* get the response */
        p_data = (u32 *)phr;
index 6aa677e..6610bd0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/pci.h>
 #include <linux/stringify.h>
 #include <linux/module.h>
@@ -153,6 +153,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                goto out;
        }
 
+       res_max_size = min_t(size_t, res_max_size, sizeof(*hr));
+
        switch (hm->h.function) {
        case HPI_SUBSYS_CREATE_ADAPTER:
        case HPI_ADAPTER_DELETE:
@@ -539,10 +541,8 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev)
        hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
 
        /* unmap PCI memory space, mapped during device init. */
-       for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
-               if (pci.ap_mem_base[idx])
-                       iounmap(pci.ap_mem_base[idx]);
-       }
+       for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; ++idx)
+               iounmap(pci.ap_mem_base[idx]);
 
        if (pa->irq)
                free_irq(pa->irq, pa);
index 9c1c445..d5f15c9 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1474,7 +1474,6 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock,
  */
 static int snd_atiixp_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct atiixp *chip = card->private_data;
        int i;
@@ -1492,29 +1491,15 @@ static int snd_atiixp_suspend(struct device *dev)
                snd_ac97_suspend(chip->ac97[i]);
        snd_atiixp_aclink_down(chip);
        snd_atiixp_chip_stop(chip);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_atiixp_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct atiixp *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_atiixp_aclink_reset(chip);
        snd_atiixp_chip_start(chip);
 
@@ -1585,8 +1570,7 @@ static int snd_atiixp_free(struct atiixp *chip)
       __hw_end:
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
-       if (chip->remap_addr)
-               iounmap(chip->remap_addr);
+       iounmap(chip->remap_addr);
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
        kfree(chip);
index b2f63e0..0a38e08 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1120,7 +1120,6 @@ static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
  */
 static int snd_atiixp_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct atiixp_modem *chip = card->private_data;
        int i;
@@ -1132,29 +1131,15 @@ static int snd_atiixp_suspend(struct device *dev)
                snd_ac97_suspend(chip->ac97[i]);
        snd_atiixp_aclink_down(chip);
        snd_atiixp_chip_stop(chip);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_atiixp_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct atiixp_modem *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_atiixp_aclink_reset(chip);
        snd_atiixp_chip_start(chip);
 
@@ -1211,8 +1196,7 @@ static int snd_atiixp_free(struct atiixp_modem *chip)
       __hw_end:
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
-       if (chip->remap_addr)
-               iounmap(chip->remap_addr);
+       iounmap(chip->remap_addr);
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
        kfree(chip);
index 3a8fefe..bcc648b 100644 (file)
@@ -17,9 +17,8 @@
 #ifndef __SOUND_AU88X0_H
 #define __SOUND_AU88X0_H
 
-#ifdef __KERNEL__
 #include <linux/pci.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/rawmidi.h>
@@ -27,7 +26,6 @@
 #include <sound/hwdep.h>
 #include <sound/ac97_codec.h>
 #include <sound/tlv.h>
-#endif
 
 #ifndef CHIP_AU8820
 #include "au88x0_eq.h"
index e1cf019..8d2fee7 100644 (file)
@@ -229,9 +229,7 @@ static int snd_aw2_dev_free(struct snd_device *device)
        if (chip->irq >= 0)
                free_irq(chip->irq, (void *)chip);
        /* release the i/o ports & memory */
-       if (chip->iobase_virt)
-               iounmap(chip->iobase_virt);
-
+       iounmap(chip->iobase_virt);
        pci_release_regions(chip->pci);
        /* disable the PCI entry */
        pci_disable_device(chip->pci);
index 6d24e95..1d78904 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index fdbb9c0..a40a2b4 100644 (file)
  *  - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/bug.h> /* WARN_ONCE */
 #include <linux/pci.h>
@@ -2694,7 +2694,6 @@ snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
 static int
 snd_azf3328_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_azf3328 *chip = card->private_data;
        u16 *saved_regs_ctrl_u16;
@@ -2720,29 +2719,15 @@ snd_azf3328_suspend(struct device *dev)
                ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
        snd_azf3328_suspend_regs(chip, chip->opl3_io,
                ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int
 snd_azf3328_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        const struct snd_azf3328 *chip = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_azf3328_resume_regs(chip, chip->saved_regs_game, chip->game_io,
                                        ARRAY_SIZE(chip->saved_regs_game));
        snd_azf3328_resume_regs(chip, chip->saved_regs_mpu, chip->mpu_io,
index 058b997..5925b71 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -690,8 +690,7 @@ static int snd_bt87x_free(struct snd_bt87x *chip)
                snd_bt87x_stop(chip);
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
-       if (chip->mmio)
-               iounmap(chip->mmio);
+       iounmap(chip->mmio);
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
        kfree(chip);
index 96af339..dd75b75 100644 (file)
@@ -1910,7 +1910,6 @@ static void snd_ca0106_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_ca0106_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ca0106 *chip = card->private_data;
        int i;
@@ -1923,30 +1922,15 @@ static int snd_ca0106_suspend(struct device *dev)
        snd_ca0106_mixer_suspend(chip);
 
        ca0106_stop_chip(chip);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_ca0106_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ca0106 *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
-       if (pci_enable_device(pci) < 0) {
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-
-       pci_set_master(pci);
-
        ca0106_init_chip(chip, 1);
 
        if (chip->details->ac97)
index 68c0eb0..025805c 100644 (file)
@@ -70,7 +70,7 @@
 #include <sound/ac97_codec.h>
 #include <sound/info.h>
 #include <sound/tlv.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include "ca0106.h"
 
index 4f9c282..2c5c28a 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
 #include <sound/info.h>
 #include <sound/asoundef.h>
-#include <asm/io.h>
 
 #include "ca0106.h"
 
index 85ed403..1d0f2ca 100644 (file)
@@ -20,7 +20,7 @@
 /* Does not work. Warning may block system in capture mode */
 /* #define USE_VAR48KRATE */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -3347,7 +3347,6 @@ static unsigned char saved_mixers[] = {
 
 static int snd_cmipci_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cmipci *cm = card->private_data;
        int i;
@@ -3366,29 +3365,15 @@ static int snd_cmipci_suspend(struct device *dev)
 
        /* disable ints */
        snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_cmipci_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cmipci *cm = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        /* reset / initialize to a sane state */
        snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
        snd_cmipci_ch_reset(cm, CM_CH_PLAY);
index 4c49b5c..c296fd0 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -973,14 +973,11 @@ static struct snd_pcm_ops snd_cs4281_capture_ops = {
        .pointer =      snd_cs4281_pointer,
 };
 
-static int snd_cs4281_pcm(struct cs4281 *chip, int device,
-                         struct snd_pcm **rpcm)
+static int snd_cs4281_pcm(struct cs4281 *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(chip->card, "CS4281", device, 1, 1, &pcm);
        if (err < 0)
                return err;
@@ -996,8 +993,6 @@ static int snd_cs4281_pcm(struct cs4281 *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 512*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1321,10 +1316,8 @@ static int snd_cs4281_free(struct cs4281 *chip)
 
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
-       if (chip->ba0)
-               iounmap(chip->ba0);
-       if (chip->ba1)
-               iounmap(chip->ba1);
+       iounmap(chip->ba0);
+       iounmap(chip->ba1);
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
 
@@ -1788,14 +1781,11 @@ static struct snd_rawmidi_ops snd_cs4281_midi_input =
        .trigger =      snd_cs4281_midi_input_trigger,
 };
 
-static int snd_cs4281_midi(struct cs4281 *chip, int device,
-                          struct snd_rawmidi **rrawmidi)
+static int snd_cs4281_midi(struct cs4281 *chip, int device)
 {
        struct snd_rawmidi *rmidi;
        int err;
 
-       if (rrawmidi)
-               *rrawmidi = NULL;
        if ((err = snd_rawmidi_new(chip->card, "CS4281", device, 1, 1, &rmidi)) < 0)
                return err;
        strcpy(rmidi->name, "CS4281");
@@ -1804,8 +1794,6 @@ static int snd_cs4281_midi(struct cs4281 *chip, int device,
        rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
        rmidi->private_data = chip;
        chip->rmidi = rmidi;
-       if (rrawmidi)
-               *rrawmidi = rmidi;
        return 0;
 }
 
@@ -1941,11 +1929,11 @@ static int snd_cs4281_probe(struct pci_dev *pci,
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_cs4281_pcm(chip, 0, NULL)) < 0) {
+       if ((err = snd_cs4281_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_cs4281_midi(chip, 0, NULL)) < 0) {
+       if ((err = snd_cs4281_midi(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -2008,7 +1996,6 @@ static int saved_regs[SUSPEND_REGISTERS] = {
 
 static int cs4281_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cs4281 *chip = card->private_data;
        u32 ulCLK;
@@ -2047,30 +2034,16 @@ static int cs4281_suspend(struct device *dev)
        ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
        ulCLK &= ~CLKCR1_CKRA;
        snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int cs4281_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cs4281 *chip = card->private_data;
        unsigned int i;
        u32 ulCLK;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
        ulCLK |= CLKCR1_CKRA;
        snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
index 6a6858c..655fbea 100644 (file)
@@ -100,16 +100,16 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
        }
        card->private_data = chip;
        chip->accept_valid = mmap_valid[dev];
-       if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) {
+       if ((err = snd_cs46xx_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-       if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
+       if ((err = snd_cs46xx_pcm_rear(chip, 1)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
+       if ((err = snd_cs46xx_pcm_iec958(chip, 2)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -120,13 +120,13 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
        }
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
        if (chip->nr_ac97_codecs ==2) {
-               if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) {
+               if ((err = snd_cs46xx_pcm_center_lfe(chip, 3)) < 0) {
                        snd_card_free(card);
                        return err;
                }
        }
 #endif
-       if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) {
+       if ((err = snd_cs46xx_midi(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
index c49a082..9c9f89a 100644 (file)
@@ -1737,12 +1737,12 @@ int snd_cs46xx_create(struct snd_card *card,
                      struct snd_cs46xx **rcodec);
 extern const struct dev_pm_ops snd_cs46xx_pm;
 
-int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
-int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
-int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
-int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
+int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device);
+int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device);
+int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device);
+int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device);
 int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device);
-int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi);
+int snd_cs46xx_midi(struct snd_cs46xx *chip, int device);
 int snd_cs46xx_start_dsp(struct snd_cs46xx *chip);
 int snd_cs46xx_gameport(struct snd_cs46xx *chip);
 
index 32b44f2..8d74004 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/vmalloc.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -65,8 +66,6 @@
 #include <sound/pcm_params.h>
 #include "cs46xx.h"
 
-#include <asm/io.h>
-
 #include "cs46xx_lib.h"
 #include "dsp_spos.h"
 
@@ -1778,13 +1777,11 @@ static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
 #define MAX_PLAYBACK_CHANNELS  1
 #endif
 
-int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm)
+int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0)
                return err;
 
@@ -1801,23 +1798,16 @@ int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm)
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device,
-                       struct snd_pcm **rpcm)
+int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
                return err;
 
@@ -1833,21 +1823,14 @@ int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
-int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device,
-                             struct snd_pcm **rpcm)
+int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0)
                return err;
 
@@ -1863,21 +1846,14 @@ int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
-int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device,
-                         struct snd_pcm **rpcm)
+int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
                return err;
 
@@ -1893,9 +1869,6 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 #endif
@@ -2724,13 +2697,11 @@ static struct snd_rawmidi_ops snd_cs46xx_midi_input =
        .trigger =      snd_cs46xx_midi_input_trigger,
 };
 
-int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
+int snd_cs46xx_midi(struct snd_cs46xx *chip, int device)
 {
        struct snd_rawmidi *rmidi;
        int err;
 
-       if (rrawmidi)
-               *rrawmidi = NULL;
        if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0)
                return err;
        strcpy(rmidi->name, "CS46XX");
@@ -2739,8 +2710,6 @@ int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rr
        rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
        rmidi->private_data = chip;
        chip->rmidi = rmidi;
-       if (rrawmidi)
-               *rrawmidi = NULL;
        return 0;
 }
 
@@ -2979,8 +2948,8 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
 
        for (idx = 0; idx < 5; idx++) {
                struct snd_cs46xx_region *region = &chip->region.idx[idx];
-               if (region->remap_addr)
-                       iounmap(region->remap_addr);
+
+               iounmap(region->remap_addr);
                release_and_free_resource(region->resource);
        }
 
@@ -3804,7 +3773,6 @@ static unsigned int saved_regs[] = {
 
 static int snd_cs46xx_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_cs46xx *chip = card->private_data;
        int i, amp_saved;
@@ -3829,16 +3797,11 @@ static int snd_cs46xx_suspend(struct device *dev)
        /* disable CLKRUN */
        chip->active_ctrl(chip, -chip->amplifier);
        chip->amplifier = amp_saved; /* restore the status */
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_cs46xx_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_cs46xx *chip = card->private_data;
        int amp_saved;
@@ -3847,15 +3810,6 @@ static int snd_cs46xx_resume(struct device *dev)
 #endif
        unsigned int tmp;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        amp_saved = chip->amplifier;
        chip->amplifier = 0;
        chip->active_ctrl(chip, 1); /* force to on */
index 1c4a0fb..5c99efb 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/init.h>
index 8284bc9..2c90c0b 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/init.h>
index b102550..0a8cf94 100644 (file)
@@ -223,7 +223,7 @@ static int snd_cs5530_create(struct snd_card *card,
                return err;
        }
 
-       err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm);
+       err = snd_sb16dsp_pcm(chip->sb, 0);
        if (err < 0) {
                dev_err(card->dev, "Could not create PCM\n");
                snd_cs5530_free(chip);
index 16288e4..802c33f 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index 34cc600..06ac5d8 100644 (file)
@@ -57,7 +57,6 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
 
 static int snd_cs5535audio_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cs5535audio *cs5535au = card->private_data;
        int i;
@@ -72,34 +71,17 @@ static int snd_cs5535audio_suspend(struct device *dev)
        }
        /* save important regs, then disable aclink in hw */
        snd_cs5535audio_stop_hardware(cs5535au);
-
-       if (pci_save_state(pci)) {
-               dev_err(dev, "pci_save_state failed!\n");
-               return -EIO;
-       }
-       pci_disable_device(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_cs5535audio_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct cs5535audio *cs5535au = card->private_data;
        u32 tmp;
        int timeout;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        /* set LNK_WRM_RST to reset AC link */
        cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
 
index b425aa8..1cac55f 100644 (file)
@@ -1985,10 +1985,7 @@ static int hw_card_shutdown(struct hw *hw)
                free_irq(hw->irq, hw);
 
        hw->irq = -1;
-
-       if (hw->mem_base)
-               iounmap(hw->mem_base);
-
+       iounmap(hw->mem_base);
        hw->mem_base = NULL;
 
        if (hw->io_base)
@@ -2099,20 +2096,11 @@ static int hw_suspend(struct hw *hw)
                pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0);
        }
 
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
-
        return 0;
 }
 
 static int hw_resume(struct hw *hw, struct card_conf *info)
 {
-       struct pci_dev *pci = hw->pci;
-
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
        /* Re-initialize card hardware. */
        return hw_card_init(hw, info);
 }
index 253899d..955ad87 100644 (file)
@@ -2110,10 +2110,7 @@ static int hw_card_shutdown(struct hw *hw)
                free_irq(hw->irq, hw);
 
        hw->irq = -1;
-
-       if (hw->mem_base)
-               iounmap(hw->mem_base);
-
+       iounmap(hw->mem_base);
        hw->mem_base = NULL;
 
        if (hw->io_base)
@@ -2209,24 +2206,12 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
 #ifdef CONFIG_PM_SLEEP
 static int hw_suspend(struct hw *hw)
 {
-       struct pci_dev *pci = hw->pci;
-
        hw_card_stop(hw);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
-
        return 0;
 }
 
 static int hw_resume(struct hw *hw, struct card_conf *info)
 {
-       struct pci_dev *pci = hw->pci;
-
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
        /* Re-initialize card hardware. */
        return hw_card_init(hw, info);
 }
index 4632946..c95da63 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -51,7 +52,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index f81c839..3013b4d 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -55,7 +56,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 3a5346c..1f34a07 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -63,7 +64,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 21228ad..a962de0 100644 (file)
@@ -1872,12 +1872,8 @@ static int snd_echo_free(struct echoaudio *chip)
        if (chip->comm_page)
                snd_dma_free_pages(&chip->commpage_dma_buf);
 
-       if (chip->dsp_registers)
-               iounmap(chip->dsp_registers);
-
+       iounmap(chip->dsp_registers);
        release_and_free_resource(chip->iores);
-
-
        pci_disable_device(chip->pci);
 
        /* release chip data */
@@ -2162,7 +2158,6 @@ ctl_error:
 
 static int snd_echo_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct echoaudio *chip = dev_get_drvdata(dev);
 
        snd_pcm_suspend_all(chip->analog_pcm);
@@ -2188,9 +2183,6 @@ static int snd_echo_suspend(struct device *dev)
        chip->dsp_code = NULL;
        free_irq(chip->irq, chip);
        chip->irq = -1;
-       pci_save_state(pci);
-       pci_disable_device(pci);
-
        return 0;
 }
 
@@ -2204,7 +2196,6 @@ static int snd_echo_resume(struct device *dev)
        u32 pipe_alloc_mask;
        int err;
 
-       pci_restore_state(pci);
        commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
        if (commpage_bak == NULL)
                return -ENOMEM;
index 9cb81c5..4fa32a2 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -55,7 +56,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 35d3e6e..b1bcaca 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -61,7 +62,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 8d91842..175af9b 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -53,7 +54,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 289cb96..8c60314 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -53,7 +54,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 405a3f2..f7618ed 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -54,7 +55,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index b392dd7..12e5d21 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -61,7 +62,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index bc7f730..6e40237 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -63,7 +64,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 27a9a6e..2f7562f 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -62,7 +63,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index d913749..a8fe583 100644 (file)
@@ -257,9 +257,8 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream
        spin_lock_irq(&chip->lock);
        if (up) {
                if (!chip->tinuse) {
-                       init_timer(&chip->timer);
-                       chip->timer.function = snd_echo_midi_output_write;
-                       chip->timer.data = (unsigned long)chip;
+                       setup_timer(&chip->timer, snd_echo_midi_output_write,
+                                   (unsigned long)chip);
                        chip->tinuse = 1;
                }
        } else {
index 3d13875..34d4994 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -59,7 +60,6 @@
 #include <sound/pcm_params.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include <asm/io.h>
 #include <linux/atomic.h>
 #include "echoaudio.h"
 
index 4c17163..37d0220 100644 (file)
@@ -132,11 +132,11 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
                goto error;
        card->private_data = emu;
        emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
-       if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
+       if ((err = snd_emu10k1_pcm(emu, 0)) < 0)
                goto error;
-       if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
+       if ((err = snd_emu10k1_pcm_mic(emu, 1)) < 0)
                goto error;
-       if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0)
+       if ((err = snd_emu10k1_pcm_efx(emu, 2)) < 0)
                goto error;
        /* This stores the periods table. */
        if (emu->card_capabilities->ca0151_chip) { /* P16V */   
@@ -151,10 +151,10 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
        if ((err = snd_emu10k1_timer(emu, 0)) < 0)
                goto error;
 
-       if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0)
+       if ((err = snd_emu10k1_pcm_multi(emu, 3)) < 0)
                goto error;
        if (emu->card_capabilities->ca0151_chip) { /* P16V */
-               if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0)
+               if ((err = snd_p16v_pcm(emu, 4)) < 0)
                        goto error;
        }
        if (emu->audigy) {
@@ -164,7 +164,7 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
                if ((err = snd_emu10k1_midi(emu)) < 0)
                        goto error;
        }
-       if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0)
+       if ((err = snd_emu10k1_fx8010_new(emu, 0)) < 0)
                goto error;
 #ifdef ENABLE_SYNTH
        if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
@@ -210,7 +210,6 @@ static void snd_card_emu10k1_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_emu10k1_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_emu10k1 *emu = card->private_data;
 
@@ -232,28 +231,14 @@ static int snd_emu10k1_suspend(struct device *dev)
                snd_p16v_suspend(emu);
 
        snd_emu10k1_done(emu);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_emu10k1_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_emu10k1 *emu = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_emu10k1_resume_init(emu);
        snd_emu10k1_efx_resume(emu);
        snd_ac97_resume(emu->ac97);
index 15933f9..6d1b98d 100644 (file)
@@ -847,15 +847,13 @@ static const struct snd_pcm_chmap_elem clfe_map[] = {
        { }
 };
 
-static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
+static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device)
 {
        struct snd_pcm *pcm;
        const struct snd_pcm_chmap_elem *map = NULL;
        int err;
        int capture = 0;
   
-       if (rpcm)
-               *rpcm = NULL;
        if (device == 0)
                capture = 1;
        
@@ -896,15 +894,8 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **r
                                              snd_dma_pci_data(emu->pci), 
                                              32*1024, 32*1024);
   
-       err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
+       return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
                                     1 << 2, NULL);
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-  
-       return 0;
 }
 
 static int snd_emu10k1x_create(struct snd_card *card,
@@ -1583,15 +1574,15 @@ static int snd_emu10k1x_probe(struct pci_dev *pci,
                return err;
        }
 
-       if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) {
+       if ((err = snd_emu10k1x_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) {
+       if ((err = snd_emu10k1x_pcm(chip, 1)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) {
+       if ((err = snd_emu10k1x_pcm(chip, 2)) < 0) {
                snd_card_free(card);
                return err;
        }
index eb5c0ab..56fc47b 100644 (file)
@@ -2641,14 +2641,11 @@ static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
        return 0;
 }
 
-int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device,
-                          struct snd_hwdep **rhwdep)
+int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device)
 {
        struct snd_hwdep *hw;
        int err;
        
-       if (rhwdep)
-               *rhwdep = NULL;
        if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
                return err;
        strcpy(hw->name, "EMU10K1 (FX8010)");
@@ -2657,8 +2654,6 @@ int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device,
        hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
        hw->ops.release = snd_emu10k1_fx8010_release;
        hw->private_data = emu;
-       if (rhwdep)
-               *rhwdep = hw;
        return 0;
 }
 
index f82481b..0dc0738 100644 (file)
@@ -1400,15 +1400,12 @@ static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = {
        .page =                 snd_pcm_sgbuf_ops_page,
 };
 
-int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
+int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device)
 {
        struct snd_pcm *pcm;
        struct snd_pcm_substream *substream;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)
                return err;
 
@@ -1429,22 +1426,15 @@ int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
        for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
                snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
-int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device,
-                         struct snd_pcm **rpcm)
+int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device)
 {
        struct snd_pcm *pcm;
        struct snd_pcm_substream *substream;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0)
                return err;
 
@@ -1461,9 +1451,6 @@ int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device,
                if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
                        return err;
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
@@ -1479,15 +1466,11 @@ static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = {
        .pointer =              snd_emu10k1_capture_pointer,
 };
 
-int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device,
-                       struct snd_pcm **rpcm)
+int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0)
                return err;
 
@@ -1501,8 +1484,6 @@ int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device,
 
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1822,16 +1803,12 @@ static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = {
        .ack =                  snd_emu10k1_fx8010_playback_transfer,
 };
 
-int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device,
-                       struct snd_pcm **rpcm)
+int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device)
 {
        struct snd_pcm *pcm;
        struct snd_kcontrol *kctl;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
-
        if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0)
                return err;
 
@@ -1843,8 +1820,6 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device,
        pcm->info_flags = 0;
        strcpy(pcm->name, "Multichannel Capture/PT Playback");
        emu->pcm_efx = pcm;
-       if (rpcm)
-               *rpcm = pcm;
 
        /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs 
         * to these
index 7ef3898..3c60b43 100644 (file)
@@ -166,11 +166,8 @@ static struct snd_pcm_hardware snd_p16v_capture_hw = {
 static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
        struct snd_emu10k1_pcm *epcm = runtime->private_data;
-  
-       if (epcm) {
-               /* dev_dbg(emu->card->dev, "epcm free: %p\n", epcm); */
-               kfree(epcm);
-       }
+
+       kfree(epcm);
 }
 
 /* open_playback callback */
@@ -640,7 +637,7 @@ int snd_p16v_free(struct snd_emu10k1 *chip)
        return 0;
 }
 
-int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
+int snd_p16v_pcm(struct snd_emu10k1 *emu, int device)
 {
        struct snd_pcm *pcm;
        struct snd_pcm_substream *substream;
@@ -649,8 +646,6 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
   
        /* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */
        emu->p16v_device_offset = device;
-       if (rpcm)
-               *rpcm = NULL;
 
        if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
                return err;
@@ -694,9 +689,6 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
                */
        }
   
-       if (rpcm)
-               *rpcm = pcm;
-  
        return 0;
 }
 
index d94cb3c..0dc44eb 100644 (file)
@@ -26,7 +26,7 @@
  * by Kurt J. Bosch
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1268,14 +1268,11 @@ static const struct snd_pcm_chmap_elem surround_map[] = {
        { }
 };
 
-static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device,
-                          struct snd_pcm **rpcm)
+static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm);
        if (err < 0)
                return err;
@@ -1302,22 +1299,14 @@ static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device,
        err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                     snd_pcm_std_chmaps, 2, 0, NULL);
 #endif
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-       return 0;
+       return err;
 }
 
-static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device,
-                           struct snd_pcm **rpcm)
+static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm);
        if (err < 0)
                return err;
@@ -1342,12 +1331,7 @@ static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device,
        err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                     surround_map, 2, 0, NULL);
 #endif
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-       return 0;
+       return err;
 }
 
 /*
@@ -2049,7 +2033,6 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
 #ifdef CONFIG_PM_SLEEP
 static int snd_ensoniq_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct ensoniq *ensoniq = card->private_data;
        
@@ -2070,28 +2053,14 @@ static int snd_ensoniq_suspend(struct device *dev)
        udelay(100);
        snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
 #endif 
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_ensoniq_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct ensoniq *ensoniq = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_ensoniq_chip_init(ensoniq);
 
 #ifdef CHIP1371        
@@ -2362,14 +2331,11 @@ static struct snd_rawmidi_ops snd_ensoniq_midi_input =
        .trigger =      snd_ensoniq_midi_input_trigger,
 };
 
-static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device,
-                           struct snd_rawmidi **rrawmidi)
+static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device)
 {
        struct snd_rawmidi *rmidi;
        int err;
 
-       if (rrawmidi)
-               *rrawmidi = NULL;
        if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
                return err;
        strcpy(rmidi->name, CHIP_NAME);
@@ -2379,8 +2345,6 @@ static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device,
                SNDRV_RAWMIDI_INFO_DUPLEX;
        rmidi->private_data = ensoniq;
        ensoniq->rmidi = rmidi;
-       if (rrawmidi)
-               *rrawmidi = rmidi;
        return 0;
 }
 
@@ -2462,15 +2426,15 @@ static int snd_audiopci_probe(struct pci_dev *pci,
                return err;
        }
 #endif
-       if ((err = snd_ensoniq_pcm(ensoniq, 0, NULL)) < 0) {
+       if ((err = snd_ensoniq_pcm(ensoniq, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_ensoniq_pcm2(ensoniq, 1, NULL)) < 0) {
+       if ((err = snd_ensoniq_pcm2(ensoniq, 1)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_ensoniq_midi(ensoniq, 0, NULL)) < 0) {
+       if ((err = snd_ensoniq_midi(ensoniq, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
index 0fc46eb..e1858d9 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -63,8 +64,6 @@
 #include <sound/initval.h>
 #include <sound/tlv.h>
 
-#include <asm/io.h>
-
 MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");
 MODULE_DESCRIPTION("ESS Solo-1");
 MODULE_LICENSE("GPL");
@@ -1454,7 +1453,6 @@ static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
 
 static int es1938_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct es1938 *chip = card->private_data;
        unsigned char *s, *d;
@@ -1471,9 +1469,6 @@ static int es1938_suspend(struct device *dev)
                free_irq(chip->irq, chip);
                chip->irq = -1;
        }
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
@@ -1484,14 +1479,6 @@ static int es1938_resume(struct device *dev)
        struct es1938 *chip = card->private_data;
        unsigned char *s, *d;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-
        if (request_irq(pci->irq, snd_es1938_interrupt,
                        IRQF_SHARED, KBUILD_MODNAME, chip)) {
                dev_err(dev, "unable to grab IRQ %d, disabling device\n",
index 6039700..059f384 100644 (file)
@@ -94,7 +94,7 @@
  *     places.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -2383,7 +2383,6 @@ static void snd_es1968_start_irq(struct es1968 *chip)
  */
 static int es1968_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct es1968 *chip = card->private_data;
 
@@ -2396,16 +2395,11 @@ static int es1968_suspend(struct device *dev)
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
        snd_es1968_bob_stop(chip);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int es1968_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct es1968 *chip = card->private_data;
        struct esschan *es;
@@ -2413,16 +2407,6 @@ static int es1968_resume(struct device *dev)
        if (! chip->do_pm)
                return 0;
 
-       /* restore all our config */
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_es1968_chip_init(chip);
 
        /* need to restore the base pointers.. */ 
index d167aff..1fdd92b 100644 (file)
@@ -2,8 +2,6 @@
  *  The driver for the ForteMedia FM801 based soundcards
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *
- *  Support FM only card by Andy Shevchenko <andy@smile.org.ua>
- *
  *   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
  *   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 <linux/delay.h>
@@ -704,13 +698,11 @@ static struct snd_pcm_ops snd_fm801_capture_ops = {
        .pointer =      snd_fm801_capture_pointer,
 };
 
-static int snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm **rpcm)
+static int snd_fm801_pcm(struct fm801 *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "FM801", device, 1, 1, &pcm)) < 0)
                return err;
 
@@ -726,16 +718,10 @@ static int snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm **rpcm)
                                              snd_dma_pci_data(chip->pci),
                                              chip->multichannel ? 128*1024 : 64*1024, 128*1024);
 
-       err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+       return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                     snd_pcm_alt_chmaps,
                                     chip->multichannel ? 6 : 2, 0,
                                     NULL);
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-       return 0;
 }
 
 /*
@@ -1186,12 +1172,6 @@ static int snd_fm801_free(struct fm801 *chip)
                v4l2_device_unregister(&chip->v4l2_dev);
        }
 #endif
-       if (chip->irq >= 0)
-               free_irq(chip->irq, chip);
-       pci_release_regions(chip->pci);
-       pci_disable_device(chip->pci);
-
-       kfree(chip);
        return 0;
 }
 
@@ -1214,28 +1194,23 @@ static int snd_fm801_create(struct snd_card *card,
        };
 
        *rchip = NULL;
-       if ((err = pci_enable_device(pci)) < 0)
+       if ((err = pcim_enable_device(pci)) < 0)
                return err;
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (chip == NULL) {
-               pci_disable_device(pci);
+       chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
+       if (chip == NULL)
                return -ENOMEM;
-       }
        spin_lock_init(&chip->reg_lock);
        chip->card = card;
        chip->pci = pci;
        chip->irq = -1;
        chip->tea575x_tuner = tea575x_tuner;
-       if ((err = pci_request_regions(pci, "FM801")) < 0) {
-               kfree(chip);
-               pci_disable_device(pci);
+       if ((err = pci_request_regions(pci, "FM801")) < 0)
                return err;
-       }
        chip->port = pci_resource_start(pci, 0);
        if ((tea575x_tuner & TUNER_ONLY) == 0) {
-               if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
-                               KBUILD_MODNAME, chip)) {
-                       dev_err(card->dev, "unable to grab IRQ %d\n", chip->irq);
+               if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
+                               IRQF_SHARED, KBUILD_MODNAME, chip)) {
+                       dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
                        snd_fm801_free(chip);
                        return -EBUSY;
                }
@@ -1250,12 +1225,6 @@ static int snd_fm801_create(struct snd_card *card,
        /* init might set tuner access method */
        tea575x_tuner = chip->tea575x_tuner;
 
-       if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) {
-               pci_clear_master(pci);
-               free_irq(chip->irq, chip);
-               chip->irq = -1;
-       }
-
        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
                snd_fm801_free(chip);
                return err;
@@ -1340,7 +1309,7 @@ static int snd_card_fm801_probe(struct pci_dev *pci,
        if (chip->tea575x_tuner & TUNER_ONLY)
                goto __fm801_tuner_only;
 
-       if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
+       if ((err = snd_fm801_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -1392,7 +1361,6 @@ static unsigned char saved_regs[] = {
 
 static int snd_fm801_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct fm801 *chip = card->private_data;
        int i;
@@ -1404,29 +1372,15 @@ static int snd_fm801_suspend(struct device *dev)
        for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
                chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
        /* FIXME: tea575x suspend */
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_fm801_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct fm801 *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_fm801_chip_init(chip, 1);
        snd_ac97_resume(chip->ac97);
        snd_ac97_resume(chip->ac97_sec);
index ebf4c2f..7f0f2c5 100644 (file)
@@ -107,6 +107,7 @@ config SND_HDA_PATCH_LOADER
 config SND_HDA_CODEC_REALTEK
        tristate "Build Realtek HD-audio codec support"
        select SND_HDA_GENERIC
+       select INPUT
        help
          Say Y or M here to include Realtek HD-audio codec support in
          snd-hda-intel driver, such as ALC880.
index 1ede822..3f8706b 100644 (file)
@@ -409,10 +409,10 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
        /*
         * debug prints of the parsed results
         */
-       codec_info(codec, "autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
-                  cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
-                  cfg->line_out_pins[2], cfg->line_out_pins[3],
-                  cfg->line_out_pins[4],
+       codec_info(codec, "autoconfig for %s: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n",
+                  codec->chip_name, cfg->line_outs, cfg->line_out_pins[0],
+                  cfg->line_out_pins[1], cfg->line_out_pins[2],
+                  cfg->line_out_pins[3], cfg->line_out_pins[4],
                   cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" :
                   (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ?
                    "speaker" : "line"));
@@ -920,6 +920,8 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec,
                        codec->fixup_id = pq->value;
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                        codec->fixup_name = pq->name;
+                       codec_dbg(codec, "%s: picked fixup %s (pin match)\n",
+                                 codec->chip_name, codec->fixup_name);
 #endif
                        codec->fixup_list = fixlist;
                        return;
@@ -960,6 +962,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
                codec->fixup_list = NULL;
                codec->fixup_name = NULL;
                codec->fixup_id = HDA_FIXUP_ID_NO_FIXUP;
+               codec_dbg(codec, "%s: picked no fixup (nofixup specified)\n",
+                         codec->chip_name);
                return;
        }
 
@@ -969,6 +973,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
                                codec->fixup_id = models->id;
                                codec->fixup_name = models->name;
                                codec->fixup_list = fixlist;
+                               codec_dbg(codec, "%s: picked fixup %s (model specified)\n",
+                                         codec->chip_name, codec->fixup_name);
                                return;
                        }
                        models++;
@@ -980,6 +986,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
                        id = q->value;
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                        name = q->name;
+                       codec_dbg(codec, "%s: picked fixup %s (PCI SSID%s)\n",
+                                 codec->chip_name, name, q->subdevice_mask ? "" : " - vendor generic");
 #endif
                }
        }
@@ -992,6 +1000,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
                                id = q->value;
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                                name = q->name;
+                               codec_dbg(codec, "%s: picked fixup %s (codec SSID)\n",
+                                         codec->chip_name, name);
 #endif
                                break;
                        }
index 0cfc9c8..657b604 100644 (file)
@@ -1993,4 +1993,4 @@ void azx_notifier_unregister(struct azx *chip)
 EXPORT_SYMBOL_GPL(azx_notifier_unregister);
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Common HDA driver funcitons");
+MODULE_DESCRIPTION("Common HDA driver functions");
index d4d0375..7148945 100644 (file)
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/component.h>
+#include <drm/i915_component.h>
 #include <sound/core.h>
-#include <drm/i915_powerwell.h>
 #include "hda_priv.h"
-#include "hda_i915.h"
+#include "hda_intel.h"
 
 /* Intel HSW/BDW display HDA controller Extended Mode registers.
  * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display
 #define AZX_REG_EM4                    0x100c
 #define AZX_REG_EM5                    0x1010
 
-static int (*get_power)(void);
-static int (*put_power)(void);
-static int (*get_cdclk)(void);
-
-int hda_display_power(bool enable)
+int hda_display_power(struct hda_intel *hda, bool enable)
 {
-       if (!get_power || !put_power)
+       struct i915_audio_component *acomp = &hda->audio_component;
+
+       if (!acomp->ops)
                return -ENODEV;
 
-       pr_debug("HDA display power %s \n",
-                       enable ? "Enable" : "Disable");
+       dev_dbg(&hda->chip.pci->dev, "display power %s\n",
+               enable ? "enable" : "disable");
        if (enable)
-               return get_power();
+               acomp->ops->get_power(acomp->dev);
        else
-               return put_power();
+               acomp->ops->put_power(acomp->dev);
+
+       return 0;
 }
 
-void haswell_set_bclk(struct azx *chip)
+void haswell_set_bclk(struct hda_intel *hda)
 {
        int cdclk_freq;
        unsigned int bclk_m, bclk_n;
+       struct i915_audio_component *acomp = &hda->audio_component;
 
-       if (!get_cdclk)
+       if (!acomp->ops)
                return;
 
-       cdclk_freq = get_cdclk();
+       cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
        switch (cdclk_freq) {
        case 337500:
                bclk_m = 16;
@@ -80,51 +83,108 @@ void haswell_set_bclk(struct azx *chip)
                break;
        }
 
-       azx_writew(chip, EM4, bclk_m);
-       azx_writew(chip, EM5, bclk_n);
+       azx_writew(&hda->chip, EM4, bclk_m);
+       azx_writew(&hda->chip, EM5, bclk_n);
 }
 
-
-int hda_i915_init(void)
+static int hda_component_master_bind(struct device *dev)
 {
-       int err = 0;
-
-       get_power = symbol_request(i915_request_power_well);
-       if (!get_power) {
-               pr_warn("hda-i915: get_power symbol get fail\n");
-               return -ENODEV;
+       struct snd_card *card = dev_get_drvdata(dev);
+       struct azx *chip = card->private_data;
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+       struct i915_audio_component *acomp = &hda->audio_component;
+       int ret;
+
+       ret = component_bind_all(dev, acomp);
+       if (ret < 0)
+               return ret;
+
+       if (WARN_ON(!(acomp->dev && acomp->ops && acomp->ops->get_power &&
+                     acomp->ops->put_power && acomp->ops->get_cdclk_freq))) {
+               ret = -EINVAL;
+               goto out_unbind;
        }
 
-       put_power = symbol_request(i915_release_power_well);
-       if (!put_power) {
-               symbol_put(i915_request_power_well);
-               get_power = NULL;
-               return -ENODEV;
+       /*
+        * Atm, we don't support dynamic unbinding initiated by the child
+        * component, so pin its containing module until we unbind.
+        */
+       if (!try_module_get(acomp->ops->owner)) {
+               ret = -ENODEV;
+               goto out_unbind;
        }
 
-       get_cdclk = symbol_request(i915_get_cdclk_freq);
-       if (!get_cdclk) /* may have abnormal BCLK and audio playback rate */
-               pr_warn("hda-i915: get_cdclk symbol get fail\n");
+       return 0;
 
-       pr_debug("HDA driver get symbol successfully from i915 module\n");
+out_unbind:
+       component_unbind_all(dev, acomp);
 
-       return err;
+       return ret;
 }
 
-int hda_i915_exit(void)
+static void hda_component_master_unbind(struct device *dev)
 {
-       if (get_power) {
-               symbol_put(i915_request_power_well);
-               get_power = NULL;
-       }
-       if (put_power) {
-               symbol_put(i915_release_power_well);
-               put_power = NULL;
-       }
-       if (get_cdclk) {
-               symbol_put(i915_get_cdclk_freq);
-               get_cdclk = NULL;
+       struct snd_card *card = dev_get_drvdata(dev);
+       struct azx *chip = card->private_data;
+       struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+       struct i915_audio_component *acomp = &hda->audio_component;
+
+       module_put(acomp->ops->owner);
+       component_unbind_all(dev, acomp);
+       WARN_ON(acomp->ops || acomp->dev);
+}
+
+static const struct component_master_ops hda_component_master_ops = {
+       .bind = hda_component_master_bind,
+       .unbind = hda_component_master_unbind,
+};
+
+static int hda_component_master_match(struct device *dev, void *data)
+{
+       /* i915 is the only supported component */
+       return !strcmp(dev->driver->name, "i915");
+}
+
+int hda_i915_init(struct hda_intel *hda)
+{
+       struct component_match *match = NULL;
+       struct device *dev = &hda->chip.pci->dev;
+       struct i915_audio_component *acomp = &hda->audio_component;
+       int ret;
+
+       component_match_add(dev, &match, hda_component_master_match, hda);
+       ret = component_master_add_with_match(dev, &hda_component_master_ops,
+                                             match);
+       if (ret < 0)
+               goto out_err;
+
+       /*
+        * Atm, we don't support deferring the component binding, so make sure
+        * i915 is loaded and that the binding successfully completes.
+        */
+       request_module("i915");
+
+       if (!acomp->ops) {
+               ret = -ENODEV;
+               goto out_master_del;
        }
 
+       dev_dbg(dev, "bound to i915 component master\n");
+
+       return 0;
+out_master_del:
+       component_master_del(dev, &hda_component_master_ops);
+out_err:
+       dev_err(dev, "failed to add i915 component master (%d)\n", ret);
+
+       return ret;
+}
+
+int hda_i915_exit(struct hda_intel *hda)
+{
+       struct device *dev = &hda->chip.pci->dev;
+
+       component_master_del(dev, &hda_component_master_ops);
+
        return 0;
 }
diff --git a/sound/pci/hda/hda_i915.h b/sound/pci/hda/hda_i915.h
deleted file mode 100644 (file)
index e6072c6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  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.
- */
-#ifndef __SOUND_HDA_I915_H
-#define __SOUND_HDA_I915_H
-
-#ifdef CONFIG_SND_HDA_I915
-int hda_display_power(bool enable);
-void haswell_set_bclk(struct azx *chip);
-int hda_i915_init(void);
-int hda_i915_exit(void);
-#else
-static inline int hda_display_power(bool enable) { return 0; }
-static inline void haswell_set_bclk(struct azx *chip) { return; }
-static inline int hda_i915_init(void)
-{
-       return -ENODEV;
-}
-static inline int hda_i915_exit(void)
-{
-       return 0;
-}
-#endif
-
-#endif
index d426a0b..36d2f20 100644 (file)
@@ -63,7 +63,7 @@
 #include "hda_codec.h"
 #include "hda_controller.h"
 #include "hda_priv.h"
-#include "hda_i915.h"
+#include "hda_intel.h"
 
 /* position fix mode */
 enum {
@@ -354,31 +354,6 @@ static char *driver_short_names[] = {
        [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
 };
 
-struct hda_intel {
-       struct azx chip;
-
-       /* for pending irqs */
-       struct work_struct irq_pending_work;
-
-       /* sync probing */
-       struct completion probe_wait;
-       struct work_struct probe_work;
-
-       /* card list (for power_save trigger) */
-       struct list_head list;
-
-       /* extra flags */
-       unsigned int irq_pending_warned:1;
-
-       /* VGA-switcheroo setup */
-       unsigned int use_vga_switcheroo:1;
-       unsigned int vga_switcheroo_registered:1;
-       unsigned int init_failed:1; /* delayed init failed */
-
-       /* secondary power domain for hdmi audio under vga device */
-       struct dev_pm_domain hdmi_pm_domain;
-};
-
 #ifdef CONFIG_X86
 static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
 {
@@ -795,7 +770,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
  */
 static int azx_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip;
        struct hda_intel *hda;
@@ -824,11 +798,8 @@ static int azx_suspend(struct device *dev)
 
        if (chip->msi)
                pci_disable_msi(chip->pci);
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
-               hda_display_power(false);
+               hda_display_power(hda, false);
        return 0;
 }
 
@@ -848,18 +819,9 @@ static int azx_resume(struct device *dev)
                return 0;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
-               hda_display_power(true);
-               haswell_set_bclk(chip);
+               hda_display_power(hda, true);
+               haswell_set_bclk(hda);
        }
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(chip->card->dev,
-                       "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        if (chip->msi)
                if (pci_enable_msi(pci) < 0)
                        chip->msi = 0;
@@ -901,7 +863,7 @@ static int azx_runtime_suspend(struct device *dev)
        azx_enter_link_reset(chip);
        azx_clear_irq_pending(chip);
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
-               hda_display_power(false);
+               hda_display_power(hda, false);
 
        return 0;
 }
@@ -927,8 +889,8 @@ static int azx_runtime_resume(struct device *dev)
                return 0;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
-               hda_display_power(true);
-               haswell_set_bclk(chip);
+               hda_display_power(hda, true);
+               haswell_set_bclk(hda);
        }
 
        /* Read STATESTS before controller reset */
@@ -1138,8 +1100,7 @@ static int azx_free(struct azx *chip)
                free_irq(chip->irq, (void*)chip);
        if (chip->msi)
                pci_disable_msi(chip->pci);
-       if (chip->remap_addr)
-               iounmap(chip->remap_addr);
+       iounmap(chip->remap_addr);
 
        azx_free_stream_pages(chip);
        if (chip->region_requested)
@@ -1150,8 +1111,8 @@ static int azx_free(struct azx *chip)
        release_firmware(chip->fw);
 #endif
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
-               hda_display_power(false);
-               hda_i915_exit();
+               hda_display_power(hda, false);
+               hda_i915_exit(hda);
        }
        kfree(hda);
 
@@ -1629,8 +1590,12 @@ static int azx_first_init(struct azx *chip)
        /* initialize chip */
        azx_init_pci(chip);
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
-               haswell_set_bclk(chip);
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+               struct hda_intel *hda;
+
+               hda = container_of(chip, struct hda_intel, chip);
+               haswell_set_bclk(hda);
+       }
 
        azx_init_chip(chip, (probe_only[dev] & 2) == 0);
 
@@ -1910,13 +1875,10 @@ static int azx_probe_continue(struct azx *chip)
        /* Request power well for Haswell HDA controller and codec */
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
 #ifdef CONFIG_SND_HDA_I915
-               err = hda_i915_init();
-               if (err < 0) {
-                       dev_err(chip->card->dev,
-                               "Error request power-well from i915\n");
+               err = hda_i915_init(hda);
+               if (err < 0)
                        goto out_free;
-               }
-               err = hda_display_power(true);
+               err = hda_display_power(hda, true);
                if (err < 0) {
                        dev_err(chip->card->dev,
                                "Cannot turn on display power on i915\n");
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h
new file mode 100644 (file)
index 0000000..3486118
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  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.
+ */
+#ifndef __SOUND_HDA_INTEL_H
+#define __SOUND_HDA_INTEL_H
+
+#include <drm/i915_component.h>
+#include "hda_priv.h"
+
+struct hda_intel {
+       struct azx chip;
+
+       /* for pending irqs */
+       struct work_struct irq_pending_work;
+
+       /* sync probing */
+       struct completion probe_wait;
+       struct work_struct probe_work;
+
+       /* card list (for power_save trigger) */
+       struct list_head list;
+
+       /* extra flags */
+       unsigned int irq_pending_warned:1;
+
+       /* VGA-switcheroo setup */
+       unsigned int use_vga_switcheroo:1;
+       unsigned int vga_switcheroo_registered:1;
+       unsigned int init_failed:1; /* delayed init failed */
+
+       /* secondary power domain for hdmi audio under vga device */
+       struct dev_pm_domain hdmi_pm_domain;
+
+       /* i915 component interface */
+       struct i915_audio_component audio_component;
+};
+
+#ifdef CONFIG_SND_HDA_I915
+int hda_display_power(struct hda_intel *hda, bool enable);
+void haswell_set_bclk(struct hda_intel *hda);
+int hda_i915_init(struct hda_intel *hda);
+int hda_i915_exit(struct hda_intel *hda);
+#else
+static inline int hda_display_power(struct hda_intel *hda, bool enable)
+{
+       return 0;
+}
+static inline void haswell_set_bclk(struct hda_intel *hda) { return; }
+static inline int hda_i915_init(struct hda_intel *hda)
+{
+       return -ENODEV;
+}
+static inline int hda_i915_exit(struct hda_intel *hda)
+{
+       return 0;
+}
+#endif
+
+#endif
index a9d78e2..d285904 100644 (file)
@@ -739,39 +739,6 @@ static int patch_ad1981(struct hda_codec *codec)
  *      E/F quad mic array
  */
 
-#ifdef ENABLE_AD_STATIC_QUIRKS
-static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
-                              struct snd_ctl_elem_info *uinfo)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct ad198x_spec *spec = codec->spec;
-       return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
-                                   spec->num_channel_mode);
-}
-
-static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct ad198x_spec *spec = codec->spec;
-       return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
-                                  spec->num_channel_mode, spec->multiout.max_channels);
-}
-
-static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct ad198x_spec *spec = codec->spec;
-       int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
-                                     spec->num_channel_mode,
-                                     &spec->multiout.max_channels);
-       if (err >= 0 && spec->need_dac_fix)
-               spec->multiout.num_dacs = spec->multiout.max_channels / 2;
-       return err;
-}
-#endif /* ENABLE_AD_STATIC_QUIRKS */
-
 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_info *uinfo)
 {
index 65f1f4e..0403061 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/module.h>
+#include <linux/input.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -120,6 +121,7 @@ struct alc_spec {
        hda_nid_t pll_nid;
        unsigned int pll_coef_idx, pll_coef_bit;
        unsigned int coef0;
+       struct input_dev *kb_dev;
 };
 
 /*
@@ -3472,6 +3474,79 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
        }
 }
 
+static void gpio2_mic_hotkey_event(struct hda_codec *codec,
+                                  struct hda_jack_callback *event)
+{
+       struct alc_spec *spec = codec->spec;
+
+       /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
+          send both key on and key off event for every interrupt. */
+       input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
+       input_sync(spec->kb_dev);
+       input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
+       input_sync(spec->kb_dev);
+}
+
+static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
+                                            const struct hda_fixup *fix, int action)
+{
+       /* GPIO1 = set according to SKU external amp
+          GPIO2 = mic mute hotkey
+          GPIO3 = mute LED
+          GPIO4 = mic mute LED */
+       static const struct hda_verb gpio_init[] = {
+               { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
+               { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
+               { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
+               {}
+       };
+
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->kb_dev = input_allocate_device();
+               if (!spec->kb_dev) {
+                       codec_err(codec, "Out of memory (input_allocate_device)\n");
+                       return;
+               }
+               spec->kb_dev->name = "Microphone Mute Button";
+               spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
+               spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
+               if (input_register_device(spec->kb_dev)) {
+                       codec_err(codec, "input_register_device failed\n");
+                       input_free_device(spec->kb_dev);
+                       spec->kb_dev = NULL;
+                       return;
+               }
+
+               snd_hda_add_verbs(codec, gpio_init);
+               snd_hda_codec_write_cache(codec, codec->afg, 0,
+                                         AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
+               snd_hda_jack_detect_enable_callback(codec, codec->afg,
+                                                   gpio2_mic_hotkey_event);
+
+               spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
+               spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
+               spec->gpio_led = 0;
+               spec->mute_led_polarity = 0;
+               spec->gpio_mute_led_mask = 0x08;
+               spec->gpio_mic_led_mask = 0x10;
+               return;
+       }
+
+       if (!spec->kb_dev)
+               return;
+
+       switch (action) {
+       case HDA_FIXUP_ACT_PROBE:
+               spec->init_amp = ALC_INIT_DEFAULT;
+               break;
+       case HDA_FIXUP_ACT_FREE:
+               input_unregister_device(spec->kb_dev);
+               spec->kb_dev = NULL;
+       }
+}
+
 static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
                                const struct hda_fixup *fix, int action)
 {
@@ -4341,6 +4416,8 @@ enum {
        ALC282_FIXUP_ASPIRE_V5_PINS,
        ALC280_FIXUP_HP_GPIO4,
        ALC286_FIXUP_HP_GPIO_LED,
+       ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
+       ALC280_FIXUP_HP_DOCK_PINS,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -4814,6 +4891,21 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc286_fixup_hp_gpio_led,
        },
+       [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
+       },
+       [ALC280_FIXUP_HP_DOCK_PINS] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x1b, 0x21011020 }, /* line-out */
+                       { 0x1a, 0x01a1903c }, /* headset mic */
+                       { 0x18, 0x2181103f }, /* line-in */
+                       { },
+               },
+               .chained = true,
+               .chain_id = ALC280_FIXUP_HP_GPIO4
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -4843,6 +4935,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
        SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
        /* ALC282 */
        SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -4856,6 +4949,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
        SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
        SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
index 3981823..179ef7a 100644 (file)
@@ -21,7 +21,7 @@
  *
  */      
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
index b039b46..f7b1523 100644 (file)
@@ -880,13 +880,11 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = {
        .pointer =      snd_ice1712_capture_pointer,
 };
 
-static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm);
        if (err < 0)
                return err;
@@ -902,22 +900,17 @@ static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm *
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        dev_warn(ice->card->dev,
                 "Consumer PCM code does not work well at the moment --jk\n");
 
        return 0;
 }
 
-static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);
        if (err < 0)
                return err;
@@ -932,9 +925,6 @@ static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pc
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(ice->pci), 64*1024, 128*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
-
        return 0;
 }
 
@@ -1260,13 +1250,11 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
        .pointer =      snd_ice1712_capture_pro_pointer,
 };
 
-static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);
        if (err < 0)
                return err;
@@ -1282,8 +1270,6 @@ static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd
                                              snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
 
        ice->pcm_pro = pcm;
-       if (rpcm)
-               *rpcm = pcm;
 
        if (ice->cs8427) {
                /* assign channels to iec958 */
@@ -2691,14 +2677,14 @@ static int snd_ice1712_probe(struct pci_dev *pci,
        c = &no_matched;
  __found:
 
-       err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL);
+       err = snd_ice1712_pcm_profi(ice, pcm_dev++);
        if (err < 0) {
                snd_card_free(card);
                return err;
        }
 
        if (ice_has_con_ac97(ice)) {
-               err = snd_ice1712_pcm(ice, pcm_dev++, NULL);
+               err = snd_ice1712_pcm(ice, pcm_dev++);
                if (err < 0) {
                        snd_card_free(card);
                        return err;
@@ -2726,7 +2712,7 @@ static int snd_ice1712_probe(struct pci_dev *pci,
        }
 
        if (ice_has_con_ac97(ice)) {
-               err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL);
+               err = snd_ice1712_pcm_ds(ice, pcm_dev++);
                if (err < 0) {
                        snd_card_free(card);
                        return err;
@@ -2798,7 +2784,6 @@ static void snd_ice1712_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_ice1712_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ice1712 *ice = card->private_data;
 
@@ -2820,16 +2805,11 @@ static int snd_ice1712_suspend(struct device *dev)
 
        if (ice->pm_suspend)
                ice->pm_suspend(ice);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_ice1712_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ice1712 *ice = card->private_data;
        int rate;
@@ -2837,16 +2817,6 @@ static int snd_ice1712_resume(struct device *dev)
        if (!ice->pm_suspend_enabled)
                return 0;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
-       if (pci_enable_device(pci) < 0) {
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-
-       pci_set_master(pci);
-
        if (ice->cur_rate)
                rate = ice->cur_rate;
        else
index d73da15..0b22c00 100644 (file)
@@ -2798,7 +2798,6 @@ static void snd_vt1724_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_vt1724_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ice1712 *ice = card->private_data;
 
@@ -2821,32 +2820,17 @@ static int snd_vt1724_suspend(struct device *dev)
 
        if (ice->pm_suspend)
                ice->pm_suspend(ice);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_vt1724_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ice1712 *ice = card->private_data;
 
        if (!ice->pm_suspend_enabled)
                return 0;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
-       if (pci_enable_device(pci) < 0) {
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-
-       pci_set_master(pci);
-
        snd_vt1724_chip_reset(ice);
 
        if (snd_vt1724_chip_init(ice) < 0) {
index 21b373b..f7ac8d5 100644 (file)
@@ -183,22 +183,6 @@ void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac)
        snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac);
 }
 
-void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode)
-{
-       u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_MSTR_MASK;
-
-       mode &= WM8766_DAC3_MSTR_MASK;
-       snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | mode);
-}
-
-void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power)
-{
-       u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_POWER_MASK;
-
-       power &= WM8766_DAC3_POWER_MASK;
-       snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | power);
-}
-
 void snd_wm8766_volume_restore(struct snd_wm8766 *wm)
 {
        u16 val = wm->regs[WM8766_REG_DACR1];
index c119f84..18c8d9d 100644 (file)
@@ -155,8 +155,6 @@ struct snd_wm8766 {
 void snd_wm8766_init(struct snd_wm8766 *wm);
 void snd_wm8766_resume(struct snd_wm8766 *wm);
 void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac);
-void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode);
-void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power);
 void snd_wm8766_volume_restore(struct snd_wm8766 *wm);
 int snd_wm8766_build_controls(struct snd_wm8766 *wm);
 
index e66c0da..ebd2fe4 100644 (file)
@@ -452,21 +452,6 @@ void snd_wm8776_resume(struct snd_wm8776 *wm)
                snd_wm8776_write(wm, i, wm->regs[i]);
 }
 
-void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac)
-{
-       snd_wm8776_write(wm, WM8776_REG_DACIFCTRL, dac);
-}
-
-void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc)
-{
-       snd_wm8776_write(wm, WM8776_REG_ADCIFCTRL, adc);
-}
-
-void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode)
-{
-       snd_wm8776_write(wm, WM8776_REG_MSTRCTRL, mode);
-}
-
 void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power)
 {
        snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power);
index 93a2d69..42acef0 100644 (file)
@@ -216,9 +216,6 @@ struct snd_wm8776 {
 
 void snd_wm8776_init(struct snd_wm8776 *wm);
 void snd_wm8776_resume(struct snd_wm8776 *wm);
-void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac);
-void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc);
-void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode);
 void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power);
 void snd_wm8776_volume_restore(struct snd_wm8776 *wm);
 int snd_wm8776_build_controls(struct snd_wm8776 *wm);
index 4a28252..2c5484e 100644 (file)
@@ -26,7 +26,7 @@
  *
  */      
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -2654,7 +2654,6 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
  */
 static int intel8x0_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct intel8x0 *chip = card->private_data;
        int i;
@@ -2682,12 +2681,6 @@ static int intel8x0_suspend(struct device *dev)
                free_irq(chip->irq, chip);
                chip->irq = -1;
        }
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       /* The call below may disable built-in speaker on some laptops
-        * after S2RAM.  So, don't touch it.
-        */
-       /* pci_set_power_state(pci, PCI_D3hot); */
        return 0;
 }
 
@@ -2698,14 +2691,6 @@ static int intel8x0_resume(struct device *dev)
        struct intel8x0 *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        snd_intel8x0_chip_init(chip, 0);
        if (request_irq(pci->irq, snd_intel8x0_interrupt,
                        IRQF_SHARED, KBUILD_MODNAME, chip)) {
index 6b40235..7577f31 100644 (file)
@@ -23,7 +23,7 @@
  *
  */      
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1023,7 +1023,6 @@ static int snd_intel8x0m_free(struct intel8x0m *chip)
  */
 static int intel8x0m_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct intel8x0m *chip = card->private_data;
        int i;
@@ -1036,9 +1035,6 @@ static int intel8x0m_suspend(struct device *dev)
                free_irq(chip->irq, chip);
                chip->irq = -1;
        }
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
@@ -1048,14 +1044,6 @@ static int intel8x0m_resume(struct device *dev)
        struct snd_card *card = dev_get_drvdata(dev);
        struct intel8x0m *chip = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        if (request_irq(pci->irq, snd_intel8x0m_interrupt,
                        IRQF_SHARED, KBUILD_MODNAME, chip)) {
                dev_err(dev, "unable to grab IRQ %d, disabling device\n",
index 59d21c9..7acbc21 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -36,8 +37,6 @@
 #include <sound/pcm_params.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
-
 // ----------------------------------------------------------------------------
 // Debug Stuff
 // ----------------------------------------------------------------------------
@@ -585,8 +584,7 @@ static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
                korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
                /* program the timer */
                korg1212->stop_pending_cnt = HZ;
-               korg1212->timer.expires = jiffies + 1;
-               add_timer(&korg1212->timer);
+               mod_timer(&korg1212->timer, jiffies + 1);
        }
 }
 
@@ -617,8 +615,7 @@ static void snd_korg1212_timer_func(unsigned long data)
        } else {
                if (--korg1212->stop_pending_cnt > 0) {
                        /* reprogram timer */
-                       korg1212->timer.expires = jiffies + 1;
-                       add_timer(&korg1212->timer);
+                       mod_timer(&korg1212->timer, jiffies + 1);
                } else {
                        snd_printd("korg1212_timer_func timeout\n");
                        korg1212->sharedBufferPtr->cardCommand = 0;
@@ -2172,9 +2169,8 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
         init_waitqueue_head(&korg1212->wait);
         spin_lock_init(&korg1212->lock);
        mutex_init(&korg1212->open_mutex);
-       init_timer(&korg1212->timer);
-       korg1212->timer.function = snd_korg1212_timer_func;
-       korg1212->timer.data = (unsigned long)korg1212;
+       setup_timer(&korg1212->timer, snd_korg1212_timer_func,
+                   (unsigned long)korg1212);
 
         korg1212->irq = -1;
         korg1212->clkSource = K1212_CLKIDX_Local;
index 4cf4be5..9ff6000 100644 (file)
@@ -551,10 +551,8 @@ static void lola_free(struct lola *chip)
        lola_free_mixer(chip);
        if (chip->irq >= 0)
                free_irq(chip->irq, (void *)chip);
-       if (chip->bar[0].remap_addr)
-               iounmap(chip->bar[0].remap_addr);
-       if (chip->bar[1].remap_addr)
-               iounmap(chip->bar[1].remap_addr);
+       iounmap(chip->bar[0].remap_addr);
+       iounmap(chip->bar[1].remap_addr);
        if (chip->rb.area)
                snd_dma_free_pages(&chip->rb);
        pci_release_regions(chip->pci);
index 98823d1..9be6609 100644 (file)
@@ -31,7 +31,7 @@
 #define CARD_NAME "ESS Maestro3/Allegro/Canyon3D-2"
 #define DRIVER_NAME "Maestro3"
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -2395,7 +2395,6 @@ static int snd_m3_free(struct snd_m3 *chip)
 #ifdef CONFIG_PM_SLEEP
 static int m3_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_m3 *chip = card->private_data;
        int i, dsp_index;
@@ -2421,16 +2420,11 @@ static int m3_suspend(struct device *dev)
        for (i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
                chip->suspend_mem[dsp_index++] =
                        snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int m3_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_m3 *chip = card->private_data;
        int i, dsp_index;
@@ -2438,15 +2432,6 @@ static int m3_resume(struct device *dev)
        if (chip->suspend_mem == NULL)
                return 0;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        /* first lets just bring everything back. .*/
        snd_m3_outw(chip, 0, 0x54);
        snd_m3_outw(chip, 0, 0x56);
index 1faf47e..c3a9f39 100644 (file)
@@ -1114,10 +1114,9 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
        }
 
        /* release the i/o ports */
-       for (i = 0; i < 2; i++) {
-               if (mgr->mem[i].virt)
-                       iounmap(mgr->mem[i].virt);
-       }
+       for (i = 0; i < 2; ++i)
+               iounmap(mgr->mem[i].virt);
+
        pci_release_regions(mgr->pci);
 
        /* free flowarray */
index fe80313..dccf3db 100644 (file)
@@ -23,8 +23,8 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <sound/core.h>
 #include "mixart.h"
 #include "mixart_hwdep.h"
index 9996a4d..5bfd3ac 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include "mixart.h"
 #include "mixart_mixer.h"
index 4e41a4e..4735e27 100644 (file)
@@ -24,7 +24,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
   
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1392,7 +1392,6 @@ snd_nm256_peek_for_sig(struct nm256 *chip)
  */
 static int nm256_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct nm256 *chip = card->private_data;
 
@@ -1400,15 +1399,11 @@ static int nm256_suspend(struct device *dev)
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
        chip->coeffs_current = 0;
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int nm256_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct nm256 *chip = card->private_data;
        int i;
@@ -1416,15 +1411,6 @@ static int nm256_resume(struct device *dev)
        /* Perform a full reset on the hardware */
        chip->in_resume = 1;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_nm256_init_chip(chip);
 
        /* restore ac97 */
@@ -1460,10 +1446,8 @@ static int snd_nm256_free(struct nm256 *chip)
        if (chip->irq >= 0)
                free_irq(chip->irq, chip);
 
-       if (chip->cport)
-               iounmap(chip->cport);
-       if (chip->buffer)
-               iounmap(chip->buffer);
+       iounmap(chip->cport);
+       iounmap(chip->buffer);
        release_and_free_resource(chip->res_cport);
        release_and_free_resource(chip->res_buffer);
 
index 8f4c409..ab085d7 100644 (file)
@@ -1,8 +1,10 @@
 snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
 snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o
+snd-se6x-objs := se6x.o
 snd-virtuoso-objs := virtuoso.o xonar_lib.o \
        xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
 
 obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
 obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
+obj-$(CONFIG_SND_SE6X) += snd-se6x.o
 obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
index c10ab07..293d0b9 100644 (file)
@@ -35,7 +35,7 @@
 #define CAPTURE_1_FROM_SPDIF   0x0080
 #define CAPTURE_2_FROM_I2S_2   0x0100
 #define CAPTURE_2_FROM_AC97_1  0x0200
-     /* CAPTURE_3_FROM_I2S_3           not implemented */
+#define CAPTURE_3_FROM_I2S_3   0x0400
 #define MIDI_OUTPUT            0x0800
 #define MIDI_INPUT             0x1000
 #define AC97_CD_INPUT          0x2000
index 4b8a32c..c7851da 100644 (file)
@@ -20,9 +20,9 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/export.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/mpu401.h>
-#include <asm/io.h>
 #include "oxygen.h"
 
 u8 oxygen_read8(struct oxygen *chip, unsigned int reg)
index b67e306..ffff3b2 100644 (file)
@@ -319,11 +319,12 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
 
 static void configure_pcie_bridge(struct pci_dev *pci)
 {
-       enum { PEX811X, PI7C9X110 };
+       enum { PEX811X, PI7C9X110, XIO2001 };
        static const struct pci_device_id bridge_ids[] = {
                { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X },
                { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X },
                { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
+               { PCI_VDEVICE(TI, 0x8240), .driver_data = XIO2001 },
                { }
        };
        struct pci_dev *bridge;
@@ -357,6 +358,14 @@ static void configure_pcie_bridge(struct pci_dev *pci)
                tmp |= 1;       /* park the PCI arbiter to the sound chip */
                pci_write_config_dword(bridge, 0x40, tmp);
                break;
+
+       case XIO2001: /* Texas Instruments XIO2001 PCIe/PCI bridge */
+               pci_read_config_dword(bridge, 0xe8, &tmp);
+               tmp &= ~0xf;    /* request length limit: 64 bytes */
+               tmp &= ~(0xf << 8);
+               tmp |= 1 << 8;  /* request count limit: one buffer */
+               pci_write_config_dword(bridge, 0xe8, tmp);
+               break;
        }
 }
 
@@ -441,9 +450,18 @@ static void oxygen_init(struct oxygen *chip)
                oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
                               OXYGEN_I2S_MASTER |
                               OXYGEN_I2S_MUTE_MCLK);
-       oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
-                      OXYGEN_I2S_MASTER |
-                      OXYGEN_I2S_MUTE_MCLK);
+       if (chip->model.device_config & CAPTURE_3_FROM_I2S_3)
+               oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
+                              OXYGEN_RATE_48000 |
+                              chip->model.adc_i2s_format |
+                              OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
+                              OXYGEN_I2S_BITS_16 |
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_BCLK_64);
+       else
+               oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
+                              OXYGEN_I2S_MASTER |
+                              OXYGEN_I2S_MUTE_MCLK);
        oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
                            OXYGEN_SPDIF_OUT_ENABLE |
                            OXYGEN_SPDIF_LOOPBACK);
@@ -728,7 +746,6 @@ EXPORT_SYMBOL(oxygen_pci_remove);
 #ifdef CONFIG_PM_SLEEP
 static int oxygen_pci_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct oxygen *chip = card->private_data;
        unsigned int i, saved_interrupt_mask;
@@ -736,8 +753,7 @@ static int oxygen_pci_suspend(struct device *dev)
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 
        for (i = 0; i < PCM_COUNT; ++i)
-               if (chip->streams[i])
-                       snd_pcm_suspend(chip->streams[i]);
+               snd_pcm_suspend(chip->streams[i]);
 
        if (chip->model.suspend)
                chip->model.suspend(chip);
@@ -753,10 +769,6 @@ static int oxygen_pci_suspend(struct device *dev)
        flush_work(&chip->spdif_input_bits_work);
        flush_work(&chip->gpio_work);
        chip->interrupt_mask = saved_interrupt_mask;
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
@@ -788,20 +800,10 @@ static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
 
 static int oxygen_pci_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct oxygen *chip = card->private_data;
        unsigned int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "cannot reenable device");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
        oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
        for (i = 0; i < OXYGEN_IO_SIZE; ++i)
index 5988e04..6492bca 100644 (file)
@@ -786,6 +786,9 @@ static const struct snd_kcontrol_new controls[] = {
                .get = upmix_get,
                .put = upmix_put,
        },
+};
+
+static const struct snd_kcontrol_new spdif_output_controls[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
@@ -937,6 +940,33 @@ static const struct {
                        },
                },
        },
+       {
+               .pcm_dev = CAPTURE_3_FROM_I2S_3,
+               .controls = {
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Playback Switch",
+                               .index = 2,
+                               .info = snd_ctl_boolean_mono_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_C,
+                       },
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Playback Volume",
+                               .index = 2,
+                               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+                               .info = monitor_volume_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
+                                               | (1 << 8),
+                               .tlv = { .p = monitor_db_scale, },
+                       },
+               },
+       },
        {
                .pcm_dev = CAPTURE_1_FROM_SPDIF,
                .controls = {
@@ -1073,6 +1103,12 @@ int oxygen_mixer_init(struct oxygen *chip)
        err = add_controls(chip, controls, ARRAY_SIZE(controls));
        if (err < 0)
                return err;
+       if (chip->model.device_config & PLAYBACK_1_TO_SPDIF) {
+               err = add_controls(chip, spdif_output_controls,
+                                  ARRAY_SIZE(spdif_output_controls));
+               if (err < 0)
+                       return err;
+       }
        if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
                err = add_controls(chip, spdif_input_controls,
                                   ARRAY_SIZE(spdif_input_controls));
index 0282824..aa2ebd1 100644 (file)
@@ -144,9 +144,11 @@ static int oxygen_open(struct snd_pcm_substream *substream,
                runtime->hw = *oxygen_hardware[channel];
        switch (channel) {
        case PCM_C:
-               runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
-                                      SNDRV_PCM_RATE_64000);
-               runtime->hw.rate_min = 44100;
+               if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
+                       runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
+                                              SNDRV_PCM_RATE_64000);
+                       runtime->hw.rate_min = 44100;
+               }
                /* fall through */
        case PCM_A:
        case PCM_B:
@@ -430,17 +432,36 @@ static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *hw_params)
 {
        struct oxygen *chip = snd_pcm_substream_chip(substream);
+       bool is_spdif;
        int err;
 
        err = oxygen_hw_params(substream, hw_params);
        if (err < 0)
                return err;
 
+       is_spdif = chip->model.device_config & CAPTURE_1_FROM_SPDIF;
+
        spin_lock_irq(&chip->reg_lock);
        oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
                             oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
                             OXYGEN_REC_FORMAT_C_MASK);
+       if (!is_spdif)
+               oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT,
+                                     oxygen_rate(hw_params) |
+                                     chip->model.adc_i2s_format |
+                                     get_mclk(chip, PCM_B, hw_params) |
+                                     oxygen_i2s_bits(hw_params),
+                                     OXYGEN_I2S_RATE_MASK |
+                                     OXYGEN_I2S_FORMAT_MASK |
+                                     OXYGEN_I2S_MCLK_MASK |
+                                     OXYGEN_I2S_BITS_MASK);
        spin_unlock_irq(&chip->reg_lock);
+
+       if (!is_spdif) {
+               mutex_lock(&chip->mutex);
+               chip->model.set_adc_params(chip, hw_params);
+               mutex_unlock(&chip->mutex);
+       }
        return 0;
 }
 
@@ -676,11 +697,6 @@ static struct snd_pcm_ops oxygen_ac97_ops = {
        .pointer   = oxygen_pointer,
 };
 
-static void oxygen_pcm_free(struct snd_pcm *pcm)
-{
-       snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 int oxygen_pcm_init(struct oxygen *chip)
 {
        struct snd_pcm *pcm;
@@ -705,7 +721,6 @@ int oxygen_pcm_init(struct oxygen *chip)
                        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                                        &oxygen_rec_b_ops);
                pcm->private_data = chip;
-               pcm->private_free = oxygen_pcm_free;
                strcpy(pcm->name, "Multichannel");
                if (outs)
                        snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
@@ -734,7 +749,6 @@ int oxygen_pcm_init(struct oxygen *chip)
                        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                                        &oxygen_rec_c_ops);
                pcm->private_data = chip;
-               pcm->private_free = oxygen_pcm_free;
                strcpy(pcm->name, "Digital");
                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                                      snd_dma_pci_data(chip->pci),
@@ -765,12 +779,29 @@ int oxygen_pcm_init(struct oxygen *chip)
                        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                                        &oxygen_rec_b_ops);
                pcm->private_data = chip;
-               pcm->private_free = oxygen_pcm_free;
                strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                                      snd_dma_pci_data(chip->pci),
                                                      DEFAULT_BUFFER_BYTES,
                                                      BUFFER_BYTES_MAX);
        }
+
+       ins = !!(chip->model.device_config & CAPTURE_3_FROM_I2S_3);
+       if (ins) {
+               err = snd_pcm_new(chip->card, "Analog3", 3, 0, ins, &pcm);
+               if (err < 0)
+                       return err;
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                               &oxygen_rec_c_ops);
+               oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
+                                    OXYGEN_REC_C_ROUTE_I2S_ADC_3,
+                                    OXYGEN_REC_C_ROUTE_MASK);
+               pcm->private_data = chip;
+               strcpy(pcm->name, "Analog 3");
+               snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+                                                     snd_dma_pci_data(chip->pci),
+                                                     DEFAULT_BUFFER_BYTES,
+                                                     BUFFER_BYTES_MAX);
+       }
        return 0;
 }
diff --git a/sound/pci/oxygen/se6x.c b/sound/pci/oxygen/se6x.c
new file mode 100644 (file)
index 0000000..f70d514
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * C-Media CMI8787 driver for the Studio Evolution SE6X
+ *
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ *
+ *  This driver is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License, version 2.
+ *
+ *  This driver 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 driver; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * CMI8787:
+ *
+ *   SPI    -> microcontroller (not actually used)
+ *   GPIO 0 -> do.
+ *   GPIO 2 -> do.
+ *
+ *   DAC0   -> both PCM1792A (L+R, each in mono mode)
+ *   ADC1  <-  1st PCM1804
+ *   ADC2  <-  2nd PCM1804
+ *   ADC3  <-  3rd PCM1804
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include "oxygen.h"
+
+MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
+MODULE_DESCRIPTION("Studio Evolution SE6X driver");
+MODULE_LICENSE("GPL v2");
+MODULE_SUPPORTED_DEVICE("{{Studio Evolution,SE6X}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "card index");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "enable card");
+
+static const struct pci_device_id se6x_ids[] = {
+       { OXYGEN_PCI_SUBID(0x13f6, 0x8788) },
+       { }
+};
+MODULE_DEVICE_TABLE(pci, se6x_ids);
+
+static void se6x_init(struct oxygen *chip)
+{
+       oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x005);
+
+       snd_component_add(chip->card, "PCM1792A");
+       snd_component_add(chip->card, "PCM1804");
+}
+
+static int se6x_control_filter(struct snd_kcontrol_new *template)
+{
+       /* no DAC volume/mute */
+       if (!strncmp(template->name, "Master Playback ", 16))
+               return 1;
+       return 0;
+}
+
+static void se6x_cleanup(struct oxygen *chip)
+{
+}
+
+static void set_pcm1792a_params(struct oxygen *chip,
+                               struct snd_pcm_hw_params *params)
+{
+       /* nothing to do (the microcontroller monitors DAC_LRCK) */
+}
+
+static void set_pcm1804_params(struct oxygen *chip,
+                              struct snd_pcm_hw_params *params)
+{
+}
+
+static unsigned int se6x_adjust_dac_routing(struct oxygen *chip,
+                                           unsigned int play_routing)
+{
+       /* route the same stereo pair to DAC0 and DAC1 */
+       return ( play_routing       & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
+              ((play_routing << 2) & OXYGEN_PLAY_DAC1_SOURCE_MASK);
+}
+
+static const struct oxygen_model model_se6x = {
+       .shortname = "Studio Evolution SE6X",
+       .longname = "C-Media Oxygen HD Audio",
+       .chip = "CMI8787",
+       .init = se6x_init,
+       .control_filter = se6x_control_filter,
+       .cleanup = se6x_cleanup,
+       .set_dac_params = set_pcm1792a_params,
+       .set_adc_params = set_pcm1804_params,
+       .adjust_dac_routing = se6x_adjust_dac_routing,
+       .device_config = PLAYBACK_0_TO_I2S |
+                        CAPTURE_0_FROM_I2S_1 |
+                        CAPTURE_2_FROM_I2S_2 |
+                        CAPTURE_3_FROM_I2S_3,
+       .dac_channels_pcm = 2,
+       .function_flags = OXYGEN_FUNCTION_SPI,
+       .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
+       .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
+       .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+       .adc_i2s_format = OXYGEN_I2S_FORMAT_I2S,
+};
+
+static int se6x_get_model(struct oxygen *chip,
+                         const struct pci_device_id *pci_id)
+{
+       chip->model = model_se6x;
+       return 0;
+}
+
+static int se6x_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+       static int dev;
+       int err;
+
+       if (dev >= SNDRV_CARDS)
+               return -ENODEV;
+       if (!enable[dev]) {
+               ++dev;
+               return -ENOENT;
+       }
+       err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
+                              se6x_ids, se6x_get_model);
+       if (err >= 0)
+               ++dev;
+       return err;
+}
+
+static struct pci_driver se6x_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = se6x_ids,
+       .probe = se6x_probe,
+       .remove = oxygen_pci_remove,
+#ifdef CONFIG_PM_SLEEP
+       .driver = {
+               .pm = &oxygen_pci_pm,
+       },
+#endif
+       .shutdown = oxygen_pci_shutdown,
+};
+
+module_pci_driver(se6x_driver);
index 181f772..c5194f5 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include "pcxhr.h"
 #include "pcxhr_mixer.h"
index 15a8ce5..8063305 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/firmware.h>
 #include <linux/pci.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
 #include "pcxhr.h"
index 6abc2ac..29f2827 100644 (file)
@@ -99,7 +99,7 @@
 #include <linux/firmware.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -1153,7 +1153,6 @@ static void riptide_handleirq(unsigned long dev_id)
 #ifdef CONFIG_PM_SLEEP
 static int riptide_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_riptide *chip = card->private_data;
 
@@ -1161,27 +1160,14 @@ static int riptide_suspend(struct device *dev)
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int riptide_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_riptide *chip = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               printk(KERN_ERR "riptide: pci_enable_device failed, "
-                      "disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        snd_riptide_initialize(chip);
        snd_ac97_resume(chip->ac97);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -1706,14 +1692,11 @@ static struct snd_pcm_ops snd_riptide_capture_ops = {
        .pointer = snd_riptide_pointer,
 };
 
-static int
-snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
+static int snd_riptide_pcm(struct snd_riptide *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err =
             snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
                         &pcm)) < 0)
@@ -1729,8 +1712,6 @@ snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
                                              snd_dma_pci_data(chip->pci),
                                              64 * 1024, 128 * 1024);
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -2092,7 +2073,7 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
        if (err < 0)
                goto error;
        card->private_data = chip;
-       err = snd_riptide_pcm(chip, 0, NULL);
+       err = snd_riptide_pcm(chip, 0);
        if (err < 0)
                goto error;
        err = snd_riptide_mixer(chip);
index 6c60dcd..23d7f5d 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -85,8 +86,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
-
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;    /* Enable this card */
@@ -632,7 +631,7 @@ snd_rme32_setframelog(struct rme32 * rme32, int n_channels, int is_playback)
        }
 }
 
-static int snd_rme32_setformat(struct rme32 * rme32, int format)
+static int snd_rme32_setformat(struct rme32 *rme32, snd_pcm_format_t format)
 {
        switch (format) {
        case SNDRV_PCM_FORMAT_S16_LE:
index 2f1a851..2306ccf 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -38,8 +39,6 @@
 #include <sound/asoundef.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
-
 /* note, two last pcis should be equal, it is not a bug */
 
 MODULE_AUTHOR("Anders Torger <torger@ludd.luth.se>");
@@ -922,8 +921,7 @@ snd_rme96_setframelog(struct rme96 *rme96,
 }
 
 static int
-snd_rme96_playback_setformat(struct rme96 *rme96,
-                            int format)
+snd_rme96_playback_setformat(struct rme96 *rme96, snd_pcm_format_t format)
 {
        switch (format) {
        case SNDRV_PCM_FORMAT_S16_LE:
@@ -940,8 +938,7 @@ snd_rme96_playback_setformat(struct rme96 *rme96,
 }
 
 static int
-snd_rme96_capture_setformat(struct rme96 *rme96,
-                           int format)
+snd_rme96_capture_setformat(struct rme96 *rme96, snd_pcm_format_t format)
 {
        switch (format) {
        case SNDRV_PCM_FORMAT_S16_LE:
@@ -2358,7 +2355,6 @@ snd_rme96_create_switches(struct snd_card *card,
 
 static int rme96_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct rme96 *rme96 = card->private_data;
 
@@ -2381,26 +2377,14 @@ static int rme96_suspend(struct device *dev)
        /* disable the DAC  */
        rme96->areg &= ~RME96_AR_DAC_EN;
        writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-
        return 0;
 }
 
 static int rme96_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct rme96 *rme96 = card->private_data;
 
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-
        /* reset playback and record buffer pointers */
        writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS
                  + rme96->playback_pointer);
index cf5a6c8..c19e021 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/math64.h>
 #include <linux/vmalloc.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -42,7 +43,6 @@
 
 #include <asm/byteorder.h>
 #include <asm/current.h>
-#include <asm/io.h>
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
@@ -1428,10 +1428,8 @@ static void snd_hdsp_midi_output_timer(unsigned long data)
           leaving istimer wherever it was set before.
        */
 
-       if (hmidi->istimer) {
-               hmidi->timer.expires = 1 + jiffies;
-               add_timer(&hmidi->timer);
-       }
+       if (hmidi->istimer)
+               mod_timer(&hmidi->timer, 1 + jiffies);
 
        spin_unlock_irqrestore (&hmidi->lock, flags);
 }
@@ -1445,11 +1443,9 @@ static void snd_hdsp_midi_output_trigger(struct snd_rawmidi_substream *substream
        spin_lock_irqsave (&hmidi->lock, flags);
        if (up) {
                if (!hmidi->istimer) {
-                       init_timer(&hmidi->timer);
-                       hmidi->timer.function = snd_hdsp_midi_output_timer;
-                       hmidi->timer.data = (unsigned long) hmidi;
-                       hmidi->timer.expires = 1 + jiffies;
-                       add_timer(&hmidi->timer);
+                       setup_timer(&hmidi->timer, snd_hdsp_midi_output_timer,
+                                   (unsigned long) hmidi);
+                       mod_timer(&hmidi->timer, 1 + jiffies);
                        hmidi->istimer++;
                }
        } else {
@@ -5309,9 +5305,7 @@ static int snd_hdsp_free(struct hdsp *hdsp)
 
        release_firmware(hdsp->firmware);
        vfree(hdsp->fw_uploaded);
-
-       if (hdsp->iobase)
-               iounmap(hdsp->iobase);
+       iounmap(hdsp->iobase);
 
        if (hdsp->port)
                pci_release_regions(hdsp->pci);
index 3342705..2c363fd 100644 (file)
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/math64.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -1957,10 +1957,8 @@ static void snd_hdspm_midi_output_timer(unsigned long data)
           leaving istimer wherever it was set before.
        */
 
-       if (hmidi->istimer) {
-               hmidi->timer.expires = 1 + jiffies;
-               add_timer(&hmidi->timer);
-       }
+       if (hmidi->istimer)
+               mod_timer(&hmidi->timer, 1 + jiffies);
 
        spin_unlock_irqrestore (&hmidi->lock, flags);
 }
@@ -1975,11 +1973,9 @@ snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
        spin_lock_irqsave (&hmidi->lock, flags);
        if (up) {
                if (!hmidi->istimer) {
-                       init_timer(&hmidi->timer);
-                       hmidi->timer.function = snd_hdspm_midi_output_timer;
-                       hmidi->timer.data = (unsigned long) hmidi;
-                       hmidi->timer.expires = 1 + jiffies;
-                       add_timer(&hmidi->timer);
+                       setup_timer(&hmidi->timer, snd_hdspm_midi_output_timer,
+                                   (unsigned long) hmidi);
+                       mod_timer(&hmidi->timer, 1 + jiffies);
                        hmidi->istimer++;
                }
        } else {
@@ -6965,9 +6961,7 @@ static int snd_hdspm_free(struct hdspm * hdspm)
                free_irq(hdspm->irq, (void *) hdspm);
 
        kfree(hdspm->mixer);
-
-       if (hdspm->iobase)
-               iounmap(hdspm->iobase);
+       iounmap(hdspm->iobase);
 
        if (hdspm->port)
                pci_release_regions(hdspm->pci);
index 6521521..fdbc0aa 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -34,7 +35,6 @@
 #include <sound/initval.h>
 
 #include <asm/current.h>
-#include <asm/io.h>
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
@@ -1756,8 +1756,7 @@ static int snd_rme9652_free(struct snd_rme9652 *rme9652)
 
        if (rme9652->irq >= 0)
                free_irq(rme9652->irq, (void *)rme9652);
-       if (rme9652->iobase)
-               iounmap(rme9652->iobase);
+       iounmap(rme9652->iobase);
        if (rme9652->port)
                pci_release_regions(rme9652->pci);
 
index 7f6a0a0..efe669b 100644 (file)
@@ -1064,12 +1064,9 @@ static int sis_chip_free(struct sis7019 *sis)
        if (sis->irq >= 0)
                free_irq(sis->irq, sis);
 
-       if (sis->ioaddr)
-               iounmap(sis->ioaddr);
-
+       iounmap(sis->ioaddr);
        pci_release_regions(sis->pci);
        pci_disable_device(sis->pci);
-
        sis_free_suspend(sis);
        return 0;
 }
@@ -1211,7 +1208,6 @@ static int sis_chip_init(struct sis7019 *sis)
 #ifdef CONFIG_PM_SLEEP
 static int sis_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct sis7019 *sis = card->private_data;
        void __iomem *ioaddr = sis->ioaddr;
@@ -1240,9 +1236,6 @@ static int sis_suspend(struct device *dev)
                ioaddr += 4096;
        }
 
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
@@ -1254,14 +1247,6 @@ static int sis_resume(struct device *dev)
        void __iomem *ioaddr = sis->ioaddr;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-
-       if (pci_enable_device(pci) < 0) {
-               dev_err(&pci->dev, "unable to re-enable device\n");
-               goto error;
-       }
-
        if (sis_chip_init(sis)) {
                dev_err(&pci->dev, "unable to re-init controller\n");
                goto error;
@@ -1284,7 +1269,6 @@ static int sis_resume(struct device *dev)
        memset(sis->suspend_state[0], 0, 4096);
 
        sis->irq = pci->irq;
-       pci_set_master(pci);
 
        if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
                snd_ac97_resume(sis->ac97[0]);
index 313a732..0f40624 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/gameport.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -39,8 +40,6 @@
 #include <sound/opl3.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
-
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("S3 SonicVibes PCI");
 MODULE_LICENSE("GPL");
@@ -880,8 +879,7 @@ static struct snd_pcm_ops snd_sonicvibes_capture_ops = {
        .pointer =      snd_sonicvibes_capture_pointer,
 };
 
-static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device,
-                             struct snd_pcm **rpcm)
+static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device)
 {
        struct snd_pcm *pcm;
        int err;
@@ -902,8 +900,6 @@ static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(sonic->pci), 64*1024, 128*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1491,7 +1487,7 @@ static int snd_sonic_probe(struct pci_dev *pci,
                (unsigned long long)pci_resource_start(pci, 1),
                sonic->irq);
 
-       if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) {
+       if ((err = snd_sonicvibes_pcm(sonic, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
index a54cd68..cedf13b 100644 (file)
@@ -127,21 +127,21 @@ static int snd_trident_probe(struct pci_dev *pci,
        sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
                card->shortname, trident->port, trident->irq);
 
-       if ((err = snd_trident_pcm(trident, pcm_dev++, NULL)) < 0) {
+       if ((err = snd_trident_pcm(trident, pcm_dev++)) < 0) {
                snd_card_free(card);
                return err;
        }
        switch (trident->device) {
        case TRIDENT_DEVICE_ID_DX:
        case TRIDENT_DEVICE_ID_NX:
-               if ((err = snd_trident_foldback_pcm(trident, pcm_dev++, NULL)) < 0) {
+               if ((err = snd_trident_foldback_pcm(trident, pcm_dev++)) < 0) {
                        snd_card_free(card);
                        return err;
                }
                break;
        }
        if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
-               if ((err = snd_trident_spdif_pcm(trident, pcm_dev++, NULL)) < 0) {
+               if ((err = snd_trident_spdif_pcm(trident, pcm_dev++)) < 0) {
                        snd_card_free(card);
                        return err;
                }
index 5f110eb..9624e59 100644 (file)
@@ -420,9 +420,9 @@ int snd_trident_create(struct snd_card *card,
                       struct snd_trident ** rtrident);
 int snd_trident_create_gameport(struct snd_trident *trident);
 
-int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
-int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
-int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_pcm(struct snd_trident *trident, int device);
+int snd_trident_foldback_pcm(struct snd_trident *trident, int device);
+int snd_trident_spdif_pcm(struct snd_trident *trident, int device);
 int snd_trident_attach_synthesizer(struct snd_trident * trident);
 struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type,
                                             int client, int port);
index 57cd757..b72be03 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/gameport.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
@@ -44,8 +45,6 @@
 #include "trident.h"
 #include <sound/asoundef.h>
 
-#include <asm/io.h>
-
 static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
                                       struct snd_trident_voice * voice,
                                       struct snd_pcm_substream *substream);
@@ -2172,14 +2171,11 @@ static struct snd_pcm_ops snd_trident_spdif_7018_ops = {
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_pcm(struct snd_trident *trident,
-                   int device, struct snd_pcm **rpcm)
+int snd_trident_pcm(struct snd_trident *trident, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, trident->ChanPCM, 1, &pcm)) < 0)
                return err;
 
@@ -2214,8 +2210,6 @@ int snd_trident_pcm(struct snd_trident *trident,
                                                      snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
        }
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -2230,16 +2224,13 @@ int snd_trident_pcm(struct snd_trident *trident,
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_foldback_pcm(struct snd_trident *trident,
-                            int device, struct snd_pcm **rpcm)
+int snd_trident_foldback_pcm(struct snd_trident *trident, int device)
 {
        struct snd_pcm *foldback;
        int err;
        int num_chan = 3;
        struct snd_pcm_substream *substream;
 
-       if (rpcm)
-               *rpcm = NULL;
        if (trident->device == TRIDENT_DEVICE_ID_NX)
                num_chan = 4;
        if ((err = snd_pcm_new(trident->card, "trident_dx_nx", device, 0, num_chan, &foldback)) < 0)
@@ -2271,8 +2262,6 @@ int snd_trident_foldback_pcm(struct snd_trident *trident,
                snd_pcm_lib_preallocate_pages_for_all(foldback, SNDRV_DMA_TYPE_DEV,
                                                      snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
 
-       if (rpcm)
-               *rpcm = foldback;
        return 0;
 }
 
@@ -2287,14 +2276,11 @@ int snd_trident_foldback_pcm(struct snd_trident *trident,
   
   ---------------------------------------------------------------------------*/
 
-int snd_trident_spdif_pcm(struct snd_trident *trident,
-                         int device, struct snd_pcm **rpcm)
+int snd_trident_spdif_pcm(struct snd_trident *trident, int device)
 {
        struct snd_pcm *spdif;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(trident->card, "trident_dx_nx IEC958", device, 1, 0, &spdif)) < 0)
                return err;
 
@@ -2310,8 +2296,6 @@ int snd_trident_spdif_pcm(struct snd_trident *trident,
 
        snd_pcm_lib_preallocate_pages_for_all(spdif, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), 64*1024, 128*1024);
 
-       if (rpcm)
-               *rpcm = spdif;
        return 0;
 }
 
@@ -3926,7 +3910,6 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
 #ifdef CONFIG_PM_SLEEP
 static int snd_trident_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_trident *trident = card->private_data;
 
@@ -3938,28 +3921,14 @@ static int snd_trident_suspend(struct device *dev)
 
        snd_ac97_suspend(trident->ac97);
        snd_ac97_suspend(trident->ac97_sec);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_trident_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_trident *trident = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        switch (trident->device) {
        case TRIDENT_DEVICE_ID_DX:
                snd_trident_4d_dx_init(trident);
index 04c4746..b9ebb51 100644 (file)
@@ -23,7 +23,7 @@
  *
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/pci.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
index e088467..8622283 100644 (file)
@@ -46,7 +46,7 @@
  *     - Optimize position calculation for the 823x chips. 
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -2271,7 +2271,6 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
  */
 static int snd_via82xx_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct via82xx *chip = card->private_data;
        int i;
@@ -2291,28 +2290,15 @@ static int snd_via82xx_suspend(struct device *dev)
                chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
        }
 
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_via82xx_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct via82xx *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_via82xx_chip_init(chip);
 
        if (chip->chip_type == TYPE_VIA686) {
index fd46ffe..99b9137 100644 (file)
@@ -31,7 +31,7 @@
  *      modems.
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -1031,7 +1031,6 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
  */
 static int snd_via82xx_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct via82xx_modem *chip = card->private_data;
        int i;
@@ -1043,29 +1042,15 @@ static int snd_via82xx_suspend(struct device *dev)
                snd_via82xx_channel_reset(chip, &chip->devs[i]);
        synchronize_irq(chip->irq);
        snd_ac97_suspend(chip->ac97);
-
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
 static int snd_via82xx_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct via82xx_modem *chip = card->private_data;
        int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
-
        snd_via82xx_chip_init(chip);
 
        snd_ac97_resume(chip->ac97);
index c5a25e3..ecbaf47 100644 (file)
@@ -259,32 +259,17 @@ static void snd_vx222_remove(struct pci_dev *pci)
 #ifdef CONFIG_PM_SLEEP
 static int snd_vx222_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_vx222 *vx = card->private_data;
-       int err;
 
-       err = snd_vx_suspend(&vx->core);
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
-       return err;
+       return snd_vx_suspend(&vx->core);
 }
 
 static int snd_vx222_resume(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_vx222 *vx = card->private_data;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        return snd_vx_resume(&vx->core);
 }
 
index 52c1a8d..af83b3b 100644 (file)
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/mutex.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tlv.h>
-#include <asm/io.h>
 #include "vx222.h"
 
 
index 47a1923..812e27a 100644 (file)
@@ -283,11 +283,11 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
                card->shortname,
                chip->reg_area_phys,
                chip->irq);
-       if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
+       if ((err = snd_ymfpci_pcm(chip, 0)) < 0) {
                snd_card_free(card);
                return err;
        }
-       if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
+       if ((err = snd_ymfpci_pcm_spdif(chip, 1)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -297,12 +297,12 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
                return err;
        }
        if (chip->ac97->ext_id & AC97_EI_SDAC) {
-               err = snd_ymfpci_pcm_4ch(chip, 2, NULL);
+               err = snd_ymfpci_pcm_4ch(chip, 2);
                if (err < 0) {
                        snd_card_free(card);
                        return err;
                }
-               err = snd_ymfpci_pcm2(chip, 3, NULL);
+               err = snd_ymfpci_pcm2(chip, 3);
                if (err < 0) {
                        snd_card_free(card);
                        return err;
index 4631a23..149d4cb 100644 (file)
@@ -379,10 +379,10 @@ void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
 
 extern const struct dev_pm_ops snd_ymfpci_pm;
 
-int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
-int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
-int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
-int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
+int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device);
+int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device);
+int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device);
+int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device);
 int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
 int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
 
index 81c916a..4c26076 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -36,7 +37,6 @@
 #include <sound/asoundef.h>
 #include <sound/mpu401.h>
 
-#include <asm/io.h>
 #include <asm/byteorder.h>
 
 /*
@@ -1145,13 +1145,11 @@ static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = {
        .pointer =              snd_ymfpci_capture_pointer,
 };
 
-int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
+int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
                return err;
        pcm->private_data = chip;
@@ -1167,14 +1165,8 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+       return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                     snd_pcm_std_chmaps, 2, 0, NULL);
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-       return 0;
 }
 
 static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {
@@ -1188,13 +1180,11 @@ static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {
        .pointer =              snd_ymfpci_capture_pointer,
 };
 
-int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
+int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
                return err;
        pcm->private_data = chip;
@@ -1210,8 +1200,6 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1226,14 +1214,11 @@ static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = {
        .pointer =              snd_ymfpci_playback_pointer,
 };
 
-int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device,
-                        struct snd_pcm **rpcm)
+int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
                return err;
        pcm->private_data = chip;
@@ -1248,8 +1233,6 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       if (rpcm)
-               *rpcm = pcm;
        return 0;
 }
 
@@ -1272,14 +1255,11 @@ static const struct snd_pcm_chmap_elem surround_map[] = {
        { }
 };
 
-int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device,
-                      struct snd_pcm **rpcm)
+int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (rpcm)
-               *rpcm = NULL;
        if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
                return err;
        pcm->private_data = chip;
@@ -1294,14 +1274,8 @@ int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device,
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                              snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
-       err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+       return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                     surround_map, 2, 0, NULL);
-       if (err < 0)
-               return err;
-
-       if (rpcm)
-               *rpcm = pcm;
-       return 0;
 }
 
 static int snd_ymfpci_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
@@ -2272,8 +2246,7 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
        release_and_free_resource(chip->mpu_res);
        release_and_free_resource(chip->fm_res);
        snd_ymfpci_free_gameport(chip);
-       if (chip->reg_area_virt)
-               iounmap(chip->reg_area_virt);
+       iounmap(chip->reg_area_virt);
        if (chip->work_ptr.area)
                snd_dma_free_pages(&chip->work_ptr);
        
@@ -2326,7 +2299,6 @@ static int saved_regs_index[] = {
 
 static int snd_ymfpci_suspend(struct device *dev)
 {
-       struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ymfpci *chip = card->private_data;
        unsigned int i;
@@ -2347,9 +2319,6 @@ static int snd_ymfpci_suspend(struct device *dev)
        snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
        snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
        snd_ymfpci_disable_dsp(chip);
-       pci_disable_device(pci);
-       pci_save_state(pci);
-       pci_set_power_state(pci, PCI_D3hot);
        return 0;
 }
 
@@ -2360,14 +2329,6 @@ static int snd_ymfpci_resume(struct device *dev)
        struct snd_ymfpci *chip = card->private_data;
        unsigned int i;
 
-       pci_set_power_state(pci, PCI_D0);
-       pci_restore_state(pci);
-       if (pci_enable_device(pci) < 0) {
-               dev_err(dev, "pci_enable_device failed, disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
-       pci_set_master(pci);
        snd_ymfpci_aclink_reset(pci);
        snd_ymfpci_codec_ready(chip, 0);
        snd_ymfpci_download_image(chip);
index 5fbf5db..09da7b5 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/nvram.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 0040f04..d3524f9 100644 (file)
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <linux/init.h>
 #include <linux/slab.h>
index cb4f0a5..b86159e 100644 (file)
@@ -19,7 +19,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <sound/core.h>
index 5a13b22..13146d7 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -867,16 +867,11 @@ static int snd_pmac_free(struct snd_pmac *chip)
        snd_pmac_dbdma_free(chip, &chip->capture.cmd);
        snd_pmac_dbdma_free(chip, &chip->extra_dma);
        snd_pmac_dbdma_free(chip, &emergency_dbdma);
-       if (chip->macio_base)
-               iounmap(chip->macio_base);
-       if (chip->latch_base)
-               iounmap(chip->latch_base);
-       if (chip->awacs)
-               iounmap(chip->awacs);
-       if (chip->playback.dma)
-               iounmap(chip->playback.dma);
-       if (chip->capture.dma)
-               iounmap(chip->capture.dma);
+       iounmap(chip->macio_base);
+       iounmap(chip->latch_base);
+       iounmap(chip->awacs);
+       iounmap(chip->playback.dma);
+       iounmap(chip->capture.dma);
 
        if (chip->node) {
                int i;
index 58f292a..3682425 100644 (file)
@@ -1044,7 +1044,7 @@ static int snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
        if (!the_card.null_buffer_start_vaddr) {
                pr_info("%s: nullbuffer alloc failed\n", __func__);
                ret = -ENOMEM;
-               goto clean_preallocate;
+               goto clean_card;
        }
        pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__,
                 the_card.null_buffer_start_vaddr,
@@ -1066,8 +1066,6 @@ clean_dma_map:
                          PAGE_SIZE,
                          the_card.null_buffer_start_vaddr,
                          the_card.null_buffer_start_dma_addr);
-clean_preallocate:
-       snd_pcm_lib_preallocate_free_for_all(the_card.pcm);
 clean_card:
        snd_card_free(the_card.card);
 clean_irq:
index 24c8766..c8fafba 100644 (file)
@@ -32,8 +32,8 @@
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/of_irq.h>
+#include <linux/io.h>
 #include <sound/core.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
index f44dda6..ad3d9ae 100644 (file)
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
+#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
 #include <sound/info.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <mach/sysasic.h>
 #include "aica.h"
@@ -343,11 +343,9 @@ static void spu_begin_dma(struct snd_pcm_substream *substream)
                mod_timer(&dreamcastcard->timer, jiffies + 4);
                return;
        }
-       init_timer(&(dreamcastcard->timer));
-       dreamcastcard->timer.data = (unsigned long) substream;
-       dreamcastcard->timer.function = aica_period_elapsed;
-       dreamcastcard->timer.expires = jiffies + 4;
-       add_timer(&(dreamcastcard->timer));
+       setup_timer(&dreamcastcard->timer, aica_period_elapsed,
+                   (unsigned long) substream);
+       mod_timer(&dreamcastcard->timer, jiffies + 4);
 }
 
 static int snd_aicapcm_pcm_open(struct snd_pcm_substream
index d0547fa..dcdfac0 100644 (file)
@@ -46,6 +46,8 @@ static int pcm512x_i2c_remove(struct i2c_client *i2c)
 static const struct i2c_device_id pcm512x_i2c_id[] = {
        { "pcm5121", },
        { "pcm5122", },
+       { "pcm5141", },
+       { "pcm5142", },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
@@ -53,6 +55,8 @@ MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
 static const struct of_device_id pcm512x_of_match[] = {
        { .compatible = "ti,pcm5121", },
        { .compatible = "ti,pcm5122", },
+       { .compatible = "ti,pcm5141", },
+       { .compatible = "ti,pcm5142", },
        { }
 };
 MODULE_DEVICE_TABLE(of, pcm512x_of_match);
index f297058..7b64a9c 100644 (file)
@@ -43,6 +43,8 @@ static int pcm512x_spi_remove(struct spi_device *spi)
 static const struct spi_device_id pcm512x_spi_id[] = {
        { "pcm5121", },
        { "pcm5122", },
+       { "pcm5141", },
+       { "pcm5142", },
        { },
 };
 MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
@@ -50,6 +52,8 @@ MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
 static const struct of_device_id pcm512x_of_match[] = {
        { .compatible = "ti,pcm5121", },
        { .compatible = "ti,pcm5122", },
+       { .compatible = "ti,pcm5141", },
+       { .compatible = "ti,pcm5142", },
        { }
 };
 MODULE_DEVICE_TABLE(of, pcm512x_of_match);
index 8a0833d..0a027bc 100644 (file)
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/spi/spi.h>
+#include <linux/dmi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -2188,6 +2190,13 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
        if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
                return 0;
 
+       if (rt5670->pdata.jd_mode) {
+               if (clk_id == RT5670_SCLK_S_PLL1)
+                       snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
+               else
+                       snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
+               snd_soc_dapm_sync(&codec->dapm);
+       }
        switch (clk_id) {
        case RT5670_SCLK_S_MCLK:
                reg_val |= RT5670_SCLK_SRC_MCLK;
@@ -2549,6 +2558,17 @@ static struct acpi_device_id rt5670_acpi_match[] = {
 MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
 #endif
 
+static const struct dmi_system_id dmi_platform_intel_braswell[] = {
+       {
+               .ident = "Intel Braswell",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"),
+               },
+       },
+       {}
+};
+
 static int rt5670_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
@@ -2568,6 +2588,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
        if (pdata)
                rt5670->pdata = *pdata;
 
+       if (dmi_check_system(dmi_platform_intel_braswell)) {
+               rt5670->pdata.dmic_en = true;
+               rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
+               rt5670->pdata.jd_mode = 1;
+       }
+
        rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
        if (IS_ERR(rt5670->regmap)) {
                ret = PTR_ERR(rt5670->regmap);
@@ -2609,6 +2635,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
        }
 
        if (rt5670->pdata.jd_mode) {
+               regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
+                                  RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
+               rt5670->sysclk = 0;
+               rt5670->sysclk_src = RT5670_SCLK_S_RCCLK;
                regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
                                   RT5670_PWR_MB, RT5670_PWR_MB);
                regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2,
@@ -2716,18 +2746,26 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 
        }
 
+       pm_runtime_enable(&i2c->dev);
+       pm_request_idle(&i2c->dev);
+
        ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
                        rt5670_dai, ARRAY_SIZE(rt5670_dai));
        if (ret < 0)
                goto err;
 
+       pm_runtime_put(&i2c->dev);
+
        return 0;
 err:
+       pm_runtime_disable(&i2c->dev);
+
        return ret;
 }
 
 static int rt5670_i2c_remove(struct i2c_client *i2c)
 {
+       pm_runtime_disable(&i2c->dev);
        snd_soc_unregister_codec(&i2c->dev);
 
        return 0;
index 918ada9..d27630a 100644 (file)
@@ -922,6 +922,97 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                return 0;
 }
 
+static int is_using_asrc(struct snd_soc_dapm_widget *source,
+                        struct snd_soc_dapm_widget *sink)
+{
+       unsigned int reg, shift, val;
+
+       if (source->reg == RT5677_ASRC_1) {
+               switch (source->shift) {
+               case 12:
+                       reg = RT5677_ASRC_4;
+                       shift = 0;
+                       break;
+               case 13:
+                       reg = RT5677_ASRC_4;
+                       shift = 4;
+                       break;
+               case 14:
+                       reg = RT5677_ASRC_4;
+                       shift = 8;
+                       break;
+               case 15:
+                       reg = RT5677_ASRC_4;
+                       shift = 12;
+                       break;
+               default:
+                       return 0;
+               }
+       } else {
+               switch (source->shift) {
+               case 0:
+                       reg = RT5677_ASRC_6;
+                       shift = 8;
+                       break;
+               case 1:
+                       reg = RT5677_ASRC_6;
+                       shift = 12;
+                       break;
+               case 2:
+                       reg = RT5677_ASRC_5;
+                       shift = 0;
+                       break;
+               case 3:
+                       reg = RT5677_ASRC_5;
+                       shift = 4;
+                       break;
+               case 4:
+                       reg = RT5677_ASRC_5;
+                       shift = 8;
+                       break;
+               case 5:
+                       reg = RT5677_ASRC_5;
+                       shift = 12;
+                       break;
+               case 12:
+                       reg = RT5677_ASRC_3;
+                       shift = 0;
+                       break;
+               case 13:
+                       reg = RT5677_ASRC_3;
+                       shift = 4;
+                       break;
+               case 14:
+                       reg = RT5677_ASRC_3;
+                       shift = 12;
+                       break;
+               default:
+                       return 0;
+               }
+       }
+
+       val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
+       switch (val) {
+       case 1 ... 6:
+               return 1;
+       default:
+               return 0;
+       }
+
+}
+
+static int can_use_asrc(struct snd_soc_dapm_widget *source,
+                        struct snd_soc_dapm_widget *sink)
+{
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+       if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384)
+               return 1;
+
+       return 0;
+}
+
 /* Digital Mixer */
 static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
        SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
@@ -2226,6 +2317,45 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
                0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU |
                SND_SOC_DAPM_POST_PMU),
 
+       /* ASRC */
+       SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5677_ASRC_1, 0, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO3 L ASRC", 1, RT5677_ASRC_1, 15, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO3 R ASRC", 1, RT5677_ASRC_1, 14, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO4 L ASRC", 1, RT5677_ASRC_1, 13, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DAC MONO4 R ASRC", 1, RT5677_ASRC_1, 12, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5677_ASRC_2, 11, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5677_ASRC_2, 10, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC STO3 ASRC", 1, RT5677_ASRC_2, 9, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC STO4 ASRC", 1, RT5677_ASRC_2, 8, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5677_ASRC_2, 7, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5677_ASRC_2, 6, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5677_ASRC_2, 5, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5677_ASRC_2, 4, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("ADC STO3 ASRC", 1, RT5677_ASRC_2, 3, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("ADC STO4 ASRC", 1, RT5677_ASRC_2, 2, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5677_ASRC_2, 1, 0, NULL,
+               0),
+       SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5677_ASRC_2, 0, 0, NULL,
+               0),
+
        /* Input Side */
        /* micbias */
        SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5677_PWR_ANLG2, RT5677_PWR_MB1_BIT,
@@ -2656,10 +2786,18 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
        /* DAC Mixer */
        SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2,
                RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("dac mono left filter", RT5677_PWR_DIG2,
+       SND_SOC_DAPM_SUPPLY("dac mono2 left filter", RT5677_PWR_DIG2,
                RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("dac mono right filter", RT5677_PWR_DIG2,
+       SND_SOC_DAPM_SUPPLY("dac mono2 right filter", RT5677_PWR_DIG2,
                RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("dac mono3 left filter", RT5677_PWR_DIG2,
+               RT5677_PWR_DAC_M3F_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("dac mono3 right filter", RT5677_PWR_DIG2,
+               RT5677_PWR_DAC_M3F_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("dac mono4 left filter", RT5677_PWR_DIG2,
+               RT5677_PWR_DAC_M4F_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("dac mono4 right filter", RT5677_PWR_DIG2,
+               RT5677_PWR_DAC_M4F_R_BIT, 0, NULL, 0),
 
        SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
                rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)),
@@ -2732,6 +2870,31 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
+       { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc },
+       { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc },
+       { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc },
+       { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc },
+       { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc },
+       { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc },
+       { "I2S1", NULL, "I2S1 ASRC", can_use_asrc},
+       { "I2S2", NULL, "I2S2 ASRC", can_use_asrc},
+       { "I2S3", NULL, "I2S3 ASRC", can_use_asrc},
+       { "I2S4", NULL, "I2S4 ASRC", can_use_asrc},
+
+       { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc },
+       { "dac mono2 left filter", NULL, "DAC MONO2 L ASRC", is_using_asrc },
+       { "dac mono2 right filter", NULL, "DAC MONO2 R ASRC", is_using_asrc },
+       { "dac mono3 left filter", NULL, "DAC MONO3 L ASRC", is_using_asrc },
+       { "dac mono3 right filter", NULL, "DAC MONO3 R ASRC", is_using_asrc },
+       { "dac mono4 left filter", NULL, "DAC MONO4 L ASRC", is_using_asrc },
+       { "dac mono4 right filter", NULL, "DAC MONO4 R ASRC", is_using_asrc },
+       { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
+       { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
+       { "adc stereo3 filter", NULL, "ADC STO3 ASRC", is_using_asrc },
+       { "adc stereo4 filter", NULL, "ADC STO4 ASRC", is_using_asrc },
+       { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc },
+       { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc },
+
        { "DMIC1", NULL, "DMIC L1" },
        { "DMIC1", NULL, "DMIC R1" },
        { "DMIC2", NULL, "DMIC L2" },
@@ -2862,8 +3025,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 
        { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
        { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
-       { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
-
        { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
        { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
        { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
@@ -2884,8 +3045,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 
        { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
        { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" },
-       { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll },
-
        { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
        { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" },
        { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll },
@@ -2900,8 +3059,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 
        { "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" },
        { "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" },
-       { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll },
-
        { "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" },
        { "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" },
        { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll },
@@ -2916,8 +3073,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 
        { "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" },
        { "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" },
-       { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll },
-
        { "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" },
        { "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" },
        { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll },
@@ -3466,10 +3621,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 
        { "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" },
        { "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" },
-       { "DAC1 MIXL", NULL, "dac stereo1 filter" },
        { "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" },
        { "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" },
-       { "DAC1 MIXR", NULL, "dac stereo1 filter" },
 
        { "DAC1 FS", NULL, "DAC1 MIXL" },
        { "DAC1 FS", NULL, "DAC1 MIXR" },
@@ -3536,35 +3689,46 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
        { "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" },
        { "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" },
        { "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
+       { "dac stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" },
        { "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" },
        { "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" },
        { "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" },
-       { "Mono DAC MIXL", NULL, "dac mono left filter" },
+       { "Mono DAC MIXL", NULL, "dac mono2 left filter" },
+       { "dac mono2 left filter", NULL, "PLL1", is_sys_clk_from_pll },
        { "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" },
        { "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" },
        { "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" },
        { "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" },
-       { "Mono DAC MIXR", NULL, "dac mono right filter" },
+       { "Mono DAC MIXR", NULL, "dac mono2 right filter" },
+       { "dac mono2 right filter", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
        { "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" },
        { "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" },
        { "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" },
+       { "DD1 MIXL", NULL, "dac mono3 left filter" },
+       { "dac mono3 left filter", NULL, "PLL1", is_sys_clk_from_pll },
        { "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
        { "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" },
        { "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" },
        { "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" },
+       { "DD1 MIXR", NULL, "dac mono3 right filter" },
+       { "dac mono3 right filter", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
        { "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" },
        { "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" },
        { "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" },
+       { "DD2 MIXL", NULL, "dac mono4 left filter" },
+       { "dac mono4 left filter", NULL, "PLL1", is_sys_clk_from_pll },
        { "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
        { "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" },
        { "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" },
        { "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" },
+       { "DD2 MIXR", NULL, "dac mono4 right filter" },
+       { "dac mono4 right filter", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "Stereo DAC MIX", NULL, "Stereo DAC MIXL" },
        { "Stereo DAC MIX", NULL, "Stereo DAC MIXR" },
@@ -3586,11 +3750,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
        { "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" },
 
        { "DAC 1", NULL, "DAC12 SRC Mux" },
-       { "DAC 1", NULL, "PLL1", is_sys_clk_from_pll },
        { "DAC 2", NULL, "DAC12 SRC Mux" },
-       { "DAC 2", NULL, "PLL1", is_sys_clk_from_pll },
        { "DAC 3", NULL, "DAC3 SRC Mux" },
-       { "DAC 3", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" },
        { "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" },
index f6847fd..eb0a164 100644 (file)
@@ -323,7 +323,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
        SND_SOC_DAPM_OUTPUT("ROUT2"),
        SND_SOC_DAPM_OUTPUT("MONO1"),
        SND_SOC_DAPM_OUTPUT("OUT3"),
-       SND_SOC_DAPM_OUTPUT("VREF"),
+       SND_SOC_DAPM_VMID("VREF"),
 
        SND_SOC_DAPM_INPUT("LINPUT1"),
        SND_SOC_DAPM_INPUT("LINPUT2"),
index 8d18bbd..06d3a34 100644 (file)
@@ -335,13 +335,47 @@ static int dw_i2s_resume(struct snd_soc_dai *dai)
 #define dw_i2s_resume  NULL
 #endif
 
+static void dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
+                                  struct snd_soc_dai_driver *dw_i2s_dai,
+                                  struct resource *res,
+                                  const struct i2s_platform_data *pdata)
+{
+       /* Set DMA slaves info */
+
+       dev->play_dma_data.data = pdata->play_dma_data;
+       dev->capture_dma_data.data = pdata->capture_dma_data;
+       dev->play_dma_data.addr = res->start + I2S_TXDMA;
+       dev->capture_dma_data.addr = res->start + I2S_RXDMA;
+       dev->play_dma_data.max_burst = 16;
+       dev->capture_dma_data.max_burst = 16;
+       dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+       dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+       dev->play_dma_data.filter = pdata->filter;
+       dev->capture_dma_data.filter = pdata->filter;
+
+       if (pdata->cap & DWC_I2S_PLAY) {
+               dev_dbg(dev->dev, " designware: play supported\n");
+               dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
+               dw_i2s_dai->playback.channels_max = pdata->channel;
+               dw_i2s_dai->playback.formats = pdata->snd_fmts;
+               dw_i2s_dai->playback.rates = pdata->snd_rates;
+       }
+
+       if (pdata->cap & DWC_I2S_RECORD) {
+               dev_dbg(dev->dev, "designware: record supported\n");
+               dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
+               dw_i2s_dai->capture.channels_max = pdata->channel;
+               dw_i2s_dai->capture.formats = pdata->snd_fmts;
+               dw_i2s_dai->capture.rates = pdata->snd_rates;
+       }
+}
+
 static int dw_i2s_probe(struct platform_device *pdev)
 {
        const struct i2s_platform_data *pdata = pdev->dev.platform_data;
        struct dw_i2s_dev *dev;
        struct resource *res;
        int ret;
-       unsigned int cap;
        struct snd_soc_dai_driver *dw_i2s_dai;
 
        if (!pdata) {
@@ -356,44 +390,23 @@ static int dw_i2s_probe(struct platform_device *pdev)
        }
 
        dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
-       if (!dw_i2s_dai) {
-               dev_err(&pdev->dev, "mem allocation failed for dai driver\n");
+       if (!dw_i2s_dai)
                return -ENOMEM;
-       }
 
        dw_i2s_dai->ops = &dw_i2s_dai_ops;
        dw_i2s_dai->suspend = dw_i2s_suspend;
        dw_i2s_dai->resume = dw_i2s_resume;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "no i2s resource defined\n");
-               return -ENODEV;
-       }
-
        dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(dev->i2s_base)) {
-               dev_err(&pdev->dev, "ioremap fail for i2s_region\n");
+       if (IS_ERR(dev->i2s_base))
                return PTR_ERR(dev->i2s_base);
-       }
-
-       cap = pdata->cap;
-       dev->capability = cap;
-       dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
-
-       /* Set DMA slaves info */
 
-       dev->play_dma_data.data = pdata->play_dma_data;
-       dev->capture_dma_data.data = pdata->capture_dma_data;
-       dev->play_dma_data.addr = res->start + I2S_TXDMA;
-       dev->capture_dma_data.addr = res->start + I2S_RXDMA;
-       dev->play_dma_data.max_burst = 16;
-       dev->capture_dma_data.max_burst = 16;
-       dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-       dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-       dev->play_dma_data.filter = pdata->filter;
-       dev->capture_dma_data.filter = pdata->filter;
+       dev->dev = &pdev->dev;
+       dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
 
+       dev->capability = pdata->cap;
+       dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
        dev->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(dev->clk))
                return  PTR_ERR(dev->clk);
@@ -402,23 +415,6 @@ static int dw_i2s_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_clk_put;
 
-       if (cap & DWC_I2S_PLAY) {
-               dev_dbg(&pdev->dev, " designware: play supported\n");
-               dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
-               dw_i2s_dai->playback.channels_max = pdata->channel;
-               dw_i2s_dai->playback.formats = pdata->snd_fmts;
-               dw_i2s_dai->playback.rates = pdata->snd_rates;
-       }
-
-       if (cap & DWC_I2S_RECORD) {
-               dev_dbg(&pdev->dev, "designware: record supported\n");
-               dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
-               dw_i2s_dai->capture.channels_max = pdata->channel;
-               dw_i2s_dai->capture.formats = pdata->snd_fmts;
-               dw_i2s_dai->capture.rates = pdata->snd_rates;
-       }
-
-       dev->dev = &pdev->dev;
        dev_set_drvdata(&pdev->dev, dev);
        ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component,
                                         dw_i2s_dai, 1);
index f86de12..c0813f5 100644 (file)
@@ -46,7 +46,7 @@ config SND_SOC_INTEL_BAYTRAIL
 
 config SND_SOC_INTEL_HASWELL_MACH
        tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
-       depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\
+       depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \
                   I2C_DESIGNWARE_PLATFORM
        select SND_SOC_INTEL_HASWELL
        select SND_SOC_RT5640
@@ -76,7 +76,7 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
 
 config SND_SOC_INTEL_BROADWELL_MACH
        tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
-       depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\
+       depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \
                   I2C_DESIGNWARE_PLATFORM
        select SND_SOC_INTEL_HASWELL
        select SND_COMPRESS_OFFLOAD
index eef0c56..5930862 100644 (file)
@@ -215,7 +215,6 @@ static int snd_byt_mc_probe(struct platform_device *pdev)
 
 static struct platform_driver snd_byt_mc_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "bytt100_rt5640",
                .pm = &snd_soc_pm_ops,
        },
index 9b8b561..a406c61 100644 (file)
@@ -270,7 +270,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
 
 static struct platform_driver snd_cht_mc_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "cht-bsw-rt5672",
                .pm = &snd_soc_pm_ops,
        },
index b3f9489..a2ae2c5 100644 (file)
@@ -497,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw,
        sst_module->sst_fw = sst_fw;
        sst_module->scratch_size = template->scratch_size;
        sst_module->persistent_size = template->persistent_size;
+       sst_module->entry = template->entry;
 
        INIT_LIST_HEAD(&sst_module->block_list);
        INIT_LIST_HEAD(&sst_module->runtime_list);
index 2ac72eb..c3fbcde 100644 (file)
@@ -245,7 +245,7 @@ static struct sst_machines *sst_acpi_find_machine(
        return NULL;
 }
 
-int sst_acpi_probe(struct platform_device *pdev)
+static int sst_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        int ret = 0;
@@ -332,7 +332,7 @@ do_sst_cleanup:
 * This function is called by OS when a device is unloaded
 * This frees the interrupt etc
 */
-int sst_acpi_remove(struct platform_device *pdev)
+static int sst_acpi_remove(struct platform_device *pdev)
 {
        struct intel_sst_drv *ctx;
 
@@ -366,7 +366,6 @@ MODULE_DEVICE_TABLE(acpi, sst_acpi_ids);
 static struct platform_driver sst_acpi_driver = {
        .driver = {
                .name                   = "intel_sst_acpi",
-               .owner                  = THIS_MODULE,
                .acpi_match_table       = ACPI_PTR(sst_acpi_ids),
                .pm                     = &intel_sst_pm,
        },
index 3f9ac7d..ccfb41c 100644 (file)
@@ -393,7 +393,6 @@ static int omap_hdmi_audio_remove(struct platform_device *pdev)
 static struct platform_driver hdmi_audio_driver = {
        .driver = {
                .name = DRV_NAME,
-               .owner = THIS_MODULE,
        },
        .probe = omap_hdmi_audio_probe,
        .remove = omap_hdmi_audio_remove,
index d7d5fb2..a6d680a 100644 (file)
@@ -352,7 +352,6 @@ static int spitz_remove(struct platform_device *pdev)
 static struct platform_driver spitz_driver = {
        .driver         = {
                .name   = "spitz-audio",
-               .owner  = THIS_MODULE,
                .pm     = &snd_soc_pm_ops,
        },
        .probe          = spitz_probe,
index dcc26ed..acb5be5 100644 (file)
@@ -247,6 +247,10 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
 
        regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val);
        regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val);
+       regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
+                          I2S_DMACR_TDL(16));
+       regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
+                          I2S_DMACR_RDL(16));
 
        return 0;
 }
index 1e2b61c..8bf2e2c 100644 (file)
@@ -135,7 +135,6 @@ MODULE_DEVICE_TABLE(of, samsung_arndale_rt5631_of_match);
 static struct platform_driver arndale_audio_driver = {
        .driver = {
                .name   = "arndale-audio",
-               .owner  = THIS_MODULE,
                .pm = &snd_soc_pm_ops,
                .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match),
        },
index 2c62620..c024962 100644 (file)
@@ -1626,9 +1626,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
                }
        }
 
-       if (card->fully_routed)
-               snd_soc_dapm_auto_nc_pins(card);
-
        snd_soc_dapm_new_widgets(card);
 
        ret = snd_card_register(card->snd_card);
index c5136bb..ea49684 100644 (file)
@@ -2279,6 +2279,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
 
        switch (w->id) {
        case snd_soc_dapm_input:
+               /* On a fully routed card a input is never a source */
+               if (w->dapm->card->fully_routed)
+                       break;
                w->is_source = 1;
                list_for_each_entry(p, &w->sources, list_sink) {
                        if (p->source->id == snd_soc_dapm_micbias ||
@@ -2291,6 +2294,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
                }
                break;
        case snd_soc_dapm_output:
+               /* On a fully routed card a output is never a sink */
+               if (w->dapm->card->fully_routed)
+                       break;
                w->is_sink = 1;
                list_for_each_entry(p, &w->sinks, list_source) {
                        if (p->sink->id == snd_soc_dapm_spk ||
@@ -3085,16 +3091,24 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 
        switch (w->id) {
        case snd_soc_dapm_mic:
-       case snd_soc_dapm_input:
                w->is_source = 1;
                w->power_check = dapm_generic_check_power;
                break;
+       case snd_soc_dapm_input:
+               if (!dapm->card->fully_routed)
+                       w->is_source = 1;
+               w->power_check = dapm_generic_check_power;
+               break;
        case snd_soc_dapm_spk:
        case snd_soc_dapm_hp:
-       case snd_soc_dapm_output:
                w->is_sink = 1;
                w->power_check = dapm_generic_check_power;
                break;
+       case snd_soc_dapm_output:
+               if (!dapm->card->fully_routed)
+                       w->is_sink = 1;
+               w->power_check = dapm_generic_check_power;
+               break;
        case snd_soc_dapm_vmid:
        case snd_soc_dapm_siggen:
                w->is_source = 1;
@@ -3808,93 +3822,6 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
 
-/**
- * dapm_is_external_path() - Checks if a path is a external path
- * @card: The card the path belongs to
- * @path: The path to check
- *
- * Returns true if the path is either between two different DAPM contexts or
- * between two external pins of the same DAPM context. Otherwise returns
- * false.
- */
-static bool dapm_is_external_path(struct snd_soc_card *card,
-       struct snd_soc_dapm_path *path)
-{
-       dev_dbg(card->dev,
-               "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
-               path->source->name, path->source->id, path->source->dapm,
-               path->sink->name, path->sink->id, path->sink->dapm);
-
-       /* Connection between two different DAPM contexts */
-       if (path->source->dapm != path->sink->dapm)
-               return true;
-
-       /* Loopback connection from external pin to external pin */
-       if (path->sink->id == snd_soc_dapm_input) {
-               switch (path->source->id) {
-               case snd_soc_dapm_output:
-               case snd_soc_dapm_micbias:
-                       return true;
-               default:
-                       break;
-               }
-       }
-
-       return false;
-}
-
-static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
-                                             struct snd_soc_dapm_widget *w)
-{
-       struct snd_soc_dapm_path *p;
-
-       list_for_each_entry(p, &w->sources, list_sink) {
-               if (dapm_is_external_path(card, p))
-                       return true;
-       }
-
-       list_for_each_entry(p, &w->sinks, list_source) {
-               if (dapm_is_external_path(card, p))
-                       return true;
-       }
-
-       return false;
-}
-
-/**
- * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins
- * @card: The card whose pins should be processed
- *
- * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card
- * which are unused. Pins are used if they are connected externally to a
- * component, whether that be to some other device, or a loop-back connection to
- * the component itself.
- */
-void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card)
-{
-       struct snd_soc_dapm_widget *w;
-
-       dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm);
-
-       list_for_each_entry(w, &card->widgets, list) {
-               switch (w->id) {
-               case snd_soc_dapm_input:
-               case snd_soc_dapm_output:
-               case snd_soc_dapm_micbias:
-                       dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n",
-                               w->name);
-                       if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
-                               dev_dbg(card->dev,
-                                       "... Not in map; disabling\n");
-                               snd_soc_dapm_nc_pin(w->dapm, w->name);
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
 /**
  * snd_soc_dapm_free - free dapm resources
  * @dapm: DAPM context
index eb87d96..6b0136e 100644 (file)
@@ -301,34 +301,18 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream)
        return symmetry;
 }
 
-/*
- * List of sample sizes that might go over the bus for parameter
- * application.  There ought to be a wildcard sample size for things
- * like the DAC/ADC resolution to use but there isn't right now.
- */
-static int sample_sizes[] = {
-       24, 32,
-};
-
 static void soc_pcm_set_msb(struct snd_pcm_substream *substream, int bits)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int ret, i;
+       int ret;
 
        if (!bits)
                return;
 
-       for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) {
-               if (bits >= sample_sizes[i])
-                       continue;
-
-               ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
-                                                  sample_sizes[i], bits);
-               if (ret != 0)
-                       dev_warn(rtd->dev,
-                                "ASoC: Failed to set MSB %d/%d: %d\n",
-                                bits, sample_sizes[i], ret);
-       }
+       ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 0, bits);
+       if (ret != 0)
+               dev_warn(rtd->dev, "ASoC: Failed to set MSB %d: %d\n",
+                                bits, ret);
 }
 
 static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
@@ -746,7 +730,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
                                                              codec_dai);
                        if (ret < 0) {
                                dev_err(codec_dai->dev,
-                                       "ASoC: DAI prepare error: %d\n", ret);
+                                       "ASoC: codec DAI prepare error: %d\n",
+                                       ret);
                                goto out;
                        }
                }
@@ -755,8 +740,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
        if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) {
                ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
                if (ret < 0) {
-                       dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n",
-                               ret);
+                       dev_err(cpu_dai->dev,
+                               "ASoC: cpu DAI prepare error: %d\n", ret);
                        goto out;
                }
        }
index 86280d6..1b1a89e 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/moduleparam.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/io.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -44,7 +45,6 @@
 #include <sound/control.h>
 #include <sound/initval.h>
 
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
 
index 9352207..4919532 100644 (file)
@@ -53,9 +53,7 @@ int snd_emux_new(struct snd_emux **remu)
        emu->max_voices = 0;
        emu->use_time = 0;
 
-       init_timer(&emu->tlist);
-       emu->tlist.function = snd_emux_timer_callback;
-       emu->tlist.data = (unsigned long)emu;
+       setup_timer(&emu->tlist, snd_emux_timer_callback, (unsigned long)emu);
        emu->timer_active = 0;
 
        *remu = emu;
@@ -160,12 +158,8 @@ int snd_emux_free(struct snd_emux *emu)
        snd_emux_detach_seq_oss(emu);
 #endif
        snd_emux_detach_seq(emu);
-
        snd_emux_delete_hwdep(emu);
-
-       if (emu->sflist)
-               snd_sf_free(emu->sflist);
-
+       snd_sf_free(emu->sflist);
        kfree(emu->voices);
        kfree(emu->name);
        kfree(emu);
index 5ae1eae..e557946 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <sound/core.h>
 #include <sound/hwdep.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "emux_voice.h"
 
 
index 319754c..ab37add 100644 (file)
@@ -26,7 +26,7 @@
 #ifdef CONFIG_SND_SEQUENCER_OSS
 
 #include <linux/export.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <sound/core.h>
 #include "emux_voice.h"
 #include <sound/asoundef.h>
index 9a38de4..599551b 100644 (file)
@@ -186,8 +186,7 @@ snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
                                 */
                                vp->state = SNDRV_EMUX_ST_PENDING;
                                if (! emu->timer_active) {
-                                       emu->tlist.expires = jiffies + 1;
-                                       add_timer(&emu->tlist);
+                                       mod_timer(&emu->tlist, jiffies + 1);
                                        emu->timer_active = 1;
                                }
                        } else
@@ -223,8 +222,7 @@ void snd_emux_timer_callback(unsigned long data)
                }
        }
        if (do_again) {
-               emu->tlist.expires = jiffies + 1;
-               add_timer(&emu->tlist);
+               mod_timer(&emu->tlist, jiffies + 1);
                emu->timer_active = 1;
        } else
                emu->timer_active = 0;
index 78683b2..31a4ea9 100644 (file)
@@ -25,7 +25,7 @@
  * of doing things so that the old sfxload utility can be used.
  * Everything may change when there is an alsa way of doing things.
  */
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/export.h>
 #include <sound/core.h>
index d393153..a452ad7 100644 (file)
@@ -160,5 +160,7 @@ config SND_BCD2000
          To compile this driver as a module, choose M here: the module
          will be called snd-bcd2000.
 
+source "sound/usb/line6/Kconfig"
+
 endif  # SND_USB
 
index bcee406..2d2d122 100644 (file)
@@ -25,3 +25,4 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
 obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
 
 obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/
+obj-$(CONFIG_SND_USB_LINE6)    += line6/
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
new file mode 100644 (file)
index 0000000..f4585d3
--- /dev/null
@@ -0,0 +1,42 @@
+config SND_USB_LINE6
+       tristate
+       select SND_RAWMIDI
+       select SND_PCM
+
+config SND_USB_POD
+       tristate "Line 6 POD USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for PODxt and other similar devices,
+         supporting the following features:
+           * Reading/writing individual parameters
+           * Reading/writing complete channel, effects setup, and amp
+             setup data
+           * Channel switching
+           * Virtual MIDI interface
+           * Tuner access
+           * Playback/capture/mixer device for any ALSA-compatible PCM
+             audio application
+           * Signal routing (record clean/processed guitar signal,
+             re-amping)
+
+config SND_USB_PODHD
+       tristate "Line 6 POD HD300/400/500 USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for POD HD300, 400 and 500 devices.
+
+config SND_USB_TONEPORT
+       tristate "TonePort GX, UX1 and UX2 USB support"
+       select SND_USB_LINE6
+       select NEW_LEDS
+       select LEDS_CLASS
+       help
+         This is a driver for TonePort GX, UX1 and UX2 devices.
+
+config SND_USB_VARIAX
+       tristate "Variax Workbench USB support"
+       select SND_USB_LINE6
+       help
+         This is a driver for Variax Workbench device.
+
diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile
new file mode 100644 (file)
index 0000000..b8b3b2a
--- /dev/null
@@ -0,0 +1,18 @@
+snd-usb-line6-y :=             \
+               capture.o       \
+               driver.o        \
+               midi.o          \
+               midibuf.o       \
+               pcm.o           \
+               playback.o
+
+snd-usb-pod-y := pod.o
+snd-usb-podhd-y := podhd.o
+snd-usb-toneport-y := toneport.o
+snd-usb-variax-y := variax.o
+
+obj-$(CONFIG_SND_USB_LINE6)    += snd-usb-line6.o
+obj-$(CONFIG_SND_USB_POD)      += snd-usb-pod.o
+obj-$(CONFIG_SND_USB_PODHD)    += snd-usb-podhd.o
+obj-$(CONFIG_SND_USB_TONEPORT) += snd-usb-toneport.o
+obj-$(CONFIG_SND_USB_VARIAX)   += snd-usb-variax.o
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
new file mode 100644 (file)
index 0000000..4183c5f
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "pcm.h"
+
+/*
+       Find a free URB and submit it.
+       must be called in line6pcm->in.lock context
+*/
+static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
+{
+       int index;
+       int i, urb_size;
+       int ret;
+       struct urb *urb_in;
+
+       index =
+           find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS);
+
+       if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+               dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
+               return -EINVAL;
+       }
+
+       urb_in = line6pcm->in.urbs[index];
+       urb_size = 0;
+
+       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+               struct usb_iso_packet_descriptor *fin =
+                   &urb_in->iso_frame_desc[i];
+               fin->offset = urb_size;
+               fin->length = line6pcm->max_packet_size;
+               urb_size += line6pcm->max_packet_size;
+       }
+
+       urb_in->transfer_buffer =
+           line6pcm->in.buffer +
+           index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+       urb_in->transfer_buffer_length = urb_size;
+       urb_in->context = line6pcm;
+
+       ret = usb_submit_urb(urb_in, GFP_ATOMIC);
+
+       if (ret == 0)
+               set_bit(index, &line6pcm->in.active_urbs);
+       else
+               dev_err(line6pcm->line6->ifcdev,
+                       "URB in #%d submission failed (%d)\n", index, ret);
+
+       return 0;
+}
+
+/*
+       Submit all currently available capture URBs.
+       must be called in line6pcm->in.lock context
+*/
+int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
+{
+       int ret = 0, i;
+
+       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+               ret = submit_audio_in_urb(line6pcm);
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
+}
+
+/*
+       Copy data into ALSA capture buffer.
+*/
+void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
+{
+       struct snd_pcm_substream *substream =
+           get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+       int frames = fsize / bytes_per_frame;
+
+       if (runtime == NULL)
+               return;
+
+       if (line6pcm->in.pos_done + frames > runtime->buffer_size) {
+               /*
+                  The transferred area goes over buffer boundary,
+                  copy two separate chunks.
+                */
+               int len;
+
+               len = runtime->buffer_size - line6pcm->in.pos_done;
+
+               if (len > 0) {
+                       memcpy(runtime->dma_area +
+                              line6pcm->in.pos_done * bytes_per_frame, fbuf,
+                              len * bytes_per_frame);
+                       memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
+                              (frames - len) * bytes_per_frame);
+               } else {
+                       /* this is somewhat paranoid */
+                       dev_err(line6pcm->line6->ifcdev,
+                               "driver bug: len = %d\n", len);
+               }
+       } else {
+               /* copy single chunk */
+               memcpy(runtime->dma_area +
+                      line6pcm->in.pos_done * bytes_per_frame, fbuf, fsize);
+       }
+
+       line6pcm->in.pos_done += frames;
+       if (line6pcm->in.pos_done >= runtime->buffer_size)
+               line6pcm->in.pos_done -= runtime->buffer_size;
+}
+
+void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
+{
+       struct snd_pcm_substream *substream =
+           get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
+
+       line6pcm->in.bytes += length;
+       if (line6pcm->in.bytes >= line6pcm->in.period) {
+               line6pcm->in.bytes %= line6pcm->in.period;
+               spin_unlock(&line6pcm->in.lock);
+               snd_pcm_period_elapsed(substream);
+               spin_lock(&line6pcm->in.lock);
+       }
+}
+
+/*
+ * Callback for completed capture URB.
+ */
+static void audio_in_callback(struct urb *urb)
+{
+       int i, index, length = 0, shutdown = 0;
+       unsigned long flags;
+
+       struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
+
+       line6pcm->in.last_frame = urb->start_frame;
+
+       /* find index of URB */
+       for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
+               if (urb == line6pcm->in.urbs[index])
+                       break;
+
+       spin_lock_irqsave(&line6pcm->in.lock, flags);
+
+       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+               char *fbuf;
+               int fsize;
+               struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
+
+               if (fin->status == -EXDEV) {
+                       shutdown = 1;
+                       break;
+               }
+
+               fbuf = urb->transfer_buffer + fin->offset;
+               fsize = fin->actual_length;
+
+               if (fsize > line6pcm->max_packet_size) {
+                       dev_err(line6pcm->line6->ifcdev,
+                               "driver and/or device bug: packet too large (%d > %d)\n",
+                               fsize, line6pcm->max_packet_size);
+               }
+
+               length += fsize;
+
+               /* the following assumes LINE6_ISO_PACKETS == 1: */
+               line6pcm->prev_fbuf = fbuf;
+               line6pcm->prev_fsize = fsize;
+
+               if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) &&
+                   test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) &&
+                   fsize > 0)
+                       line6_capture_copy(line6pcm, fbuf, fsize);
+       }
+
+       clear_bit(index, &line6pcm->in.active_urbs);
+
+       if (test_and_clear_bit(index, &line6pcm->in.unlink_urbs))
+               shutdown = 1;
+
+       if (!shutdown) {
+               submit_audio_in_urb(line6pcm);
+
+               if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) &&
+                   test_bit(LINE6_STREAM_PCM, &line6pcm->in.running))
+                       line6_capture_check_period(line6pcm, length);
+       }
+
+       spin_unlock_irqrestore(&line6pcm->in.lock, flags);
+}
+
+/* open capture callback */
+static int snd_line6_capture_open(struct snd_pcm_substream *substream)
+{
+       int err;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+       err = snd_pcm_hw_constraint_ratdens(runtime, 0,
+                                           SNDRV_PCM_HW_PARAM_RATE,
+                                           (&line6pcm->
+                                            properties->snd_line6_rates));
+       if (err < 0)
+               return err;
+
+       runtime->hw = line6pcm->properties->snd_line6_capture_hw;
+       return 0;
+}
+
+/* close capture callback */
+static int snd_line6_capture_close(struct snd_pcm_substream *substream)
+{
+       return 0;
+}
+
+/* capture operators */
+struct snd_pcm_ops snd_line6_capture_ops = {
+       .open = snd_line6_capture_open,
+       .close = snd_line6_capture_close,
+       .ioctl = snd_pcm_lib_ioctl,
+       .hw_params = snd_line6_hw_params,
+       .hw_free = snd_line6_hw_free,
+       .prepare = snd_line6_prepare,
+       .trigger = snd_line6_trigger,
+       .pointer = snd_line6_pointer,
+};
+
+int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+       struct usb_line6 *line6 = line6pcm->line6;
+       int i;
+
+       /* create audio URBs and fill in constant values: */
+       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+               struct urb *urb;
+
+               /* URB for audio in: */
+               urb = line6pcm->in.urbs[i] =
+                   usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+               if (urb == NULL)
+                       return -ENOMEM;
+
+               urb->dev = line6->usbdev;
+               urb->pipe =
+                   usb_rcvisocpipe(line6->usbdev,
+                                   line6->properties->ep_audio_r &
+                                   USB_ENDPOINT_NUMBER_MASK);
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->start_frame = -1;
+               urb->number_of_packets = LINE6_ISO_PACKETS;
+               urb->interval = LINE6_ISO_INTERVAL;
+               urb->error_count = 0;
+               urb->complete = audio_in_callback;
+       }
+
+       return 0;
+}
diff --git a/sound/usb/line6/capture.h b/sound/usb/line6/capture.h
new file mode 100644 (file)
index 0000000..890b21b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "pcm.h"
+
+extern struct snd_pcm_ops snd_line6_capture_ops;
+
+extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
+                              int fsize);
+extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
+                                      int length);
+extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
+
+#endif
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
new file mode 100644 (file)
index 0000000..a043699
--- /dev/null
@@ -0,0 +1,644 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "midi.h"
+#include "playback.h"
+#include "revision.h"
+#include "usbdefs.h"
+
+#define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
+#define DRIVER_DESC    "Line 6 USB Driver"
+
+/*
+       This is Line 6's MIDI manufacturer ID.
+*/
+const unsigned char line6_midi_id[] = {
+       0x00, 0x01, 0x0c
+};
+EXPORT_SYMBOL_GPL(line6_midi_id);
+
+/*
+       Code to request version of POD, Variax interface
+       (and maybe other devices).
+*/
+static const char line6_request_version[] = {
+       0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
+};
+
+/**
+        Class for asynchronous messages.
+*/
+struct message {
+       struct usb_line6 *line6;
+       const char *buffer;
+       int size;
+       int done;
+};
+
+/*
+       Forward declarations.
+*/
+static void line6_data_received(struct urb *urb);
+static int line6_send_raw_message_async_part(struct message *msg,
+                                            struct urb *urb);
+
+/*
+       Start to listen on endpoint.
+*/
+static int line6_start_listen(struct usb_line6 *line6)
+{
+       int err;
+
+       usb_fill_int_urb(line6->urb_listen, line6->usbdev,
+               usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r),
+               line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
+               line6_data_received, line6, line6->interval);
+       line6->urb_listen->actual_length = 0;
+       err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
+       return err;
+}
+
+/*
+       Stop listening on endpoint.
+*/
+static void line6_stop_listen(struct usb_line6 *line6)
+{
+       usb_kill_urb(line6->urb_listen);
+}
+
+/*
+       Send raw message in pieces of wMaxPacketSize bytes.
+*/
+static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+                                 int size)
+{
+       int i, done = 0;
+
+       for (i = 0; i < size; i += line6->max_packet_size) {
+               int partial;
+               const char *frag_buf = buffer + i;
+               int frag_size = min(line6->max_packet_size, size - i);
+               int retval;
+
+               retval = usb_interrupt_msg(line6->usbdev,
+                                       usb_sndintpipe(line6->usbdev,
+                                               line6->properties->ep_ctrl_w),
+                                       (char *)frag_buf, frag_size,
+                                       &partial, LINE6_TIMEOUT * HZ);
+
+               if (retval) {
+                       dev_err(line6->ifcdev,
+                               "usb_interrupt_msg failed (%d)\n", retval);
+                       break;
+               }
+
+               done += frag_size;
+       }
+
+       return done;
+}
+
+/*
+       Notification of completion of asynchronous request transmission.
+*/
+static void line6_async_request_sent(struct urb *urb)
+{
+       struct message *msg = (struct message *)urb->context;
+
+       if (msg->done >= msg->size) {
+               usb_free_urb(urb);
+               kfree(msg);
+       } else
+               line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+       Asynchronously send part of a raw message.
+*/
+static int line6_send_raw_message_async_part(struct message *msg,
+                                            struct urb *urb)
+{
+       int retval;
+       struct usb_line6 *line6 = msg->line6;
+       int done = msg->done;
+       int bytes = min(msg->size - done, line6->max_packet_size);
+
+       usb_fill_int_urb(urb, line6->usbdev,
+               usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w),
+               (char *)msg->buffer + done, bytes,
+               line6_async_request_sent, msg, line6->interval);
+
+       msg->done += bytes;
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+       if (retval < 0) {
+               dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
+                       __func__, retval);
+               usb_free_urb(urb);
+               kfree(msg);
+               return retval;
+       }
+
+       return 0;
+}
+
+/*
+       Setup and start timer.
+*/
+void line6_start_timer(struct timer_list *timer, unsigned int msecs,
+                      void (*function)(unsigned long), unsigned long data)
+{
+       setup_timer(timer, function, data);
+       mod_timer(timer, jiffies + msecs * HZ / 1000);
+}
+EXPORT_SYMBOL_GPL(line6_start_timer);
+
+/*
+       Asynchronously send raw message.
+*/
+int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
+                                int size)
+{
+       struct message *msg;
+       struct urb *urb;
+
+       /* create message: */
+       msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
+       if (msg == NULL)
+               return -ENOMEM;
+
+       /* create URB: */
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+       if (urb == NULL) {
+               kfree(msg);
+               return -ENOMEM;
+       }
+
+       /* set message data: */
+       msg->line6 = line6;
+       msg->buffer = buffer;
+       msg->size = size;
+       msg->done = 0;
+
+       /* start sending: */
+       return line6_send_raw_message_async_part(msg, urb);
+}
+EXPORT_SYMBOL_GPL(line6_send_raw_message_async);
+
+/*
+       Send asynchronous device version request.
+*/
+int line6_version_request_async(struct usb_line6 *line6)
+{
+       char *buffer;
+       int retval;
+
+       buffer = kmemdup(line6_request_version,
+                       sizeof(line6_request_version), GFP_ATOMIC);
+       if (buffer == NULL)
+               return -ENOMEM;
+
+       retval = line6_send_raw_message_async(line6, buffer,
+                                             sizeof(line6_request_version));
+       kfree(buffer);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(line6_version_request_async);
+
+/*
+       Send sysex message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
+                            int size)
+{
+       return line6_send_raw_message(line6, buffer,
+                                     size + SYSEX_EXTRA_SIZE) -
+           SYSEX_EXTRA_SIZE;
+}
+EXPORT_SYMBOL_GPL(line6_send_sysex_message);
+
+/*
+       Allocate buffer for sysex message and prepare header.
+       @param code sysex message code
+       @param size number of bytes between code and sysex end
+*/
+char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
+                              int size)
+{
+       char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
+
+       if (!buffer)
+               return NULL;
+
+       buffer[0] = LINE6_SYSEX_BEGIN;
+       memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
+       buffer[sizeof(line6_midi_id) + 1] = code1;
+       buffer[sizeof(line6_midi_id) + 2] = code2;
+       buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
+       return buffer;
+}
+EXPORT_SYMBOL_GPL(line6_alloc_sysex_buffer);
+
+/*
+       Notification of data received from the Line 6 device.
+*/
+static void line6_data_received(struct urb *urb)
+{
+       struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+       struct midi_buffer *mb = &line6->line6midi->midibuf_in;
+       int done;
+
+       if (urb->status == -ESHUTDOWN)
+               return;
+
+       done =
+           line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+
+       if (done < urb->actual_length) {
+               line6_midibuf_ignore(mb, done);
+               dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
+                       done, urb->actual_length);
+       }
+
+       for (;;) {
+               done =
+                   line6_midibuf_read(mb, line6->buffer_message,
+                                      LINE6_MESSAGE_MAXLEN);
+
+               if (done == 0)
+                       break;
+
+               line6->message_length = done;
+               line6_midi_receive(line6, line6->buffer_message, done);
+
+               if (line6->process_message)
+                       line6->process_message(line6);
+       }
+
+       line6_start_listen(line6);
+}
+
+/*
+       Read data from device.
+*/
+int line6_read_data(struct usb_line6 *line6, int address, void *data,
+                   size_t datalen)
+{
+       struct usb_device *usbdev = line6->usbdev;
+       int ret;
+       unsigned char len;
+
+       /* query the serial number: */
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                             (datalen << 8) | 0x21, address,
+                             NULL, 0, LINE6_TIMEOUT * HZ);
+
+       if (ret < 0) {
+               dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
+               return ret;
+       }
+
+       /* Wait for data length. We'll get 0xff until length arrives. */
+       do {
+               ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+                                     USB_DIR_IN,
+                                     0x0012, 0x0000, &len, 1,
+                                     LINE6_TIMEOUT * HZ);
+               if (ret < 0) {
+                       dev_err(line6->ifcdev,
+                               "receive length failed (error %d)\n", ret);
+                       return ret;
+               }
+       } while (len == 0xff);
+
+       if (len != datalen) {
+               /* should be equal or something went wrong */
+               dev_err(line6->ifcdev,
+                       "length mismatch (expected %d, got %d)\n",
+                       (int)datalen, (int)len);
+               return -EINVAL;
+       }
+
+       /* receive the result: */
+       ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                             0x0013, 0x0000, data, datalen,
+                             LINE6_TIMEOUT * HZ);
+
+       if (ret < 0) {
+               dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_read_data);
+
+/*
+       Write data to device.
+*/
+int line6_write_data(struct usb_line6 *line6, int address, void *data,
+                    size_t datalen)
+{
+       struct usb_device *usbdev = line6->usbdev;
+       int ret;
+       unsigned char status;
+
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                             0x0022, address, data, datalen,
+                             LINE6_TIMEOUT * HZ);
+
+       if (ret < 0) {
+               dev_err(line6->ifcdev,
+                       "write request failed (error %d)\n", ret);
+               return ret;
+       }
+
+       do {
+               ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
+                                     0x67,
+                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+                                     USB_DIR_IN,
+                                     0x0012, 0x0000,
+                                     &status, 1, LINE6_TIMEOUT * HZ);
+
+               if (ret < 0) {
+                       dev_err(line6->ifcdev,
+                               "receiving status failed (error %d)\n", ret);
+                       return ret;
+               }
+       } while (status == 0xff);
+
+       if (status != 0) {
+               dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_write_data);
+
+/*
+       Read Line 6 device serial number.
+       (POD, TonePort, GuitarPort)
+*/
+int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
+{
+       return line6_read_data(line6, 0x80d0, serial_number,
+                              sizeof(*serial_number));
+}
+EXPORT_SYMBOL_GPL(line6_read_serial_number);
+
+/*
+       Card destructor.
+*/
+static void line6_destruct(struct snd_card *card)
+{
+       struct usb_line6 *line6 = card->private_data;
+       struct usb_device *usbdev = line6->usbdev;
+
+       /* free buffer memory first: */
+       kfree(line6->buffer_message);
+       kfree(line6->buffer_listen);
+
+       /* then free URBs: */
+       usb_free_urb(line6->urb_listen);
+
+       /* decrement reference counters: */
+       usb_put_dev(usbdev);
+}
+
+/* get data from endpoint descriptor (see usb_maxpacket): */
+static void line6_get_interval(struct usb_line6 *line6)
+{
+       struct usb_device *usbdev = line6->usbdev;
+       struct usb_host_endpoint *ep;
+       unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r);
+       unsigned epnum = usb_pipeendpoint(pipe);
+
+       ep = usbdev->ep_in[epnum];
+       if (ep) {
+               line6->interval = ep->desc.bInterval;
+               line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+       } else {
+               dev_err(line6->ifcdev,
+                       "endpoint not available, using fallback values");
+               line6->interval = LINE6_FALLBACK_INTERVAL;
+               line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
+       }
+}
+
+static int line6_init_cap_control(struct usb_line6 *line6)
+{
+       int ret;
+
+       /* initialize USB buffers: */
+       line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+       if (!line6->buffer_listen)
+               return -ENOMEM;
+
+       line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
+       if (!line6->buffer_message)
+               return -ENOMEM;
+
+       line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
+       if (!line6->urb_listen)
+               return -ENOMEM;
+
+       ret = line6_start_listen(line6);
+       if (ret < 0) {
+               dev_err(line6->ifcdev, "cannot start listening: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+       Probe USB device.
+*/
+int line6_probe(struct usb_interface *interface,
+               const struct usb_device_id *id,
+               const struct line6_properties *properties,
+               int (*private_init)(struct usb_line6 *, const struct usb_device_id *id),
+               size_t data_size)
+{
+       struct usb_device *usbdev = interface_to_usbdev(interface);
+       struct snd_card *card;
+       struct usb_line6 *line6;
+       int interface_number;
+       int ret;
+
+       if (WARN_ON(data_size < sizeof(*line6)))
+               return -EINVAL;
+
+       /* we don't handle multiple configurations */
+       if (usbdev->descriptor.bNumConfigurations != 1)
+               return -ENODEV;
+
+       ret = snd_card_new(&interface->dev,
+                          SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+                          THIS_MODULE, data_size, &card);
+       if (ret < 0)
+               return ret;
+
+       /* store basic data: */
+       line6 = card->private_data;
+       line6->card = card;
+       line6->properties = properties;
+       line6->usbdev = usbdev;
+       line6->ifcdev = &interface->dev;
+
+       strcpy(card->id, properties->id);
+       strcpy(card->driver, DRIVER_NAME);
+       strcpy(card->shortname, properties->name);
+       sprintf(card->longname, "Line 6 %s at USB %s", properties->name,
+               dev_name(line6->ifcdev));
+       card->private_free = line6_destruct;
+
+       usb_set_intfdata(interface, line6);
+
+       /* increment reference counters: */
+       usb_get_dev(usbdev);
+
+       /* initialize device info: */
+       dev_info(&interface->dev, "Line 6 %s found\n", properties->name);
+
+       /* query interface number */
+       interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+
+       ret = usb_set_interface(usbdev, interface_number,
+                               properties->altsetting);
+       if (ret < 0) {
+               dev_err(&interface->dev, "set_interface failed\n");
+               goto error;
+       }
+
+       line6_get_interval(line6);
+
+       if (properties->capabilities & LINE6_CAP_CONTROL) {
+               ret = line6_init_cap_control(line6);
+               if (ret < 0)
+                       goto error;
+       }
+
+       /* initialize device data based on device: */
+       ret = private_init(line6, id);
+       if (ret < 0)
+               goto error;
+
+       /* creation of additional special files should go here */
+
+       dev_info(&interface->dev, "Line 6 %s now attached\n",
+                properties->name);
+
+       return 0;
+
+ error:
+       if (line6->disconnect)
+               line6->disconnect(line6);
+       snd_card_free(card);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(line6_probe);
+
+/*
+       Line 6 device disconnected.
+*/
+void line6_disconnect(struct usb_interface *interface)
+{
+       struct usb_line6 *line6 = usb_get_intfdata(interface);
+       struct usb_device *usbdev = interface_to_usbdev(interface);
+
+       if (!line6)
+               return;
+
+       if (WARN_ON(usbdev != line6->usbdev))
+               return;
+
+       if (line6->urb_listen != NULL)
+               line6_stop_listen(line6);
+
+       snd_card_disconnect(line6->card);
+       if (line6->line6pcm)
+               line6_pcm_disconnect(line6->line6pcm);
+       if (line6->disconnect)
+               line6->disconnect(line6);
+
+       dev_info(&interface->dev, "Line 6 %s now disconnected\n",
+                line6->properties->name);
+
+       /* make sure the device isn't destructed twice: */
+       usb_set_intfdata(interface, NULL);
+
+       snd_card_free_when_closed(line6->card);
+}
+EXPORT_SYMBOL_GPL(line6_disconnect);
+
+#ifdef CONFIG_PM
+
+/*
+       Suspend Line 6 device.
+*/
+int line6_suspend(struct usb_interface *interface, pm_message_t message)
+{
+       struct usb_line6 *line6 = usb_get_intfdata(interface);
+       struct snd_line6_pcm *line6pcm = line6->line6pcm;
+
+       snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
+
+       if (line6->properties->capabilities & LINE6_CAP_CONTROL)
+               line6_stop_listen(line6);
+
+       if (line6pcm != NULL) {
+               snd_pcm_suspend_all(line6pcm->pcm);
+               line6pcm->flags = 0;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_suspend);
+
+/*
+       Resume Line 6 device.
+*/
+int line6_resume(struct usb_interface *interface)
+{
+       struct usb_line6 *line6 = usb_get_intfdata(interface);
+
+       if (line6->properties->capabilities & LINE6_CAP_CONTROL)
+               line6_start_listen(line6);
+
+       snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_resume);
+
+#endif /* CONFIG_PM */
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
new file mode 100644 (file)
index 0000000..fce10f1
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <sound/core.h>
+
+#include "midi.h"
+
+#define DRIVER_NAME "line6usb"
+
+#define LINE6_TIMEOUT 1
+#define LINE6_BUFSIZE_LISTEN 32
+#define LINE6_MESSAGE_MAXLEN 256
+
+/*
+       Line 6 MIDI control commands
+*/
+#define LINE6_PARAM_CHANGE   0xb0
+#define LINE6_PROGRAM_CHANGE 0xc0
+#define LINE6_SYSEX_BEGIN    0xf0
+#define LINE6_SYSEX_END      0xf7
+#define LINE6_RESET          0xff
+
+/*
+       MIDI channel for messages initiated by the host
+       (and eventually echoed back by the device)
+*/
+#define LINE6_CHANNEL_HOST   0x00
+
+/*
+       MIDI channel for messages initiated by the device
+*/
+#define LINE6_CHANNEL_DEVICE 0x02
+
+#define LINE6_CHANNEL_UNKNOWN 5        /* don't know yet what this is good for */
+
+#define LINE6_CHANNEL_MASK 0x0f
+
+#define CHECK_STARTUP_PROGRESS(x, n)   \
+do {                                   \
+       if ((x) >= (n))                 \
+               return;                 \
+       x = (n);                        \
+} while (0)
+
+extern const unsigned char line6_midi_id[3];
+
+static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
+static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
+
+/**
+        Common properties of Line 6 devices.
+*/
+struct line6_properties {
+       /**
+                Card id string (maximum 16 characters).
+                This can be used to address the device in ALSA programs as
+                "default:CARD=<id>"
+       */
+       const char *id;
+
+       /**
+                Card short name (maximum 32 characters).
+       */
+       const char *name;
+
+       /**
+                Bit vector defining this device's capabilities in the
+                line6usb driver.
+       */
+       int capabilities;
+
+       int altsetting;
+
+       unsigned ep_ctrl_r;
+       unsigned ep_ctrl_w;
+       unsigned ep_audio_r;
+       unsigned ep_audio_w;
+};
+
+/**
+        Common data shared by all Line 6 devices.
+        Corresponds to a pair of USB endpoints.
+*/
+struct usb_line6 {
+       /**
+                USB device.
+       */
+       struct usb_device *usbdev;
+
+       /**
+                Properties.
+       */
+       const struct line6_properties *properties;
+
+       /**
+                Interval (ms).
+       */
+       int interval;
+
+       /**
+                Maximum size of USB packet.
+       */
+       int max_packet_size;
+
+       /**
+                Device representing the USB interface.
+       */
+       struct device *ifcdev;
+
+       /**
+                Line 6 sound card data structure.
+                Each device has at least MIDI or PCM.
+       */
+       struct snd_card *card;
+
+       /**
+                Line 6 PCM device data structure.
+       */
+       struct snd_line6_pcm *line6pcm;
+
+       /**
+                Line 6 MIDI device data structure.
+       */
+       struct snd_line6_midi *line6midi;
+
+       /**
+                URB for listening to PODxt Pro control endpoint.
+       */
+       struct urb *urb_listen;
+
+       /**
+                Buffer for listening to PODxt Pro control endpoint.
+       */
+       unsigned char *buffer_listen;
+
+       /**
+                Buffer for message to be processed.
+       */
+       unsigned char *buffer_message;
+
+       /**
+                Length of message to be processed.
+       */
+       int message_length;
+
+       void (*process_message)(struct usb_line6 *);
+       void (*disconnect)(struct usb_line6 *line6);
+};
+
+extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
+                                     int code2, int size);
+extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
+                          size_t datalen);
+extern int line6_read_serial_number(struct usb_line6 *line6,
+                                   int *serial_number);
+extern int line6_send_raw_message_async(struct usb_line6 *line6,
+                                       const char *buffer, int size);
+extern int line6_send_sysex_message(struct usb_line6 *line6,
+                                   const char *buffer, int size);
+extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t count);
+extern void line6_start_timer(struct timer_list *timer, unsigned int msecs,
+                             void (*function)(unsigned long),
+                             unsigned long data);
+extern int line6_version_request_async(struct usb_line6 *line6);
+extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
+                           size_t datalen);
+
+int line6_probe(struct usb_interface *interface,
+               const struct usb_device_id *id,
+               const struct line6_properties *properties,
+               int (*private_init)(struct usb_line6 *, const struct usb_device_id *id),
+               size_t data_size);
+
+void line6_disconnect(struct usb_interface *interface);
+
+#ifdef CONFIG_PM
+int line6_suspend(struct usb_interface *interface, pm_message_t message);
+int line6_resume(struct usb_interface *interface);
+#endif
+
+#endif
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
new file mode 100644 (file)
index 0000000..beeedf9
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/export.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "driver.h"
+#include "midi.h"
+#include "usbdefs.h"
+
+#define line6_rawmidi_substream_midi(substream) \
+       ((struct snd_line6_midi *)((substream)->rmidi->private_data))
+
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+                          int length);
+
+/*
+       Pass data received via USB to MIDI.
+*/
+void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+                       int length)
+{
+       if (line6->line6midi->substream_receive)
+               snd_rawmidi_receive(line6->line6midi->substream_receive,
+                                   data, length);
+}
+
+/*
+       Read data from MIDI buffer and transmit them via USB.
+*/
+static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+{
+       struct usb_line6 *line6 =
+           line6_rawmidi_substream_midi(substream)->line6;
+       struct snd_line6_midi *line6midi = line6->line6midi;
+       struct midi_buffer *mb = &line6midi->midibuf_out;
+       unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];
+       int req, done;
+
+       for (;;) {
+               req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
+               done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+               if (done == 0)
+                       break;
+
+               line6_midibuf_write(mb, chunk, done);
+               snd_rawmidi_transmit_ack(substream, done);
+       }
+
+       for (;;) {
+               done = line6_midibuf_read(mb, chunk,
+                                         LINE6_FALLBACK_MAXPACKETSIZE);
+
+               if (done == 0)
+                       break;
+
+               send_midi_async(line6, chunk, done);
+       }
+}
+
+/*
+       Notification of completion of MIDI transmission.
+*/
+static void midi_sent(struct urb *urb)
+{
+       unsigned long flags;
+       int status;
+       int num;
+       struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+       status = urb->status;
+       kfree(urb->transfer_buffer);
+       usb_free_urb(urb);
+
+       if (status == -ESHUTDOWN)
+               return;
+
+       spin_lock_irqsave(&line6->line6midi->lock, flags);
+       num = --line6->line6midi->num_active_send_urbs;
+
+       if (num == 0) {
+               line6_midi_transmit(line6->line6midi->substream_transmit);
+               num = line6->line6midi->num_active_send_urbs;
+       }
+
+       if (num == 0)
+               wake_up(&line6->line6midi->send_wait);
+
+       spin_unlock_irqrestore(&line6->line6midi->lock, flags);
+}
+
+/*
+       Send an asynchronous MIDI message.
+       Assumes that line6->line6midi->lock is held
+       (i.e., this function is serialized).
+*/
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+                          int length)
+{
+       struct urb *urb;
+       int retval;
+       unsigned char *transfer_buffer;
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+       if (urb == NULL)
+               return -ENOMEM;
+
+       transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
+
+       if (transfer_buffer == NULL) {
+               usb_free_urb(urb);
+               return -ENOMEM;
+       }
+
+       usb_fill_int_urb(urb, line6->usbdev,
+                        usb_sndbulkpipe(line6->usbdev,
+                                        line6->properties->ep_ctrl_w),
+                        transfer_buffer, length, midi_sent, line6,
+                        line6->interval);
+       urb->actual_length = 0;
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+       if (retval < 0) {
+               dev_err(line6->ifcdev, "usb_submit_urb failed\n");
+               usb_free_urb(urb);
+               return retval;
+       }
+
+       ++line6->line6midi->num_active_send_urbs;
+       return 0;
+}
+
+static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
+                                     int up)
+{
+       unsigned long flags;
+       struct usb_line6 *line6 =
+           line6_rawmidi_substream_midi(substream)->line6;
+
+       line6->line6midi->substream_transmit = substream;
+       spin_lock_irqsave(&line6->line6midi->lock, flags);
+
+       if (line6->line6midi->num_active_send_urbs == 0)
+               line6_midi_transmit(substream);
+
+       spin_unlock_irqrestore(&line6->line6midi->lock, flags);
+}
+
+static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
+{
+       struct usb_line6 *line6 =
+           line6_rawmidi_substream_midi(substream)->line6;
+       struct snd_line6_midi *midi = line6->line6midi;
+
+       wait_event_interruptible(midi->send_wait,
+                                midi->num_active_send_urbs == 0);
+}
+
+static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
+                                    int up)
+{
+       struct usb_line6 *line6 =
+           line6_rawmidi_substream_midi(substream)->line6;
+
+       if (up)
+               line6->line6midi->substream_receive = substream;
+       else
+               line6->line6midi->substream_receive = NULL;
+}
+
+static struct snd_rawmidi_ops line6_midi_output_ops = {
+       .open = line6_midi_output_open,
+       .close = line6_midi_output_close,
+       .trigger = line6_midi_output_trigger,
+       .drain = line6_midi_output_drain,
+};
+
+static struct snd_rawmidi_ops line6_midi_input_ops = {
+       .open = line6_midi_input_open,
+       .close = line6_midi_input_close,
+       .trigger = line6_midi_input_trigger,
+};
+
+/* Create a MIDI device */
+static int snd_line6_new_midi(struct usb_line6 *line6,
+                             struct snd_rawmidi **rmidi_ret)
+{
+       struct snd_rawmidi *rmidi;
+       int err;
+
+       err = snd_rawmidi_new(line6->card, "Line 6 MIDI", 0, 1, 1, rmidi_ret);
+       if (err < 0)
+               return err;
+
+       rmidi = *rmidi_ret;
+       strcpy(rmidi->id, line6->properties->id);
+       strcpy(rmidi->name, line6->properties->name);
+
+       rmidi->info_flags =
+           SNDRV_RAWMIDI_INFO_OUTPUT |
+           SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
+
+       snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+                           &line6_midi_output_ops);
+       snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+                           &line6_midi_input_ops);
+       return 0;
+}
+
+/* MIDI device destructor */
+static void snd_line6_midi_free(struct snd_rawmidi *rmidi)
+{
+       struct snd_line6_midi *line6midi = rmidi->private_data;
+
+       line6_midibuf_destroy(&line6midi->midibuf_in);
+       line6_midibuf_destroy(&line6midi->midibuf_out);
+       kfree(line6midi);
+}
+
+/*
+       Initialize the Line 6 MIDI subsystem.
+*/
+int line6_init_midi(struct usb_line6 *line6)
+{
+       int err;
+       struct snd_rawmidi *rmidi;
+       struct snd_line6_midi *line6midi;
+
+       if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) {
+               /* skip MIDI initialization and report success */
+               return 0;
+       }
+
+       err = snd_line6_new_midi(line6, &rmidi);
+       if (err < 0)
+               return err;
+
+       line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+       if (!line6midi)
+               return -ENOMEM;
+
+       rmidi->private_data = line6midi;
+       rmidi->private_free = snd_line6_midi_free;
+
+       init_waitqueue_head(&line6midi->send_wait);
+       spin_lock_init(&line6midi->lock);
+       line6midi->line6 = line6;
+
+       err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
+       if (err < 0)
+               return err;
+
+       err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
+       if (err < 0)
+               return err;
+
+       line6->line6midi = line6midi;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_init_midi);
diff --git a/sound/usb/line6/midi.h b/sound/usb/line6/midi.h
new file mode 100644 (file)
index 0000000..9d9467b
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef MIDI_H
+#define MIDI_H
+
+#include <sound/rawmidi.h>
+
+#include "midibuf.h"
+
+#define MIDI_BUFFER_SIZE 1024
+
+struct snd_line6_midi {
+       /**
+                Pointer back to the Line 6 driver data structure.
+       */
+       struct usb_line6 *line6;
+
+       /**
+                MIDI substream for receiving (or NULL if not active).
+       */
+       struct snd_rawmidi_substream *substream_receive;
+
+       /**
+                MIDI substream for transmitting (or NULL if not active).
+       */
+       struct snd_rawmidi_substream *substream_transmit;
+
+       /**
+                Number of currently active MIDI send URBs.
+       */
+       int num_active_send_urbs;
+
+       /**
+                Spin lock to protect MIDI buffer handling.
+       */
+       spinlock_t lock;
+
+       /**
+                Wait queue for MIDI transmission.
+       */
+       wait_queue_head_t send_wait;
+
+       /**
+                Buffer for incoming MIDI stream.
+       */
+       struct midi_buffer midibuf_in;
+
+       /**
+                Buffer for outgoing MIDI stream.
+       */
+       struct midi_buffer midibuf_out;
+};
+
+extern int line6_init_midi(struct usb_line6 *line6);
+extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+                              int length);
+
+#endif
diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c
new file mode 100644 (file)
index 0000000..b5c4d79
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+
+#include "midibuf.h"
+
+static int midibuf_message_length(unsigned char code)
+{
+       int message_length;
+
+       if (code < 0x80)
+               message_length = -1;
+       else if (code < 0xf0) {
+               static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
+
+               message_length = length[(code >> 4) - 8];
+       } else {
+               /*
+                  Note that according to the MIDI specification 0xf2 is
+                  the "Song Position Pointer", but this is used by Line 6
+                  to send sysex messages to the host.
+                */
+               static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+                       1, 1, 1, -1, 1, 1
+               };
+               message_length = length[code & 0x0f];
+       }
+
+       return message_length;
+}
+
+static int midibuf_is_empty(struct midi_buffer *this)
+{
+       return (this->pos_read == this->pos_write) && !this->full;
+}
+
+static int midibuf_is_full(struct midi_buffer *this)
+{
+       return this->full;
+}
+
+void line6_midibuf_reset(struct midi_buffer *this)
+{
+       this->pos_read = this->pos_write = this->full = 0;
+       this->command_prev = -1;
+}
+
+int line6_midibuf_init(struct midi_buffer *this, int size, int split)
+{
+       this->buf = kmalloc(size, GFP_KERNEL);
+
+       if (this->buf == NULL)
+               return -ENOMEM;
+
+       this->size = size;
+       this->split = split;
+       line6_midibuf_reset(this);
+       return 0;
+}
+
+void line6_midibuf_status(struct midi_buffer *this)
+{
+       pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n",
+                this->size, this->split, this->pos_read, this->pos_write,
+                this->full, this->command_prev);
+}
+
+int line6_midibuf_bytes_free(struct midi_buffer *this)
+{
+       return
+           midibuf_is_full(this) ?
+           0 :
+           (this->pos_read - this->pos_write + this->size - 1) % this->size +
+           1;
+}
+
+int line6_midibuf_bytes_used(struct midi_buffer *this)
+{
+       return
+           midibuf_is_empty(this) ?
+           0 :
+           (this->pos_write - this->pos_read + this->size - 1) % this->size +
+           1;
+}
+
+int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
+                       int length)
+{
+       int bytes_free;
+       int length1, length2;
+       int skip_active_sense = 0;
+
+       if (midibuf_is_full(this) || (length <= 0))
+               return 0;
+
+       /* skip trailing active sense */
+       if (data[length - 1] == 0xfe) {
+               --length;
+               skip_active_sense = 1;
+       }
+
+       bytes_free = line6_midibuf_bytes_free(this);
+
+       if (length > bytes_free)
+               length = bytes_free;
+
+       if (length > 0) {
+               length1 = this->size - this->pos_write;
+
+               if (length < length1) {
+                       /* no buffer wraparound */
+                       memcpy(this->buf + this->pos_write, data, length);
+                       this->pos_write += length;
+               } else {
+                       /* buffer wraparound */
+                       length2 = length - length1;
+                       memcpy(this->buf + this->pos_write, data, length1);
+                       memcpy(this->buf, data + length1, length2);
+                       this->pos_write = length2;
+               }
+
+               if (this->pos_write == this->pos_read)
+                       this->full = 1;
+       }
+
+       return length + skip_active_sense;
+}
+
+int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+                      int length)
+{
+       int bytes_used;
+       int length1, length2;
+       int command;
+       int midi_length;
+       int repeat = 0;
+       int i;
+
+       /* we need to be able to store at least a 3 byte MIDI message */
+       if (length < 3)
+               return -EINVAL;
+
+       if (midibuf_is_empty(this))
+               return 0;
+
+       bytes_used = line6_midibuf_bytes_used(this);
+
+       if (length > bytes_used)
+               length = bytes_used;
+
+       length1 = this->size - this->pos_read;
+
+       /* check MIDI command length */
+       command = this->buf[this->pos_read];
+
+       if (command & 0x80) {
+               midi_length = midibuf_message_length(command);
+               this->command_prev = command;
+       } else {
+               if (this->command_prev > 0) {
+                       int midi_length_prev =
+                           midibuf_message_length(this->command_prev);
+
+                       if (midi_length_prev > 0) {
+                               midi_length = midi_length_prev - 1;
+                               repeat = 1;
+                       } else
+                               midi_length = -1;
+               } else
+                       midi_length = -1;
+       }
+
+       if (midi_length < 0) {
+               /* search for end of message */
+               if (length < length1) {
+                       /* no buffer wraparound */
+                       for (i = 1; i < length; ++i)
+                               if (this->buf[this->pos_read + i] & 0x80)
+                                       break;
+
+                       midi_length = i;
+               } else {
+                       /* buffer wraparound */
+                       length2 = length - length1;
+
+                       for (i = 1; i < length1; ++i)
+                               if (this->buf[this->pos_read + i] & 0x80)
+                                       break;
+
+                       if (i < length1)
+                               midi_length = i;
+                       else {
+                               for (i = 0; i < length2; ++i)
+                                       if (this->buf[i] & 0x80)
+                                               break;
+
+                               midi_length = length1 + i;
+                       }
+               }
+
+               if (midi_length == length)
+                       midi_length = -1;       /* end of message not found */
+       }
+
+       if (midi_length < 0) {
+               if (!this->split)
+                       return 0;       /* command is not yet complete */
+       } else {
+               if (length < midi_length)
+                       return 0;       /* command is not yet complete */
+
+               length = midi_length;
+       }
+
+       if (length < length1) {
+               /* no buffer wraparound */
+               memcpy(data + repeat, this->buf + this->pos_read, length);
+               this->pos_read += length;
+       } else {
+               /* buffer wraparound */
+               length2 = length - length1;
+               memcpy(data + repeat, this->buf + this->pos_read, length1);
+               memcpy(data + repeat + length1, this->buf, length2);
+               this->pos_read = length2;
+       }
+
+       if (repeat)
+               data[0] = this->command_prev;
+
+       this->full = 0;
+       return length + repeat;
+}
+
+int line6_midibuf_ignore(struct midi_buffer *this, int length)
+{
+       int bytes_used = line6_midibuf_bytes_used(this);
+
+       if (length > bytes_used)
+               length = bytes_used;
+
+       this->pos_read = (this->pos_read + length) % this->size;
+       this->full = 0;
+       return length;
+}
+
+int line6_midibuf_skip_message(struct midi_buffer *this, unsigned short mask)
+{
+       int cmd = this->command_prev;
+
+       if ((cmd >= 0x80) && (cmd < 0xf0))
+               if ((mask & (1 << (cmd & 0x0f))) == 0)
+                       return 1;
+
+       return 0;
+}
+
+void line6_midibuf_destroy(struct midi_buffer *this)
+{
+       kfree(this->buf);
+       this->buf = NULL;
+}
diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h
new file mode 100644 (file)
index 0000000..05dbf11
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef MIDIBUF_H
+#define MIDIBUF_H
+
+struct midi_buffer {
+       unsigned char *buf;
+       int size;
+       int split;
+       int pos_read, pos_write;
+       int full;
+       int command_prev;
+};
+
+extern int line6_midibuf_bytes_used(struct midi_buffer *mb);
+extern int line6_midibuf_bytes_free(struct midi_buffer *mb);
+extern void line6_midibuf_destroy(struct midi_buffer *mb);
+extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
+extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
+extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
+                             int length);
+extern void line6_midibuf_reset(struct midi_buffer *mb);
+extern int line6_midibuf_skip_message(struct midi_buffer *mb,
+                                     unsigned short mask);
+extern void line6_midibuf_status(struct midi_buffer *mb);
+extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
+                              int length);
+
+#endif
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
new file mode 100644 (file)
index 0000000..8461d6b
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "playback.h"
+
+/* impulse response volume controls */
+static int snd_line6_impulse_volume_info(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 255;
+       return 0;
+}
+
+static int snd_line6_impulse_volume_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = line6pcm->impulse_volume;
+       return 0;
+}
+
+static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       int value = ucontrol->value.integer.value[0];
+       int err;
+
+       if (line6pcm->impulse_volume == value)
+               return 0;
+
+       line6pcm->impulse_volume = value;
+       if (value > 0) {
+               err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
+               if (err < 0) {
+                       line6pcm->impulse_volume = 0;
+                       line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
+                       return err;
+               }
+       } else {
+               line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
+       }
+       return 1;
+}
+
+/* impulse response period controls */
+static int snd_line6_impulse_period_info(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 2000;
+       return 0;
+}
+
+static int snd_line6_impulse_period_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = line6pcm->impulse_period;
+       return 0;
+}
+
+static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       int value = ucontrol->value.integer.value[0];
+
+       if (line6pcm->impulse_period == value)
+               return 0;
+
+       line6pcm->impulse_period = value;
+       return 1;
+}
+
+/*
+       Unlink all currently active URBs.
+*/
+static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
+                                   struct line6_pcm_stream *pcms)
+{
+       int i;
+
+       for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
+               if (test_bit(i, &pcms->active_urbs)) {
+                       if (!test_and_set_bit(i, &pcms->unlink_urbs))
+                               usb_unlink_urb(pcms->urbs[i]);
+               }
+       }
+}
+
+/*
+       Wait until unlinking of all currently active URBs has been finished.
+*/
+static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
+                                       struct line6_pcm_stream *pcms)
+{
+       int timeout = HZ;
+       int i;
+       int alive;
+
+       do {
+               alive = 0;
+               for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
+                       if (test_bit(i, &pcms->active_urbs))
+                               alive++;
+               }
+               if (!alive)
+                       break;
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(1);
+       } while (--timeout > 0);
+       if (alive)
+               dev_err(line6pcm->line6->ifcdev,
+                       "timeout: still %d active urbs..\n", alive);
+}
+
+static inline struct line6_pcm_stream *
+get_stream(struct snd_line6_pcm *line6pcm, int direction)
+{
+       return (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
+               &line6pcm->out : &line6pcm->in;
+}
+
+/* allocate a buffer if not opened yet;
+ * call this in line6pcm.state_change mutex
+ */
+static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
+                               struct line6_pcm_stream *pstr, int type)
+{
+       /* Invoked multiple times in a row so allocate once only */
+       if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) {
+               pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+                                      line6pcm->max_packet_size, GFP_KERNEL);
+               if (!pstr->buffer)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+/* free a buffer if all streams are closed;
+ * call this in line6pcm.state_change mutex
+ */
+static void line6_buffer_release(struct snd_line6_pcm *line6pcm,
+                                struct line6_pcm_stream *pstr, int type)
+{
+
+       clear_bit(type, &pstr->opened);
+       if (!pstr->opened) {
+               line6_wait_clear_audio_urbs(line6pcm, pstr);
+               kfree(pstr->buffer);
+               pstr->buffer = NULL;
+       }
+}
+
+/* start a PCM stream */
+static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
+                             int type)
+{
+       unsigned long flags;
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
+       int ret = 0;
+
+       spin_lock_irqsave(&pstr->lock, flags);
+       if (!test_and_set_bit(type, &pstr->running)) {
+               if (pstr->active_urbs || pstr->unlink_urbs) {
+                       ret = -EBUSY;
+                       goto error;
+               }
+
+               pstr->count = 0;
+               /* Submit all currently available URBs */
+               if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+                       ret = line6_submit_audio_out_all_urbs(line6pcm);
+               else
+                       ret = line6_submit_audio_in_all_urbs(line6pcm);
+       }
+ error:
+       if (ret < 0)
+               clear_bit(type, &pstr->running);
+       spin_unlock_irqrestore(&pstr->lock, flags);
+       return ret;
+}
+
+/* stop a PCM stream; this doesn't sync with the unlinked URBs */
+static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
+                         int type)
+{
+       unsigned long flags;
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, direction);
+
+       spin_lock_irqsave(&pstr->lock, flags);
+       clear_bit(type, &pstr->running);
+       if (!pstr->running) {
+               line6_unlink_audio_urbs(line6pcm, pstr);
+               if (direction == SNDRV_PCM_STREAM_CAPTURE) {
+                       line6pcm->prev_fbuf = NULL;
+                       line6pcm->prev_fsize = 0;
+               }
+       }
+       spin_unlock_irqrestore(&pstr->lock, flags);
+}
+
+/* common PCM trigger callback */
+int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+       struct snd_pcm_substream *s;
+       int err;
+
+       clear_bit(LINE6_FLAG_PREPARED, &line6pcm->flags);
+
+       snd_pcm_group_for_each_entry(s, substream) {
+               if (s->pcm->card != substream->pcm->card)
+                       continue;
+
+               switch (cmd) {
+               case SNDRV_PCM_TRIGGER_START:
+               case SNDRV_PCM_TRIGGER_RESUME:
+                       err = line6_stream_start(line6pcm, s->stream,
+                                                LINE6_STREAM_PCM);
+                       if (err < 0)
+                               return err;
+                       break;
+
+               case SNDRV_PCM_TRIGGER_STOP:
+               case SNDRV_PCM_TRIGGER_SUSPEND:
+                       line6_stream_stop(line6pcm, s->stream,
+                                         LINE6_STREAM_PCM);
+                       break;
+
+               case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+                       if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
+                               return -EINVAL;
+                       set_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
+                       break;
+
+               case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+                       if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
+                               return -EINVAL;
+                       clear_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags);
+                       break;
+
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+/* common PCM pointer callback */
+snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
+
+       return pstr->pos_done;
+}
+
+/* Acquire and start duplex streams:
+ * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR
+ */
+int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type)
+{
+       struct line6_pcm_stream *pstr;
+       int ret = 0, dir;
+
+       mutex_lock(&line6pcm->state_mutex);
+       for (dir = 0; dir < 2; dir++) {
+               pstr = get_stream(line6pcm, dir);
+               ret = line6_buffer_acquire(line6pcm, pstr, type);
+               if (ret < 0)
+                       goto error;
+               if (!pstr->running)
+                       line6_wait_clear_audio_urbs(line6pcm, pstr);
+       }
+       for (dir = 0; dir < 2; dir++) {
+               ret = line6_stream_start(line6pcm, dir, type);
+               if (ret < 0)
+                       goto error;
+       }
+ error:
+       mutex_unlock(&line6pcm->state_mutex);
+       if (ret < 0)
+               line6_pcm_release(line6pcm, type);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(line6_pcm_acquire);
+
+/* Stop and release duplex streams */
+void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type)
+{
+       struct line6_pcm_stream *pstr;
+       int dir;
+
+       mutex_lock(&line6pcm->state_mutex);
+       for (dir = 0; dir < 2; dir++)
+               line6_stream_stop(line6pcm, dir, type);
+       for (dir = 0; dir < 2; dir++) {
+               pstr = get_stream(line6pcm, dir);
+               line6_buffer_release(line6pcm, pstr, type);
+       }
+       mutex_unlock(&line6pcm->state_mutex);
+}
+EXPORT_SYMBOL_GPL(line6_pcm_release);
+
+/* common PCM hw_params callback */
+int snd_line6_hw_params(struct snd_pcm_substream *substream,
+                       struct snd_pcm_hw_params *hw_params)
+{
+       int ret;
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
+
+       mutex_lock(&line6pcm->state_mutex);
+       ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM);
+       if (ret < 0)
+               goto error;
+
+       ret = snd_pcm_lib_malloc_pages(substream,
+                                      params_buffer_bytes(hw_params));
+       if (ret < 0) {
+               line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
+               goto error;
+       }
+
+       pstr->period = params_period_bytes(hw_params);
+ error:
+       mutex_unlock(&line6pcm->state_mutex);
+       return ret;
+}
+
+/* common PCM hw_free callback */
+int snd_line6_hw_free(struct snd_pcm_substream *substream)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
+
+       mutex_lock(&line6pcm->state_mutex);
+       line6_buffer_release(line6pcm, pstr, LINE6_STREAM_PCM);
+       mutex_unlock(&line6pcm->state_mutex);
+       return snd_pcm_lib_free_pages(substream);
+}
+
+
+/* control info callback */
+static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
+                                          struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 2;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 256;
+       return 0;
+}
+
+/* control get callback */
+static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
+{
+       int i;
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+       for (i = 0; i < 2; i++)
+               ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
+
+       return 0;
+}
+
+/* control put callback */
+static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
+{
+       int i, changed = 0;
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+       for (i = 0; i < 2; i++)
+               if (line6pcm->volume_playback[i] !=
+                   ucontrol->value.integer.value[i]) {
+                       line6pcm->volume_playback[i] =
+                           ucontrol->value.integer.value[i];
+                       changed = 1;
+               }
+
+       return changed;
+}
+
+/* control definition */
+static struct snd_kcontrol_new line6_controls[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "PCM Playback Volume",
+               .info = snd_line6_control_playback_info,
+               .get = snd_line6_control_playback_get,
+               .put = snd_line6_control_playback_put
+       },
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Impulse Response Volume",
+               .info = snd_line6_impulse_volume_info,
+               .get = snd_line6_impulse_volume_get,
+               .put = snd_line6_impulse_volume_put
+       },
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Impulse Response Period",
+               .info = snd_line6_impulse_period_info,
+               .get = snd_line6_impulse_period_get,
+               .put = snd_line6_impulse_period_put
+       },
+};
+
+/*
+       Cleanup the PCM device.
+*/
+static void cleanup_urbs(struct line6_pcm_stream *pcms)
+{
+       int i;
+
+       for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
+               if (pcms->urbs[i]) {
+                       usb_kill_urb(pcms->urbs[i]);
+                       usb_free_urb(pcms->urbs[i]);
+               }
+       }
+}
+
+static void line6_cleanup_pcm(struct snd_pcm *pcm)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+
+       cleanup_urbs(&line6pcm->out);
+       cleanup_urbs(&line6pcm->in);
+       kfree(line6pcm);
+}
+
+/* create a PCM device */
+static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
+{
+       struct snd_pcm *pcm;
+       int err;
+
+       err = snd_pcm_new(line6->card, (char *)line6->properties->name,
+                         0, 1, 1, pcm_ret);
+       if (err < 0)
+               return err;
+       pcm = *pcm_ret;
+       strcpy(pcm->name, line6->properties->name);
+
+       /* set operators */
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                       &snd_line6_playback_ops);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
+
+       /* pre-allocation of buffers */
+       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+                                             snd_dma_continuous_data
+                                             (GFP_KERNEL), 64 * 1024,
+                                             128 * 1024);
+       return 0;
+}
+
+/*
+       Sync with PCM stream stops.
+*/
+void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
+{
+       line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
+       line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
+       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
+       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
+}
+
+/*
+       Create and register the PCM device and mixer entries.
+       Create URBs for playback and capture.
+*/
+int line6_init_pcm(struct usb_line6 *line6,
+                  struct line6_pcm_properties *properties)
+{
+       int i, err;
+       unsigned ep_read = line6->properties->ep_audio_r;
+       unsigned ep_write = line6->properties->ep_audio_w;
+       struct snd_pcm *pcm;
+       struct snd_line6_pcm *line6pcm;
+
+       if (!(line6->properties->capabilities & LINE6_CAP_PCM))
+               return 0;       /* skip PCM initialization and report success */
+
+       err = snd_line6_new_pcm(line6, &pcm);
+       if (err < 0)
+               return err;
+
+       line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
+       if (!line6pcm)
+               return -ENOMEM;
+
+       mutex_init(&line6pcm->state_mutex);
+       line6pcm->pcm = pcm;
+       line6pcm->properties = properties;
+       line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
+       line6pcm->volume_monitor = 255;
+       line6pcm->line6 = line6;
+
+       /* Read and write buffers are sized identically, so choose minimum */
+       line6pcm->max_packet_size = min(
+                       usb_maxpacket(line6->usbdev,
+                               usb_rcvisocpipe(line6->usbdev, ep_read), 0),
+                       usb_maxpacket(line6->usbdev,
+                               usb_sndisocpipe(line6->usbdev, ep_write), 1));
+
+       spin_lock_init(&line6pcm->out.lock);
+       spin_lock_init(&line6pcm->in.lock);
+       line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
+
+       line6->line6pcm = line6pcm;
+
+       pcm->private_data = line6pcm;
+       pcm->private_free = line6_cleanup_pcm;
+
+       err = line6_create_audio_out_urbs(line6pcm);
+       if (err < 0)
+               return err;
+
+       err = line6_create_audio_in_urbs(line6pcm);
+       if (err < 0)
+               return err;
+
+       /* mixer: */
+       for (i = 0; i < ARRAY_SIZE(line6_controls); i++) {
+               err = snd_ctl_add(line6->card,
+                                 snd_ctl_new1(&line6_controls[i], line6pcm));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(line6_init_pcm);
+
+/* prepare pcm callback */
+int snd_line6_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+       struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
+
+       mutex_lock(&line6pcm->state_mutex);
+       if (!pstr->running)
+               line6_wait_clear_audio_urbs(line6pcm, pstr);
+
+       if (!test_and_set_bit(LINE6_FLAG_PREPARED, &line6pcm->flags)) {
+               line6pcm->out.count = 0;
+               line6pcm->out.pos = 0;
+               line6pcm->out.pos_done = 0;
+               line6pcm->out.bytes = 0;
+               line6pcm->in.count = 0;
+               line6pcm->in.pos_done = 0;
+               line6pcm->in.bytes = 0;
+       }
+
+       mutex_unlock(&line6pcm->state_mutex);
+       return 0;
+}
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h
new file mode 100644 (file)
index 0000000..42d3e6f
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+/*
+       PCM interface to POD series devices.
+*/
+
+#ifndef PCM_H
+#define PCM_H
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "usbdefs.h"
+
+/* number of URBs */
+#define LINE6_ISO_BUFFERS      2
+
+/*
+       number of USB frames per URB
+       The Line 6 Windows driver always transmits two frames per packet, but
+       the Linux driver performs significantly better (i.e., lower latency)
+       with only one frame per packet.
+*/
+#define LINE6_ISO_PACKETS      1
+
+/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
+#define LINE6_ISO_INTERVAL     1
+
+#define LINE6_IMPULSE_DEFAULT_PERIOD 100
+
+/*
+       Get substream from Line 6 PCM data structure
+*/
+#define get_substream(line6pcm, stream)        \
+               (line6pcm->pcm->streams[stream].substream)
+
+/*
+       PCM mode bits.
+
+       There are several features of the Line 6 USB driver which require PCM
+       data to be exchanged with the device:
+       *) PCM playback and capture via ALSA
+       *) software monitoring (for devices without hardware monitoring)
+       *) optional impulse response measurement
+       However, from the device's point of view, there is just a single
+       capture and playback stream, which must be shared between these
+       subsystems. It is therefore necessary to maintain the state of the
+       subsystems with respect to PCM usage.
+
+       We define two bit flags, "opened" and "running", for each playback
+       or capture stream.  Both can contain the bit flag corresponding to
+       LINE6_STREAM_* type,
+         LINE6_STREAM_PCM = ALSA PCM playback or capture
+         LINE6_STREAM_MONITOR = software monitoring
+         IMPULSE = optional impulse response measurement
+       The opened flag indicates whether the buffer is allocated while
+       the running flag indicates whether the stream is running.
+
+       For monitor or impulse operations, the driver needs to call
+       snd_line6_duplex_acquire() or snd_line6_duplex_release() with the
+       appropriate LINE6_STREAM_* flag.
+*/
+
+/* stream types */
+enum {
+       LINE6_STREAM_PCM,
+       LINE6_STREAM_MONITOR,
+       LINE6_STREAM_IMPULSE,
+};
+
+/* misc bit flags for PCM operation */
+enum {
+       LINE6_FLAG_PAUSE_PLAYBACK,
+       LINE6_FLAG_PREPARED,
+};
+
+struct line6_pcm_properties {
+       struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
+       struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
+       int bytes_per_frame;
+};
+
+struct line6_pcm_stream {
+       /* allocated URBs */
+       struct urb *urbs[LINE6_ISO_BUFFERS];
+
+       /* Temporary buffer;
+        * Since the packet size is not known in advance, this buffer is
+        * large enough to store maximum size packets.
+        */
+       unsigned char *buffer;
+
+       /* Free frame position in the buffer. */
+       snd_pcm_uframes_t pos;
+
+       /* Count processed bytes;
+        * This is modulo period size (to determine when a period is finished).
+        */
+       unsigned bytes;
+
+       /* Counter to create desired sample rate */
+       unsigned count;
+
+       /* period size in bytes */
+       unsigned period;
+
+       /* Processed frame position in the buffer;
+        * The contents of the ring buffer have been consumed by the USB
+        * subsystem (i.e., sent to the USB device) up to this position.
+        */
+       snd_pcm_uframes_t pos_done;
+
+       /* Bit mask of active URBs */
+       unsigned long active_urbs;
+
+       /* Bit mask of URBs currently being unlinked */
+       unsigned long unlink_urbs;
+
+       /* Spin lock to protect updates of the buffer positions (not contents)
+        */
+       spinlock_t lock;
+
+       /* Bit flags for operational stream types */
+       unsigned long opened;
+
+       /* Bit flags for running stream types */
+       unsigned long running;
+
+       int last_frame;
+};
+
+struct snd_line6_pcm {
+       /**
+                Pointer back to the Line 6 driver data structure.
+       */
+       struct usb_line6 *line6;
+
+       /**
+                Properties.
+       */
+       struct line6_pcm_properties *properties;
+
+       /**
+                ALSA pcm stream
+       */
+       struct snd_pcm *pcm;
+
+       /* protection to state changes of in/out streams */
+       struct mutex state_mutex;
+
+       /* Capture and playback streams */
+       struct line6_pcm_stream in;
+       struct line6_pcm_stream out;
+
+       /**
+                Previously captured frame (for software monitoring).
+       */
+       unsigned char *prev_fbuf;
+
+       /**
+                Size of previously captured frame (for software monitoring).
+       */
+       int prev_fsize;
+
+       /**
+                Maximum size of USB packet.
+       */
+       int max_packet_size;
+
+       /**
+                PCM playback volume (left and right).
+       */
+       int volume_playback[2];
+
+       /**
+                PCM monitor volume.
+       */
+       int volume_monitor;
+
+       /**
+                Volume of impulse response test signal (if zero, test is disabled).
+       */
+       int impulse_volume;
+
+       /**
+                Period of impulse response test signal.
+       */
+       int impulse_period;
+
+       /**
+                Counter for impulse response test signal.
+       */
+       int impulse_count;
+
+       /**
+                Several status bits (see LINE6_FLAG_*).
+       */
+       unsigned long flags;
+};
+
+extern int line6_init_pcm(struct usb_line6 *line6,
+                         struct line6_pcm_properties *properties);
+extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
+extern int snd_line6_prepare(struct snd_pcm_substream *substream);
+extern int snd_line6_hw_params(struct snd_pcm_substream *substream,
+                              struct snd_pcm_hw_params *hw_params);
+extern int snd_line6_hw_free(struct snd_pcm_substream *substream);
+extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream);
+extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
+extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type);
+extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type);
+
+#endif
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
new file mode 100644 (file)
index 0000000..1708c05
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "pcm.h"
+#include "playback.h"
+
+/*
+       Software stereo volume control.
+*/
+static void change_volume(struct urb *urb_out, int volume[],
+                         int bytes_per_frame)
+{
+       int chn = 0;
+
+       if (volume[0] == 256 && volume[1] == 256)
+               return;         /* maximum volume - no change */
+
+       if (bytes_per_frame == 4) {
+               short *p, *buf_end;
+
+               p = (short *)urb_out->transfer_buffer;
+               buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
+
+               for (; p < buf_end; ++p) {
+                       int val = (*p * volume[chn & 1]) >> 8;
+                       *p = clamp(val, 0x7fff, -0x8000);
+                       ++chn;
+               }
+       } else if (bytes_per_frame == 6) {
+               unsigned char *p, *buf_end;
+
+               p = (unsigned char *)urb_out->transfer_buffer;
+               buf_end = p + urb_out->transfer_buffer_length;
+
+               for (; p < buf_end; p += 3) {
+                       int val;
+
+                       val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
+                       val = (val * volume[chn & 1]) >> 8;
+                       val = clamp(val, 0x7fffff, -0x800000);
+                       p[0] = val;
+                       p[1] = val >> 8;
+                       p[2] = val >> 16;
+                       ++chn;
+               }
+       }
+}
+
+/*
+       Create signal for impulse response test.
+*/
+static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
+                                      struct urb *urb_out, int bytes_per_frame)
+{
+       int frames = urb_out->transfer_buffer_length / bytes_per_frame;
+
+       if (bytes_per_frame == 4) {
+               int i;
+               short *pi = (short *)line6pcm->prev_fbuf;
+               short *po = (short *)urb_out->transfer_buffer;
+
+               for (i = 0; i < frames; ++i) {
+                       po[0] = pi[0];
+                       po[1] = 0;
+                       pi += 2;
+                       po += 2;
+               }
+       } else if (bytes_per_frame == 6) {
+               int i, j;
+               unsigned char *pi = line6pcm->prev_fbuf;
+               unsigned char *po = urb_out->transfer_buffer;
+
+               for (i = 0; i < frames; ++i) {
+                       for (j = 0; j < bytes_per_frame / 2; ++j)
+                               po[j] = pi[j];
+
+                       for (; j < bytes_per_frame; ++j)
+                               po[j] = 0;
+
+                       pi += bytes_per_frame;
+                       po += bytes_per_frame;
+               }
+       }
+       if (--line6pcm->impulse_count <= 0) {
+               ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
+                                                             1] =
+                   line6pcm->impulse_volume;
+               line6pcm->impulse_count = line6pcm->impulse_period;
+       }
+}
+
+/*
+       Add signal to buffer for software monitoring.
+*/
+static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
+                              int volume, int bytes_per_frame)
+{
+       if (volume == 0)
+               return;         /* zero volume - no change */
+
+       if (bytes_per_frame == 4) {
+               short *pi, *po, *buf_end;
+
+               pi = (short *)signal;
+               po = (short *)urb_out->transfer_buffer;
+               buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
+
+               for (; po < buf_end; ++pi, ++po) {
+                       int val = *po + ((*pi * volume) >> 8);
+                       *po = clamp(val, 0x7fff, -0x8000);
+               }
+       }
+
+       /*
+          We don't need to handle devices with 6 bytes per frame here
+          since they all support hardware monitoring.
+        */
+}
+
+/*
+       Find a free URB, prepare audio data, and submit URB.
+       must be called in line6pcm->out.lock context
+*/
+static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
+{
+       int index;
+       int i, urb_size, urb_frames;
+       int ret;
+       const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+       const int frame_increment =
+           line6pcm->properties->snd_line6_rates.rats[0].num_min;
+       const int frame_factor =
+           line6pcm->properties->snd_line6_rates.rats[0].den *
+           (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
+       struct urb *urb_out;
+
+       index =
+           find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS);
+
+       if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+               dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
+               return -EINVAL;
+       }
+
+       urb_out = line6pcm->out.urbs[index];
+       urb_size = 0;
+
+       for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+               /* compute frame size for given sampling rate */
+               int fsize = 0;
+               struct usb_iso_packet_descriptor *fout =
+                   &urb_out->iso_frame_desc[i];
+
+               fsize = line6pcm->prev_fsize;
+               if (fsize == 0) {
+                       int n;
+
+                       line6pcm->out.count += frame_increment;
+                       n = line6pcm->out.count / frame_factor;
+                       line6pcm->out.count -= n * frame_factor;
+                       fsize = n * bytes_per_frame;
+               }
+
+               fout->offset = urb_size;
+               fout->length = fsize;
+               urb_size += fsize;
+       }
+
+       if (urb_size == 0) {
+               /* can't determine URB size */
+               dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
+               return -EINVAL;
+       }
+
+       urb_frames = urb_size / bytes_per_frame;
+       urb_out->transfer_buffer =
+           line6pcm->out.buffer +
+           index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+       urb_out->transfer_buffer_length = urb_size;
+       urb_out->context = line6pcm;
+
+       if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) &&
+           !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) {
+               struct snd_pcm_runtime *runtime =
+                   get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
+
+               if (line6pcm->out.pos + urb_frames > runtime->buffer_size) {
+                       /*
+                          The transferred area goes over buffer boundary,
+                          copy the data to the temp buffer.
+                        */
+                       int len;
+
+                       len = runtime->buffer_size - line6pcm->out.pos;
+
+                       if (len > 0) {
+                               memcpy(urb_out->transfer_buffer,
+                                      runtime->dma_area +
+                                      line6pcm->out.pos * bytes_per_frame,
+                                      len * bytes_per_frame);
+                               memcpy(urb_out->transfer_buffer +
+                                      len * bytes_per_frame, runtime->dma_area,
+                                      (urb_frames - len) * bytes_per_frame);
+                       } else
+                               dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n",
+                                       len);
+               } else {
+                       memcpy(urb_out->transfer_buffer,
+                              runtime->dma_area +
+                              line6pcm->out.pos * bytes_per_frame,
+                              urb_out->transfer_buffer_length);
+               }
+
+               line6pcm->out.pos += urb_frames;
+               if (line6pcm->out.pos >= runtime->buffer_size)
+                       line6pcm->out.pos -= runtime->buffer_size;
+
+               change_volume(urb_out, line6pcm->volume_playback,
+                             bytes_per_frame);
+       } else {
+               memset(urb_out->transfer_buffer, 0,
+                      urb_out->transfer_buffer_length);
+       }
+
+       spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING);
+       if (line6pcm->prev_fbuf) {
+               if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) {
+                       create_impulse_test_signal(line6pcm, urb_out,
+                                                  bytes_per_frame);
+                       if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) {
+                               line6_capture_copy(line6pcm,
+                                                  urb_out->transfer_buffer,
+                                                  urb_out->
+                                                  transfer_buffer_length);
+                               line6_capture_check_period(line6pcm,
+                                       urb_out->transfer_buffer_length);
+                       }
+               } else {
+                       if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON)
+                           && line6pcm->out.running && line6pcm->in.running)
+                               add_monitor_signal(urb_out, line6pcm->prev_fbuf,
+                                                  line6pcm->volume_monitor,
+                                                  bytes_per_frame);
+               }
+               line6pcm->prev_fbuf = NULL;
+               line6pcm->prev_fsize = 0;
+       }
+       spin_unlock(&line6pcm->in.lock);
+
+       ret = usb_submit_urb(urb_out, GFP_ATOMIC);
+
+       if (ret == 0)
+               set_bit(index, &line6pcm->out.active_urbs);
+       else
+               dev_err(line6pcm->line6->ifcdev,
+                       "URB out #%d submission failed (%d)\n", index, ret);
+
+       return 0;
+}
+
+/*
+       Submit all currently available playback URBs.
+       must be called in line6pcm->out.lock context
+ */
+int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
+{
+       int ret = 0, i;
+
+       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+               ret = submit_audio_out_urb(line6pcm);
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
+}
+
+/*
+       Callback for completed playback URB.
+*/
+static void audio_out_callback(struct urb *urb)
+{
+       int i, index, length = 0, shutdown = 0;
+       unsigned long flags;
+       struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
+       struct snd_pcm_substream *substream =
+           get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
+
+#if USE_CLEAR_BUFFER_WORKAROUND
+       memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
+#endif
+
+       line6pcm->out.last_frame = urb->start_frame;
+
+       /* find index of URB */
+       for (index = 0; index < LINE6_ISO_BUFFERS; index++)
+               if (urb == line6pcm->out.urbs[index])
+                       break;
+
+       if (index >= LINE6_ISO_BUFFERS)
+               return;         /* URB has been unlinked asynchronously */
+
+       for (i = 0; i < LINE6_ISO_PACKETS; i++)
+               length += urb->iso_frame_desc[i].length;
+
+       spin_lock_irqsave(&line6pcm->out.lock, flags);
+
+       if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
+               struct snd_pcm_runtime *runtime = substream->runtime;
+
+               line6pcm->out.pos_done +=
+                   length / line6pcm->properties->bytes_per_frame;
+
+               if (line6pcm->out.pos_done >= runtime->buffer_size)
+                       line6pcm->out.pos_done -= runtime->buffer_size;
+       }
+
+       clear_bit(index, &line6pcm->out.active_urbs);
+
+       for (i = 0; i < LINE6_ISO_PACKETS; i++)
+               if (urb->iso_frame_desc[i].status == -EXDEV) {
+                       shutdown = 1;
+                       break;
+               }
+
+       if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs))
+               shutdown = 1;
+
+       if (!shutdown) {
+               submit_audio_out_urb(line6pcm);
+
+               if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
+                       line6pcm->out.bytes += length;
+                       if (line6pcm->out.bytes >= line6pcm->out.period) {
+                               line6pcm->out.bytes %= line6pcm->out.period;
+                               spin_unlock(&line6pcm->out.lock);
+                               snd_pcm_period_elapsed(substream);
+                               spin_lock(&line6pcm->out.lock);
+                       }
+               }
+       }
+       spin_unlock_irqrestore(&line6pcm->out.lock, flags);
+}
+
+/* open playback callback */
+static int snd_line6_playback_open(struct snd_pcm_substream *substream)
+{
+       int err;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+       err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                           (&line6pcm->
+                                            properties->snd_line6_rates));
+       if (err < 0)
+               return err;
+
+       runtime->hw = line6pcm->properties->snd_line6_playback_hw;
+       return 0;
+}
+
+/* close playback callback */
+static int snd_line6_playback_close(struct snd_pcm_substream *substream)
+{
+       return 0;
+}
+
+/* playback operators */
+struct snd_pcm_ops snd_line6_playback_ops = {
+       .open = snd_line6_playback_open,
+       .close = snd_line6_playback_close,
+       .ioctl = snd_pcm_lib_ioctl,
+       .hw_params = snd_line6_hw_params,
+       .hw_free = snd_line6_hw_free,
+       .prepare = snd_line6_prepare,
+       .trigger = snd_line6_trigger,
+       .pointer = snd_line6_pointer,
+};
+
+int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+       struct usb_line6 *line6 = line6pcm->line6;
+       int i;
+
+       /* create audio URBs and fill in constant values: */
+       for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+               struct urb *urb;
+
+               /* URB for audio out: */
+               urb = line6pcm->out.urbs[i] =
+                   usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+               if (urb == NULL)
+                       return -ENOMEM;
+
+               urb->dev = line6->usbdev;
+               urb->pipe =
+                   usb_sndisocpipe(line6->usbdev,
+                                   line6->properties->ep_audio_w &
+                                   USB_ENDPOINT_NUMBER_MASK);
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->start_frame = -1;
+               urb->number_of_packets = LINE6_ISO_PACKETS;
+               urb->interval = LINE6_ISO_INTERVAL;
+               urb->error_count = 0;
+               urb->complete = audio_out_callback;
+       }
+
+       return 0;
+}
diff --git a/sound/usb/line6/playback.h b/sound/usb/line6/playback.h
new file mode 100644 (file)
index 0000000..51fce29
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef PLAYBACK_H
+#define PLAYBACK_H
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+
+/*
+ * When the TonePort is used with jack in full duplex mode and the outputs are
+ * not connected, the software monitor produces an ugly noise since everything
+ * written to the output buffer (i.e., the input signal) will be repeated in
+ * the next period (sounds like a delay effect). As a workaround, the output
+ * buffer is cleared after the data have been read, but there must be a better
+ * solution. Until one is found, this workaround can be used to fix the
+ * problem.
+ */
+#define USE_CLEAR_BUFFER_WORKAROUND 1
+
+extern struct snd_pcm_ops snd_line6_playback_ops;
+
+extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
+
+#endif
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
new file mode 100644 (file)
index 0000000..6f7cd58
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "playback.h"
+#include "usbdefs.h"
+
+/*
+       Locate name in binary program dump
+*/
+#define        POD_NAME_OFFSET 0
+#define        POD_NAME_LENGTH 16
+
+/*
+       Other constants
+*/
+#define POD_CONTROL_SIZE 0x80
+#define POD_BUFSIZE_DUMPREQ 7
+#define POD_STARTUP_DELAY 1000
+
+/*
+       Stages of POD startup procedure
+*/
+enum {
+       POD_STARTUP_INIT = 1,
+       POD_STARTUP_VERSIONREQ,
+       POD_STARTUP_WORKQUEUE,
+       POD_STARTUP_SETUP,
+       POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
+};
+
+enum {
+       LINE6_BASSPODXT,
+       LINE6_BASSPODXTLIVE,
+       LINE6_BASSPODXTPRO,
+       LINE6_POCKETPOD,
+       LINE6_PODXT,
+       LINE6_PODXTLIVE_POD,
+       LINE6_PODXTPRO,
+};
+
+struct usb_line6_pod {
+       /**
+               Generic Line 6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Instrument monitor level.
+       */
+       int monitor_level;
+
+       /**
+               Timer for device initializaton.
+       */
+       struct timer_list startup_timer;
+
+       /**
+               Work handler for device initializaton.
+       */
+       struct work_struct startup_work;
+
+       /**
+               Current progress in startup procedure.
+       */
+       int startup_progress;
+
+       /**
+               Serial number of device.
+       */
+       int serial_number;
+
+       /**
+               Firmware version (x 100).
+       */
+       int firmware_version;
+
+       /**
+               Device ID.
+       */
+       int device_id;
+};
+
+#define POD_SYSEX_CODE 3
+#define POD_BYTES_PER_FRAME 6  /* 24bit audio (stereo) */
+
+/* *INDENT-OFF* */
+
+enum {
+       POD_SYSEX_SAVE      = 0x24,
+       POD_SYSEX_SYSTEM    = 0x56,
+       POD_SYSEX_SYSTEMREQ = 0x57,
+       /* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
+       POD_SYSEX_STORE     = 0x71,
+       POD_SYSEX_FINISH    = 0x72,
+       POD_SYSEX_DUMPMEM   = 0x73,
+       POD_SYSEX_DUMP      = 0x74,
+       POD_SYSEX_DUMPREQ   = 0x75
+
+       /* dumps entire internal memory of PODxt Pro */
+       /* POD_SYSEX_DUMPMEM2  = 0x76 */
+};
+
+enum {
+       POD_MONITOR_LEVEL  = 0x04,
+       POD_SYSTEM_INVALID = 0x10000
+};
+
+/* *INDENT-ON* */
+
+enum {
+       POD_DUMP_MEMORY = 2
+};
+
+enum {
+       POD_BUSY_READ,
+       POD_BUSY_WRITE,
+       POD_CHANNEL_DIRTY,
+       POD_SAVE_PRESSED,
+       POD_BUSY_MIDISEND
+};
+
+static struct snd_ratden pod_ratden = {
+       .num_min = 78125,
+       .num_max = 78125,
+       .num_step = 1,
+       .den = 2
+};
+
+static struct line6_pcm_properties pod_pcm_properties = {
+       .snd_line6_playback_hw = {
+                                 .info = (SNDRV_PCM_INFO_MMAP |
+                                          SNDRV_PCM_INFO_INTERLEAVED |
+                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                          SNDRV_PCM_INFO_MMAP_VALID |
+                                          SNDRV_PCM_INFO_PAUSE |
+                                          SNDRV_PCM_INFO_SYNC_START),
+                                 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                 .rates = SNDRV_PCM_RATE_KNOT,
+                                 .rate_min = 39062,
+                                 .rate_max = 39063,
+                                 .channels_min = 2,
+                                 .channels_max = 2,
+                                 .buffer_bytes_max = 60000,
+                                 .period_bytes_min = 64,
+                                 .period_bytes_max = 8192,
+                                 .periods_min = 1,
+                                 .periods_max = 1024},
+       .snd_line6_capture_hw = {
+                                .info = (SNDRV_PCM_INFO_MMAP |
+                                         SNDRV_PCM_INFO_INTERLEAVED |
+                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                         SNDRV_PCM_INFO_MMAP_VALID |
+                                         SNDRV_PCM_INFO_SYNC_START),
+                                .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                .rates = SNDRV_PCM_RATE_KNOT,
+                                .rate_min = 39062,
+                                .rate_max = 39063,
+                                .channels_min = 2,
+                                .channels_max = 2,
+                                .buffer_bytes_max = 60000,
+                                .period_bytes_min = 64,
+                                .period_bytes_max = 8192,
+                                .periods_min = 1,
+                                .periods_max = 1024},
+       .snd_line6_rates = {
+                           .nrats = 1,
+                           .rats = &pod_ratden},
+       .bytes_per_frame = POD_BYTES_PER_FRAME
+};
+
+static const char pod_version_header[] = {
+       0xf2, 0x7e, 0x7f, 0x06, 0x02
+};
+
+/* forward declarations: */
+static void pod_startup2(unsigned long data);
+static void pod_startup3(struct usb_line6_pod *pod);
+
+static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
+                                   int size)
+{
+       return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
+                                       size);
+}
+
+/*
+       Process a completely received message.
+*/
+static void line6_pod_process_message(struct usb_line6 *line6)
+{
+       struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
+       const unsigned char *buf = pod->line6.buffer_message;
+
+       if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
+               pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
+               pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
+                                (int) buf[10];
+               pod_startup3(pod);
+               return;
+       }
+
+       /* Only look for sysex messages from this device */
+       if (buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE) &&
+           buf[0] != (LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN)) {
+               return;
+       }
+       if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) != 0)
+               return;
+
+       if (buf[5] == POD_SYSEX_SYSTEM && buf[6] == POD_MONITOR_LEVEL) {
+               short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) |
+                             ((int)buf[9] << 4) | (int)buf[10];
+               pod->monitor_level = value;
+       }
+}
+
+/*
+       Send system parameter (from integer).
+*/
+static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
+                                   int code)
+{
+       char *sysex;
+       static const int size = 5;
+
+       sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
+       if (!sysex)
+               return -ENOMEM;
+       sysex[SYSEX_DATA_OFS] = code;
+       sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
+       sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
+       sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
+       sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
+       line6_send_sysex_message(&pod->line6, sysex, size);
+       kfree(sysex);
+       return 0;
+}
+
+/*
+       "read" request on "serial_number" special file.
+*/
+static ssize_t serial_number_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct usb_interface *interface = to_usb_interface(dev);
+       struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+       return sprintf(buf, "%d\n", pod->serial_number);
+}
+
+/*
+       "read" request on "firmware_version" special file.
+*/
+static ssize_t firmware_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct usb_interface *interface = to_usb_interface(dev);
+       struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+       return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
+                      pod->firmware_version % 100);
+}
+
+/*
+       "read" request on "device_id" special file.
+*/
+static ssize_t device_id_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct usb_interface *interface = to_usb_interface(dev);
+       struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+       return sprintf(buf, "%d\n", pod->device_id);
+}
+
+/*
+       POD startup procedure.
+       This is a sequence of functions with special requirements (e.g., must
+       not run immediately after initialization, must not run in interrupt
+       context). After the last one has finished, the device is ready to use.
+*/
+
+static void pod_startup1(struct usb_line6_pod *pod)
+{
+       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
+
+       /* delay startup procedure: */
+       line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
+                         (unsigned long)pod);
+}
+
+static void pod_startup2(unsigned long data)
+{
+       struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
+       struct usb_line6 *line6 = &pod->line6;
+
+       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
+
+       /* request firmware version: */
+       line6_version_request_async(line6);
+}
+
+static void pod_startup3(struct usb_line6_pod *pod)
+{
+       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
+
+       /* schedule work for global work queue: */
+       schedule_work(&pod->startup_work);
+}
+
+static void pod_startup4(struct work_struct *work)
+{
+       struct usb_line6_pod *pod =
+           container_of(work, struct usb_line6_pod, startup_work);
+       struct usb_line6 *line6 = &pod->line6;
+
+       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
+
+       /* serial number: */
+       line6_read_serial_number(&pod->line6, &pod->serial_number);
+
+       /* ALSA audio interface: */
+       snd_card_register(line6->card);
+}
+
+/* POD special files: */
+static DEVICE_ATTR_RO(device_id);
+static DEVICE_ATTR_RO(firmware_version);
+static DEVICE_ATTR_RO(serial_number);
+
+/* control info callback */
+static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 65535;
+       return 0;
+}
+
+/* control get callback */
+static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+
+       ucontrol->value.integer.value[0] = pod->monitor_level;
+       return 0;
+}
+
+/* control put callback */
+static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+
+       if (ucontrol->value.integer.value[0] == pod->monitor_level)
+               return 0;
+
+       pod->monitor_level = ucontrol->value.integer.value[0];
+       pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
+                                POD_MONITOR_LEVEL);
+       return 1;
+}
+
+/* control definition */
+static struct snd_kcontrol_new pod_control_monitor = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Monitor Playback Volume",
+       .index = 0,
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+       .info = snd_pod_control_monitor_info,
+       .get = snd_pod_control_monitor_get,
+       .put = snd_pod_control_monitor_put
+};
+
+/*
+       POD device disconnected.
+*/
+static void line6_pod_disconnect(struct usb_line6 *line6)
+{
+       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
+       struct device *dev = line6->ifcdev;
+
+       /* remove sysfs entries: */
+       device_remove_file(dev, &dev_attr_device_id);
+       device_remove_file(dev, &dev_attr_firmware_version);
+       device_remove_file(dev, &dev_attr_serial_number);
+
+       del_timer_sync(&pod->startup_timer);
+       cancel_work_sync(&pod->startup_work);
+}
+
+/*
+       Create sysfs entries.
+*/
+static int pod_create_files2(struct device *dev)
+{
+       int err;
+
+       err = device_create_file(dev, &dev_attr_device_id);
+       if (err < 0)
+               return err;
+       err = device_create_file(dev, &dev_attr_firmware_version);
+       if (err < 0)
+               return err;
+       err = device_create_file(dev, &dev_attr_serial_number);
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+/*
+        Try to init POD device.
+*/
+static int pod_init(struct usb_line6 *line6,
+                   const struct usb_device_id *id)
+{
+       int err;
+       struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
+
+       line6->process_message = line6_pod_process_message;
+       line6->disconnect = line6_pod_disconnect;
+
+       init_timer(&pod->startup_timer);
+       INIT_WORK(&pod->startup_work, pod_startup4);
+
+       /* create sysfs entries: */
+       err = pod_create_files2(line6->ifcdev);
+       if (err < 0)
+               return err;
+
+       /* initialize MIDI subsystem: */
+       err = line6_init_midi(line6);
+       if (err < 0)
+               return err;
+
+       /* initialize PCM subsystem: */
+       err = line6_init_pcm(line6, &pod_pcm_properties);
+       if (err < 0)
+               return err;
+
+       /* register monitor control: */
+       err = snd_ctl_add(line6->card,
+                         snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
+       if (err < 0)
+               return err;
+
+       /*
+          When the sound card is registered at this point, the PODxt Live
+          displays "Invalid Code Error 07", so we do it later in the event
+          handler.
+        */
+
+       if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
+               pod->monitor_level = POD_SYSTEM_INVALID;
+
+               /* initiate startup procedure: */
+               pod_startup1(pod);
+       }
+
+       return 0;
+}
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id pod_id_table[] = {
+       { LINE6_DEVICE(0x4250),    .driver_info = LINE6_BASSPODXT },
+       { LINE6_DEVICE(0x4642),    .driver_info = LINE6_BASSPODXTLIVE },
+       { LINE6_DEVICE(0x4252),    .driver_info = LINE6_BASSPODXTPRO },
+       { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD },
+       { LINE6_DEVICE(0x5044),    .driver_info = LINE6_PODXT },
+       { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD },
+       { LINE6_DEVICE(0x5050),    .driver_info = LINE6_PODXTPRO },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, pod_id_table);
+
+static const struct line6_properties pod_properties_table[] = {
+       [LINE6_BASSPODXT] = {
+               .id = "BassPODxt",
+               .name = "BassPODxt",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_BASSPODXTLIVE] = {
+               .id = "BassPODxtLive",
+               .name = "BassPODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_BASSPODXTPRO] = {
+               .id = "BassPODxtPro",
+               .name = "BassPODxt Pro",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_POCKETPOD] = {
+               .id = "PocketPOD",
+               .name = "Pocket POD",
+               .capabilities   = LINE6_CAP_CONTROL,
+               .altsetting = 0,
+               .ep_ctrl_r = 0x82,
+               .ep_ctrl_w = 0x02,
+               /* no audio channel */
+       },
+       [LINE6_PODXT] = {
+               .id = "PODxt",
+               .name = "PODxt",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODXTLIVE_POD] = {
+               .id = "PODxtLive",
+               .name = "PODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODXTPRO] = {
+               .id = "PODxtPro",
+               .name = "PODxt Pro",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+};
+
+/*
+       Probe USB device.
+*/
+static int pod_probe(struct usb_interface *interface,
+                    const struct usb_device_id *id)
+{
+       return line6_probe(interface, id,
+                          &pod_properties_table[id->driver_info],
+                          pod_init, sizeof(struct usb_line6_pod));
+}
+
+static struct usb_driver pod_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = pod_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = pod_id_table,
+};
+
+module_usb_driver(pod_driver);
+
+MODULE_DESCRIPTION("Line 6 POD USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
new file mode 100644 (file)
index 0000000..43c3988
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Line 6 Pod HD
+ *
+ * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.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, version 2.
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "pcm.h"
+#include "usbdefs.h"
+
+enum {
+       LINE6_PODHD300,
+       LINE6_PODHD400,
+       LINE6_PODHD500_0,
+       LINE6_PODHD500_1,
+};
+
+struct usb_line6_podhd {
+       /**
+               Generic Line 6 USB data.
+       */
+       struct usb_line6 line6;
+};
+
+#define PODHD_BYTES_PER_FRAME 6        /* 24bit audio (stereo) */
+
+static struct snd_ratden podhd_ratden = {
+       .num_min = 48000,
+       .num_max = 48000,
+       .num_step = 1,
+       .den = 1,
+};
+
+static struct line6_pcm_properties podhd_pcm_properties = {
+       .snd_line6_playback_hw = {
+                                 .info = (SNDRV_PCM_INFO_MMAP |
+                                          SNDRV_PCM_INFO_INTERLEAVED |
+                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                          SNDRV_PCM_INFO_MMAP_VALID |
+                                          SNDRV_PCM_INFO_PAUSE |
+                                          SNDRV_PCM_INFO_SYNC_START),
+                                 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                 .rates = SNDRV_PCM_RATE_48000,
+                                 .rate_min = 48000,
+                                 .rate_max = 48000,
+                                 .channels_min = 2,
+                                 .channels_max = 2,
+                                 .buffer_bytes_max = 60000,
+                                 .period_bytes_min = 64,
+                                 .period_bytes_max = 8192,
+                                 .periods_min = 1,
+                                 .periods_max = 1024},
+       .snd_line6_capture_hw = {
+                                .info = (SNDRV_PCM_INFO_MMAP |
+                                         SNDRV_PCM_INFO_INTERLEAVED |
+                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                         SNDRV_PCM_INFO_MMAP_VALID |
+                                         SNDRV_PCM_INFO_SYNC_START),
+                                .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                .rates = SNDRV_PCM_RATE_48000,
+                                .rate_min = 48000,
+                                .rate_max = 48000,
+                                .channels_min = 2,
+                                .channels_max = 2,
+                                .buffer_bytes_max = 60000,
+                                .period_bytes_min = 64,
+                                .period_bytes_max = 8192,
+                                .periods_min = 1,
+                                .periods_max = 1024},
+       .snd_line6_rates = {
+                           .nrats = 1,
+                           .rats = &podhd_ratden},
+       .bytes_per_frame = PODHD_BYTES_PER_FRAME
+};
+
+/*
+       Try to init POD HD device.
+*/
+static int podhd_init(struct usb_line6 *line6,
+                     const struct usb_device_id *id)
+{
+       int err;
+
+       /* initialize MIDI subsystem: */
+       err = line6_init_midi(line6);
+       if (err < 0)
+               return err;
+
+       /* initialize PCM subsystem: */
+       err = line6_init_pcm(line6, &podhd_pcm_properties);
+       if (err < 0)
+               return err;
+
+       /* register USB audio system: */
+       return snd_card_register(line6->card);
+}
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id podhd_id_table[] = {
+       { LINE6_DEVICE(0x5057),    .driver_info = LINE6_PODHD300 },
+       { LINE6_DEVICE(0x5058),    .driver_info = LINE6_PODHD400 },
+       { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
+       { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, podhd_id_table);
+
+static const struct line6_properties podhd_properties_table[] = {
+       [LINE6_PODHD300] = {
+               .id = "PODHD300",
+               .name = "POD HD300",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODHD400] = {
+               .id = "PODHD400",
+               .name = "POD HD400",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 5,
+               .ep_ctrl_r = 0x84,
+               .ep_ctrl_w = 0x03,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODHD500_0] = {
+               .id = "PODHD500",
+               .name = "POD HD500",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x81,
+               .ep_ctrl_w = 0x01,
+               .ep_audio_r = 0x86,
+               .ep_audio_w = 0x02,
+       },
+       [LINE6_PODHD500_1] = {
+               .id = "PODHD500",
+               .name = "POD HD500",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x81,
+               .ep_ctrl_w = 0x01,
+               .ep_audio_r = 0x86,
+               .ep_audio_w = 0x02,
+       },
+};
+
+/*
+       Probe USB device.
+*/
+static int podhd_probe(struct usb_interface *interface,
+                      const struct usb_device_id *id)
+{
+       return line6_probe(interface, id,
+                          &podhd_properties_table[id->driver_info],
+                          podhd_init, sizeof(struct usb_line6_podhd));
+}
+
+static struct usb_driver podhd_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = podhd_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = podhd_id_table,
+};
+
+module_usb_driver(podhd_driver);
+
+MODULE_DESCRIPTION("Line 6 PODHD USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/revision.h b/sound/usb/line6/revision.h
new file mode 100644 (file)
index 0000000..b4eee2b
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef DRIVER_REVISION
+/* current subversion revision */
+#define DRIVER_REVISION " (904)"
+#endif
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
new file mode 100644 (file)
index 0000000..819e06b
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *                         Emil Myhrman (emil.myhrman@gmail.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, version 2.
+ *
+ */
+
+#include <linux/wait.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <sound/core.h>
+#include <sound/control.h>
+
+#include "capture.h"
+#include "driver.h"
+#include "playback.h"
+#include "usbdefs.h"
+
+enum line6_device_type {
+       LINE6_GUITARPORT,
+       LINE6_PODSTUDIO_GX,
+       LINE6_PODSTUDIO_UX1,
+       LINE6_PODSTUDIO_UX2,
+       LINE6_TONEPORT_GX,
+       LINE6_TONEPORT_UX1,
+       LINE6_TONEPORT_UX2,
+};
+
+struct usb_line6_toneport;
+
+struct toneport_led {
+       struct led_classdev dev;
+       char name[64];
+       struct usb_line6_toneport *toneport;
+       bool registered;
+};
+
+struct usb_line6_toneport {
+       /**
+               Generic Line 6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Source selector.
+       */
+       int source;
+
+       /**
+               Serial number of device.
+       */
+       int serial_number;
+
+       /**
+               Firmware version (x 100).
+       */
+       int firmware_version;
+
+       /**
+                Timer for delayed PCM startup.
+       */
+       struct timer_list timer;
+
+       /**
+                Device type.
+       */
+       enum line6_device_type type;
+
+       /* LED instances */
+       struct toneport_led leds[2];
+};
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
+
+#define TONEPORT_PCM_DELAY 1
+
+static struct snd_ratden toneport_ratden = {
+       .num_min = 44100,
+       .num_max = 44100,
+       .num_step = 1,
+       .den = 1
+};
+
+static struct line6_pcm_properties toneport_pcm_properties = {
+       .snd_line6_playback_hw = {
+                                 .info = (SNDRV_PCM_INFO_MMAP |
+                                          SNDRV_PCM_INFO_INTERLEAVED |
+                                          SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                          SNDRV_PCM_INFO_MMAP_VALID |
+                                          SNDRV_PCM_INFO_PAUSE |
+                                          SNDRV_PCM_INFO_SYNC_START),
+                                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                                 .rates = SNDRV_PCM_RATE_KNOT,
+                                 .rate_min = 44100,
+                                 .rate_max = 44100,
+                                 .channels_min = 2,
+                                 .channels_max = 2,
+                                 .buffer_bytes_max = 60000,
+                                 .period_bytes_min = 64,
+                                 .period_bytes_max = 8192,
+                                 .periods_min = 1,
+                                 .periods_max = 1024},
+       .snd_line6_capture_hw = {
+                                .info = (SNDRV_PCM_INFO_MMAP |
+                                         SNDRV_PCM_INFO_INTERLEAVED |
+                                         SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                         SNDRV_PCM_INFO_MMAP_VALID |
+                                         SNDRV_PCM_INFO_SYNC_START),
+                                .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                                .rates = SNDRV_PCM_RATE_KNOT,
+                                .rate_min = 44100,
+                                .rate_max = 44100,
+                                .channels_min = 2,
+                                .channels_max = 2,
+                                .buffer_bytes_max = 60000,
+                                .period_bytes_min = 64,
+                                .period_bytes_max = 8192,
+                                .periods_min = 1,
+                                .periods_max = 1024},
+       .snd_line6_rates = {
+                           .nrats = 1,
+                           .rats = &toneport_ratden},
+       .bytes_per_frame = 4
+};
+
+static const struct {
+       const char *name;
+       int code;
+} toneport_source_info[] = {
+       {"Microphone", 0x0a01},
+       {"Line", 0x0801},
+       {"Instrument", 0x0b01},
+       {"Inst & Mic", 0x0901}
+};
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
+{
+       int ret;
+
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                             cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
+
+       if (ret < 0) {
+               dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+/* monitor info callback */
+static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 256;
+       return 0;
+}
+
+/* monitor get callback */
+static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = line6pcm->volume_monitor;
+       return 0;
+}
+
+/* monitor put callback */
+static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       int err;
+
+       if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
+               return 0;
+
+       line6pcm->volume_monitor = ucontrol->value.integer.value[0];
+
+       if (line6pcm->volume_monitor > 0) {
+               err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR);
+               if (err < 0) {
+                       line6pcm->volume_monitor = 0;
+                       line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR);
+                       return err;
+               }
+       } else {
+               line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR);
+       }
+
+       return 1;
+}
+
+/* source info callback */
+static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_info *uinfo)
+{
+       const int size = ARRAY_SIZE(toneport_source_info);
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+       uinfo->count = 1;
+       uinfo->value.enumerated.items = size;
+
+       if (uinfo->value.enumerated.item >= size)
+               uinfo->value.enumerated.item = size - 1;
+
+       strcpy(uinfo->value.enumerated.name,
+              toneport_source_info[uinfo->value.enumerated.item].name);
+
+       return 0;
+}
+
+/* source get callback */
+static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       struct usb_line6_toneport *toneport =
+           (struct usb_line6_toneport *)line6pcm->line6;
+       ucontrol->value.enumerated.item[0] = toneport->source;
+       return 0;
+}
+
+/* source put callback */
+static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+       struct usb_line6_toneport *toneport =
+           (struct usb_line6_toneport *)line6pcm->line6;
+       unsigned int source;
+
+       source = ucontrol->value.enumerated.item[0];
+       if (source >= ARRAY_SIZE(toneport_source_info))
+               return -EINVAL;
+       if (source == toneport->source)
+               return 0;
+
+       toneport->source = source;
+       toneport_send_cmd(toneport->line6.usbdev,
+                         toneport_source_info[source].code, 0x0000);
+       return 1;
+}
+
+static void toneport_start_pcm(unsigned long arg)
+{
+       struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
+       struct usb_line6 *line6 = &toneport->line6;
+
+       line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR);
+}
+
+/* control definition */
+static struct snd_kcontrol_new toneport_control_monitor = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Monitor Playback Volume",
+       .index = 0,
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+       .info = snd_toneport_monitor_info,
+       .get = snd_toneport_monitor_get,
+       .put = snd_toneport_monitor_put
+};
+
+/* source selector definition */
+static struct snd_kcontrol_new toneport_control_source = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "PCM Capture Source",
+       .index = 0,
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+       .info = snd_toneport_source_info,
+       .get = snd_toneport_source_get,
+       .put = snd_toneport_source_put
+};
+
+/*
+       For the led on Guitarport.
+       Brightness goes from 0x00 to 0x26. Set a value above this to have led
+       blink.
+       (void cmd_0x02(byte red, byte green)
+*/
+
+static bool toneport_has_led(enum line6_device_type type)
+{
+       return
+           (type == LINE6_GUITARPORT) ||
+           (type == LINE6_TONEPORT_GX);
+       /* add your device here if you are missing support for the LEDs */
+}
+
+static const char * const led_colors[2] = { "red", "green" };
+static const int led_init_vals[2] = { 0x00, 0x26 };
+
+static void toneport_update_led(struct usb_line6_toneport *toneport)
+{
+       toneport_send_cmd(toneport->line6.usbdev,
+                         (toneport->leds[0].dev.brightness << 8) | 0x0002,
+                         toneport->leds[1].dev.brightness);
+}
+
+static void toneport_led_brightness_set(struct led_classdev *led_cdev,
+                                       enum led_brightness brightness)
+{
+       struct toneport_led *leds =
+               container_of(led_cdev, struct toneport_led, dev);
+       toneport_update_led(leds->toneport);
+}
+
+static int toneport_init_leds(struct usb_line6_toneport *toneport)
+{
+       struct device *dev = &toneport->line6.usbdev->dev;
+       int i, err;
+
+       for (i = 0; i < 2; i++) {
+               struct toneport_led *led = &toneport->leds[i];
+               struct led_classdev *leddev = &led->dev;
+
+               led->toneport = toneport;
+               snprintf(led->name, sizeof(led->name), "%s::%s",
+                        dev_name(dev), led_colors[i]);
+               leddev->name = led->name;
+               leddev->brightness = led_init_vals[i];
+               leddev->max_brightness = 0x26;
+               leddev->brightness_set = toneport_led_brightness_set;
+               err = led_classdev_register(dev, leddev);
+               if (err)
+                       return err;
+               led->registered = true;
+       }
+
+       return 0;
+}
+
+static void toneport_remove_leds(struct usb_line6_toneport *toneport)
+{
+       struct toneport_led *led;
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               led = &toneport->leds[i];
+               if (!led->registered)
+                       break;
+               led_classdev_unregister(&led->dev);
+               led->registered = false;
+       }
+}
+
+/*
+       Setup Toneport device.
+*/
+static void toneport_setup(struct usb_line6_toneport *toneport)
+{
+       int ticks;
+       struct usb_line6 *line6 = &toneport->line6;
+       struct usb_device *usbdev = line6->usbdev;
+
+       /* sync time on device with host: */
+       ticks = (int)get_seconds();
+       line6_write_data(line6, 0x80c6, &ticks, 4);
+
+       /* enable device: */
+       toneport_send_cmd(usbdev, 0x0301, 0x0000);
+
+       /* initialize source select: */
+       switch (toneport->type) {
+       case LINE6_TONEPORT_UX1:
+       case LINE6_TONEPORT_UX2:
+       case LINE6_PODSTUDIO_UX1:
+       case LINE6_PODSTUDIO_UX2:
+               toneport_send_cmd(usbdev,
+                                 toneport_source_info[toneport->source].code,
+                                 0x0000);
+       default:
+               break;
+       }
+
+       if (toneport_has_led(toneport->type))
+               toneport_update_led(toneport);
+
+       mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
+}
+
+/*
+       Toneport device disconnected.
+*/
+static void line6_toneport_disconnect(struct usb_line6 *line6)
+{
+       struct usb_line6_toneport *toneport =
+               (struct usb_line6_toneport *)line6;
+
+       del_timer_sync(&toneport->timer);
+
+       if (toneport_has_led(toneport->type))
+               toneport_remove_leds(toneport);
+}
+
+
+/*
+        Try to init Toneport device.
+*/
+static int toneport_init(struct usb_line6 *line6,
+                        const struct usb_device_id *id)
+{
+       int err;
+       struct usb_line6_toneport *toneport =  (struct usb_line6_toneport *) line6;
+
+       toneport->type = id->driver_info;
+       setup_timer(&toneport->timer, toneport_start_pcm,
+                   (unsigned long)toneport);
+
+       line6->disconnect = line6_toneport_disconnect;
+
+       /* initialize PCM subsystem: */
+       err = line6_init_pcm(line6, &toneport_pcm_properties);
+       if (err < 0)
+               return err;
+
+       /* register monitor control: */
+       err = snd_ctl_add(line6->card,
+                         snd_ctl_new1(&toneport_control_monitor,
+                                      line6->line6pcm));
+       if (err < 0)
+               return err;
+
+       /* register source select control: */
+       switch (toneport->type) {
+       case LINE6_TONEPORT_UX1:
+       case LINE6_TONEPORT_UX2:
+       case LINE6_PODSTUDIO_UX1:
+       case LINE6_PODSTUDIO_UX2:
+               err =
+                   snd_ctl_add(line6->card,
+                               snd_ctl_new1(&toneport_control_source,
+                                            line6->line6pcm));
+               if (err < 0)
+                       return err;
+
+       default:
+               break;
+       }
+
+       line6_read_serial_number(line6, &toneport->serial_number);
+       line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
+
+       if (toneport_has_led(toneport->type)) {
+               err = toneport_init_leds(toneport);
+               if (err < 0)
+                       return err;
+       }
+
+       toneport_setup(toneport);
+
+       /* register audio system: */
+       return snd_card_register(line6->card);
+}
+
+#ifdef CONFIG_PM
+/*
+       Resume Toneport device after reset.
+*/
+static int toneport_reset_resume(struct usb_interface *interface)
+{
+       toneport_setup(usb_get_intfdata(interface));
+       return line6_resume(interface);
+}
+#endif
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id toneport_id_table[] = {
+       { LINE6_DEVICE(0x4750),    .driver_info = LINE6_GUITARPORT },
+       { LINE6_DEVICE(0x4153),    .driver_info = LINE6_PODSTUDIO_GX },
+       { LINE6_DEVICE(0x4150),    .driver_info = LINE6_PODSTUDIO_UX1 },
+       { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 },
+       { LINE6_DEVICE(0x4147),    .driver_info = LINE6_TONEPORT_GX },
+       { LINE6_DEVICE(0x4141),    .driver_info = LINE6_TONEPORT_UX1 },
+       { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, toneport_id_table);
+
+static const struct line6_properties toneport_properties_table[] = {
+       [LINE6_GUITARPORT] = {
+               .id = "GuitarPort",
+               .name = "GuitarPort",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_GX] = {
+               .id = "PODStudioGX",
+               .name = "POD Studio GX",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_UX1] = {
+               .id = "PODStudioUX1",
+               .name = "POD Studio UX1",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_PODSTUDIO_UX2] = {
+               .id = "PODStudioUX2",
+               .name = "POD Studio UX2",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_GX] = {
+               .id = "TonePortGX",
+               .name = "TonePort GX",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_UX1] = {
+               .id = "TonePortUX1",
+               .name = "TonePort UX1",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* 1..4 seem to be ok */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_TONEPORT_UX2] = {
+               .id = "TonePortUX2",
+               .name = "TonePort UX2",
+               .capabilities   = LINE6_CAP_PCM,
+               .altsetting = 2,  /* defaults to 44.1kHz, 16-bit */
+               /* no control channel */
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+};
+
+/*
+       Probe USB device.
+*/
+static int toneport_probe(struct usb_interface *interface,
+                         const struct usb_device_id *id)
+{
+       return line6_probe(interface, id,
+                          &toneport_properties_table[id->driver_info],
+                          toneport_init, sizeof(struct usb_line6_toneport));
+}
+
+static struct usb_driver toneport_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = toneport_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = toneport_reset_resume,
+#endif
+       .id_table = toneport_id_table,
+};
+
+module_usb_driver(toneport_driver);
+
+MODULE_DESCRIPTION("TonePort USB driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/usb/line6/usbdefs.h b/sound/usb/line6/usbdefs.h
new file mode 100644 (file)
index 0000000..5ef7bcd
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#ifndef USBDEFS_H
+#define USBDEFS_H
+
+#define USB_INTERVALS_PER_SECOND 1000
+
+/* device supports settings parameter via USB */
+#define LINE6_CAP_CONTROL (1 << 0)
+/* device supports PCM input/output via USB */
+#define LINE6_CAP_PCM (1 << 1)
+/* device support hardware monitoring */
+#define LINE6_CAP_HWMON (1 << 2)
+
+#define LINE6_FALLBACK_INTERVAL 10
+#define LINE6_FALLBACK_MAXPACKETSIZE 16
+
+#endif
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
new file mode 100644 (file)
index 0000000..9701ffa
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Line 6 Linux USB driver
+ *
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *     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, version 2.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/module.h>
+#include <sound/core.h>
+
+#include "driver.h"
+#include "usbdefs.h"
+
+#define VARIAX_STARTUP_DELAY1 1000
+#define VARIAX_STARTUP_DELAY3 100
+#define VARIAX_STARTUP_DELAY4 100
+
+/*
+       Stages of Variax startup procedure
+*/
+enum {
+       VARIAX_STARTUP_INIT = 1,
+       VARIAX_STARTUP_VERSIONREQ,
+       VARIAX_STARTUP_WAIT,
+       VARIAX_STARTUP_ACTIVATE,
+       VARIAX_STARTUP_WORKQUEUE,
+       VARIAX_STARTUP_SETUP,
+       VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
+};
+
+enum {
+       LINE6_PODXTLIVE_VARIAX,
+       LINE6_VARIAX
+};
+
+struct usb_line6_variax {
+       /**
+               Generic Line 6 USB data.
+       */
+       struct usb_line6 line6;
+
+       /**
+               Buffer for activation code.
+       */
+       unsigned char *buffer_activate;
+
+       /**
+               Handler for device initializaton.
+       */
+       struct work_struct startup_work;
+
+       /**
+               Timers for device initializaton.
+       */
+       struct timer_list startup_timer1;
+       struct timer_list startup_timer2;
+
+       /**
+               Current progress in startup procedure.
+       */
+       int startup_progress;
+};
+
+#define VARIAX_OFFSET_ACTIVATE 7
+
+/*
+       This message is sent by the device during initialization and identifies
+       the connected guitar version.
+*/
+static const char variax_init_version[] = {
+       0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
+       0x07, 0x00, 0x00, 0x00
+};
+
+/*
+       This message is the last one sent by the device during initialization.
+*/
+static const char variax_init_done[] = {
+       0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
+};
+
+static const char variax_activate[] = {
+       0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
+       0xf7
+};
+
+/* forward declarations: */
+static void variax_startup2(unsigned long data);
+static void variax_startup4(unsigned long data);
+static void variax_startup5(unsigned long data);
+
+static void variax_activate_async(struct usb_line6_variax *variax, int a)
+{
+       variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
+       line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+                                    sizeof(variax_activate));
+}
+
+/*
+       Variax startup procedure.
+       This is a sequence of functions with special requirements (e.g., must
+       not run immediately after initialization, must not run in interrupt
+       context). After the last one has finished, the device is ready to use.
+*/
+
+static void variax_startup1(struct usb_line6_variax *variax)
+{
+       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
+
+       /* delay startup procedure: */
+       line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
+                         variax_startup2, (unsigned long)variax);
+}
+
+static void variax_startup2(unsigned long data)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+       struct usb_line6 *line6 = &variax->line6;
+
+       /* schedule another startup procedure until startup is complete: */
+       if (variax->startup_progress >= VARIAX_STARTUP_LAST)
+               return;
+
+       variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
+       line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
+                         variax_startup2, (unsigned long)variax);
+
+       /* request firmware version: */
+       line6_version_request_async(line6);
+}
+
+static void variax_startup3(struct usb_line6_variax *variax)
+{
+       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
+
+       /* delay startup procedure: */
+       line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
+                         variax_startup4, (unsigned long)variax);
+}
+
+static void variax_startup4(unsigned long data)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+
+       CHECK_STARTUP_PROGRESS(variax->startup_progress,
+                              VARIAX_STARTUP_ACTIVATE);
+
+       /* activate device: */
+       variax_activate_async(variax, 1);
+       line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
+                         variax_startup5, (unsigned long)variax);
+}
+
+static void variax_startup5(unsigned long data)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+
+       CHECK_STARTUP_PROGRESS(variax->startup_progress,
+                              VARIAX_STARTUP_WORKQUEUE);
+
+       /* schedule work for global work queue: */
+       schedule_work(&variax->startup_work);
+}
+
+static void variax_startup6(struct work_struct *work)
+{
+       struct usb_line6_variax *variax =
+           container_of(work, struct usb_line6_variax, startup_work);
+
+       CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
+
+       /* ALSA audio interface: */
+       snd_card_register(variax->line6.card);
+}
+
+/*
+       Process a completely received message.
+*/
+static void line6_variax_process_message(struct usb_line6 *line6)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
+       const unsigned char *buf = variax->line6.buffer_message;
+
+       switch (buf[0]) {
+       case LINE6_RESET:
+               dev_info(variax->line6.ifcdev, "VARIAX reset\n");
+               break;
+
+       case LINE6_SYSEX_BEGIN:
+               if (memcmp(buf + 1, variax_init_version + 1,
+                          sizeof(variax_init_version) - 1) == 0) {
+                       variax_startup3(variax);
+               } else if (memcmp(buf + 1, variax_init_done + 1,
+                                 sizeof(variax_init_done) - 1) == 0) {
+                       /* notify of complete initialization: */
+                       variax_startup4((unsigned long)variax);
+               }
+               break;
+       }
+}
+
+/*
+       Variax destructor.
+*/
+static void line6_variax_disconnect(struct usb_line6 *line6)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
+
+       del_timer(&variax->startup_timer1);
+       del_timer(&variax->startup_timer2);
+       cancel_work_sync(&variax->startup_work);
+
+       kfree(variax->buffer_activate);
+}
+
+/*
+        Try to init workbench device.
+*/
+static int variax_init(struct usb_line6 *line6,
+                      const struct usb_device_id *id)
+{
+       struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
+       int err;
+
+       line6->process_message = line6_variax_process_message;
+       line6->disconnect = line6_variax_disconnect;
+
+       init_timer(&variax->startup_timer1);
+       init_timer(&variax->startup_timer2);
+       INIT_WORK(&variax->startup_work, variax_startup6);
+
+       /* initialize USB buffers: */
+       variax->buffer_activate = kmemdup(variax_activate,
+                                         sizeof(variax_activate), GFP_KERNEL);
+
+       if (variax->buffer_activate == NULL)
+               return -ENOMEM;
+
+       /* initialize MIDI subsystem: */
+       err = line6_init_midi(&variax->line6);
+       if (err < 0)
+               return err;
+
+       /* initiate startup procedure: */
+       variax_startup1(variax);
+       return 0;
+}
+
+#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
+#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
+
+/* table of devices that work with this driver */
+static const struct usb_device_id variax_id_table[] = {
+       { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX },
+       { LINE6_DEVICE(0x534d),    .driver_info = LINE6_VARIAX },
+       {}
+};
+
+MODULE_DEVICE_TABLE(usb, variax_id_table);
+
+static const struct line6_properties variax_properties_table[] = {
+       [LINE6_PODXTLIVE_VARIAX] = {
+               .id = "PODxtLive",
+               .name = "PODxt Live",
+               .capabilities   = LINE6_CAP_CONTROL
+                               | LINE6_CAP_PCM
+                               | LINE6_CAP_HWMON,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x86,
+               .ep_ctrl_w = 0x05,
+               .ep_audio_r = 0x82,
+               .ep_audio_w = 0x01,
+       },
+       [LINE6_VARIAX] = {
+               .id = "Variax",
+               .name = "Variax Workbench",
+               .capabilities   = LINE6_CAP_CONTROL,
+               .altsetting = 1,
+               .ep_ctrl_r = 0x82,
+               .ep_ctrl_w = 0x01,
+               /* no audio channel */
+       }
+};
+
+/*
+       Probe USB device.
+*/
+static int variax_probe(struct usb_interface *interface,
+                       const struct usb_device_id *id)
+{
+       return line6_probe(interface, id,
+                          &variax_properties_table[id->driver_info],
+                          variax_init, sizeof(struct usb_line6_variax));
+}
+
+static struct usb_driver variax_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = variax_probe,
+       .disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+       .suspend = line6_suspend,
+       .resume = line6_resume,
+       .reset_resume = line6_resume,
+#endif
+       .id_table = variax_id_table,
+};
+
+module_usb_driver(variax_driver);
+
+MODULE_DESCRIPTION("Vairax Workbench USB driver");
+MODULE_LICENSE("GPL");
index 5bfb695..417ebb1 100644 (file)
@@ -2292,14 +2292,13 @@ int snd_usbmidi_create(struct snd_card *card,
        umidi->iface = iface;
        umidi->quirk = quirk;
        umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
-       init_timer(&umidi->error_timer);
        spin_lock_init(&umidi->disc_lock);
        init_rwsem(&umidi->disc_rwsem);
        mutex_init(&umidi->mutex);
        umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
                               le16_to_cpu(umidi->dev->descriptor.idProduct));
-       umidi->error_timer.function = snd_usbmidi_error_timer;
-       umidi->error_timer.data = (unsigned long)umidi;
+       setup_timer(&umidi->error_timer, snd_usbmidi_error_timer,
+                   (unsigned long)umidi);
 
        /* detect the endpoint(s) to use */
        memset(endpoints, 0, sizeof(endpoints));
index 0a598af..67d4765 100644 (file)
@@ -2486,6 +2486,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
        }
 },
 
+{
+       /* Akai MPC Element */
+       USB_DEVICE(0x09e8, 0x0021),
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = & (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_IGNORE_INTERFACE
+                       },
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_MIDI_STANDARD_INTERFACE
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
+       }
+},
+
 /* TerraTec devices */
 {
        USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
index 4dd74ab..9036900 100644 (file)
@@ -1,76 +1,7 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+#ifndef __USB_STREAM_H
+#define __USB_STREAM_H
 
-#define USB_STREAM_INTERFACE_VERSION 2
-
-#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
-       _IOW('H', 0x90, struct usb_stream_config)
-
-struct usb_stream_packet {
-       unsigned offset;
-       unsigned length;
-};
-
-
-struct usb_stream_config {
-       unsigned version;
-       unsigned sample_rate;
-       unsigned period_frames;
-       unsigned frame_size;
-};
-
-struct usb_stream {
-       struct usb_stream_config cfg;
-       unsigned read_size;
-       unsigned write_size;
-
-       int period_size;
-
-       unsigned state;
-
-       int idle_insize;
-       int idle_outsize;
-       int sync_packet;
-       unsigned insize_done;
-       unsigned periods_done;
-       unsigned periods_polled;
-
-       struct usb_stream_packet outpacket[2];
-       unsigned                 inpackets;
-       unsigned                 inpacket_head;
-       unsigned                 inpacket_split;
-       unsigned                 inpacket_split_at;
-       unsigned                 next_inpacket_split;
-       unsigned                 next_inpacket_split_at;
-       struct usb_stream_packet inpacket[0];
-};
-
-enum usb_stream_state {
-       usb_stream_invalid,
-       usb_stream_stopped,
-       usb_stream_sync0,
-       usb_stream_sync1,
-       usb_stream_ready,
-       usb_stream_running,
-       usb_stream_xrun,
-};
-
-#if __KERNEL__
+#include <uapi/sound/usb_stream.h>
 
 #define USB_STREAM_NURBS 4
 #define USB_STREAM_URBDEPTH 4
@@ -108,5 +39,4 @@ void usb_stream_free(struct usb_stream_kernel *);
 int usb_stream_start(struct usb_stream_kernel *);
 void usb_stream_stop(struct usb_stream_kernel *);
 
-
-#endif
+#endif /* __USB_STREAM_H */