mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
[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_PCXHR, /* Digigram PCXHR */
|
||||
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
|
||||
SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
|
||||
|
||||
/* Don't forget to change the following: */
|
||||
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
|
||||
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
|
||||
tristate "RME Hammerfall DSP Audio"
|
||||
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,
|
||||
# merge it into a single module although it was originally
|
||||
# designed to be individual modules
|
||||
snd-hda-intel-objs += hda_codec.o \
|
||||
snd-hda-intel-y += hda_codec.o \
|
||||
hda_generic.o \
|
||||
patch_realtek.o \
|
||||
patch_cmedia.o \
|
||||
@ -12,8 +12,7 @@ snd-hda-intel-objs += hda_codec.o \
|
||||
patch_atihdmi.o \
|
||||
patch_conexant.o \
|
||||
patch_via.o
|
||||
ifdef CONFIG_PROC_FS
|
||||
snd-hda-intel-objs += hda_proc.o
|
||||
endif
|
||||
snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
|
||||
snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
|
||||
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/initval.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);
|
||||
|
||||
snd_hda_codec_proc_new(codec);
|
||||
#ifdef CONFIG_SND_HDA_HWDEP
|
||||
snd_hda_create_hwdep(codec);
|
||||
#endif
|
||||
|
||||
sprintf(component, "HDA:%08x", codec->vendor_id);
|
||||
snd_component_add(codec->bus->card, component);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sound/info.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/hwdep.h>
|
||||
|
||||
/*
|
||||
* nodes
|
||||
@ -566,6 +567,8 @@ struct hda_codec {
|
||||
unsigned int spdif_status; /* IEC958 status bits */
|
||||
unsigned short spdif_ctls; /* SPDIF control bits */
|
||||
unsigned int spdif_in_enable; /* SPDIF input enable? */
|
||||
|
||||
struct snd_hwdep *hwdep; /* assigned hwdep device */
|
||||
};
|
||||
|
||||
/* 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,
|
||||
unsigned int caps);
|
||||
|
||||
/*
|
||||
* hwdep interface
|
||||
*/
|
||||
int snd_hda_create_hwdep(struct hda_codec *codec);
|
||||
|
||||
#endif /* __SOUND_HDA_LOCAL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user