ALSA: hda - Move codec create to hda_controller
authorDylan Reid <dgreid@chromium.org>
Fri, 28 Feb 2014 23:41:30 +0000 (15:41 -0800)
committerTakashi Iwai <tiwai@suse.de>
Sat, 1 Mar 2014 10:23:33 +0000 (11:23 +0100)
Codec creation and stream initialization can be shared between
hda_intel and hda platform drivers.  Move it and the static functions
it depends on to hda_controller.c.

Signed-off-by: Dylan Reid <dgreid@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_intel.c

index 43b99b495347784c4e0b7ac86625dcd70ad415c3..6156d0a2c0f922be8f2c1fd454ff626321dd27a2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -1022,7 +1023,6 @@ int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
        pcm->dev = &codec->dev;
        return 0;
 }
-EXPORT_SYMBOL_GPL(azx_attach_pcm_stream);
 
 /*
  * CORB / RIRB interface
@@ -1380,7 +1380,7 @@ static unsigned int azx_single_get_response(struct hda_bus *bus,
  */
 
 /* send a command */
-int azx_send_cmd(struct hda_bus *bus, unsigned int val)
+static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
 {
        struct azx *chip = bus->private_data;
 
@@ -1395,7 +1395,7 @@ int azx_send_cmd(struct hda_bus *bus, unsigned int val)
 EXPORT_SYMBOL_GPL(azx_send_cmd);
 
 /* get a response */
-unsigned int azx_get_response(struct hda_bus *bus,
+static unsigned int azx_get_response(struct hda_bus *bus,
                                     unsigned int addr)
 {
        struct azx *chip = bus->private_data;
@@ -1420,9 +1420,9 @@ azx_get_dsp_loader_dev(struct azx *chip)
        return &chip->azx_dev[chip->playback_index_offset];
 }
 
-int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
-                        unsigned int byte_size,
-                        struct snd_dma_buffer *bufp)
+static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
+                               unsigned int byte_size,
+                               struct snd_dma_buffer *bufp)
 {
        u32 *bdl;
        struct azx *chip = bus->private_data;
@@ -1480,9 +1480,8 @@ int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
        dsp_unlock(azx_dev);
        return err;
 }
-EXPORT_SYMBOL_GPL(azx_load_dsp_prepare);
 
-void azx_load_dsp_trigger(struct hda_bus *bus, bool start)
+static void azx_load_dsp_trigger(struct hda_bus *bus, bool start)
 {
        struct azx *chip = bus->private_data;
        struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
@@ -1493,10 +1492,9 @@ void azx_load_dsp_trigger(struct hda_bus *bus, bool start)
                azx_stream_stop(chip, azx_dev);
        azx_dev->running = start;
 }
-EXPORT_SYMBOL_GPL(azx_load_dsp_trigger);
 
-void azx_load_dsp_cleanup(struct hda_bus *bus,
-                         struct snd_dma_buffer *dmab)
+static void azx_load_dsp_cleanup(struct hda_bus *bus,
+                                struct snd_dma_buffer *dmab)
 {
        struct azx *chip = bus->private_data;
        struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
@@ -1523,7 +1521,6 @@ void azx_load_dsp_cleanup(struct hda_bus *bus,
        spin_unlock_irq(&chip->reg_lock);
        dsp_unlock(azx_dev);
 }
-EXPORT_SYMBOL_GPL(azx_load_dsp_cleanup);
 #endif /* CONFIG_SND_HDA_DSP_LOADER */
 
 int azx_alloc_stream_pages(struct azx *chip)
@@ -1746,6 +1743,7 @@ void azx_stop_chip(struct azx *chip)
 
        chip->initialized = 0;
 }
+EXPORT_SYMBOL_GPL(azx_stop_chip);
 
 /*
  * interrupt handler
@@ -1812,5 +1810,222 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
 }
 EXPORT_SYMBOL_GPL(azx_interrupt);
 
+/*
+ * Codec initerface
+ */
+
+/*
+ * Probe the given codec address
+ */
+static int probe_codec(struct azx *chip, int addr)
+{
+       unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
+               (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
+       unsigned int res;
+
+       mutex_lock(&chip->bus->cmd_mutex);
+       chip->probing = 1;
+       azx_send_cmd(chip->bus, cmd);
+       res = azx_get_response(chip->bus, addr);
+       chip->probing = 0;
+       mutex_unlock(&chip->bus->cmd_mutex);
+       if (res == -1)
+               return -EIO;
+       dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr);
+       return 0;
+}
+
+static void azx_bus_reset(struct hda_bus *bus)
+{
+       struct azx *chip = bus->private_data;
+
+       bus->in_reset = 1;
+       azx_stop_chip(chip);
+       azx_init_chip(chip, 1);
+#ifdef CONFIG_PM
+       if (chip->initialized) {
+               struct azx_pcm *p;
+               list_for_each_entry(p, &chip->pcm_list, list)
+                       snd_pcm_suspend_all(p->pcm);
+               snd_hda_suspend(chip->bus);
+               snd_hda_resume(chip->bus);
+       }
+#endif
+       bus->in_reset = 0;
+}
+
+#ifdef CONFIG_PM
+/* power-up/down the controller */
+static void azx_power_notify(struct hda_bus *bus, bool power_up)
+{
+       struct azx *chip = bus->private_data;
+
+       if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+               return;
+
+       if (power_up)
+               pm_runtime_get_sync(chip->card->dev);
+       else
+               pm_runtime_put_sync(chip->card->dev);
+}
+#endif
+
+static int get_jackpoll_interval(struct azx *chip)
+{
+       int i;
+       unsigned int j;
+
+       if (!chip->jackpoll_ms)
+               return 0;
+
+       i = chip->jackpoll_ms[chip->dev_index];
+       if (i == 0)
+               return 0;
+       if (i < 50 || i > 60000)
+               j = 0;
+       else
+               j = msecs_to_jiffies(i);
+       if (j == 0)
+               dev_warn(chip->card->dev,
+                        "jackpoll_ms value out of range: %d\n", i);
+       return j;
+}
+
+/* Codec initialization */
+int azx_codec_create(struct azx *chip, const char *model,
+                    unsigned int max_slots,
+                    int *power_save_to)
+{
+       struct hda_bus_template bus_temp;
+       int c, codecs, err;
+
+       memset(&bus_temp, 0, sizeof(bus_temp));
+       bus_temp.private_data = chip;
+       bus_temp.modelname = model;
+       bus_temp.pci = chip->pci;
+       bus_temp.ops.command = azx_send_cmd;
+       bus_temp.ops.get_response = azx_get_response;
+       bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
+       bus_temp.ops.bus_reset = azx_bus_reset;
+#ifdef CONFIG_PM
+       bus_temp.power_save = power_save_to;
+       bus_temp.ops.pm_notify = azx_power_notify;
+#endif
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+       bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare;
+       bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger;
+       bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup;
+#endif
+
+       err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
+       if (err < 0)
+               return err;
+
+       if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
+               dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
+               chip->bus->needs_damn_long_delay = 1;
+       }
+
+       codecs = 0;
+       if (!max_slots)
+               max_slots = AZX_DEFAULT_CODECS;
+
+       /* First try to probe all given codec slots */
+       for (c = 0; c < max_slots; c++) {
+               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
+                       if (probe_codec(chip, c) < 0) {
+                               /* Some BIOSen give you wrong codec addresses
+                                * that don't exist
+                                */
+                               dev_warn(chip->card->dev,
+                                        "Codec #%d probe error; disabling it...\n", c);
+                               chip->codec_mask &= ~(1 << c);
+                               /* More badly, accessing to a non-existing
+                                * codec often screws up the controller chip,
+                                * and disturbs the further communications.
+                                * Thus if an error occurs during probing,
+                                * better to reset the controller chip to
+                                * get back to the sanity state.
+                                */
+                               azx_stop_chip(chip);
+                               azx_init_chip(chip, 1);
+                       }
+               }
+       }
+
+       /* AMD chipsets often cause the communication stalls upon certain
+        * sequence like the pin-detection.  It seems that forcing the synced
+        * access works around the stall.  Grrr...
+        */
+       if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
+               dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n");
+               chip->bus->sync_write = 1;
+               chip->bus->allow_bus_reset = 1;
+       }
+
+       /* Then create codec instances */
+       for (c = 0; c < max_slots; c++) {
+               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
+                       struct hda_codec *codec;
+                       err = snd_hda_codec_new(chip->bus, c, &codec);
+                       if (err < 0)
+                               continue;
+                       codec->jackpoll_interval = get_jackpoll_interval(chip);
+                       codec->beep_mode = chip->beep_mode;
+                       codecs++;
+               }
+       }
+       if (!codecs) {
+               dev_err(chip->card->dev, "no codecs initialized\n");
+               return -ENXIO;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(azx_codec_create);
+
+/* configure each codec instance */
+int azx_codec_configure(struct azx *chip)
+{
+       struct hda_codec *codec;
+       list_for_each_entry(codec, &chip->bus->codec_list, list) {
+               snd_hda_codec_configure(codec);
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(azx_codec_configure);
+
+/* mixer creation - all stuff is implemented in hda module */
+int azx_mixer_create(struct azx *chip)
+{
+       return snd_hda_build_controls(chip->bus);
+}
+EXPORT_SYMBOL_GPL(azx_mixer_create);
+
+
+/* initialize SD streams */
+int azx_init_stream(struct azx *chip)
+{
+       int i;
+
+       /* initialize each stream (aka device)
+        * assign the starting bdl address to each stream (device)
+        * and initialize
+        */
+       for (i = 0; i < chip->num_streams; i++) {
+               struct azx_dev *azx_dev = &chip->azx_dev[i];
+               azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8);
+               /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
+               azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
+               /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
+               azx_dev->sd_int_sta_mask = 1 << i;
+               /* stream tag: must be non-zero and unique */
+               azx_dev->index = i;
+               azx_dev->stream_tag = i + 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(azx_init_stream);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Common HDA driver funcitons");
index fac929948f1954c463b9151d54eab04b2ab0549d..1d2e3be2bae6c32149f8ac256d1086b73e036af2 100644 (file)
@@ -21,8 +21,6 @@
 #include "hda_priv.h"
 
 /* PCM setup */
-int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
-                         struct hda_pcm *cpcm);
 static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
 {
        return substream->runtime->private_data;
@@ -34,30 +32,22 @@ unsigned int azx_get_position(struct azx *chip,
 /* Stream control. */
 void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev);
 
-#ifdef CONFIG_SND_HDA_DSP_LOADER
-int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
-                        unsigned int byte_size,
-                        struct snd_dma_buffer *bufp);
-void azx_load_dsp_trigger(struct hda_bus *bus, bool start);
-void azx_load_dsp_cleanup(struct hda_bus *bus,
-                         struct snd_dma_buffer *dmab);
-#endif
-
 /* Allocation functions. */
 int azx_alloc_stream_pages(struct azx *chip);
 void azx_free_stream_pages(struct azx *chip);
 
-/*
- * CORB / RIRB interface
- */
-int azx_send_cmd(struct hda_bus *bus, unsigned int val);
-unsigned int azx_get_response(struct hda_bus *bus,
-                             unsigned int addr);
-
 /* Low level azx interface */
 void azx_init_chip(struct azx *chip, int full_reset);
 void azx_stop_chip(struct azx *chip);
 void azx_enter_link_reset(struct azx *chip);
 irqreturn_t azx_interrupt(int irq, void *dev_id);
 
+/* Codec interface */
+int azx_codec_create(struct azx *chip, const char *model,
+                    unsigned int max_slots,
+                    int *power_save_to);
+int azx_codec_configure(struct azx *chip);
+int azx_mixer_create(struct azx *chip);
+int azx_init_stream(struct azx *chip);
+
 #endif /* __SOUND_HDA_CONTROLLER_H */
index 96c22a3a2dc0e37ad87c0edc694ed3f738deb5d3..b26eff3edfc1174e8c123a0a0f539ecbac9e73d7 100644 (file)
@@ -336,10 +336,6 @@ static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
 
 static int azx_acquire_irq(struct azx *chip, int do_disconnect);
 
-#ifdef CONFIG_PM
-static void azx_power_notify(struct hda_bus *bus, bool power_up);
-#endif
-
 /*
  * initialize the PCI registers
  */
@@ -432,171 +428,6 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
        return 0;
 }
 
-/*
- * Probe the given codec address
- */
-static int probe_codec(struct azx *chip, int addr)
-{
-       unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
-               (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
-       unsigned int res;
-
-       mutex_lock(&chip->bus->cmd_mutex);
-       chip->probing = 1;
-       azx_send_cmd(chip->bus, cmd);
-       res = azx_get_response(chip->bus, addr);
-       chip->probing = 0;
-       mutex_unlock(&chip->bus->cmd_mutex);
-       if (res == -1)
-               return -EIO;
-       dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr);
-       return 0;
-}
-
-static void azx_bus_reset(struct hda_bus *bus)
-{
-       struct azx *chip = bus->private_data;
-
-       bus->in_reset = 1;
-       azx_stop_chip(chip);
-       azx_init_chip(chip, 1);
-#ifdef CONFIG_PM
-       if (chip->initialized) {
-               struct azx_pcm *p;
-               list_for_each_entry(p, &chip->pcm_list, list)
-                       snd_pcm_suspend_all(p->pcm);
-               snd_hda_suspend(chip->bus);
-               snd_hda_resume(chip->bus);
-       }
-#endif
-       bus->in_reset = 0;
-}
-
-static int get_jackpoll_interval(struct azx *chip)
-{
-       int i;
-       unsigned int j;
-
-       if (!chip->jackpoll_ms)
-               return 0;
-
-       i = chip->jackpoll_ms[chip->dev_index];
-       if (i == 0)
-               return 0;
-       if (i < 50 || i > 60000)
-               j = 0;
-       else
-               j = msecs_to_jiffies(i);
-       if (j == 0)
-               dev_warn(chip->card->dev,
-                        "jackpoll_ms value out of range: %d\n", i);
-       return j;
-}
-
-/*
- * Codec initialization
- */
-
-static int azx_codec_create(struct azx *chip, const char *model,
-                           unsigned int max_slots,
-                           int *power_save_to)
-{
-       struct hda_bus_template bus_temp;
-       int c, codecs, err;
-
-       memset(&bus_temp, 0, sizeof(bus_temp));
-       bus_temp.private_data = chip;
-       bus_temp.modelname = model;
-       bus_temp.pci = chip->pci;
-       bus_temp.ops.command = azx_send_cmd;
-       bus_temp.ops.get_response = azx_get_response;
-       bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
-       bus_temp.ops.bus_reset = azx_bus_reset;
-#ifdef CONFIG_PM
-       bus_temp.power_save = power_save_to;
-       bus_temp.ops.pm_notify = azx_power_notify;
-#endif
-#ifdef CONFIG_SND_HDA_DSP_LOADER
-       bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare;
-       bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger;
-       bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup;
-#endif
-
-       err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
-       if (err < 0)
-               return err;
-
-       if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
-               dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
-               chip->bus->needs_damn_long_delay = 1;
-       }
-
-       codecs = 0;
-       if (!max_slots)
-               max_slots = AZX_DEFAULT_CODECS;
-
-       /* First try to probe all given codec slots */
-       for (c = 0; c < max_slots; c++) {
-               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
-                       if (probe_codec(chip, c) < 0) {
-                               /* Some BIOSen give you wrong codec addresses
-                                * that don't exist
-                                */
-                               dev_warn(chip->card->dev,
-                                        "Codec #%d probe error; disabling it...\n", c);
-                               chip->codec_mask &= ~(1 << c);
-                               /* More badly, accessing to a non-existing
-                                * codec often screws up the controller chip,
-                                * and disturbs the further communications.
-                                * Thus if an error occurs during probing,
-                                * better to reset the controller chip to
-                                * get back to the sanity state.
-                                */
-                               azx_stop_chip(chip);
-                               azx_init_chip(chip, 1);
-                       }
-               }
-       }
-
-       /* AMD chipsets often cause the communication stalls upon certain
-        * sequence like the pin-detection.  It seems that forcing the synced
-        * access works around the stall.  Grrr...
-        */
-       if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
-               dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n");
-               chip->bus->sync_write = 1;
-               chip->bus->allow_bus_reset = 1;
-       }
-
-       /* Then create codec instances */
-       for (c = 0; c < max_slots; c++) {
-               if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
-                       struct hda_codec *codec;
-                       err = snd_hda_codec_new(chip->bus, c, &codec);
-                       if (err < 0)
-                               continue;
-                       codec->jackpoll_interval = get_jackpoll_interval(chip);
-                       codec->beep_mode = chip->beep_mode;
-                       codecs++;
-               }
-       }
-       if (!codecs) {
-               dev_err(chip->card->dev, "no codecs initialized\n");
-               return -ENXIO;
-       }
-       return 0;
-}
-
-/* configure each codec instance */
-static int azx_codec_configure(struct azx *chip)
-{
-       struct hda_codec *codec;
-       list_for_each_entry(codec, &chip->bus->codec_list, list) {
-               snd_hda_codec_configure(codec);
-       }
-       return 0;
-}
-
 /*
  * Check whether the current DMA position is acceptable for updating
  * periods.  Returns non-zero if it's OK.
@@ -681,41 +512,6 @@ static void azx_clear_irq_pending(struct azx *chip)
        spin_unlock_irq(&chip->reg_lock);
 }
 
-/*
- * mixer creation - all stuff is implemented in hda module
- */
-static int azx_mixer_create(struct azx *chip)
-{
-       return snd_hda_build_controls(chip->bus);
-}
-
-
-/*
- * initialize SD streams
- */
-static int azx_init_stream(struct azx *chip)
-{
-       int i;
-
-       /* initialize each stream (aka device)
-        * assign the starting bdl address to each stream (device)
-        * and initialize
-        */
-       for (i = 0; i < chip->num_streams; i++) {
-               struct azx_dev *azx_dev = &chip->azx_dev[i];
-               azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8);
-               /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
-               azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
-               /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
-               azx_dev->sd_int_sta_mask = 1 << i;
-               /* stream tag: must be non-zero and unique */
-               azx_dev->index = i;
-               azx_dev->stream_tag = i + 1;
-       }
-
-       return 0;
-}
-
 static int azx_acquire_irq(struct azx *chip, int do_disconnect)
 {
        if (request_irq(chip->pci->irq, azx_interrupt,
@@ -734,20 +530,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
 }
 
 #ifdef CONFIG_PM
-/* power-up/down the controller */
-static void azx_power_notify(struct hda_bus *bus, bool power_up)
-{
-       struct azx *chip = bus->private_data;
-
-       if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
-               return;
-
-       if (power_up)
-               pm_runtime_get_sync(chip->card->dev);
-       else
-               pm_runtime_put_sync(chip->card->dev);
-}
-
 static DEFINE_MUTEX(card_list_lock);
 static LIST_HEAD(card_list);