aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-07-27 12:58:06 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:10 -0400
commit2807314d467e7dd929c42050031aabbd28e78f0b (patch)
treed4d05f61ef8cc1115ae73af900b8012392321caa
parentef5fa1a49fc3b5fe8e734f25fa61bc73ccba344e (diff)
[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>
-rw-r--r--include/sound/asound.h1
-rw-r--r--include/sound/hda_hwdep.h44
-rw-r--r--sound/pci/Kconfig9
-rw-r--r--sound/pci/hda/Makefile9
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_hwdep.c122
-rw-r--r--sound/pci/hda/hda_local.h5
8 files changed, 192 insertions, 5 deletions
diff --git a/include/sound/asound.h b/include/sound/asound.h
index c1621c650a9a..0a108aec8a91 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -92,6 +92,7 @@ enum {
92 SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */ 92 SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */
93 SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */ 93 SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
94 SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ 94 SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
95 SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
95 96
96 /* Don't forget to change the following: */ 97 /* Don't forget to change the following: */
97 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC 98 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
diff --git a/include/sound/hda_hwdep.h b/include/sound/hda_hwdep.h
new file mode 100644
index 000000000000..1c0034e87f22
--- /dev/null
+++ b/include/sound/hda_hwdep.h
@@ -0,0 +1,44 @@
1/*
2 * HWDEP Interface for HD-audio codec
3 *
4 * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This driver is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __SOUND_HDA_HWDEP_H
22#define __SOUND_HDA_HWDEP_H
23
24#define HDA_HWDEP_VERSION ((1 << 16) | (0 << 8) | (0 << 0)) /* 1.0.0 */
25
26/* verb */
27#define HDA_REG_NID_SHIFT 24
28#define HDA_REG_VERB_SHIFT 8
29#define HDA_REG_VAL_SHIFT 0
30#define HDA_VERB(nid,verb,param) ((nid)<<24 | (verb)<<8 | (param))
31
32struct hda_verb_ioctl {
33 u32 verb; /* HDA_VERB() */
34 u32 res; /* response */
35};
36
37/*
38 * ioctls
39 */
40#define HDA_IOCTL_PVERSION _IOR('H', 0x10, int)
41#define HDA_IOCTL_VERB_WRITE _IOWR('H', 0x11, struct hda_verb_ioctl)
42#define HDA_IOCTL_GET_WCAP _IOWR('H', 0x12, struct hda_verb_ioctl)
43
44#endif
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index c6b44102aa5b..57426f6fa423 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -500,6 +500,15 @@ config SND_HDA_INTEL
500 To compile this driver as a module, choose M here: the module 500 To compile this driver as a module, choose M here: the module
501 will be called snd-hda-intel. 501 will be called snd-hda-intel.
502 502
503config SND_HDA_HWDEP
504 bool "Build hwdep interface for HD-audio driver"
505 depends on SND_HDA_INTEL
506 select SND_HWDEP
507 help
508 Say Y here to build a hwdep interface for HD-audio driver.
509 This interface can be used for out-of-bound communication
510 with codesc for debugging purposes.
511
503config SND_HDSP 512config SND_HDSP
504 tristate "RME Hammerfall DSP Audio" 513 tristate "RME Hammerfall DSP Audio"
505 depends on SND 514 depends on SND
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index b2484bbdcc1d..f85c34551ac8 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,8 +1,8 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-y := hda_intel.o
2# since snd-hda-intel is the only driver using hda-codec, 2# since snd-hda-intel is the only driver using hda-codec,
3# merge it into a single module although it was originally 3# merge it into a single module although it was originally
4# designed to be individual modules 4# designed to be individual modules
5snd-hda-intel-objs += hda_codec.o \ 5snd-hda-intel-y += hda_codec.o \
6 hda_generic.o \ 6 hda_generic.o \
7 patch_realtek.o \ 7 patch_realtek.o \
8 patch_cmedia.o \ 8 patch_cmedia.o \
@@ -12,8 +12,7 @@ snd-hda-intel-objs += hda_codec.o \
12 patch_atihdmi.o \ 12 patch_atihdmi.o \
13 patch_conexant.o \ 13 patch_conexant.o \
14 patch_via.o 14 patch_via.o
15ifdef CONFIG_PROC_FS 15snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
16snd-hda-intel-objs += hda_proc.o 16snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
17endif
18 17
19obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o 18obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a05db2f214bd..e7843ffeeb2f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -31,6 +31,7 @@
31#include <sound/tlv.h> 31#include <sound/tlv.h>
32#include <sound/initval.h> 32#include <sound/initval.h>
33#include "hda_local.h" 33#include "hda_local.h"
34#include <sound/hda_hwdep.h>
34 35
35 36
36/* 37/*
@@ -594,6 +595,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
594 init_unsol_queue(bus); 595 init_unsol_queue(bus);
595 596
596 snd_hda_codec_proc_new(codec); 597 snd_hda_codec_proc_new(codec);
598#ifdef CONFIG_SND_HDA_HWDEP
599 snd_hda_create_hwdep(codec);
600#endif
597 601
598 sprintf(component, "HDA:%08x", codec->vendor_id); 602 sprintf(component, "HDA:%08x", codec->vendor_id);
599 snd_component_add(codec->bus->card, component); 603 snd_component_add(codec->bus->card, component);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 6809386109c8..1370e346bf34 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -24,6 +24,7 @@
24#include <sound/info.h> 24#include <sound/info.h>
25#include <sound/control.h> 25#include <sound/control.h>
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/hwdep.h>
27 28
28/* 29/*
29 * nodes 30 * nodes
@@ -566,6 +567,8 @@ struct hda_codec {
566 unsigned int spdif_status; /* IEC958 status bits */ 567 unsigned int spdif_status; /* IEC958 status bits */
567 unsigned short spdif_ctls; /* SPDIF control bits */ 568 unsigned short spdif_ctls; /* SPDIF control bits */
568 unsigned int spdif_in_enable; /* SPDIF input enable? */ 569 unsigned int spdif_in_enable; /* SPDIF input enable? */
570
571 struct snd_hwdep *hwdep; /* assigned hwdep device */
569}; 572};
570 573
571/* direction */ 574/* direction */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
new file mode 100644
index 000000000000..64be7b533488
--- /dev/null
+++ b/sound/pci/hda/hda_hwdep.c
@@ -0,0 +1,122 @@
1/*
2 * HWDEP Interface for HD-audio codec
3 *
4 * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This driver is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/pci.h>
25#include <linux/compat.h>
26#include <linux/mutex.h>
27#include <sound/core.h>
28#include "hda_codec.h"
29#include "hda_local.h"
30#include <sound/hda_hwdep.h>
31
32/*
33 * write/read an out-of-bound verb
34 */
35static int verb_write_ioctl(struct hda_codec *codec,
36 struct hda_verb_ioctl __user *arg)
37{
38 u32 verb, res;
39
40 if (get_user(verb, &arg->verb))
41 return -EFAULT;
42 res = snd_hda_codec_read(codec, verb >> 24, 0,
43 (verb >> 8) & 0xffff, verb & 0xff);
44 if (put_user(res, &arg->res))
45 return -EFAULT;
46 return 0;
47}
48
49static int get_wcap_ioctl(struct hda_codec *codec,
50 struct hda_verb_ioctl __user *arg)
51{
52 u32 verb, res;
53
54 if (get_user(verb, &arg->verb))
55 return -EFAULT;
56 res = get_wcaps(codec, verb >> 24);
57 if (put_user(res, &arg->res))
58 return -EFAULT;
59 return 0;
60}
61
62
63/*
64 */
65static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
66 unsigned int cmd, unsigned long arg)
67{
68 struct hda_codec *codec = hw->private_data;
69 void __user *argp = (void __user *)arg;
70
71 switch (cmd) {
72 case HDA_IOCTL_PVERSION:
73 return put_user(HDA_HWDEP_VERSION, (int __user *)argp);
74 case HDA_IOCTL_VERB_WRITE:
75 return verb_write_ioctl(codec, argp);
76 case HDA_IOCTL_GET_WCAP:
77 return get_wcap_ioctl(codec, argp);
78 }
79 return -ENOIOCTLCMD;
80}
81
82#ifdef CONFIG_COMPAT
83static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
84 unsigned int cmd, unsigned long arg)
85{
86 return hda_hwdep_ioctl(hw, file, cmd, compat_ptr(arg));
87}
88#endif
89
90static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
91{
92#ifndef CONFIG_SND_DEBUG_DETECT
93 if (!capable(CAP_SYS_RAWIO))
94 return -EACCES;
95#endif
96 return 0;
97}
98
99int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
100{
101 char hwname[16];
102 struct snd_hwdep *hwdep;
103 int err;
104
105 sprintf(hwname, "HDA Codec %d", codec->addr);
106 err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep);
107 if (err < 0)
108 return err;
109 codec->hwdep = hwdep;
110 sprintf(hwdep->name, "HDA Codec %d", codec->addr);
111 hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
112 hwdep->private_data = codec;
113 hwdep->exclusive = 1;
114
115 hwdep->ops.open = hda_hwdep_open;
116 hwdep->ops.ioctl = hda_hwdep_ioctl;
117#ifdef CONFIG_COMPAT
118 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
119#endif
120
121 return 0;
122}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index c8d34a5b081f..12428a67eb2a 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -313,4 +313,9 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
313int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 313int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
314 unsigned int caps); 314 unsigned int caps);
315 315
316/*
317 * hwdep interface
318 */
319int snd_hda_create_hwdep(struct hda_codec *codec);
320
316#endif /* __SOUND_HDA_LOCAL_H */ 321#endif /* __SOUND_HDA_LOCAL_H */