Loading sound/pci/hda/hda_codec.h +22 −11 Original line number Diff line number Diff line Loading @@ -199,7 +199,9 @@ enum { #define AC_AMPCAP_OFFSET_SHIFT 0 #define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ #define AC_AMPCAP_NUM_STEPS_SHIFT 8 #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */ #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB * in 0.25dB */ #define AC_AMPCAP_STEP_SIZE_SHIFT 16 #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ #define AC_AMPCAP_MUTE_SHIFT 31 Loading Loading @@ -436,7 +438,8 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ /* link caddr -> codec */ struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; struct mutex cmd_mutex; Loading Loading @@ -582,13 +585,17 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, /* * low level functions */ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); #define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); #define snd_hda_param_read(codec, nid, param) \ snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); struct hda_verb { hda_nid_t nid; Loading @@ -596,7 +603,8 @@ struct hda_verb { u32 param; }; void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); /* unsolicited event */ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); Loading @@ -610,10 +618,13 @@ int snd_hda_build_controls(struct hda_bus *bus); * PCM */ int snd_hda_build_pcms(struct hda_bus *bus); void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format); unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, unsigned int maxbps); unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, unsigned int maxbps); int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u32 *ratesp, u64 *formatsp, unsigned int *bpsp); int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, Loading sound/pci/hda/hda_intel.c +119 −69 Original line number Diff line number Diff line /* * * hda_intel.c - Implementation of primary alsa driver code base for Intel HD Audio. * hda_intel.c - Implementation of primary alsa driver code base * for Intel HD Audio. * * Copyright(c) 2004 Intel Corporation. All rights reserved. * Loading Loading @@ -64,11 +65,13 @@ MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); module_param(model, charp, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param(position_fix, int, 0444); MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); MODULE_PARM_DESC(position_fix, "Fix DMA pointer " "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); module_param(probe_mask, int, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only)."); module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); Loading Loading @@ -213,7 +216,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */ #define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */ #define SD_INT_COMPLETE 0x04 /* completion interrupt */ #define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|SD_INT_COMPLETE) #define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\ SD_INT_COMPLETE) /* SD_STS */ #define SD_STS_FIFO_READY 0x20 /* FIFO ready */ Loading Loading @@ -271,8 +275,12 @@ struct azx_dev { u32 sd_int_sta_mask; /* stream int status mask */ /* pcm support */ struct snd_pcm_substream *substream; /* assigned substream, set in PCM open */ unsigned int format_val; /* format value to be set in the controller and the codec */ struct snd_pcm_substream *substream; /* assigned substream, * set in PCM open */ unsigned int format_val; /* format value to be set in the * controller and the codec */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ /* for sanity check of position buffer */ Loading Loading @@ -418,7 +426,8 @@ static int azx_alloc_cmd_io(struct azx *chip) int err; /* single page (at least 4096 bytes) must suffice for both ringbuffes */ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->rb); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); Loading Loading @@ -585,16 +594,19 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val) while (timeout--) { /* check ICB busy bit */ if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { /* Clear IRV valid bit */ azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID); azx_writel(chip, IC, val); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY); return 0; } udelay(1); } snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val); snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val); return -EIO; } Loading @@ -610,7 +622,8 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) return azx_readl(chip, IR); udelay(1); } snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS)); snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS)); return (unsigned int)-1; } Loading Loading @@ -785,7 +798,8 @@ static void azx_init_chip(struct azx *chip) /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio codecs * Ensuring these bits are 0 clears playback static on some HD Audio * codecs */ pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, ®); pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8); Loading @@ -808,10 +822,13 @@ static void azx_init_chip(struct azx *chip) switch (chip->driver_type) { case AZX_DRIVER_ATI: /* For ATI SB450 azalia HD audio, we need to enable snoop */ pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, ®); pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); break; case AZX_DRIVER_NVIDIA: /* For NVIDIA HDA, enable snoop */ Loading Loading @@ -911,9 +928,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) int timeout; /* make sure the run bit is zero for SD */ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START); azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START); /* reset stream */ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET); azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET); udelay(3); timeout = 300; while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && Loading Loading @@ -952,10 +971,12 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) /* enable the position buffer */ if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr |ICH6_DPLBASE_ENABLE); /* set the interrupt enable bits in the descriptor control register */ azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); return 0; } Loading Loading @@ -987,7 +1008,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) bus_temp.ops.command = azx_send_cmd; bus_temp.ops.get_response = azx_get_response; if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); if (err < 0) return err; codecs = audio_codecs = 0; Loading Loading @@ -1052,7 +1074,8 @@ static inline void azx_release_device(struct azx_dev *azx_dev) } static struct snd_pcm_hardware azx_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | /* No full-resume yet implemented */ Loading Loading @@ -1105,7 +1128,8 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) 128); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) { azx_release_device(azx_dev); mutex_unlock(&chip->open_mutex); return err; Loading Loading @@ -1139,9 +1163,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) return 0; } static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } static int azx_pcm_hw_free(struct snd_pcm_substream *substream) Loading Loading @@ -1176,12 +1202,14 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) runtime->format, hinfo->maxbps); if (!azx_dev->format_val) { snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n", snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n", runtime->rate, runtime->channels, runtime->format); return -EINVAL; } snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, format=0x%x\n", snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, " "format=0x%x\n", azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val); azx_setup_periods(azx_dev); azx_setup_controller(chip, azx_dev); Loading Loading @@ -1223,7 +1251,8 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) cmd == SNDRV_PCM_TRIGGER_SUSPEND || cmd == SNDRV_PCM_TRIGGER_STOP) { int timeout = 5000; while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) while ((azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START) && --timeout) ; } return err; Loading Loading @@ -1292,7 +1321,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, snd_assert(cpcm->name, return -EINVAL); err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, cpcm->stream[0].substreams, cpcm->stream[1].substreams, cpcm->stream[0].substreams, cpcm->stream[1].substreams, &pcm); if (err < 0) return err; Loading Loading @@ -1327,7 +1357,8 @@ static int __devinit azx_pcm_create(struct azx *chip) int c, err; int pcm_dev; if ((err = snd_hda_build_pcms(chip->bus)) < 0) err = snd_hda_build_pcms(chip->bus); if (err < 0) return err; /* create audio PCMs */ Loading @@ -1338,10 +1369,12 @@ static int __devinit azx_pcm_create(struct azx *chip) if (codec->pcm_info[c].is_modem) continue; /* create later */ if (pcm_dev >= AZX_MAX_AUDIO_PCMS) { snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); return -EINVAL; } err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); if (err < 0) return err; pcm_dev++; Loading @@ -1356,10 +1389,12 @@ static int __devinit azx_pcm_create(struct azx *chip) if (!codec->pcm_info[c].is_modem) continue; /* already created */ if (pcm_dev >= AZX_MAX_PCMS) { snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); return -EINVAL; } err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); if (err < 0) return err; chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM; Loading @@ -1386,7 +1421,8 @@ static int __devinit azx_init_stream(struct azx *chip) int i; /* initialize each stream (aka device) * assign the starting bdl address to each stream (device) and initialize * assign the starting bdl address to each stream (device) * and initialize */ for (i = 0; i < chip->num_streams; i++) { unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); Loading Loading @@ -1650,28 +1686,35 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, break; } chip->num_streams = chip->playback_streams + chip->capture_streams; chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); if (!chip->azx_dev) { snd_printk(KERN_ERR "cannot malloc azx_dev\n"); goto errout; } /* allocate memory for the BDL for each stream */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), BDL_SIZE, &chip->bdl)) < 0) { err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), BDL_SIZE, &chip->bdl); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); goto errout; } /* allocate memory for the position buffer */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), chip->num_streams * 8, &chip->posbuf)) < 0) { err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), chip->num_streams * 8, &chip->posbuf); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); goto errout; } /* allocate CORB/RIRB */ if (! chip->single_cmd) if ((err = azx_alloc_cmd_io(chip)) < 0) if (!chip->single_cmd) { err = azx_alloc_cmd_io(chip); if (err < 0) goto errout; } /* initialize streams */ azx_init_stream(chip); Loading @@ -1688,14 +1731,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, goto errout; } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) <0) { err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err <0) { snd_printk(KERN_ERR SFX "Error creating device [card]!\n"); goto errout; } strcpy(card->driver, "HDA-Intel"); strcpy(card->shortname, driver_short_names[chip->driver_type]); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); *rchip = chip; return 0; Loading @@ -1705,7 +1750,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, return err; } static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct snd_card *card; struct azx *chip; Loading @@ -1725,26 +1771,30 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * card->private_data = chip; /* create codec instances */ if ((err = azx_codec_create(chip, model)) < 0) { err = azx_codec_create(chip, model); if (err < 0) { snd_card_free(card); return err; } /* create PCM streams */ if ((err = azx_pcm_create(chip)) < 0) { err = azx_pcm_create(chip); if (err < 0) { snd_card_free(card); return err; } /* create mixer controls */ if ((err = azx_mixer_create(chip)) < 0) { err = azx_mixer_create(chip); if (err < 0) { snd_card_free(card); return err; } snd_card_set_dev(card, &pci->dev); if ((err = snd_card_register(card)) < 0) { err = snd_card_register(card); if (err < 0) { snd_card_free(card); return err; } Loading sound/pci/hda/hda_local.h +66 −33 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ /* * for mixer controls */ #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) /* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ Loading Loading @@ -64,13 +65,20 @@ #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); /* lowlevel accessor with caching; use carefully */ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); Loading @@ -86,10 +94,13 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } /* stereo switch binding multiple inputs */ #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) #define HDA_BIND_MUTE(xname,nid,indices,dir) \ HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); Loading @@ -107,8 +118,10 @@ struct hda_input_mux { struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; }; int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, unsigned int *cur_val); Loading @@ -120,13 +133,19 @@ struct hda_channel_mode { const struct hda_verb *sequence; }; int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, const struct hda_channel_mode *chmode, int num_chmodes); int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, const struct hda_channel_mode *chmode, int num_chmodes); int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int max_channels); int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int *max_channelsp); /* Loading @@ -146,20 +165,25 @@ struct hda_multi_out { int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ }; int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); /* * generic codec parser Loading @@ -181,7 +205,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); /* * power management Loading Loading @@ -232,7 +257,9 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { int line_outs; hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ hda_nid_t line_out_pins[5]; /* sorted in the order of * Front/Surr/CLFE/Side */ int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; Loading @@ -243,13 +270,19 @@ struct auto_pin_cfg { hda_nid_t dig_in_pin; }; #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, #define get_defcfg_connect(cfg) \ ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) #define get_defcfg_association(cfg) \ ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) #define get_defcfg_location(cfg) \ ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) #define get_defcfg_sequence(cfg) \ (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) \ ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, hda_nid_t *ignore_nids); /* amp values */ Loading sound/pci/hda/hda_proc.c +18 −9 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ static void print_amp_caps(struct snd_info_buffer *buffer, snd_iprintf(buffer, "N/A\n"); return; } snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, mute=%x\n", snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, " "mute=%x\n", caps & AC_AMPCAP_OFFSET, (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT, (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT, Loading @@ -76,11 +77,13 @@ static void print_amp_vals(struct snd_info_buffer *buffer, for (i = 0; i < indices; i++) { snd_iprintf(buffer, " ["); if (stereo) { val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_LEFT | dir | i); snd_iprintf(buffer, "0x%02x ", val); } val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_RIGHT | dir | i); snd_iprintf(buffer, "0x%02x]", val); } Loading Loading @@ -237,7 +240,8 @@ static void print_pin_caps(struct snd_info_buffer *buffer, } static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct hda_codec *codec = entry->private_data; char buf[32]; Loading Loading @@ -271,9 +275,11 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe return; } for (i = 0; i < nodes; i++, nid++) { unsigned int wid_caps = snd_hda_param_read(codec, nid, unsigned int wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; int conn_len = 0; hda_nid_t conn[HDA_MAX_CONNECTIONS]; Loading Loading @@ -313,7 +319,9 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_type == AC_WID_PIN) { unsigned int pinctls; print_pin_caps(buffer, codec, nid); pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls); if (pinctls & AC_PINCTL_IN_EN) snd_iprintf(buffer, " IN"); Loading @@ -333,7 +341,8 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_caps & AC_WCAP_POWER) snd_iprintf(buffer, " Power: 0x%x\n", snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0)); AC_VERB_GET_POWER_STATE, 0)); if (wid_caps & AC_WCAP_CONN_LIST) { int c, curr = -1; Loading Loading
sound/pci/hda/hda_codec.h +22 −11 Original line number Diff line number Diff line Loading @@ -199,7 +199,9 @@ enum { #define AC_AMPCAP_OFFSET_SHIFT 0 #define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ #define AC_AMPCAP_NUM_STEPS_SHIFT 8 #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */ #define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB * in 0.25dB */ #define AC_AMPCAP_STEP_SIZE_SHIFT 16 #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ #define AC_AMPCAP_MUTE_SHIFT 31 Loading Loading @@ -436,7 +438,8 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ /* link caddr -> codec */ struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; struct mutex cmd_mutex; Loading Loading @@ -582,13 +585,17 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, /* * low level functions */ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); #define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); #define snd_hda_param_read(codec, nid, param) \ snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); struct hda_verb { hda_nid_t nid; Loading @@ -596,7 +603,8 @@ struct hda_verb { u32 param; }; void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); /* unsolicited event */ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); Loading @@ -610,10 +618,13 @@ int snd_hda_build_controls(struct hda_bus *bus); * PCM */ int snd_hda_build_pcms(struct hda_bus *bus); void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format); unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, unsigned int maxbps); unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, unsigned int maxbps); int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u32 *ratesp, u64 *formatsp, unsigned int *bpsp); int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, Loading
sound/pci/hda/hda_intel.c +119 −69 Original line number Diff line number Diff line /* * * hda_intel.c - Implementation of primary alsa driver code base for Intel HD Audio. * hda_intel.c - Implementation of primary alsa driver code base * for Intel HD Audio. * * Copyright(c) 2004 Intel Corporation. All rights reserved. * Loading Loading @@ -64,11 +65,13 @@ MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); module_param(model, charp, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param(position_fix, int, 0444); MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); MODULE_PARM_DESC(position_fix, "Fix DMA pointer " "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); module_param(probe_mask, int, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only)."); module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); Loading Loading @@ -213,7 +216,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */ #define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */ #define SD_INT_COMPLETE 0x04 /* completion interrupt */ #define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|SD_INT_COMPLETE) #define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\ SD_INT_COMPLETE) /* SD_STS */ #define SD_STS_FIFO_READY 0x20 /* FIFO ready */ Loading Loading @@ -271,8 +275,12 @@ struct azx_dev { u32 sd_int_sta_mask; /* stream int status mask */ /* pcm support */ struct snd_pcm_substream *substream; /* assigned substream, set in PCM open */ unsigned int format_val; /* format value to be set in the controller and the codec */ struct snd_pcm_substream *substream; /* assigned substream, * set in PCM open */ unsigned int format_val; /* format value to be set in the * controller and the codec */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ /* for sanity check of position buffer */ Loading Loading @@ -418,7 +426,8 @@ static int azx_alloc_cmd_io(struct azx *chip) int err; /* single page (at least 4096 bytes) must suffice for both ringbuffes */ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->rb); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); Loading Loading @@ -585,16 +594,19 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val) while (timeout--) { /* check ICB busy bit */ if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { /* Clear IRV valid bit */ azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID); azx_writel(chip, IC, val); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY); azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY); return 0; } udelay(1); } snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val); snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val); return -EIO; } Loading @@ -610,7 +622,8 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) return azx_readl(chip, IR); udelay(1); } snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS)); snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS)); return (unsigned int)-1; } Loading Loading @@ -785,7 +798,8 @@ static void azx_init_chip(struct azx *chip) /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio codecs * Ensuring these bits are 0 clears playback static on some HD Audio * codecs */ pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, ®); pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8); Loading @@ -808,10 +822,13 @@ static void azx_init_chip(struct azx *chip) switch (chip->driver_type) { case AZX_DRIVER_ATI: /* For ATI SB450 azalia HD audio, we need to enable snoop */ pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, ®); pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); break; case AZX_DRIVER_NVIDIA: /* For NVIDIA HDA, enable snoop */ Loading Loading @@ -911,9 +928,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) int timeout; /* make sure the run bit is zero for SD */ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START); azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START); /* reset stream */ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET); azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET); udelay(3); timeout = 300; while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && Loading Loading @@ -952,10 +971,12 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) /* enable the position buffer */ if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr |ICH6_DPLBASE_ENABLE); /* set the interrupt enable bits in the descriptor control register */ azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); return 0; } Loading Loading @@ -987,7 +1008,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) bus_temp.ops.command = azx_send_cmd; bus_temp.ops.get_response = azx_get_response; if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); if (err < 0) return err; codecs = audio_codecs = 0; Loading Loading @@ -1052,7 +1074,8 @@ static inline void azx_release_device(struct azx_dev *azx_dev) } static struct snd_pcm_hardware azx_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | /* No full-resume yet implemented */ Loading Loading @@ -1105,7 +1128,8 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) 128); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) { azx_release_device(azx_dev); mutex_unlock(&chip->open_mutex); return err; Loading Loading @@ -1139,9 +1163,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) return 0; } static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } static int azx_pcm_hw_free(struct snd_pcm_substream *substream) Loading Loading @@ -1176,12 +1202,14 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) runtime->format, hinfo->maxbps); if (!azx_dev->format_val) { snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n", snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n", runtime->rate, runtime->channels, runtime->format); return -EINVAL; } snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, format=0x%x\n", snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, " "format=0x%x\n", azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val); azx_setup_periods(azx_dev); azx_setup_controller(chip, azx_dev); Loading Loading @@ -1223,7 +1251,8 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) cmd == SNDRV_PCM_TRIGGER_SUSPEND || cmd == SNDRV_PCM_TRIGGER_STOP) { int timeout = 5000; while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) while ((azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START) && --timeout) ; } return err; Loading Loading @@ -1292,7 +1321,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, snd_assert(cpcm->name, return -EINVAL); err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, cpcm->stream[0].substreams, cpcm->stream[1].substreams, cpcm->stream[0].substreams, cpcm->stream[1].substreams, &pcm); if (err < 0) return err; Loading Loading @@ -1327,7 +1357,8 @@ static int __devinit azx_pcm_create(struct azx *chip) int c, err; int pcm_dev; if ((err = snd_hda_build_pcms(chip->bus)) < 0) err = snd_hda_build_pcms(chip->bus); if (err < 0) return err; /* create audio PCMs */ Loading @@ -1338,10 +1369,12 @@ static int __devinit azx_pcm_create(struct azx *chip) if (codec->pcm_info[c].is_modem) continue; /* create later */ if (pcm_dev >= AZX_MAX_AUDIO_PCMS) { snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); return -EINVAL; } err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); if (err < 0) return err; pcm_dev++; Loading @@ -1356,10 +1389,12 @@ static int __devinit azx_pcm_create(struct azx *chip) if (!codec->pcm_info[c].is_modem) continue; /* already created */ if (pcm_dev >= AZX_MAX_PCMS) { snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); return -EINVAL; } err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); if (err < 0) return err; chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM; Loading @@ -1386,7 +1421,8 @@ static int __devinit azx_init_stream(struct azx *chip) int i; /* initialize each stream (aka device) * assign the starting bdl address to each stream (device) and initialize * assign the starting bdl address to each stream (device) * and initialize */ for (i = 0; i < chip->num_streams; i++) { unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); Loading Loading @@ -1650,28 +1686,35 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, break; } chip->num_streams = chip->playback_streams + chip->capture_streams; chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); if (!chip->azx_dev) { snd_printk(KERN_ERR "cannot malloc azx_dev\n"); goto errout; } /* allocate memory for the BDL for each stream */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), BDL_SIZE, &chip->bdl)) < 0) { err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), BDL_SIZE, &chip->bdl); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); goto errout; } /* allocate memory for the position buffer */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), chip->num_streams * 8, &chip->posbuf)) < 0) { err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), chip->num_streams * 8, &chip->posbuf); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); goto errout; } /* allocate CORB/RIRB */ if (! chip->single_cmd) if ((err = azx_alloc_cmd_io(chip)) < 0) if (!chip->single_cmd) { err = azx_alloc_cmd_io(chip); if (err < 0) goto errout; } /* initialize streams */ azx_init_stream(chip); Loading @@ -1688,14 +1731,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, goto errout; } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) <0) { err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err <0) { snd_printk(KERN_ERR SFX "Error creating device [card]!\n"); goto errout; } strcpy(card->driver, "HDA-Intel"); strcpy(card->shortname, driver_short_names[chip->driver_type]); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); *rchip = chip; return 0; Loading @@ -1705,7 +1750,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, return err; } static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct snd_card *card; struct azx *chip; Loading @@ -1725,26 +1771,30 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * card->private_data = chip; /* create codec instances */ if ((err = azx_codec_create(chip, model)) < 0) { err = azx_codec_create(chip, model); if (err < 0) { snd_card_free(card); return err; } /* create PCM streams */ if ((err = azx_pcm_create(chip)) < 0) { err = azx_pcm_create(chip); if (err < 0) { snd_card_free(card); return err; } /* create mixer controls */ if ((err = azx_mixer_create(chip)) < 0) { err = azx_mixer_create(chip); if (err < 0) { snd_card_free(card); return err; } snd_card_set_dev(card, &pci->dev); if ((err = snd_card_register(card)) < 0) { err = snd_card_register(card); if (err < 0) { snd_card_free(card); return err; } Loading
sound/pci/hda/hda_local.h +66 −33 Original line number Diff line number Diff line Loading @@ -26,7 +26,8 @@ /* * for mixer controls */ #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) /* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ Loading Loading @@ -64,13 +65,20 @@ #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); /* lowlevel accessor with caching; use carefully */ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); Loading @@ -86,10 +94,13 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } /* stereo switch binding multiple inputs */ #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) #define HDA_BIND_MUTE(xname,nid,indices,dir) \ HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); Loading @@ -107,8 +118,10 @@ struct hda_input_mux { struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; }; int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, unsigned int *cur_val); Loading @@ -120,13 +133,19 @@ struct hda_channel_mode { const struct hda_verb *sequence; }; int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, const struct hda_channel_mode *chmode, int num_chmodes); int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, const struct hda_channel_mode *chmode, int num_chmodes); int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int max_channels); int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, const struct hda_channel_mode *chmode, int num_chmodes, int *max_channelsp); /* Loading @@ -146,20 +165,25 @@ struct hda_multi_out { int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ }; int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); /* * generic codec parser Loading @@ -181,7 +205,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); /* * power management Loading Loading @@ -232,7 +257,9 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { int line_outs; hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ hda_nid_t line_out_pins[5]; /* sorted in the order of * Front/Surr/CLFE/Side */ int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; Loading @@ -243,13 +270,19 @@ struct auto_pin_cfg { hda_nid_t dig_in_pin; }; #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, #define get_defcfg_connect(cfg) \ ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) #define get_defcfg_association(cfg) \ ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) #define get_defcfg_location(cfg) \ ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) #define get_defcfg_sequence(cfg) \ (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) \ ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, hda_nid_t *ignore_nids); /* amp values */ Loading
sound/pci/hda/hda_proc.c +18 −9 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ static void print_amp_caps(struct snd_info_buffer *buffer, snd_iprintf(buffer, "N/A\n"); return; } snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, mute=%x\n", snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, " "mute=%x\n", caps & AC_AMPCAP_OFFSET, (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT, (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT, Loading @@ -76,11 +77,13 @@ static void print_amp_vals(struct snd_info_buffer *buffer, for (i = 0; i < indices; i++) { snd_iprintf(buffer, " ["); if (stereo) { val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_LEFT | dir | i); snd_iprintf(buffer, "0x%02x ", val); } val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_RIGHT | dir | i); snd_iprintf(buffer, "0x%02x]", val); } Loading Loading @@ -237,7 +240,8 @@ static void print_pin_caps(struct snd_info_buffer *buffer, } static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct hda_codec *codec = entry->private_data; char buf[32]; Loading Loading @@ -271,9 +275,11 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe return; } for (i = 0; i < nodes; i++, nid++) { unsigned int wid_caps = snd_hda_param_read(codec, nid, unsigned int wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; int conn_len = 0; hda_nid_t conn[HDA_MAX_CONNECTIONS]; Loading Loading @@ -313,7 +319,9 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_type == AC_WID_PIN) { unsigned int pinctls; print_pin_caps(buffer, codec, nid); pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls); if (pinctls & AC_PINCTL_IN_EN) snd_iprintf(buffer, " IN"); Loading @@ -333,7 +341,8 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_caps & AC_WCAP_POWER) snd_iprintf(buffer, " Power: 0x%x\n", snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0)); AC_VERB_GET_POWER_STATE, 0)); if (wid_caps & AC_WCAP_CONN_LIST) { int c, curr = -1; Loading