提交 17fbb5bd 编写于 作者: T Takashi Iwai

Merge branch 'fix/misc' into topic/misc

...@@ -375,6 +375,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, ...@@ -375,6 +375,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
} }
if (runtime->no_period_wakeup) { if (runtime->no_period_wakeup) {
snd_pcm_sframes_t xrun_threshold;
/* /*
* Without regular period interrupts, we have to check * Without regular period interrupts, we have to check
* the elapsed time to detect xruns. * the elapsed time to detect xruns.
...@@ -383,7 +384,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, ...@@ -383,7 +384,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
if (jdelta < runtime->hw_ptr_buffer_jiffies / 2) if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
goto no_delta_check; goto no_delta_check;
hdelta = jdelta - delta * HZ / runtime->rate; hdelta = jdelta - delta * HZ / runtime->rate;
while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1;
while (hdelta > xrun_threshold) {
delta += runtime->buffer_size; delta += runtime->buffer_size;
hw_base += runtime->buffer_size; hw_base += runtime->buffer_size;
if (hw_base >= runtime->boundary) if (hw_base >= runtime->boundary)
......
...@@ -778,10 +778,9 @@ static int __devexit fwspk_remove(struct device *dev) ...@@ -778,10 +778,9 @@ static int __devexit fwspk_remove(struct device *dev)
{ {
struct fwspk *fwspk = dev_get_drvdata(dev); struct fwspk *fwspk = dev_get_drvdata(dev);
snd_card_disconnect(fwspk->card);
mutex_lock(&fwspk->mutex); mutex_lock(&fwspk->mutex);
amdtp_out_stream_pcm_abort(&fwspk->stream); amdtp_out_stream_pcm_abort(&fwspk->stream);
snd_card_disconnect(fwspk->card);
fwspk_stop_stream(fwspk); fwspk_stop_stream(fwspk);
mutex_unlock(&fwspk->mutex); mutex_unlock(&fwspk->mutex);
......
...@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); ...@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
#define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */
#define ES_1371_CODEC_RDY (1<<31) /* codec ready */ #define ES_1371_CODEC_RDY (1<<31) /* codec ready */
#define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */
#define EV_1938_CODEC_MAGIC (1<<26)
#define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */
#define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
#define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD)
...@@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, ...@@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
#ifdef CHIP1371 #ifdef CHIP1371
static inline bool is_ev1938(struct ensoniq *ensoniq)
{
return ensoniq->pci->device == 0x8938;
}
static void snd_es1371_codec_write(struct snd_ac97 *ac97, static void snd_es1371_codec_write(struct snd_ac97 *ac97,
unsigned short reg, unsigned short val) unsigned short reg, unsigned short val)
{ {
struct ensoniq *ensoniq = ac97->private_data; struct ensoniq *ensoniq = ac97->private_data;
unsigned int t, x; unsigned int t, x, flag;
flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
mutex_lock(&ensoniq->src_mutex); mutex_lock(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) { for (t = 0; t < POLL_COUNT; t++) {
if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {
...@@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, ...@@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97,
0x00010000) 0x00010000)
break; break;
} }
outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); outl(ES_1371_CODEC_WRITE(reg, val) | flag,
ES_REG(ensoniq, 1371_CODEC));
/* restore SRC reg */ /* restore SRC reg */
snd_es1371_wait_src_ready(ensoniq); snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE)); outl(x, ES_REG(ensoniq, 1371_SMPRATE));
...@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, ...@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
unsigned short reg) unsigned short reg)
{ {
struct ensoniq *ensoniq = ac97->private_data; struct ensoniq *ensoniq = ac97->private_data;
unsigned int t, x, fail = 0; unsigned int t, x, flag, fail = 0;
flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0;
__again: __again:
mutex_lock(&ensoniq->src_mutex); mutex_lock(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) { for (t = 0; t < POLL_COUNT; t++) {
...@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, ...@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
0x00010000) 0x00010000)
break; break;
} }
outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); outl(ES_1371_CODEC_READS(reg) | flag,
ES_REG(ensoniq, 1371_CODEC));
/* restore SRC reg */ /* restore SRC reg */
snd_es1371_wait_src_ready(ensoniq); snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE)); outl(x, ES_REG(ensoniq, 1371_SMPRATE));
...@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, ...@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
/* now wait for the stinkin' data (RDY) */ /* now wait for the stinkin' data (RDY) */
for (t = 0; t < POLL_COUNT; t++) { for (t = 0; t < POLL_COUNT; t++) {
if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {
if (is_ev1938(ensoniq)) {
for (t = 0; t < 100; t++)
inl(ES_REG(ensoniq, CONTROL));
x = inl(ES_REG(ensoniq, 1371_CODEC));
}
mutex_unlock(&ensoniq->src_mutex); mutex_unlock(&ensoniq->src_mutex);
return ES_1371_CODEC_READ(x); return ES_1371_CODEC_READ(x);
} }
......
...@@ -3034,6 +3034,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { ...@@ -3034,6 +3034,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
{} {}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册