[alsa-devel] [RFC] [PATCH v2] ASoC: CX20442: push down machine independent line discipline bits

Janusz Krzysztofik jkrzyszt at tis.icnet.pl
Wed Jul 29 12:24:46 CEST 2009


This corrected patch adds machine independent line discipline code, prevoiusly
exsiting inside my Amstrad Delta ASoC machine dirver, to the Conexant CX20442
codec driver. The code can be used as a standalone line discipline, or as a
set of codec specific functions called from machine's line discipline
callbacks. Anyway, the line discipline itself must be registered by a machine
driver.

Applies on top of the followup to my initial driver version:
http://mailman.alsa-project.org/pipermail/alsa-devel/2009-July/019757.html

Suggested by ASoC manintainer Mark Brown <broonie at opensource.wolfsonmicro.com>

Signed-off-by: Janusz Krzysztofik <jkrzyszt at tis.icnet.pl>
---
Corrections:
  sound/soc/codecs/cx20442.c
    line 300:
	-static struct tty_ldisc_ops v253_ops = {
	+struct tty_ldisc_ops v253_ops = {
    line 420:
	-	dev_err(&codec->dev, "Failed to register codec: %d\n", ret);
	+	dev_err(codec->dev, "Failed to register codec: %d\n", ret);
    line 425:
	-	dev_err(&codec->dev, "Failed to register DAI: %d\n", ret);
	+	dev_err(codec->dev, "Failed to register DAI: %d\n", ret);

Corrected patch:

--- linux-2.6.31-rc3/sound/soc/codecs/cx20442.h.orig	2009-07-22 
04:56:45.000000000 +0200
+++ linux-2.6.31-rc3/sound/soc/codecs/cx20442.h	2009-07-28 21:23:17.000000000 
+0200
@@ -15,5 +15,6 @@
 
 extern struct snd_soc_dai cx20442_dai;
 extern struct snd_soc_codec_device cx20442_codec_dev;
+extern struct tty_ldisc_ops v253_ops;
 
 #endif
--- linux-2.6.31-rc3/sound/soc/codecs/cx20442.c.orig	2009-07-28 
20:26:18.000000000 +0200
+++ linux-2.6.31-rc3/sound/soc/codecs/cx20442.c	2009-07-29 02:16:05.000000000 
+0200
@@ -13,6 +13,8 @@
  *  option) any later version.
  */
 
+#include <linux/tty.h>
+
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/soc-dapm.h>
@@ -172,8 +174,7 @@ static int cx20442_write(struct snd_soc_
 		return -EINVAL;
 
 	/* hw_write and control_data pointers required for talking to the modem
-	 * are expected to be set by the machine driver's line discipline
-	 * initialization code */
+	 * are expected to be set by the line discipline initialization code */
 	if (!codec->hw_write || !codec->control_data)
 		return -EIO;
 
@@ -208,6 +209,111 @@ static int cx20442_write(struct snd_soc_
 	return 0;
 }
 
+
+/* Moved up here as line discipline referres it during initialization */
+static struct snd_soc_codec *cx20442_codec;
+
+
+/*
+ * Line discpline related code
+ *
+ * Any of the callback functions below can be used in two ways:
+ * 1) registerd by a machine driver as one of line discipline operations,
+ * 2) called from a machine's provided line discipline callback function
+ *    in case when extra machine specific code must be run as well.
+ */
+
+/* Modem init: echo off, digital speaker off, quiet off, voice mode */
+static const char *v253_init = "ate0m0q0+fclass=8\r";
+
+/* Line discipline .open() */
+static int v253_open(struct tty_struct *tty)
+{
+	struct snd_soc_codec *codec = cx20442_codec;
+	int ret, len = strlen(v253_init);
+
+	/* Doesn't make sense without write callback */
+	if (!tty->ops->write)
+		return -EINVAL;
+
+	/* Pass the codec structure address for use by other ldisc callbacks */
+	tty->disc_data = codec;
+
+	if (tty->ops->write(tty, v253_init, len) != len) {
+		ret = -EIO;
+		goto err;
+	}
+	/* Actual setup will be performed after the modem responds. */
+	return 0;
+err:
+	tty->disc_data = NULL;
+	return ret;
+}
+
+/* Line discipline .close() */
+static void v253_close(struct tty_struct *tty)
+{
+	struct snd_soc_codec *codec = tty->disc_data;
+
+	tty->disc_data = NULL;
+
+	if (!codec)
+		return;
+
+	/* Prevent the codec driver from further accessing the modem */
+	codec->hw_write = NULL;
+	codec->control_data = NULL;
+	codec->pop_time = 0;
+}
+
+/* Line discipline .hangup() */
+static int v253_hangup(struct tty_struct *tty)
+{
+	v253_close(tty);
+	return 0;
+}
+
+/* Line discipline .receive_buf() */
+static void v253_receive(struct tty_struct *tty,
+				const unsigned char *cp, char *fp, int count)
+{
+	struct snd_soc_codec *codec = tty->disc_data;
+
+	if (!codec)
+		return;
+
+	if (!codec->control_data) {
+		/* First modem response, complete setup procedure */
+
+		/* Set up codec driver access to modem controls */
+		codec->control_data = tty;
+		codec->hw_write = (hw_write_t)tty->ops->write;
+		codec->pop_time = 1;
+	}
+}
+
+/* Line discipline .write_wakeup() */
+static void v253_wakeup(struct tty_struct *tty)
+{
+}
+
+struct tty_ldisc_ops v253_ops = {
+	.magic = TTY_LDISC_MAGIC,
+	.name = "cx20442",
+	.owner = THIS_MODULE,
+	.open = v253_open,
+	.close = v253_close,
+	.hangup = v253_hangup,
+	.receive_buf = v253_receive,
+	.write_wakeup = v253_wakeup,
+};
+EXPORT_SYMBOL_GPL(v253_ops);
+
+
+/*
+ * Codec DAI
+ */
+
 struct snd_soc_dai cx20442_dai = {
 	.name = "CX20442",
 	.playback = {
@@ -227,8 +333,6 @@ struct snd_soc_dai cx20442_dai = {
 };
 EXPORT_SYMBOL_GPL(cx20442_dai);
 
-static struct snd_soc_codec *cx20442_codec;
-
 static int cx20442_codec_probe(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -313,13 +417,13 @@ static int cx20442_register(struct cx204
 
 	ret = snd_soc_register_codec(codec);
 	if (ret != 0) {
-		dev_err(&codec->dev, "Failed to register codec: %d\n", ret);
+		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
 		goto err;
 	}
 
 	ret = snd_soc_register_dai(&cx20442_dai);
 	if (ret != 0) {
-		dev_err(&codec->dev, "Failed to register DAI: %d\n", ret);
+		dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
 		goto err_codec;
 	}
 
 



More information about the Alsa-devel mailing list