Merge tag 'asoc-v4.2-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorTakashi Iwai <tiwai@suse.de>
Mon, 31 Aug 2015 14:25:22 +0000 (16:25 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 31 Aug 2015 14:25:22 +0000 (16:25 +0200)
ASoC: Updates for v4.3

Not many updates to the core here, but an awful lot of driver updates
this time round:

 - Factoring out of AC'97 reset code into the core
 - New drivers for Cirrus CS4349, GTM601, InvenSense ICS43432, Realtek
   RT298 and ST STI controllers.
 - Machine drivers for Rockchip systems with MAX98090 and RT5645 and
   RT5650.
 - Initial driver support for Intel Skylake devices.
 - A large number of cleanups for Lars-Peter Clausen and Axel Lin.

65 files changed:
drivers/input/touchscreen/wm97xx-core.c
include/sound/hda_register.h
include/sound/hdaudio.h
include/sound/hdaudio_ext.h
sound/ac97_bus.c
sound/aoa/codecs/onyx.c
sound/aoa/codecs/tas.c
sound/aoa/fabrics/layout.c
sound/aoa/soundbus/core.c
sound/aoa/soundbus/soundbus.h
sound/firewire/bebob/bebob_pcm.c
sound/firewire/dice/dice-pcm.c
sound/firewire/fireworks/fireworks_pcm.c
sound/firewire/oxfw/oxfw-pcm.c
sound/firewire/oxfw/oxfw-stream.c
sound/hda/ext/hdac_ext_bus.c
sound/hda/ext/hdac_ext_controller.c
sound/hda/ext/hdac_ext_stream.c
sound/hda/hdac_device.c
sound/hda/hdac_regmap.c
sound/hda/hdac_stream.c
sound/hda/hdac_sysfs.c
sound/pci/echoaudio/darla20_dsp.c
sound/pci/echoaudio/darla24_dsp.c
sound/pci/echoaudio/echo3g_dsp.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/echoaudio.h
sound/pci/echoaudio/echoaudio_3g.c
sound/pci/echoaudio/echoaudio_dsp.c
sound/pci/echoaudio/echoaudio_gml.c
sound/pci/echoaudio/gina20.c
sound/pci/echoaudio/gina20_dsp.c
sound/pci/echoaudio/gina24_dsp.c
sound/pci/echoaudio/indigo_dsp.c
sound/pci/echoaudio/indigodj_dsp.c
sound/pci/echoaudio/indigodjx_dsp.c
sound/pci/echoaudio/indigoio_dsp.c
sound/pci/echoaudio/indigoiox_dsp.c
sound/pci/echoaudio/layla20.c
sound/pci/echoaudio/layla20_dsp.c
sound/pci/echoaudio/layla24_dsp.c
sound/pci/echoaudio/mia.c
sound/pci/echoaudio/mia_dsp.c
sound/pci/echoaudio/mona_dsp.c
sound/pci/emu10k1/emumixer.c
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/rme9652/hdsp.c
sound/ppc/keywest.c
sound/usb/card.c
sound/usb/endpoint.c
sound/usb/mixer.c
sound/usb/mixer.h
sound/usb/mixer_quirks.c
sound/usb/pcm.c
sound/usb/proc.c
sound/usb/quirks.c
sound/usb/usbaudio.h

index b1ae779..1534e9b 100644 (file)
@@ -732,8 +732,7 @@ static int wm97xx_remove(struct device *dev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int wm97xx_suspend(struct device *dev, pm_message_t state)
+static int __maybe_unused wm97xx_suspend(struct device *dev)
 {
        struct wm97xx *wm = dev_get_drvdata(dev);
        u16 reg;
@@ -765,7 +764,7 @@ static int wm97xx_suspend(struct device *dev, pm_message_t state)
        return 0;
 }
 
-static int wm97xx_resume(struct device *dev)
+static int __maybe_unused wm97xx_resume(struct device *dev)
 {
        struct wm97xx *wm = dev_get_drvdata(dev);
 
@@ -799,10 +798,7 @@ static int wm97xx_resume(struct device *dev)
        return 0;
 }
 
-#else
-#define wm97xx_suspend         NULL
-#define wm97xx_resume          NULL
-#endif
+static SIMPLE_DEV_PM_OPS(wm97xx_pm_ops, wm97xx_suspend, wm97xx_resume);
 
 /*
  * Machine specific operations
@@ -836,8 +832,7 @@ static struct device_driver wm97xx_driver = {
        .owner =        THIS_MODULE,
        .probe =        wm97xx_probe,
        .remove =       wm97xx_remove,
-       .suspend =      wm97xx_suspend,
-       .resume =       wm97xx_resume,
+       .pm =           &wm97xx_pm_ops,
 };
 
 static int __init wm97xx_init(void)
index ae995e5..2ae8812 100644 (file)
@@ -160,6 +160,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_SPB_BASE                   0x08
 /* Interval used to calculate the iterating register offset */
 #define AZX_SPB_INTERVAL               0x08
+/* SPIB base */
+#define AZX_SPB_SPIB                   0x00
+/* SPIB MAXFIFO base*/
+#define AZX_SPB_MAXFIFO                        0x04
 
 /* registers of Global Time Synchronization Capability Structure */
 #define AZX_GTS_CAP_ID                 0x1
index 4caf1fd..49bc836 100644 (file)
@@ -119,6 +119,7 @@ int snd_hdac_device_register(struct hdac_device *codec);
 void snd_hdac_device_unregister(struct hdac_device *codec);
 
 int snd_hdac_refresh_widgets(struct hdac_device *codec);
+int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec);
 
 unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
                               unsigned int verb, unsigned int parm);
@@ -164,15 +165,15 @@ static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
 }
 
 #ifdef CONFIG_PM
-void snd_hdac_power_up(struct hdac_device *codec);
-void snd_hdac_power_down(struct hdac_device *codec);
-void snd_hdac_power_up_pm(struct hdac_device *codec);
-void snd_hdac_power_down_pm(struct hdac_device *codec);
+int snd_hdac_power_up(struct hdac_device *codec);
+int snd_hdac_power_down(struct hdac_device *codec);
+int snd_hdac_power_up_pm(struct hdac_device *codec);
+int snd_hdac_power_down_pm(struct hdac_device *codec);
 #else
-static inline void snd_hdac_power_up(struct hdac_device *codec) {}
-static inline void snd_hdac_power_down(struct hdac_device *codec) {}
-static inline void snd_hdac_power_up_pm(struct hdac_device *codec) {}
-static inline void snd_hdac_power_down_pm(struct hdac_device *codec) {}
+static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
 #endif
 
 /*
@@ -437,6 +438,8 @@ void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
 struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
                                           struct snd_pcm_substream *substream);
 void snd_hdac_stream_release(struct hdac_stream *azx_dev);
+struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
+                                       int dir, int stream_tag);
 
 int snd_hdac_stream_setup(struct hdac_stream *azx_dev);
 void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev);
index 0f89df1..94210dc 100644 (file)
@@ -34,6 +34,7 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *sbus, struct device *dev,
 void snd_hdac_ext_bus_exit(struct hdac_ext_bus *sbus);
 int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *sbus, int addr);
 void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
+void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
 
 #define ebus_to_hbus(ebus)     (&(ebus)->bus)
 #define hbus_to_ebus(_bus) \
@@ -62,6 +63,8 @@ enum hdac_ext_stream_type {
  * @hstream: hdac_stream
  * @pphc_addr: processing pipe host stream pointer
  * @pplc_addr: processing pipe link stream pointer
+ * @spib_addr: software position in buffers stream pointer
+ * @fifo_addr: software position Max fifos stream pointer
  * @decoupled: stream host and link is decoupled
  * @link_locked: link is locked
  * @link_prepared: link is prepared
@@ -73,6 +76,9 @@ struct hdac_ext_stream {
        void __iomem *pphc_addr;
        void __iomem *pplc_addr;
 
+       void __iomem *spib_addr;
+       void __iomem *fifo_addr;
+
        bool decoupled:1;
        bool link_locked:1;
        bool link_prepared;
@@ -99,6 +105,11 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *bus,
                                struct hdac_ext_stream *azx_dev, bool decouple);
 void snd_hdac_ext_stop_streams(struct hdac_ext_bus *sbus);
 
+int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
+                                struct hdac_ext_stream *stream, u32 value);
+int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
+                                struct hdac_ext_stream *stream);
+
 void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
 void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
 void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
@@ -115,6 +126,7 @@ struct hdac_ext_link {
 
 int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
 int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
+int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus);
 void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
                                 int stream);
 void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
@@ -129,4 +141,63 @@ void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
        writew(((readw(addr + reg) & ~(mask)) | (val)), \
                addr + reg)
 
+
+struct hdac_ext_device;
+
+/* ops common to all codec drivers */
+struct hdac_ext_codec_ops {
+       int (*build_controls)(struct hdac_ext_device *dev);
+       int (*init)(struct hdac_ext_device *dev);
+       void (*free)(struct hdac_ext_device *dev);
+};
+
+struct hda_dai_map {
+       char *dai_name;
+       hda_nid_t nid;
+       u32     maxbps;
+};
+
+#define HDA_MAX_NIDS 16
+
+/**
+ * struct hdac_ext_device - HDAC Ext device
+ *
+ * @hdac: hdac core device
+ * @nid_list - the dai map which matches the dai-name with the nid
+ * @map_cur_idx - the idx in use in dai_map
+ * @ops - the hda codec ops common to all codec drivers
+ * @pvt_data - private data, for asoc contains asoc codec object
+ */
+struct hdac_ext_device {
+       struct hdac_device hdac;
+       struct hdac_ext_bus *ebus;
+
+       /* soc-dai to nid map */
+       struct hda_dai_map nid_list[HDA_MAX_NIDS];
+       unsigned int map_cur_idx;
+
+       /* codec ops */
+       struct hdac_ext_codec_ops ops;
+
+       void *private_data;
+};
+
+#define to_ehdac_device(dev) (container_of((dev), \
+                                struct hdac_ext_device, hdac))
+/*
+ * HD-audio codec base driver
+ */
+struct hdac_ext_driver {
+       struct hdac_driver hdac;
+
+       int     (*probe)(struct hdac_ext_device *dev);
+       int     (*remove)(struct hdac_ext_device *dev);
+       void    (*shutdown)(struct hdac_ext_device *dev);
+};
+
+int snd_hda_ext_driver_register(struct hdac_ext_driver *drv);
+void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv);
+
+#define to_ehdac_driver(_drv) container_of(_drv, struct hdac_ext_driver, hdac)
+
 #endif /* __SOUND_HDAUDIO_EXT_H */
index 55791a0..52e4bc5 100644 (file)
@@ -89,35 +89,9 @@ static int ac97_bus_match(struct device *dev, struct device_driver *drv)
        return 1;
 }
 
-#ifdef CONFIG_PM
-static int ac97_bus_suspend(struct device *dev, pm_message_t state)
-{
-       int ret = 0;
-
-       if (dev->driver && dev->driver->suspend)
-               ret = dev->driver->suspend(dev, state);
-
-       return ret;
-}
-
-static int ac97_bus_resume(struct device *dev)
-{
-       int ret = 0;
-
-       if (dev->driver && dev->driver->resume)
-               ret = dev->driver->resume(dev);
-
-       return ret;
-}
-#endif /* CONFIG_PM */
-
 struct bus_type ac97_bus_type = {
        .name           = "ac97",
        .match          = ac97_bus_match,
-#ifdef CONFIG_PM
-       .suspend        = ac97_bus_suspend,
-       .resume         = ac97_bus_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init ac97_bus_init(void)
index 23c371e..a04edff 100644 (file)
@@ -1050,7 +1050,6 @@ MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
 static struct i2c_driver onyx_driver = {
        .driver = {
                .name = "aoa_codec_onyx",
-               .owner = THIS_MODULE,
        },
        .probe = onyx_i2c_probe,
        .remove = onyx_i2c_remove,
index 364c7c4..78ed1ff 100644 (file)
@@ -939,7 +939,6 @@ MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
 static struct i2c_driver tas_driver = {
        .driver = {
                .name = "aoa_codec_tas",
-               .owner = THIS_MODULE,
        },
        .probe = tas_i2c_probe,
        .remove = tas_i2c_remove,
index 9dc5806..8f71f7e 100644 (file)
@@ -1120,10 +1120,10 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int aoa_fabric_layout_suspend(struct device *dev)
 {
-       struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
+       struct layout_dev *ldev = dev_get_drvdata(dev);
 
        if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
                ldev->gpio.methods->all_amps_off(&ldev->gpio);
@@ -1131,15 +1131,19 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta
        return 0;
 }
 
-static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
+static int aoa_fabric_layout_resume(struct device *dev)
 {
-       struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
+       struct layout_dev *ldev = dev_get_drvdata(dev);
 
        if (ldev->gpio.methods && ldev->gpio.methods->all_amps_restore)
                ldev->gpio.methods->all_amps_restore(&ldev->gpio);
 
        return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(aoa_fabric_layout_pm_ops,
+       aoa_fabric_layout_suspend, aoa_fabric_layout_resume);
+
 #endif
 
 static struct soundbus_driver aoa_soundbus_driver = {
@@ -1147,12 +1151,11 @@ static struct soundbus_driver aoa_soundbus_driver = {
        .owner = THIS_MODULE,
        .probe = aoa_fabric_layout_probe,
        .remove = aoa_fabric_layout_remove,
-#ifdef CONFIG_PM
-       .suspend = aoa_fabric_layout_suspend,
-       .resume = aoa_fabric_layout_resume,
-#endif
        .driver = {
                .owner = THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+               .pm = &aoa_fabric_layout_pm_ops,
+#endif
        }
 };
 
index 3edf736..70bcaa7 100644 (file)
@@ -126,30 +126,6 @@ static void soundbus_device_shutdown(struct device *dev)
                drv->shutdown(soundbus_dev);
 }
 
-#ifdef CONFIG_PM
-
-static int soundbus_device_suspend(struct device *dev, pm_message_t state)
-{
-       struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
-       struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
-       if (dev->driver && drv->suspend)
-               return drv->suspend(soundbus_dev, state);
-       return 0;
-}
-
-static int soundbus_device_resume(struct device * dev)
-{
-       struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
-       struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
-
-       if (dev->driver && drv->resume)
-               return drv->resume(soundbus_dev);
-       return 0;
-}
-
-#endif /* CONFIG_PM */
-
 /* soundbus_dev_attrs is declared in sysfs.c */
 ATTRIBUTE_GROUPS(soundbus_dev);
 static struct bus_type soundbus_bus_type = {
@@ -158,10 +134,6 @@ static struct bus_type soundbus_bus_type = {
        .uevent         = soundbus_uevent,
        .remove         = soundbus_device_remove,
        .shutdown       = soundbus_device_shutdown,
-#ifdef CONFIG_PM
-       .suspend        = soundbus_device_suspend,
-       .resume         = soundbus_device_resume,
-#endif
        .dev_groups     = soundbus_dev_groups,
 };
 
index 21e756c..ae40224 100644 (file)
@@ -188,8 +188,6 @@ struct soundbus_driver {
        int     (*probe)(struct soundbus_dev* dev);
        int     (*remove)(struct soundbus_dev* dev);
 
-       int     (*suspend)(struct soundbus_dev* dev, pm_message_t state);
-       int     (*resume)(struct soundbus_dev* dev);
        int     (*shutdown)(struct soundbus_dev* dev);
 
        struct device_driver driver;
index 7a2c1f5..c0f018a 100644 (file)
@@ -211,26 +211,38 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream,
                      struct snd_pcm_hw_params *hw_params)
 {
        struct snd_bebob *bebob = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
                atomic_inc(&bebob->substreams_counter);
        amdtp_stream_set_pcm_format(&bebob->tx_stream,
                                    params_format(hw_params));
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+
+       return 0;
 }
 static int
 pcm_playback_hw_params(struct snd_pcm_substream *substream,
                       struct snd_pcm_hw_params *hw_params)
 {
        struct snd_bebob *bebob = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
                atomic_inc(&bebob->substreams_counter);
        amdtp_stream_set_pcm_format(&bebob->rx_stream,
                                    params_format(hw_params));
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+
+       return 0;
 }
 
 static int
index f777145..4e67b1d 100644 (file)
@@ -230,6 +230,12 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *hw_params)
 {
        struct snd_dice *dice = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                mutex_lock(&dice->mutex);
@@ -240,13 +246,18 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
        amdtp_stream_set_pcm_format(&dice->tx_stream,
                                    params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 static int playback_hw_params(struct snd_pcm_substream *substream,
                              struct snd_pcm_hw_params *hw_params)
 {
        struct snd_dice *dice = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                mutex_lock(&dice->mutex);
@@ -257,8 +268,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
        amdtp_stream_set_pcm_format(&dice->rx_stream,
                                    params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 
 static int capture_hw_free(struct snd_pcm_substream *substream)
index 8a34753..c30b2ff 100644 (file)
@@ -244,25 +244,35 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *hw_params)
 {
        struct snd_efw *efw = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
                atomic_inc(&efw->capture_substreams);
        amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *hw_params)
 {
        struct snd_efw *efw = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
                atomic_inc(&efw->playback_substreams);
        amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 
 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
index 67ade07..9c73930 100644 (file)
@@ -231,7 +231,12 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *hw_params)
 {
        struct snd_oxfw *oxfw = substream->private_data;
+       int err;
 
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                mutex_lock(&oxfw->mutex);
@@ -241,13 +246,18 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
 
        amdtp_stream_set_pcm_format(&oxfw->tx_stream, params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *hw_params)
 {
        struct snd_oxfw *oxfw = substream->private_data;
+       int err;
+
+       err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                              params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
 
        if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
                mutex_lock(&oxfw->mutex);
@@ -257,8 +267,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
 
        amdtp_stream_set_pcm_format(&oxfw->rx_stream, params_format(hw_params));
 
-       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-                                               params_buffer_bytes(hw_params));
+       return 0;
 }
 
 static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
index 873d40f..77ad5b9 100644 (file)
@@ -512,12 +512,11 @@ assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
        if (err < 0)
                goto end;
 
-       formats[eid] = kmalloc(*len, GFP_KERNEL);
+       formats[eid] = kmemdup(buf, *len, GFP_KERNEL);
        if (formats[eid] == NULL) {
                err = -ENOMEM;
                goto end;
        }
-       memcpy(formats[eid], buf, *len);
 
        /* apply the format for each available sampling rate */
        for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
@@ -531,12 +530,11 @@ assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
                        continue;
 
                eid++;
-               formats[eid] = kmalloc(*len, GFP_KERNEL);
+               formats[eid] = kmemdup(buf, *len, GFP_KERNEL);
                if (formats[eid] == NULL) {
                        err = -ENOMEM;
                        goto end;
                }
-               memcpy(formats[eid], buf, *len);
                formats[eid][2] = avc_stream_rate_table[i];
        }
 
@@ -594,12 +592,11 @@ static int fill_stream_formats(struct snd_oxfw *oxfw,
                if (err < 0)
                        break;
 
-               formats[eid] = kmalloc(len, GFP_KERNEL);
+               formats[eid] = kmemdup(buf, len, GFP_KERNEL);
                if (formats[eid] == NULL) {
                        err = -ENOMEM;
                        break;
                }
-               memcpy(formats[eid], buf, len);
 
                /* get next entry */
                len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
index 0aa5d9e..4449d1a 100644 (file)
@@ -125,7 +125,7 @@ static void default_release(struct device *dev)
 }
 
 /**
- * snd_hdac_ext_device_init - initialize the HDA extended codec base device
+ * snd_hdac_ext_bus_device_init - initialize the HDA extended codec base device
  * @ebus: hdac extended bus to attach to
  * @addr: codec address
  *
@@ -133,14 +133,16 @@ static void default_release(struct device *dev)
  */
 int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr)
 {
+       struct hdac_ext_device *edev;
        struct hdac_device *hdev = NULL;
        struct hdac_bus *bus = ebus_to_hbus(ebus);
        char name[15];
        int ret;
 
-       hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
-       if (!hdev)
+       edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+       if (!edev)
                return -ENOMEM;
+       hdev = &edev->hdac;
 
        snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr);
 
@@ -158,6 +160,7 @@ int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr)
                snd_hdac_ext_bus_device_exit(hdev);
                return ret;
        }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);
@@ -168,7 +171,94 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);
  */
 void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev)
 {
+       struct hdac_ext_device *edev = to_ehdac_device(hdev);
+
        snd_hdac_device_exit(hdev);
-       kfree(hdev);
+       kfree(edev);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);
+
+/**
+ * snd_hdac_ext_bus_device_remove - remove HD-audio extended codec base devices
+ *
+ * @ebus: HD-audio extended bus
+ */
+void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus)
+{
+       struct hdac_device *codec, *__codec;
+       /*
+        * we need to remove all the codec devices objects created in the
+        * snd_hdac_ext_bus_device_init
+        */
+       list_for_each_entry_safe(codec, __codec, &ebus->bus.codec_list, list) {
+               snd_hdac_device_unregister(codec);
+               put_device(&codec->dev);
+       }
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_remove);
+#define dev_to_hdac(dev) (container_of((dev), \
+                       struct hdac_device, dev))
+
+static inline struct hdac_ext_driver *get_edrv(struct device *dev)
+{
+       struct hdac_driver *hdrv = drv_to_hdac_driver(dev->driver);
+       struct hdac_ext_driver *edrv = to_ehdac_driver(hdrv);
+
+       return edrv;
+}
+
+static inline struct hdac_ext_device *get_edev(struct device *dev)
+{
+       struct hdac_device *hdev = dev_to_hdac_dev(dev);
+       struct hdac_ext_device *edev = to_ehdac_device(hdev);
+
+       return edev;
+}
+
+static int hda_ext_drv_probe(struct device *dev)
+{
+       return (get_edrv(dev))->probe(get_edev(dev));
+}
+
+static int hdac_ext_drv_remove(struct device *dev)
+{
+       return (get_edrv(dev))->remove(get_edev(dev));
+}
+
+static void hdac_ext_drv_shutdown(struct device *dev)
+{
+       return (get_edrv(dev))->shutdown(get_edev(dev));
+}
+
+/**
+ * snd_hda_ext_driver_register - register a driver for ext hda devices
+ *
+ * @drv: ext hda driver structure
+ */
+int snd_hda_ext_driver_register(struct hdac_ext_driver *drv)
+{
+       drv->hdac.type = HDA_DEV_ASOC;
+       drv->hdac.driver.bus = &snd_hda_bus_type;
+       /* we use default match */
+
+       if (drv->probe)
+               drv->hdac.driver.probe = hda_ext_drv_probe;
+       if (drv->remove)
+               drv->hdac.driver.remove = hdac_ext_drv_remove;
+       if (drv->shutdown)
+               drv->hdac.driver.shutdown = hdac_ext_drv_shutdown;
+
+       return driver_register(&drv->hdac.driver);
+}
+EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register);
+
+/**
+ * snd_hda_ext_driver_unregister - unregister a driver for ext hda devices
+ *
+ * @drv: ext hda driver structure
+ */
+void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv)
+{
+       driver_unregister(&drv->hdac.driver);
+}
+EXPORT_SYMBOL_GPL(snd_hda_ext_driver_unregister);
index 358f161..63215b1 100644 (file)
@@ -177,8 +177,8 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
                hlink->bus = bus;
                hlink->ml_addr = ebus->mlcap + AZX_ML_BASE +
                                        (AZX_ML_INTERVAL * idx);
-               hlink->lcaps  = snd_hdac_chip_readl(bus, ML_LCAP);
-               hlink->lsdiid = snd_hdac_chip_readw(bus, ML_LSDIID);
+               hlink->lcaps  = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
+               hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
 
                list_add_tail(&hlink->list, &ebus->hlink_list);
        }
@@ -243,7 +243,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
        timeout = 50;
 
        do {
-               val = snd_hdac_chip_readl(link->bus, ML_LCTL);
+               val = readl(link->ml_addr + AZX_REG_ML_LCTL);
                if (enable) {
                        if (((val & mask) >> AZX_MLCTL_CPA))
                                return 0;
@@ -263,7 +263,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
  */
 int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link)
 {
-       snd_hdac_chip_updatel(link->bus, ML_LCTL, 0, AZX_MLCTL_SPA);
+       snd_hdac_updatel(link->ml_addr, AZX_REG_ML_LCTL, 0, AZX_MLCTL_SPA);
 
        return check_hdac_link_power_active(link, true);
 }
@@ -275,8 +275,28 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_up);
  */
 int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link)
 {
-       snd_hdac_chip_updatel(link->bus, ML_LCTL, AZX_MLCTL_SPA, 0);
+       snd_hdac_updatel(link->ml_addr, AZX_REG_ML_LCTL, AZX_MLCTL_SPA, 0);
 
        return check_hdac_link_power_active(link, false);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down);
+
+/**
+ * snd_hdac_ext_bus_link_power_down_all -power down all hda link
+ * @ebus: HD-audio extended bus
+ */
+int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus)
+{
+       struct hdac_ext_link *hlink = NULL;
+       int ret;
+
+       list_for_each_entry(hlink, &ebus->hlink_list, list) {
+               snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, AZX_MLCTL_SPA, 0);
+               ret = check_hdac_link_power_active(hlink, false);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all);
index 3de47dd..33ba77d 100644 (file)
@@ -49,6 +49,16 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
                                AZX_PPLC_INTERVAL * idx;
        }
 
+       if (ebus->spbcap) {
+               stream->spib_addr = ebus->spbcap + AZX_SPB_BASE +
+                                       AZX_SPB_INTERVAL * idx +
+                                       AZX_SPB_SPIB;
+
+               stream->fifo_addr = ebus->spbcap + AZX_SPB_BASE +
+                                       AZX_SPB_INTERVAL * idx +
+                                       AZX_SPB_MAXFIFO;
+       }
+
        stream->decoupled = false;
        snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag);
 }
@@ -281,17 +291,12 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
        struct hdac_ext_stream *res = NULL;
        struct hdac_stream *stream = NULL;
        struct hdac_bus *hbus = &ebus->bus;
-       int key;
 
        if (!ebus->ppcap) {
                dev_err(hbus->dev, "stream type not supported\n");
                return NULL;
        }
 
-       /* make a non-zero unique key for the substream */
-       key = (substream->pcm->device << 16) | (substream->number << 2) |
-                       (substream->stream + 1);
-
        list_for_each_entry(stream, &hbus->stream_list, list) {
                struct hdac_ext_stream *hstream = container_of(stream,
                                                struct hdac_ext_stream,
@@ -310,7 +315,6 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
                spin_lock_irq(&hbus->reg_lock);
                res->hstream.opened = 1;
                res->hstream.running = 0;
-               res->hstream.assigned_key = key;
                res->hstream.substream = substream;
                spin_unlock_irq(&hbus->reg_lock);
        }
@@ -423,7 +427,7 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
 
        mask |= (1 << index);
 
-       register_mask = snd_hdac_chip_readl(bus, SPB_SPBFCCTL);
+       register_mask = readl(ebus->spbcap + AZX_REG_SPB_SPBFCCTL);
 
        mask |= register_mask;
 
@@ -434,6 +438,50 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable);
 
+/**
+ * snd_hdac_ext_stream_set_spib - sets the spib value of a stream
+ * @ebus: HD-audio ext core bus
+ * @stream: hdac_ext_stream
+ * @value: spib value to set
+ */
+int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
+                                struct hdac_ext_stream *stream, u32 value)
+{
+       struct hdac_bus *bus = &ebus->bus;
+
+       if (!ebus->spbcap) {
+               dev_err(bus->dev, "Address of SPB capability is NULL");
+               return -EINVAL;
+       }
+
+       writel(value, stream->spib_addr);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_spib);
+
+/**
+ * snd_hdac_ext_stream_get_spbmaxfifo - gets the spib value of a stream
+ * @ebus: HD-audio ext core bus
+ * @stream: hdac_ext_stream
+ *
+ * Return maxfifo for the stream
+ */
+int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
+                                struct hdac_ext_stream *stream)
+{
+       struct hdac_bus *bus = &ebus->bus;
+
+       if (!ebus->spbcap) {
+               dev_err(bus->dev, "Address of SPB capability is NULL");
+               return -EINVAL;
+       }
+
+       return readl(stream->fifo_addr);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo);
+
+
 /**
  * snd_hdac_ext_stop_streams - stop all stream if running
  * @ebus: HD-audio ext core bus
index cdee710..db96042 100644 (file)
@@ -372,6 +372,36 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec)
 }
 EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets);
 
+/**
+ * snd_hdac_refresh_widget_sysfs - Reset the codec widgets and reinit the
+ * codec sysfs
+ * @codec: the codec object
+ *
+ * first we need to remove sysfs, then refresh widgets and lastly
+ * recreate it
+ */
+int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec)
+{
+       int ret;
+
+       if (device_is_registered(&codec->dev))
+               hda_widget_sysfs_exit(codec);
+       ret = snd_hdac_refresh_widgets(codec);
+       if (ret) {
+               dev_err(&codec->dev, "failed to refresh widget: %d\n", ret);
+               return ret;
+       }
+       if (device_is_registered(&codec->dev)) {
+               ret = hda_widget_sysfs_init(codec);
+               if (ret) {
+                       dev_err(&codec->dev, "failed to init sysfs: %d\n", ret);
+                       return ret;
+               }
+       }
+       return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_refresh_widget_sysfs);
+
 /* return CONNLIST_LEN parameter of the given widget */
 static unsigned int get_num_conns(struct hdac_device *codec, hda_nid_t nid)
 {
@@ -501,23 +531,27 @@ EXPORT_SYMBOL_GPL(snd_hdac_get_connections);
  * This function calls the runtime PM helper to power up the given codec.
  * Unlike snd_hdac_power_up_pm(), you should call this only for the code
  * path that isn't included in PM path.  Otherwise it gets stuck.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_up(struct hdac_device *codec)
+int snd_hdac_power_up(struct hdac_device *codec)
 {
-       pm_runtime_get_sync(&codec->dev);
+       return pm_runtime_get_sync(&codec->dev);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_up);
 
 /**
  * snd_hdac_power_down - power down the codec
  * @codec: the codec object
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_down(struct hdac_device *codec)
+int snd_hdac_power_down(struct hdac_device *codec)
 {
        struct device *dev = &codec->dev;
 
        pm_runtime_mark_last_busy(dev);
-       pm_runtime_put_autosuspend(dev);
+       return pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_down);
 
@@ -529,11 +563,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_down);
  * which may be called by PM suspend/resume again.  OTOH, if a power-up
  * call must wake up the sleeper (e.g. in a kctl callback), use
  * snd_hdac_power_up() instead.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_up_pm(struct hdac_device *codec)
+int snd_hdac_power_up_pm(struct hdac_device *codec)
 {
        if (!atomic_inc_not_zero(&codec->in_pm))
-               snd_hdac_power_up(codec);
+               return snd_hdac_power_up(codec);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
 
@@ -543,11 +580,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
  *
  * Like snd_hdac_power_up_pm(), this function is used in a recursive
  * code path like init code which may be called by PM suspend/resume again.
+ *
+ * Returns zero if successful, or a negative error code.
  */
-void snd_hdac_power_down_pm(struct hdac_device *codec)
+int snd_hdac_power_down_pm(struct hdac_device *codec)
 {
        if (atomic_dec_if_positive(&codec->in_pm) < 0)
-               snd_hdac_power_down(codec);
+               return snd_hdac_power_down(codec);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
 #endif
index 1eabcdf..b0ed870 100644 (file)
@@ -410,8 +410,9 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
 
        err = reg_raw_write(codec, reg, val);
        if (err == -EAGAIN) {
-               snd_hdac_power_up_pm(codec);
-               err = reg_raw_write(codec, reg, val);
+               err = snd_hdac_power_up_pm(codec);
+               if (!err)
+                       err = reg_raw_write(codec, reg, val);
                snd_hdac_power_down_pm(codec);
        }
        return err;
@@ -442,8 +443,9 @@ int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
 
        err = reg_raw_read(codec, reg, val);
        if (err == -EAGAIN) {
-               snd_hdac_power_up_pm(codec);
-               err = reg_raw_read(codec, reg, val);
+               err = snd_hdac_power_up_pm(codec);
+               if (!err)
+                       err = reg_raw_read(codec, reg, val);
                snd_hdac_power_down_pm(codec);
        }
        return err;
index 4c15d0a..8981159 100644 (file)
@@ -286,6 +286,28 @@ void snd_hdac_stream_release(struct hdac_stream *azx_dev)
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_release);
 
+/**
+ * snd_hdac_get_stream - return hdac_stream based on stream_tag and
+ * direction
+ *
+ * @bus: HD-audio core bus
+ * @dir: direction for the stream to be found
+ * @stream_tag: stream tag for stream to be found
+ */
+struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
+                                       int dir, int stream_tag)
+{
+       struct hdac_stream *s;
+
+       list_for_each_entry(s, &bus->stream_list, list) {
+               if (s->direction == dir && s->stream_tag == stream_tag)
+                       return s;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_get_stream);
+
 /*
  * set up a BDL entry
  */
index 0a6ce3b..c71142d 100644 (file)
@@ -321,8 +321,7 @@ static void widget_tree_free(struct hdac_device *codec)
                        free_widget_node(*p, &widget_node_group);
                kfree(tree->nodes);
        }
-       if (tree->root)
-               kobject_put(tree->root);
+       kobject_put(tree->root);
        kfree(tree);
        codec->widgets = NULL;
 }
@@ -391,6 +390,9 @@ int hda_widget_sysfs_init(struct hdac_device *codec)
 {
        int err;
 
+       if (codec->widgets)
+               return 0; /* already created */
+
        err = widget_tree_create(codec);
        if (err < 0) {
                widget_tree_free(codec);
index febee5b..320837b 100644 (file)
@@ -44,18 +44,18 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_DARLA20_DSP;
        chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
        chip->clock_state = GD_CLOCK_UNDEF;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 7b4f6fd..8736b5e 100644 (file)
@@ -44,17 +44,17 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_DARLA24_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
                ECHO_CLOCK_BIT_ESYNC;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index ae11ce1..6deb80c 100644 (file)
@@ -59,8 +59,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
                cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2);
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
-       chip->has_midi = TRUE;
+       chip->bad_board = true;
+       chip->has_midi = true;
        chip->dsp_code_to_load = FW_ECHO3G_DSP;
 
        /* Load the DSP code and the ASIC on the PCI card and get
@@ -78,8 +78,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
                chip->px_analog_in = chip->bx_analog_in = 14;
                chip->px_digital_in = chip->bx_digital_in = 16;
                chip->px_num = chip->bx_num = 24;
-               chip->has_phantom_power = TRUE;
-               chip->hasnt_input_nominal_level = TRUE;
+               chip->has_phantom_power = true;
+               chip->hasnt_input_nominal_level = true;
        } else if (err == E3G_LAYLA3G_BOX_TYPE) {
                chip->input_clock_types =       ECHO_CLOCK_BIT_INTERNAL |
                                                ECHO_CLOCK_BIT_SPDIF |
@@ -106,10 +106,10 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 static int set_mixer_defaults(struct echoaudio *chip)
 {
        chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
-       chip->professional_spdif = FALSE;
-       chip->non_audio_spdif = FALSE;
-       chip->bad_board = FALSE;
-       chip->phantom_power = FALSE;
+       chip->professional_spdif = false;
+       chip->non_audio_spdif = false;
+       chip->bad_board = false;
+       chip->phantom_power = false;
        return init_line_levels(chip);
 }
 
index 862db9a..1cb85ae 100644 (file)
@@ -2245,7 +2245,7 @@ static int snd_echo_resume(struct device *dev)
 
 #ifdef ECHOCARD_HAS_MIDI
        if (chip->midi_input_enabled)
-               enable_midi_input(chip, TRUE);
+               enable_midi_input(chip, true);
        if (chip->midi_out)
                snd_echo_midi_output_trigger(chip->midi_out, 1);
 #endif
index 3251522..152ce15 100644 (file)
 #define _ECHOAUDIO_H_
 
 
-#define TRUE 1
-#define FALSE 0
-
 #include "echoaudio_dsp.h"
 
 
@@ -378,8 +375,8 @@ struct echoaudio {
                                         */
        u8 output_clock;                /* Layla20 only */
        char meters_enabled;            /* VU-meters status */
-       char asic_loaded;               /* Set TRUE when ASIC loaded */
-       char bad_board;                 /* Set TRUE if DSP won't load */
+       char asic_loaded;               /* Set true when ASIC loaded */
+       char bad_board;                 /* Set true if DSP won't load */
        char professional_spdif;        /* 0 = consumer; 1 = professional */
        char non_audio_spdif;           /* 3G - only */
        char digital_in_automute;       /* Gina24, Layla24, Mona - only */
index 2fa66dc..22c786b 100644 (file)
@@ -41,7 +41,7 @@ static int check_asic_status(struct echoaudio *chip)
                return -EIO;
 
        chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED);
-       chip->asic_loaded = FALSE;
+       chip->asic_loaded = false;
        clear_handshake(chip);
        send_vector(chip, DSP_VC_TEST_ASIC);
 
@@ -55,7 +55,7 @@ static int check_asic_status(struct echoaudio *chip)
        if (box_status == E3G_ASIC_NOT_LOADED)
                return -ENODEV;
 
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        return box_status & E3G_BOX_TYPE_MASK;
 }
 
@@ -243,7 +243,7 @@ static int load_asic(struct echoaudio *chip)
         * 48 kHz, internal clock, S/PDIF RCA mode */
        if (box_type >= 0) {
                err = write_control_reg(chip, E3G_48KHZ,
-                                       E3G_FREQ_REG_DEFAULT, TRUE);
+                                       E3G_FREQ_REG_DEFAULT, true);
                if (err < 0)
                        return err;
        }
@@ -378,16 +378,16 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
        int err, incompatible_clock;
 
        /* Set clock to "internal" if it's not compatible with the new mode */
-       incompatible_clock = FALSE;
+       incompatible_clock = false;
        switch (mode) {
        case DIGITAL_MODE_SPDIF_OPTICAL:
        case DIGITAL_MODE_SPDIF_RCA:
                if (chip->input_clock == ECHO_CLOCK_ADAT)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        case DIGITAL_MODE_ADAT:
                if (chip->input_clock == ECHO_CLOCK_SPDIF)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        default:
                dev_err(chip->card->dev,
index 1a9427a..15aae2f 100644 (file)
@@ -103,8 +103,8 @@ static int write_dsp(struct echoaudio *chip, u32 data)
                cond_resched();
        }
 
-       chip->bad_board = TRUE;         /* Set TRUE until DSP re-loaded */
-       dev_dbg(chip->card->dev, "write_dsp: Set bad_board to TRUE\n");
+       chip->bad_board = true;         /* Set true until DSP re-loaded */
+       dev_dbg(chip->card->dev, "write_dsp: Set bad_board to true\n");
        return -EIO;
 }
 
@@ -126,8 +126,8 @@ static int read_dsp(struct echoaudio *chip, u32 *data)
                cond_resched();
        }
 
-       chip->bad_board = TRUE;         /* Set TRUE until DSP re-loaded */
-       dev_err(chip->card->dev, "read_dsp: Set bad_board to TRUE\n");
+       chip->bad_board = true;         /* Set true until DSP re-loaded */
+       dev_err(chip->card->dev, "read_dsp: Set bad_board to true\n");
        return -EIO;
 }
 
@@ -166,7 +166,7 @@ static int read_sn(struct echoaudio *chip)
 /* This card has no ASIC, just return ok */
 static inline int check_asic_status(struct echoaudio *chip)
 {
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        return 0;
 }
 
@@ -341,11 +341,11 @@ static int load_dsp(struct echoaudio *chip, u16 *code)
                dev_warn(chip->card->dev, "DSP is already loaded!\n");
                return 0;
        }
-       chip->bad_board = TRUE;         /* Set TRUE until DSP loaded */
+       chip->bad_board = true;         /* Set true until DSP loaded */
        chip->dsp_code = NULL;          /* Current DSP code not loaded */
-       chip->asic_loaded = FALSE;      /* Loading the DSP code will reset the ASIC */
+       chip->asic_loaded = false;      /* Loading the DSP code will reset the ASIC */
 
-       dev_dbg(chip->card->dev, "load_dsp: Set bad_board to TRUE\n");
+       dev_dbg(chip->card->dev, "load_dsp: Set bad_board to true\n");
 
        /* If this board requires a resident loader, install it. */
 #ifdef DSP_56361
@@ -471,7 +471,7 @@ static int load_dsp(struct echoaudio *chip, u16 *code)
                        }
 
                        chip->dsp_code = code;          /* Show which DSP code loaded */
-                       chip->bad_board = FALSE;        /* DSP OK */
+                       chip->bad_board = false;        /* DSP OK */
                        return 0;
                }
                udelay(100);
@@ -951,10 +951,10 @@ static int rest_in_peace(struct echoaudio *chip)
        /* Stops all active pipes (just to be sure) */
        stop_transport(chip, chip->active_mask);
 
-       set_meters_on(chip, FALSE);
+       set_meters_on(chip, false);
 
 #ifdef ECHOCARD_HAS_MIDI
-       enable_midi_input(chip, FALSE);
+       enable_midi_input(chip, false);
 #endif
 
        /* Go to sleep */
@@ -981,9 +981,9 @@ static int init_dsp_comm_page(struct echoaudio *chip)
 
        /* Init all the basic stuff */
        chip->card_name = ECHOCARD_NAME;
-       chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
+       chip->bad_board = true; /* Set true until DSP loaded */
        chip->dsp_code = NULL;  /* Current DSP code not loaded */
-       chip->asic_loaded = FALSE;
+       chip->asic_loaded = false;
        memset(chip->comm_page, 0, sizeof(struct comm_page));
 
        /* Init the comm page */
index 23a0994..834b39e 100644 (file)
@@ -48,7 +48,7 @@ static int check_asic_status(struct echoaudio *chip)
        if (read_dsp(chip, &asic_status) < 0) {
                dev_err(chip->card->dev,
                        "check_asic_status: failed on read_dsp\n");
-               chip->asic_loaded = FALSE;
+               chip->asic_loaded = false;
                return -EIO;
        }
 
@@ -192,7 +192,7 @@ static int set_professional_spdif(struct echoaudio *chip, char prof)
                }
        }
 
-       if ((err = write_control_reg(chip, control_reg, FALSE)))
+       if ((err = write_control_reg(chip, control_reg, false)))
                return err;
        chip->professional_spdif = prof;
        dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
index 4fa32a2..67bd0c9 100644 (file)
@@ -23,7 +23,7 @@
 #define ECHOCARD_HAS_INPUT_GAIN
 #define ECHOCARD_HAS_DIGITAL_IO
 #define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT      FALSE
+#define ECHOCARD_HAS_ADAT      false
 
 /* Pipe indexes */
 #define PX_ANALOG_OUT  0       /* 8 */
index 5dafe92..b237757 100644 (file)
@@ -48,19 +48,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_GINA20_DSP;
        chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
        chip->clock_state = GD_CLOCK_UNDEF;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
                ECHO_CLOCK_BIT_SPDIF;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
@@ -69,7 +69,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
 static int set_mixer_defaults(struct echoaudio *chip)
 {
-       chip->professional_spdif = FALSE;
+       chip->professional_spdif = false;
        return init_line_levels(chip);
 }
 
index 6971766..8eff2b4 100644 (file)
@@ -52,7 +52,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->input_clock_types =
                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
                ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
@@ -76,7 +76,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
@@ -86,8 +86,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 static int set_mixer_defaults(struct echoaudio *chip)
 {
        chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
-       chip->professional_spdif = FALSE;
-       chip->digital_in_automute = TRUE;
+       chip->professional_spdif = false;
+       chip->digital_in_automute = true;
        return init_line_levels(chip);
 }
 
@@ -152,7 +152,7 @@ static int load_asic(struct echoaudio *chip)
           48 kHz, internal clock, S/PDIF RCA mode */
        if (!err) {
                control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
-               err = write_control_reg(chip, control_reg, TRUE);
+               err = write_control_reg(chip, control_reg, true);
        }
        return err;
 }
@@ -226,7 +226,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
        chip->sample_rate = rate;
        dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock);
 
-       return write_control_reg(chip, control_reg, FALSE);
+       return write_control_reg(chip, control_reg, false);
 }
 
 
@@ -274,7 +274,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
        }
 
        chip->input_clock = clock;
-       return write_control_reg(chip, control_reg, TRUE);
+       return write_control_reg(chip, control_reg, true);
 }
 
 
@@ -285,17 +285,17 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
        int err, incompatible_clock;
 
        /* Set clock to "internal" if it's not compatible with the new mode */
-       incompatible_clock = FALSE;
+       incompatible_clock = false;
        switch (mode) {
        case DIGITAL_MODE_SPDIF_OPTICAL:
        case DIGITAL_MODE_SPDIF_CDROM:
        case DIGITAL_MODE_SPDIF_RCA:
                if (chip->input_clock == ECHO_CLOCK_ADAT)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        case DIGITAL_MODE_ADAT:
                if (chip->input_clock == ECHO_CLOCK_SPDIF)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        default:
                dev_err(chip->card->dev,
@@ -333,7 +333,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
                break;
        }
 
-       err = write_control_reg(chip, control_reg, TRUE);
+       err = write_control_reg(chip, control_reg, true);
        spin_unlock_irq(&chip->lock);
        if (err < 0)
                return err;
index 54edd67..c97dc83 100644 (file)
@@ -49,16 +49,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_INDIGO_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 2cf5cc0..2428b35 100644 (file)
@@ -49,16 +49,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_INDIGO_DJ_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 5252863..5fbd4a3 100644 (file)
@@ -47,17 +47,17 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_INDIGO_DJX_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        err = load_firmware(chip);
        if (err < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 4e81787..79b68ba 100644 (file)
@@ -49,16 +49,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 6de3f9b..1ae394e 100644 (file)
@@ -47,17 +47,17 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_INDIGO_IOX_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
 
        err = load_firmware(chip);
        if (err < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 12e5d21..fc8468d 100644 (file)
@@ -26,7 +26,7 @@
 #define ECHOCARD_HAS_SUPER_INTERLEAVE
 #define ECHOCARD_HAS_DIGITAL_IO
 #define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT      FALSE
+#define ECHOCARD_HAS_ADAT      false
 #define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
 #define ECHOCARD_HAS_MIDI
 
index f2024a3..5e5b6e2 100644 (file)
@@ -51,8 +51,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
-       chip->has_midi = TRUE;
+       chip->bad_board = true;
+       chip->has_midi = true;
        chip->dsp_code_to_load = FW_LAYLA20_DSP;
        chip->input_clock_types =
                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
@@ -62,7 +62,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
@@ -71,7 +71,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
 static int set_mixer_defaults(struct echoaudio *chip)
 {
-       chip->professional_spdif = FALSE;
+       chip->professional_spdif = false;
        return init_line_levels(chip);
 }
 
@@ -113,7 +113,7 @@ static int check_asic_status(struct echoaudio *chip)
        u32 asic_status;
        int goodcnt, i;
 
-       chip->asic_loaded = FALSE;
+       chip->asic_loaded = false;
        for (i = goodcnt = 0; i < 5; i++) {
                send_vector(chip, DSP_VC_TEST_ASIC);
 
@@ -127,7 +127,7 @@ static int check_asic_status(struct echoaudio *chip)
 
                if (asic_status == ASIC_ALREADY_LOADED) {
                        if (++goodcnt == 3) {
-                               chip->asic_loaded = TRUE;
+                               chip->asic_loaded = true;
                                return 0;
                        }
                }
index 4f11e81..df28e51 100644 (file)
@@ -51,8 +51,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
-       chip->has_midi = TRUE;
+       chip->bad_board = true;
+       chip->has_midi = true;
        chip->dsp_code_to_load = FW_LAYLA24_DSP;
        chip->input_clock_types =
                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
@@ -64,7 +64,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        if ((err = init_line_levels(chip)) < 0)
                return err;
@@ -77,8 +77,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 static int set_mixer_defaults(struct echoaudio *chip)
 {
        chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
-       chip->professional_spdif = FALSE;
-       chip->digital_in_automute = TRUE;
+       chip->professional_spdif = false;
+       chip->digital_in_automute = true;
        return init_line_levels(chip);
 }
 
@@ -135,7 +135,7 @@ static int load_asic(struct echoaudio *chip)
        err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
                                FW_LAYLA24_2S_ASIC);
        if (err < 0)
-               return FALSE;
+               return false;
 
        /* Now give the external ASIC a little time to set up */
        mdelay(10);
@@ -147,7 +147,7 @@ static int load_asic(struct echoaudio *chip)
           48 kHz, internal clock, S/PDIF RCA mode */
        if (!err)
                err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ,
-                                       TRUE);
+                                       true);
        
        return err;
 }
@@ -241,7 +241,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
        dev_dbg(chip->card->dev,
                "set_sample_rate: %d clock %d\n", rate, control_reg);
 
-       return write_control_reg(chip, control_reg, FALSE);
+       return write_control_reg(chip, control_reg, false);
 }
 
 
@@ -287,7 +287,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
        }
 
        chip->input_clock = clock;
-       return write_control_reg(chip, control_reg, TRUE);
+       return write_control_reg(chip, control_reg, true);
 }
 
 
@@ -334,17 +334,17 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
        short asic;
 
        /* Set clock to "internal" if it's not compatible with the new mode */
-       incompatible_clock = FALSE;
+       incompatible_clock = false;
        switch (mode) {
        case DIGITAL_MODE_SPDIF_OPTICAL:
        case DIGITAL_MODE_SPDIF_RCA:
                if (chip->input_clock == ECHO_CLOCK_ADAT)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                asic = FW_LAYLA24_2S_ASIC;
                break;
        case DIGITAL_MODE_ADAT:
                if (chip->input_clock == ECHO_CLOCK_SPDIF)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                asic = FW_LAYLA24_2A_ASIC;
                break;
        default:
@@ -383,7 +383,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
                break;
        }
 
-       err = write_control_reg(chip, control_reg, TRUE);
+       err = write_control_reg(chip, control_reg, true);
        spin_unlock_irq(&chip->lock);
        if (err < 0)
                return err;
index 2f7562f..62b5240 100644 (file)
@@ -26,7 +26,7 @@
 #define ECHOCARD_HAS_VMIXER
 #define ECHOCARD_HAS_DIGITAL_IO
 #define ECHOCARD_HAS_EXTERNAL_CLOCK
-#define ECHOCARD_HAS_ADAT      FALSE
+#define ECHOCARD_HAS_ADAT      false
 #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
 #define ECHOCARD_HAS_MIDI
 #define ECHOCARD_HAS_LINE_OUT_GAIN
index fdad079..8f612a0 100644 (file)
@@ -52,19 +52,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->dsp_code_to_load = FW_MIA_DSP;
        /* Since this card has no ASIC, mark it as loaded so everything
           works OK */
-       chip->asic_loaded = TRUE;
+       chip->asic_loaded = true;
        if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
-               chip->has_midi = TRUE;
+               chip->has_midi = true;
        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
                ECHO_CLOCK_BIT_SPDIF;
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
index 843c7a5..dce9e57 100644 (file)
@@ -52,7 +52,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        chip->device_id = device_id;
        chip->subdevice_id = subdevice_id;
-       chip->bad_board = TRUE;
+       chip->bad_board = true;
        chip->input_clock_types =
                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
                ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
@@ -69,7 +69,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
        if ((err = load_firmware(chip)) < 0)
                return err;
-       chip->bad_board = FALSE;
+       chip->bad_board = false;
 
        return err;
 }
@@ -79,8 +79,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 static int set_mixer_defaults(struct echoaudio *chip)
 {
        chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
-       chip->professional_spdif = FALSE;
-       chip->digital_in_automute = TRUE;
+       chip->professional_spdif = false;
+       chip->digital_in_automute = true;
        return init_line_levels(chip);
 }
 
@@ -148,7 +148,7 @@ static int load_asic(struct echoaudio *chip)
           48 kHz, internal clock, S/PDIF RCA mode */
        if (!err) {
                control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
-               err = write_control_reg(chip, control_reg, TRUE);
+               err = write_control_reg(chip, control_reg, true);
        }
 
        return err;
@@ -356,7 +356,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
        }
 
        chip->input_clock = clock;
-       return write_control_reg(chip, control_reg, TRUE);
+       return write_control_reg(chip, control_reg, true);
 }
 
 
@@ -367,16 +367,16 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
        int err, incompatible_clock;
 
        /* Set clock to "internal" if it's not compatible with the new mode */
-       incompatible_clock = FALSE;
+       incompatible_clock = false;
        switch (mode) {
        case DIGITAL_MODE_SPDIF_OPTICAL:
        case DIGITAL_MODE_SPDIF_RCA:
                if (chip->input_clock == ECHO_CLOCK_ADAT)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        case DIGITAL_MODE_ADAT:
                if (chip->input_clock == ECHO_CLOCK_SPDIF)
-                       incompatible_clock = TRUE;
+                       incompatible_clock = true;
                break;
        default:
                dev_err(chip->card->dev,
@@ -415,7 +415,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
                break;
        }
 
-       err = write_control_reg(chip, control_reg, FALSE);
+       err = write_control_reg(chip, control_reg, false);
        spin_unlock_irq(&chip->lock);
        if (err < 0)
                return err;
index 55e5716..076b117 100644 (file)
@@ -1741,7 +1741,7 @@ static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
 static struct snd_kcontrol_new snd_audigy_capture_boost =
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-       .name =         "Analog Capture Boost",
+       .name =         "Mic Extra Boost",
        .info =         snd_audigy_capture_boost_info,
        .get =          snd_audigy_capture_boost_get,
        .put =          snd_audigy_capture_boost_put
@@ -1819,8 +1819,6 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                 * the Philips ADC for 24bit capture */
                "PCM Playback Switch",
                "PCM Playback Volume",
-               "Master Mono Playback Switch",
-               "Master Mono Playback Volume",
                "Master Playback Switch",
                "Master Playback Volume",
                "PCM Out Path & Mute",
@@ -1830,10 +1828,16 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                "Capture Switch",
                "Capture Volume",
                "Mic Select",
+               "Headphone Playback Switch",
+               "Headphone Playback Volume",
+               "3D Control - Center",
+               "3D Control - Depth",
+               "3D Control - Switch",
                "Video Playback Switch",
                "Video Playback Volume",
                "Mic Playback Switch",
                "Mic Playback Volume",
+               "External Amplifier",
                NULL
        };
        static char *audigy_rename_ctls[] = {
@@ -1842,6 +1846,8 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                /* "Wave Capture Volume", "PCM Capture Volume", */
                "Wave Master Playback Volume", "Master Playback Volume",
                "AMic Playback Volume", "Mic Playback Volume",
+               "Master Mono Playback Switch", "Phone Output Playback Switch",
+               "Master Mono Playback Volume", "Phone Output Playback Volume",
                NULL
        };
        static char *audigy_rename_ctls_i2c_adc[] = {
@@ -1867,8 +1873,6 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                 * the Philips ADC for 24bit capture */
                "PCM Playback Switch",
                "PCM Playback Volume",
-               "Master Mono Playback Switch",
-               "Master Mono Playback Volume",
                "Capture Source",
                "Capture Switch",
                "Capture Volume",
@@ -1900,7 +1904,8 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                "Aux Playback Volume", "Aux Capture Volume",
                "Video Playback Switch", "Video Capture Switch",
                "Video Playback Volume", "Video Capture Volume",
-
+               "Master Mono Playback Switch", "Phone Output Playback Switch",
+               "Master Mono Playback Volume", "Phone Output Playback Volume",
                NULL
        };
 
@@ -1935,6 +1940,9 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                        snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
                        /* set capture source to mic */
                        snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
+                       /* set mono output (TAD) to mic */
+                       snd_ac97_update_bits(emu->ac97, AC97_GENERAL_PURPOSE,
+                               0x0200, 0x0200);
                        if (emu->card_capabilities->adc_1361t)
                                c = audigy_remove_ctls_1361t_adc;
                        else 
@@ -1996,11 +2004,6 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
                rename_ctl(card, "Aux2 Capture Volume", "Line3 Capture Volume");
                rename_ctl(card, "Mic Capture Volume", "Unknown1 Capture Volume");
-               remove_ctl(card, "Headphone Playback Switch");
-               remove_ctl(card, "Headphone Playback Volume");
-               remove_ctl(card, "3D Control - Center");
-               remove_ctl(card, "3D Control - Depth");
-               remove_ctl(card, "3D Control - Switch");
        }
        if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
                return -ENOMEM;
index 03b7399..7f57a14 100644 (file)
@@ -887,11 +887,32 @@ EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
 static bool pin_config_match(struct hda_codec *codec,
                             const struct hda_pintbl *pins)
 {
-       for (; pins->nid; pins++) {
-               u32 def_conf = snd_hda_codec_get_pincfg(codec, pins->nid);
-               if (pins->val != def_conf)
+       int i;
+
+       for (i = 0; i < codec->init_pins.used; i++) {
+               struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
+               hda_nid_t nid = pin->nid;
+               u32 cfg = pin->cfg;
+               const struct hda_pintbl *t_pins;
+               int found;
+
+               t_pins = pins;
+               found = 0;
+               for (; t_pins->nid; t_pins++) {
+                       if (t_pins->nid == nid) {
+                               found = 1;
+                               if (t_pins->val == cfg)
+                                       break;
+                               else if ((cfg & 0xf0000000) == 0x40000000 && (t_pins->val & 0xf0000000) == 0x40000000)
+                                       break;
+                               else
+                                       return false;
+                       }
+               }
+               if (!found && (cfg & 0xf0000000) != 0x40000000)
                        return false;
        }
+
        return true;
 }
 
index 5de3c5d..37f43a1 100644 (file)
 #define codec_has_clkstop(codec) \
        ((codec)->core.power_caps & AC_PWRST_CLKSTOP)
 
-/**
- * snd_hda_get_jack_location - Give a location string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack location, e.g. "Rear", "Front", etc.
- */
-const char *snd_hda_get_jack_location(u32 cfg)
-{
-       static char *bases[7] = {
-               "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
-       };
-       static unsigned char specials_idx[] = {
-               0x07, 0x08,
-               0x17, 0x18, 0x19,
-               0x37, 0x38
-       };
-       static char *specials[] = {
-               "Rear Panel", "Drive Bar",
-               "Riser", "HDMI", "ATAPI",
-               "Mobile-In", "Mobile-Out"
-       };
-       int i;
-       cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
-       if ((cfg & 0x0f) < 7)
-               return bases[cfg & 0x0f];
-       for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
-               if (cfg == specials_idx[i])
-                       return specials[i];
-       }
-       return "UNKNOWN";
-}
-EXPORT_SYMBOL_GPL(snd_hda_get_jack_location);
-
-/**
- * snd_hda_get_jack_connectivity - Give a connectivity string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack connectivity, i.e. external or internal connection.
- */
-const char *snd_hda_get_jack_connectivity(u32 cfg)
-{
-       static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
-
-       return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
-}
-EXPORT_SYMBOL_GPL(snd_hda_get_jack_connectivity);
-
-/**
- * snd_hda_get_jack_type - Give a type string of the jack
- * @cfg: pin default config value
- *
- * Parse the pin default config value and returns the string of the
- * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
- */
-const char *snd_hda_get_jack_type(u32 cfg)
-{
-       static char *jack_types[16] = {
-               "Line Out", "Speaker", "HP Out", "CD",
-               "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
-               "Line In", "Aux", "Mic", "Telephony",
-               "SPDIF In", "Digital In", "Reserved", "Other"
-       };
-
-       return jack_types[(cfg & AC_DEFCFG_DEVICE)
-                               >> AC_DEFCFG_DEVICE_SHIFT];
-}
-EXPORT_SYMBOL_GPL(snd_hda_get_jack_type);
-
 /*
  * Send and receive a verb - passed to exec_verb override for hdac_device
  */
@@ -975,7 +905,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
        if (codec->bus->modelname) {
                codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
                if (!codec->modelname) {
-                       err = -ENODEV;
+                       err = -ENOMEM;
                        goto error;
                }
        }
@@ -1025,7 +955,7 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
        hda_nid_t fg;
        int err;
 
-       err = snd_hdac_refresh_widgets(&codec->core);
+       err = snd_hdac_refresh_widget_sysfs(&codec->core);
        if (err < 0)
                return err;
 
@@ -3172,8 +3102,7 @@ static int add_std_chmaps(struct hda_codec *codec)
                        struct snd_pcm_chmap *chmap;
                        const struct snd_pcm_chmap_elem *elem;
 
-                       if (!pcm || pcm->own_chmap ||
-                           !hinfo->substreams)
+                       if (!pcm->pcm || pcm->own_chmap || !hinfo->substreams)
                                continue;
                        elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
                        err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem,
index 12837ab..2970413 100644 (file)
@@ -468,13 +468,6 @@ int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
        return 0;
 }
 
-/*
- * get widget information
- */
-const char *snd_hda_get_jack_connectivity(u32 cfg);
-const char *snd_hda_get_jack_type(u32 cfg);
-const char *snd_hda_get_jack_location(u32 cfg);
-
 /*
  * power saving
  */
index c746cd9..563984d 100644 (file)
@@ -42,7 +42,7 @@ enum cea_edid_versions {
        CEA_EDID_VER_RESERVED   = 4,
 };
 
-static char *cea_speaker_allocation_names[] = {
+static const char * const cea_speaker_allocation_names[] = {
        /*  0 */ "FL/FR",
        /*  1 */ "LFE",
        /*  2 */ "FC",
@@ -56,7 +56,7 @@ static char *cea_speaker_allocation_names[] = {
        /* 10 */ "FCH",
 };
 
-static char *eld_connection_type_names[4] = {
+static const char * const eld_connection_type_names[4] = {
        "HDMI",
        "DisplayPort",
        "2-reserved",
@@ -94,7 +94,7 @@ enum cea_audio_coding_xtypes {
        AUDIO_CODING_XTYPE_FIRST_RESERVED       = 4,
 };
 
-static char *cea_audio_coding_type_names[] = {
+static const char * const cea_audio_coding_type_names[] = {
        /*  0 */ "undefined",
        /*  1 */ "LPCM",
        /*  2 */ "AC-3",
@@ -482,14 +482,14 @@ void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
        struct parsed_hdmi_eld *e = &eld->info;
        char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
        int i;
-       static char *eld_version_names[32] = {
+       static const char * const eld_version_names[32] = {
                "reserved",
                "reserved",
                "CEA-861D or below",
                [3 ... 30] = "reserved",
                [31] = "partial"
        };
-       static char *cea_edid_version_names[8] = {
+       static const char * const cea_edid_version_names[8] = {
                "no CEA EDID Timing Extension block present",
                "CEA-861",
                "CEA-861-A",
index b077bb6..24f9111 100644 (file)
@@ -671,7 +671,8 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
                }
                for (i = 0; i < path->depth; i++) {
                        if (path->path[i] == nid) {
-                               if (dir == HDA_OUTPUT || path->idx[i] == idx)
+                               if (dir == HDA_OUTPUT || idx == -1 ||
+                                   path->idx[i] == idx)
                                        return true;
                                break;
                        }
@@ -682,7 +683,7 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
 
 /* check whether the NID is referred by any active paths */
 #define is_active_nid_for_any(codec, nid) \
-       is_active_nid(codec, nid, HDA_OUTPUT, 0)
+       is_active_nid(codec, nid, HDA_OUTPUT, -1)
 
 /* get the default amp value for the target state */
 static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
@@ -883,8 +884,7 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
        struct hda_gen_spec *spec = codec->spec;
        int i;
 
-       if (!enable)
-               path->active = false;
+       path->active = enable;
 
        /* make sure the widget is powered up */
        if (enable && (spec->power_down_unused || codec->power_save_node))
@@ -902,9 +902,6 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
                if (has_amp_out(codec, path, i))
                        activate_amp_out(codec, path, i, enable);
        }
-
-       if (enable)
-               path->active = true;
 }
 EXPORT_SYMBOL_GPL(snd_hda_activate_path);
 
index baaf7ed..033aa84 100644 (file)
@@ -36,24 +36,9 @@ MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1
 #define param_read(codec, nid, parm) \
        snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
 
-static char *bits_names(unsigned int bits, char *names[], int size)
-{
-       int i, n;
-       static char buf[128];
-
-       for (i = 0, n = 0; i < size; i++) {
-               if (bits & (1U<<i) && names[i])
-                       n += snprintf(buf + n, sizeof(buf) - n, " %s",
-                                     names[i]);
-       }
-       buf[n] = '\0';
-
-       return buf;
-}
-
 static const char *get_wid_type_name(unsigned int wid_value)
 {
-       static char *names[16] = {
+       static const char * const names[16] = {
                [AC_WID_AUD_OUT] = "Audio Output",
                [AC_WID_AUD_IN] = "Audio Input",
                [AC_WID_AUD_MIX] = "Audio Mixer",
@@ -241,7 +226,7 @@ static void print_pcm_caps(struct snd_info_buffer *buffer,
 
 static const char *get_jack_connection(u32 cfg)
 {
-       static char *names[16] = {
+       static const char * const names[16] = {
                "Unknown", "1/8", "1/4", "ATAPI",
                "RCA", "Optical","Digital", "Analog",
                "DIN", "XLR", "RJ11", "Comb",
@@ -256,7 +241,7 @@ static const char *get_jack_connection(u32 cfg)
 
 static const char *get_jack_color(u32 cfg)
 {
-       static char *names[16] = {
+       static const char * const names[16] = {
                "Unknown", "Black", "Grey", "Blue",
                "Green", "Red", "Orange", "Yellow",
                "Purple", "Pink", NULL, NULL,
@@ -269,11 +254,74 @@ static const char *get_jack_color(u32 cfg)
                return "UNKNOWN";
 }
 
+/*
+ * Parse the pin default config value and returns the string of the
+ * jack location, e.g. "Rear", "Front", etc.
+ */
+static const char *get_jack_location(u32 cfg)
+{
+       static const char * const bases[7] = {
+               "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
+       };
+       static const unsigned char specials_idx[] = {
+               0x07, 0x08,
+               0x17, 0x18, 0x19,
+               0x37, 0x38
+       };
+       static const char * const specials[] = {
+               "Rear Panel", "Drive Bar",
+               "Riser", "HDMI", "ATAPI",
+               "Mobile-In", "Mobile-Out"
+       };
+       int i;
+
+       cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
+       if ((cfg & 0x0f) < 7)
+               return bases[cfg & 0x0f];
+       for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
+               if (cfg == specials_idx[i])
+                       return specials[i];
+       }
+       return "UNKNOWN";
+}
+
+/*
+ * Parse the pin default config value and returns the string of the
+ * jack connectivity, i.e. external or internal connection.
+ */
+static const char *get_jack_connectivity(u32 cfg)
+{
+       static const char * const jack_locations[4] = {
+               "Ext", "Int", "Sep", "Oth"
+       };
+
+       return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
+}
+
+/*
+ * Parse the pin default config value and returns the string of the
+ * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
+ */
+static const char *get_jack_type(u32 cfg)
+{
+       static const char * const jack_types[16] = {
+               "Line Out", "Speaker", "HP Out", "CD",
+               "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
+               "Line In", "Aux", "Mic", "Telephony",
+               "SPDIF In", "Digital In", "Reserved", "Other"
+       };
+
+       return jack_types[(cfg & AC_DEFCFG_DEVICE)
+                               >> AC_DEFCFG_DEVICE_SHIFT];
+}
+
 static void print_pin_caps(struct snd_info_buffer *buffer,
                           struct hda_codec *codec, hda_nid_t nid,
                           int *supports_vref)
 {
-       static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
+       static const char * const jack_conns[4] = {
+               "Jack", "N/A", "Fixed", "Both"
+       };
        unsigned int caps, val;
 
        caps = param_read(codec, nid, AC_PAR_PIN_CAP);
@@ -340,9 +388,9 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
        caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
        snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
                    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
-                   snd_hda_get_jack_type(caps),
-                   snd_hda_get_jack_connectivity(caps),
-                   snd_hda_get_jack_location(caps));
+                   get_jack_type(caps),
+                   get_jack_connectivity(caps),
+                   get_jack_location(caps));
        snd_iprintf(buffer, "    Conn = %s, Color = %s\n",
                    get_jack_connection(caps),
                    get_jack_color(caps));
@@ -478,7 +526,7 @@ static const char *get_pwr_state(u32 state)
 static void print_power_state(struct snd_info_buffer *buffer,
                              struct hda_codec *codec, hda_nid_t nid)
 {
-       static char *names[] = {
+       static const char * const names[] = {
                [ilog2(AC_PWRST_D0SUP)]         = "D0",
                [ilog2(AC_PWRST_D1SUP)]         = "D1",
                [ilog2(AC_PWRST_D2SUP)]         = "D2",
@@ -492,9 +540,16 @@ static void print_power_state(struct snd_info_buffer *buffer,
        int sup = param_read(codec, nid, AC_PAR_POWER_STATE);
        int pwr = snd_hda_codec_read(codec, nid, 0,
                                     AC_VERB_GET_POWER_STATE, 0);
-       if (sup != -1)
-               snd_iprintf(buffer, "  Power states: %s\n",
-                           bits_names(sup, names, ARRAY_SIZE(names)));
+       if (sup != -1) {
+               int i;
+
+               snd_iprintf(buffer, "  Power states: ");
+               for (i = 0; i < ARRAY_SIZE(names); i++) {
+                       if (sup & (1U << i))
+                               snd_iprintf(buffer, " %s", names[i]);
+               }
+               snd_iprintf(buffer, "\n");
+       }
 
        snd_iprintf(buffer, "  Power: setting=%s, actual=%s",
                    get_pwr_state(pwr & AC_PWRST_SETTING),
index 0f039ab..186792f 100644 (file)
@@ -763,6 +763,20 @@ enum {
        QUIRK_ALIENWARE,
 };
 
+static const struct hda_pintbl alienware_pincfgs[] = {
+       { 0x0b, 0x90170110 }, /* Builtin Speaker */
+       { 0x0c, 0x411111f0 }, /* N/A */
+       { 0x0d, 0x411111f0 }, /* N/A */
+       { 0x0e, 0x411111f0 }, /* N/A */
+       { 0x0f, 0x0321101f }, /* HP */
+       { 0x10, 0x411111f0 }, /* Headset?  disabled for now */
+       { 0x11, 0x03a11021 }, /* Mic */
+       { 0x12, 0xd5a30140 }, /* Builtin Mic */
+       { 0x13, 0x411111f0 }, /* N/A */
+       { 0x18, 0x411111f0 }, /* N/A */
+       {}
+};
+
 static const struct snd_pci_quirk ca0132_quirks[] = {
        SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15", QUIRK_ALIENWARE),
        {}
@@ -3147,7 +3161,7 @@ static int ca0132_select_out(struct hda_codec *codec)
        auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
 
        if (auto_jack)
-               jack_present = snd_hda_jack_detect(codec, spec->out_pins[1]);
+               jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_hp);
        else
                jack_present =
                        spec->vnode_lswitch[VNID_HP_SEL - VNODE_START_NID];
@@ -3309,7 +3323,7 @@ static int ca0132_select_mic(struct hda_codec *codec)
        auto_jack = spec->vnode_lswitch[VNID_AMIC1_ASEL - VNODE_START_NID];
 
        if (auto_jack)
-               jack_present = snd_hda_jack_detect(codec, spec->input_pins[0]);
+               jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_amic1);
        else
                jack_present =
                        spec->vnode_lswitch[VNID_AMIC1_SEL - VNODE_START_NID];
@@ -4617,37 +4631,54 @@ static void ca0132_config(struct hda_codec *codec)
        spec->multiout.num_dacs = 3;
        spec->multiout.max_channels = 2;
 
-       spec->num_outputs = 2;
-       spec->out_pins[0] = 0x0b; /* speaker out */
        if (spec->quirk == QUIRK_ALIENWARE) {
                codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n");
+               snd_hda_apply_pincfgs(codec, alienware_pincfgs);
+
+               spec->num_outputs = 2;
+               spec->out_pins[0] = 0x0b; /* speaker out */
                spec->out_pins[1] = 0x0f;
-       } else{
+               spec->shared_out_nid = 0x2;
+               spec->unsol_tag_hp = 0x0f;
+
+               spec->adcs[0] = 0x7; /* digital mic / analog mic1 */
+               spec->adcs[1] = 0x8; /* analog mic2 */
+               spec->adcs[2] = 0xa; /* what u hear */
+
+               spec->num_inputs = 3;
+               spec->input_pins[0] = 0x12;
+               spec->input_pins[1] = 0x11;
+               spec->input_pins[2] = 0x13;
+               spec->shared_mic_nid = 0x7;
+               spec->unsol_tag_amic1 = 0x11;
+       } else {
+               spec->num_outputs = 2;
+               spec->out_pins[0] = 0x0b; /* speaker out */
                spec->out_pins[1] = 0x10; /* headphone out */
+               spec->shared_out_nid = 0x2;
+               spec->unsol_tag_hp = spec->out_pins[1];
+
+               spec->adcs[0] = 0x7; /* digital mic / analog mic1 */
+               spec->adcs[1] = 0x8; /* analog mic2 */
+               spec->adcs[2] = 0xa; /* what u hear */
+
+               spec->num_inputs = 3;
+               spec->input_pins[0] = 0x12;
+               spec->input_pins[1] = 0x11;
+               spec->input_pins[2] = 0x13;
+               spec->shared_mic_nid = 0x7;
+               spec->unsol_tag_amic1 = spec->input_pins[0];
+
+               /* SPDIF I/O */
+               spec->dig_out = 0x05;
+               spec->multiout.dig_out_nid = spec->dig_out;
+               cfg->dig_out_pins[0] = 0x0c;
+               cfg->dig_outs = 1;
+               cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
+               spec->dig_in = 0x09;
+               cfg->dig_in_pin = 0x0e;
+               cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
        }
-       spec->shared_out_nid = 0x2;
-       spec->unsol_tag_hp = spec->out_pins[1];
-
-       spec->adcs[0] = 0x7; /* digital mic / analog mic1 */
-       spec->adcs[1] = 0x8; /* analog mic2 */
-       spec->adcs[2] = 0xa; /* what u hear */
-
-       spec->num_inputs = 3;
-       spec->input_pins[0] = 0x12;
-       spec->input_pins[1] = 0x11;
-       spec->input_pins[2] = 0x13;
-       spec->shared_mic_nid = 0x7;
-       spec->unsol_tag_amic1 = spec->input_pins[0];
-
-       /* SPDIF I/O */
-       spec->dig_out = 0x05;
-       spec->multiout.dig_out_nid = spec->dig_out;
-       cfg->dig_out_pins[0] = 0x0c;
-       cfg->dig_outs = 1;
-       cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
-       spec->dig_in = 0x09;
-       cfg->dig_in_pin = 0x0e;
-       cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
 }
 
 static int ca0132_prepare_verbs(struct hda_codec *codec)
index f788a91..ca03c40 100644 (file)
@@ -200,12 +200,33 @@ static int cx_auto_init(struct hda_codec *codec)
        return 0;
 }
 
-#define cx_auto_free   snd_hda_gen_free
+static void cx_auto_reboot_notify(struct hda_codec *codec)
+{
+       struct conexant_spec *spec = codec->spec;
+
+       if (codec->core.vendor_id != 0x14f150f2)
+               return;
+
+       /* Turn the CX20722 codec into D3 to avoid spurious noises
+          from the internal speaker during (and after) reboot */
+       cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, false);
+
+       snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
+       snd_hda_codec_write(codec, codec->core.afg, 0,
+                           AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+}
+
+static void cx_auto_free(struct hda_codec *codec)
+{
+       cx_auto_reboot_notify(codec);
+       snd_hda_gen_free(codec);
+}
 
 static const struct hda_codec_ops cx_auto_patch_ops = {
        .build_controls = cx_auto_build_controls,
        .build_pcms = snd_hda_gen_build_pcms,
        .init = cx_auto_init,
+       .reboot_notify = cx_auto_reboot_notify,
        .free = cx_auto_free,
        .unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
index 374ea53..4e6b090 100644 (file)
@@ -5389,400 +5389,202 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {}
 };
 
-#define ALC255_STANDARD_PINS \
-       {0x18, 0x411111f0}, \
-       {0x19, 0x411111f0}, \
-       {0x1a, 0x411111f0}, \
-       {0x1b, 0x411111f0}, \
-       {0x1e, 0x411111f0}
-
 #define ALC256_STANDARD_PINS \
        {0x12, 0x90a60140}, \
        {0x14, 0x90170110}, \
-       {0x19, 0x411111f0}, \
-       {0x1a, 0x411111f0}, \
-       {0x1b, 0x411111f0}, \
        {0x21, 0x02211020}
 
 #define ALC282_STANDARD_PINS \
-       {0x14, 0x90170110}, \
-       {0x18, 0x411111f0}, \
-       {0x1a, 0x411111f0}, \
-       {0x1b, 0x411111f0}, \
-       {0x1e, 0x411111f0}
-
-#define ALC288_STANDARD_PINS \
-       {0x17, 0x411111f0}, \
-       {0x18, 0x411111f0}, \
-       {0x19, 0x411111f0}, \
-       {0x1a, 0x411111f0}, \
-       {0x1e, 0x411111f0}
+       {0x14, 0x90170110}
 
 #define ALC290_STANDARD_PINS \
-       {0x12, 0x99a30130}, \
-       {0x13, 0x40000000}, \
-       {0x16, 0x411111f0}, \
-       {0x17, 0x411111f0}, \
-       {0x19, 0x411111f0}, \
-       {0x1b, 0x411111f0}, \
-       {0x1e, 0x411111f0}
+       {0x12, 0x99a30130}
 
 #define ALC292_STANDARD_PINS \
        {0x14, 0x90170110}, \
-       {0x15, 0x0221401f}, \
-       {0x1a, 0x411111f0}, \
-       {0x1b, 0x411111f0}, \
-       {0x1d, 0x40700001}
+       {0x15, 0x0221401f}
 
 #define ALC298_STANDARD_PINS \
-       {0x18, 0x411111f0}, \
-       {0x19, 0x411111f0}, \
-       {0x1a, 0x411111f0}, \
-       {0x1e, 0x411111f0}, \
-       {0x1f, 0x411111f0}
+       {0x12, 0x90a60130}, \
+       {0x21, 0x03211020}
 
 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
-               {0x12, 0x40300000},
                {0x14, 0x90170110},
-               {0x17, 0x411111f0},
-               {0x1d, 0x40538029},
                {0x21, 0x02211020}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60140},
                {0x14, 0x90170110},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211020}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60160},
                {0x14, 0x90170120},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211030}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               {0x12, 0x40000000},
                {0x14, 0x90170130},
-               {0x17, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
                {0x1b, 0x01014020},
-               {0x1d, 0x4054c029},
-               {0x1e, 0x411111f0},
                {0x21, 0x0221103f}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               {0x12, 0x40000000},
                {0x14, 0x90170150},
-               {0x17, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
                {0x1b, 0x02011020},
-               {0x1d, 0x4054c029},
-               {0x1e, 0x411111f0},
                {0x21, 0x0221105f}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               {0x12, 0x40000000},
                {0x14, 0x90170110},
-               {0x17, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
                {0x1b, 0x01014020},
-               {0x1d, 0x4054c029},
-               {0x1e, 0x411111f0},
                {0x21, 0x0221101f}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
                {0x12, 0x90a60160},
                {0x14, 0x90170120},
                {0x17, 0x90170140},
-               {0x18, 0x40000000},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x41163b05},
-               {0x1e, 0x411111f0},
                {0x21, 0x0321102f}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60160},
                {0x14, 0x90170130},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211040}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60160},
                {0x14, 0x90170140},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211050}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60170},
                {0x14, 0x90170120},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211030}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60170},
                {0x14, 0x90170130},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211040}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60170},
                {0x14, 0x90170140},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211050}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60180},
                {0x14, 0x90170130},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211040}),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC255_STANDARD_PINS,
                {0x12, 0x90a60160},
                {0x14, 0x90170120},
-               {0x17, 0x40000000},
-               {0x1d, 0x40700001},
                {0x21, 0x02211030}),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC256_STANDARD_PINS,
-               {0x13, 0x40000000},
-               {0x1d, 0x40700001},
-               {0x1e, 0x411111f0}),
-       SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC256_STANDARD_PINS,
-               {0x13, 0x411111f0},
-               {0x1d, 0x40700001},
-               {0x1e, 0x411111f0}),
-       SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC256_STANDARD_PINS,
-               {0x13, 0x411111f0},
-               {0x1d, 0x4077992d},
-               {0x1e, 0x411111ff}),
+               ALC256_STANDARD_PINS),
        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
                {0x12, 0x90a60130},
-               {0x13, 0x40000000},
                {0x14, 0x90170110},
                {0x15, 0x0421101f},
-               {0x16, 0x411111f0},
-               {0x17, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x04a11020},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x40748605},
-               {0x1e, 0x411111f0}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
                {0x12, 0x90a60140},
-               {0x13, 0x40000000},
                {0x14, 0x90170110},
                {0x15, 0x0421101f},
-               {0x16, 0x411111f0},
-               {0x17, 0x411111f0},
                {0x18, 0x02811030},
-               {0x19, 0x411111f0},
                {0x1a, 0x04a1103f},
-               {0x1b, 0x02011020},
-               {0x1d, 0x40700001},
-               {0x1e, 0x411111f0}),
+               {0x1b, 0x02011020}),
        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC282_STANDARD_PINS,
                {0x12, 0x99a30130},
-               {0x17, 0x40000000},
                {0x19, 0x03a11020},
-               {0x1d, 0x40f41905},
                {0x21, 0x0321101f}),
        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC282_STANDARD_PINS,
                {0x12, 0x99a30130},
-               {0x17, 0x40020008},
                {0x19, 0x03a11020},
-               {0x1d, 0x40e00001},
                {0x21, 0x03211040}),
        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC282_STANDARD_PINS,
                {0x12, 0x99a30130},
-               {0x17, 0x40000000},
                {0x19, 0x03a11030},
-               {0x1d, 0x40e00001},
                {0x21, 0x03211020}),
        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC282_STANDARD_PINS,
                {0x12, 0x99a30130},
-               {0x17, 0x40000000},
-               {0x19, 0x03a11030},
-               {0x1d, 0x40f00001},
-               {0x21, 0x03211020}),
-       SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
-               ALC282_STANDARD_PINS,
-               {0x12, 0x99a30130},
-               {0x17, 0x40000000},
                {0x19, 0x04a11020},
-               {0x1d, 0x40f00001},
                {0x21, 0x0421101f}),
-       SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
-               ALC282_STANDARD_PINS,
-               {0x12, 0x99a30130},
-               {0x17, 0x40000000},
-               {0x19, 0x03a11030},
-               {0x1d, 0x40f00001},
-               {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
                ALC282_STANDARD_PINS,
                {0x12, 0x90a60140},
-               {0x17, 0x40000000},
                {0x19, 0x04a11030},
-               {0x1d, 0x40f00001},
                {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC282_STANDARD_PINS,
                {0x12, 0x90a60130},
-               {0x17, 0x40020008},
-               {0x19, 0x411111f0},
-               {0x1d, 0x40e00001},
                {0x21, 0x0321101f}),
        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
                {0x12, 0x90a60160},
                {0x14, 0x90170120},
-               {0x17, 0x40000000},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x40700001},
-               {0x1e, 0x411111f0},
                {0x21, 0x02211030}),
        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC282_STANDARD_PINS,
                {0x12, 0x90a60130},
-               {0x17, 0x40020008},
                {0x19, 0x03a11020},
-               {0x1d, 0x40e00001},
                {0x21, 0x0321101f}),
        SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
-               ALC288_STANDARD_PINS,
                {0x12, 0x90a60120},
-               {0x13, 0x40000000},
                {0x14, 0x90170110},
-               {0x1d, 0x4076832d},
                {0x21, 0x0321101f}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
-               {0x14, 0x411111f0},
                {0x15, 0x04211040},
                {0x18, 0x90170112},
-               {0x1a, 0x04a11020},
-               {0x1d, 0x4075812d}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
-               {0x14, 0x411111f0},
                {0x15, 0x04211040},
                {0x18, 0x90170110},
-               {0x1a, 0x04a11020},
-               {0x1d, 0x4075812d}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
-               {0x14, 0x411111f0},
                {0x15, 0x0421101f},
-               {0x18, 0x411111f0},
-               {0x1a, 0x04a11020},
-               {0x1d, 0x4075812d}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
-               {0x14, 0x411111f0},
                {0x15, 0x04211020},
-               {0x18, 0x411111f0},
-               {0x1a, 0x04a11040},
-               {0x1d, 0x4076a12d}),
+               {0x1a, 0x04a11040}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
                {0x14, 0x90170110},
                {0x15, 0x04211020},
-               {0x18, 0x411111f0},
-               {0x1a, 0x04a11040},
-               {0x1d, 0x4076a12d}),
+               {0x1a, 0x04a11040}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
                {0x14, 0x90170110},
                {0x15, 0x04211020},
-               {0x18, 0x411111f0},
-               {0x1a, 0x04a11020},
-               {0x1d, 0x4076a12d}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
                {0x14, 0x90170110},
                {0x15, 0x0421101f},
-               {0x18, 0x411111f0},
-               {0x1a, 0x04a11020},
-               {0x1d, 0x4075812d}),
+               {0x1a, 0x04a11020}),
        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
                {0x12, 0x90a60140},
-               {0x13, 0x411111f0},
                {0x16, 0x01014020},
-               {0x18, 0x411111f0},
-               {0x19, 0x01a19030},
-               {0x1e, 0x411111f0}),
+               {0x19, 0x01a19030}),
        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
                {0x12, 0x90a60140},
-               {0x13, 0x411111f0},
                {0x16, 0x01014020},
                {0x18, 0x02a19031},
-               {0x19, 0x01a1903e},
-               {0x1e, 0x411111f0}),
+               {0x19, 0x01a1903e}),
        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
-               {0x12, 0x90a60140},
-               {0x13, 0x411111f0},
-               {0x16, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1e, 0x411111f0}),
+               {0x12, 0x90a60140}),
        SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
-               {0x12, 0x40000000},
                {0x13, 0x90a60140},
                {0x16, 0x21014020},
-               {0x18, 0x411111f0},
-               {0x19, 0x21a19030},
-               {0x1e, 0x411111f0}),
-       SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
-               ALC292_STANDARD_PINS,
-               {0x12, 0x40000000},
-               {0x13, 0x90a60140},
-               {0x16, 0x411111f0},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1e, 0x411111f0}),
+               {0x19, 0x21a19030}),
        SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC292_STANDARD_PINS,
-               {0x12, 0x40000000},
-               {0x13, 0x90a60140},
-               {0x16, 0x21014020},
-               {0x18, 0x411111f0},
-               {0x19, 0x21a19030},
-               {0x1e, 0x411111ff}),
+               {0x13, 0x90a60140}),
        SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC298_STANDARD_PINS,
-               {0x12, 0x90a60130},
-               {0x13, 0x40000000},
-               {0x14, 0x411111f0},
-               {0x17, 0x90170140},
-               {0x1d, 0x4068a36d},
-               {0x21, 0x03211020}),
+               {0x17, 0x90170110}),
+       SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC298_STANDARD_PINS,
+               {0x17, 0x90170140}),
+       SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC298_STANDARD_PINS,
+               {0x17, 0x90170150}),
        {}
 };
 
@@ -6675,77 +6477,33 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
 
 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
-               {0x12, 0x4004c000},
                {0x14, 0x01014010},
-               {0x15, 0x411111f0},
-               {0x16, 0x411111f0},
                {0x18, 0x01a19020},
-               {0x19, 0x411111f0},
                {0x1a, 0x0181302f},
-               {0x1b, 0x0221401f},
-               {0x1c, 0x411111f0},
-               {0x1d, 0x4054c601},
-               {0x1e, 0x411111f0}),
+               {0x1b, 0x0221401f}),
        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
                {0x12, 0x99a30130},
                {0x14, 0x90170110},
                {0x15, 0x0321101f},
-               {0x16, 0x03011020},
-               {0x18, 0x40000008},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x41000001},
-               {0x1e, 0x411111f0},
-               {0x1f, 0x411111f0}),
+               {0x16, 0x03011020}),
        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
                {0x12, 0x99a30140},
                {0x14, 0x90170110},
                {0x15, 0x0321101f},
-               {0x16, 0x03011020},
-               {0x18, 0x40000008},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x41000001},
-               {0x1e, 0x411111f0},
-               {0x1f, 0x411111f0}),
+               {0x16, 0x03011020}),
        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
                {0x12, 0x99a30150},
                {0x14, 0x90170110},
                {0x15, 0x0321101f},
-               {0x16, 0x03011020},
-               {0x18, 0x40000008},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x41000001},
-               {0x1e, 0x411111f0},
-               {0x1f, 0x411111f0}),
+               {0x16, 0x03011020}),
        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
-               {0x12, 0x411111f0},
                {0x14, 0x90170110},
                {0x15, 0x0321101f},
-               {0x16, 0x03011020},
-               {0x18, 0x40000008},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x41000001},
-               {0x1e, 0x411111f0},
-               {0x1f, 0x411111f0}),
+               {0x16, 0x03011020}),
        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
                {0x12, 0x90a60130},
                {0x14, 0x90170110},
-               {0x15, 0x0321101f},
-               {0x16, 0x40000000},
-               {0x18, 0x411111f0},
-               {0x19, 0x411111f0},
-               {0x1a, 0x411111f0},
-               {0x1b, 0x411111f0},
-               {0x1d, 0x40d6832d},
-               {0x1e, 0x411111f0},
-               {0x1f, 0x411111f0}),
+               {0x15, 0x0321101f}),
        {}
 };
 
index c19e021..9bba275 100644 (file)
@@ -1526,7 +1526,7 @@ static struct snd_rawmidi_ops snd_hdsp_midi_input =
 
 static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int id)
 {
-       char buf[32];
+       char buf[40];
 
        hdsp->midi[id].id = id;
        hdsp->midi[id].rmidi = NULL;
@@ -1537,7 +1537,7 @@ static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int i
        hdsp->midi[id].pending = 0;
        spin_lock_init (&hdsp->midi[id].lock);
 
-       sprintf (buf, "%s MIDI %d", card->shortname, id+1);
+       snprintf(buf, sizeof(buf), "%s MIDI %d", card->shortname, id + 1);
        if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
                return -1;
 
@@ -2806,7 +2806,8 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
        struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
        offset = ucontrol->id.index - 1;
-       snd_BUG_ON(offset < 0);
+       if (snd_BUG_ON(offset < 0))
+               return -EINVAL;
 
        switch (hdsp->io_type) {
        case Digiface:
index 6120a06..4373615 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "pmac.h"
 
@@ -101,6 +102,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
        { "keywest", 0 },               /* instantiated by us if needed */
        { }
 };
+MODULE_DEVICE_TABLE(i2c, keywest_i2c_id);
 
 static struct i2c_driver keywest_driver = {
        .driver = {
index 0450593..18f5664 100644 (file)
@@ -365,13 +365,15 @@ static int snd_usb_audio_create(struct usb_interface *intf,
        }
 
        mutex_init(&chip->mutex);
-       init_rwsem(&chip->shutdown_rwsem);
+       init_waitqueue_head(&chip->shutdown_wait);
        chip->index = idx;
        chip->dev = dev;
        chip->card = card;
        chip->setup = device_setup[idx];
        chip->autoclock = autoclock;
-       chip->probing = 1;
+       atomic_set(&chip->active, 1); /* avoid autopm during probing */
+       atomic_set(&chip->usage_count, 0);
+       atomic_set(&chip->shutdown, 0);
 
        chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
                              le16_to_cpu(dev->descriptor.idProduct));
@@ -495,13 +497,13 @@ static int usb_audio_probe(struct usb_interface *intf,
        mutex_lock(&register_mutex);
        for (i = 0; i < SNDRV_CARDS; i++) {
                if (usb_chip[i] && usb_chip[i]->dev == dev) {
-                       if (usb_chip[i]->shutdown) {
+                       if (atomic_read(&usb_chip[i]->shutdown)) {
                                dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n");
                                err = -EIO;
                                goto __error;
                        }
                        chip = usb_chip[i];
-                       chip->probing = 1;
+                       atomic_inc(&chip->active); /* avoid autopm */
                        break;
                }
        }
@@ -561,8 +563,8 @@ static int usb_audio_probe(struct usb_interface *intf,
 
        usb_chip[chip->index] = chip;
        chip->num_interfaces++;
-       chip->probing = 0;
        usb_set_intfdata(intf, chip);
+       atomic_dec(&chip->active);
        mutex_unlock(&register_mutex);
        return 0;
 
@@ -570,7 +572,7 @@ static int usb_audio_probe(struct usb_interface *intf,
        if (chip) {
                if (!chip->num_interfaces)
                        snd_card_free(chip->card);
-               chip->probing = 0;
+               atomic_dec(&chip->active);
        }
        mutex_unlock(&register_mutex);
        return err;
@@ -585,23 +587,23 @@ static void usb_audio_disconnect(struct usb_interface *intf)
        struct snd_usb_audio *chip = usb_get_intfdata(intf);
        struct snd_card *card;
        struct list_head *p;
-       bool was_shutdown;
 
        if (chip == (void *)-1L)
                return;
 
        card = chip->card;
-       down_write(&chip->shutdown_rwsem);
-       was_shutdown = chip->shutdown;
-       chip->shutdown = 1;
-       up_write(&chip->shutdown_rwsem);
 
        mutex_lock(&register_mutex);
-       if (!was_shutdown) {
+       if (atomic_inc_return(&chip->shutdown) == 1) {
                struct snd_usb_stream *as;
                struct snd_usb_endpoint *ep;
                struct usb_mixer_interface *mixer;
 
+               /* wait until all pending tasks done;
+                * they are protected by snd_usb_lock_shutdown()
+                */
+               wait_event(chip->shutdown_wait,
+                          !atomic_read(&chip->usage_count));
                snd_card_disconnect(card);
                /* release the pcm resources */
                list_for_each_entry(as, &chip->pcm_list, list) {
@@ -631,28 +633,50 @@ static void usb_audio_disconnect(struct usb_interface *intf)
        }
 }
 
-#ifdef CONFIG_PM
-
-int snd_usb_autoresume(struct snd_usb_audio *chip)
+/* lock the shutdown (disconnect) task and autoresume */
+int snd_usb_lock_shutdown(struct snd_usb_audio *chip)
 {
-       int err = -ENODEV;
+       int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->probing || chip->in_pm)
-               err = 0;
-       else if (!chip->shutdown)
-               err = usb_autopm_get_interface(chip->pm_intf);
-       up_read(&chip->shutdown_rwsem);
+       atomic_inc(&chip->usage_count);
+       if (atomic_read(&chip->shutdown)) {
+               err = -EIO;
+               goto error;
+       }
+       err = snd_usb_autoresume(chip);
+       if (err < 0)
+               goto error;
+       return 0;
 
+ error:
+       if (atomic_dec_and_test(&chip->usage_count))
+               wake_up(&chip->shutdown_wait);
        return err;
 }
 
+/* autosuspend and unlock the shutdown */
+void snd_usb_unlock_shutdown(struct snd_usb_audio *chip)
+{
+       snd_usb_autosuspend(chip);
+       if (atomic_dec_and_test(&chip->usage_count))
+               wake_up(&chip->shutdown_wait);
+}
+
+#ifdef CONFIG_PM
+
+int snd_usb_autoresume(struct snd_usb_audio *chip)
+{
+       if (atomic_read(&chip->shutdown))
+               return -EIO;
+       if (atomic_inc_return(&chip->active) == 1)
+               return usb_autopm_get_interface(chip->pm_intf);
+       return 0;
+}
+
 void snd_usb_autosuspend(struct snd_usb_audio *chip)
 {
-       down_read(&chip->shutdown_rwsem);
-       if (!chip->shutdown && !chip->probing && !chip->in_pm)
+       if (atomic_dec_and_test(&chip->active))
                usb_autopm_put_interface(chip->pm_intf);
-       up_read(&chip->shutdown_rwsem);
 }
 
 static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
@@ -665,30 +689,20 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
        if (chip == (void *)-1L)
                return 0;
 
-       if (!PMSG_IS_AUTO(message)) {
+       chip->autosuspended = !!PMSG_IS_AUTO(message);
+       if (!chip->autosuspended)
                snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
-               if (!chip->num_suspended_intf++) {
-                       list_for_each_entry(as, &chip->pcm_list, list) {
-                               snd_pcm_suspend_all(as->pcm);
-                               as->substream[0].need_setup_ep =
-                                       as->substream[1].need_setup_ep = true;
-                       }
-                       list_for_each(p, &chip->midi_list) {
-                               snd_usbmidi_suspend(p);
-                       }
+       if (!chip->num_suspended_intf++) {
+               list_for_each_entry(as, &chip->pcm_list, list) {
+                       snd_pcm_suspend_all(as->pcm);
+                       as->substream[0].need_setup_ep =
+                               as->substream[1].need_setup_ep = true;
                }
-       } else {
-               /*
-                * otherwise we keep the rest of the system in the dark
-                * to keep this transparent
-                */
-               if (!chip->num_suspended_intf++)
-                       chip->autosuspended = 1;
-       }
-
-       if (chip->num_suspended_intf == 1)
+               list_for_each(p, &chip->midi_list)
+                       snd_usbmidi_suspend(p);
                list_for_each_entry(mixer, &chip->mixer_list, list)
                        snd_usb_mixer_suspend(mixer);
+       }
 
        return 0;
 }
@@ -705,7 +719,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
        if (--chip->num_suspended_intf)
                return 0;
 
-       chip->in_pm = 1;
+       atomic_inc(&chip->active); /* avoid autopm */
        /*
         * ALSA leaves material resumption to user space
         * we just notify and restart the mixers
@@ -725,7 +739,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
        chip->autosuspended = 0;
 
 err_out:
-       chip->in_pm = 0;
+       atomic_dec(&chip->active); /* allow autopm after this point */
        return err;
 }
 
index 03b0744..e6f7189 100644 (file)
@@ -355,8 +355,10 @@ static void snd_complete_urb(struct urb *urb)
        if (unlikely(urb->status == -ENOENT ||          /* unlinked */
                     urb->status == -ENODEV ||          /* device removed */
                     urb->status == -ECONNRESET ||      /* unlinked */
-                    urb->status == -ESHUTDOWN ||       /* device disabled */
-                    ep->chip->shutdown))               /* device disconnected */
+                    urb->status == -ESHUTDOWN))        /* device disabled */
+               goto exit_clear;
+       /* device disconnected */
+       if (unlikely(atomic_read(&ep->chip->shutdown)))
                goto exit_clear;
 
        if (usb_pipeout(ep->pipe)) {
@@ -529,7 +531,7 @@ static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force)
 {
        unsigned int i;
 
-       if (!force && ep->chip->shutdown) /* to be sure... */
+       if (!force && atomic_read(&ep->chip->shutdown)) /* to be sure... */
                return -EBADFD;
 
        clear_bit(EP_FLAG_RUNNING, &ep->flags);
@@ -868,7 +870,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)
        int err;
        unsigned int i;
 
-       if (ep->chip->shutdown)
+       if (atomic_read(&ep->chip->shutdown))
                return -EBADFD;
 
        /* already running? */
index 6b3acba..f494dce 100644 (file)
@@ -282,6 +282,21 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
        return val;
 }
 
+static int uac2_ctl_value_size(int val_type)
+{
+       switch (val_type) {
+       case USB_MIXER_S32:
+       case USB_MIXER_U32:
+               return 4;
+       case USB_MIXER_S16:
+       case USB_MIXER_U16:
+               return 2;
+       default:
+               return 1;
+       }
+       return 0; /* unreachable */
+}
+
 
 /*
  * retrieve a mixer value
@@ -296,14 +311,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
        int timeout = 10;
        int idx = 0, err;
 
-       err = snd_usb_autoresume(chip);
+       err = snd_usb_lock_shutdown(chip);
        if (err < 0)
                return -EIO;
 
-       down_read(&chip->shutdown_rwsem);
        while (timeout-- > 0) {
-               if (chip->shutdown)
-                       break;
                idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
                if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
                                    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
@@ -319,8 +331,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
        err = -EINVAL;
 
  out:
-       up_read(&chip->shutdown_rwsem);
-       snd_usb_autosuspend(chip);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -328,14 +339,14 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
                            int validx, int *value_ret)
 {
        struct snd_usb_audio *chip = cval->head.mixer->chip;
-       unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */
+       unsigned char buf[4 + 3 * sizeof(__u32)]; /* enough space for one range */
        unsigned char *val;
        int idx = 0, ret, size;
        __u8 bRequest;
 
        if (request == UAC_GET_CUR) {
                bRequest = UAC2_CS_CUR;
-               size = sizeof(__u16);
+               size = uac2_ctl_value_size(cval->val_type);
        } else {
                bRequest = UAC2_CS_RANGE;
                size = sizeof(buf);
@@ -343,21 +354,15 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
 
        memset(buf, 0, sizeof(buf));
 
-       ret = snd_usb_autoresume(chip) ? -EIO : 0;
+       ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
        if (ret)
                goto error;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               ret = -ENODEV;
-       } else {
-               idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
-               ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
+       idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
+       ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
                              USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
                              validx, idx, buf, size);
-       }
-       up_read(&chip->shutdown_rwsem);
-       snd_usb_autosuspend(chip);
+       snd_usb_unlock_shutdown(chip);
 
        if (ret < 0) {
 error:
@@ -446,7 +451,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
                                int request, int validx, int value_set)
 {
        struct snd_usb_audio *chip = cval->head.mixer->chip;
-       unsigned char buf[2];
+       unsigned char buf[4];
        int idx = 0, val_len, err, timeout = 10;
 
        validx += cval->idx_off;
@@ -454,8 +459,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
        if (cval->head.mixer->protocol == UAC_VERSION_1) {
                val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
        } else { /* UAC_VERSION_2 */
-               /* audio class v2 controls are always 2 bytes in size */
-               val_len = sizeof(__u16);
+               val_len = uac2_ctl_value_size(cval->val_type);
 
                /* FIXME */
                if (request != UAC_SET_CUR) {
@@ -469,13 +473,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
        value_set = convert_bytes_value(cval, value_set);
        buf[0] = value_set & 0xff;
        buf[1] = (value_set >> 8) & 0xff;
-       err = snd_usb_autoresume(chip);
+       buf[2] = (value_set >> 16) & 0xff;
+       buf[3] = (value_set >> 24) & 0xff;
+
+       err = snd_usb_lock_shutdown(chip);
        if (err < 0)
                return -EIO;
-       down_read(&chip->shutdown_rwsem);
+
        while (timeout-- > 0) {
-               if (chip->shutdown)
-                       break;
                idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
                if (snd_usb_ctl_msg(chip->dev,
                                    usb_sndctrlpipe(chip->dev, 0), request,
@@ -490,8 +495,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
        err = -EINVAL;
 
  out:
-       up_read(&chip->shutdown_rwsem);
-       snd_usb_autosuspend(chip);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -715,15 +719,21 @@ static int check_input_term(struct mixer_build *state, int id,
                                term->name = d->iTerminal;
                        } else { /* UAC_VERSION_2 */
                                struct uac2_input_terminal_descriptor *d = p1;
-                               term->type = le16_to_cpu(d->wTerminalType);
-                               term->channels = d->bNrChannels;
-                               term->chconfig = le32_to_cpu(d->bmChannelConfig);
-                               term->name = d->iTerminal;
 
-                               /* call recursively to get the clock selectors */
+                               /* call recursively to verify that the
+                                * referenced clock entity is valid */
                                err = check_input_term(state, d->bCSourceID, term);
                                if (err < 0)
                                        return err;
+
+                               /* save input term properties after recursion,
+                                * to ensure they are not overriden by the
+                                * recursion calls */
+                               term->id = id;
+                               term->type = le16_to_cpu(d->wTerminalType);
+                               term->channels = d->bNrChannels;
+                               term->chconfig = le32_to_cpu(d->bmChannelConfig);
+                               term->name = d->iTerminal;
                        }
                        return 0;
                case UAC_FEATURE_UNIT: {
@@ -798,24 +808,25 @@ static int check_input_term(struct mixer_build *state, int id,
 /* feature unit control information */
 struct usb_feature_control_info {
        const char *name;
-       unsigned int type;      /* control type (mute, volume, etc.) */
+       int type;       /* data type for uac1 */
+       int type_uac2;  /* data type for uac2 if different from uac1, else -1 */
 };
 
 static struct usb_feature_control_info audio_feature_info[] = {
-       { "Mute",                       USB_MIXER_INV_BOOLEAN },
-       { "Volume",                     USB_MIXER_S16 },
-       { "Tone Control - Bass",        USB_MIXER_S8 },
-       { "Tone Control - Mid",         USB_MIXER_S8 },
-       { "Tone Control - Treble",      USB_MIXER_S8 },
-       { "Graphic Equalizer",          USB_MIXER_S8 }, /* FIXME: not implemeted yet */
-       { "Auto Gain Control",          USB_MIXER_BOOLEAN },
-       { "Delay Control",              USB_MIXER_U16 }, /* FIXME: U32 in UAC2 */
-       { "Bass Boost",                 USB_MIXER_BOOLEAN },
-       { "Loudness",                   USB_MIXER_BOOLEAN },
+       { "Mute",                       USB_MIXER_INV_BOOLEAN, -1 },
+       { "Volume",                     USB_MIXER_S16, -1 },
+       { "Tone Control - Bass",        USB_MIXER_S8, -1 },
+       { "Tone Control - Mid",         USB_MIXER_S8, -1 },
+       { "Tone Control - Treble",      USB_MIXER_S8, -1 },
+       { "Graphic Equalizer",          USB_MIXER_S8, -1 }, /* FIXME: not implemeted yet */
+       { "Auto Gain Control",          USB_MIXER_BOOLEAN, -1 },
+       { "Delay Control",              USB_MIXER_U16, USB_MIXER_U32 },
+       { "Bass Boost",                 USB_MIXER_BOOLEAN, -1 },
+       { "Loudness",                   USB_MIXER_BOOLEAN, -1 },
        /* UAC2 specific */
-       { "Input Gain Control",         USB_MIXER_S16 },
-       { "Input Gain Pad Control",     USB_MIXER_S16 },
-       { "Phase Inverter Control",     USB_MIXER_BOOLEAN },
+       { "Input Gain Control",         USB_MIXER_S16, -1 },
+       { "Input Gain Pad Control",     USB_MIXER_S16, -1 },
+       { "Phase Inverter Control",     USB_MIXER_BOOLEAN, -1 },
 };
 
 /* private_free callback */
@@ -1215,6 +1226,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                              int readonly_mask)
 {
        struct uac_feature_unit_descriptor *desc = raw_desc;
+       struct usb_feature_control_info *ctl_info;
        unsigned int len = 0;
        int mapped_name = 0;
        int nameid = uac_feature_unit_iFeature(desc);
@@ -1240,7 +1252,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
        snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
        cval->control = control;
        cval->cmask = ctl_mask;
-       cval->val_type = audio_feature_info[control-1].type;
+       ctl_info = &audio_feature_info[control-1];
+       if (state->mixer->protocol == UAC_VERSION_1)
+               cval->val_type = ctl_info->type;
+       else /* UAC_VERSION_2 */
+               cval->val_type = ctl_info->type_uac2 >= 0 ?
+                       ctl_info->type_uac2 : ctl_info->type;
+
        if (ctl_mask == 0) {
                cval->channels = 1;     /* master channel */
                cval->master_readonly = readonly_mask;
@@ -2522,7 +2540,7 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
                for (c = 0; c < MAX_CHANNELS; c++) {
                        if (!(cval->cmask & (1 << c)))
                                continue;
-                       if (cval->cached & (1 << c)) {
+                       if (cval->cached & (1 << (c + 1))) {
                                err = snd_usb_set_cur_mix_value(cval, c + 1, idx,
                                                        cval->cache_val[idx]);
                                if (err < 0)
index d3268f0..3417ef3 100644 (file)
@@ -33,6 +33,8 @@ enum {
        USB_MIXER_U8,
        USB_MIXER_S16,
        USB_MIXER_U16,
+       USB_MIXER_S32,
+       USB_MIXER_U32,
 };
 
 typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer,
index 337c317..d3608c0 100644 (file)
@@ -308,11 +308,10 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
        struct snd_usb_audio *chip = mixer->chip;
        int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               err = -ENODEV;
-               goto out;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
+
        if (chip->usb_id == USB_ID(0x041e, 0x3042))
                err = snd_usb_ctl_msg(chip->dev,
                              usb_sndctrlpipe(chip->dev, 0), 0x24,
@@ -329,8 +328,7 @@ static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
                              usb_sndctrlpipe(chip->dev, 0), 0x24,
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
                              value, index + 2, NULL, 0);
- out:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -441,16 +439,15 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
 
        for (i = 0; jacks[i].name; ++i) {
                snd_iprintf(buffer, "%s: ", jacks[i].name);
-               down_read(&mixer->chip->shutdown_rwsem);
-               if (mixer->chip->shutdown)
-                       err = 0;
-               else
-                       err = snd_usb_ctl_msg(mixer->chip->dev,
+               err = snd_usb_lock_shutdown(mixer->chip);
+               if (err < 0)
+                       return;
+               err = snd_usb_ctl_msg(mixer->chip->dev,
                                      usb_rcvctrlpipe(mixer->chip->dev, 0),
                                      UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
                                      USB_RECIP_INTERFACE, 0,
                                      jacks[i].unitid << 8, buf, 3);
-               up_read(&mixer->chip->shutdown_rwsem);
+               snd_usb_unlock_shutdown(mixer->chip);
                if (err == 3 && (buf[0] == 3 || buf[0] == 6))
                        snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
                else
@@ -481,11 +478,9 @@ static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
        int err;
        unsigned char buf[2];
 
-       down_read(&chip->shutdown_rwsem);
-       if (mixer->chip->shutdown) {
-               err = -ENODEV;
-               goto out;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
 
        buf[0] = 0x01;
        buf[1] = value ? 0x02 : 0x01;
@@ -493,8 +488,7 @@ static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
                      usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
                      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
                      0x0400, 0x0e00, buf, 2);
- out:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -554,15 +548,14 @@ static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
        struct snd_usb_audio *chip = mixer->chip;
        int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown)
-               err = -ENODEV;
-       else
-               err = snd_usb_ctl_msg(chip->dev,
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
+       err = snd_usb_ctl_msg(chip->dev,
                              usb_sndctrlpipe(chip->dev, 0), 0x08,
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
                              50, 0, &status, 1);
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -623,11 +616,9 @@ static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
        int err;
        unsigned char buff[3];
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               err = -ENODEV;
-               goto err;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
 
        /* Prepare for magic command to toggle clock source */
        err = snd_usb_ctl_msg(chip->dev,
@@ -683,7 +674,7 @@ static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
                goto err;
 
 err:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -778,15 +769,14 @@ static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
        unsigned int pval = list->kctl->private_value;
        int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown)
-               err = -ENODEV;
-       else
-               err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
-                                     (pval >> 16) & 0xff,
-                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                                     pval >> 24, pval & 0xffff, NULL, 0, 1000);
-       up_read(&chip->shutdown_rwsem);
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
+       err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
+                             (pval >> 16) & 0xff,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                             pval >> 24, pval & 0xffff, NULL, 0, 1000);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -944,18 +934,17 @@ static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
        value[0] = pval >> 24;
        value[1] = 0;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown)
-               err = -ENODEV;
-       else
-               err = snd_usb_ctl_msg(chip->dev,
-                                     usb_sndctrlpipe(chip->dev, 0),
-                                     UAC_SET_CUR,
-                                     USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-                                     pval & 0xff00,
-                                     snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
-                                     value, 2);
-       up_read(&chip->shutdown_rwsem);
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
+       err = snd_usb_ctl_msg(chip->dev,
+                             usb_sndctrlpipe(chip->dev, 0),
+                             UAC_SET_CUR,
+                             USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+                             pval & 0xff00,
+                             snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
+                             value, 2);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -1519,11 +1508,9 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
        unsigned char data[3];
        int rate;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               err = -ENODEV;
-               goto end;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
 
        ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
        ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
@@ -1551,7 +1538,7 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
 
        err = 0;
  end:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -1562,11 +1549,9 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
        u8 reg;
        int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               err = -ENODEV;
-               goto end;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
 
        reg = ((pval >> 4) & 0xf0) | (pval & 0x0f);
        err = snd_usb_ctl_msg(chip->dev,
@@ -1594,7 +1579,7 @@ static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
                goto end;
 
  end:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
@@ -1650,11 +1635,9 @@ static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
        u8 reg = list->kctl->private_value;
        int err;
 
-       down_read(&chip->shutdown_rwsem);
-       if (chip->shutdown) {
-               err = -ENODEV;
-               goto end;
-       }
+       err = snd_usb_lock_shutdown(chip);
+       if (err < 0)
+               return err;
 
        err = snd_usb_ctl_msg(chip->dev,
                        usb_sndctrlpipe(chip->dev, 0),
@@ -1665,8 +1648,7 @@ static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
                        NULL,
                        0);
 
- end:
-       up_read(&chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(chip);
        return err;
 }
 
index b4ef410..cdac517 100644 (file)
@@ -80,7 +80,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
        unsigned int hwptr_done;
 
        subs = (struct snd_usb_substream *)substream->runtime->private_data;
-       if (subs->stream->chip->shutdown)
+       if (atomic_read(&subs->stream->chip->shutdown))
                return SNDRV_PCM_POS_XRUN;
        spin_lock(&subs->lock);
        hwptr_done = subs->hwptr_done;
@@ -391,6 +391,20 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
         */
        attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
 
+       if ((is_playback && (attr != USB_ENDPOINT_SYNC_ASYNC)) ||
+               (!is_playback && (attr != USB_ENDPOINT_SYNC_ADAPTIVE))) {
+
+               /*
+                * In these modes the notion of sync_endpoint is irrelevant.
+                * Reset pointers to avoid using stale data from previously
+                * used settings, e.g. when configuration and endpoints were
+                * changed
+                */
+
+               subs->sync_endpoint = NULL;
+               subs->data_endpoint->sync_master = NULL;
+       }
+
        err = set_sync_ep_implicit_fb_quirk(subs, dev, altsd, attr);
        if (err < 0)
                return err;
@@ -398,10 +412,17 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
        if (altsd->bNumEndpoints < 2)
                return 0;
 
-       if ((is_playback && attr != USB_ENDPOINT_SYNC_ASYNC) ||
+       if ((is_playback && (attr == USB_ENDPOINT_SYNC_SYNC ||
+                            attr == USB_ENDPOINT_SYNC_ADAPTIVE)) ||
            (!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
                return 0;
 
+       /*
+        * In case of illegal SYNC_NONE for OUT endpoint, we keep going to see
+        * if we don't find a sync endpoint, as on M-Audio Transit. In case of
+        * error fall back to SYNC mode and don't create sync endpoint
+        */
+
        /* check sync-pipe endpoint */
        /* ... and check descriptor size before accessing bSynchAddress
           because there is a version of the SB Audigy 2 NX firmware lacking
@@ -415,6 +436,8 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
                           get_endpoint(alts, 1)->bmAttributes,
                           get_endpoint(alts, 1)->bLength,
                           get_endpoint(alts, 1)->bSynchAddress);
+               if (is_playback && attr == USB_ENDPOINT_SYNC_NONE)
+                       return 0;
                return -EINVAL;
        }
        ep = get_endpoint(alts, 1)->bEndpointAddress;
@@ -425,6 +448,8 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
                        "%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
                           fmt->iface, fmt->altsetting,
                           is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
+               if (is_playback && attr == USB_ENDPOINT_SYNC_NONE)
+                       return 0;
                return -EINVAL;
        }
 
@@ -436,8 +461,11 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
                                                   implicit_fb ?
                                                        SND_USB_ENDPOINT_TYPE_DATA :
                                                        SND_USB_ENDPOINT_TYPE_SYNC);
-       if (!subs->sync_endpoint)
+       if (!subs->sync_endpoint) {
+               if (is_playback && attr == USB_ENDPOINT_SYNC_NONE)
+                       return 0;
                return -EINVAL;
+       }
 
        subs->data_endpoint->sync_master = subs->sync_endpoint;
 
@@ -707,12 +735,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       down_read(&subs->stream->chip->shutdown_rwsem);
-       if (subs->stream->chip->shutdown)
-               ret = -ENODEV;
-       else
-               ret = set_format(subs, fmt);
-       up_read(&subs->stream->chip->shutdown_rwsem);
+       ret = snd_usb_lock_shutdown(subs->stream->chip);
+       if (ret < 0)
+               return ret;
+       ret = set_format(subs, fmt);
+       snd_usb_unlock_shutdown(subs->stream->chip);
        if (ret < 0)
                return ret;
 
@@ -735,13 +762,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
        subs->cur_audiofmt = NULL;
        subs->cur_rate = 0;
        subs->period_bytes = 0;
-       down_read(&subs->stream->chip->shutdown_rwsem);
-       if (!subs->stream->chip->shutdown) {
+       if (!snd_usb_lock_shutdown(subs->stream->chip)) {
                stop_endpoints(subs, true);
                snd_usb_endpoint_deactivate(subs->sync_endpoint);
                snd_usb_endpoint_deactivate(subs->data_endpoint);
+               snd_usb_unlock_shutdown(subs->stream->chip);
        }
-       up_read(&subs->stream->chip->shutdown_rwsem);
        return snd_pcm_lib_free_vmalloc_buffer(substream);
 }
 
@@ -763,11 +789,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
                return -ENXIO;
        }
 
-       down_read(&subs->stream->chip->shutdown_rwsem);
-       if (subs->stream->chip->shutdown) {
-               ret = -ENODEV;
-               goto unlock;
-       }
+       ret = snd_usb_lock_shutdown(subs->stream->chip);
+       if (ret < 0)
+               return ret;
        if (snd_BUG_ON(!subs->data_endpoint)) {
                ret = -EIO;
                goto unlock;
@@ -816,7 +840,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
                ret = start_endpoints(subs, true);
 
  unlock:
-       up_read(&subs->stream->chip->shutdown_rwsem);
+       snd_usb_unlock_shutdown(subs->stream->chip);
        return ret;
 }
 
@@ -1218,9 +1242,11 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
 
        stop_endpoints(subs, true);
 
-       if (!as->chip->shutdown && subs->interface >= 0) {
+       if (subs->interface >= 0 &&
+           !snd_usb_lock_shutdown(subs->stream->chip)) {
                usb_set_interface(subs->dev, subs->interface, 0);
                subs->interface = -1;
+               snd_usb_unlock_shutdown(subs->stream->chip);
        }
 
        subs->pcm_substream = NULL;
index 5f761ab..0ac89e2 100644 (file)
@@ -46,14 +46,14 @@ static inline unsigned get_high_speed_hz(unsigned int usb_rate)
 static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
        struct snd_usb_audio *chip = entry->private_data;
-       if (!chip->shutdown)
+       if (!atomic_read(&chip->shutdown))
                snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
 }
 
 static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
        struct snd_usb_audio *chip = entry->private_data;
-       if (!chip->shutdown)
+       if (!atomic_read(&chip->shutdown))
                snd_iprintf(buffer, "%04x:%04x\n", 
                            USB_ID_VENDOR(chip->usb_id),
                            USB_ID_PRODUCT(chip->usb_id));
index 754e689..00ebc0c 100644 (file)
@@ -1268,6 +1268,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
                        return SNDRV_PCM_FMTBIT_DSD_U32_BE;
                break;
 
+       case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */
        case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
        case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
                if (fp->altsetting == 3)
index 91d0380..33a1764 100644 (file)
@@ -37,11 +37,11 @@ struct snd_usb_audio {
        struct usb_interface *pm_intf;
        u32 usb_id;
        struct mutex mutex;
-       struct rw_semaphore shutdown_rwsem;
-       unsigned int shutdown:1;
-       unsigned int probing:1;
-       unsigned int in_pm:1;
        unsigned int autosuspended:1;   
+       atomic_t active;
+       atomic_t shutdown;
+       atomic_t usage_count;
+       wait_queue_head_t shutdown_wait;
        unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
        
        int num_interfaces;
@@ -115,4 +115,7 @@ struct snd_usb_audio_quirk {
 #define combine_triple(s)  (combine_word(s) | ((unsigned int)(s)[2] << 16))
 #define combine_quad(s)    (combine_triple(s) | ((unsigned int)(s)[3] << 24))
 
+int snd_usb_lock_shutdown(struct snd_usb_audio *chip);
+void snd_usb_unlock_shutdown(struct snd_usb_audio *chip);
+
 #endif /* __USBAUDIO_H */