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: Do not announce false surround in Conexant auto
  ALSA: HDA: Conexant auto: Handle multiple connections to ADC node
  ALSA: HDA: Add position_fix quirk for an Asus device
  ALSA: caiaq - Fix possible string-buffer overflow
  ALSA: au88x0 - Modify pointer callback to give accurate playback position
This commit is contained in:
Linus Torvalds 2011-02-20 10:15:57 -08:00
commit 6f576d57f1
5 changed files with 63 additions and 19 deletions

View File

@ -1252,11 +1252,19 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
{ {
stream_t *dma = &vortex->dma_adb[adbdma]; stream_t *dma = &vortex->dma_adb[adbdma];
int temp; int temp, page, delta;
temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)); temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1)); page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
return temp; if (dma->nr_periods >= 4)
delta = (page - dma->period_real) & 3;
else {
delta = (page - dma->period_real);
if (delta < 0)
delta += dma->nr_periods;
}
return (dma->period_virt + delta) * dma->period_bytes
+ (temp & (dma->period_bytes - 1));
} }
static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma) static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)

View File

@ -2308,6 +2308,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB),
SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),

View File

@ -3410,7 +3410,7 @@ static void cx_auto_parse_output(struct hda_codec *codec)
} }
} }
spec->multiout.dac_nids = spec->private_dac_nids; spec->multiout.dac_nids = spec->private_dac_nids;
spec->multiout.max_channels = nums * 2; spec->multiout.max_channels = spec->multiout.num_dacs * 2;
if (cfg->hp_outs > 0) if (cfg->hp_outs > 0)
spec->auto_mute = 1; spec->auto_mute = 1;
@ -3729,9 +3729,9 @@ static int cx_auto_init(struct hda_codec *codec)
return 0; return 0;
} }
static int cx_auto_add_volume(struct hda_codec *codec, const char *basename, static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
const char *dir, int cidx, const char *dir, int cidx,
hda_nid_t nid, int hda_dir) hda_nid_t nid, int hda_dir, int amp_idx)
{ {
static char name[32]; static char name[32];
static struct snd_kcontrol_new knew[] = { static struct snd_kcontrol_new knew[] = {
@ -3743,7 +3743,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir); knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
hda_dir);
knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
knew[i].index = cidx; knew[i].index = cidx;
snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
@ -3759,6 +3760,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
return 0; return 0;
} }
#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
#define cx_auto_add_pb_volume(codec, nid, str, idx) \ #define cx_auto_add_pb_volume(codec, nid, str, idx) \
cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
@ -3808,29 +3812,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
struct conexant_spec *spec = codec->spec; struct conexant_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg; struct auto_pin_cfg *cfg = &spec->autocfg;
static const char *prev_label; static const char *prev_label;
int i, err, cidx; int i, err, cidx, conn_len;
hda_nid_t conn[HDA_MAX_CONNECTIONS];
int multi_adc_volume = 0; /* If the ADC nid has several input volumes */
int adc_nid = spec->adc_nids[0];
conn_len = snd_hda_get_connections(codec, adc_nid, conn,
HDA_MAX_CONNECTIONS);
if (conn_len < 0)
return conn_len;
multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
if (!multi_adc_volume) {
err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
HDA_INPUT);
if (err < 0)
return err;
}
err = cx_auto_add_volume(codec, "Capture", "", 0, spec->adc_nids[0],
HDA_INPUT);
if (err < 0)
return err;
prev_label = NULL; prev_label = NULL;
cidx = 0; cidx = 0;
for (i = 0; i < cfg->num_inputs; i++) { for (i = 0; i < cfg->num_inputs; i++) {
hda_nid_t nid = cfg->inputs[i].pin; hda_nid_t nid = cfg->inputs[i].pin;
const char *label; const char *label;
if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) int j;
int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
if (!pin_amp && !multi_adc_volume)
continue; continue;
label = hda_get_autocfg_input_label(codec, cfg, i); label = hda_get_autocfg_input_label(codec, cfg, i);
if (label == prev_label) if (label == prev_label)
cidx++; cidx++;
else else
cidx = 0; cidx = 0;
prev_label = label; prev_label = label;
err = cx_auto_add_volume(codec, label, " Capture", cidx,
nid, HDA_INPUT); if (pin_amp) {
if (err < 0) err = cx_auto_add_volume(codec, label, " Boost", cidx,
return err; nid, HDA_INPUT);
if (err < 0)
return err;
}
if (!multi_adc_volume)
continue;
for (j = 0; j < conn_len; j++) {
if (conn[j] == nid) {
err = cx_auto_add_volume_idx(codec, label,
" Capture", cidx, adc_nid, HDA_INPUT, j);
if (err < 0)
return err;
break;
}
}
} }
return 0; return 0;
} }

View File

@ -785,7 +785,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
} }
dev->pcm->private_data = dev; dev->pcm->private_data = dev;
strcpy(dev->pcm->name, dev->product_name); strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name));
memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); memset(dev->sub_capture, 0, sizeof(dev->sub_capture));

View File

@ -136,7 +136,7 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
if (ret < 0) if (ret < 0)
return ret; return ret;
strcpy(rmidi->name, device->product_name); strlcpy(rmidi->name, device->product_name, sizeof(rmidi->name));
rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
rmidi->private_data = device; rmidi->private_data = device;