Index: ac97.c =================================================================== RCS file: /space2/ncvs/src/sys/dev/sound/pcm/ac97.c,v retrieving revision 1.51 diff -u -p -r1.51 ac97.c --- ac97.c 8 May 2004 03:41:40 -0000 1.51 +++ ac97.c 18 Oct 2004 00:38:25 -0000 @@ -155,8 +155,11 @@ static struct ac97_codecid ac97codecid[] { 0x43525940, 0x07, 0, "CS4201", 0 }, { 0x43525958, 0x07, 0, "CS4205", 0 }, { 0x43525960, 0x07, 0, "CS4291A", 0 }, - { 0x434d4961, 0x00, 0, "CMI9739", 0 }, { 0x434d4941, 0x00, 0, "CMI9738", 0 }, + { 0x434d4961, 0x00, 0, "CMI9739", 0 }, + { 0x434d4978, 0x00, 0, "CMI9761", cm9761_patch }, + { 0x434d4982, 0x00, 0, "CMI9761", cm9761_patch }, + { 0x434d4983, 0x00, 0, "CMI9761", cm9761_patch }, { 0x43585421, 0x00, 0, "HSD11246", 0 }, { 0x43585428, 0x07, 0, "CX20468", 0 }, { 0x44543000, 0x00, 0, "DT0398", 0 }, @@ -370,6 +373,18 @@ ac97_getcaps(struct ac97_info *codec) return codec->caps; } +u_int32_t +ac97_getid(struct ac97_info *codec) +{ + return codec->id; +} + +device_t +ac97_getdev(struct ac97_info *codec) +{ + return codec->dev; +} + static int ac97_setrecsrc(struct ac97_info *codec, int channel) { Index: ac97.h =================================================================== RCS file: /space2/ncvs/src/sys/dev/sound/pcm/ac97.h,v retrieving revision 1.15 diff -u -p -r1.15 ac97.h --- ac97.h 7 Sep 2003 16:28:03 -0000 1.15 +++ ac97.h 18 Oct 2004 00:40:19 -0000 @@ -55,6 +55,7 @@ #define AC97_MIX_MGAIN 0x1e #define AC97_REG_GEN 0x20 #define AC97_REG_3D 0x22 +#define AC97_INT_PAGING 0x24 #define AC97_REG_POWER 0x26 #define AC97_POWER_ADC (1 << 0) #define AC97_POWER_DAC (1 << 1) @@ -100,6 +101,8 @@ int ac97_setextmode(struct ac97_info *co u_int16_t ac97_getextmode(struct ac97_info *codec); u_int16_t ac97_getextcaps(struct ac97_info *codec); u_int16_t ac97_getcaps(struct ac97_info *codec); +u_int32_t ac97_getid(struct ac97_info *codec); +device_t ac97_getdev(struct ac97_info *codec); u_int16_t ac97_rdcd(struct ac97_info *codec, int reg); void ac97_wrcd(struct ac97_info *codec, int reg, u_int16_t val); Index: ac97_patch.c =================================================================== RCS file: /space2/ncvs/src/sys/dev/sound/pcm/ac97_patch.c,v retrieving revision 1.2 diff -u -p -r1.2 ac97_patch.c --- ac97_patch.c 21 Aug 2003 15:44:55 -0000 1.2 +++ ac97_patch.c 18 Oct 2004 00:39:21 -0000 @@ -46,3 +46,40 @@ void ad198x_patch(struct ac97_info* code ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0420); } +#define AC97_CM9761_MULTI_CHAN 0x64 +#define AC97_CM9761_SPDIF_CTRL 0x6c + +void cm9761_patch(struct ac97_info* codec) +{ + device_t dev; + int revb; + uint16_t val, tmp; + + dev = ac97_getdev(codec); + if ((ac97_getid(codec) & 0x000000ff) == 0x82) { + device_printf(dev, "Enabling workaround for CMI9761 0x82\n"); + val = ac97_rdcd(codec, AC97_INT_PAGING); + ac97_wrcd(codec, AC97_INT_PAGING, (val & ~0x0f) | 0x01); + tmp = ac97_rdcd(codec, 0x60); + revb = tmp & 1; + if (revb) + device_printf(dev, "CMI9761 revision B\n"); + ac97_wrcd(codec, AC97_INT_PAGING, val); + } + + /* To be sure, we overwrite the ext status bits. */ + ac97_wrcd(codec, AC97_REGEXT_STAT, 0x05c0); + ac97_wrcd(codec, AC97_CM9761_SPDIF_CTRL, 0x0209); + +#if 0 + if (revb) + val = 0x0214; + else + val = 0x321c; + ac97_wrcd(codec, AC97_CM9761_MULTI_CHAN, val); +#endif + + /* XXX - Set up GPIO. */ + ac97_wrcd(codec, 0x70, 0x0100); + ac97_wrcd(codec, 0x72, 0x0020); +} Index: ac97_patch.h =================================================================== RCS file: /space2/ncvs/src/sys/dev/sound/pcm/ac97_patch.h,v retrieving revision 1.2 diff -u -p -r1.2 ac97_patch.h --- ac97_patch.h 21 Aug 2003 15:44:55 -0000 1.2 +++ ac97_patch.h 16 Oct 2004 23:25:57 -0000 @@ -29,3 +29,4 @@ typedef void (*ac97_patch)(struct ac97_i void ad1886_patch(struct ac97_info*); void ad198x_patch(struct ac97_info*); +void cm9761_patch(struct ac97_info*);