Make variable rate AC97 codecs use a min/max rate
This commit is contained in:
@@ -110,7 +110,7 @@ typedef struct {
|
|||||||
} ac97_vendor_reg_t;
|
} ac97_vendor_reg_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t vendor_id, max_rate, misc_flags;
|
uint32_t vendor_id, min_rate, max_rate, misc_flags;
|
||||||
uint16_t reset_flags, extid_flags,
|
uint16_t reset_flags, extid_flags,
|
||||||
powerdown_mask, regs[64];
|
powerdown_mask, regs[64];
|
||||||
uint8_t codec_id, vendor_reg_page_max;
|
uint8_t codec_id, vendor_reg_page_max;
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const uint32_t vendor_id, max_rate, misc_flags; /* definitions for misc_flags in snd_ac97.h */
|
const uint32_t vendor_id, min_rate, max_rate, misc_flags; /* definitions for misc_flags in snd_ac97.h */
|
||||||
const uint16_t reset_flags, extid_flags, /* definitions in snd_ac97.h */
|
const uint16_t reset_flags, extid_flags, /* definitions in snd_ac97.h */
|
||||||
powerdown_mask; /* bits [7:0] => register 26 bits [15:8]; bits [11:8] => register 2A bits [14:11] */
|
powerdown_mask; /* bits [7:0] => register 26 bits [15:8]; bits [11:8] => register 2A bits [14:11] */
|
||||||
const ac97_vendor_reg_t *vendor_regs; /* bits [11:8] of index are the page number if applicable (registers [60:6F]) */
|
const ac97_vendor_reg_t *vendor_regs; /* bits [11:8] of index are the page number if applicable (registers [60:6F]) */
|
||||||
@@ -35,16 +35,17 @@ static const struct {
|
|||||||
} ac97_codecs[] = {
|
} ac97_codecs[] = {
|
||||||
[AC97_CODEC_AD1881] = {
|
[AC97_CODEC_AD1881] = {
|
||||||
.vendor_id = AC97_VENDOR_ID('A', 'D', 'S', 0x40),
|
.vendor_id = AC97_VENDOR_ID('A', 'D', 'S', 0x40),
|
||||||
|
.min_rate = 7000,
|
||||||
.max_rate = 48000,
|
.max_rate = 48000,
|
||||||
.misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */
|
.reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */
|
||||||
.extid_flags = AC97_VRA,
|
.extid_flags = AC97_VRA,
|
||||||
.powerdown_mask = 0x0bf,
|
.powerdown_mask = 0x0bf,
|
||||||
|
.vendor_regs = (const ac97_vendor_reg_t[]) {{0x74, 0x0000, 0xff07}, {0x76, 0x0404, 0xdde5}, {0x78, 48000, 0x0000}, {0x7a, 48000, 0x0000}, {0}},
|
||||||
.device = &ad1881_device
|
.device = &ad1881_device
|
||||||
},
|
},
|
||||||
[AC97_CODEC_ALC100] = {
|
[AC97_CODEC_ALC100] = {
|
||||||
.vendor_id = AC97_VENDOR_ID('A', 'L', 'C', 0x20),
|
.vendor_id = AC97_VENDOR_ID('A', 'L', 'C', 0x20),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = (22 << AC97_3D_SHIFT),
|
.reset_flags = (22 << AC97_3D_SHIFT),
|
||||||
.extid_flags = AC97_AMAP,
|
.extid_flags = AC97_AMAP,
|
||||||
@@ -53,7 +54,6 @@ static const struct {
|
|||||||
},
|
},
|
||||||
[AC97_CODEC_CS4297] = {
|
[AC97_CODEC_CS4297] = {
|
||||||
.vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x03),
|
.vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x03),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B,
|
.reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B,
|
||||||
.extid_flags = 0,
|
.extid_flags = 0,
|
||||||
@@ -63,7 +63,6 @@ static const struct {
|
|||||||
},
|
},
|
||||||
[AC97_CODEC_CS4297A] = {
|
[AC97_CODEC_CS4297A] = {
|
||||||
.vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x11),
|
.vendor_id = AC97_VENDOR_ID('C', 'R', 'Y', 0x11),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT),
|
.reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT),
|
||||||
.extid_flags = AC97_AMAP,
|
.extid_flags = AC97_AMAP,
|
||||||
@@ -73,7 +72,6 @@ static const struct {
|
|||||||
},
|
},
|
||||||
[AC97_CODEC_STAC9708] = {
|
[AC97_CODEC_STAC9708] = {
|
||||||
.vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08),
|
.vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B,
|
.reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B,
|
||||||
.extid_flags = AC97_SDAC,
|
.extid_flags = AC97_SDAC,
|
||||||
@@ -83,7 +81,6 @@ static const struct {
|
|||||||
},
|
},
|
||||||
[AC97_CODEC_STAC9721] = {
|
[AC97_CODEC_STAC9721] = {
|
||||||
.vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09),
|
.vendor_id = AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B,
|
.reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B,
|
||||||
.extid_flags = AC97_AMAP,
|
.extid_flags = AC97_AMAP,
|
||||||
@@ -93,7 +90,6 @@ static const struct {
|
|||||||
},
|
},
|
||||||
[AC97_CODEC_WM9701A] = {
|
[AC97_CODEC_WM9701A] = {
|
||||||
.vendor_id = AC97_VENDOR_ID('W', 'M', 'L', 0x00),
|
.vendor_id = AC97_VENDOR_ID('W', 'M', 'L', 0x00),
|
||||||
.max_rate = 48000,
|
|
||||||
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||||
.reset_flags = AC97_DAC_18B | AC97_ADC_18B,
|
.reset_flags = AC97_DAC_18B | AC97_ADC_18B,
|
||||||
.extid_flags = 0,
|
.extid_flags = 0,
|
||||||
@@ -331,8 +327,10 @@ rate: /* Writable only if VRA/VRM is set. */
|
|||||||
if (!(dev->extid_flags & i))
|
if (!(dev->extid_flags & i))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Limit to maximum rate. */
|
/* Limit to supported sample rate range. */
|
||||||
if (val > dev->max_rate)
|
if (val < dev->min_rate)
|
||||||
|
val = dev->min_rate;
|
||||||
|
else if (val > dev->max_rate)
|
||||||
val = dev->max_rate;
|
val = dev->max_rate;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -561,6 +559,7 @@ ac97_codec_init(const device_t *info)
|
|||||||
memset(dev, 0, sizeof(ac97_codec_t));
|
memset(dev, 0, sizeof(ac97_codec_t));
|
||||||
|
|
||||||
dev->vendor_id = ac97_codecs[info->local].vendor_id;
|
dev->vendor_id = ac97_codecs[info->local].vendor_id;
|
||||||
|
dev->min_rate = ac97_codecs[info->local].min_rate;
|
||||||
dev->max_rate = ac97_codecs[info->local].max_rate;
|
dev->max_rate = ac97_codecs[info->local].max_rate;
|
||||||
dev->extid_flags = ac97_codecs[info->local].extid_flags;
|
dev->extid_flags = ac97_codecs[info->local].extid_flags;
|
||||||
dev->misc_flags = ac97_codecs[info->local].misc_flags;
|
dev->misc_flags = ac97_codecs[info->local].misc_flags;
|
||||||
|
Reference in New Issue
Block a user