From: Takashi Iwai <tiwai@suse.de>
To: Liam Girdwood <Liam.Girdwood@wolfsonmicro.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
Jeff Garzik <jgarzik@pobox.com>,
lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] AC97 support for low power codecs
Date: Tue, 04 Jan 2005 16:47:32 +0100 [thread overview]
Message-ID: <s5hacrpgprf.wl@alsa2.suse.de> (raw)
In-Reply-To: <1104852422.9143.348.camel@cearnarfon>
At Tue, 04 Jan 2005 15:27:02 +0000,
Liam Girdwood wrote:
>
> On Tue, 2005-01-04 at 15:08, Takashi Iwai wrote:
> >
> > Does writing RESET on such a codec must be avoided always?
> > Or can one power up again by writing some values on POWER register?
> >
>
> Writing RESET causes an AC97 codec to return to it's default state. On
> some codecs this is state is "power down" and therefore undesirable
> during a call to probe.
>
> The only way to wake such a codec is via an AC97 warm reset.
Understood. Thanks for explanation.
I have also a patch for ALSA about this as attached below. It's
to the very latest ALSA CVS version (and untested, of course ;)
Takashi
--- linux/include/sound/ac97_codec.h 4 Jan 2005 03:27:54 -0000 1.61
+++ linux/include/sound/ac97_codec.h 4 Jan 2005 14:43:24 -0000
@@ -366,7 +366,9 @@
#define AC97_DOUBLE_RATE (1<<5) /* supports double rate playback */
#define AC97_HAS_NO_MASTER_VOL (1<<6) /* no Master volume */
#define AC97_HAS_NO_PCM_VOL (1<<7) /* no PCM volume */
+#define AC97_DEFAULT_POWER_OFF (1<<8) /* no RESET write */
+#define AC97_MODEM_PATCH (1<<9) /* modem patch */
/* rates indexes */
#define AC97_RATES_FRONT_DAC 0
#define CONFIG_SND_DATE ""
--- linux/sound/pci/ac97/ac97_codec.c 4 Jan 2005 11:08:31 -0000 1.159
+++ linux/sound/pci/ac97/ac97_codec.c 4 Jan 2005 15:07:17 -0000
@@ -55,127 +55,128 @@
unsigned int mask;
const char *name;
int (*patch)(ac97_t *ac97);
- int (*mpatch)(ac97_t *ac97);
+ unsigned int flags;
} ac97_codec_id_t;
static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
-{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
-{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
-{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
-{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
-{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
-{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
-{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
-{ 0x44543000, 0xffffff00, "Diamond Technology", NULL, NULL },
-{ 0x454d4300, 0xffffff00, "eMicro", NULL, NULL },
-{ 0x45838300, 0xffffff00, "ESS Technology", NULL, NULL },
-{ 0x48525300, 0xffffff00, "Intersil", NULL, NULL },
-{ 0x49434500, 0xffffff00, "ICEnsemble", NULL, NULL },
-{ 0x49544500, 0xffffff00, "ITE Tech.Inc", NULL, NULL },
-{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
-{ 0x50534300, 0xffffff00, "Philips", NULL, NULL },
-{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL },
-{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL },
-{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL },
-{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL },
-{ 0x57454300, 0xffffff00, "Winbond", NULL, NULL },
-{ 0x574d4c00, 0xffffff00, "Wolfson", NULL, NULL },
-{ 0x594d4800, 0xffffff00, "Yamaha", NULL, NULL },
-{ 0x83847600, 0xffffff00, "SigmaTel", NULL, NULL },
-{ 0, 0, NULL, NULL, NULL }
+{ 0x414b4d00, 0xffffff00, "Asahi Kasei" },
+{ 0x41445300, 0xffffff00, "Analog Devices" },
+{ 0x414c4300, 0xffffff00, "Realtek" },
+{ 0x414c4700, 0xffffff00, "Realtek" },
+{ 0x434d4900, 0xffffff00, "C-Media Electronics" },
+{ 0x43525900, 0xffffff00, "Cirrus Logic" },
+{ 0x43585400, 0xffffff00, "Conexant" },
+{ 0x44543000, 0xffffff00, "Diamond Technology" },
+{ 0x454d4300, 0xffffff00, "eMicro" },
+{ 0x45838300, 0xffffff00, "ESS Technology" },
+{ 0x48525300, 0xffffff00, "Intersil" },
+{ 0x49434500, 0xffffff00, "ICEnsemble" },
+{ 0x49544500, 0xffffff00, "ITE Tech.Inc" },
+{ 0x4e534300, 0xffffff00, "National Semiconductor" },
+{ 0x50534300, 0xffffff00, "Philips" },
+{ 0x53494c00, 0xffffff00, "Silicon Laboratory" },
+{ 0x54524100, 0xffffff00, "TriTech" },
+{ 0x54584e00, 0xffffff00, "Texas Instruments" },
+{ 0x56494100, 0xffffff00, "VIA Technologies" },
+{ 0x57454300, 0xffffff00, "Winbond" },
+{ 0x574d4c00, 0xffffff00, "Wolfson" },
+{ 0x594d4800, 0xffffff00, "Yamaha" },
+{ 0x83847600, 0xffffff00, "SigmaTel" },
+{ 0 } /* terminator */
};
static const ac97_codec_id_t snd_ac97_codec_ids[] = {
-{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
-{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
-{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
-{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
-{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
-{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
-{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
-{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
-{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885, NULL },
-{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886, NULL },
-{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881, NULL },
-{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881, NULL },
-{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888, NULL },
-{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL },
-{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL },
-{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
-{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
-{ 0x414c4300, 0xffffff00, "ALC100/100P", NULL, NULL },
-{ 0x414c4710, 0xfffffff0, "ALC200/200P", NULL, NULL },
-{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
-{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
-{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
-{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
-{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
-{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
-{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
-{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
-{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
-{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
-{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
-{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
-{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
-{ 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761, NULL },
-{ 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761, NULL },
-{ 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761, NULL },
-{ 0x43525900, 0xfffffff8, "CS4297", NULL, NULL },
-{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif, NULL },
-{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif, NULL },
-{ 0x43525928, 0xfffffff8, "CS4294", NULL, NULL },
-{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299, NULL },
-{ 0x43525948, 0xfffffff8, "CS4201", NULL, NULL },
-{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif, NULL },
-{ 0x43525960, 0xfffffff8, "CS4291", NULL, NULL },
-{ 0x43525970, 0xfffffff8, "CS4202", NULL, NULL },
-{ 0x43585421, 0xffffffff, "HSD11246", NULL, NULL }, // SmartMC II
-{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant, NULL }, // SmartAMC fixme: the mask might be different
-{ 0x44543031, 0xfffffff0, "DT0398", NULL, NULL },
-{ 0x454d4328, 0xffffffff, "28028", NULL, NULL }, // same as TR28028?
-{ 0x45838308, 0xffffffff, "ESS1988", NULL, NULL },
-{ 0x48525300, 0xffffff00, "HMP9701", NULL, NULL },
-{ 0x49434501, 0xffffffff, "ICE1230", NULL, NULL },
-{ 0x49434511, 0xffffffff, "ICE1232", NULL, NULL }, // alias VIA VT1611A?
-{ 0x49434514, 0xffffffff, "ICE1232A", NULL, NULL },
-{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616, NULL },
-{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616, NULL }, // VT1616 compatible (chipset integrated)
-{ 0x49544520, 0xffffffff, "IT2226E", NULL, NULL },
-{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL },
-{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48", NULL, NULL }, // only guess --jk
-{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
-{ 0x4e534350, 0xffffffff, "LM4550", NULL, NULL },
-{ 0x50534304, 0xffffffff, "UCB1400", NULL, NULL },
-{ 0x53494c20, 0xffffffe0, "Si3036/8", NULL, mpatch_si3036 },
-{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
-{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
-{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
-{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
-{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
-{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
-{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
-{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL },
-{ 0x574d4C03, 0xffffffff, "WM9703/WM9707/WM9708/WM9717", patch_wolfson03, NULL},
-{ 0x574d4C04, 0xffffffff, "WM9704M/WM9704Q", patch_wolfson04, NULL},
-{ 0x574d4C05, 0xffffffff, "WM9705/WM9710", patch_wolfson05, NULL},
-{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
-{ 0x574d4C12, 0xffffffff, "WM9711/WM9712", patch_wolfson11, NULL},
-{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL },
-{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
-{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
-{ 0x83847600, 0xffffffff, "STAC9700/83/84", patch_sigmatel_stac9700, NULL },
-{ 0x83847604, 0xffffffff, "STAC9701/3/4/5", NULL, NULL },
-{ 0x83847605, 0xffffffff, "STAC9704", NULL, NULL },
-{ 0x83847608, 0xffffffff, "STAC9708/11", patch_sigmatel_stac9708, NULL },
-{ 0x83847609, 0xffffffff, "STAC9721/23", patch_sigmatel_stac9721, NULL },
-{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744, NULL },
-{ 0x83847650, 0xffffffff, "STAC9750/51", NULL, NULL }, // patch?
-{ 0x83847652, 0xffffffff, "STAC9752/53", NULL, NULL }, // patch?
-{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756, NULL },
-{ 0x83847658, 0xffffffff, "STAC9758/59", patch_sigmatel_stac9758, NULL },
-{ 0x83847666, 0xffffffff, "STAC9766/67", NULL, NULL }, // patch?
-{ 0, 0, NULL, NULL, NULL }
+{ 0x414b4d00, 0xffffffff, "AK4540", NULL },
+{ 0x414b4d01, 0xffffffff, "AK4542", NULL },
+{ 0x414b4d02, 0xffffffff, "AK4543", NULL },
+{ 0x414b4d06, 0xffffffff, "AK4544A", NULL },
+{ 0x414b4d07, 0xffffffff, "AK4545", NULL },
+{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819 },
+{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881 },
+{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881 },
+{ 0x41445360, 0xffffffff, "AD1885", patch_ad1885 },
+{ 0x41445361, 0xffffffff, "AD1886", patch_ad1886 },
+{ 0x41445362, 0xffffffff, "AD1887", patch_ad1881 },
+{ 0x41445363, 0xffffffff, "AD1886A", patch_ad1881 },
+{ 0x41445368, 0xffffffff, "AD1888", patch_ad1888 },
+{ 0x41445370, 0xffffffff, "AD1980", patch_ad1980 },
+{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a },
+{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b },
+{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985 },
+{ 0x414c4300, 0xffffff00, "ALC100/100P", NULL },
+{ 0x414c4710, 0xfffffff0, "ALC200/200P", NULL },
+{ 0x414c4721, 0xffffffff, "ALC650D", NULL }, /* already patched */
+{ 0x414c4722, 0xffffffff, "ALC650E", NULL }, /* already patched */
+{ 0x414c4723, 0xffffffff, "ALC650F", NULL }, /* already patched */
+{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650 },
+{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655 },
+{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655 },
+{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850 },
+{ 0x414c4730, 0xffffffff, "ALC101", NULL },
+{ 0x414c4740, 0xfffffff0, "ALC202", NULL },
+{ 0x414c4750, 0xfffffff0, "ALC250", NULL },
+{ 0x414c4770, 0xfffffff0, "ALC203", NULL },
+{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738 },
+{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739 },
+{ 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761 },
+{ 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761 },
+{ 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761 },
+{ 0x43525900, 0xfffffff8, "CS4297", NULL },
+{ 0x43525910, 0xfffffff8, "CS4297A", patch_cirrus_spdif },
+{ 0x43525920, 0xfffffff8, "CS4298", patch_cirrus_spdif },
+{ 0x43525928, 0xfffffff8, "CS4294", NULL },
+{ 0x43525930, 0xfffffff8, "CS4299", patch_cirrus_cs4299 },
+{ 0x43525948, 0xfffffff8, "CS4201", NULL },
+{ 0x43525958, 0xfffffff8, "CS4205", patch_cirrus_spdif },
+{ 0x43525960, 0xfffffff8, "CS4291", NULL },
+{ 0x43525970, 0xfffffff8, "CS4202", NULL },
+{ 0x43585421, 0xffffffff, "HSD11246", NULL }, // SmartMC II
+{ 0x43585428, 0xfffffff8, "Cx20468", patch_conexant }, // SmartAMC fixme: the mask might be different
+{ 0x44543031, 0xfffffff0, "DT0398", NULL },
+{ 0x454d4328, 0xffffffff, "28028", NULL }, // same as TR28028?
+{ 0x45838308, 0xffffffff, "ESS1988", NULL },
+{ 0x48525300, 0xffffff00, "HMP9701", NULL },
+{ 0x49434501, 0xffffffff, "ICE1230", NULL },
+{ 0x49434511, 0xffffffff, "ICE1232", NULL }, // alias VIA VT1611A?
+{ 0x49434514, 0xffffffff, "ICE1232A", NULL },
+{ 0x49434551, 0xffffffff, "VT1616", patch_vt1616 },
+{ 0x49434552, 0xffffffff, "VT1616i", patch_vt1616 }, // VT1616 compatible (chipset integrated)
+{ 0x49544520, 0xffffffff, "IT2226E", NULL },
+{ 0x49544561, 0xffffffff, "IT2646E", patch_it2646 },
+{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48", NULL }, // only guess --jk
+{ 0x4e534331, 0xffffffff, "LM4549", NULL },
+{ 0x4e534350, 0xffffffff, "LM4550", NULL },
+{ 0x50534304, 0xffffffff, "UCB1400", NULL },
+{ 0x53494c20, 0xffffffe0, "Si3036/8", mpatch_si3036, AC97_MODEM_PATCH },
+{ 0x54524102, 0xffffffff, "TR28022", NULL },
+{ 0x54524106, 0xffffffff, "TR28026", NULL },
+{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028 }, // added by xin jin [07/09/99]
+{ 0x54524123, 0xffffffff, "TR28602", NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
+{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL },
+{ 0x56494161, 0xffffffff, "VIA1612A", NULL }, // modified ICE1232 with S/PDIF
+{ 0x57454301, 0xffffffff, "W83971D", NULL },
+{ 0x574d4c00, 0xffffffff, "WM9701A", NULL },
+{ 0x574d4c03, 0xffffffff, "WM9703/WM9707/WM9708/WM9717", patch_wolfson03 },
+{ 0x574d4c04, 0xffffffff, "WM9704M/WM9704Q", patch_wolfson04 },
+{ 0x574d4c05, 0xffffffff, "WM9705/WM9710", patch_wolfson05 },
+{ 0x574d4c09, 0xffffffff, "WM9709", NULL },
+{ 0x574d4c12, 0xffffffff, "WM9711/WM9712", patch_wolfson11 },
+{ 0x574d4c13, 0xffffffff, "WM9713", patch_wolfson13, AC97_DEFAULT_POWER_OFF }, /* warm start */
+{ 0x594d4800, 0xffffffff, "YMF743", NULL },
+{ 0x594d4802, 0xffffffff, "YMF752", NULL },
+{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753 },
+{ 0x83847600, 0xffffffff, "STAC9700/83/84", patch_sigmatel_stac9700 },
+{ 0x83847604, 0xffffffff, "STAC9701/3/4/5", NULL },
+{ 0x83847605, 0xffffffff, "STAC9704", NULL },
+{ 0x83847608, 0xffffffff, "STAC9708/11", patch_sigmatel_stac9708 },
+{ 0x83847609, 0xffffffff, "STAC9721/23", patch_sigmatel_stac9721 },
+{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 },
+{ 0x83847650, 0xffffffff, "STAC9750/51", NULL }, // patch?
+{ 0x83847652, 0xffffffff, "STAC9752/53", NULL }, // patch?
+{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 },
+{ 0x83847658, 0xffffffff, "STAC9758/59", patch_sigmatel_stac9758 },
+{ 0x83847666, 0xffffffff, "STAC9766/67", NULL }, // patch?
+{ 0 } /* terminator */
};
const char *snd_ac97_stereo_enhancements[] =
@@ -1663,6 +1664,18 @@
return result;
}
+/* look for the codec id table matching with the given id */
+static const ac97_codec_id_t *look_for_codec_id(const ac97_codec_id_t *table,
+ unsigned int id)
+{
+ const ac97_codec_id_t *pid;
+
+ for (pid = table; pid->id; pid++)
+ if (pid->id == (id & pid->mask))
+ return pid;
+ return NULL;
+}
+
void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
{
const ac97_codec_id_t *pid;
@@ -1671,35 +1684,30 @@
printable(id >> 24),
printable(id >> 16),
printable(id >> 8));
- for (pid = snd_ac97_codec_id_vendors; pid->id; pid++)
- if (pid->id == (id & pid->mask)) {
- strcpy(name, pid->name);
- if (ac97) {
- if (!modem && pid->patch)
- pid->patch(ac97);
- else if (modem && pid->mpatch)
- pid->mpatch(ac97);
- }
- goto __vendor_ok;
- }
- return;
+ pid = look_for_codec_id(snd_ac97_codec_id_vendors, id);
+ if (! pid)
+ return;
- __vendor_ok:
- for (pid = snd_ac97_codec_ids; pid->id; pid++)
- if (pid->id == (id & pid->mask)) {
- strcat(name, " ");
- strcat(name, pid->name);
- if (pid->mask != 0xffffffff)
- sprintf(name + strlen(name), " rev %d", id & ~pid->mask);
- if (ac97) {
- if (!modem && pid->patch)
- pid->patch(ac97);
- else if (modem && pid->mpatch)
- pid->mpatch(ac97);
- }
- return;
+ strcpy(name, pid->name);
+ if (ac97 && pid->patch) {
+ if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
+ (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
+ pid->patch(ac97);
+ }
+
+ pid = look_for_codec_id(snd_ac97_codec_ids, id);
+ if (pid) {
+ strcat(name, " ");
+ strcat(name, pid->name);
+ if (pid->mask != 0xffffffff)
+ sprintf(name + strlen(name), " rev %d", id & ~pid->mask);
+ if (ac97 && pid->patch) {
+ if ((modem && (pid->flags & AC97_MODEM_PATCH)) ||
+ (! modem && ! (pid->flags & AC97_MODEM_PATCH)))
+ pid->patch(ac97);
}
- sprintf(name + strlen(name), " id %x", id & 0xff);
+ } else
+ sprintf(name + strlen(name), " id %x", id & 0xff);
}
/**
@@ -1838,6 +1846,7 @@
char name[64];
unsigned long end_time;
unsigned int reg;
+ const ac97_codec_id_t *pid;
static snd_device_ops_t ops = {
.dev_free = snd_ac97_dev_free,
};
@@ -1888,6 +1897,14 @@
goto __access_ok;
}
+ ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
+ ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
+ if (ac97->id && ac97->id != (unsigned int)-1) {
+ pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
+ if (pid && (pid->flags & AC97_DEFAULT_POWER_OFF))
+ goto __access_ok;
+ }
+
snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */
if (bus->ops->wait)
bus->ops->wait(ac97);
@@ -1914,6 +1931,9 @@
snd_ac97_free(ac97);
return -EIO;
}
+ pid = look_for_codec_id(snd_ac97_codec_ids, ac97->id);
+ if (pid)
+ ac97->flags |= pid->flags;
/* test for AC'97 */
if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO) && !(ac97->scaps & AC97_SCAP_AUDIO)) {
@@ -1952,10 +1972,12 @@
if (ac97_is_audio(ac97)) {
/* nothing should be in powerdown mode */
snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
- snd_ac97_write_cache(ac97, AC97_RESET, 0); /* reset to defaults */
- udelay(100);
+ if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
+ snd_ac97_write_cache(ac97, AC97_RESET, 0); /* reset to defaults */
+ udelay(100);
+ snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
+ }
/* nothing should be in powerdown mode */
- snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0);
snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
end_time = jiffies + (HZ / 10);
do {
@@ -2217,9 +2239,11 @@
}
snd_ac97_write(ac97, AC97_POWERDOWN, 0);
- snd_ac97_write(ac97, AC97_RESET, 0);
- udelay(100);
- snd_ac97_write(ac97, AC97_POWERDOWN, 0);
+ if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
+ snd_ac97_write(ac97, AC97_RESET, 0);
+ udelay(100);
+ snd_ac97_write(ac97, AC97_POWERDOWN, 0);
+ }
snd_ac97_write(ac97, AC97_GENERAL_PURPOSE, 0);
snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
--- linux/sound/pci/ac97/ac97_patch.c 4 Jan 2005 10:58:12 -0000 1.67
+++ linux/sound/pci/ac97/ac97_patch.c 4 Jan 2005 14:51:36 -0000
@@ -305,6 +305,24 @@
return 0;
}
+int patch_wolfson13(ac97_t * ac97)
+{
+ /* WM9713 */
+ static unsigned short inits[] = {
+ AC97_REC_GAIN, 0x00a0,
+ AC97_EXTENDED_MID, 0xda00,
+ AC97_EXTENDED_MSTATUS, 0x3810,
+ AC97_PHONE, 0x0808,
+ AC97_PC_BEEP, 0x0808,
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(inits); i += 2)
+ snd_ac97_write_cache(ac97, inits[0], inits[1]);
+
+ return 0;
+}
+
/*
* Tritech codec
*/
--- linux/sound/pci/ac97/ac97_patch.h 29 Sep 2004 09:44:11 -0000 1.17
+++ linux/sound/pci/ac97/ac97_patch.h 4 Jan 2005 14:43:57 -0000
@@ -28,6 +28,7 @@
int patch_wolfson04(ac97_t * ac97);
int patch_wolfson05(ac97_t * ac97);
int patch_wolfson11(ac97_t * ac97);
+int patch_wolfson13(ac97_t * ac97);
int patch_tritech_tr28028(ac97_t * ac97);
int patch_sigmatel_stac9700(ac97_t * ac97);
int patch_sigmatel_stac9708(ac97_t * ac97);
next prev parent reply other threads:[~2005-01-04 15:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-04 11:34 [PATCH] AC97 support for low power codecs Liam Girdwood
2005-01-04 15:08 ` Takashi Iwai
2005-01-04 15:27 ` Liam Girdwood
2005-01-04 15:47 ` Takashi Iwai [this message]
2005-01-04 16:24 ` Liam Girdwood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hacrpgprf.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=Liam.Girdwood@wolfsonmicro.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=jgarzik@pobox.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.