mirror of https://github.com/ericonr/sndio.git
Allow alternate devices to be switched with sndioctl
This commit is contained in:
parent
2494f95430
commit
9a446c6b72
43
sndiod/dev.c
43
sndiod/dev.c
|
@ -68,6 +68,7 @@ int dev_init(struct dev *);
|
|||
void dev_done(struct dev *);
|
||||
struct dev *dev_bynum(int);
|
||||
void dev_del(struct dev *);
|
||||
void dev_setalt(struct dev *, unsigned int);
|
||||
unsigned int dev_roundof(struct dev *, unsigned int);
|
||||
void dev_wakeup(struct dev *);
|
||||
void dev_sync_attach(struct dev *);
|
||||
|
@ -1088,6 +1089,30 @@ dev_addname(struct dev *d, char *name)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* set prefered alt device name
|
||||
*/
|
||||
void
|
||||
dev_setalt(struct dev *d, unsigned int idx)
|
||||
{
|
||||
struct dev_alt **pa, *a;
|
||||
|
||||
/* find alt with given index */
|
||||
for (pa = &d->alt_list; (a = *pa)->idx != idx; pa = &a->next)
|
||||
;
|
||||
|
||||
/* detach from list */
|
||||
*pa = a->next;
|
||||
|
||||
/* attach at head */
|
||||
a->next = d->alt_list;
|
||||
d->alt_list = a;
|
||||
|
||||
/* reopen device with the new alt */
|
||||
if (idx != d->alt_num)
|
||||
dev_reopen(d);
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust device parameters and mode
|
||||
*/
|
||||
|
@ -1177,6 +1202,7 @@ dev_open(struct dev *d)
|
|||
{
|
||||
int i;
|
||||
char name[CTL_NAMEMAX];
|
||||
struct dev_alt *a;
|
||||
|
||||
d->master_enabled = 0;
|
||||
d->mode = d->reqmode;
|
||||
|
@ -1210,6 +1236,15 @@ dev_open(struct dev *d)
|
|||
NULL, -1, 127, d->slot[i].vol);
|
||||
}
|
||||
|
||||
for (a = d->alt_list; a != NULL; a = a->next) {
|
||||
/* XXX: may already exist, move to hw/ group ? */
|
||||
snprintf(name, sizeof(name), "%d", a->idx);
|
||||
dev_addctl(d, "", CTL_SEL,
|
||||
CTLADDR_ALT_SEL + a->idx,
|
||||
"device", -1, "select",
|
||||
name, -1, 1, a->idx == d->alt_num);
|
||||
}
|
||||
|
||||
d->pstate = DEV_INIT;
|
||||
return 1;
|
||||
}
|
||||
|
@ -2473,7 +2508,13 @@ dev_setctl(struct dev *d, int addr, int val)
|
|||
c->dirty = 1;
|
||||
dev_ref(d);
|
||||
} else {
|
||||
if (addr == CTLADDR_MASTER) {
|
||||
if (addr >= CTLADDR_ALT_SEL) {
|
||||
if (val) {
|
||||
num = addr - CTLADDR_ALT_SEL;
|
||||
dev_setalt(d, num);
|
||||
}
|
||||
return 1;
|
||||
} else if (addr == CTLADDR_MASTER) {
|
||||
if (d->master_enabled) {
|
||||
dev_master(d, val);
|
||||
dev_midi_master(d);
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#define CTLADDR_SLOT_LEVEL(n) (n)
|
||||
#define CTLADDR_MASTER (DEV_NSLOT)
|
||||
#define CTLADDR_END (DEV_NSLOT + 1)
|
||||
#define CTLADDR_ALT_SEL (CTLADDR_MASTER + 1)
|
||||
#define CTLADDR_END (CTLADDR_ALT_SEL + DEV_NMAX)
|
||||
|
||||
/*
|
||||
* audio stream state structure
|
||||
|
|
|
@ -95,7 +95,8 @@ dev_sio_openlist(struct dev *d, unsigned int mode, struct sioctl_hdl **rctlhdl)
|
|||
struct dev_alt *n;
|
||||
struct sio_hdl *hdl;
|
||||
struct sioctl_hdl *ctlhdl;
|
||||
int idx;
|
||||
struct ctl *c;
|
||||
int val;
|
||||
|
||||
for (n = d->alt_list; n != NULL; n = n->next) {
|
||||
if (d->alt_num == n->idx)
|
||||
|
@ -117,6 +118,17 @@ dev_sio_openlist(struct dev *d, unsigned int mode, struct sioctl_hdl **rctlhdl)
|
|||
}
|
||||
}
|
||||
d->alt_num = n->idx;
|
||||
for (c = d->ctl_list; c != NULL; c = c->next) {
|
||||
if (c->addr < CTLADDR_ALT_SEL ||
|
||||
c->addr >= CTLADDR_ALT_SEL + DEV_NMAX)
|
||||
continue;
|
||||
val = (c->addr - CTLADDR_ALT_SEL) == n->idx;
|
||||
if (c->curval == val)
|
||||
continue;
|
||||
c->curval = val;
|
||||
if (val)
|
||||
c->val_mask = ~0U;
|
||||
}
|
||||
*rctlhdl = ctlhdl;
|
||||
return hdl;
|
||||
}
|
||||
|
|
|
@ -196,6 +196,11 @@ PCI device allows
|
|||
.Nm
|
||||
to use the USB one preferably when it's connected
|
||||
and to fall back to the PCI one when it's disconnected.
|
||||
Alternate devices may be switched with the
|
||||
.Va device.select
|
||||
control of the
|
||||
.Xr sndioctl 1
|
||||
utility.
|
||||
.It Fl f Ar device
|
||||
Add this
|
||||
.Xr sndio 7
|
||||
|
|
Loading…
Reference in New Issue