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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxxxxxxxxxx>

Signed-off-by: Janusz Krzysztofik <jkrzyszt@xxxxxxxxxxxx>
---
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;
 	}
 
 

_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux