mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: hda - Make jack-plug notification selectable ALSA: ctxfi - Add PM support sound: seq_midi_event: fix decoding of (N)RPN events ALSA: hda - Add digital-mic support to ALC262 auto model ALSA: hda - Fix check of input source type for realtek codecs ALSA: hda - Add quirk for Sony VAIO Z21MN ALSA: hda - Get back Input Source for ALC262 toshiba-s06 model ALSA: hda - Fix unsigned comparison in patch_sigmatel.c ALSA: via82xx: add option to disable 500ms delay in snd_via82xx_codec_wait sound: fix check for return value in snd_pcm_hw_refine ALSA: ctxfi - Allow unknown PCI SSIDs ASoC: Blackfin: update the bf5xx_i2s_resume parameters ASoC: Blackfin: keep better track of SPORT configuration state
This commit is contained in:
commit
c488eef815
17 changed files with 463 additions and 182 deletions
|
@ -320,7 +320,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
|
||||||
snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) {
|
snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) {
|
||||||
changed = substream->ops->ioctl(substream,
|
changed = substream->ops->ioctl(substream,
|
||||||
SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
|
SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
|
||||||
if (params < 0)
|
if (changed < 0)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,10 +504,10 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
|
||||||
if (dev->nostat && count < 12)
|
if (dev->nostat && count < 12)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
|
cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
|
||||||
bytes[0] = ev->data.control.param & 0x007f;
|
bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
|
||||||
bytes[1] = (ev->data.control.param & 0x3f80) >> 7;
|
bytes[1] = ev->data.control.param & 0x007f;
|
||||||
bytes[2] = ev->data.control.value & 0x007f;
|
bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
|
||||||
bytes[3] = (ev->data.control.value & 0x3f80) >> 7;
|
bytes[3] = ev->data.control.value & 0x007f;
|
||||||
if (cmd != dev->lastcmd && !dev->nostat) {
|
if (cmd != dev->lastcmd && !dev->nostat) {
|
||||||
if (count < 9)
|
if (count < 9)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -46,8 +46,6 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
|
||||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
|
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
|
||||||
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
|
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
|
||||||
"UAA", CTUAA),
|
"UAA", CTUAA),
|
||||||
SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE,
|
|
||||||
"Unknown", CT20K1_UNKNOWN),
|
|
||||||
{ } /* terminator */
|
{ } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,13 +65,16 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *ct_subsys_name[NUM_CTCARDS] = {
|
static const char *ct_subsys_name[NUM_CTCARDS] = {
|
||||||
|
/* 20k1 models */
|
||||||
[CTSB055X] = "SB055x",
|
[CTSB055X] = "SB055x",
|
||||||
[CTSB073X] = "SB073x",
|
[CTSB073X] = "SB073x",
|
||||||
[CTSB0760] = "SB076x",
|
|
||||||
[CTUAA] = "UAA",
|
[CTUAA] = "UAA",
|
||||||
[CT20K1_UNKNOWN] = "Unknown",
|
[CT20K1_UNKNOWN] = "Unknown",
|
||||||
|
/* 20k2 models */
|
||||||
|
[CTSB0760] = "SB076x",
|
||||||
[CTHENDRIX] = "Hendrix",
|
[CTHENDRIX] = "Hendrix",
|
||||||
[CTSB0880] = "SB0880",
|
[CTSB0880] = "SB0880",
|
||||||
|
[CT20K2_UNKNOWN] = "Unknown",
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -260,13 +261,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
|
||||||
int device = apcm->substream->pcm->device;
|
int device = apcm->substream->pcm->device;
|
||||||
unsigned int pitch;
|
unsigned int pitch;
|
||||||
|
|
||||||
if (NULL != apcm->src) {
|
|
||||||
/* Prepared pcm playback */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first release old resources */
|
/* first release old resources */
|
||||||
atc->pcm_release_resources(atc, apcm);
|
atc_pcm_release_resources(atc, apcm);
|
||||||
|
|
||||||
/* Get SRC resource */
|
/* Get SRC resource */
|
||||||
desc.multi = apcm->substream->runtime->channels;
|
desc.multi = apcm->substream->runtime->channels;
|
||||||
|
@ -660,10 +656,7 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
|
||||||
unsigned int pitch;
|
unsigned int pitch;
|
||||||
int mix_base = 0, imp_base = 0;
|
int mix_base = 0, imp_base = 0;
|
||||||
|
|
||||||
if (NULL != apcm->src) {
|
atc_pcm_release_resources(atc, apcm);
|
||||||
/* Prepared pcm capture */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get needed resources. */
|
/* Get needed resources. */
|
||||||
err = atc_pcm_capture_get_resources(atc, apcm);
|
err = atc_pcm_capture_get_resources(atc, apcm);
|
||||||
|
@ -866,7 +859,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
|
||||||
struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
|
struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
|
||||||
unsigned int rate = apcm->substream->runtime->rate;
|
unsigned int rate = apcm->substream->runtime->rate;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
int err;
|
int err = 0;
|
||||||
unsigned char iec958_con_fs;
|
unsigned char iec958_con_fs;
|
||||||
|
|
||||||
switch (rate) {
|
switch (rate) {
|
||||||
|
@ -907,8 +900,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (NULL != apcm->src)
|
atc_pcm_release_resources(atc, apcm);
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Configure SPDIFOO and PLL to passthrough mode;
|
/* Configure SPDIFOO and PLL to passthrough mode;
|
||||||
* determine pll_rate. */
|
* determine pll_rate. */
|
||||||
|
@ -1115,32 +1107,20 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ct_atc_destroy(struct ct_atc *atc)
|
static int atc_release_resources(struct ct_atc *atc)
|
||||||
{
|
{
|
||||||
struct daio_mgr *daio_mgr;
|
int i;
|
||||||
struct dao *dao;
|
struct daio_mgr *daio_mgr = NULL;
|
||||||
struct dai *dai;
|
struct dao *dao = NULL;
|
||||||
struct daio *daio;
|
struct dai *dai = NULL;
|
||||||
struct sum_mgr *sum_mgr;
|
struct daio *daio = NULL;
|
||||||
struct src_mgr *src_mgr;
|
struct sum_mgr *sum_mgr = NULL;
|
||||||
struct srcimp_mgr *srcimp_mgr;
|
struct src_mgr *src_mgr = NULL;
|
||||||
struct srcimp *srcimp;
|
struct srcimp_mgr *srcimp_mgr = NULL;
|
||||||
struct ct_mixer *mixer;
|
struct srcimp *srcimp = NULL;
|
||||||
int i = 0;
|
struct ct_mixer *mixer = NULL;
|
||||||
|
|
||||||
if (NULL == atc)
|
/* disconnect internal mixer objects */
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (atc->timer) {
|
|
||||||
ct_timer_free(atc->timer);
|
|
||||||
atc->timer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop hardware and disable all interrupts */
|
|
||||||
if (NULL != atc->hw)
|
|
||||||
((struct hw *)atc->hw)->card_stop(atc->hw);
|
|
||||||
|
|
||||||
/* Destroy internal mixer objects */
|
|
||||||
if (NULL != atc->mixer) {
|
if (NULL != atc->mixer) {
|
||||||
mixer = atc->mixer;
|
mixer = atc->mixer;
|
||||||
mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
|
mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
|
||||||
|
@ -1149,7 +1129,6 @@ static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
|
mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
|
||||||
mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
|
mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
|
||||||
mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
|
mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
|
||||||
ct_mixer_destroy(atc->mixer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != atc->daios) {
|
if (NULL != atc->daios) {
|
||||||
|
@ -1167,6 +1146,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
daio_mgr->put_daio(daio_mgr, daio);
|
daio_mgr->put_daio(daio_mgr, daio);
|
||||||
}
|
}
|
||||||
kfree(atc->daios);
|
kfree(atc->daios);
|
||||||
|
atc->daios = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != atc->pcm) {
|
if (NULL != atc->pcm) {
|
||||||
|
@ -1175,6 +1155,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
|
sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
|
||||||
|
|
||||||
kfree(atc->pcm);
|
kfree(atc->pcm);
|
||||||
|
atc->pcm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != atc->srcs) {
|
if (NULL != atc->srcs) {
|
||||||
|
@ -1183,6 +1164,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
src_mgr->put_src(src_mgr, atc->srcs[i]);
|
src_mgr->put_src(src_mgr, atc->srcs[i]);
|
||||||
|
|
||||||
kfree(atc->srcs);
|
kfree(atc->srcs);
|
||||||
|
atc->srcs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != atc->srcimps) {
|
if (NULL != atc->srcimps) {
|
||||||
|
@ -1193,8 +1175,30 @@ static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
|
srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
|
||||||
}
|
}
|
||||||
kfree(atc->srcimps);
|
kfree(atc->srcimps);
|
||||||
|
atc->srcimps = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ct_atc_destroy(struct ct_atc *atc)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (NULL == atc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (atc->timer) {
|
||||||
|
ct_timer_free(atc->timer);
|
||||||
|
atc->timer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
atc_release_resources(atc);
|
||||||
|
|
||||||
|
/* Destroy internal mixer objects */
|
||||||
|
if (NULL != atc->mixer)
|
||||||
|
ct_mixer_destroy(atc->mixer);
|
||||||
|
|
||||||
for (i = 0; i < NUM_RSCTYP; i++) {
|
for (i = 0; i < NUM_RSCTYP; i++) {
|
||||||
if ((NULL != rsc_mgr_funcs[i].destroy) &&
|
if ((NULL != rsc_mgr_funcs[i].destroy) &&
|
||||||
(NULL != atc->rsc_mgrs[i]))
|
(NULL != atc->rsc_mgrs[i]))
|
||||||
|
@ -1240,9 +1244,21 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
p = snd_pci_quirk_lookup(atc->pci, list);
|
p = snd_pci_quirk_lookup(atc->pci, list);
|
||||||
if (!p)
|
if (p) {
|
||||||
return -ENOENT;
|
if (p->value < 0) {
|
||||||
atc->model = p->value;
|
printk(KERN_ERR "ctxfi: "
|
||||||
|
"Device %04x:%04x is black-listed\n",
|
||||||
|
atc->pci->subsystem_vendor,
|
||||||
|
atc->pci->subsystem_device);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
atc->model = p->value;
|
||||||
|
} else {
|
||||||
|
if (atc->chip_type == ATC20K1)
|
||||||
|
atc->model = CT20K1_UNKNOWN;
|
||||||
|
else
|
||||||
|
atc->model = CT20K2_UNKNOWN;
|
||||||
|
}
|
||||||
atc->model_name = ct_subsys_name[atc->model];
|
atc->model_name = ct_subsys_name[atc->model];
|
||||||
snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
|
snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
|
||||||
atc->chip_name, atc->model_name,
|
atc->chip_name, atc->model_name,
|
||||||
|
@ -1310,7 +1326,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit atc_get_resources(struct ct_atc *atc)
|
static int atc_get_resources(struct ct_atc *atc)
|
||||||
{
|
{
|
||||||
struct daio_desc da_desc = {0};
|
struct daio_desc da_desc = {0};
|
||||||
struct daio_mgr *daio_mgr;
|
struct daio_mgr *daio_mgr;
|
||||||
|
@ -1407,16 +1423,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc)
|
||||||
atc->n_pcm++;
|
atc->n_pcm++;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
|
|
||||||
if (err) {
|
|
||||||
printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devinit
|
static void
|
||||||
atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
|
atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
|
||||||
struct src **srcs, struct srcimp **srcimps)
|
struct src **srcs, struct srcimp **srcimps)
|
||||||
{
|
{
|
||||||
|
@ -1455,7 +1465,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
|
||||||
src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
|
src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devinit atc_connect_resources(struct ct_atc *atc)
|
static void atc_connect_resources(struct ct_atc *atc)
|
||||||
{
|
{
|
||||||
struct dai *dai;
|
struct dai *dai;
|
||||||
struct dao *dao;
|
struct dao *dao;
|
||||||
|
@ -1501,6 +1511,84 @@ static void __devinit atc_connect_resources(struct ct_atc *atc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int atc_suspend(struct ct_atc *atc, pm_message_t state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct hw *hw = atc->hw;
|
||||||
|
|
||||||
|
snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot);
|
||||||
|
|
||||||
|
for (i = FRONT; i < NUM_PCMS; i++) {
|
||||||
|
if (!atc->pcms[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_pcm_suspend_all(atc->pcms[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
atc_release_resources(atc);
|
||||||
|
|
||||||
|
hw->suspend(hw, state);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atc_hw_resume(struct ct_atc *atc)
|
||||||
|
{
|
||||||
|
struct hw *hw = atc->hw;
|
||||||
|
struct card_conf info = {0};
|
||||||
|
|
||||||
|
/* Re-initialize card hardware. */
|
||||||
|
info.rsr = atc->rsr;
|
||||||
|
info.msr = atc->msr;
|
||||||
|
info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
|
||||||
|
return hw->resume(hw, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atc_resources_resume(struct ct_atc *atc)
|
||||||
|
{
|
||||||
|
struct ct_mixer *mixer;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
/* Get resources */
|
||||||
|
err = atc_get_resources(atc);
|
||||||
|
if (err < 0) {
|
||||||
|
atc_release_resources(atc);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build topology */
|
||||||
|
atc_connect_resources(atc);
|
||||||
|
|
||||||
|
mixer = atc->mixer;
|
||||||
|
mixer->resume(mixer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int atc_resume(struct ct_atc *atc)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
/* Do hardware resume. */
|
||||||
|
err = atc_hw_resume(atc);
|
||||||
|
if (err < 0) {
|
||||||
|
printk(KERN_ERR "ctxfi: pci_enable_device failed, "
|
||||||
|
"disabling device\n");
|
||||||
|
snd_card_disconnect(atc->card);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = atc_resources_resume(atc);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct ct_atc atc_preset __devinitdata = {
|
static struct ct_atc atc_preset __devinitdata = {
|
||||||
.map_audio_buffer = ct_map_audio_buffer,
|
.map_audio_buffer = ct_map_audio_buffer,
|
||||||
.unmap_audio_buffer = ct_unmap_audio_buffer,
|
.unmap_audio_buffer = ct_unmap_audio_buffer,
|
||||||
|
@ -1529,6 +1617,10 @@ static struct ct_atc atc_preset __devinitdata = {
|
||||||
.spdif_out_set_status = atc_spdif_out_set_status,
|
.spdif_out_set_status = atc_spdif_out_set_status,
|
||||||
.spdif_out_passthru = atc_spdif_out_passthru,
|
.spdif_out_passthru = atc_spdif_out_passthru,
|
||||||
.have_digit_io_switch = atc_have_digit_io_switch,
|
.have_digit_io_switch = atc_have_digit_io_switch,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = atc_suspend,
|
||||||
|
.resume = atc_resume,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1587,6 +1679,12 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error1;
|
goto error1;
|
||||||
|
|
||||||
|
err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
|
||||||
|
goto error1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get resources */
|
/* Get resources */
|
||||||
err = atc_get_resources(atc);
|
err = atc_get_resources(atc);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -136,6 +136,13 @@ struct ct_atc {
|
||||||
unsigned char n_pcm;
|
unsigned char n_pcm;
|
||||||
|
|
||||||
struct ct_timer *timer;
|
struct ct_timer *timer;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
int (*suspend)(struct ct_atc *atc, pm_message_t state);
|
||||||
|
int (*resume)(struct ct_atc *atc);
|
||||||
|
#define NUM_PCMS (NUM_CTALSADEVS - 1)
|
||||||
|
struct snd_pcm *pcms[NUM_PCMS];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,16 @@ enum CHIPTYP {
|
||||||
enum CTCARDS {
|
enum CTCARDS {
|
||||||
/* 20k1 models */
|
/* 20k1 models */
|
||||||
CTSB055X,
|
CTSB055X,
|
||||||
|
CT20K1_MODEL_FIRST = CTSB055X,
|
||||||
CTSB073X,
|
CTSB073X,
|
||||||
CTUAA,
|
CTUAA,
|
||||||
CT20K1_UNKNOWN,
|
CT20K1_UNKNOWN,
|
||||||
/* 20k2 models */
|
/* 20k2 models */
|
||||||
CTSB0760,
|
CTSB0760,
|
||||||
|
CT20K2_MODEL_FIRST = CTSB0760,
|
||||||
CTHENDRIX,
|
CTHENDRIX,
|
||||||
CTSB0880,
|
CTSB0880,
|
||||||
|
CT20K2_UNKNOWN,
|
||||||
NUM_CTCARDS /* This should always be the last */
|
NUM_CTCARDS /* This should always be the last */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +64,10 @@ struct hw {
|
||||||
int (*card_init)(struct hw *hw, struct card_conf *info);
|
int (*card_init)(struct hw *hw, struct card_conf *info);
|
||||||
int (*card_stop)(struct hw *hw);
|
int (*card_stop)(struct hw *hw);
|
||||||
int (*pll_init)(struct hw *hw, unsigned int rsr);
|
int (*pll_init)(struct hw *hw, unsigned int rsr);
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
int (*suspend)(struct hw *hw, pm_message_t state);
|
||||||
|
int (*resume)(struct hw *hw, struct card_conf *info);
|
||||||
|
#endif
|
||||||
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
|
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
|
||||||
int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
|
int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
|
||||||
int (*have_digit_io_switch)(struct hw *hw);
|
int (*have_digit_io_switch)(struct hw *hw);
|
||||||
|
|
|
@ -1911,9 +1911,17 @@ static int hw_card_start(struct hw *hw)
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_request_regions(pci, "XFi");
|
if (!hw->io_base) {
|
||||||
if (err < 0)
|
err = pci_request_regions(pci, "XFi");
|
||||||
goto error1;
|
if (err < 0)
|
||||||
|
goto error1;
|
||||||
|
|
||||||
|
if (hw->model == CTUAA)
|
||||||
|
hw->io_base = pci_resource_start(pci, 5);
|
||||||
|
else
|
||||||
|
hw->io_base = pci_resource_start(pci, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Switch to X-Fi mode from UAA mode if neeeded */
|
/* Switch to X-Fi mode from UAA mode if neeeded */
|
||||||
if (hw->model == CTUAA) {
|
if (hw->model == CTUAA) {
|
||||||
|
@ -1921,18 +1929,17 @@ static int hw_card_start(struct hw *hw)
|
||||||
if (err)
|
if (err)
|
||||||
goto error2;
|
goto error2;
|
||||||
|
|
||||||
hw->io_base = pci_resource_start(pci, 5);
|
|
||||||
} else {
|
|
||||||
hw->io_base = pci_resource_start(pci, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
|
if (hw->irq < 0) {
|
||||||
"ctxfi", hw);
|
err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
|
||||||
if (err < 0) {
|
"ctxfi", hw);
|
||||||
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
|
if (err < 0) {
|
||||||
goto error2;
|
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
|
||||||
|
goto error2;
|
||||||
|
}
|
||||||
|
hw->irq = pci->irq;
|
||||||
}
|
}
|
||||||
hw->irq = pci->irq;
|
|
||||||
|
|
||||||
pci_set_master(pci);
|
pci_set_master(pci);
|
||||||
|
|
||||||
|
@ -1948,6 +1955,15 @@ error1:
|
||||||
|
|
||||||
static int hw_card_stop(struct hw *hw)
|
static int hw_card_stop(struct hw *hw)
|
||||||
{
|
{
|
||||||
|
unsigned int data;
|
||||||
|
|
||||||
|
/* disable transport bus master and queueing of request */
|
||||||
|
hw_write_20kx(hw, TRNCTL, 0x00);
|
||||||
|
|
||||||
|
/* disable pll */
|
||||||
|
data = hw_read_20kx(hw, PLLCTL);
|
||||||
|
hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12))));
|
||||||
|
|
||||||
/* TODO: Disable interrupt and so on... */
|
/* TODO: Disable interrupt and so on... */
|
||||||
if (hw->irq >= 0)
|
if (hw->irq >= 0)
|
||||||
synchronize_irq(hw->irq);
|
synchronize_irq(hw->irq);
|
||||||
|
@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||||
struct trn_conf trn_info = {0};
|
struct trn_conf trn_info = {0};
|
||||||
|
|
||||||
/* Get PCI io port base address and do Hendrix switch if needed. */
|
/* Get PCI io port base address and do Hendrix switch if needed. */
|
||||||
if (!hw->io_base) {
|
err = hw_card_start(hw);
|
||||||
err = hw_card_start(hw);
|
if (err)
|
||||||
if (err)
|
return err;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PLL init */
|
/* PLL init */
|
||||||
err = hw_pll_init(hw, info->rsr);
|
err = hw_pll_init(hw, info->rsr);
|
||||||
|
@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct pci_dev *pci = hw->pci;
|
||||||
|
|
||||||
|
hw_card_stop(hw);
|
||||||
|
|
||||||
|
if (hw->model == CTUAA) {
|
||||||
|
/* Switch to UAA config space. */
|
||||||
|
pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_disable_device(pci);
|
||||||
|
pci_save_state(pci);
|
||||||
|
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hw_resume(struct hw *hw, struct card_conf *info)
|
||||||
|
{
|
||||||
|
struct pci_dev *pci = hw->pci;
|
||||||
|
|
||||||
|
pci_set_power_state(pci, PCI_D0);
|
||||||
|
pci_restore_state(pci);
|
||||||
|
|
||||||
|
/* Re-initialize card hardware. */
|
||||||
|
return hw_card_init(hw, info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32 hw_read_20kx(struct hw *hw, u32 reg)
|
static u32 hw_read_20kx(struct hw *hw, u32 reg)
|
||||||
{
|
{
|
||||||
u32 value;
|
u32 value;
|
||||||
|
@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = {
|
||||||
.is_adc_source_selected = hw_is_adc_input_selected,
|
.is_adc_source_selected = hw_is_adc_input_selected,
|
||||||
.select_adc_source = hw_adc_input_select,
|
.select_adc_source = hw_adc_input_select,
|
||||||
.have_digit_io_switch = hw_have_digit_io_switch,
|
.have_digit_io_switch = hw_have_digit_io_switch,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = hw_suspend,
|
||||||
|
.resume = hw_resume,
|
||||||
|
#endif
|
||||||
|
|
||||||
.src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
|
.src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
|
||||||
.src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
|
.src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
|
||||||
|
|
|
@ -1860,16 +1860,18 @@ static int hw_card_start(struct hw *hw)
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_request_regions(pci, "XFi");
|
if (!hw->io_base) {
|
||||||
if (err < 0)
|
err = pci_request_regions(pci, "XFi");
|
||||||
goto error1;
|
if (err < 0)
|
||||||
|
goto error1;
|
||||||
|
|
||||||
hw->io_base = pci_resource_start(hw->pci, 2);
|
hw->io_base = pci_resource_start(hw->pci, 2);
|
||||||
hw->mem_base = (unsigned long)ioremap(hw->io_base,
|
hw->mem_base = (unsigned long)ioremap(hw->io_base,
|
||||||
pci_resource_len(hw->pci, 2));
|
pci_resource_len(hw->pci, 2));
|
||||||
if (NULL == (void *)hw->mem_base) {
|
if (NULL == (void *)hw->mem_base) {
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
goto error2;
|
goto error2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to 20k2 mode from UAA mode. */
|
/* Switch to 20k2 mode from UAA mode. */
|
||||||
|
@ -1901,6 +1903,15 @@ error1:
|
||||||
|
|
||||||
static int hw_card_stop(struct hw *hw)
|
static int hw_card_stop(struct hw *hw)
|
||||||
{
|
{
|
||||||
|
unsigned int data;
|
||||||
|
|
||||||
|
/* disable transport bus master and queueing of request */
|
||||||
|
hw_write_20kx(hw, TRANSPORT_CTL, 0x00);
|
||||||
|
|
||||||
|
/* disable pll */
|
||||||
|
data = hw_read_20kx(hw, PLL_ENB);
|
||||||
|
hw_write_20kx(hw, PLL_ENB, (data & (~0x07)));
|
||||||
|
|
||||||
/* TODO: Disable interrupt and so on... */
|
/* TODO: Disable interrupt and so on... */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||||
|
|
||||||
/* Get PCI io port/memory base address and
|
/* Get PCI io port/memory base address and
|
||||||
* do 20kx core switch if needed. */
|
* do 20kx core switch if needed. */
|
||||||
if (!hw->io_base) {
|
err = hw_card_start(hw);
|
||||||
err = hw_card_start(hw);
|
if (err)
|
||||||
if (err)
|
return err;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PLL init */
|
/* PLL init */
|
||||||
err = hw_pll_init(hw, info->rsr);
|
err = hw_pll_init(hw, info->rsr);
|
||||||
|
@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct pci_dev *pci = hw->pci;
|
||||||
|
|
||||||
|
hw_card_stop(hw);
|
||||||
|
|
||||||
|
pci_disable_device(pci);
|
||||||
|
pci_save_state(pci);
|
||||||
|
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hw_resume(struct hw *hw, struct card_conf *info)
|
||||||
|
{
|
||||||
|
struct pci_dev *pci = hw->pci;
|
||||||
|
|
||||||
|
pci_set_power_state(pci, PCI_D0);
|
||||||
|
pci_restore_state(pci);
|
||||||
|
|
||||||
|
/* Re-initialize card hardware. */
|
||||||
|
return hw_card_init(hw, info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32 hw_read_20kx(struct hw *hw, u32 reg)
|
static u32 hw_read_20kx(struct hw *hw, u32 reg)
|
||||||
{
|
{
|
||||||
return readl((void *)(hw->mem_base + reg));
|
return readl((void *)(hw->mem_base + reg));
|
||||||
|
@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = {
|
||||||
.is_adc_source_selected = hw_is_adc_input_selected,
|
.is_adc_source_selected = hw_is_adc_input_selected,
|
||||||
.select_adc_source = hw_adc_input_select,
|
.select_adc_source = hw_adc_input_select,
|
||||||
.have_digit_io_switch = hw_have_digit_io_switch,
|
.have_digit_io_switch = hw_have_digit_io_switch,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = hw_suspend,
|
||||||
|
.resume = hw_resume,
|
||||||
|
#endif
|
||||||
|
|
||||||
.src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
|
.src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
|
||||||
.src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
|
.src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
|
||||||
|
|
|
@ -462,6 +462,43 @@ do_digit_io_switch(struct ct_atc *atc, int state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
|
||||||
|
{
|
||||||
|
struct ct_mixer *mixer = atc->mixer;
|
||||||
|
|
||||||
|
/* Do changes in mixer. */
|
||||||
|
if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
|
||||||
|
if (state) {
|
||||||
|
ct_mixer_recording_select(mixer,
|
||||||
|
get_amixer_index(type));
|
||||||
|
} else {
|
||||||
|
ct_mixer_recording_unselect(mixer,
|
||||||
|
get_amixer_index(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Do changes out of mixer. */
|
||||||
|
if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
|
||||||
|
do_line_mic_switch(atc, type);
|
||||||
|
else if (MIXER_WAVEF_P_S == type)
|
||||||
|
atc->line_front_unmute(atc, state);
|
||||||
|
else if (MIXER_WAVES_P_S == type)
|
||||||
|
atc->line_surround_unmute(atc, state);
|
||||||
|
else if (MIXER_WAVEC_P_S == type)
|
||||||
|
atc->line_clfe_unmute(atc, state);
|
||||||
|
else if (MIXER_WAVER_P_S == type)
|
||||||
|
atc->line_rear_unmute(atc, state);
|
||||||
|
else if (MIXER_LINEIN_P_S == type)
|
||||||
|
atc->line_in_unmute(atc, state);
|
||||||
|
else if (MIXER_SPDIFO_P_S == type)
|
||||||
|
atc->spdif_out_unmute(atc, state);
|
||||||
|
else if (MIXER_SPDIFI_P_S == type)
|
||||||
|
atc->spdif_in_unmute(atc, state);
|
||||||
|
else if (MIXER_DIGITAL_IO_S == type)
|
||||||
|
do_digit_io_switch(atc, state);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol,
|
static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_info *uinfo)
|
struct snd_ctl_elem_info *uinfo)
|
||||||
{
|
{
|
||||||
|
@ -498,35 +535,7 @@ static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
set_switch_state(mixer, type, state);
|
set_switch_state(mixer, type, state);
|
||||||
/* Do changes in mixer. */
|
do_switch(atc, type, state);
|
||||||
if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
|
|
||||||
if (state) {
|
|
||||||
ct_mixer_recording_select(mixer,
|
|
||||||
get_amixer_index(type));
|
|
||||||
} else {
|
|
||||||
ct_mixer_recording_unselect(mixer,
|
|
||||||
get_amixer_index(type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Do changes out of mixer. */
|
|
||||||
if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
|
|
||||||
do_line_mic_switch(atc, type);
|
|
||||||
else if (MIXER_WAVEF_P_S == type)
|
|
||||||
atc->line_front_unmute(atc, state);
|
|
||||||
else if (MIXER_WAVES_P_S == type)
|
|
||||||
atc->line_surround_unmute(atc, state);
|
|
||||||
else if (MIXER_WAVEC_P_S == type)
|
|
||||||
atc->line_clfe_unmute(atc, state);
|
|
||||||
else if (MIXER_WAVER_P_S == type)
|
|
||||||
atc->line_rear_unmute(atc, state);
|
|
||||||
else if (MIXER_LINEIN_P_S == type)
|
|
||||||
atc->line_in_unmute(atc, state);
|
|
||||||
else if (MIXER_SPDIFO_P_S == type)
|
|
||||||
atc->spdif_out_unmute(atc, state);
|
|
||||||
else if (MIXER_SPDIFI_P_S == type)
|
|
||||||
atc->spdif_in_unmute(atc, state);
|
|
||||||
else if (MIXER_DIGITAL_IO_S == type)
|
|
||||||
do_digit_io_switch(atc, state);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1039,6 +1048,28 @@ mixer_set_input_right(struct ct_mixer *mixer,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int mixer_resume(struct ct_mixer *mixer)
|
||||||
|
{
|
||||||
|
int i, state;
|
||||||
|
struct amixer *amixer;
|
||||||
|
|
||||||
|
/* resume topology and volume gain. */
|
||||||
|
for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) {
|
||||||
|
amixer = mixer->amixers[i];
|
||||||
|
amixer->ops->commit_write(amixer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resume switch state. */
|
||||||
|
for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) {
|
||||||
|
state = get_switch_state(mixer, i);
|
||||||
|
do_switch(mixer->atc, i, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ct_mixer_destroy(struct ct_mixer *mixer)
|
int ct_mixer_destroy(struct ct_mixer *mixer)
|
||||||
{
|
{
|
||||||
struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
|
struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
|
||||||
|
@ -1087,6 +1118,9 @@ int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
|
||||||
mixer->get_output_ports = mixer_get_output_ports;
|
mixer->get_output_ports = mixer_get_output_ports;
|
||||||
mixer->set_input_left = mixer_set_input_left;
|
mixer->set_input_left = mixer_set_input_left;
|
||||||
mixer->set_input_right = mixer_set_input_right;
|
mixer->set_input_right = mixer_set_input_right;
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
mixer->resume = mixer_resume;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Allocate chip resources for mixer obj */
|
/* Allocate chip resources for mixer obj */
|
||||||
err = ct_mixer_get_resources(mixer);
|
err = ct_mixer_get_resources(mixer);
|
||||||
|
|
|
@ -56,6 +56,9 @@ struct ct_mixer {
|
||||||
enum MIXER_PORT_T type, struct rsc *rsc);
|
enum MIXER_PORT_T type, struct rsc *rsc);
|
||||||
int (*set_input_right)(struct ct_mixer *mixer,
|
int (*set_input_right)(struct ct_mixer *mixer,
|
||||||
enum MIXER_PORT_T type, struct rsc *rsc);
|
enum MIXER_PORT_T type, struct rsc *rsc);
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
int (*resume)(struct ct_mixer *mixer);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int ct_alsa_mix_create(struct ct_atc *atc,
|
int ct_alsa_mix_create(struct ct_atc *atc,
|
||||||
|
|
|
@ -422,5 +422,9 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
|
||||||
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
|
snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
atc->pcms[device] = pcm;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,11 +121,33 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
|
||||||
pci_set_drvdata(pci, NULL);
|
pci_set_drvdata(pci, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int ct_card_suspend(struct pci_dev *pci, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct snd_card *card = pci_get_drvdata(pci);
|
||||||
|
struct ct_atc *atc = card->private_data;
|
||||||
|
|
||||||
|
return atc->suspend(atc, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ct_card_resume(struct pci_dev *pci)
|
||||||
|
{
|
||||||
|
struct snd_card *card = pci_get_drvdata(pci);
|
||||||
|
struct ct_atc *atc = card->private_data;
|
||||||
|
|
||||||
|
return atc->resume(atc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct pci_driver ct_driver = {
|
static struct pci_driver ct_driver = {
|
||||||
.name = "SB-XFi",
|
.name = "SB-XFi",
|
||||||
.id_table = ct_pci_dev_ids,
|
.id_table = ct_pci_dev_ids,
|
||||||
.probe = ct_card_probe,
|
.probe = ct_card_probe,
|
||||||
.remove = __devexit_p(ct_card_remove),
|
.remove = __devexit_p(ct_card_remove),
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = ct_card_suspend,
|
||||||
|
.resume = ct_card_resume,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ct_card_init(void)
|
static int __init ct_card_init(void)
|
||||||
|
|
|
@ -2,7 +2,6 @@ menuconfig SND_HDA_INTEL
|
||||||
tristate "Intel HD Audio"
|
tristate "Intel HD Audio"
|
||||||
select SND_PCM
|
select SND_PCM
|
||||||
select SND_VMASTER
|
select SND_VMASTER
|
||||||
select SND_JACK if INPUT=y || INPUT=SND
|
|
||||||
help
|
help
|
||||||
Say Y here to include support for Intel "High Definition
|
Say Y here to include support for Intel "High Definition
|
||||||
Audio" (Azalia) and its compatible devices.
|
Audio" (Azalia) and its compatible devices.
|
||||||
|
@ -39,6 +38,14 @@ config SND_HDA_INPUT_BEEP
|
||||||
Say Y here to build a digital beep interface for HD-audio
|
Say Y here to build a digital beep interface for HD-audio
|
||||||
driver. This interface is used to generate digital beeps.
|
driver. This interface is used to generate digital beeps.
|
||||||
|
|
||||||
|
config SND_HDA_INPUT_JACK
|
||||||
|
bool "Support jack plugging notification via input layer"
|
||||||
|
depends on INPUT=y || INPUT=SND_HDA_INTEL
|
||||||
|
select SND_JACK
|
||||||
|
help
|
||||||
|
Say Y here to enable the jack plugging notification via
|
||||||
|
input layer.
|
||||||
|
|
||||||
config SND_HDA_CODEC_REALTEK
|
config SND_HDA_CODEC_REALTEK
|
||||||
bool "Build Realtek HD-audio codec support"
|
bool "Build Realtek HD-audio codec support"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -349,7 +349,7 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
|
||||||
&spec->cur_mux[adc_idx]);
|
&spec->cur_mux[adc_idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||||
static void conexant_free_jack_priv(struct snd_jack *jack)
|
static void conexant_free_jack_priv(struct snd_jack *jack)
|
||||||
{
|
{
|
||||||
struct conexant_jack *jacks = jack->private_data;
|
struct conexant_jack *jacks = jack->private_data;
|
||||||
|
@ -463,7 +463,7 @@ static int conexant_init(struct hda_codec *codec)
|
||||||
|
|
||||||
static void conexant_free(struct hda_codec *codec)
|
static void conexant_free(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||||
struct conexant_spec *spec = codec->spec;
|
struct conexant_spec *spec = codec->spec;
|
||||||
if (spec->jacks.list) {
|
if (spec->jacks.list) {
|
||||||
struct conexant_jack *jacks = spec->jacks.list;
|
struct conexant_jack *jacks = spec->jacks.list;
|
||||||
|
|
|
@ -250,13 +250,6 @@ enum {
|
||||||
ALC883_MODEL_LAST,
|
ALC883_MODEL_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* styles of capture selection */
|
|
||||||
enum {
|
|
||||||
CAPT_MUX = 0, /* only mux based */
|
|
||||||
CAPT_MIX, /* only mixer based */
|
|
||||||
CAPT_1MUX_MIX, /* first mux and other mixers */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* for GPIO Poll */
|
/* for GPIO Poll */
|
||||||
#define GPIO_MASK 0x03
|
#define GPIO_MASK 0x03
|
||||||
|
|
||||||
|
@ -306,7 +299,6 @@ struct alc_spec {
|
||||||
hda_nid_t *adc_nids;
|
hda_nid_t *adc_nids;
|
||||||
hda_nid_t *capsrc_nids;
|
hda_nid_t *capsrc_nids;
|
||||||
hda_nid_t dig_in_nid; /* digital-in NID; optional */
|
hda_nid_t dig_in_nid; /* digital-in NID; optional */
|
||||||
int capture_style; /* capture style (CAPT_*) */
|
|
||||||
|
|
||||||
/* capture source */
|
/* capture source */
|
||||||
unsigned int num_mux_defs;
|
unsigned int num_mux_defs;
|
||||||
|
@ -420,12 +412,13 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
|
||||||
unsigned int mux_idx;
|
unsigned int mux_idx;
|
||||||
hda_nid_t nid = spec->capsrc_nids ?
|
hda_nid_t nid = spec->capsrc_nids ?
|
||||||
spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
|
spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
|
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
|
||||||
imux = &spec->input_mux[mux_idx];
|
imux = &spec->input_mux[mux_idx];
|
||||||
|
|
||||||
if (spec->capture_style &&
|
type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||||
!(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
|
if (type == AC_WID_AUD_MIX) {
|
||||||
/* Matrix-mixer style (e.g. ALC882) */
|
/* Matrix-mixer style (e.g. ALC882) */
|
||||||
unsigned int *cur_val = &spec->cur_mux[adc_idx];
|
unsigned int *cur_val = &spec->cur_mux[adc_idx];
|
||||||
unsigned int i, idx;
|
unsigned int i, idx;
|
||||||
|
@ -7557,7 +7550,6 @@ static int patch_alc882(struct hda_codec *codec)
|
||||||
spec->stream_digital_playback = &alc882_pcm_digital_playback;
|
spec->stream_digital_playback = &alc882_pcm_digital_playback;
|
||||||
spec->stream_digital_capture = &alc882_pcm_digital_capture;
|
spec->stream_digital_capture = &alc882_pcm_digital_capture;
|
||||||
|
|
||||||
spec->capture_style = CAPT_MIX; /* matrix-style capture */
|
|
||||||
if (!spec->adc_nids && spec->input_mux) {
|
if (!spec->adc_nids && spec->input_mux) {
|
||||||
/* check whether NID 0x07 is valid */
|
/* check whether NID 0x07 is valid */
|
||||||
unsigned int wcap = get_wcaps(codec, 0x07);
|
unsigned int wcap = get_wcaps(codec, 0x07);
|
||||||
|
@ -9781,7 +9773,6 @@ static int patch_alc883(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
if (!spec->capsrc_nids)
|
if (!spec->capsrc_nids)
|
||||||
spec->capsrc_nids = alc883_capsrc_nids;
|
spec->capsrc_nids = alc883_capsrc_nids;
|
||||||
spec->capture_style = CAPT_MIX; /* matrix-style capture */
|
|
||||||
spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
|
spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
|
||||||
break;
|
break;
|
||||||
case 0x10ec0889:
|
case 0x10ec0889:
|
||||||
|
@ -9791,8 +9782,6 @@ static int patch_alc883(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
if (!spec->capsrc_nids)
|
if (!spec->capsrc_nids)
|
||||||
spec->capsrc_nids = alc889_capsrc_nids;
|
spec->capsrc_nids = alc889_capsrc_nids;
|
||||||
spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
|
|
||||||
capture */
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!spec->num_adc_nids) {
|
if (!spec->num_adc_nids) {
|
||||||
|
@ -9801,7 +9790,6 @@ static int patch_alc883(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
if (!spec->capsrc_nids)
|
if (!spec->capsrc_nids)
|
||||||
spec->capsrc_nids = alc883_capsrc_nids;
|
spec->capsrc_nids = alc883_capsrc_nids;
|
||||||
spec->capture_style = CAPT_MIX; /* matrix-style capture */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10913,9 +10901,27 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* identical with ALC880 */
|
static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
|
||||||
#define alc262_auto_create_analog_input_ctls \
|
const struct auto_pin_cfg *cfg)
|
||||||
alc880_auto_create_analog_input_ctls
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = alc880_auto_create_analog_input_ctls(spec, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
/* digital-mic input pin is excluded in alc880_auto_create..()
|
||||||
|
* because it's under 0x18
|
||||||
|
*/
|
||||||
|
if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
|
||||||
|
cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
|
||||||
|
struct hda_input_mux *imux = &spec->private_imux[0];
|
||||||
|
imux->items[imux->num_items].label = "Int Mic";
|
||||||
|
imux->items[imux->num_items].index = 0x09;
|
||||||
|
imux->num_items++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generic initialization of ADC, input mixers and output mixers
|
* generic initialization of ADC, input mixers and output mixers
|
||||||
|
@ -11332,6 +11338,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
|
SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
|
||||||
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
|
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
|
SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
|
||||||
|
SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
|
||||||
SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
|
SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
|
||||||
ALC262_SONY_ASSAMD),
|
ALC262_SONY_ASSAMD),
|
||||||
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
|
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
|
||||||
|
@ -11539,6 +11546,7 @@ static struct alc_config_preset alc262_presets[] = {
|
||||||
.capsrc_nids = alc262_dmic_capsrc_nids,
|
.capsrc_nids = alc262_dmic_capsrc_nids,
|
||||||
.dac_nids = alc262_dac_nids,
|
.dac_nids = alc262_dac_nids,
|
||||||
.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
|
.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
|
||||||
|
.num_adc_nids = 1, /* single ADC */
|
||||||
.dig_out_nid = ALC262_DIGOUT_NID,
|
.dig_out_nid = ALC262_DIGOUT_NID,
|
||||||
.num_channel_mode = ARRAY_SIZE(alc262_modes),
|
.num_channel_mode = ARRAY_SIZE(alc262_modes),
|
||||||
.channel_mode = alc262_modes,
|
.channel_mode = alc262_modes,
|
||||||
|
@ -11640,21 +11648,36 @@ static int patch_alc262(struct hda_codec *codec)
|
||||||
spec->stream_digital_playback = &alc262_pcm_digital_playback;
|
spec->stream_digital_playback = &alc262_pcm_digital_playback;
|
||||||
spec->stream_digital_capture = &alc262_pcm_digital_capture;
|
spec->stream_digital_capture = &alc262_pcm_digital_capture;
|
||||||
|
|
||||||
spec->capture_style = CAPT_MIX;
|
|
||||||
if (!spec->adc_nids && spec->input_mux) {
|
if (!spec->adc_nids && spec->input_mux) {
|
||||||
/* check whether NID 0x07 is valid */
|
int i;
|
||||||
unsigned int wcap = get_wcaps(codec, 0x07);
|
/* check whether the digital-mic has to be supported */
|
||||||
|
for (i = 0; i < spec->input_mux->num_items; i++) {
|
||||||
/* get type */
|
if (spec->input_mux->items[i].index >= 9)
|
||||||
wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
break;
|
||||||
if (wcap != AC_WID_AUD_IN) {
|
}
|
||||||
spec->adc_nids = alc262_adc_nids_alt;
|
if (i < spec->input_mux->num_items) {
|
||||||
spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
|
/* use only ADC0 */
|
||||||
spec->capsrc_nids = alc262_capsrc_nids_alt;
|
spec->adc_nids = alc262_dmic_adc_nids;
|
||||||
|
spec->num_adc_nids = 1;
|
||||||
|
spec->capsrc_nids = alc262_dmic_capsrc_nids;
|
||||||
} else {
|
} else {
|
||||||
spec->adc_nids = alc262_adc_nids;
|
/* all analog inputs */
|
||||||
spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
|
/* check whether NID 0x07 is valid */
|
||||||
spec->capsrc_nids = alc262_capsrc_nids;
|
unsigned int wcap = get_wcaps(codec, 0x07);
|
||||||
|
|
||||||
|
/* get type */
|
||||||
|
wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||||
|
if (wcap != AC_WID_AUD_IN) {
|
||||||
|
spec->adc_nids = alc262_adc_nids_alt;
|
||||||
|
spec->num_adc_nids =
|
||||||
|
ARRAY_SIZE(alc262_adc_nids_alt);
|
||||||
|
spec->capsrc_nids = alc262_capsrc_nids_alt;
|
||||||
|
} else {
|
||||||
|
spec->adc_nids = alc262_adc_nids;
|
||||||
|
spec->num_adc_nids =
|
||||||
|
ARRAY_SIZE(alc262_adc_nids);
|
||||||
|
spec->capsrc_nids = alc262_capsrc_nids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!spec->cap_mixer && !spec->no_analog)
|
if (!spec->cap_mixer && !spec->no_analog)
|
||||||
|
@ -13244,26 +13267,8 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
|
#define alc269_auto_create_analog_input_ctls \
|
||||||
const struct auto_pin_cfg *cfg)
|
alc262_auto_create_analog_input_ctls
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = alc880_auto_create_analog_input_ctls(spec, cfg);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
/* digital-mic input pin is excluded in alc880_auto_create..()
|
|
||||||
* because it's under 0x18
|
|
||||||
*/
|
|
||||||
if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
|
|
||||||
cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
|
|
||||||
struct hda_input_mux *imux = &spec->private_imux[0];
|
|
||||||
imux->items[imux->num_items].label = "Int Mic";
|
|
||||||
imux->items[imux->num_items].index = 0x05;
|
|
||||||
imux->num_items++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||||
#define alc269_loopbacks alc880_loopbacks
|
#define alc269_loopbacks alc880_loopbacks
|
||||||
|
@ -15554,7 +15559,6 @@ static int patch_alc861vd(struct hda_codec *codec)
|
||||||
spec->adc_nids = alc861vd_adc_nids;
|
spec->adc_nids = alc861vd_adc_nids;
|
||||||
spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
|
spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
|
||||||
spec->capsrc_nids = alc861vd_capsrc_nids;
|
spec->capsrc_nids = alc861vd_capsrc_nids;
|
||||||
spec->capture_style = CAPT_MIX;
|
|
||||||
|
|
||||||
set_capture_mixer(spec);
|
set_capture_mixer(spec);
|
||||||
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
|
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
|
||||||
|
@ -17474,7 +17478,6 @@ static int patch_alc662(struct hda_codec *codec)
|
||||||
spec->adc_nids = alc662_adc_nids;
|
spec->adc_nids = alc662_adc_nids;
|
||||||
spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
|
spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
|
||||||
spec->capsrc_nids = alc662_capsrc_nids;
|
spec->capsrc_nids = alc662_capsrc_nids;
|
||||||
spec->capture_style = CAPT_MIX;
|
|
||||||
|
|
||||||
if (!spec->cap_mixer)
|
if (!spec->cap_mixer)
|
||||||
set_capture_mixer(spec);
|
set_capture_mixer(spec);
|
||||||
|
|
|
@ -639,7 +639,7 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
|
||||||
static unsigned int stac92xx_vref_set(struct hda_codec *codec,
|
static unsigned int stac92xx_vref_set(struct hda_codec *codec,
|
||||||
hda_nid_t nid, unsigned int new_vref)
|
hda_nid_t nid, unsigned int new_vref)
|
||||||
{
|
{
|
||||||
unsigned int error;
|
int error;
|
||||||
unsigned int pincfg;
|
unsigned int pincfg;
|
||||||
pincfg = snd_hda_codec_read(codec, nid, 0,
|
pincfg = snd_hda_codec_read(codec, nid, 0,
|
||||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||||
|
@ -2703,7 +2703,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
|
||||||
{
|
{
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
unsigned int new_vref = 0;
|
unsigned int new_vref = 0;
|
||||||
unsigned int error;
|
int error;
|
||||||
hda_nid_t nid = kcontrol->private_value;
|
hda_nid_t nid = kcontrol->private_value;
|
||||||
|
|
||||||
if (ucontrol->value.enumerated.item[0] == 0)
|
if (ucontrol->value.enumerated.item[0] == 0)
|
||||||
|
@ -4035,7 +4035,7 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
|
||||||
AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
|
AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||||
static void stac92xx_free_jack_priv(struct snd_jack *jack)
|
static void stac92xx_free_jack_priv(struct snd_jack *jack)
|
||||||
{
|
{
|
||||||
struct sigmatel_jack *jacks = jack->private_data;
|
struct sigmatel_jack *jacks = jack->private_data;
|
||||||
|
@ -4047,7 +4047,7 @@ static void stac92xx_free_jack_priv(struct snd_jack *jack)
|
||||||
static int stac92xx_add_jack(struct hda_codec *codec,
|
static int stac92xx_add_jack(struct hda_codec *codec,
|
||||||
hda_nid_t nid, int type)
|
hda_nid_t nid, int type)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
struct sigmatel_jack *jack;
|
struct sigmatel_jack *jack;
|
||||||
int def_conf = snd_hda_codec_get_pincfg(codec, nid);
|
int def_conf = snd_hda_codec_get_pincfg(codec, nid);
|
||||||
|
@ -4336,7 +4336,7 @@ static int stac92xx_init(struct hda_codec *codec)
|
||||||
|
|
||||||
static void stac92xx_free_jacks(struct hda_codec *codec)
|
static void stac92xx_free_jacks(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||||
/* free jack instances manually when clearing/reconfiguring */
|
/* free jack instances manually when clearing/reconfiguring */
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
if (!codec->bus->shutdown && spec->jacks.list) {
|
if (!codec->bus->shutdown && spec->jacks.list) {
|
||||||
|
|
|
@ -85,6 +85,7 @@ static int joystick;
|
||||||
static int ac97_clock = 48000;
|
static int ac97_clock = 48000;
|
||||||
static char *ac97_quirk;
|
static char *ac97_quirk;
|
||||||
static int dxs_support;
|
static int dxs_support;
|
||||||
|
static int nodelay;
|
||||||
|
|
||||||
module_param(index, int, 0444);
|
module_param(index, int, 0444);
|
||||||
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
|
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
|
||||||
|
@ -102,6 +103,8 @@ module_param(ac97_quirk, charp, 0444);
|
||||||
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
|
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
|
||||||
module_param(dxs_support, int, 0444);
|
module_param(dxs_support, int, 0444);
|
||||||
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
|
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
|
||||||
|
module_param(nodelay, int, 0444);
|
||||||
|
MODULE_PARM_DESC(nodelay, "Disable 500ms init delay");
|
||||||
|
|
||||||
/* just for backward compatibility */
|
/* just for backward compatibility */
|
||||||
static int enable;
|
static int enable;
|
||||||
|
@ -549,7 +552,8 @@ static void snd_via82xx_codec_wait(struct snd_ac97 *ac97)
|
||||||
int err;
|
int err;
|
||||||
err = snd_via82xx_codec_ready(chip, ac97->num);
|
err = snd_via82xx_codec_ready(chip, ac97->num);
|
||||||
/* here we need to wait fairly for long time.. */
|
/* here we need to wait fairly for long time.. */
|
||||||
msleep(500);
|
if (!nodelay)
|
||||||
|
msleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
|
static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct bf5xx_i2s_port {
|
||||||
u16 tcr2;
|
u16 tcr2;
|
||||||
u16 rcr2;
|
u16 rcr2;
|
||||||
int counter;
|
int counter;
|
||||||
|
int configured;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bf5xx_i2s_port bf5xx_i2s;
|
static struct bf5xx_i2s_port bf5xx_i2s;
|
||||||
|
@ -168,7 +169,7 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bf5xx_i2s.counter == 1) {
|
if (!bf5xx_i2s.configured) {
|
||||||
/*
|
/*
|
||||||
* TX and RX are not independent,they are enabled at the
|
* TX and RX are not independent,they are enabled at the
|
||||||
* same time, even if only one side is running. So, we
|
* same time, even if only one side is running. So, we
|
||||||
|
@ -177,6 +178,7 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||||
*
|
*
|
||||||
* CPU DAI:slave mode.
|
* CPU DAI:slave mode.
|
||||||
*/
|
*/
|
||||||
|
bf5xx_i2s.configured = 1;
|
||||||
ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
|
ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
|
||||||
bf5xx_i2s.rcr2, 0, 0);
|
bf5xx_i2s.rcr2, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -200,6 +202,9 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
|
||||||
{
|
{
|
||||||
pr_debug("%s enter\n", __func__);
|
pr_debug("%s enter\n", __func__);
|
||||||
bf5xx_i2s.counter--;
|
bf5xx_i2s.counter--;
|
||||||
|
/* No active stream, SPORT is allowed to be configured again. */
|
||||||
|
if (!bf5xx_i2s.counter)
|
||||||
|
bf5xx_i2s.configured = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bf5xx_i2s_probe(struct platform_device *pdev,
|
static int bf5xx_i2s_probe(struct platform_device *pdev,
|
||||||
|
@ -244,8 +249,7 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bf5xx_i2s_resume(struct platform_device *pdev,
|
static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
|
||||||
struct snd_soc_dai *dai)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sport_device *sport =
|
struct sport_device *sport =
|
||||||
|
|
Loading…
Reference in a new issue