diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/bt87x.c | 6 | ||||
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 41 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 39 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 53 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 21 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 112 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 44 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 105 | ||||
-rw-r--r-- | sound/pci/korg1212/korg1212.c | 6 |
11 files changed, 340 insertions, 103 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 97ee127ac33d..78288dbfc17a 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -2122,7 +2122,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, | |||
2122 | } | 2122 | } |
2123 | /* nothing should be in powerdown mode */ | 2123 | /* nothing should be in powerdown mode */ |
2124 | snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); | 2124 | snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); |
2125 | end_time = jiffies + msecs_to_jiffies(100); | 2125 | end_time = jiffies + msecs_to_jiffies(120); |
2126 | do { | 2126 | do { |
2127 | if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) | 2127 | if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) |
2128 | goto __ready_ok; | 2128 | goto __ready_ok; |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index a299340519df..ce3f2e90f4d7 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -349,7 +349,8 @@ static struct snd_pcm_hardware snd_bt87x_digital_hw = { | |||
349 | .info = SNDRV_PCM_INFO_MMAP | | 349 | .info = SNDRV_PCM_INFO_MMAP | |
350 | SNDRV_PCM_INFO_INTERLEAVED | | 350 | SNDRV_PCM_INFO_INTERLEAVED | |
351 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 351 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
352 | SNDRV_PCM_INFO_MMAP_VALID, | 352 | SNDRV_PCM_INFO_MMAP_VALID | |
353 | SNDRV_PCM_INFO_BATCH, | ||
353 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 354 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
354 | .rates = 0, /* set at runtime */ | 355 | .rates = 0, /* set at runtime */ |
355 | .channels_min = 2, | 356 | .channels_min = 2, |
@@ -365,7 +366,8 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = { | |||
365 | .info = SNDRV_PCM_INFO_MMAP | | 366 | .info = SNDRV_PCM_INFO_MMAP | |
366 | SNDRV_PCM_INFO_INTERLEAVED | | 367 | SNDRV_PCM_INFO_INTERLEAVED | |
367 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 368 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
368 | SNDRV_PCM_INFO_MMAP_VALID, | 369 | SNDRV_PCM_INFO_MMAP_VALID | |
370 | SNDRV_PCM_INFO_BATCH, | ||
369 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, | 371 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, |
370 | .rates = SNDRV_PCM_RATE_KNOT, | 372 | .rates = SNDRV_PCM_RATE_KNOT, |
371 | .rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX, | 373 | .rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX, |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 191e1cd9997d..4b302d86f5f2 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -2493,24 +2493,17 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2493 | case SNDRV_EMU10K1_IOCTL_CODE_POKE: | 2493 | case SNDRV_EMU10K1_IOCTL_CODE_POKE: |
2494 | if (!capable(CAP_SYS_ADMIN)) | 2494 | if (!capable(CAP_SYS_ADMIN)) |
2495 | return -EPERM; | 2495 | return -EPERM; |
2496 | icode = kmalloc(sizeof(*icode), GFP_KERNEL); | 2496 | |
2497 | if (icode == NULL) | 2497 | icode = memdup_user(argp, sizeof(*icode)); |
2498 | return -ENOMEM; | 2498 | if (IS_ERR(icode)) |
2499 | if (copy_from_user(icode, argp, sizeof(*icode))) { | 2499 | return PTR_ERR(icode); |
2500 | kfree(icode); | ||
2501 | return -EFAULT; | ||
2502 | } | ||
2503 | res = snd_emu10k1_icode_poke(emu, icode); | 2500 | res = snd_emu10k1_icode_poke(emu, icode); |
2504 | kfree(icode); | 2501 | kfree(icode); |
2505 | return res; | 2502 | return res; |
2506 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: | 2503 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: |
2507 | icode = kmalloc(sizeof(*icode), GFP_KERNEL); | 2504 | icode = memdup_user(argp, sizeof(*icode)); |
2508 | if (icode == NULL) | 2505 | if (IS_ERR(icode)) |
2509 | return -ENOMEM; | 2506 | return PTR_ERR(icode); |
2510 | if (copy_from_user(icode, argp, sizeof(*icode))) { | ||
2511 | kfree(icode); | ||
2512 | return -EFAULT; | ||
2513 | } | ||
2514 | res = snd_emu10k1_icode_peek(emu, icode); | 2507 | res = snd_emu10k1_icode_peek(emu, icode); |
2515 | if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) { | 2508 | if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) { |
2516 | kfree(icode); | 2509 | kfree(icode); |
@@ -2519,24 +2512,16 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2519 | kfree(icode); | 2512 | kfree(icode); |
2520 | return res; | 2513 | return res; |
2521 | case SNDRV_EMU10K1_IOCTL_PCM_POKE: | 2514 | case SNDRV_EMU10K1_IOCTL_PCM_POKE: |
2522 | ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL); | 2515 | ipcm = memdup_user(argp, sizeof(*ipcm)); |
2523 | if (ipcm == NULL) | 2516 | if (IS_ERR(ipcm)) |
2524 | return -ENOMEM; | 2517 | return PTR_ERR(ipcm); |
2525 | if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { | ||
2526 | kfree(ipcm); | ||
2527 | return -EFAULT; | ||
2528 | } | ||
2529 | res = snd_emu10k1_ipcm_poke(emu, ipcm); | 2518 | res = snd_emu10k1_ipcm_poke(emu, ipcm); |
2530 | kfree(ipcm); | 2519 | kfree(ipcm); |
2531 | return res; | 2520 | return res; |
2532 | case SNDRV_EMU10K1_IOCTL_PCM_PEEK: | 2521 | case SNDRV_EMU10K1_IOCTL_PCM_PEEK: |
2533 | ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL); | 2522 | ipcm = memdup_user(argp, sizeof(*ipcm)); |
2534 | if (ipcm == NULL) | 2523 | if (IS_ERR(ipcm)) |
2535 | return -ENOMEM; | 2524 | return PTR_ERR(ipcm); |
2536 | if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { | ||
2537 | kfree(ipcm); | ||
2538 | return -EFAULT; | ||
2539 | } | ||
2540 | res = snd_emu10k1_ipcm_peek(emu, ipcm); | 2525 | res = snd_emu10k1_ipcm_peek(emu, ipcm); |
2541 | if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) { | 2526 | if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) { |
2542 | kfree(ipcm); | 2527 | kfree(ipcm); |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a4e5e5952115..8820faf6c9d8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -642,19 +642,21 @@ static int get_codec_name(struct hda_codec *codec) | |||
642 | */ | 642 | */ |
643 | static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) | 643 | static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) |
644 | { | 644 | { |
645 | int i, total_nodes; | 645 | int i, total_nodes, function_id; |
646 | hda_nid_t nid; | 646 | hda_nid_t nid; |
647 | 647 | ||
648 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); | 648 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); |
649 | for (i = 0; i < total_nodes; i++, nid++) { | 649 | for (i = 0; i < total_nodes; i++, nid++) { |
650 | codec->function_id = snd_hda_param_read(codec, nid, | 650 | function_id = snd_hda_param_read(codec, nid, |
651 | AC_PAR_FUNCTION_TYPE) & 0xff; | 651 | AC_PAR_FUNCTION_TYPE) & 0xff; |
652 | switch (codec->function_id) { | 652 | switch (function_id) { |
653 | case AC_GRP_AUDIO_FUNCTION: | 653 | case AC_GRP_AUDIO_FUNCTION: |
654 | codec->afg = nid; | 654 | codec->afg = nid; |
655 | codec->function_id = function_id; | ||
655 | break; | 656 | break; |
656 | case AC_GRP_MODEM_FUNCTION: | 657 | case AC_GRP_MODEM_FUNCTION: |
657 | codec->mfg = nid; | 658 | codec->mfg = nid; |
659 | codec->function_id = function_id; | ||
658 | break; | 660 | break; |
659 | default: | 661 | default: |
660 | break; | 662 | break; |
@@ -2250,7 +2252,11 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, | |||
2250 | err = bus->ops.command(bus, res); | 2252 | err = bus->ops.command(bus, res); |
2251 | if (!err) { | 2253 | if (!err) { |
2252 | struct hda_cache_head *c; | 2254 | struct hda_cache_head *c; |
2253 | u32 key = build_cmd_cache_key(nid, verb); | 2255 | u32 key; |
2256 | /* parm may contain the verb stuff for get/set amp */ | ||
2257 | verb = verb | (parm >> 8); | ||
2258 | parm &= 0xff; | ||
2259 | key = build_cmd_cache_key(nid, verb); | ||
2254 | c = get_alloc_hash(&codec->cmd_cache, key); | 2260 | c = get_alloc_hash(&codec->cmd_cache, key); |
2255 | if (c) | 2261 | if (c) |
2256 | c->val = parm; | 2262 | c->val = parm; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7ba8db5d4c42..21e99cfa8c49 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -312,6 +312,8 @@ struct azx_dev { | |||
312 | unsigned int period_bytes; /* size of the period in bytes */ | 312 | unsigned int period_bytes; /* size of the period in bytes */ |
313 | unsigned int frags; /* number for period in the play buffer */ | 313 | unsigned int frags; /* number for period in the play buffer */ |
314 | unsigned int fifo_size; /* FIFO size */ | 314 | unsigned int fifo_size; /* FIFO size */ |
315 | unsigned long start_jiffies; /* start + minimum jiffies */ | ||
316 | unsigned long min_jiffies; /* minimum jiffies before position is valid */ | ||
315 | 317 | ||
316 | void __iomem *sd_addr; /* stream descriptor pointer */ | 318 | void __iomem *sd_addr; /* stream descriptor pointer */ |
317 | 319 | ||
@@ -330,7 +332,7 @@ struct azx_dev { | |||
330 | unsigned int opened :1; | 332 | unsigned int opened :1; |
331 | unsigned int running :1; | 333 | unsigned int running :1; |
332 | unsigned int irq_pending :1; | 334 | unsigned int irq_pending :1; |
333 | unsigned int irq_ignore :1; | 335 | unsigned int start_flag: 1; /* stream full start flag */ |
334 | /* | 336 | /* |
335 | * For VIA: | 337 | * For VIA: |
336 | * A flag to ensure DMA position is 0 | 338 | * A flag to ensure DMA position is 0 |
@@ -975,7 +977,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
975 | struct azx *chip = dev_id; | 977 | struct azx *chip = dev_id; |
976 | struct azx_dev *azx_dev; | 978 | struct azx_dev *azx_dev; |
977 | u32 status; | 979 | u32 status; |
978 | int i; | 980 | int i, ok; |
979 | 981 | ||
980 | spin_lock(&chip->reg_lock); | 982 | spin_lock(&chip->reg_lock); |
981 | 983 | ||
@@ -991,18 +993,14 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
991 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 993 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
992 | if (!azx_dev->substream || !azx_dev->running) | 994 | if (!azx_dev->substream || !azx_dev->running) |
993 | continue; | 995 | continue; |
994 | /* ignore the first dummy IRQ (due to pos_adj) */ | ||
995 | if (azx_dev->irq_ignore) { | ||
996 | azx_dev->irq_ignore = 0; | ||
997 | continue; | ||
998 | } | ||
999 | /* check whether this IRQ is really acceptable */ | 996 | /* check whether this IRQ is really acceptable */ |
1000 | if (azx_position_ok(chip, azx_dev)) { | 997 | ok = azx_position_ok(chip, azx_dev); |
998 | if (ok == 1) { | ||
1001 | azx_dev->irq_pending = 0; | 999 | azx_dev->irq_pending = 0; |
1002 | spin_unlock(&chip->reg_lock); | 1000 | spin_unlock(&chip->reg_lock); |
1003 | snd_pcm_period_elapsed(azx_dev->substream); | 1001 | snd_pcm_period_elapsed(azx_dev->substream); |
1004 | spin_lock(&chip->reg_lock); | 1002 | spin_lock(&chip->reg_lock); |
1005 | } else if (chip->bus && chip->bus->workq) { | 1003 | } else if (ok == 0 && chip->bus && chip->bus->workq) { |
1006 | /* bogus IRQ, process it later */ | 1004 | /* bogus IRQ, process it later */ |
1007 | azx_dev->irq_pending = 1; | 1005 | azx_dev->irq_pending = 1; |
1008 | queue_work(chip->bus->workq, | 1006 | queue_work(chip->bus->workq, |
@@ -1088,7 +1086,6 @@ static int azx_setup_periods(struct azx *chip, | |||
1088 | bdl = (u32 *)azx_dev->bdl.area; | 1086 | bdl = (u32 *)azx_dev->bdl.area; |
1089 | ofs = 0; | 1087 | ofs = 0; |
1090 | azx_dev->frags = 0; | 1088 | azx_dev->frags = 0; |
1091 | azx_dev->irq_ignore = 0; | ||
1092 | pos_adj = bdl_pos_adj[chip->dev_index]; | 1089 | pos_adj = bdl_pos_adj[chip->dev_index]; |
1093 | if (pos_adj > 0) { | 1090 | if (pos_adj > 0) { |
1094 | struct snd_pcm_runtime *runtime = substream->runtime; | 1091 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1109,7 +1106,6 @@ static int azx_setup_periods(struct azx *chip, | |||
1109 | &bdl, ofs, pos_adj, 1); | 1106 | &bdl, ofs, pos_adj, 1); |
1110 | if (ofs < 0) | 1107 | if (ofs < 0) |
1111 | goto error; | 1108 | goto error; |
1112 | azx_dev->irq_ignore = 1; | ||
1113 | } | 1109 | } |
1114 | } else | 1110 | } else |
1115 | pos_adj = 0; | 1111 | pos_adj = 0; |
@@ -1155,6 +1151,9 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) | |||
1155 | while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && | 1151 | while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && |
1156 | --timeout) | 1152 | --timeout) |
1157 | ; | 1153 | ; |
1154 | |||
1155 | /* reset first position - may not be synced with hw at this time */ | ||
1156 | *azx_dev->posbuf = 0; | ||
1158 | } | 1157 | } |
1159 | 1158 | ||
1160 | /* | 1159 | /* |
@@ -1409,7 +1408,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1409 | snd_pcm_set_sync(substream); | 1408 | snd_pcm_set_sync(substream); |
1410 | mutex_unlock(&chip->open_mutex); | 1409 | mutex_unlock(&chip->open_mutex); |
1411 | 1410 | ||
1412 | azx_stream_reset(chip, azx_dev); | ||
1413 | return 0; | 1411 | return 0; |
1414 | } | 1412 | } |
1415 | 1413 | ||
@@ -1474,6 +1472,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1474 | unsigned int bufsize, period_bytes, format_val; | 1472 | unsigned int bufsize, period_bytes, format_val; |
1475 | int err; | 1473 | int err; |
1476 | 1474 | ||
1475 | azx_stream_reset(chip, azx_dev); | ||
1477 | format_val = snd_hda_calc_stream_format(runtime->rate, | 1476 | format_val = snd_hda_calc_stream_format(runtime->rate, |
1478 | runtime->channels, | 1477 | runtime->channels, |
1479 | runtime->format, | 1478 | runtime->format, |
@@ -1502,6 +1501,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1502 | return err; | 1501 | return err; |
1503 | } | 1502 | } |
1504 | 1503 | ||
1504 | azx_dev->min_jiffies = (runtime->period_size * HZ) / | ||
1505 | (runtime->rate * 2); | ||
1505 | azx_setup_controller(chip, azx_dev); | 1506 | azx_setup_controller(chip, azx_dev); |
1506 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1507 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1507 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; | 1508 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; |
@@ -1518,13 +1519,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1518 | struct azx *chip = apcm->chip; | 1519 | struct azx *chip = apcm->chip; |
1519 | struct azx_dev *azx_dev; | 1520 | struct azx_dev *azx_dev; |
1520 | struct snd_pcm_substream *s; | 1521 | struct snd_pcm_substream *s; |
1521 | int start, nsync = 0, sbits = 0; | 1522 | int rstart = 0, start, nsync = 0, sbits = 0; |
1522 | int nwait, timeout; | 1523 | int nwait, timeout; |
1523 | 1524 | ||
1524 | switch (cmd) { | 1525 | switch (cmd) { |
1526 | case SNDRV_PCM_TRIGGER_START: | ||
1527 | rstart = 1; | ||
1525 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 1528 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1526 | case SNDRV_PCM_TRIGGER_RESUME: | 1529 | case SNDRV_PCM_TRIGGER_RESUME: |
1527 | case SNDRV_PCM_TRIGGER_START: | ||
1528 | start = 1; | 1530 | start = 1; |
1529 | break; | 1531 | break; |
1530 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1532 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
@@ -1554,6 +1556,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1554 | if (s->pcm->card != substream->pcm->card) | 1556 | if (s->pcm->card != substream->pcm->card) |
1555 | continue; | 1557 | continue; |
1556 | azx_dev = get_azx_dev(s); | 1558 | azx_dev = get_azx_dev(s); |
1559 | if (rstart) { | ||
1560 | azx_dev->start_flag = 1; | ||
1561 | azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; | ||
1562 | } | ||
1557 | if (start) | 1563 | if (start) |
1558 | azx_stream_start(chip, azx_dev); | 1564 | azx_stream_start(chip, azx_dev); |
1559 | else | 1565 | else |
@@ -1703,6 +1709,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | |||
1703 | { | 1709 | { |
1704 | unsigned int pos; | 1710 | unsigned int pos; |
1705 | 1711 | ||
1712 | if (azx_dev->start_flag && | ||
1713 | time_before_eq(jiffies, azx_dev->start_jiffies)) | ||
1714 | return -1; /* bogus (too early) interrupt */ | ||
1715 | azx_dev->start_flag = 0; | ||
1716 | |||
1706 | pos = azx_get_position(chip, azx_dev); | 1717 | pos = azx_get_position(chip, azx_dev); |
1707 | if (chip->position_fix == POS_FIX_AUTO) { | 1718 | if (chip->position_fix == POS_FIX_AUTO) { |
1708 | if (!pos) { | 1719 | if (!pos) { |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 38ad3f7b040f..84cc49ca9148 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3817,6 +3817,49 @@ static struct hda_verb ad1884a_laptop_verbs[] = { | |||
3817 | { } /* end */ | 3817 | { } /* end */ |
3818 | }; | 3818 | }; |
3819 | 3819 | ||
3820 | static struct hda_verb ad1884a_mobile_verbs[] = { | ||
3821 | /* DACs; unmute as default */ | ||
3822 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | ||
3823 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | ||
3824 | /* Port-A (HP) mixer - route only from analog mixer */ | ||
3825 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3826 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3827 | /* Port-A pin */ | ||
3828 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3829 | /* Port-A (HP) pin - always unmuted */ | ||
3830 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3831 | /* Port-B (mic jack) pin */ | ||
3832 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3833 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
3834 | /* Port-C (int mic) pin */ | ||
3835 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3836 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
3837 | /* Port-F (int speaker) mixer - route only from analog mixer */ | ||
3838 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3839 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3840 | /* Port-F pin */ | ||
3841 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3842 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3843 | /* Analog mixer; mute as default */ | ||
3844 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3845 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3846 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
3847 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
3848 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
3849 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
3850 | /* Analog Mix output amp */ | ||
3851 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3852 | /* capture sources */ | ||
3853 | /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ | ||
3854 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3855 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
3856 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3857 | /* unsolicited event for pin-sense */ | ||
3858 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | ||
3859 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, | ||
3860 | { } /* end */ | ||
3861 | }; | ||
3862 | |||
3820 | /* | 3863 | /* |
3821 | * Thinkpad X300 | 3864 | * Thinkpad X300 |
3822 | * 0x11 - HP | 3865 | * 0x11 - HP |
@@ -3977,10 +4020,18 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
3977 | spec->input_mux = &ad1884a_laptop_capture_source; | 4020 | spec->input_mux = &ad1884a_laptop_capture_source; |
3978 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; | 4021 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; |
3979 | codec->patch_ops.init = ad1884a_hp_init; | 4022 | codec->patch_ops.init = ad1884a_hp_init; |
4023 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
4024 | * possible damage by overloading | ||
4025 | */ | ||
4026 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, | ||
4027 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
4028 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
4029 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
4030 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
3980 | break; | 4031 | break; |
3981 | case AD1884A_MOBILE: | 4032 | case AD1884A_MOBILE: |
3982 | spec->mixers[0] = ad1884a_mobile_mixers; | 4033 | spec->mixers[0] = ad1884a_mobile_mixers; |
3983 | spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; | 4034 | spec->init_verbs[0] = ad1884a_mobile_verbs; |
3984 | spec->multiout.dig_out_nid = 0; | 4035 | spec->multiout.dig_out_nid = 0; |
3985 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; | 4036 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; |
3986 | codec->patch_ops.init = ad1884a_hp_init; | 4037 | codec->patch_ops.init = ad1884a_hp_init; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 1f2ad76ca94b..56ce19e68cb5 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -350,12 +350,20 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
350 | } | 350 | } |
351 | 351 | ||
352 | #ifdef CONFIG_SND_JACK | 352 | #ifdef CONFIG_SND_JACK |
353 | static void conexant_free_jack_priv(struct snd_jack *jack) | ||
354 | { | ||
355 | struct conexant_jack *jacks = jack->private_data; | ||
356 | jacks->nid = 0; | ||
357 | jacks->jack = NULL; | ||
358 | } | ||
359 | |||
353 | static int conexant_add_jack(struct hda_codec *codec, | 360 | static int conexant_add_jack(struct hda_codec *codec, |
354 | hda_nid_t nid, int type) | 361 | hda_nid_t nid, int type) |
355 | { | 362 | { |
356 | struct conexant_spec *spec; | 363 | struct conexant_spec *spec; |
357 | struct conexant_jack *jack; | 364 | struct conexant_jack *jack; |
358 | const char *name; | 365 | const char *name; |
366 | int err; | ||
359 | 367 | ||
360 | spec = codec->spec; | 368 | spec = codec->spec; |
361 | snd_array_init(&spec->jacks, sizeof(*jack), 32); | 369 | snd_array_init(&spec->jacks, sizeof(*jack), 32); |
@@ -368,7 +376,12 @@ static int conexant_add_jack(struct hda_codec *codec, | |||
368 | jack->nid = nid; | 376 | jack->nid = nid; |
369 | jack->type = type; | 377 | jack->type = type; |
370 | 378 | ||
371 | return snd_jack_new(codec->bus->card, name, type, &jack->jack); | 379 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); |
380 | if (err < 0) | ||
381 | return err; | ||
382 | jack->jack->private_data = jack; | ||
383 | jack->jack->private_free = conexant_free_jack_priv; | ||
384 | return 0; | ||
372 | } | 385 | } |
373 | 386 | ||
374 | static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) | 387 | static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) |
@@ -455,8 +468,10 @@ static void conexant_free(struct hda_codec *codec) | |||
455 | if (spec->jacks.list) { | 468 | if (spec->jacks.list) { |
456 | struct conexant_jack *jacks = spec->jacks.list; | 469 | struct conexant_jack *jacks = spec->jacks.list; |
457 | int i; | 470 | int i; |
458 | for (i = 0; i < spec->jacks.used; i++) | 471 | for (i = 0; i < spec->jacks.used; i++, jacks++) { |
459 | snd_device_free(codec->bus->card, &jacks[i].jack); | 472 | if (jacks->jack) |
473 | snd_device_free(codec->bus->card, jacks->jack); | ||
474 | } | ||
460 | snd_array_free(&spec->jacks); | 475 | snd_array_free(&spec->jacks); |
461 | } | 476 | } |
462 | #endif | 477 | #endif |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f35e58a2d921..bcbb736f94f0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -188,6 +188,8 @@ enum { | |||
188 | ALC663_ASUS_MODE4, | 188 | ALC663_ASUS_MODE4, |
189 | ALC663_ASUS_MODE5, | 189 | ALC663_ASUS_MODE5, |
190 | ALC663_ASUS_MODE6, | 190 | ALC663_ASUS_MODE6, |
191 | ALC272_DELL, | ||
192 | ALC272_DELL_ZM1, | ||
191 | ALC662_AUTO, | 193 | ALC662_AUTO, |
192 | ALC662_MODEL_LAST, | 194 | ALC662_MODEL_LAST, |
193 | }; | 195 | }; |
@@ -8742,10 +8744,9 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8742 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), | 8744 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), |
8743 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), | 8745 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), |
8744 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 8746 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
8745 | SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", | 8747 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", |
8746 | ALC883_FUJITSU_PI2515), | 8748 | ALC883_FUJITSU_PI2515), |
8747 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), | 8749 | SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", |
8748 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", | ||
8749 | ALC888_FUJITSU_XA3530), | 8750 | ALC888_FUJITSU_XA3530), |
8750 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), | 8751 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), |
8751 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), | 8752 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), |
@@ -12057,6 +12058,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
12057 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), | 12058 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), |
12058 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), | 12059 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), |
12059 | SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), | 12060 | SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), |
12061 | SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA), | ||
12060 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | 12062 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), |
12061 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), | 12063 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), |
12062 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), | 12064 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), |
@@ -12977,10 +12979,17 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { | |||
12977 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | 12979 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), |
12978 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 12980 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
12979 | ALC269_ASUS_EEEPC_P703), | 12981 | ALC269_ASUS_EEEPC_P703), |
12982 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), | ||
12983 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), | ||
12984 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), | ||
12985 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), | ||
12986 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), | ||
12987 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), | ||
12980 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", | 12988 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", |
12981 | ALC269_ASUS_EEEPC_P901), | 12989 | ALC269_ASUS_EEEPC_P901), |
12982 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", | 12990 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", |
12983 | ALC269_ASUS_EEEPC_P901), | 12991 | ALC269_ASUS_EEEPC_P901), |
12992 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), | ||
12984 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | 12993 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), |
12985 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | 12994 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), |
12986 | {} | 12995 | {} |
@@ -15211,12 +15220,23 @@ static hda_nid_t alc662_dac_nids[4] = { | |||
15211 | 0x02, 0x03, 0x04 | 15220 | 0x02, 0x03, 0x04 |
15212 | }; | 15221 | }; |
15213 | 15222 | ||
15223 | static hda_nid_t alc272_dac_nids[2] = { | ||
15224 | 0x02, 0x03 | ||
15225 | }; | ||
15226 | |||
15214 | static hda_nid_t alc662_adc_nids[1] = { | 15227 | static hda_nid_t alc662_adc_nids[1] = { |
15215 | /* ADC1-2 */ | 15228 | /* ADC1-2 */ |
15216 | 0x09, | 15229 | 0x09, |
15217 | }; | 15230 | }; |
15218 | 15231 | ||
15232 | static hda_nid_t alc272_adc_nids[1] = { | ||
15233 | /* ADC1-2 */ | ||
15234 | 0x08, | ||
15235 | }; | ||
15236 | |||
15219 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; | 15237 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; |
15238 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | ||
15239 | |||
15220 | 15240 | ||
15221 | /* input MUX */ | 15241 | /* input MUX */ |
15222 | /* FIXME: should be a matrix-type input source selection */ | 15242 | /* FIXME: should be a matrix-type input source selection */ |
@@ -15642,14 +15662,7 @@ static struct hda_verb alc662_init_verbs[] = { | |||
15642 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | 15662 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ |
15643 | /* Input mixer */ | 15663 | /* Input mixer */ |
15644 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 15664 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
15645 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
15646 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
15647 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
15648 | |||
15649 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 15665 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
15650 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
15651 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
15652 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
15653 | 15666 | ||
15654 | /* always trun on EAPD */ | 15667 | /* always trun on EAPD */ |
15655 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 15668 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
@@ -15844,12 +15857,48 @@ static struct hda_verb alc662_ecs_init_verbs[] = { | |||
15844 | {} | 15857 | {} |
15845 | }; | 15858 | }; |
15846 | 15859 | ||
15860 | static struct hda_verb alc272_dell_zm1_init_verbs[] = { | ||
15861 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15862 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15863 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15864 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15865 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
15866 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
15867 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
15868 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
15869 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
15870 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
15871 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
15872 | {} | ||
15873 | }; | ||
15874 | |||
15875 | static struct hda_verb alc272_dell_init_verbs[] = { | ||
15876 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15877 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15878 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15879 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
15880 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
15881 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
15882 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
15883 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
15884 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
15885 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
15886 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
15887 | {} | ||
15888 | }; | ||
15889 | |||
15847 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { | 15890 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { |
15848 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 15891 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
15849 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 15892 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
15850 | { } /* end */ | 15893 | { } /* end */ |
15851 | }; | 15894 | }; |
15852 | 15895 | ||
15896 | static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { | ||
15897 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
15898 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
15899 | { } /* end */ | ||
15900 | }; | ||
15901 | |||
15853 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 15902 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) |
15854 | { | 15903 | { |
15855 | unsigned int present; | 15904 | unsigned int present; |
@@ -16361,6 +16410,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
16361 | 16410 | ||
16362 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | 16411 | static struct snd_pci_quirk alc662_cfg_tbl[] = { |
16363 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), | 16412 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), |
16413 | SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), | ||
16414 | SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), | ||
16364 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), | 16415 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), |
16365 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), | 16416 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), |
16366 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), | 16417 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), |
@@ -16373,26 +16424,36 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16373 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | 16424 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), |
16374 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | 16425 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), |
16375 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | 16426 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), |
16427 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), | ||
16428 | SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), | ||
16429 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), | ||
16376 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), | 16430 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), |
16377 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), | 16431 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), |
16378 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), | 16432 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), |
16379 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), | 16433 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), |
16434 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), | ||
16380 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), | 16435 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), |
16381 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), | 16436 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), |
16382 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), | 16437 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), |
16383 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ | 16438 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ |
16384 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), | 16439 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), |
16385 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), | 16440 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), |
16441 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), | ||
16442 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), | ||
16443 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), | ||
16386 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), | 16444 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), |
16387 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), | 16445 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), |
16388 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), | 16446 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), |
16447 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), | ||
16389 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), | 16448 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), |
16390 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), | 16449 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), |
16450 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), | ||
16391 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), | 16451 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), |
16392 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), | 16452 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), |
16393 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ | 16453 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ |
16394 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), | 16454 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), |
16395 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), | 16455 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), |
16456 | SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), | ||
16396 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), | 16457 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), |
16397 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), | 16458 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), |
16398 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), | 16459 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), |
@@ -16404,6 +16465,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
16404 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | 16465 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", |
16405 | ALC662_3ST_6ch_DIG), | 16466 | ALC662_3ST_6ch_DIG), |
16406 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | 16467 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), |
16468 | SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), | ||
16407 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | 16469 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), |
16408 | SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", | 16470 | SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", |
16409 | ALC662_3ST_6ch_DIG), | 16471 | ALC662_3ST_6ch_DIG), |
@@ -16641,6 +16703,36 @@ static struct alc_config_preset alc662_presets[] = { | |||
16641 | .unsol_event = alc663_mode6_unsol_event, | 16703 | .unsol_event = alc663_mode6_unsol_event, |
16642 | .init_hook = alc663_mode6_inithook, | 16704 | .init_hook = alc663_mode6_inithook, |
16643 | }, | 16705 | }, |
16706 | [ALC272_DELL] = { | ||
16707 | .mixers = { alc663_m51va_mixer }, | ||
16708 | .cap_mixer = alc272_auto_capture_mixer, | ||
16709 | .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, | ||
16710 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
16711 | .dac_nids = alc662_dac_nids, | ||
16712 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
16713 | .adc_nids = alc272_adc_nids, | ||
16714 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), | ||
16715 | .capsrc_nids = alc272_capsrc_nids, | ||
16716 | .channel_mode = alc662_3ST_2ch_modes, | ||
16717 | .input_mux = &alc663_m51va_capture_source, | ||
16718 | .unsol_event = alc663_m51va_unsol_event, | ||
16719 | .init_hook = alc663_m51va_inithook, | ||
16720 | }, | ||
16721 | [ALC272_DELL_ZM1] = { | ||
16722 | .mixers = { alc663_m51va_mixer }, | ||
16723 | .cap_mixer = alc662_auto_capture_mixer, | ||
16724 | .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, | ||
16725 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
16726 | .dac_nids = alc662_dac_nids, | ||
16727 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
16728 | .adc_nids = alc662_adc_nids, | ||
16729 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | ||
16730 | .capsrc_nids = alc662_capsrc_nids, | ||
16731 | .channel_mode = alc662_3ST_2ch_modes, | ||
16732 | .input_mux = &alc663_m51va_capture_source, | ||
16733 | .unsol_event = alc663_m51va_unsol_event, | ||
16734 | .init_hook = alc663_m51va_inithook, | ||
16735 | }, | ||
16644 | }; | 16736 | }; |
16645 | 16737 | ||
16646 | 16738 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 61996a2f45df..03b3646018a1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3076,6 +3076,11 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3076 | unsigned int wid_caps; | 3076 | unsigned int wid_caps; |
3077 | 3077 | ||
3078 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { | 3078 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { |
3079 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3080 | wid_caps = get_wcaps(codec, pins[i]); | ||
3081 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3082 | spec->hp_detect = 1; | ||
3083 | } | ||
3079 | nid = dac_nids[i]; | 3084 | nid = dac_nids[i]; |
3080 | if (!nid) | 3085 | if (!nid) |
3081 | continue; | 3086 | continue; |
@@ -3119,11 +3124,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3119 | err = create_controls_idx(codec, name, idx, nid, 3); | 3124 | err = create_controls_idx(codec, name, idx, nid, 3); |
3120 | if (err < 0) | 3125 | if (err < 0) |
3121 | return err; | 3126 | return err; |
3122 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3123 | wid_caps = get_wcaps(codec, pins[i]); | ||
3124 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3125 | spec->hp_detect = 1; | ||
3126 | } | ||
3127 | } | 3127 | } |
3128 | } | 3128 | } |
3129 | return 0; | 3129 | return 0; |
@@ -3851,6 +3851,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
3851 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ | 3851 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ |
3852 | } | 3852 | } |
3853 | 3853 | ||
3854 | #ifdef CONFIG_SND_JACK | ||
3855 | static void stac92xx_free_jack_priv(struct snd_jack *jack) | ||
3856 | { | ||
3857 | struct sigmatel_jack *jacks = jack->private_data; | ||
3858 | jacks->nid = 0; | ||
3859 | jacks->jack = NULL; | ||
3860 | } | ||
3861 | #endif | ||
3862 | |||
3854 | static int stac92xx_add_jack(struct hda_codec *codec, | 3863 | static int stac92xx_add_jack(struct hda_codec *codec, |
3855 | hda_nid_t nid, int type) | 3864 | hda_nid_t nid, int type) |
3856 | { | 3865 | { |
@@ -3860,6 +3869,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3860 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 3869 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3861 | int connectivity = get_defcfg_connect(def_conf); | 3870 | int connectivity = get_defcfg_connect(def_conf); |
3862 | char name[32]; | 3871 | char name[32]; |
3872 | int err; | ||
3863 | 3873 | ||
3864 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) | 3874 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) |
3865 | return 0; | 3875 | return 0; |
@@ -3876,10 +3886,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3876 | snd_hda_get_jack_connectivity(def_conf), | 3886 | snd_hda_get_jack_connectivity(def_conf), |
3877 | snd_hda_get_jack_location(def_conf)); | 3887 | snd_hda_get_jack_location(def_conf)); |
3878 | 3888 | ||
3879 | return snd_jack_new(codec->bus->card, name, type, &jack->jack); | 3889 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); |
3880 | #else | 3890 | if (err < 0) { |
3881 | return 0; | 3891 | jack->nid = 0; |
3892 | return err; | ||
3893 | } | ||
3894 | jack->jack->private_data = jack; | ||
3895 | jack->jack->private_free = stac92xx_free_jack_priv; | ||
3882 | #endif | 3896 | #endif |
3897 | return 0; | ||
3883 | } | 3898 | } |
3884 | 3899 | ||
3885 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | 3900 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, |
@@ -4064,7 +4079,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4064 | pinctl = snd_hda_codec_read(codec, nid, 0, | 4079 | pinctl = snd_hda_codec_read(codec, nid, 0, |
4065 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 4080 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
4066 | /* if PINCTL already set then skip */ | 4081 | /* if PINCTL already set then skip */ |
4067 | if (!(pinctl & AC_PINCTL_IN_EN)) { | 4082 | /* Also, if both INPUT and OUTPUT are set, |
4083 | * it must be a BIOS bug; need to override, too | ||
4084 | */ | ||
4085 | if (!(pinctl & AC_PINCTL_IN_EN) || | ||
4086 | (pinctl & AC_PINCTL_OUT_EN)) { | ||
4087 | pinctl &= ~AC_PINCTL_OUT_EN; | ||
4068 | pinctl |= AC_PINCTL_IN_EN; | 4088 | pinctl |= AC_PINCTL_IN_EN; |
4069 | stac92xx_auto_set_pinctl(codec, nid, | 4089 | stac92xx_auto_set_pinctl(codec, nid, |
4070 | pinctl); | 4090 | pinctl); |
@@ -4138,8 +4158,10 @@ static void stac92xx_free_jacks(struct hda_codec *codec) | |||
4138 | if (!codec->bus->shutdown && spec->jacks.list) { | 4158 | if (!codec->bus->shutdown && spec->jacks.list) { |
4139 | struct sigmatel_jack *jacks = spec->jacks.list; | 4159 | struct sigmatel_jack *jacks = spec->jacks.list; |
4140 | int i; | 4160 | int i; |
4141 | for (i = 0; i < spec->jacks.used; i++) | 4161 | for (i = 0; i < spec->jacks.used; i++, jacks++) { |
4142 | snd_device_free(codec->bus->card, &jacks[i].jack); | 4162 | if (jacks->jack) |
4163 | snd_device_free(codec->bus->card, jacks->jack); | ||
4164 | } | ||
4143 | } | 4165 | } |
4144 | snd_array_free(&spec->jacks); | 4166 | snd_array_free(&spec->jacks); |
4145 | #endif | 4167 | #endif |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 57648810eaf1..173bebf9f51d 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -355,6 +355,9 @@ struct ichdev { | |||
355 | unsigned int fragsize1; | 355 | unsigned int fragsize1; |
356 | unsigned int position; | 356 | unsigned int position; |
357 | unsigned int pos_shift; | 357 | unsigned int pos_shift; |
358 | unsigned int last_pos; | ||
359 | unsigned long last_pos_jiffies; | ||
360 | unsigned int jiffy_to_bytes; | ||
358 | int frags; | 361 | int frags; |
359 | int lvi; | 362 | int lvi; |
360 | int lvi_frag; | 363 | int lvi_frag; |
@@ -838,7 +841,10 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd | |||
838 | ichdev->suspended = 0; | 841 | ichdev->suspended = 0; |
839 | /* fallthru */ | 842 | /* fallthru */ |
840 | case SNDRV_PCM_TRIGGER_START: | 843 | case SNDRV_PCM_TRIGGER_START: |
844 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
841 | val = ICH_IOCE | ICH_STARTBM; | 845 | val = ICH_IOCE | ICH_STARTBM; |
846 | ichdev->last_pos = ichdev->position; | ||
847 | ichdev->last_pos_jiffies = jiffies; | ||
842 | break; | 848 | break; |
843 | case SNDRV_PCM_TRIGGER_SUSPEND: | 849 | case SNDRV_PCM_TRIGGER_SUSPEND: |
844 | ichdev->suspended = 1; | 850 | ichdev->suspended = 1; |
@@ -849,9 +855,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd | |||
849 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 855 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
850 | val = ICH_IOCE; | 856 | val = ICH_IOCE; |
851 | break; | 857 | break; |
852 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
853 | val = ICH_IOCE | ICH_STARTBM; | ||
854 | break; | ||
855 | default: | 858 | default: |
856 | return -EINVAL; | 859 | return -EINVAL; |
857 | } | 860 | } |
@@ -1045,6 +1048,7 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) | |||
1045 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; | 1048 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; |
1046 | } | 1049 | } |
1047 | snd_intel8x0_setup_periods(chip, ichdev); | 1050 | snd_intel8x0_setup_periods(chip, ichdev); |
1051 | ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ; | ||
1048 | return 0; | 1052 | return 0; |
1049 | } | 1053 | } |
1050 | 1054 | ||
@@ -1053,7 +1057,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1053 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); | 1057 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
1054 | struct ichdev *ichdev = get_ichdev(substream); | 1058 | struct ichdev *ichdev = get_ichdev(substream); |
1055 | size_t ptr1, ptr; | 1059 | size_t ptr1, ptr; |
1056 | int civ, timeout = 100; | 1060 | int civ, timeout = 10; |
1057 | unsigned int position; | 1061 | unsigned int position; |
1058 | 1062 | ||
1059 | spin_lock(&chip->reg_lock); | 1063 | spin_lock(&chip->reg_lock); |
@@ -1069,9 +1073,19 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1069 | ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1073 | ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) |
1070 | break; | 1074 | break; |
1071 | } while (timeout--); | 1075 | } while (timeout--); |
1072 | ptr1 <<= ichdev->pos_shift; | 1076 | if (ptr1 != 0) { |
1073 | ptr = ichdev->fragsize1 - ptr1; | 1077 | ptr1 <<= ichdev->pos_shift; |
1074 | ptr += position; | 1078 | ptr = ichdev->fragsize1 - ptr1; |
1079 | ptr += position; | ||
1080 | ichdev->last_pos = ptr; | ||
1081 | ichdev->last_pos_jiffies = jiffies; | ||
1082 | } else { | ||
1083 | ptr1 = jiffies - ichdev->last_pos_jiffies; | ||
1084 | if (ptr1) | ||
1085 | ptr1 -= 1; | ||
1086 | ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes; | ||
1087 | ptr %= ichdev->size; | ||
1088 | } | ||
1075 | spin_unlock(&chip->reg_lock); | 1089 | spin_unlock(&chip->reg_lock); |
1076 | if (ptr >= ichdev->size) | 1090 | if (ptr >= ichdev->size) |
1077 | return 0; | 1091 | return 0; |
@@ -1840,6 +1854,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
1840 | }, | 1854 | }, |
1841 | { | 1855 | { |
1842 | .subvendor = 0x1028, | 1856 | .subvendor = 0x1028, |
1857 | .subdevice = 0x016a, | ||
1858 | .name = "Dell Inspiron 8600", /* STAC9750/51 */ | ||
1859 | .type = AC97_TUNE_HP_ONLY | ||
1860 | }, | ||
1861 | { | ||
1862 | .subvendor = 0x1028, | ||
1843 | .subdevice = 0x0186, | 1863 | .subdevice = 0x0186, |
1844 | .name = "Dell Latitude D810", /* cf. Malone #41015 */ | 1864 | .name = "Dell Latitude D810", /* cf. Malone #41015 */ |
1845 | .type = AC97_TUNE_HP_MUTE_LED | 1865 | .type = AC97_TUNE_HP_MUTE_LED |
@@ -1882,12 +1902,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
1882 | }, | 1902 | }, |
1883 | { | 1903 | { |
1884 | .subvendor = 0x103c, | 1904 | .subvendor = 0x103c, |
1885 | .subdevice = 0x0934, | ||
1886 | .name = "HP nx8220", | ||
1887 | .type = AC97_TUNE_MUTE_LED | ||
1888 | }, | ||
1889 | { | ||
1890 | .subvendor = 0x103c, | ||
1891 | .subdevice = 0x129d, | 1905 | .subdevice = 0x129d, |
1892 | .name = "HP xw8000", | 1906 | .name = "HP xw8000", |
1893 | .type = AC97_TUNE_HP_ONLY | 1907 | .type = AC97_TUNE_HP_ONLY |
@@ -2661,12 +2675,14 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2661 | struct snd_pcm_substream *subs; | 2675 | struct snd_pcm_substream *subs; |
2662 | struct ichdev *ichdev; | 2676 | struct ichdev *ichdev; |
2663 | unsigned long port; | 2677 | unsigned long port; |
2664 | unsigned long pos, t; | 2678 | unsigned long pos, pos1, t; |
2665 | struct timeval start_time, stop_time; | 2679 | int civ, timeout = 1000, attempt = 1; |
2680 | struct timespec start_time, stop_time; | ||
2666 | 2681 | ||
2667 | if (chip->ac97_bus->clock != 48000) | 2682 | if (chip->ac97_bus->clock != 48000) |
2668 | return; /* specified in module option */ | 2683 | return; /* specified in module option */ |
2669 | 2684 | ||
2685 | __again: | ||
2670 | subs = chip->pcm[0]->streams[0].substream; | 2686 | subs = chip->pcm[0]->streams[0].substream; |
2671 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { | 2687 | if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { |
2672 | snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); | 2688 | snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); |
@@ -2674,7 +2690,7 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2674 | } | 2690 | } |
2675 | ichdev = &chip->ichd[ICHD_PCMOUT]; | 2691 | ichdev = &chip->ichd[ICHD_PCMOUT]; |
2676 | ichdev->physbuf = subs->dma_buffer.addr; | 2692 | ichdev->physbuf = subs->dma_buffer.addr; |
2677 | ichdev->size = chip->ichd[ICHD_PCMOUT].fragsize = INTEL8X0_TESTBUF_SIZE; | 2693 | ichdev->size = ichdev->fragsize = INTEL8X0_TESTBUF_SIZE; |
2678 | ichdev->substream = NULL; /* don't process interrupts */ | 2694 | ichdev->substream = NULL; /* don't process interrupts */ |
2679 | 2695 | ||
2680 | /* set rate */ | 2696 | /* set rate */ |
@@ -2693,16 +2709,31 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2693 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); | 2709 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
2694 | iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); | 2710 | iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
2695 | } | 2711 | } |
2696 | do_gettimeofday(&start_time); | 2712 | do_posix_clock_monotonic_gettime(&start_time); |
2697 | spin_unlock_irq(&chip->reg_lock); | 2713 | spin_unlock_irq(&chip->reg_lock); |
2698 | msleep(50); | 2714 | msleep(50); |
2699 | spin_lock_irq(&chip->reg_lock); | 2715 | spin_lock_irq(&chip->reg_lock); |
2700 | /* check the position */ | 2716 | /* check the position */ |
2701 | pos = ichdev->fragsize1; | 2717 | do { |
2702 | pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift; | 2718 | civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV); |
2703 | pos += ichdev->position; | 2719 | pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb); |
2720 | if (pos1 == 0) { | ||
2721 | udelay(10); | ||
2722 | continue; | ||
2723 | } | ||
2724 | if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && | ||
2725 | pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | ||
2726 | break; | ||
2727 | } while (timeout--); | ||
2728 | if (pos1 == 0) { /* oops, this value is not reliable */ | ||
2729 | pos = 0; | ||
2730 | } else { | ||
2731 | pos = ichdev->fragsize1; | ||
2732 | pos -= pos1 << ichdev->pos_shift; | ||
2733 | pos += ichdev->position; | ||
2734 | } | ||
2704 | chip->in_measurement = 0; | 2735 | chip->in_measurement = 0; |
2705 | do_gettimeofday(&stop_time); | 2736 | do_posix_clock_monotonic_gettime(&stop_time); |
2706 | /* stop */ | 2737 | /* stop */ |
2707 | if (chip->device_type == DEVICE_ALI) { | 2738 | if (chip->device_type == DEVICE_ALI) { |
2708 | iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); | 2739 | iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); |
@@ -2717,22 +2748,42 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2717 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); | 2748 | iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
2718 | spin_unlock_irq(&chip->reg_lock); | 2749 | spin_unlock_irq(&chip->reg_lock); |
2719 | 2750 | ||
2751 | if (pos == 0) { | ||
2752 | snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n"); | ||
2753 | __retry: | ||
2754 | if (attempt < 3) { | ||
2755 | msleep(300); | ||
2756 | attempt++; | ||
2757 | goto __again; | ||
2758 | } | ||
2759 | goto __end; | ||
2760 | } | ||
2761 | |||
2762 | pos /= 4; | ||
2720 | t = stop_time.tv_sec - start_time.tv_sec; | 2763 | t = stop_time.tv_sec - start_time.tv_sec; |
2721 | t *= 1000000; | 2764 | t *= 1000000; |
2722 | t += stop_time.tv_usec - start_time.tv_usec; | 2765 | t += (stop_time.tv_nsec - start_time.tv_nsec) / 1000; |
2723 | printk(KERN_INFO "%s: measured %lu usecs\n", __func__, t); | 2766 | printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); |
2724 | if (t == 0) { | 2767 | if (t == 0) { |
2725 | snd_printk(KERN_ERR "?? calculation error..\n"); | 2768 | snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); |
2726 | return; | 2769 | goto __retry; |
2727 | } | 2770 | } |
2728 | pos = (pos / 4) * 1000; | 2771 | pos *= 1000; |
2729 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; | 2772 | pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; |
2730 | if (pos < 40000 || pos >= 60000) | 2773 | if (pos < 40000 || pos >= 60000) { |
2731 | /* abnormal value. hw problem? */ | 2774 | /* abnormal value. hw problem? */ |
2732 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); | 2775 | printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); |
2776 | goto __retry; | ||
2777 | } else if (pos > 40500 && pos < 41500) | ||
2778 | /* first exception - 41000Hz reference clock */ | ||
2779 | chip->ac97_bus->clock = 41000; | ||
2780 | else if (pos > 43600 && pos < 44600) | ||
2781 | /* second exception - 44100HZ reference clock */ | ||
2782 | chip->ac97_bus->clock = 44100; | ||
2733 | else if (pos < 47500 || pos > 48500) | 2783 | else if (pos < 47500 || pos > 48500) |
2734 | /* not 48000Hz, tuning the clock.. */ | 2784 | /* not 48000Hz, tuning the clock.. */ |
2735 | chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; | 2785 | chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; |
2786 | __end: | ||
2736 | printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock); | 2787 | printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock); |
2737 | snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); | 2788 | snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); |
2738 | } | 2789 | } |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 8b79969034be..7cc38a11e997 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -1238,7 +1238,8 @@ static struct snd_pcm_hardware snd_korg1212_playback_info = | |||
1238 | { | 1238 | { |
1239 | .info = (SNDRV_PCM_INFO_MMAP | | 1239 | .info = (SNDRV_PCM_INFO_MMAP | |
1240 | SNDRV_PCM_INFO_MMAP_VALID | | 1240 | SNDRV_PCM_INFO_MMAP_VALID | |
1241 | SNDRV_PCM_INFO_INTERLEAVED), | 1241 | SNDRV_PCM_INFO_INTERLEAVED | |
1242 | SNDRV_PCM_INFO_BATCH), | ||
1242 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1243 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
1243 | .rates = (SNDRV_PCM_RATE_44100 | | 1244 | .rates = (SNDRV_PCM_RATE_44100 | |
1244 | SNDRV_PCM_RATE_48000), | 1245 | SNDRV_PCM_RATE_48000), |
@@ -1258,7 +1259,8 @@ static struct snd_pcm_hardware snd_korg1212_capture_info = | |||
1258 | { | 1259 | { |
1259 | .info = (SNDRV_PCM_INFO_MMAP | | 1260 | .info = (SNDRV_PCM_INFO_MMAP | |
1260 | SNDRV_PCM_INFO_MMAP_VALID | | 1261 | SNDRV_PCM_INFO_MMAP_VALID | |
1261 | SNDRV_PCM_INFO_INTERLEAVED), | 1262 | SNDRV_PCM_INFO_INTERLEAVED | |
1263 | SNDRV_PCM_INFO_BATCH), | ||
1262 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1264 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
1263 | .rates = (SNDRV_PCM_RATE_44100 | | 1265 | .rates = (SNDRV_PCM_RATE_44100 | |
1264 | SNDRV_PCM_RATE_48000), | 1266 | SNDRV_PCM_RATE_48000), |