Add ioctls required by hdaudioctl. This involves some refactoring of the
hdaudio_afg ioctl code.
This commit is contained in:
parent
1a79cac984
commit
6c11da0940
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudio.c,v 1.4 2009/09/07 16:35:02 jmcneill Exp $ */
|
||||
/* $NetBSD: hdaudio.c,v 1.5 2009/10/11 08:50:11 sborrill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4 2009/09/07 16:35:02 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.5 2009/10/11 08:50:11 sborrill Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -1339,6 +1339,48 @@ hdaudioioctl_fgrp_setconfig(struct hdaudio_softc *sc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hdaudio_dispatch_fgrp_ioctl(struct hdaudio_softc *sc, u_long cmd,
|
||||
prop_dictionary_t request, prop_dictionary_t response)
|
||||
{
|
||||
struct hdaudio_function_group *fg;
|
||||
int16_t codecid, nid;
|
||||
void *fgrp_sc;
|
||||
int err;
|
||||
|
||||
if (!prop_dictionary_get_int16(request, "codecid", &codecid) ||
|
||||
!prop_dictionary_get_int16(request, "nid", &nid))
|
||||
return EINVAL;
|
||||
|
||||
fg = hdaudioioctl_fgrp_lookup(sc, codecid, nid);
|
||||
if (fg == NULL)
|
||||
return ENODEV;
|
||||
fgrp_sc = device_private(fg->fg_device);
|
||||
|
||||
switch (fg->fg_type) {
|
||||
case HDAUDIO_GROUP_TYPE_AFG:
|
||||
switch (cmd) {
|
||||
case HDAUDIO_FGRP_CODEC_INFO:
|
||||
err = hdaudio_afg_codec_info(fgrp_sc,
|
||||
request, response);
|
||||
break;
|
||||
case HDAUDIO_FGRP_WIDGET_INFO:
|
||||
err = hdaudio_afg_widget_info(fgrp_sc,
|
||||
request, response);
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
hdaudioopen(dev_t dev, int flag, int mode, struct lwp *l)
|
||||
{
|
||||
|
@ -1389,6 +1431,10 @@ hdaudioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
|
|||
case HDAUDIO_FGRP_SETCONFIG:
|
||||
err = hdaudioioctl_fgrp_setconfig(sc, request, response);
|
||||
break;
|
||||
case HDAUDIO_FGRP_CODEC_INFO:
|
||||
case HDAUDIO_FGRP_WIDGET_INFO:
|
||||
err = hdaudio_dispatch_fgrp_ioctl(sc, cmd, request, response);
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudio_afg.c,v 1.16 2009/09/29 15:58:54 sborrill Exp $ */
|
||||
/* $NetBSD: hdaudio_afg.c,v 1.17 2009/10/11 08:50:11 sborrill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -60,7 +60,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.16 2009/09/29 15:58:54 sborrill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.17 2009/10/11 08:50:11 sborrill Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -3644,19 +3644,71 @@ hdaudio_afg_trigger_input(void *opaque, void *start, void *end, int blksize,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hdaudio_afg_widget_info(void *opaque, prop_dictionary_t request,
|
||||
prop_dictionary_t response)
|
||||
{
|
||||
struct hdaudio_afg_softc *sc = opaque;
|
||||
struct hdaudio_widget *w;
|
||||
prop_array_t connlist;
|
||||
uint32_t config, wcap;
|
||||
uint16_t index;
|
||||
int nid;
|
||||
int i;
|
||||
|
||||
if (prop_dictionary_get_uint16(request, "index", &index) == false)
|
||||
return EINVAL;
|
||||
|
||||
nid = sc->sc_startnode + index;
|
||||
if (nid >= sc->sc_endnode)
|
||||
return EINVAL;
|
||||
|
||||
w = hdaudio_afg_widget_lookup(sc, nid);
|
||||
if (w == NULL)
|
||||
return ENXIO;
|
||||
wcap = hda_get_wparam(w, PIN_CAPABILITIES);
|
||||
config = hdaudio_command(sc->sc_codec, w->w_nid,
|
||||
CORB_GET_CONFIGURATION_DEFAULT, 0);
|
||||
prop_dictionary_set_cstring_nocopy(response, "name", w->w_name);
|
||||
prop_dictionary_set_bool(response, "enable", w->w_enable);
|
||||
prop_dictionary_set_uint8(response, "nid", w->w_nid);
|
||||
prop_dictionary_set_uint8(response, "type", w->w_type);
|
||||
prop_dictionary_set_uint32(response, "config", config);
|
||||
prop_dictionary_set_uint32(response, "cap", wcap);
|
||||
if (w->w_nconns == 0)
|
||||
return 0;
|
||||
connlist = prop_array_create();
|
||||
for (i = 0; i < w->w_nconns; i++) {
|
||||
if (w->w_conns[i] == 0)
|
||||
continue;
|
||||
prop_array_add(connlist,
|
||||
prop_number_create_unsigned_integer(w->w_conns[i]));
|
||||
}
|
||||
prop_dictionary_set(response, "connlist", connlist);
|
||||
prop_object_release(connlist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hdaudio_afg_codec_info(void *opaque, prop_dictionary_t request,
|
||||
prop_dictionary_t response)
|
||||
{
|
||||
struct hdaudio_afg_softc *sc = opaque;
|
||||
prop_dictionary_set_uint16(response, "vendor-id",
|
||||
sc->sc_vendor);
|
||||
prop_dictionary_set_uint16(response, "product-id",
|
||||
sc->sc_product);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hdaudio_afg_dev_ioctl(void *opaque, u_long cmd, void *addr, int flag, lwp_t *l)
|
||||
{
|
||||
struct hdaudio_audiodev *ad = opaque;
|
||||
struct hdaudio_afg_softc *sc = ad->ad_sc;
|
||||
struct plistref *pref = addr;
|
||||
struct hdaudio_widget *w;
|
||||
prop_dictionary_t request, response;
|
||||
prop_array_t connlist;
|
||||
uint32_t config, wcap;
|
||||
uint16_t index;
|
||||
int err, nid;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
response = prop_dictionary_create();
|
||||
if (response == NULL)
|
||||
|
@ -3667,60 +3719,22 @@ hdaudio_afg_dev_ioctl(void *opaque, u_long cmd, void *addr, int flag, lwp_t *l)
|
|||
prop_object_release(response);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (prop_dictionary_get_uint16(request, "index", &index) == false) {
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nid = sc->sc_startnode + index;
|
||||
if (nid >= sc->sc_endnode) {
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
switch (cmd) {
|
||||
case HDAUDIO_AFG_WIDGET_INFO:
|
||||
w = hdaudio_afg_widget_lookup(sc, nid);
|
||||
if (w == NULL) {
|
||||
err = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
wcap = hda_get_wparam(w, PIN_CAPABILITIES);
|
||||
config = hdaudio_command(sc->sc_codec, w->w_nid,
|
||||
CORB_GET_CONFIGURATION_DEFAULT, 0);
|
||||
prop_dictionary_set_cstring_nocopy(response, "name", w->w_name);
|
||||
prop_dictionary_set_bool(response, "enable", w->w_enable);
|
||||
prop_dictionary_set_uint8(response, "nid", w->w_nid);
|
||||
prop_dictionary_set_uint8(response, "type", w->w_type);
|
||||
prop_dictionary_set_uint32(response, "config", config);
|
||||
prop_dictionary_set_uint32(response, "cap", wcap);
|
||||
if (w->w_nconns == 0)
|
||||
break;
|
||||
connlist = prop_array_create();
|
||||
for (i = 0; i < w->w_nconns; i++) {
|
||||
if (w->w_conns[i] == 0)
|
||||
continue;
|
||||
prop_array_add(connlist,
|
||||
prop_number_create_unsigned_integer(w->w_conns[i]));
|
||||
}
|
||||
prop_dictionary_set(response, "connlist", connlist);
|
||||
prop_object_release(connlist);
|
||||
err = hdaudio_afg_widget_info(sc, request, response);
|
||||
break;
|
||||
case HDAUDIO_AFG_CODEC_INFO:
|
||||
prop_dictionary_set_uint16(response, "vendor-id",
|
||||
sc->sc_vendor);
|
||||
prop_dictionary_set_uint16(response, "product-id",
|
||||
sc->sc_product);
|
||||
err = hdaudio_afg_codec_info(sc, request, response);
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
err = prop_dictionary_copyout_ioctl(pref, cmd, response);
|
||||
if (!err)
|
||||
err = prop_dictionary_copyout_ioctl(pref, cmd, response);
|
||||
|
||||
out:
|
||||
if (response)
|
||||
prop_object_release(response);
|
||||
prop_object_release(request);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudioio.h,v 1.2 2009/09/06 17:33:53 sborrill Exp $ */
|
||||
/* $NetBSD: hdaudioio.h,v 1.3 2009/10/11 08:50:12 sborrill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -38,6 +38,8 @@
|
|||
#define HDAUDIO_FGRP_INFO _IOWR('h', 0, struct plistref)
|
||||
#define HDAUDIO_FGRP_GETCONFIG _IOWR('h', 1, struct plistref)
|
||||
#define HDAUDIO_FGRP_SETCONFIG _IOWR('h', 2, struct plistref)
|
||||
#define HDAUDIO_FGRP_WIDGET_INFO _IOWR('h', 3, struct plistref)
|
||||
#define HDAUDIO_FGRP_CODEC_INFO _IOWR('h', 4, struct plistref)
|
||||
|
||||
#define HDAUDIO_AFG_WIDGET_INFO _IOWR('H', 0, struct plistref)
|
||||
#define HDAUDIO_AFG_CODEC_INFO _IOWR('H', 1, struct plistref)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudiovar.h,v 1.4 2009/09/07 16:21:08 jmcneill Exp $ */
|
||||
/* $NetBSD: hdaudiovar.h,v 1.5 2009/10/11 08:50:12 sborrill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -178,4 +178,7 @@ void hdaudio_stream_reset(struct hdaudio_stream *);
|
|||
int hdaudio_stream_tag(struct hdaudio_stream *);
|
||||
uint16_t hdaudio_stream_param(struct hdaudio_stream *, const audio_params_t *);
|
||||
|
||||
int hdaudio_afg_widget_info(void *, prop_dictionary_t, prop_dictionary_t);
|
||||
int hdaudio_afg_codec_info(void *, prop_dictionary_t, prop_dictionary_t);
|
||||
|
||||
#endif /* !_HDAUDIOVAR_H */
|
||||
|
|
Loading…
Reference in New Issue