Comment 5 for bug 100114

Revision history for this message
TJ (tj) wrote :

I decided to track the interrupt/DMA enabling/disabling. I'll put my notes here in case others want to investigate.

I analysed the sequence of operations in hda_intel.c::azx_suspend(), azx_resume() and the device initialisation functions.

I noticed that azx_suspend() calls snd_hda_suspend() then azx_free_cmd_io() which does:

 /* disable ringbuffer DMAs */
 azx_writeb(chip, RIRBCTL, 0);
 azx_writeb(chip, CORBCTL, 0);
}

I then looked at the corresponding resume operations. Immediately prior to azx_resume() calling snd_hda_resume() it calls
 azx_init_chip(). It in turn does:

 /* initialize the codec command I/O */
 if (!chip->single_cmd)
  azx_init_cmd_io(chip);

Which does:

 /* enable corb dma */
 azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN);

 /* enable rirb dma and response irq */
 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);

I then looked at the Sigmatel patch. On the Sony Vaio VGN-FE41Z the chipset reports as:

  Codec: SigmaTel STAC9872AK
  Address: 0
  Vendor Id: 0x83847662
  Subsystem Id: 0x104d0c00
  Revision Id: 0x100201

which corresponds with patch_sigmatel.c struct hda_codec_preset snd_hda_preset_sigmatel[]:

  { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 },

In patch_stac9872() the following code is executed:

 switch (board_config) {
 case CXD9872RD_VAIO:
 case STAC9872AK_VAIO: // *** this is the matching config ***
 case STAC9872K_VAIO:

followed by:

 codec->patch_ops = stac9872_patch_ops;

stac9872_patch_ops is defined as:

static struct hda_codec_ops stac9872_patch_ops = {
 .build_controls = stac92xx_build_controls,
 .build_pcms = stac92xx_build_pcms,
 .init = stac92xx_init,
 .free = stac92xx_free,
#ifdef CONFIG_PM
 .resume = stac92xx_resume,
#endif
};

stac9872_patch_ops.resume points to stac92xx_resume().

stac92xx_resume() calls the same function as is used on device init, stac92xx_init() so there doesn't appear to be any difference between cold-start and resume.