浏览代码

ALSA CVS update
HDA Codec driver,HDA generic driver
Summar: hda-codec - MFG support

This adds Modem Functional Group (MFG) support and option for 9600
sample rate.

Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

Sasha Khapyorsky 20 年之前
父节点
当前提交
673b683a07
共有 3 个文件被更改,包括 22 次插入12 次删除
  1. 16 12
      sound/pci/hda/hda_codec.c
  2. 1 0
      sound/pci/hda/hda_codec.h
  3. 5 0
      sound/pci/hda/hda_generic.c

+ 16 - 12
sound/pci/hda/hda_codec.c

@@ -432,22 +432,26 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
 }
 }
 
 
 /*
 /*
- * look for an AFG node
- *
- * return 0 if not found
+ * look for an AFG and MFG nodes
  */
  */
-static int look_for_afg_node(struct hda_codec *codec)
+static void setup_fg_nodes(struct hda_codec *codec)
 {
 {
 	int i, total_nodes;
 	int i, total_nodes;
 	hda_nid_t nid;
 	hda_nid_t nid;
 
 
 	total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
 	total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
 	for (i = 0; i < total_nodes; i++, nid++) {
 	for (i = 0; i < total_nodes; i++, nid++) {
-		if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) ==
-		    AC_GRP_AUDIO_FUNCTION)
-			return nid;
+		switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
+		case AC_GRP_AUDIO_FUNCTION:
+			codec->afg = nid;
+			break;
+		case AC_GRP_MODEM_FUNCTION:
+			codec->mfg = nid;
+			break;
+		default:
+			break;
+		}
 	}
 	}
-	return 0;
 }
 }
 
 
 /*
 /*
@@ -507,10 +511,9 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 	codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
 	codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
 	codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
 	codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
 
 
-	/* FIXME: support for multiple AFGs? */
-	codec->afg = look_for_afg_node(codec);
-	if (! codec->afg) {
-		snd_printdd("hda_codec: no AFG node found\n");
+	setup_fg_nodes(codec);
+	if (! codec->afg && ! codec->mfg) {
+		snd_printdd("hda_codec: no AFG or MFG node found\n");
 		snd_hda_codec_free(codec);
 		snd_hda_codec_free(codec);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -1163,6 +1166,7 @@ int snd_hda_build_controls(struct hda_bus *bus)
 static unsigned int rate_bits[][3] = {
 static unsigned int rate_bits[][3] = {
 	/* rate in Hz, ALSA rate bitmask, HDA format value */
 	/* rate in Hz, ALSA rate bitmask, HDA format value */
 	{ 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
 	{ 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
+	{ 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
 	{ 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
 	{ 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
 	{ 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
 	{ 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
 	{ 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */
 	{ 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */

+ 1 - 0
sound/pci/hda/hda_codec.h

@@ -514,6 +514,7 @@ struct hda_codec {
 	struct list_head list;	/* list point */
 	struct list_head list;	/* list point */
 
 
 	hda_nid_t afg;	/* AFG node id */
 	hda_nid_t afg;	/* AFG node id */
+	hda_nid_t mfg;	/* MFG node id */
 
 
 	/* ids */
 	/* ids */
 	u32 vendor_id;
 	u32 vendor_id;

+ 5 - 0
sound/pci/hda/hda_generic.c

@@ -881,6 +881,11 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
 	struct hda_gspec *spec;
 	struct hda_gspec *spec;
 	int err;
 	int err;
 
 
+	if(!codec->afg) {
+		snd_printdd("hda_generic: no generic modem yet\n");
+		return -ENODEV;
+	}
+
 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL) {
 	if (spec == NULL) {
 		printk(KERN_ERR "hda_generic: can't allocate spec\n");
 		printk(KERN_ERR "hda_generic: can't allocate spec\n");