Merge branch 'for-4.2' into for-next
authorTakashi Iwai <tiwai@suse.de>
Mon, 27 Apr 2015 14:42:45 +0000 (16:42 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 27 Apr 2015 14:42:45 +0000 (16:42 +0200)
1  2 
sound/pci/emu10k1/emu10k1_main.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c

@@@ -1446,7 -1446,7 +1446,7 @@@ static struct snd_emu_chip_details emu_
         *
         */
        {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
 -       .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
 +       .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
         .id = "Audigy2",
         .emu10k2_chip = 1,
         .ca0108_chip = 1,
         .adc_1361t = 1,  /* 24 bit capture instead of 16bit */
         .ac97_chip = 1} ,
        {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
 -       .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
 +       .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]",
         .id = "Audigy2",
         .emu10k2_chip = 1,
         .ca0102_chip = 1,
@@@ -1904,8 -1904,8 +1904,8 @@@ int snd_emu10k1_create(struct snd_card 
  
        /* set the DMA transfer mask */
        emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
-       if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
-           pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
+       if (dma_set_mask(&pci->dev, emu->dma_mask) < 0 ||
+           dma_set_coherent_mask(&pci->dev, emu->dma_mask) < 0) {
                dev_err(card->dev,
                        "architecture does not support PCI busmaster DMA with mask 0x%lx\n",
                        emu->dma_mask);
@@@ -146,11 -146,11 +146,11 @@@ static int codec_exec_verb(struct hdac_
        bus->no_response_fallback = 0;
        mutex_unlock(&bus->core.cmd_mutex);
        snd_hda_power_down_pm(codec);
-       if (!codec_in_pm(codec) && res && err < 0 && bus->rirb_error) {
+       if (!codec_in_pm(codec) && res && err == -EAGAIN) {
                if (bus->response_reset) {
                        codec_dbg(codec,
                                  "resetting BUS due to fatal communication error\n");
-                       bus->ops.bus_reset(bus);
+                       snd_hda_bus_reset(bus);
                }
                goto again;
        }
@@@ -436,9 -436,8 +436,8 @@@ static unsigned int get_num_devices(str
            get_wcaps_type(wcaps) != AC_WID_PIN)
                return 0;
  
-       parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
-       if (parm == -1 && codec->bus->rirb_error)
-               parm = 0;
+       if (_snd_hdac_read_parm(&codec->core, nid, AC_PAR_DEVLIST_LEN, &parm))
+               return 0; /* error */
        return parm & AC_DEV_LIST_LEN_MASK;
  }
  
@@@ -467,10 -466,9 +466,9 @@@ int snd_hda_get_devices(struct hda_code
  
        devices = 0;
        while (devices < dev_len) {
-               parm = snd_hda_codec_read(codec, nid, 0,
-                                         AC_VERB_GET_DEVICE_LIST, devices);
-               if (parm == -1 && codec->bus->rirb_error)
-                       break;
+               if (snd_hdac_read(&codec->core, nid,
+                                 AC_VERB_GET_DEVICE_LIST, devices, &parm))
+                       break; /* error */
  
                for (i = 0; i < 8; i++) {
                        dev_list[devices] = (u8)parm;
        return devices;
  }
  
- /*
-  * destructor
-  */
- static void snd_hda_bus_free(struct hda_bus *bus)
- {
-       if (!bus)
-               return;
-       if (bus->ops.private_free)
-               bus->ops.private_free(bus);
-       snd_hdac_bus_exit(&bus->core);
-       kfree(bus);
- }
- static int snd_hda_bus_dev_free(struct snd_device *device)
- {
-       snd_hda_bus_free(device->device_data);
-       return 0;
- }
- static int snd_hda_bus_dev_disconnect(struct snd_device *device)
- {
-       struct hda_bus *bus = device->device_data;
-       bus->shutdown = 1;
-       return 0;
- }
- /* hdac_bus_ops translations */
- static int _hda_bus_command(struct hdac_bus *_bus, unsigned int cmd)
- {
-       struct hda_bus *bus = container_of(_bus, struct hda_bus, core);
-       return bus->ops.command(bus, cmd);
- }
- static int _hda_bus_get_response(struct hdac_bus *_bus, unsigned int addr,
-                                unsigned int *res)
- {
-       struct hda_bus *bus = container_of(_bus, struct hda_bus, core);
-       *res = bus->ops.get_response(bus, addr);
-       return bus->rirb_error ? -EIO : 0;
- }
- static const struct hdac_bus_ops bus_ops = {
-       .command = _hda_bus_command,
-       .get_response = _hda_bus_get_response,
- };
- /**
-  * snd_hda_bus_new - create a HDA bus
-  * @card: the card entry
-  * @busp: the pointer to store the created bus instance
-  *
-  * Returns 0 if successful, or a negative error code.
-  */
- int snd_hda_bus_new(struct snd_card *card,
-                   struct hda_bus **busp)
- {
-       struct hda_bus *bus;
-       int err;
-       static struct snd_device_ops dev_ops = {
-               .dev_disconnect = snd_hda_bus_dev_disconnect,
-               .dev_free = snd_hda_bus_dev_free,
-       };
-       if (busp)
-               *busp = NULL;
-       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
-       if (!bus)
-               return -ENOMEM;
-       err = snd_hdac_bus_init(&bus->core, card->dev, &bus_ops);
-       if (err < 0) {
-               kfree(bus);
-               return err;
-       }
-       bus->card = card;
-       mutex_init(&bus->prepare_mutex);
-       err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
-       if (err < 0) {
-               snd_hda_bus_free(bus);
-               return err;
-       }
-       if (busp)
-               *busp = bus;
-       return 0;
- }
- EXPORT_SYMBOL_GPL(snd_hda_bus_new);
  /*
   * read widget caps for each widget and store in cache
   */
@@@ -873,15 -781,14 +781,15 @@@ struct hda_pcm *snd_hda_codec_pcm_new(s
        struct hda_pcm *pcm;
        va_list args;
  
 -      va_start(args, fmt);
        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
        if (!pcm)
                return NULL;
  
        pcm->codec = codec;
        kref_init(&pcm->kref);
 +      va_start(args, fmt);
        pcm->name = kvasprintf(GFP_KERNEL, fmt, args);
 +      va_end(args);
        if (!pcm->name) {
                kfree(pcm);
                return NULL;
@@@ -2083,16 -1990,6 +1991,16 @@@ static struct snd_kcontrol_new vmaster_
        .put = vmaster_mute_mode_put,
  };
  
 +/* meta hook to call each driver's vmaster hook */
 +static void vmaster_hook(void *private_data, int enabled)
 +{
 +      struct hda_vmaster_mute_hook *hook = private_data;
 +
 +      if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
 +              enabled = hook->mute_mode;
 +      hook->hook(hook->codec, enabled);
 +}
 +
  /**
   * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
   * @codec: the HDA codec
@@@ -2111,9 -2008,9 +2019,9 @@@ int snd_hda_add_vmaster_hook(struct hda
  
        if (!hook->hook || !hook->sw_kctl)
                return 0;
 -      snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
        hook->codec = codec;
        hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
 +      snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
        if (!expose_enum_ctl)
                return 0;
        kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
@@@ -2139,7 -2036,14 +2047,7 @@@ void snd_hda_sync_vmaster_hook(struct h
         */
        if (hook->codec->bus->shutdown)
                return;
 -      switch (hook->mute_mode) {
 -      case HDA_VMUTE_FOLLOW_MASTER:
 -              snd_ctl_sync_vmaster_hook(hook->sw_kctl);
 -              break;
 -      default:
 -              hook->hook(hook->codec, hook->mute_mode);
 -              break;
 -      }
 +      snd_ctl_sync_vmaster_hook(hook->sw_kctl);
  }
  EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook);
  
@@@ -2533,7 -2437,7 +2441,7 @@@ static void set_dig_out(struct hda_code
        if (!d)
                return;
        for (; *d; d++)
 -              snd_hdac_regmap_update(&codec->core, nid,
 +              snd_hdac_regmap_update(&codec->core, *d,
                                       AC_VERB_SET_DIGI_CONVERT_1, mask, val);
  }
  
@@@ -3287,311 -3191,6 +3195,6 @@@ int snd_hda_codec_build_controls(struc
        return 0;
  }
  
- /*
-  * stream formats
-  */
- struct hda_rate_tbl {
-       unsigned int hz;
-       unsigned int alsa_bits;
-       unsigned int hda_fmt;
- };
- /* rate = base * mult / div */
- #define HDA_RATE(base, mult, div) \
-       (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
-        (((div) - 1) << AC_FMT_DIV_SHIFT))
- static struct hda_rate_tbl rate_bits[] = {
-       /* rate in Hz, ALSA rate bitmask, HDA format value */
-       /* autodetected value used in snd_hda_query_supported_pcm */
-       { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
-       { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
-       { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
-       { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
-       { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
-       { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
-       { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
-       { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
-       { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
-       { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
-       { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
- #define AC_PAR_PCM_RATE_BITS  11
-       /* up to bits 10, 384kHZ isn't supported properly */
-       /* not autodetected value */
-       { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
-       { 0 } /* terminator */
- };
- /**
-  * snd_hda_calc_stream_format - calculate format bitset
-  * @codec: HD-audio codec
-  * @rate: the sample rate
-  * @channels: the number of channels
-  * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
-  * @maxbps: the max. bps
-  * @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
-  *
-  * Calculate the format bitset from the given rate, channels and th PCM format.
-  *
-  * Return zero if invalid.
-  */
- unsigned int snd_hda_calc_stream_format(struct hda_codec *codec,
-                                       unsigned int rate,
-                                       unsigned int channels,
-                                       unsigned int format,
-                                       unsigned int maxbps,
-                                       unsigned short spdif_ctls)
- {
-       int i;
-       unsigned int val = 0;
-       for (i = 0; rate_bits[i].hz; i++)
-               if (rate_bits[i].hz == rate) {
-                       val = rate_bits[i].hda_fmt;
-                       break;
-               }
-       if (!rate_bits[i].hz) {
-               codec_dbg(codec, "invalid rate %d\n", rate);
-               return 0;
-       }
-       if (channels == 0 || channels > 8) {
-               codec_dbg(codec, "invalid channels %d\n", channels);
-               return 0;
-       }
-       val |= channels - 1;
-       switch (snd_pcm_format_width(format)) {
-       case 8:
-               val |= AC_FMT_BITS_8;
-               break;
-       case 16:
-               val |= AC_FMT_BITS_16;
-               break;
-       case 20:
-       case 24:
-       case 32:
-               if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
-                       val |= AC_FMT_BITS_32;
-               else if (maxbps >= 24)
-                       val |= AC_FMT_BITS_24;
-               else
-                       val |= AC_FMT_BITS_20;
-               break;
-       default:
-               codec_dbg(codec, "invalid format width %d\n",
-                         snd_pcm_format_width(format));
-               return 0;
-       }
-       if (spdif_ctls & AC_DIG1_NONAUDIO)
-               val |= AC_FMT_TYPE_NON_PCM;
-       return val;
- }
- EXPORT_SYMBOL_GPL(snd_hda_calc_stream_format);
- static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
- {
-       unsigned int val = 0;
-       if (nid != codec->core.afg &&
-           (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
-               val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
-       if (!val || val == -1)
-               val = snd_hda_param_read(codec, codec->core.afg, AC_PAR_PCM);
-       if (!val || val == -1)
-               return 0;
-       return val;
- }
- static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
- {
-       unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
-       if (!streams || streams == -1)
-               streams = snd_hda_param_read(codec, codec->core.afg, AC_PAR_STREAM);
-       if (!streams || streams == -1)
-               return 0;
-       return streams;
- }
- /**
-  * snd_hda_query_supported_pcm - query the supported PCM rates and formats
-  * @codec: the HDA codec
-  * @nid: NID to query
-  * @ratesp: the pointer to store the detected rate bitflags
-  * @formatsp: the pointer to store the detected formats
-  * @bpsp: the pointer to store the detected format widths
-  *
-  * Queries the supported PCM rates and formats.  The NULL @ratesp, @formatsp
-  * or @bsps argument is ignored.
-  *
-  * Returns 0 if successful, otherwise a negative error code.
-  */
- int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
-                               u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
- {
-       unsigned int i, val, wcaps;
-       wcaps = get_wcaps(codec, nid);
-       val = query_pcm_param(codec, nid);
-       if (ratesp) {
-               u32 rates = 0;
-               for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
-                       if (val & (1 << i))
-                               rates |= rate_bits[i].alsa_bits;
-               }
-               if (rates == 0) {
-                       codec_err(codec,
-                                 "rates == 0 (nid=0x%x, val=0x%x, ovrd=%i)\n",
-                                 nid, val,
-                                 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
-                       return -EIO;
-               }
-               *ratesp = rates;
-       }
-       if (formatsp || bpsp) {
-               u64 formats = 0;
-               unsigned int streams, bps;
-               streams = query_stream_param(codec, nid);
-               if (!streams)
-                       return -EIO;
-               bps = 0;
-               if (streams & AC_SUPFMT_PCM) {
-                       if (val & AC_SUPPCM_BITS_8) {
-                               formats |= SNDRV_PCM_FMTBIT_U8;
-                               bps = 8;
-                       }
-                       if (val & AC_SUPPCM_BITS_16) {
-                               formats |= SNDRV_PCM_FMTBIT_S16_LE;
-                               bps = 16;
-                       }
-                       if (wcaps & AC_WCAP_DIGITAL) {
-                               if (val & AC_SUPPCM_BITS_32)
-                                       formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
-                               if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
-                                       formats |= SNDRV_PCM_FMTBIT_S32_LE;
-                               if (val & AC_SUPPCM_BITS_24)
-                                       bps = 24;
-                               else if (val & AC_SUPPCM_BITS_20)
-                                       bps = 20;
-                       } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
-                                         AC_SUPPCM_BITS_32)) {
-                               formats |= SNDRV_PCM_FMTBIT_S32_LE;
-                               if (val & AC_SUPPCM_BITS_32)
-                                       bps = 32;
-                               else if (val & AC_SUPPCM_BITS_24)
-                                       bps = 24;
-                               else if (val & AC_SUPPCM_BITS_20)
-                                       bps = 20;
-                       }
-               }
- #if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
-               if (streams & AC_SUPFMT_FLOAT32) {
-                       formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
-                       if (!bps)
-                               bps = 32;
-               }
- #endif
-               if (streams == AC_SUPFMT_AC3) {
-                       /* should be exclusive */
-                       /* temporary hack: we have still no proper support
-                        * for the direct AC3 stream...
-                        */
-                       formats |= SNDRV_PCM_FMTBIT_U8;
-                       bps = 8;
-               }
-               if (formats == 0) {
-                       codec_err(codec,
-                                 "formats == 0 (nid=0x%x, val=0x%x, ovrd=%i, streams=0x%x)\n",
-                                 nid, val,
-                                 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
-                                 streams);
-                       return -EIO;
-               }
-               if (formatsp)
-                       *formatsp = formats;
-               if (bpsp)
-                       *bpsp = bps;
-       }
-       return 0;
- }
- EXPORT_SYMBOL_GPL(snd_hda_query_supported_pcm);
- /**
-  * snd_hda_is_supported_format - Check the validity of the format
-  * @codec: HD-audio codec
-  * @nid: NID to check
-  * @format: the HD-audio format value to check
-  *
-  * Check whether the given node supports the format value.
-  *
-  * Returns 1 if supported, 0 if not.
-  */
- int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
-                               unsigned int format)
- {
-       int i;
-       unsigned int val = 0, rate, stream;
-       val = query_pcm_param(codec, nid);
-       if (!val)
-               return 0;
-       rate = format & 0xff00;
-       for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
-               if (rate_bits[i].hda_fmt == rate) {
-                       if (val & (1 << i))
-                               break;
-                       return 0;
-               }
-       if (i >= AC_PAR_PCM_RATE_BITS)
-               return 0;
-       stream = query_stream_param(codec, nid);
-       if (!stream)
-               return 0;
-       if (stream & AC_SUPFMT_PCM) {
-               switch (format & 0xf0) {
-               case 0x00:
-                       if (!(val & AC_SUPPCM_BITS_8))
-                               return 0;
-                       break;
-               case 0x10:
-                       if (!(val & AC_SUPPCM_BITS_16))
-                               return 0;
-                       break;
-               case 0x20:
-                       if (!(val & AC_SUPPCM_BITS_20))
-                               return 0;
-                       break;
-               case 0x30:
-                       if (!(val & AC_SUPPCM_BITS_24))
-                               return 0;
-                       break;
-               case 0x40:
-                       if (!(val & AC_SUPPCM_BITS_32))
-                               return 0;
-                       break;
-               default:
-                       return 0;
-               }
-       } else {
-               /* FIXME: check for float32 and AC3? */
-       }
-       return 1;
- }
- EXPORT_SYMBOL_GPL(snd_hda_is_supported_format);
  /*
   * PCM stuff
   */
@@@ -3804,9 -3403,6 +3407,6 @@@ int snd_hda_codec_build_pcms(struct hda
        struct hda_pcm *cpcm;
        int dev, err;
  
-       if (snd_BUG_ON(!bus->ops.attach_pcm))
-               return -EINVAL;
        err = snd_hda_codec_parse_pcms(codec);
        if (err < 0) {
                snd_hda_codec_reset(codec);
                if (dev < 0)
                        continue; /* no fatal error */
                cpcm->device = dev;
-               err =  bus->ops.attach_pcm(bus, codec, cpcm);
+               err =  snd_hda_attach_pcm_stream(bus, codec, cpcm);
                if (err < 0) {
                        codec_err(codec,
                                  "cannot attach PCM stream %d for codec #%d\n",
@@@ -4494,10 -4090,10 +4094,10 @@@ int snd_hda_add_imux_item(struct hda_co
  EXPORT_SYMBOL_GPL(snd_hda_add_imux_item);
  
  /**
-  * snd_hda_bus_reset - Reset the bus
+  * snd_hda_bus_reset_codecs - Reset the bus
   * @bus: HD-audio bus
   */
- void snd_hda_bus_reset(struct hda_bus *bus)
+ void snd_hda_bus_reset_codecs(struct hda_bus *bus)
  {
        struct hda_codec *codec;
  
  #endif
        }
  }
- EXPORT_SYMBOL_GPL(snd_hda_bus_reset);
  
  /**
   * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
@@@ -297,9 -297,6 +297,9 @@@ enum 
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
         AZX_DCAPS_SNOOP_TYPE(SCH))
  
 +#define AZX_DCAPS_INTEL_BAYTRAIL \
 +      (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_I915_POWERWELL)
 +
  #define AZX_DCAPS_INTEL_BRASWELL \
        (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_I915_POWERWELL)
  
@@@ -495,7 -492,7 +495,7 @@@ static void azx_init_pci(struct azx *ch
  static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
                                   unsigned int pos)
  {
-       struct snd_pcm_substream *substream = azx_dev->substream;
+       struct snd_pcm_substream *substream = azx_dev->core.substream;
        int stream = substream->stream;
        unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
        int delay;
        else
                delay = lpib_pos - pos;
        if (delay < 0) {
-               if (delay >= azx_dev->delay_negative_threshold)
+               if (delay >= azx_dev->core.delay_negative_threshold)
                        delay = 0;
                else
-                       delay += azx_dev->bufsize;
+                       delay += azx_dev->core.bufsize;
        }
  
-       if (delay >= azx_dev->period_bytes) {
+       if (delay >= azx_dev->core.period_bytes) {
                dev_info(chip->card->dev,
                         "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
-                        delay, azx_dev->period_bytes);
+                        delay, azx_dev->core.period_bytes);
                delay = 0;
                chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
                chip->get_delay[stream] = NULL;
@@@ -554,13 -551,13 +554,13 @@@ static int azx_position_check(struct az
   */
  static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
  {
-       struct snd_pcm_substream *substream = azx_dev->substream;
+       struct snd_pcm_substream *substream = azx_dev->core.substream;
        int stream = substream->stream;
        u32 wallclk;
        unsigned int pos;
  
-       wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
-       if (wallclk < (azx_dev->period_wallclk * 2) / 3)
+       wallclk = azx_readl(chip, WALLCLK) - azx_dev->core.start_wallclk;
+       if (wallclk < (azx_dev->core.period_wallclk * 2) / 3)
                return -1;      /* bogus (too early) interrupt */
  
        if (chip->get_position[stream])
                        dev_info(chip->card->dev,
                                 "Invalid position buffer, using LPIB read method instead.\n");
                        chip->get_position[stream] = azx_get_pos_lpib;
+                       if (chip->get_position[0] == azx_get_pos_lpib &&
+                           chip->get_position[1] == azx_get_pos_lpib)
+                               azx_bus(chip)->use_posbuf = false;
                        pos = azx_get_pos_lpib(chip, azx_dev);
                        chip->get_delay[stream] = NULL;
                } else {
                }
        }
  
-       if (pos >= azx_dev->bufsize)
+       if (pos >= azx_dev->core.bufsize)
                pos = 0;
  
-       if (WARN_ONCE(!azx_dev->period_bytes,
+       if (WARN_ONCE(!azx_dev->core.period_bytes,
                      "hda-intel: zero azx_dev->period_bytes"))
                return -1; /* this shouldn't happen! */
-       if (wallclk < (azx_dev->period_wallclk * 5) / 4 &&
-           pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+       if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 &&
+           pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2)
                /* NG - it's below the first next period boundary */
                return chip->bdl_pos_adj[chip->dev_index] ? 0 : -1;
-       azx_dev->start_wallclk += wallclk;
+       azx_dev->core.start_wallclk += wallclk;
        return 1; /* OK, it's fine */
  }
  
@@@ -601,7 -601,9 +604,9 @@@ static void azx_irq_pending_work(struc
  {
        struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
        struct azx *chip = &hda->chip;
-       int i, pending, ok;
+       struct hdac_bus *bus = azx_bus(chip);
+       struct hdac_stream *s;
+       int pending, ok;
  
        if (!hda->irq_pending_warned) {
                dev_info(chip->card->dev,
  
        for (;;) {
                pending = 0;
-               spin_lock_irq(&chip->reg_lock);
-               for (i = 0; i < chip->num_streams; i++) {
-                       struct azx_dev *azx_dev = &chip->azx_dev[i];
+               spin_lock_irq(&bus->reg_lock);
+               list_for_each_entry(s, &bus->stream_list, list) {
+                       struct azx_dev *azx_dev = stream_to_azx_dev(s);
                        if (!azx_dev->irq_pending ||
-                           !azx_dev->substream ||
-                           !azx_dev->running)
+                           !s->substream ||
+                           !s->running)
                                continue;
                        ok = azx_position_ok(chip, azx_dev);
                        if (ok > 0) {
                                azx_dev->irq_pending = 0;
-                               spin_unlock(&chip->reg_lock);
-                               snd_pcm_period_elapsed(azx_dev->substream);
-                               spin_lock(&chip->reg_lock);
+                               spin_unlock(&bus->reg_lock);
+                               snd_pcm_period_elapsed(s->substream);
+                               spin_lock(&bus->reg_lock);
                        } else if (ok < 0) {
                                pending = 0;    /* too early */
                        } else
                                pending++;
                }
-               spin_unlock_irq(&chip->reg_lock);
+               spin_unlock_irq(&bus->reg_lock);
                if (!pending)
                        return;
                msleep(1);
  /* clear irq_pending flags and assure no on-going workq */
  static void azx_clear_irq_pending(struct azx *chip)
  {
-       int i;
+       struct hdac_bus *bus = azx_bus(chip);
+       struct hdac_stream *s;
  
-       spin_lock_irq(&chip->reg_lock);
-       for (i = 0; i < chip->num_streams; i++)
-               chip->azx_dev[i].irq_pending = 0;
-       spin_unlock_irq(&chip->reg_lock);
+       spin_lock_irq(&bus->reg_lock);
+       list_for_each_entry(s, &bus->stream_list, list) {
+               struct azx_dev *azx_dev = stream_to_azx_dev(s);
+               azx_dev->irq_pending = 0;
+       }
+       spin_unlock_irq(&bus->reg_lock);
  }
  
  static int azx_acquire_irq(struct azx *chip, int do_disconnect)
  {
+       struct hdac_bus *bus = azx_bus(chip);
        if (request_irq(chip->pci->irq, azx_interrupt,
                        chip->msi ? 0 : IRQF_SHARED,
                        KBUILD_MODNAME, chip)) {
                        snd_card_disconnect(chip->card);
                return -1;
        }
-       chip->irq = chip->pci->irq;
+       bus->irq = chip->pci->irq;
        pci_intx(chip->pci, !chip->msi);
        return 0;
  }
@@@ -673,8 -680,8 +683,8 @@@ static unsigned int azx_via_get_positio
        unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
        unsigned int fifo_size;
  
-       link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
-       if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+       link_pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
+       if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                /* Playback, no problem using link position */
                return link_pos;
        }
        /* For new chipset,
         * use mod to get the DMA position just like old chipset
         */
-       mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
-       mod_dma_pos %= azx_dev->period_bytes;
+       mod_dma_pos = le32_to_cpu(*azx_dev->core.posbuf);
+       mod_dma_pos %= azx_dev->core.period_bytes;
  
        /* azx_dev->fifo_size can't get FIFO size of in stream.
         * Get from base address + offset.
         */
-       fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
+       fifo_size = readw(azx_bus(chip)->remap_addr +
+                         VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
  
        if (azx_dev->insufficient) {
                /* Link position never gather than FIFO size */
        }
  
        if (link_pos <= fifo_size)
-               mini_pos = azx_dev->bufsize + link_pos - fifo_size;
+               mini_pos = azx_dev->core.bufsize + link_pos - fifo_size;
        else
                mini_pos = link_pos - fifo_size;
  
        /* Find nearest previous boudary */
-       mod_mini_pos = mini_pos % azx_dev->period_bytes;
-       mod_link_pos = link_pos % azx_dev->period_bytes;
+       mod_mini_pos = mini_pos % azx_dev->core.period_bytes;
+       mod_link_pos = link_pos % azx_dev->core.period_bytes;
        if (mod_link_pos >= fifo_size)
                bound_pos = link_pos - mod_link_pos;
        else if (mod_dma_pos >= mod_mini_pos)
                bound_pos = mini_pos - mod_mini_pos;
        else {
-               bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
-               if (bound_pos >= azx_dev->bufsize)
+               bound_pos = mini_pos - mod_mini_pos + azx_dev->core.period_bytes;
+               if (bound_pos >= azx_dev->core.bufsize)
                        bound_pos = 0;
        }
  
@@@ -755,9 -763,9 +766,9 @@@ static int param_set_xint(const char *v
        mutex_lock(&card_list_lock);
        list_for_each_entry(hda, &card_list, list) {
                chip = &hda->chip;
-               if (!chip->bus || chip->disabled)
+               if (!hda->probe_continued || chip->disabled)
                        continue;
-               snd_hda_set_power_save(chip->bus, power_save * 1000);
+               snd_hda_set_power_save(&chip->bus, power_save * 1000);
        }
        mutex_unlock(&card_list_lock);
        return 0;
@@@ -776,6 -784,7 +787,7 @@@ static int azx_suspend(struct device *d
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip;
        struct hda_intel *hda;
+       struct hdac_bus *bus;
  
        if (!card)
                return 0;
        if (chip->disabled || hda->init_failed)
                return 0;
  
+       bus = azx_bus(chip);
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        azx_clear_irq_pending(chip);
        azx_stop_chip(chip);
        azx_enter_link_reset(chip);
-       if (chip->irq >= 0) {
-               free_irq(chip->irq, chip);
-               chip->irq = -1;
+       if (bus->irq >= 0) {
+               free_irq(bus->irq, chip);
+               bus->irq = -1;
        }
  
        if (chip->msi)
@@@ -870,7 -880,6 +883,6 @@@ static int azx_runtime_resume(struct de
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip;
        struct hda_intel *hda;
-       struct hda_bus *bus;
        struct hda_codec *codec;
        int status;
  
        azx_init_pci(chip);
        azx_init_chip(chip, true);
  
-       bus = chip->bus;
-       if (status && bus) {
-               list_for_each_codec(codec, bus)
+       if (status) {
+               list_for_each_codec(codec, &chip->bus)
                        if (status & (1 << codec->addr))
                                schedule_delayed_work(&codec->jackpoll_work,
                                                      codec->jackpoll_interval);
@@@ -926,7 -934,7 +937,7 @@@ static int azx_runtime_idle(struct devi
                return 0;
  
        if (!power_save_controller || !azx_has_pm_runtime(chip) ||
-           chip->bus->core.codec_powered)
+           azx_bus(chip)->codec_powered)
                return -EBUSY;
  
        return 0;
@@@ -964,7 -972,7 +975,7 @@@ static void azx_vs_set_state(struct pci
        if (chip->disabled == disabled)
                return;
  
-       if (!chip->bus) {
+       if (!hda->probe_continued) {
                chip->disabled = disabled;
                if (!disabled) {
                        dev_info(chip->card->dev,
                         * put ourselves there */
                        pci->current_state = PCI_D3cold;
                        chip->disabled = true;
-                       if (snd_hda_lock_devices(chip->bus))
+                       if (snd_hda_lock_devices(&chip->bus))
                                dev_warn(chip->card->dev,
                                         "Cannot lock devices!\n");
                } else {
-                       snd_hda_unlock_devices(chip->bus);
+                       snd_hda_unlock_devices(&chip->bus);
                        pm_runtime_get_noresume(card->dev);
                        chip->disabled = false;
                        azx_resume(card->dev);
@@@ -1006,11 -1014,11 +1017,11 @@@ static bool azx_vs_can_switch(struct pc
        wait_for_completion(&hda->probe_wait);
        if (hda->init_failed)
                return false;
-       if (chip->disabled || !chip->bus)
+       if (chip->disabled || !hda->probe_continued)
                return true;
-       if (snd_hda_lock_devices(chip->bus))
+       if (snd_hda_lock_devices(&chip->bus))
                return false;
-       snd_hda_unlock_devices(chip->bus);
+       snd_hda_unlock_devices(&chip->bus);
        return true;
  }
  
@@@ -1043,7 -1051,7 +1054,7 @@@ static int register_vga_switcheroo(stru
         */
        err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops,
                                                    VGA_SWITCHEROO_DIS,
-                                                   chip->bus != NULL);
+                                                   hda->probe_continued);
        if (err < 0)
                return err;
        hda->vga_switcheroo_registered = 1;
@@@ -1066,7 -1074,7 +1077,7 @@@ static int azx_free(struct azx *chip
  {
        struct pci_dev *pci = chip->pci;
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
-       int i;
+       struct hdac_bus *bus = azx_bus(chip);
  
        if (azx_has_pm_runtime(chip) && chip->running)
                pm_runtime_get_noresume(&pci->dev);
        complete_all(&hda->probe_wait);
  
        if (use_vga_switcheroo(hda)) {
-               if (chip->disabled && chip->bus)
-                       snd_hda_unlock_devices(chip->bus);
+               if (chip->disabled && hda->probe_continued)
+                       snd_hda_unlock_devices(&chip->bus);
                if (hda->vga_switcheroo_registered)
                        vga_switcheroo_unregister_client(chip->pci);
        }
  
-       if (chip->initialized) {
+       if (bus->chip_init) {
                azx_clear_irq_pending(chip);
-               for (i = 0; i < chip->num_streams; i++)
-                       azx_stream_stop(chip, &chip->azx_dev[i]);
+               azx_stop_all_streams(chip);
                azx_stop_chip(chip);
        }
  
-       if (chip->irq >= 0)
-               free_irq(chip->irq, (void*)chip);
+       if (bus->irq >= 0)
+               free_irq(bus->irq, (void*)chip);
        if (chip->msi)
                pci_disable_msi(chip->pci);
-       iounmap(chip->remap_addr);
+       iounmap(bus->remap_addr);
  
        azx_free_stream_pages(chip);
+       azx_free_streams(chip);
+       snd_hdac_bus_exit(bus);
        if (chip->region_requested)
                pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
-       kfree(chip->azx_dev);
  #ifdef CONFIG_SND_HDA_PATCH_LOADER
        release_firmware(chip->fw);
  #endif
        return 0;
  }
  
+ static int azx_dev_disconnect(struct snd_device *device)
+ {
+       struct azx *chip = device->device_data;
+       chip->bus.shutdown = 1;
+       return 0;
+ }
  static int azx_dev_free(struct snd_device *device)
  {
        return azx_free(device->device_data);
@@@ -1279,9 -1297,9 +1300,9 @@@ static void check_probe_mask(struct az
        /* check forced option */
        if (chip->codec_probe_mask != -1 &&
            (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
-               chip->codec_mask = chip->codec_probe_mask & 0xff;
+               azx_bus(chip)->codec_mask = chip->codec_probe_mask & 0xff;
                dev_info(chip->card->dev, "codec_mask forced to 0x%x\n",
-                        chip->codec_mask);
+                        (int)azx_bus(chip)->codec_mask);
        }
  }
  
@@@ -1368,12 -1386,15 +1389,15 @@@ static void azx_probe_work(struct work_
  /*
   * constructor
   */
+ static const struct hdac_io_ops pci_hda_io_ops;
+ static const struct hda_controller_ops pci_hda_ops;
  static int azx_create(struct snd_card *card, struct pci_dev *pci,
                      int dev, unsigned int driver_caps,
-                     const struct hda_controller_ops *hda_ops,
                      struct azx **rchip)
  {
        static struct snd_device_ops ops = {
+               .dev_disconnect = azx_dev_disconnect,
                .dev_free = azx_dev_free,
        };
        struct hda_intel *hda;
        }
  
        chip = &hda->chip;
-       spin_lock_init(&chip->reg_lock);
        mutex_init(&chip->open_mutex);
        chip->card = card;
        chip->pci = pci;
-       chip->ops = hda_ops;
-       chip->irq = -1;
+       chip->ops = &pci_hda_ops;
        chip->driver_caps = driver_caps;
        chip->driver_type = driver_caps & 0xff;
        check_msi(chip);
        }
        chip->bdl_pos_adj = bdl_pos_adj;
  
+       err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
+       if (err < 0) {
+               kfree(hda);
+               pci_disable_device(pci);
+               return err;
+       }
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
                dev_err(card->dev, "Error creating device [card]!\n");
@@@ -1450,6 -1476,7 +1479,7 @@@ static int azx_first_init(struct azx *c
        int dev = chip->dev_index;
        struct pci_dev *pci = chip->pci;
        struct snd_card *card = chip->card;
+       struct hdac_bus *bus = azx_bus(chip);
        int err;
        unsigned short gcap;
        unsigned int dma_bits = 64;
                return err;
        chip->region_requested = 1;
  
-       chip->addr = pci_resource_start(pci, 0);
-       chip->remap_addr = pci_ioremap_bar(pci, 0);
-       if (chip->remap_addr == NULL) {
+       bus->addr = pci_resource_start(pci, 0);
+       bus->remap_addr = pci_ioremap_bar(pci, 0);
+       if (bus->remap_addr == NULL) {
                dev_err(card->dev, "ioremap error\n");
                return -ENXIO;
        }
                return -EBUSY;
  
        pci_set_master(pci);
-       synchronize_irq(chip->irq);
+       synchronize_irq(bus->irq);
  
        gcap = azx_readw(chip, GCAP);
        dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
        /* allow 64bit DMA address if supported by H/W */
        if (!(gcap & AZX_GCAP_64OK))
                dma_bits = 32;
-       if (!pci_set_dma_mask(pci, DMA_BIT_MASK(dma_bits))) {
-               pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(dma_bits));
+       if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
+               dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
        } else {
-               pci_set_dma_mask(pci, DMA_BIT_MASK(32));
-               pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
+               dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
+               dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
        }
  
        /* read number of streams from GCAP register instead of using
        chip->capture_index_offset = 0;
        chip->playback_index_offset = chip->capture_streams;
        chip->num_streams = chip->playback_streams + chip->capture_streams;
-       chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
-                               GFP_KERNEL);
-       if (!chip->azx_dev)
-               return -ENOMEM;
  
-       err = azx_alloc_stream_pages(chip);
+       /* initialize streams */
+       err = azx_init_streams(chip);
        if (err < 0)
                return err;
  
-       /* initialize streams */
-       azx_init_stream(chip);
+       err = azx_alloc_stream_pages(chip);
+       if (err < 0)
+               return err;
  
        /* initialize chip */
        azx_init_pci(chip);
        azx_init_chip(chip, (probe_only[dev] & 2) == 0);
  
        /* codec detection */
-       if (!chip->codec_mask) {
+       if (!azx_bus(chip)->codec_mask) {
                dev_err(card->dev, "no codecs found!\n");
                return -ENODEV;
        }
                sizeof(card->shortname));
        snprintf(card->longname, sizeof(card->longname),
                 "%s at 0x%lx irq %i",
-                card->shortname, chip->addr, chip->irq);
+                card->shortname, bus->addr, bus->irq);
  
        return 0;
  }
@@@ -1670,10 -1695,11 +1698,11 @@@ static u8 pci_azx_readb(u8 __iomem *add
  
  static int disable_msi_reset_irq(struct azx *chip)
  {
+       struct hdac_bus *bus = azx_bus(chip);
        int err;
  
-       free_irq(chip->irq, chip);
-       chip->irq = -1;
+       free_irq(bus->irq, chip);
+       bus->irq = -1;
        pci_disable_msi(chip->pci);
        chip->msi = 0;
        err = azx_acquire_irq(chip, 1);
  }
  
  /* DMA page allocation helpers.  */
- static int dma_alloc_pages(struct azx *chip,
+ static int dma_alloc_pages(struct hdac_bus *bus,
                           int type,
                           size_t size,
                           struct snd_dma_buffer *buf)
  {
+       struct azx *chip = bus_to_azx(bus);
        int err;
  
        err = snd_dma_alloc_pages(type,
-                                 chip->card->dev,
+                                 bus->dev,
                                  size, buf);
        if (err < 0)
                return err;
        return 0;
  }
  
- static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
+ static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
  {
+       struct azx *chip = bus_to_azx(bus);
        mark_pages_wc(chip, buf, false);
        snd_dma_free_pages(buf);
  }
@@@ -1714,9 -1743,6 +1746,6 @@@ static int substream_alloc_pages(struc
        int ret;
  
        mark_runtime_wc(chip, azx_dev, substream, false);
-       azx_dev->bufsize = 0;
-       azx_dev->period_bytes = 0;
-       azx_dev->format_val = 0;
        ret = snd_pcm_lib_malloc_pages(substream, size);
        if (ret < 0)
                return ret;
@@@ -1743,16 -1769,19 +1772,19 @@@ static void pcm_mmap_prepare(struct snd
  #endif
  }
  
- static const struct hda_controller_ops pci_hda_ops = {
+ static const struct hdac_io_ops pci_hda_io_ops = {
        .reg_writel = pci_azx_writel,
        .reg_readl = pci_azx_readl,
        .reg_writew = pci_azx_writew,
        .reg_readw = pci_azx_readw,
        .reg_writeb = pci_azx_writeb,
        .reg_readb = pci_azx_readb,
-       .disable_msi_reset_irq = disable_msi_reset_irq,
        .dma_alloc_pages = dma_alloc_pages,
        .dma_free_pages = dma_free_pages,
+ };
+ static const struct hda_controller_ops pci_hda_ops = {
+       .disable_msi_reset_irq = disable_msi_reset_irq,
        .substream_alloc_pages = substream_alloc_pages,
        .substream_free_pages = substream_free_pages,
        .pcm_mmap_prepare = pcm_mmap_prepare,
@@@ -1783,8 -1812,7 +1815,7 @@@ static int azx_probe(struct pci_dev *pc
                return err;
        }
  
-       err = azx_create(card, pci, dev, pci_id->driver_data,
-                        &pci_hda_ops, &chip);
+       err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        if (err < 0)
                goto out_free;
        card->private_data = chip;
@@@ -1850,6 -1878,7 +1881,7 @@@ static int azx_probe_continue(struct az
        int dev = chip->dev_index;
        int err;
  
+       hda->probe_continued = 1;
        /* Request power well for Haswell HDA controller and codec */
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
  #ifdef CONFIG_SND_HDA_I915
  #endif
  
        /* create codec instances */
-       err = azx_bus_create(chip, model[dev]);
-       if (err < 0)
-               goto out_free;
        err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
        if (err < 0)
                goto out_free;
  
  #ifdef CONFIG_SND_HDA_PATCH_LOADER
        if (chip->fw) {
-               err = snd_hda_load_patch(chip->bus, chip->fw->size,
+               err = snd_hda_load_patch(&chip->bus, chip->fw->size,
                                         chip->fw->data);
                if (err < 0)
                        goto out_free;
  
        chip->running = 1;
        azx_add_card_list(chip);
-       snd_hda_set_power_save(chip->bus, power_save * 1000);
+       snd_hda_set_power_save(&chip->bus, power_save * 1000);
        if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
                pm_runtime_put_noidle(&pci->dev);
  
@@@ -1995,7 -2020,7 +2023,7 @@@ static const struct pci_device_id azx_i
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* BayTrail */
        { PCI_DEVICE(0x8086, 0x0f04),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
        /* Braswell */
        { PCI_DEVICE(0x8086, 0x2284),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL },