summaryrefslogtreecommitdiff
path: root/sound/pci/ens1370.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-04-11 20:44:25 (GMT)
committerDavid S. Miller <davem@davemloft.net>2011-04-11 20:44:25 (GMT)
commit1c01a80cfec6f806246f31ff2680cd3639b30e67 (patch)
tree0b554aad2ec1da71ecf6339d4ba51617bfe1dc3c /sound/pci/ens1370.c
parentc44d79950b2daa1025e62eede73e4e4a274d1ef3 (diff)
parent4a9f65f6304a00f6473e83b19c1e83caa1e42530 (diff)
downloadlinux-fsl-qoriq-1c01a80cfec6f806246f31ff2680cd3639b30e67.tar.xz
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/smsc911x.c
Diffstat (limited to 'sound/pci/ens1370.c')
-rw-r--r--sound/pci/ens1370.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 537cfba..863eafe 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -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_1371_CODEC_RDY (1<<31) /* codec ready */
#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_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0))
#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,
#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,
unsigned short reg, unsigned short val)
{
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);
for (t = 0; t < POLL_COUNT; t++) {
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,
0x00010000)
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 */
snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
unsigned short reg)
{
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:
mutex_lock(&ensoniq->src_mutex);
for (t = 0; t < POLL_COUNT; t++) {
@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
0x00010000)
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 */
snd_es1371_wait_src_ready(ensoniq);
outl(x, ES_REG(ensoniq, 1371_SMPRATE));
@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
/* now wait for the stinkin' data (RDY) */
for (t = 0; t < POLL_COUNT; t++) {
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);
return ES_1371_CODEC_READ(x);
}