Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182696
b: refs/heads/master
c: 47e9134
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai committed Jan 13, 2010
1 parent 1457dce commit 3753541
Show file tree
Hide file tree
Showing 14 changed files with 592 additions and 184 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b98515a620592636d2f8e0d3e2942d1cb4847ec
refs/heads/master: 47e91348459901c30cc1bb4897e62ced21ca243a
8 changes: 5 additions & 3 deletions trunk/sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
+ HZ/100);
/* move new_hw_ptr according jiffies not pos variable */
new_hw_ptr = old_hw_ptr;
hw_base = delta;
/* use loop to avoid checks for delta overflows */
/* the delta value is small or zero in most cases */
while (delta > 0) {
Expand All @@ -403,18 +404,19 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
delta--;
}
/* align hw_base to buffer_size */
hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
delta = 0;
hw_ptr_error(substream,
"hw_ptr skipping! %s"
"(pos=%ld, delta=%ld, period=%ld, "
"jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
in_interrupt ? "[Q] " : "",
(long)pos, (long)hdelta,
(long)runtime->period_size, jdelta,
((hdelta * HZ) / runtime->rate), delta,
((hdelta * HZ) / runtime->rate), hw_base,
(unsigned long)old_hw_ptr,
(unsigned long)new_hw_ptr);
/* reset values to proper state */
delta = 0;
hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
}
no_jiffies_check:
if (delta > runtime->period_size + runtime->period_size / 2) {
Expand Down
48 changes: 22 additions & 26 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
struct hda_pincfg *pin;
unsigned int oldcfg;

if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
return -EINVAL;

oldcfg = snd_hda_codec_get_pincfg(codec, nid);
pin = look_up_pincfg(codec, list, nid);
if (!pin) {
Expand Down Expand Up @@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
}
}

/**
* snd_hda_shutup_pins - Shut up all pins
* @codec: the HDA codec
*
* Clear all pin controls to shup up before suspend for avoiding click noise.
* The controls aren't cached so that they can be resumed properly.
*/
void snd_hda_shutup_pins(struct hda_codec *codec)
{
int i;
for (i = 0; i < codec->init_pins.used; i++) {
struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
/* use read here for syncing after issuing each verb */
snd_hda_codec_read(codec, pin->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
}
}
EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);

static void init_hda_cache(struct hda_cache_rec *cache,
unsigned int record_size);
static void free_hda_cache(struct hda_cache_rec *cache);
Expand Down Expand Up @@ -3537,32 +3559,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
}
EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);

/**
* snd_hda_add_nids - assign nids to controls from the array
* @codec: the HDA codec
* @kctl: struct snd_kcontrol
* @index: index to kctl
* @nids: the array of hda_nid_t
* @size: count of hda_nid_t items
*
* This helper function assigns NIDs in the given array to a control element.
*
* Returns 0 if successful, or a negative error code.
*/
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
unsigned int index, hda_nid_t *nids, unsigned int size)
{
int err;

for ( ; size > 0; size--, nids++) {
err = snd_hda_add_nid(codec, kctl, index, *nids);
if (err < 0)
return err;
}
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_add_nids);

#ifdef CONFIG_SND_HDA_POWER_SAVE
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state);
Expand Down
1 change: 1 addition & 0 deletions trunk/sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
unsigned int cfg);
int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
hda_nid_t nid, unsigned int cfg); /* for hwdep */
void snd_hda_shutup_pins(struct hda_codec *codec);

/*
* Mixer
Expand Down
7 changes: 5 additions & 2 deletions trunk/sound/pci/hda/hda_hwdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
{ \
struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
struct hda_codec *codec = hwdep->private_data; \
char *after; \
codec->type = simple_strtoul(buf, &after, 0); \
unsigned long val; \
int err = strict_strtoul(buf, 0, &val); \
if (err < 0) \
return err; \
codec->type = val; \
return count; \
}

Expand Down
51 changes: 19 additions & 32 deletions trunk/sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ struct azx_dev {
*/
unsigned char stream_tag; /* assigned stream */
unsigned char index; /* stream index */
int device; /* last device number assigned to */

unsigned int opened :1;
unsigned int running :1;
Expand Down Expand Up @@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip)
*/

/* assign a stream for the PCM */
static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
static inline struct azx_dev *
azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
{
int dev, i, nums;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
struct azx_dev *res = NULL;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dev = chip->playback_index_offset;
nums = chip->playback_streams;
} else {
Expand All @@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
}
for (i = 0; i < nums; i++, dev++)
if (!chip->azx_dev[dev].opened) {
chip->azx_dev[dev].opened = 1;
return &chip->azx_dev[dev];
res = &chip->azx_dev[dev];
if (res->device == substream->pcm->device)
break;
}
return NULL;
if (res) {
res->opened = 1;
res->device = substream->pcm->device;
}
return res;
}

/* release the assigned stream */
Expand Down Expand Up @@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
int err;

mutex_lock(&chip->open_mutex);
azx_dev = azx_assign_device(chip, substream->stream);
azx_dev = azx_assign_device(chip, substream);
if (azx_dev == NULL) {
mutex_unlock(&chip->open_mutex);
return -EBUSY;
Expand Down Expand Up @@ -2695,32 +2704,10 @@ static struct pci_device_id azx_ids[] = {
/* ULI M5461 */
{ PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
/* NVIDIA MCP */
{ PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
.class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
.class_mask = 0xffffff,
.driver_data = AZX_DRIVER_NVIDIA },
/* Teradici */
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
/* Creative X-Fi (CA0110-IBG) */
Expand Down
2 changes: 0 additions & 2 deletions trunk/sound/pci/hda/hda_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,6 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
const struct snd_pci_quirk *tbl);
int snd_hda_add_new_ctls(struct hda_codec *codec,
struct snd_kcontrol_new *knew);
int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl,
unsigned int index, hda_nid_t *nids, unsigned int size);

/*
* unsolicited event handler
Expand Down
71 changes: 69 additions & 2 deletions trunk/sound/pci/hda/patch_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
if (!kctl)
kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
for (i = 0; kctl && i < kctl->count; i++) {
err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids,
spec->input_mux->num_items);
err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
if (err < 0)
return err;
}
Expand Down Expand Up @@ -442,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
return 0;
}

static inline void ad198x_shutup(struct hda_codec *codec)
{
snd_hda_shutup_pins(codec);
}

static void ad198x_free_kctls(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
Expand All @@ -455,18 +459,76 @@ static void ad198x_free_kctls(struct hda_codec *codec)
snd_array_free(&spec->kctls);
}

static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
hda_nid_t hp)
{
struct ad198x_spec *spec = codec->spec;
snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
!spec->inv_eapd ? 0x00 : 0x02);
snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
!spec->inv_eapd ? 0x00 : 0x02);
}

static void ad198x_power_eapd(struct hda_codec *codec)
{
/* We currently only handle front, HP */
switch (codec->vendor_id) {
case 0x11d41882:
case 0x11d4882a:
case 0x11d41884:
case 0x11d41984:
case 0x11d41883:
case 0x11d4184a:
case 0x11d4194a:
case 0x11d4194b:
ad198x_power_eapd_write(codec, 0x12, 0x11);
break;
case 0x11d41981:
case 0x11d41983:
ad198x_power_eapd_write(codec, 0x05, 0x06);
break;
case 0x11d41986:
ad198x_power_eapd_write(codec, 0x1b, 0x1a);
break;
case 0x11d41988:
case 0x11d4198b:
case 0x11d4989a:
case 0x11d4989b:
ad198x_power_eapd_write(codec, 0x29, 0x22);
break;
}
}

static void ad198x_free(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;

if (!spec)
return;

ad198x_shutup(codec);
ad198x_free_kctls(codec);
kfree(spec);
snd_hda_detach_beep_device(codec);
}

#ifdef SND_HDA_NEEDS_RESUME
static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
{
ad198x_shutup(codec);
ad198x_power_eapd(codec);
return 0;
}

static int ad198x_resume(struct hda_codec *codec)
{
ad198x_init(codec);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
return 0;
}
#endif

static struct hda_codec_ops ad198x_patch_ops = {
.build_controls = ad198x_build_controls,
.build_pcms = ad198x_build_pcms,
Expand All @@ -475,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
#ifdef CONFIG_SND_HDA_POWER_SAVE
.check_power_status = ad198x_check_power_status,
#endif
#ifdef SND_HDA_NEEDS_RESUME
.suspend = ad198x_suspend,
.resume = ad198x_resume,
#endif
.reboot_notify = ad198x_shutup,
};


Expand Down
12 changes: 8 additions & 4 deletions trunk/sound/pci/hda/patch_cirrus.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ static int build_input(struct hda_codec *codec)
spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
for (i = 0; i < 2; i++) {
struct snd_kcontrol *kctl;
int n;
if (!spec->capture_bind[i])
return -ENOMEM;
kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
Expand All @@ -762,10 +763,13 @@ static int build_input(struct hda_codec *codec)
err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0)
return err;
err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid,
spec->num_inputs);
if (err < 0)
return err;
for (n = 0; n < AUTO_PIN_LAST; n++) {
if (!spec->adc_nid[n])
continue;
err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
if (err < 0)
return err;
}
}

if (spec->num_inputs > 1 && !spec->mic_detect) {
Expand Down
3 changes: 1 addition & 2 deletions trunk/sound/pci/hda/patch_cmedia.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,7 @@ static int cmi9880_build_controls(struct hda_codec *codec)
/* assign Capture Source enums to NID */
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
for (i = 0; kctl && i < kctl->count; i++) {
err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids,
spec->input_mux->num_items);
err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
if (err < 0)
return err;
}
Expand Down
Loading

0 comments on commit 3753541

Please sign in to comment.