Strictly differentiate digital and analog PCM devices according to codec

nodes capabilities. Add "Analog"/"Digital" marks to the pcm device names.

I hope it will help new users easier accept concept of several PCM devices
and understand exact purposes of that devices.
This commit is contained in:
Alexander Motin 2008-11-23 20:03:58 +00:00
parent cc7d6b558e
commit 3a7a3fc203
2 changed files with 91 additions and 58 deletions

View File

@ -4291,6 +4291,7 @@ hdac_audio_as_parse(struct hdac_devinfo *devinfo)
for (i = 0; i < max; i++) {
as[i].hpredir = -1;
as[i].chan = -1;
as[i].digital = 1;
}
/* Scan associations skipping as=0. */
@ -4345,6 +4346,8 @@ hdac_audio_as_parse(struct hdac_devinfo *devinfo)
__func__, w->nid, j);
as[cnt].enable = 0;
}
if (!HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
as[cnt].digital = 0;
/* Headphones with seq=15 may mean redirection. */
if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
seq == 15)
@ -5075,13 +5078,8 @@ hdac_audio_bind_as(struct hdac_devinfo *devinfo)
as[j].chan = free;
devinfo->codec->sc->chans[free].as = j;
if (as[j].dir == HDA_CTL_IN) {
devinfo->codec->sc->chans[free].dir = PCMDIR_REC;
devinfo->function.audio.reccnt++;
} else {
devinfo->codec->sc->chans[free].dir = PCMDIR_PLAY;
devinfo->function.audio.playcnt++;
}
devinfo->codec->sc->chans[free].dir =
(as[j].dir == HDA_CTL_IN) ? PCMDIR_REC : PCMDIR_PLAY;
hdac_pcmchannel_setup(&devinfo->codec->sc->chans[free]);
free++;
}
@ -6213,6 +6211,82 @@ hdac_pcmchannel_setup(struct hdac_chan *ch)
return (ret);
}
static void
hdac_create_pcms(struct hdac_devinfo *devinfo)
{
struct hdac_softc *sc = devinfo->codec->sc;
struct hdac_audio_as *as = devinfo->function.audio.as;
int i, j, apdev = 0, ardev = 0, dpdev = 0, drdev = 0;
for (i = 0; i < devinfo->function.audio.ascnt; i++) {
if (as[i].enable == 0)
continue;
if (as[i].dir == HDA_CTL_IN) {
if (as[i].digital)
drdev++;
else
ardev++;
} else {
if (as[i].digital)
dpdev++;
else
apdev++;
}
}
devinfo->function.audio.num_devs =
max(ardev, apdev) + max(drdev, dpdev);
devinfo->function.audio.devs =
(struct hdac_pcm_devinfo *)malloc(
devinfo->function.audio.num_devs * sizeof(struct hdac_pcm_devinfo),
M_HDAC, M_ZERO | M_NOWAIT);
if (devinfo->function.audio.devs == NULL) {
device_printf(sc->dev,
"Unable to allocate memory for devices\n");
return;
}
for (i = 0; i < devinfo->function.audio.num_devs; i++) {
devinfo->function.audio.devs[i].index = i;
devinfo->function.audio.devs[i].devinfo = devinfo;
devinfo->function.audio.devs[i].play = -1;
devinfo->function.audio.devs[i].rec = -1;
devinfo->function.audio.devs[i].digital = 2;
}
for (i = 0; i < devinfo->function.audio.ascnt; i++) {
if (as[i].enable == 0)
continue;
for (j = 0; j < devinfo->function.audio.num_devs; j++) {
if (devinfo->function.audio.devs[j].digital != 2 &&
devinfo->function.audio.devs[j].digital !=
as[i].digital)
continue;
if (as[i].dir == HDA_CTL_IN) {
if (devinfo->function.audio.devs[j].rec >= 0)
continue;
devinfo->function.audio.devs[j].rec
= as[i].chan;
} else {
if (devinfo->function.audio.devs[j].play >= 0)
continue;
devinfo->function.audio.devs[j].play
= as[i].chan;
}
sc->chans[as[i].chan].pdevinfo =
&devinfo->function.audio.devs[j];
devinfo->function.audio.devs[j].digital =
as[i].digital;
break;
}
}
for (i = 0; i < devinfo->function.audio.num_devs; i++) {
struct hdac_pcm_devinfo *pdevinfo =
&devinfo->function.audio.devs[i];
pdevinfo->dev =
device_add_child(sc->dev, "pcm", -1);
device_set_ivars(pdevinfo->dev,
(void *)pdevinfo);
}
}
static void
hdac_dump_ctls(struct hdac_pcm_devinfo *pdevinfo, const char *banner, uint32_t flag)
{
@ -7063,7 +7137,7 @@ hdac_attach2(void *arg)
struct hdac_audio_ctl *ctl;
uint32_t quirks_on, quirks_off;
int codec_index, fg_index;
int i, pdev, rdev, dmaalloc = 0;
int i, dmaalloc = 0;
struct hdac_devinfo *devinfo;
sc = (struct hdac_softc *)arg;
@ -7245,53 +7319,10 @@ hdac_attach2(void *arg)
dmaalloc = 1;
}
i = devinfo->function.audio.playcnt;
if (devinfo->function.audio.reccnt > i)
i = devinfo->function.audio.reccnt;
devinfo->function.audio.devs =
(struct hdac_pcm_devinfo *)malloc(
sizeof(struct hdac_pcm_devinfo) * i,
M_HDAC, M_ZERO | M_NOWAIT);
if (devinfo->function.audio.devs == NULL) {
device_printf(sc->dev,
"Unable to allocate memory for devices\n");
continue;
}
devinfo->function.audio.num_devs = i;
for (i = 0; i < devinfo->function.audio.num_devs; i++) {
devinfo->function.audio.devs[i].index = i;
devinfo->function.audio.devs[i].devinfo = devinfo;
devinfo->function.audio.devs[i].play = -1;
devinfo->function.audio.devs[i].rec = -1;
}
pdev = 0;
rdev = 0;
for (i = 0; i < devinfo->function.audio.ascnt; i++) {
if (devinfo->function.audio.as[i].enable == 0)
continue;
if (devinfo->function.audio.as[i].dir ==
HDA_CTL_IN) {
devinfo->function.audio.devs[rdev].rec
= devinfo->function.audio.as[i].chan;
sc->chans[devinfo->function.audio.as[i].chan].pdevinfo =
&devinfo->function.audio.devs[rdev];
rdev++;
} else {
devinfo->function.audio.devs[pdev].play
= devinfo->function.audio.as[i].chan;
sc->chans[devinfo->function.audio.as[i].chan].pdevinfo =
&devinfo->function.audio.devs[pdev];
pdev++;
}
}
for (i = 0; i < devinfo->function.audio.num_devs; i++) {
struct hdac_pcm_devinfo *pdevinfo =
&devinfo->function.audio.devs[i];
pdevinfo->dev =
device_add_child(sc->dev, "pcm", -1);
device_set_ivars(pdevinfo->dev,
(void *)pdevinfo);
}
HDA_BOOTHVERBOSE(
device_printf(sc->dev, "Creating PCM devices...\n");
);
hdac_create_pcms(devinfo);
HDA_BOOTVERBOSE(
if (devinfo->function.audio.quirks != 0) {
@ -7636,9 +7667,10 @@ hdac_pcm_probe(device_t dev)
(struct hdac_pcm_devinfo *)device_get_ivars(dev);
char buf[128];
snprintf(buf, sizeof(buf), "HDA %s PCM #%d",
snprintf(buf, sizeof(buf), "HDA %s PCM #%d %s",
hdac_codec_name(pdevinfo->devinfo->codec),
pdevinfo->index);
pdevinfo->index,
pdevinfo->digital?"Digital":"Analog");
device_set_desc_copy(dev, buf);
return (0);
}

View File

@ -220,6 +220,7 @@ struct hdac_audio_as {
u_char dir;
u_char pincnt;
u_char fakeredir;
u_char digital;
nid_t hpredir;
nid_t pins[16];
nid_t dacs[16];
@ -236,6 +237,7 @@ struct hdac_pcm_devinfo {
u_char right[SOUND_MIXER_NRDEVICES];
int chan_size;
int chan_blkcnt;
u_char digital;
};
/****************************************************************************
@ -262,7 +264,6 @@ struct hdac_devinfo {
struct hdac_audio_as *as;
uint32_t quirks;
uint32_t gpio;
int playcnt, reccnt;
struct hdac_pcm_devinfo *devs;
int num_devs;
} audio;