[ALSA] hda-intel - Add hwdep interface
Added a hwdep interface for each codec (enabled per kconfig). This interface can be used for reading/writing HD-audio verbs and other purposes as future extensions. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
ef5fa1a49f
commit
2807314d46
@ -92,6 +92,7 @@ enum {
|
|||||||
SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */
|
SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */
|
||||||
SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
|
SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
|
||||||
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
|
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
|
||||||
|
SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
|
||||||
|
|
||||||
/* Don't forget to change the following: */
|
/* Don't forget to change the following: */
|
||||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
|
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
|
||||||
|
44
include/sound/hda_hwdep.h
Normal file
44
include/sound/hda_hwdep.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* HWDEP Interface for HD-audio codec
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
|
||||||
|
*
|
||||||
|
* This driver is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This driver is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SOUND_HDA_HWDEP_H
|
||||||
|
#define __SOUND_HDA_HWDEP_H
|
||||||
|
|
||||||
|
#define HDA_HWDEP_VERSION ((1 << 16) | (0 << 8) | (0 << 0)) /* 1.0.0 */
|
||||||
|
|
||||||
|
/* verb */
|
||||||
|
#define HDA_REG_NID_SHIFT 24
|
||||||
|
#define HDA_REG_VERB_SHIFT 8
|
||||||
|
#define HDA_REG_VAL_SHIFT 0
|
||||||
|
#define HDA_VERB(nid,verb,param) ((nid)<<24 | (verb)<<8 | (param))
|
||||||
|
|
||||||
|
struct hda_verb_ioctl {
|
||||||
|
u32 verb; /* HDA_VERB() */
|
||||||
|
u32 res; /* response */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ioctls
|
||||||
|
*/
|
||||||
|
#define HDA_IOCTL_PVERSION _IOR('H', 0x10, int)
|
||||||
|
#define HDA_IOCTL_VERB_WRITE _IOWR('H', 0x11, struct hda_verb_ioctl)
|
||||||
|
#define HDA_IOCTL_GET_WCAP _IOWR('H', 0x12, struct hda_verb_ioctl)
|
||||||
|
|
||||||
|
#endif
|
@ -500,6 +500,15 @@ config SND_HDA_INTEL
|
|||||||
To compile this driver as a module, choose M here: the module
|
To compile this driver as a module, choose M here: the module
|
||||||
will be called snd-hda-intel.
|
will be called snd-hda-intel.
|
||||||
|
|
||||||
|
config SND_HDA_HWDEP
|
||||||
|
bool "Build hwdep interface for HD-audio driver"
|
||||||
|
depends on SND_HDA_INTEL
|
||||||
|
select SND_HWDEP
|
||||||
|
help
|
||||||
|
Say Y here to build a hwdep interface for HD-audio driver.
|
||||||
|
This interface can be used for out-of-bound communication
|
||||||
|
with codesc for debugging purposes.
|
||||||
|
|
||||||
config SND_HDSP
|
config SND_HDSP
|
||||||
tristate "RME Hammerfall DSP Audio"
|
tristate "RME Hammerfall DSP Audio"
|
||||||
depends on SND
|
depends on SND
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
snd-hda-intel-objs := hda_intel.o
|
snd-hda-intel-y := hda_intel.o
|
||||||
# since snd-hda-intel is the only driver using hda-codec,
|
# since snd-hda-intel is the only driver using hda-codec,
|
||||||
# merge it into a single module although it was originally
|
# merge it into a single module although it was originally
|
||||||
# designed to be individual modules
|
# designed to be individual modules
|
||||||
snd-hda-intel-objs += hda_codec.o \
|
snd-hda-intel-y += hda_codec.o \
|
||||||
hda_generic.o \
|
hda_generic.o \
|
||||||
patch_realtek.o \
|
patch_realtek.o \
|
||||||
patch_cmedia.o \
|
patch_cmedia.o \
|
||||||
@ -12,8 +12,7 @@ snd-hda-intel-objs += hda_codec.o \
|
|||||||
patch_atihdmi.o \
|
patch_atihdmi.o \
|
||||||
patch_conexant.o \
|
patch_conexant.o \
|
||||||
patch_via.o
|
patch_via.o
|
||||||
ifdef CONFIG_PROC_FS
|
snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
|
||||||
snd-hda-intel-objs += hda_proc.o
|
snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
|
||||||
endif
|
|
||||||
|
|
||||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
|
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <sound/tlv.h>
|
#include <sound/tlv.h>
|
||||||
#include <sound/initval.h>
|
#include <sound/initval.h>
|
||||||
#include "hda_local.h"
|
#include "hda_local.h"
|
||||||
|
#include <sound/hda_hwdep.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -594,6 +595,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
|
|||||||
init_unsol_queue(bus);
|
init_unsol_queue(bus);
|
||||||
|
|
||||||
snd_hda_codec_proc_new(codec);
|
snd_hda_codec_proc_new(codec);
|
||||||
|
#ifdef CONFIG_SND_HDA_HWDEP
|
||||||
|
snd_hda_create_hwdep(codec);
|
||||||
|
#endif
|
||||||
|
|
||||||
sprintf(component, "HDA:%08x", codec->vendor_id);
|
sprintf(component, "HDA:%08x", codec->vendor_id);
|
||||||
snd_component_add(codec->bus->card, component);
|
snd_component_add(codec->bus->card, component);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <sound/info.h>
|
#include <sound/info.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
|
#include <sound/hwdep.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nodes
|
* nodes
|
||||||
@ -566,6 +567,8 @@ struct hda_codec {
|
|||||||
unsigned int spdif_status; /* IEC958 status bits */
|
unsigned int spdif_status; /* IEC958 status bits */
|
||||||
unsigned short spdif_ctls; /* SPDIF control bits */
|
unsigned short spdif_ctls; /* SPDIF control bits */
|
||||||
unsigned int spdif_in_enable; /* SPDIF input enable? */
|
unsigned int spdif_in_enable; /* SPDIF input enable? */
|
||||||
|
|
||||||
|
struct snd_hwdep *hwdep; /* assigned hwdep device */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* direction */
|
/* direction */
|
||||||
|
122
sound/pci/hda/hda_hwdep.c
Normal file
122
sound/pci/hda/hda_hwdep.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* HWDEP Interface for HD-audio codec
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
|
||||||
|
*
|
||||||
|
* This driver is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This driver is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sound/driver.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <sound/core.h>
|
||||||
|
#include "hda_codec.h"
|
||||||
|
#include "hda_local.h"
|
||||||
|
#include <sound/hda_hwdep.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write/read an out-of-bound verb
|
||||||
|
*/
|
||||||
|
static int verb_write_ioctl(struct hda_codec *codec,
|
||||||
|
struct hda_verb_ioctl __user *arg)
|
||||||
|
{
|
||||||
|
u32 verb, res;
|
||||||
|
|
||||||
|
if (get_user(verb, &arg->verb))
|
||||||
|
return -EFAULT;
|
||||||
|
res = snd_hda_codec_read(codec, verb >> 24, 0,
|
||||||
|
(verb >> 8) & 0xffff, verb & 0xff);
|
||||||
|
if (put_user(res, &arg->res))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_wcap_ioctl(struct hda_codec *codec,
|
||||||
|
struct hda_verb_ioctl __user *arg)
|
||||||
|
{
|
||||||
|
u32 verb, res;
|
||||||
|
|
||||||
|
if (get_user(verb, &arg->verb))
|
||||||
|
return -EFAULT;
|
||||||
|
res = get_wcaps(codec, verb >> 24);
|
||||||
|
if (put_user(res, &arg->res))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
|
||||||
|
unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
struct hda_codec *codec = hw->private_data;
|
||||||
|
void __user *argp = (void __user *)arg;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case HDA_IOCTL_PVERSION:
|
||||||
|
return put_user(HDA_HWDEP_VERSION, (int __user *)argp);
|
||||||
|
case HDA_IOCTL_VERB_WRITE:
|
||||||
|
return verb_write_ioctl(codec, argp);
|
||||||
|
case HDA_IOCTL_GET_WCAP:
|
||||||
|
return get_wcap_ioctl(codec, argp);
|
||||||
|
}
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
|
||||||
|
unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
return hda_hwdep_ioctl(hw, file, cmd, compat_ptr(arg));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_SND_DEBUG_DETECT
|
||||||
|
if (!capable(CAP_SYS_RAWIO))
|
||||||
|
return -EACCES;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
|
||||||
|
{
|
||||||
|
char hwname[16];
|
||||||
|
struct snd_hwdep *hwdep;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
sprintf(hwname, "HDA Codec %d", codec->addr);
|
||||||
|
err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
codec->hwdep = hwdep;
|
||||||
|
sprintf(hwdep->name, "HDA Codec %d", codec->addr);
|
||||||
|
hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
|
||||||
|
hwdep->private_data = codec;
|
||||||
|
hwdep->exclusive = 1;
|
||||||
|
|
||||||
|
hwdep->ops.open = hda_hwdep_open;
|
||||||
|
hwdep->ops.ioctl = hda_hwdep_ioctl;
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -313,4 +313,9 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
|
|||||||
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
|
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
|
||||||
unsigned int caps);
|
unsigned int caps);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hwdep interface
|
||||||
|
*/
|
||||||
|
int snd_hda_create_hwdep(struct hda_codec *codec);
|
||||||
|
|
||||||
#endif /* __SOUND_HDA_LOCAL_H */
|
#endif /* __SOUND_HDA_LOCAL_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user