linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4 v2] MFD/OMAP/ASoC: MFD device for twl4030 codec submodule
@ 2009-10-22 10:26 Peter Ujfalusi
  2009-10-22 10:26 ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Peter Ujfalusi
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-22 10:26 UTC (permalink / raw)
  To: alsa-devel, linux-omap, sameo; +Cc: linux-kernel, tony, broonie

Hello,

Changes from the first series:
- twl4030-codec MFD driver is using the mfd-core API (and selects MFD_CORE)
- Added Acked-by: Tony Lindgren <tony@atomide.com> to the patch for the OMAP
  board files
- User selectable Kconfig is removed for the TWL4030_CODEC
- soc codec driver patch separated:
 - Change the header file, and use the include/linux/mfd/twl4030-codec.h for
   register definitions
 - The actual change in the soc codec driver
- Module alias corrected in soc codec driver
- The bias is brought up when the driver comes up, rather than in soc probe.
- The soc codec driver is selecting the TWL4030_CODEC driver

The series applies on top of sound-2.6:topic/asoc branch

Commit message from the first series:

The following series adds new MFD device on top of the twl4030 MFD device for
the codec part of the chip, and also converts the soc audio driver to use the
correct probing (device model).

Reason for the twl4030_codec MFD: the vibra control is actually in the codec
part of the twl4030. If both the vibra and the audio functionality is needed
from the twl4030 at the same time, than they need to control the codec power
and APLL at the same time without breaking the other driver.
Also these two has to be able to work without the need for the other driver.

The proposed solution:
Register twl4030_codec as a child for the twl4030 mfd.
twl4030_codec is also and mfd and at the moment it has two child:
twl4030_codec_audio: for audio codec
twl4030_codec_vibra: for vibra driver

The twl4030_codec mfd registers the devices for audio and vibra (if the
platform data is not NULL for them), and has - at the moment - functions to
enable/disable resources, each of these resources has ref-counts, so the
twl4030_codec knows, when the resource is need to be turned on or off.

The interface is quite simple:
int twl4030_codec_enable_resource(enum twl4030_codec_res id);
int twl4030_codec_disable_resource(enum twl4030_codec_res id);

These functions are returning the content of the given register after the
modification (or negative value, if error -  the error handling need to be
revisited in a near future), so that the caller can update it's local cache if
it need to do (the audio driver needs it).

There are two resource defined:
TWL4030_CODEC_RES_POWER: Controlling the power of the codec
TWL4030_CODEC_RES_APLL: For APLL

The vibra driver is not part of this series.

I have also included a patch, which changes the board files for those, which
in my knowledge uses the twl4030 codec as audio device. I might missed some
boards...

To-Do list:
- add the actual vibra driver ;)
- coexistence related fixes for the audio and vibra driver
- move all audio related configuration from soc machine drivers to the board
  files (if any)

---
Peter Ujfalusi (4):
  MFD: twl4030: add twl4030_codec MFD as a new child to the core
  OMAP: Platform support for twl4030_codec MFD
  ASoC: TWL4030: use the twl4030-codec.h for register descriptions
  ASoC: TWL4030: Driver registration via twl4030_codec MFD

 arch/arm/mach-omap2/board-3430sdp.c      |    9 +
 arch/arm/mach-omap2/board-omap3beagle.c  |    9 +
 arch/arm/mach-omap2/board-omap3evm.c     |    9 +
 arch/arm/mach-omap2/board-omap3pandora.c |    9 +
 arch/arm/mach-omap2/board-overo.c        |    9 +
 arch/arm/mach-omap2/board-zoom2.c        |    9 +
 drivers/mfd/Kconfig                      |    6 +
 drivers/mfd/Makefile                     |    1 +
 drivers/mfd/twl4030-codec.c              |  241 ++++++++++++++++++++++++++
 drivers/mfd/twl4030-core.c               |   14 ++
 include/linux/i2c/twl4030.h              |   18 ++
 include/linux/mfd/twl4030-codec.h        |  271 ++++++++++++++++++++++++++++++
 sound/soc/codecs/Kconfig                 |    1 +
 sound/soc/codecs/twl4030.c               |  203 ++++++++++++++---------
 sound/soc/codecs/twl4030.h               |  242 +--------------------------
 15 files changed, 738 insertions(+), 313 deletions(-)
 create mode 100644 drivers/mfd/twl4030-codec.c
 create mode 100644 include/linux/mfd/twl4030-codec.h


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core
  2009-10-22 10:26 [PATCH 0/4 v2] MFD/OMAP/ASoC: MFD device for twl4030 codec submodule Peter Ujfalusi
@ 2009-10-22 10:26 ` Peter Ujfalusi
  2009-10-22 10:26   ` [PATCH 2/4 v2] OMAP: Platform support for twl4030_codec MFD Peter Ujfalusi
  2009-10-23 14:07   ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Samuel Ortiz
  0 siblings, 2 replies; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-22 10:26 UTC (permalink / raw)
  To: alsa-devel, linux-omap, sameo; +Cc: linux-kernel, tony, broonie

New MFD child to twl4030 MFD device.

Reason for the twl4030_codec MFD: the vibra control is actually in the codec
part of the twl4030. If both the vibra and the audio functionality is needed
from the twl4030 at the same time, than they need to control the codec power
and APLL at the same time without breaking the other driver.
Also these two has to be able to work without the need for the other driver.

This MFD device will be used by the drivers, which needs resources
from the twl4030 codec like audio and vibra.

The platform specific configuration data is passed along to the
child drivers (audio, vibra).

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
---
 drivers/mfd/Kconfig               |    6 +
 drivers/mfd/Makefile              |    1 +
 drivers/mfd/twl4030-codec.c       |  241 +++++++++++++++++++++++++++++++++
 drivers/mfd/twl4030-core.c        |   14 ++
 include/linux/i2c/twl4030.h       |   18 +++
 include/linux/mfd/twl4030-codec.h |  271 +++++++++++++++++++++++++++++++++++++
 6 files changed, 551 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/twl4030-codec.c
 create mode 100644 include/linux/mfd/twl4030-codec.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 570be13..08f2d07 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -121,6 +121,12 @@ config TWL4030_POWER
 	  and load scripts controling which resources are switched off/on
 	  or reset when a sleep, wakeup or warm reset event occurs.

+config TWL4030_CODEC
+	bool
+	depends on TWL4030_CORE
+	select MFD_CORE
+	default n
+
 config MFD_TMIO
 	bool
 	default n
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f3b277b..af0fc90 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MENELAUS)		+= menelaus.o

 obj-$(CONFIG_TWL4030_CORE)	+= twl4030-core.o twl4030-irq.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
+obj-$(CONFIG_TWL4030_CODEC)	+= twl4030-codec.o

 obj-$(CONFIG_MFD_MC13783)	+= mc13783-core.o

diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
new file mode 100644
index 0000000..9710307
--- /dev/null
+++ b/drivers/mfd/twl4030-codec.c
@@ -0,0 +1,241 @@
+/*
+ * MFD driver for twl4030 codec submodule
+ *
+ * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
+ *
+ * Copyright:   (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/twl4030-codec.h>
+
+#define TWL4030_CODEC_CELLS	2
+
+static struct platform_device *twl4030_codec_dev;
+
+struct twl4030_codec_resource {
+	int request_count;
+	u8 reg;
+	u8 mask;
+};
+
+struct twl4030_codec {
+	struct mutex mutex;
+	struct twl4030_codec_resource resource[TWL4030_CODEC_RES_MAX];
+	struct mfd_cell cells[TWL4030_CODEC_CELLS];
+};
+
+/*
+ * Modify the resource, the function returns the content of the register
+ * after the modification.
+ */
+static int twl4030_codec_set_resource(enum twl4030_codec_res id, int enable)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	u8 val;
+
+	twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
+			codec->resource[id].reg);
+
+	if (enable)
+		val |= codec->resource[id].mask;
+	else
+		val &= ~codec->resource[id].mask;
+
+	twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+					val, codec->resource[id].reg);
+
+	return val;
+}
+
+static inline int twl4030_codec_get_resource(enum twl4030_codec_res id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	u8 val;
+
+	twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
+			codec->resource[id].reg);
+
+	return val;
+}
+
+/*
+ * Enable the resource.
+ * The function returns with error or the content of the register
+ */
+int twl4030_codec_enable_resource(enum twl4030_codec_res id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	int val;
+
+	if (id >= TWL4030_CODEC_RES_MAX) {
+		dev_err(&twl4030_codec_dev->dev,
+				"Invalid resource ID (%u)\n", id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&codec->mutex);
+	if (!codec->resource[id].request_count)
+		/* Resource was disabled, enable it */
+		val = twl4030_codec_set_resource(id, 1);
+	else
+		val = twl4030_codec_get_resource(id);
+
+	codec->resource[id].request_count++;
+	mutex_unlock(&codec->mutex);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(twl4030_codec_enable_resource);
+
+/*
+ * Disable the resource.
+ * The function returns with error or the content of the register
+ */
+int twl4030_codec_disable_resource(unsigned id)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
+	int val;
+
+	if (id >= TWL4030_CODEC_RES_MAX) {
+		dev_err(&twl4030_codec_dev->dev,
+				"Invalid resource ID (%u)\n", id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&codec->mutex);
+	if (!codec->resource[id].request_count) {
+		dev_err(&twl4030_codec_dev->dev,
+			"Resource has been disabled already (%u)\n", id);
+		mutex_unlock(&codec->mutex);
+		return -EPERM;
+	}
+	codec->resource[id].request_count--;
+
+	if (!codec->resource[id].request_count)
+		/* Resource can be disabled now */
+		val = twl4030_codec_set_resource(id, 0);
+	else
+		val = twl4030_codec_get_resource(id);
+
+	mutex_unlock(&codec->mutex);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(twl4030_codec_disable_resource);
+
+static int __devinit twl4030_codec_probe(struct platform_device *pdev)
+{
+	struct twl4030_codec *codec;
+	struct twl4030_codec_data *pdata = pdev->dev.platform_data;
+	struct mfd_cell *cell = NULL;
+	int ret, childs = 0;
+
+	codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL);
+	if (!codec)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, codec);
+
+	twl4030_codec_dev = pdev;
+	mutex_init(&codec->mutex);
+
+	/* Codec power */
+	codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
+	codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ;
+
+	/* PLL */
+	codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL;
+	codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN;
+
+	if (pdata->audio) {
+		cell = &codec->cells[childs];
+		cell->name = "twl4030_codec_audio";
+		cell->platform_data = pdata->audio;
+		cell->data_size = sizeof(*pdata->audio);
+		childs++;
+	}
+	if (pdata->vibra) {
+		cell = &codec->cells[childs];
+		cell->name = "twl4030_codec_vibra";
+		cell->platform_data = pdata->vibra;
+		cell->data_size = sizeof(*pdata->vibra);
+		childs++;
+	}
+
+	if (childs)
+		ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells,
+				      childs, NULL, 0);
+	else {
+		dev_err(&pdev->dev, "No platform data found for childs\n");
+		ret = -ENODEV;
+	}
+
+	if (!ret)
+		return 0;
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(codec);
+	twl4030_codec_dev = NULL;
+	return ret;
+}
+
+static int __devexit twl4030_codec_remove(struct platform_device *pdev)
+{
+	struct twl4030_codec *codec = platform_get_drvdata(pdev);
+
+	mfd_remove_devices(&pdev->dev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(codec);
+	twl4030_codec_dev = NULL;
+
+	return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_codec");
+
+static struct platform_driver twl4030_codec_driver = {
+	.probe		= twl4030_codec_probe,
+	.remove		= __devexit_p(twl4030_codec_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "twl4030_codec",
+	},
+};
+
+static int __devinit twl4030_codec_init(void)
+{
+	return platform_driver_register(&twl4030_codec_driver);
+}
+module_init(twl4030_codec_init);
+
+static void __devexit twl4030_codec_exit(void)
+{
+	platform_driver_unregister(&twl4030_codec_driver);
+}
+module_exit(twl4030_codec_exit);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e424cf6..0ee81e4 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -114,6 +114,12 @@
 #define twl_has_watchdog()        false
 #endif

+#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
+#define twl_has_codec()	true
+#else
+#define twl_has_codec()	false
+#endif
+
 /* Triton Core internal information (BEGIN) */

 /* Last - for index max*/
@@ -557,6 +563,14 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 			return PTR_ERR(child);
 	}

+	if (twl_has_codec() && pdata->codec) {
+		child = add_child(1, "twl4030_codec",
+				pdata->codec, sizeof(*pdata->codec),
+				false, 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
 	if (twl_has_regulator()) {
 		/*
 		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 2d02dfd..42d6c72 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -401,6 +401,23 @@ struct twl4030_power_data {

 extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);

+struct twl4030_codec_audio_data {
+	unsigned int	audio_mclk;
+	unsigned int ramp_delay_value;
+	unsigned int hs_extmute:1;
+	void (*set_hs_extmute)(int mute);
+};
+
+struct twl4030_codec_vibra_data {
+	unsigned int	audio_mclk;
+	unsigned int	coexist;
+};
+
+struct twl4030_codec_data {
+	struct twl4030_codec_audio_data		*audio;
+	struct twl4030_codec_vibra_data		*vibra;
+};
+
 struct twl4030_platform_data {
 	unsigned				irq_base, irq_end;
 	struct twl4030_bci_platform_data	*bci;
@@ -409,6 +426,7 @@ struct twl4030_platform_data {
 	struct twl4030_keypad_data		*keypad;
 	struct twl4030_usb_data			*usb;
 	struct twl4030_power_data		*power;
+	struct twl4030_codec_data		*codec;

 	/* LDO regulators */
 	struct regulator_init_data		*vdac;
diff --git a/include/linux/mfd/twl4030-codec.h b/include/linux/mfd/twl4030-codec.h
new file mode 100644
index 0000000..ef0a304
--- /dev/null
+++ b/include/linux/mfd/twl4030-codec.h
@@ -0,0 +1,271 @@
+/*
+ * MFD driver for twl4030 codec submodule
+ *
+ * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
+ *
+ * Copyright:   (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __TWL4030_CODEC_H__
+#define __TWL4030_CODEC_H__
+
+/* Codec registers */
+#define TWL4030_REG_CODEC_MODE		0x01
+#define TWL4030_REG_OPTION		0x02
+#define TWL4030_REG_UNKNOWN		0x03
+#define TWL4030_REG_MICBIAS_CTL		0x04
+#define TWL4030_REG_ANAMICL		0x05
+#define TWL4030_REG_ANAMICR		0x06
+#define TWL4030_REG_AVADC_CTL		0x07
+#define TWL4030_REG_ADCMICSEL		0x08
+#define TWL4030_REG_DIGMIXING		0x09
+#define TWL4030_REG_ATXL1PGA		0x0A
+#define TWL4030_REG_ATXR1PGA		0x0B
+#define TWL4030_REG_AVTXL2PGA		0x0C
+#define TWL4030_REG_AVTXR2PGA		0x0D
+#define TWL4030_REG_AUDIO_IF		0x0E
+#define TWL4030_REG_VOICE_IF		0x0F
+#define TWL4030_REG_ARXR1PGA		0x10
+#define TWL4030_REG_ARXL1PGA		0x11
+#define TWL4030_REG_ARXR2PGA		0x12
+#define TWL4030_REG_ARXL2PGA		0x13
+#define TWL4030_REG_VRXPGA		0x14
+#define TWL4030_REG_VSTPGA		0x15
+#define TWL4030_REG_VRX2ARXPGA		0x16
+#define TWL4030_REG_AVDAC_CTL		0x17
+#define TWL4030_REG_ARX2VTXPGA		0x18
+#define TWL4030_REG_ARXL1_APGA_CTL	0x19
+#define TWL4030_REG_ARXR1_APGA_CTL	0x1A
+#define TWL4030_REG_ARXL2_APGA_CTL	0x1B
+#define TWL4030_REG_ARXR2_APGA_CTL	0x1C
+#define TWL4030_REG_ATX2ARXPGA		0x1D
+#define TWL4030_REG_BT_IF		0x1E
+#define TWL4030_REG_BTPGA		0x1F
+#define TWL4030_REG_BTSTPGA		0x20
+#define TWL4030_REG_EAR_CTL		0x21
+#define TWL4030_REG_HS_SEL		0x22
+#define TWL4030_REG_HS_GAIN_SET		0x23
+#define TWL4030_REG_HS_POPN_SET		0x24
+#define TWL4030_REG_PREDL_CTL		0x25
+#define TWL4030_REG_PREDR_CTL		0x26
+#define TWL4030_REG_PRECKL_CTL		0x27
+#define TWL4030_REG_PRECKR_CTL		0x28
+#define TWL4030_REG_HFL_CTL		0x29
+#define TWL4030_REG_HFR_CTL		0x2A
+#define TWL4030_REG_ALC_CTL		0x2B
+#define TWL4030_REG_ALC_SET1		0x2C
+#define TWL4030_REG_ALC_SET2		0x2D
+#define TWL4030_REG_BOOST_CTL		0x2E
+#define TWL4030_REG_SOFTVOL_CTL		0x2F
+#define TWL4030_REG_DTMF_FREQSEL	0x30
+#define TWL4030_REG_DTMF_TONEXT1H	0x31
+#define TWL4030_REG_DTMF_TONEXT1L	0x32
+#define TWL4030_REG_DTMF_TONEXT2H	0x33
+#define TWL4030_REG_DTMF_TONEXT2L	0x34
+#define TWL4030_REG_DTMF_TONOFF		0x35
+#define TWL4030_REG_DTMF_WANONOFF	0x36
+#define TWL4030_REG_I2S_RX_SCRAMBLE_H	0x37
+#define TWL4030_REG_I2S_RX_SCRAMBLE_M	0x38
+#define TWL4030_REG_I2S_RX_SCRAMBLE_L	0x39
+#define TWL4030_REG_APLL_CTL		0x3A
+#define TWL4030_REG_DTMF_CTL		0x3B
+#define TWL4030_REG_DTMF_PGA_CTL2	0x3C
+#define TWL4030_REG_DTMF_PGA_CTL1	0x3D
+#define TWL4030_REG_MISC_SET_1		0x3E
+#define TWL4030_REG_PCMBTMUX		0x3F
+#define TWL4030_REG_RX_PATH_SEL		0x43
+#define TWL4030_REG_VDL_APGA_CTL	0x44
+#define TWL4030_REG_VIBRA_CTL		0x45
+#define TWL4030_REG_VIBRA_SET		0x46
+#define TWL4030_REG_VIBRA_PWM_SET	0x47
+#define TWL4030_REG_ANAMIC_GAIN		0x48
+#define TWL4030_REG_MISC_SET_2		0x49
+
+/* Bitfield Definitions */
+
+/* TWL4030_CODEC_MODE (0x01) Fields */
+#define TWL4030_APLL_RATE		0xF0
+#define TWL4030_APLL_RATE_8000		0x00
+#define TWL4030_APLL_RATE_11025		0x10
+#define TWL4030_APLL_RATE_12000		0x20
+#define TWL4030_APLL_RATE_16000		0x40
+#define TWL4030_APLL_RATE_22050		0x50
+#define TWL4030_APLL_RATE_24000		0x60
+#define TWL4030_APLL_RATE_32000		0x80
+#define TWL4030_APLL_RATE_44100		0x90
+#define TWL4030_APLL_RATE_48000		0xA0
+#define TWL4030_APLL_RATE_96000		0xE0
+#define TWL4030_SEL_16K			0x08
+#define TWL4030_CODECPDZ		0x02
+#define TWL4030_OPT_MODE		0x01
+#define TWL4030_OPTION_1		(1 << 0)
+#define TWL4030_OPTION_2		(0 << 0)
+
+/* TWL4030_OPTION (0x02) Fields */
+#define TWL4030_ATXL1_EN		(1 << 0)
+#define TWL4030_ATXR1_EN		(1 << 1)
+#define TWL4030_ATXL2_VTXL_EN		(1 << 2)
+#define TWL4030_ATXR2_VTXR_EN		(1 << 3)
+#define TWL4030_ARXL1_VRX_EN		(1 << 4)
+#define TWL4030_ARXR1_EN		(1 << 5)
+#define TWL4030_ARXL2_EN		(1 << 6)
+#define TWL4030_ARXR2_EN		(1 << 7)
+
+/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
+#define TWL4030_MICBIAS2_CTL		0x40
+#define TWL4030_MICBIAS1_CTL		0x20
+#define TWL4030_HSMICBIAS_EN		0x04
+#define TWL4030_MICBIAS2_EN		0x02
+#define TWL4030_MICBIAS1_EN		0x01
+
+/* ANAMICL (0x05) Fields */
+#define TWL4030_CNCL_OFFSET_START	0x80
+#define TWL4030_OFFSET_CNCL_SEL		0x60
+#define TWL4030_OFFSET_CNCL_SEL_ARX1	0x00
+#define TWL4030_OFFSET_CNCL_SEL_ARX2	0x20
+#define TWL4030_OFFSET_CNCL_SEL_VRX	0x40
+#define TWL4030_OFFSET_CNCL_SEL_ALL	0x60
+#define TWL4030_MICAMPL_EN		0x10
+#define TWL4030_CKMIC_EN		0x08
+#define TWL4030_AUXL_EN			0x04
+#define TWL4030_HSMIC_EN		0x02
+#define TWL4030_MAINMIC_EN		0x01
+
+/* ANAMICR (0x06) Fields */
+#define TWL4030_MICAMPR_EN		0x10
+#define TWL4030_AUXR_EN			0x04
+#define TWL4030_SUBMIC_EN		0x01
+
+/* AVADC_CTL (0x07) Fields */
+#define TWL4030_ADCL_EN			0x08
+#define TWL4030_AVADC_CLK_PRIORITY	0x04
+#define TWL4030_ADCR_EN			0x02
+
+/* TWL4030_REG_ADCMICSEL (0x08) Fields */
+#define TWL4030_DIGMIC1_EN		0x08
+#define TWL4030_TX2IN_SEL		0x04
+#define TWL4030_DIGMIC0_EN		0x02
+#define TWL4030_TX1IN_SEL		0x01
+
+/* AUDIO_IF (0x0E) Fields */
+#define TWL4030_AIF_SLAVE_EN		0x80
+#define TWL4030_DATA_WIDTH		0x60
+#define TWL4030_DATA_WIDTH_16S_16W	0x00
+#define TWL4030_DATA_WIDTH_32S_16W	0x40
+#define TWL4030_DATA_WIDTH_32S_24W	0x60
+#define TWL4030_AIF_FORMAT		0x18
+#define TWL4030_AIF_FORMAT_CODEC	0x00
+#define TWL4030_AIF_FORMAT_LEFT		0x08
+#define TWL4030_AIF_FORMAT_RIGHT	0x10
+#define TWL4030_AIF_FORMAT_TDM		0x18
+#define TWL4030_AIF_TRI_EN		0x04
+#define TWL4030_CLK256FS_EN		0x02
+#define TWL4030_AIF_EN			0x01
+
+/* VOICE_IF (0x0F) Fields */
+#define TWL4030_VIF_SLAVE_EN		0x80
+#define TWL4030_VIF_DIN_EN		0x40
+#define TWL4030_VIF_DOUT_EN		0x20
+#define TWL4030_VIF_SWAP		0x10
+#define TWL4030_VIF_FORMAT		0x08
+#define TWL4030_VIF_TRI_EN		0x04
+#define TWL4030_VIF_SUB_EN		0x02
+#define TWL4030_VIF_EN			0x01
+
+/* EAR_CTL (0x21) */
+#define TWL4030_EAR_GAIN		0x30
+
+/* HS_GAIN_SET (0x23) Fields */
+#define TWL4030_HSR_GAIN		0x0C
+#define TWL4030_HSR_GAIN_PWR_DOWN	0x00
+#define TWL4030_HSR_GAIN_PLUS_6DB	0x04
+#define TWL4030_HSR_GAIN_0DB		0x08
+#define TWL4030_HSR_GAIN_MINUS_6DB	0x0C
+#define TWL4030_HSL_GAIN		0x03
+#define TWL4030_HSL_GAIN_PWR_DOWN	0x00
+#define TWL4030_HSL_GAIN_PLUS_6DB	0x01
+#define TWL4030_HSL_GAIN_0DB		0x02
+#define TWL4030_HSL_GAIN_MINUS_6DB	0x03
+
+/* HS_POPN_SET (0x24) Fields */
+#define TWL4030_VMID_EN			0x40
+#define	TWL4030_EXTMUTE			0x20
+#define TWL4030_RAMP_DELAY		0x1C
+#define TWL4030_RAMP_DELAY_20MS		0x00
+#define TWL4030_RAMP_DELAY_40MS		0x04
+#define TWL4030_RAMP_DELAY_81MS		0x08
+#define TWL4030_RAMP_DELAY_161MS	0x0C
+#define TWL4030_RAMP_DELAY_323MS	0x10
+#define TWL4030_RAMP_DELAY_645MS	0x14
+#define TWL4030_RAMP_DELAY_1291MS	0x18
+#define TWL4030_RAMP_DELAY_2581MS	0x1C
+#define TWL4030_RAMP_EN			0x02
+
+/* PREDL_CTL (0x25) */
+#define TWL4030_PREDL_GAIN		0x30
+
+/* PREDR_CTL (0x26) */
+#define TWL4030_PREDR_GAIN		0x30
+
+/* PRECKL_CTL (0x27) */
+#define TWL4030_PRECKL_GAIN		0x30
+
+/* PRECKR_CTL (0x28) */
+#define TWL4030_PRECKR_GAIN		0x30
+
+/* HFL_CTL (0x29, 0x2A) Fields */
+#define TWL4030_HF_CTL_HB_EN		0x04
+#define TWL4030_HF_CTL_LOOP_EN		0x08
+#define TWL4030_HF_CTL_RAMP_EN		0x10
+#define TWL4030_HF_CTL_REF_EN		0x20
+
+/* APLL_CTL (0x3A) Fields */
+#define TWL4030_APLL_EN			0x10
+#define TWL4030_APLL_INFREQ		0x0F
+#define TWL4030_APLL_INFREQ_19200KHZ	0x05
+#define TWL4030_APLL_INFREQ_26000KHZ	0x06
+#define TWL4030_APLL_INFREQ_38400KHZ	0x0F
+
+/* REG_MISC_SET_1 (0x3E) Fields */
+#define TWL4030_CLK64_EN		0x80
+#define TWL4030_SCRAMBLE_EN		0x40
+#define TWL4030_FMLOOP_EN		0x20
+#define TWL4030_SMOOTH_ANAVOL_EN	0x02
+#define TWL4030_DIGMIC_LR_SWAP_EN	0x01
+
+/* VIBRA_CTL (0x45) */
+#define TWL4030_VIBRA_EN		0x01
+#define TWL4030_VIBRA_DIR		0x02
+#define TWL4030_VIBRA_AUDIO_SEL_L1	(0x00 << 2)
+#define TWL4030_VIBRA_AUDIO_SEL_R1	(0x01 << 2)
+#define TWL4030_VIBRA_AUDIO_SEL_L2	(0x02 << 2)
+#define TWL4030_VIBRA_AUDIO_SEL_R2	(0x03 << 2)
+#define TWL4030_VIBRA_SEL		0x10
+#define TWL4030_VIBRA_DIR_SEL		0x20
+
+/* TWL4030 codec resource IDs */
+enum twl4030_codec_res {
+	TWL4030_CODEC_RES_POWER = 0,
+	TWL4030_CODEC_RES_APLL,
+	TWL4030_CODEC_RES_MAX,
+};
+
+int twl4030_codec_disable_resource(enum twl4030_codec_res id);
+int twl4030_codec_enable_resource(enum twl4030_codec_res id);
+
+#endif	/* End of __TWL4030_CODEC_H__ */
--
1.6.5.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4 v2] OMAP: Platform support for twl4030_codec MFD
  2009-10-22 10:26 ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Peter Ujfalusi
@ 2009-10-22 10:26   ` Peter Ujfalusi
  2009-10-22 10:26     ` [PATCH 3/4 v2] ASoC: TWL4030: use the twl4030-codec.h for register descriptions Peter Ujfalusi
  2009-10-23 14:07   ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Samuel Ortiz
  1 sibling, 1 reply; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-22 10:26 UTC (permalink / raw)
  To: alsa-devel, linux-omap, sameo; +Cc: linux-kernel, tony, broonie

Add needed platform data for the twl4030_codec MFD on boards,
where the audio part of the twl4030 codec is used.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/board-3430sdp.c      |    9 +++++++++
 arch/arm/mach-omap2/board-omap3beagle.c  |    9 +++++++++
 arch/arm/mach-omap2/board-omap3evm.c     |    9 +++++++++
 arch/arm/mach-omap2/board-omap3pandora.c |    9 +++++++++
 arch/arm/mach-omap2/board-overo.c        |    9 +++++++++
 arch/arm/mach-omap2/board-zoom2.c        |    9 +++++++++
 6 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index efaf053..4f91f7a 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -410,6 +410,14 @@ static struct regulator_init_data sdp3430_vpll2 = {
 	.consumer_supplies	= &sdp3430_vdvi_supply,
 };

+static struct twl4030_codec_audio_data sdp3430_audio = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data sdp3430_codec = {
+	.audio = &sdp3430_audio,
+};
+
 static struct twl4030_platform_data sdp3430_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -420,6 +428,7 @@ static struct twl4030_platform_data sdp3430_twldata = {
 	.madc		= &sdp3430_madc_data,
 	.keypad		= &sdp3430_kp_data,
 	.usb		= &sdp3430_usb_data,
+	.codec		= &sdp3430_codec,

 	.vaux1		= &sdp3430_vaux1,
 	.vaux2		= &sdp3430_vaux2,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 70df6b4..2161d85 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -254,6 +254,14 @@ static struct twl4030_usb_data beagle_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };

+static struct twl4030_codec_audio_data beagle_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data beagle_codec_data = {
+	.audio = &beagle_audio_data,
+};
+
 static struct twl4030_platform_data beagle_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -261,6 +269,7 @@ static struct twl4030_platform_data beagle_twldata = {
 	/* platform_data for children goes here */
 	.usb		= &beagle_usb_data,
 	.gpio		= &beagle_gpio_data,
+	.codec		= &beagle_codec_data,
 	.vmmc1		= &beagle_vmmc1,
 	.vsim		= &beagle_vsim,
 	.vdac		= &beagle_vdac,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index e4ec0c5..d9a6103 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -194,6 +194,14 @@ static struct twl4030_madc_platform_data omap3evm_madc_data = {
 	.irq_line	= 1,
 };

+static struct twl4030_codec_audio_data omap3evm_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data omap3evm_codec_data = {
+	.audio = &omap3evm_audio_data,
+};
+
 static struct twl4030_platform_data omap3evm_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -203,6 +211,7 @@ static struct twl4030_platform_data omap3evm_twldata = {
 	.madc		= &omap3evm_madc_data,
 	.usb		= &omap3evm_usb_data,
 	.gpio		= &omap3evm_gpio_data,
+	.codec		= &omap3evm_codec_data,
 };

 static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 7f6bf87..5036b56 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -281,11 +281,20 @@ static struct twl4030_usb_data omap3pandora_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };

+static struct twl4030_codec_audio_data omap3pandora_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data omap3pandora_codec_data = {
+	.audio = &omap3pandora_audio_data,
+};
+
 static struct twl4030_platform_data omap3pandora_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
 	.gpio		= &omap3pandora_gpio_data,
 	.usb		= &omap3pandora_usb_data,
+	.codec		= &omap3pandora_codec_data,
 	.vmmc1		= &pandora_vmmc1,
 	.vmmc2		= &pandora_vmmc2,
 	.keypad		= &pandora_kp_data,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 9917d2f..dc55008 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -329,6 +329,14 @@ static struct regulator_init_data overo_vmmc1 = {
 	.consumer_supplies	= &overo_vmmc1_supply,
 };

+static struct twl4030_codec_audio_data overo_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data overo_codec_data = {
+	.audio = &overo_audio_data,
+};
+
 /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */

 static struct twl4030_platform_data overo_twldata = {
@@ -336,6 +344,7 @@ static struct twl4030_platform_data overo_twldata = {
 	.irq_end	= TWL4030_IRQ_END,
 	.gpio		= &overo_gpio_data,
 	.usb		= &overo_usb_data,
+	.codec		= &overo_codec_data,
 	.vmmc1		= &overo_vmmc1,
 };

diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index b7b3220..f1b4e7c 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -229,6 +229,14 @@ static struct twl4030_madc_platform_data zoom2_madc_data = {
 	.irq_line	= 1,
 };

+static struct twl4030_codec_audio_data zoom2_audio_data = {
+	.audio_mclk = 26000000,
+};
+
+static struct twl4030_codec_data zoom2_codec_data = {
+	.audio = &zoom2_audio_data,
+};
+
 static struct twl4030_platform_data zoom2_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -239,6 +247,7 @@ static struct twl4030_platform_data zoom2_twldata = {
 	.usb		= &zoom2_usb_data,
 	.gpio		= &zoom2_gpio_data,
 	.keypad		= &zoom2_kp_twl4030_data,
+	.codec		= &zoom2_codec_data,
 	.vmmc1          = &zoom2_vmmc1,
 	.vmmc2          = &zoom2_vmmc2,
 	.vsim           = &zoom2_vsim,
--
1.6.5.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4 v2] ASoC: TWL4030: use the twl4030-codec.h for register descriptions
  2009-10-22 10:26   ` [PATCH 2/4 v2] OMAP: Platform support for twl4030_codec MFD Peter Ujfalusi
@ 2009-10-22 10:26     ` Peter Ujfalusi
  2009-10-22 10:26       ` [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD Peter Ujfalusi
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-22 10:26 UTC (permalink / raw)
  To: alsa-devel, linux-omap, sameo; +Cc: linux-kernel, tony, broonie

Remove the register descriptions from the twl4030.h file and use
the linux/mfd/twl4030-codec.h instead, which has the codec
related register descriptions also.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
---
 sound/soc/codecs/twl4030.h |  242 +------------------------------------------
 1 files changed, 6 insertions(+), 236 deletions(-)

diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa2..dd6396e 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
 #ifndef __TWL4030_AUDIO_H__
 #define __TWL4030_AUDIO_H__

-#define TWL4030_REG_CODEC_MODE		0x1
-#define TWL4030_REG_OPTION		0x2
-#define TWL4030_REG_UNKNOWN		0x3
-#define TWL4030_REG_MICBIAS_CTL		0x4
-#define TWL4030_REG_ANAMICL		0x5
-#define TWL4030_REG_ANAMICR		0x6
-#define TWL4030_REG_AVADC_CTL		0x7
-#define TWL4030_REG_ADCMICSEL		0x8
-#define TWL4030_REG_DIGMIXING		0x9
-#define TWL4030_REG_ATXL1PGA		0xA
-#define TWL4030_REG_ATXR1PGA		0xB
-#define TWL4030_REG_AVTXL2PGA		0xC
-#define TWL4030_REG_AVTXR2PGA		0xD
-#define TWL4030_REG_AUDIO_IF		0xE
-#define TWL4030_REG_VOICE_IF		0xF
-#define TWL4030_REG_ARXR1PGA		0x10
-#define TWL4030_REG_ARXL1PGA		0x11
-#define TWL4030_REG_ARXR2PGA		0x12
-#define TWL4030_REG_ARXL2PGA		0x13
-#define TWL4030_REG_VRXPGA		0x14
-#define TWL4030_REG_VSTPGA		0x15
-#define TWL4030_REG_VRX2ARXPGA		0x16
-#define TWL4030_REG_AVDAC_CTL		0x17
-#define TWL4030_REG_ARX2VTXPGA		0x18
-#define TWL4030_REG_ARXL1_APGA_CTL	0x19
-#define TWL4030_REG_ARXR1_APGA_CTL	0x1A
-#define TWL4030_REG_ARXL2_APGA_CTL	0x1B
-#define TWL4030_REG_ARXR2_APGA_CTL	0x1C
-#define TWL4030_REG_ATX2ARXPGA		0x1D
-#define TWL4030_REG_BT_IF		0x1E
-#define TWL4030_REG_BTPGA		0x1F
-#define TWL4030_REG_BTSTPGA		0x20
-#define TWL4030_REG_EAR_CTL		0x21
-#define TWL4030_REG_HS_SEL		0x22
-#define TWL4030_REG_HS_GAIN_SET		0x23
-#define TWL4030_REG_HS_POPN_SET		0x24
-#define TWL4030_REG_PREDL_CTL		0x25
-#define TWL4030_REG_PREDR_CTL		0x26
-#define TWL4030_REG_PRECKL_CTL		0x27
-#define TWL4030_REG_PRECKR_CTL		0x28
-#define TWL4030_REG_HFL_CTL		0x29
-#define TWL4030_REG_HFR_CTL		0x2A
-#define TWL4030_REG_ALC_CTL		0x2B
-#define TWL4030_REG_ALC_SET1		0x2C
-#define TWL4030_REG_ALC_SET2		0x2D
-#define TWL4030_REG_BOOST_CTL		0x2E
-#define TWL4030_REG_SOFTVOL_CTL		0x2F
-#define TWL4030_REG_DTMF_FREQSEL	0x30
-#define TWL4030_REG_DTMF_TONEXT1H	0x31
-#define TWL4030_REG_DTMF_TONEXT1L	0x32
-#define TWL4030_REG_DTMF_TONEXT2H	0x33
-#define TWL4030_REG_DTMF_TONEXT2L	0x34
-#define TWL4030_REG_DTMF_TONOFF		0x35
-#define TWL4030_REG_DTMF_WANONOFF	0x36
-#define TWL4030_REG_I2S_RX_SCRAMBLE_H	0x37
-#define TWL4030_REG_I2S_RX_SCRAMBLE_M	0x38
-#define TWL4030_REG_I2S_RX_SCRAMBLE_L	0x39
-#define TWL4030_REG_APLL_CTL		0x3A
-#define TWL4030_REG_DTMF_CTL		0x3B
-#define TWL4030_REG_DTMF_PGA_CTL2	0x3C
-#define TWL4030_REG_DTMF_PGA_CTL1	0x3D
-#define TWL4030_REG_MISC_SET_1		0x3E
-#define TWL4030_REG_PCMBTMUX		0x3F
-#define TWL4030_REG_RX_PATH_SEL		0x43
-#define TWL4030_REG_VDL_APGA_CTL	0x44
-#define TWL4030_REG_VIBRA_CTL		0x45
-#define TWL4030_REG_VIBRA_SET		0x46
-#define TWL4030_REG_VIBRA_PWM_SET	0x47
-#define TWL4030_REG_ANAMIC_GAIN		0x48
-#define TWL4030_REG_MISC_SET_2		0x49
-#define TWL4030_REG_SW_SHADOW		0x4A
+/* Register descriptions are here */
+#include <linux/mfd/twl4030-codec.h>

+/* Sgadow register used by the audio driver */
+#define TWL4030_REG_SW_SHADOW		0x4A
 #define TWL4030_CACHEREGNUM	(TWL4030_REG_SW_SHADOW + 1)

-/* Bitfield Definitions */
-
-/* TWL4030_CODEC_MODE (0x01) Fields */
-
-#define TWL4030_APLL_RATE		0xF0
-#define TWL4030_APLL_RATE_8000		0x00
-#define TWL4030_APLL_RATE_11025		0x10
-#define TWL4030_APLL_RATE_12000		0x20
-#define TWL4030_APLL_RATE_16000		0x40
-#define TWL4030_APLL_RATE_22050		0x50
-#define TWL4030_APLL_RATE_24000		0x60
-#define TWL4030_APLL_RATE_32000		0x80
-#define TWL4030_APLL_RATE_44100		0x90
-#define TWL4030_APLL_RATE_48000		0xA0
-#define TWL4030_APLL_RATE_96000		0xE0
-#define TWL4030_SEL_16K			0x08
-#define TWL4030_CODECPDZ		0x02
-#define TWL4030_OPT_MODE		0x01
-#define TWL4030_OPTION_1		(1 << 0)
-#define TWL4030_OPTION_2		(0 << 0)
-
-/* TWL4030_OPTION (0x02) Fields */
-
-#define TWL4030_ATXL1_EN		(1 << 0)
-#define TWL4030_ATXR1_EN		(1 << 1)
-#define TWL4030_ATXL2_VTXL_EN		(1 << 2)
-#define TWL4030_ATXR2_VTXR_EN		(1 << 3)
-#define TWL4030_ARXL1_VRX_EN		(1 << 4)
-#define TWL4030_ARXR1_EN		(1 << 5)
-#define TWL4030_ARXL2_EN		(1 << 6)
-#define TWL4030_ARXR2_EN		(1 << 7)
-
-/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
-
-#define TWL4030_MICBIAS2_CTL		0x40
-#define TWL4030_MICBIAS1_CTL		0x20
-#define TWL4030_HSMICBIAS_EN		0x04
-#define TWL4030_MICBIAS2_EN		0x02
-#define TWL4030_MICBIAS1_EN		0x01
-
-/* ANAMICL (0x05) Fields */
-
-#define TWL4030_CNCL_OFFSET_START	0x80
-#define TWL4030_OFFSET_CNCL_SEL		0x60
-#define TWL4030_OFFSET_CNCL_SEL_ARX1	0x00
-#define TWL4030_OFFSET_CNCL_SEL_ARX2	0x20
-#define TWL4030_OFFSET_CNCL_SEL_VRX	0x40
-#define TWL4030_OFFSET_CNCL_SEL_ALL	0x60
-#define TWL4030_MICAMPL_EN		0x10
-#define TWL4030_CKMIC_EN		0x08
-#define TWL4030_AUXL_EN			0x04
-#define TWL4030_HSMIC_EN		0x02
-#define TWL4030_MAINMIC_EN		0x01
-
-/* ANAMICR (0x06) Fields */
-
-#define TWL4030_MICAMPR_EN		0x10
-#define TWL4030_AUXR_EN			0x04
-#define TWL4030_SUBMIC_EN		0x01
-
-/* AVADC_CTL (0x07) Fields */
-
-#define TWL4030_ADCL_EN			0x08
-#define TWL4030_AVADC_CLK_PRIORITY	0x04
-#define TWL4030_ADCR_EN			0x02
-
-/* TWL4030_REG_ADCMICSEL (0x08) Fields */
-
-#define TWL4030_DIGMIC1_EN		0x08
-#define TWL4030_TX2IN_SEL		0x04
-#define TWL4030_DIGMIC0_EN		0x02
-#define TWL4030_TX1IN_SEL		0x01
-
-/* AUDIO_IF (0x0E) Fields */
-
-#define TWL4030_AIF_SLAVE_EN		0x80
-#define TWL4030_DATA_WIDTH		0x60
-#define TWL4030_DATA_WIDTH_16S_16W	0x00
-#define TWL4030_DATA_WIDTH_32S_16W	0x40
-#define TWL4030_DATA_WIDTH_32S_24W	0x60
-#define TWL4030_AIF_FORMAT		0x18
-#define TWL4030_AIF_FORMAT_CODEC	0x00
-#define TWL4030_AIF_FORMAT_LEFT		0x08
-#define TWL4030_AIF_FORMAT_RIGHT	0x10
-#define TWL4030_AIF_FORMAT_TDM		0x18
-#define TWL4030_AIF_TRI_EN		0x04
-#define TWL4030_CLK256FS_EN		0x02
-#define TWL4030_AIF_EN			0x01
-
-/* VOICE_IF (0x0F) Fields */
-
-#define TWL4030_VIF_SLAVE_EN		0x80
-#define TWL4030_VIF_DIN_EN		0x40
-#define TWL4030_VIF_DOUT_EN		0x20
-#define TWL4030_VIF_SWAP		0x10
-#define TWL4030_VIF_FORMAT		0x08
-#define TWL4030_VIF_TRI_EN		0x04
-#define TWL4030_VIF_SUB_EN		0x02
-#define TWL4030_VIF_EN			0x01
-
-/* EAR_CTL (0x21) */
-#define TWL4030_EAR_GAIN		0x30
-
-/* HS_GAIN_SET (0x23) Fields */
-
-#define TWL4030_HSR_GAIN		0x0C
-#define TWL4030_HSR_GAIN_PWR_DOWN	0x00
-#define TWL4030_HSR_GAIN_PLUS_6DB	0x04
-#define TWL4030_HSR_GAIN_0DB		0x08
-#define TWL4030_HSR_GAIN_MINUS_6DB	0x0C
-#define TWL4030_HSL_GAIN		0x03
-#define TWL4030_HSL_GAIN_PWR_DOWN	0x00
-#define TWL4030_HSL_GAIN_PLUS_6DB	0x01
-#define TWL4030_HSL_GAIN_0DB		0x02
-#define TWL4030_HSL_GAIN_MINUS_6DB	0x03
-
-/* HS_POPN_SET (0x24) Fields */
-
-#define TWL4030_VMID_EN			0x40
-#define	TWL4030_EXTMUTE			0x20
-#define TWL4030_RAMP_DELAY		0x1C
-#define TWL4030_RAMP_DELAY_20MS		0x00
-#define TWL4030_RAMP_DELAY_40MS		0x04
-#define TWL4030_RAMP_DELAY_81MS		0x08
-#define TWL4030_RAMP_DELAY_161MS	0x0C
-#define TWL4030_RAMP_DELAY_323MS	0x10
-#define TWL4030_RAMP_DELAY_645MS	0x14
-#define TWL4030_RAMP_DELAY_1291MS	0x18
-#define TWL4030_RAMP_DELAY_2581MS	0x1C
-#define TWL4030_RAMP_EN			0x02
-
-/* PREDL_CTL (0x25) */
-#define TWL4030_PREDL_GAIN		0x30
-
-/* PREDR_CTL (0x26) */
-#define TWL4030_PREDR_GAIN		0x30
-
-/* PRECKL_CTL (0x27) */
-#define TWL4030_PRECKL_GAIN		0x30
-
-/* PRECKR_CTL (0x28) */
-#define TWL4030_PRECKR_GAIN		0x30
-
-/* HFL_CTL (0x29, 0x2A) Fields */
-#define TWL4030_HF_CTL_HB_EN		0x04
-#define TWL4030_HF_CTL_LOOP_EN		0x08
-#define TWL4030_HF_CTL_RAMP_EN		0x10
-#define TWL4030_HF_CTL_REF_EN		0x20
-
-/* APLL_CTL (0x3A) Fields */
-
-#define TWL4030_APLL_EN			0x10
-#define TWL4030_APLL_INFREQ		0x0F
-#define TWL4030_APLL_INFREQ_19200KHZ	0x05
-#define TWL4030_APLL_INFREQ_26000KHZ	0x06
-#define TWL4030_APLL_INFREQ_38400KHZ	0x0F
-
-/* REG_MISC_SET_1 (0x3E) Fields */
-
-#define TWL4030_CLK64_EN		0x80
-#define TWL4030_SCRAMBLE_EN		0x40
-#define TWL4030_FMLOOP_EN		0x20
-#define TWL4030_SMOOTH_ANAVOL_EN	0x02
-#define TWL4030_DIGMIC_LR_SWAP_EN	0x01
-
 /* TWL4030_REG_SW_SHADOW (0x4A) Fields */
 #define TWL4030_HFL_EN			0x01
 #define TWL4030_HFR_EN			0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
 };

 #endif	/* End of __TWL4030_AUDIO_H__ */
+
+
--
1.6.5.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD
  2009-10-22 10:26     ` [PATCH 3/4 v2] ASoC: TWL4030: use the twl4030-codec.h for register descriptions Peter Ujfalusi
@ 2009-10-22 10:26       ` Peter Ujfalusi
  2009-10-22 16:56         ` Mark Brown
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-22 10:26 UTC (permalink / raw)
  To: alsa-devel, linux-omap, sameo; +Cc: linux-kernel, tony, broonie

Change the way how the twl4030 soc codec driver is
loaded/probed.
Use the device probing via tlw4030_codec MFD device.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
---
 sound/soc/codecs/Kconfig   |    1 +
 sound/soc/codecs/twl4030.c |  203 +++++++++++++++++++++++++++-----------------
 2 files changed, 127 insertions(+), 77 deletions(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d30fce7..3df3497 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -147,6 +147,7 @@ config SND_SOC_TLV320DAC33
 	tristate

 config SND_SOC_TWL4030
+	select TWL4030_CODEC
 	tristate

 config SND_SOC_UDA134X
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 559e9b2..5c5a4c0 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -120,6 +120,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {

 /* codec private data */
 struct twl4030_priv {
+	struct snd_soc_codec codec;
+
 	unsigned int bypass_state;
 	unsigned int codec_powered;
 	unsigned int codec_muted;
@@ -183,19 +185,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
 static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
 {
 	struct twl4030_priv *twl4030 = codec->private_data;
-	u8 mode;
+	int mode;

 	if (enable == twl4030->codec_powered)
 		return;

-	mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
 	if (enable)
-		mode |= TWL4030_CODECPDZ;
+		mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
 	else
-		mode &= ~TWL4030_CODECPDZ;
+		mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);

-	twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-	twl4030->codec_powered = enable;
+	if (mode >= 0) {
+		twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
+		twl4030->codec_powered = enable;
+	}

 	/* REVISIT: this delay is present in TI sample drivers */
 	/* but there seems to be no TRM requirement for it     */
@@ -219,22 +222,20 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
 static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
 {
 	struct twl4030_priv *twl4030 = codec->private_data;
-	u8 reg_val;
+	int status;

 	if (mute == twl4030->codec_muted)
 		return;

-	if (mute) {
+	if (mute)
 		/* Disable PLL */
-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
-		reg_val &= ~TWL4030_APLL_EN;
-		twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
-	} else {
+		status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
+	else
 		/* Enable PLL */
-		reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
-		reg_val |= TWL4030_APLL_EN;
-		twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
-	}
+		status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
+
+	if (status >= 0)
+		twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);

 	twl4030->codec_muted = mute;
 }
@@ -2123,7 +2124,7 @@ struct snd_soc_dai twl4030_dai[] = {
 };
 EXPORT_SYMBOL_GPL(twl4030_dai);

-static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
+static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 	struct snd_soc_codec *codec = socdev->card->codec;
@@ -2133,7 +2134,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }

-static int twl4030_resume(struct platform_device *pdev)
+static int twl4030_soc_resume(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 	struct snd_soc_codec *codec = socdev->card->codec;
@@ -2143,32 +2144,21 @@ static int twl4030_resume(struct platform_device *pdev)
 	return 0;
 }

-/*
- * initialize the driver
- * register the mixer and dsp interfaces with the kernel
- */
+static struct snd_soc_codec *twl4030_codec;

-static int twl4030_init(struct snd_soc_device *socdev)
+static int twl4030_soc_probe(struct platform_device *pdev)
 {
-	struct snd_soc_codec *codec = socdev->card->codec;
+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 	struct twl4030_setup_data *setup = socdev->codec_data;
-	struct twl4030_priv *twl4030 = codec->private_data;
-	int ret = 0;
+	struct snd_soc_codec *codec;
+	struct twl4030_priv *twl4030;
+	int ret;

-	printk(KERN_INFO "TWL4030 Audio Codec init \n");
+	BUG_ON(!twl4030_codec);

-	codec->name = "twl4030";
-	codec->owner = THIS_MODULE;
-	codec->read = twl4030_read_reg_cache;
-	codec->write = twl4030_write;
-	codec->set_bias_level = twl4030_set_bias_level;
-	codec->dai = twl4030_dai;
-	codec->num_dai = ARRAY_SIZE(twl4030_dai),
-	codec->reg_cache_size = sizeof(twl4030_reg);
-	codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
-					GFP_KERNEL);
-	if (codec->reg_cache == NULL)
-		return -ENOMEM;
+	codec = twl4030_codec;
+	twl4030 = codec->private_data;
+	socdev->card->codec = codec;

 	/* Configuration for headset ramp delay from setup data */
 	if (setup) {
@@ -2190,100 +2180,159 @@ static int twl4030_init(struct snd_soc_device *socdev)
 	/* register pcms */
 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
 	if (ret < 0) {
-		printk(KERN_ERR "twl4030: failed to create pcms\n");
-		goto pcm_err;
+		dev_err(&pdev->dev, "failed to create pcms\n");
+		return ret;
 	}

-	twl4030_init_chip(codec);
-
-	/* power on device */
-	twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	snd_soc_add_controls(codec, twl4030_snd_controls,
 				ARRAY_SIZE(twl4030_snd_controls));
 	twl4030_add_widgets(codec);

 	ret = snd_soc_init_card(socdev);
 	if (ret < 0) {
-		printk(KERN_ERR "twl4030: failed to register card\n");
+		dev_err(&pdev->dev, "failed to register card\n");
 		goto card_err;
 	}

-	return ret;
+	return 0;

 card_err:
 	snd_soc_free_pcms(socdev);
 	snd_soc_dapm_free(socdev);
-pcm_err:
-	kfree(codec->reg_cache);
+
 	return ret;
 }

-static struct snd_soc_device *twl4030_socdev;
-
-static int twl4030_probe(struct platform_device *pdev)
+static int twl4030_soc_remove(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = socdev->card->codec;
+
+	twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	snd_soc_free_pcms(socdev);
+	snd_soc_dapm_free(socdev);
+	kfree(codec->private_data);
+	kfree(codec);
+
+	return 0;
+}
+
+static int __devinit twl4030_codec_probe(struct platform_device *pdev)
+{
+	struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
 	struct snd_soc_codec *codec;
 	struct twl4030_priv *twl4030;
+	int ret;

-	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-	if (codec == NULL)
-		return -ENOMEM;
+	if (!pdata || !(pdata->audio_mclk == 19200000 ||
+			pdata->audio_mclk == 26000000 ||
+			pdata->audio_mclk == 38400000)) {
+		dev_err(&pdev->dev, "Invalid platform_data\n");
+		return -EINVAL;
+	}

 	twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
 	if (twl4030 == NULL) {
-		kfree(codec);
+		dev_err(&pdev->dev, "Can not allocate memroy\n");
 		return -ENOMEM;
 	}

+	codec = &twl4030->codec;
 	codec->private_data = twl4030;
-	socdev->card->codec = codec;
+	codec->dev = &pdev->dev;
+	twl4030_dai[0].dev = &pdev->dev;
+	twl4030_dai[1].dev = &pdev->dev;
+
 	mutex_init(&codec->mutex);
 	INIT_LIST_HEAD(&codec->dapm_widgets);
 	INIT_LIST_HEAD(&codec->dapm_paths);

-	twl4030_socdev = socdev;
-	twl4030_init(socdev);
+	codec->name = "twl4030";
+	codec->owner = THIS_MODULE;
+	codec->read = twl4030_read_reg_cache;
+	codec->write = twl4030_write;
+	codec->set_bias_level = twl4030_set_bias_level;
+	codec->dai = twl4030_dai;
+	codec->num_dai = ARRAY_SIZE(twl4030_dai),
+	codec->reg_cache_size = sizeof(twl4030_reg);
+	codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
+					GFP_KERNEL);
+	if (codec->reg_cache == NULL) {
+		ret = -ENOMEM;
+		goto error_cache;
+	}
+
+	platform_set_drvdata(pdev, twl4030);
+	twl4030_codec = codec;
+
+	/* Set the defaults, and power up the codec */
+	twl4030_init_chip(codec);
+	twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	ret = snd_soc_register_codec(codec);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+		goto error_codec;
+	}
+
+	ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
+		snd_soc_unregister_codec(codec);
+		goto error_codec;
+	}

 	return 0;
+
+error_codec:
+	twl4030_power_down(codec);
+	kfree(codec->reg_cache);
+error_cache:
+	kfree(twl4030);
+	return ret;
 }

-static int twl4030_remove(struct platform_device *pdev)
+static int __devexit twl4030_codec_remove(struct platform_device *pdev)
 {
-	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-	struct snd_soc_codec *codec = socdev->card->codec;
+	struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);

-	printk(KERN_INFO "TWL4030 Audio Codec remove\n");
-	twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	snd_soc_free_pcms(socdev);
-	snd_soc_dapm_free(socdev);
-	kfree(codec->private_data);
-	kfree(codec);
+	kfree(twl4030);

+	twl4030_codec = NULL;
 	return 0;
 }

-struct snd_soc_codec_device soc_codec_dev_twl4030 = {
-	.probe = twl4030_probe,
-	.remove = twl4030_remove,
-	.suspend = twl4030_suspend,
-	.resume = twl4030_resume,
+MODULE_ALIAS("platform:twl4030_codec_audio");
+
+static struct platform_driver twl4030_codec_driver = {
+	.probe		= twl4030_codec_probe,
+	.remove		= __devexit_p(twl4030_codec_remove),
+	.driver		= {
+		.name	= "twl4030_codec_audio",
+		.owner	= THIS_MODULE,
+	},
 };
-EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);

 static int __init twl4030_modinit(void)
 {
-	return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
+	return platform_driver_register(&twl4030_codec_driver);
 }
 module_init(twl4030_modinit);

 static void __exit twl4030_exit(void)
 {
-	snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
+	platform_driver_unregister(&twl4030_codec_driver);
 }
 module_exit(twl4030_exit);

+struct snd_soc_codec_device soc_codec_dev_twl4030 = {
+	.probe = twl4030_soc_probe,
+	.remove = twl4030_soc_remove,
+	.suspend = twl4030_soc_suspend,
+	.resume = twl4030_soc_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
+
 MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
 MODULE_AUTHOR("Steve Sakoman");
 MODULE_LICENSE("GPL");
--
1.6.5.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD
  2009-10-22 10:26       ` [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD Peter Ujfalusi
@ 2009-10-22 16:56         ` Mark Brown
  2009-10-23  5:27           ` Peter Ujfalusi
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2009-10-22 16:56 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: alsa-devel, linux-omap, sameo, linux-kernel, tony

On Thu, Oct 22, 2009 at 01:26:48PM +0300, Peter Ujfalusi wrote:
> Change the way how the twl4030 soc codec driver is
> loaded/probed.
> Use the device probing via tlw4030_codec MFD device.

I'm OK with the series but:

> @@ -147,6 +147,7 @@ config SND_SOC_TLV320DAC33
>  	tristate
> 
>  config SND_SOC_TWL4030
> +	select TWL4030_CODEC
>  	tristate

due to Kconfig ignoring dependencies all the individual machine drivers
are going to need to select this, and SND_SOC_ALL_CODECS will need to
select it if the MFD core is enabled.  I should be able to fix this up
myself so no need to repost for that alone.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD
  2009-10-22 16:56         ` Mark Brown
@ 2009-10-23  5:27           ` Peter Ujfalusi
  2009-10-23 12:59             ` [alsa-devel] " Mark Brown
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Ujfalusi @ 2009-10-23  5:27 UTC (permalink / raw)
  To: ext Mark Brown; +Cc: alsa-devel, linux-omap, sameo, linux-kernel, tony

On Thursday 22 October 2009 19:56:44 ext Mark Brown wrote:
> On Thu, Oct 22, 2009 at 01:26:48PM +0300, Peter Ujfalusi wrote:
> > Change the way how the twl4030 soc codec driver is
> > loaded/probed.
> > Use the device probing via tlw4030_codec MFD device.
> 
> I'm OK with the series but:
> > @@ -147,6 +147,7 @@ config SND_SOC_TLV320DAC33
> >  	tristate
> >
> >  config SND_SOC_TWL4030
> > +	select TWL4030_CODEC
> >  	tristate
> 
> due to Kconfig ignoring dependencies all the individual machine drivers
> are going to need to select this, and SND_SOC_ALL_CODECS will need to
> select it if the MFD core is enabled.  I should be able to fix this up
> myself so no need to repost for that alone.

Hmm, what do you mean by that?
I have checked it, and selecting the machine driver will enables the MFD_CORE 
and TWL4030_CODEC in .config, also disabling the machine driver will also 
disable the MFD_CORE and the TWL4030_CODEC.

Can you go into details?

-- 
Péter

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [alsa-devel] [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD
  2009-10-23  5:27           ` Peter Ujfalusi
@ 2009-10-23 12:59             ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2009-10-23 12:59 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: tony, alsa-devel, linux-omap, sameo, linux-kernel

On Fri, Oct 23, 2009 at 08:27:55AM +0300, Peter Ujfalusi wrote:

> Hmm, what do you mean by that?
> I have checked it, and selecting the machine driver will enables the MFD_CORE 
> and TWL4030_CODEC in .config, also disabling the machine driver will also 
> disable the MFD_CORE and the TWL4030_CODEC.

> Can you go into details?

Kconfig has never guaranteed to pay any attention to dependencies of
things that were enabled as a result of a select statement - they would
be silently ignored.  I've done some tests and it does seem that this is
doing what would be expected at the minute but looking at the Kconfig
changelogs I can't see anything that makes this an intentional change.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core
  2009-10-22 10:26 ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Peter Ujfalusi
  2009-10-22 10:26   ` [PATCH 2/4 v2] OMAP: Platform support for twl4030_codec MFD Peter Ujfalusi
@ 2009-10-23 14:07   ` Samuel Ortiz
  2009-10-25 17:18     ` [alsa-devel] " Mark Brown
  1 sibling, 1 reply; 10+ messages in thread
From: Samuel Ortiz @ 2009-10-23 14:07 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: alsa-devel, linux-omap, linux-kernel, tony, broonie

Hi Peter,

On Thu, Oct 22, 2009 at 01:26:45PM +0300, Peter Ujfalusi wrote:
> New MFD child to twl4030 MFD device.
> 
> Reason for the twl4030_codec MFD: the vibra control is actually in the codec
> part of the twl4030. If both the vibra and the audio functionality is needed
> from the twl4030 at the same time, than they need to control the codec power
> and APLL at the same time without breaking the other driver.
> Also these two has to be able to work without the need for the other driver.
> 
> This MFD device will be used by the drivers, which needs resources
> from the twl4030 codec like audio and vibra.
> 
> The platform specific configuration data is passed along to the
> child drivers (audio, vibra).
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
As agreed, Mark is taking this one. So:
Acked-by: Samuel Ortiz <sameo@linux.intel.com>

Cheers,
Samuel.

> ---
>  drivers/mfd/Kconfig               |    6 +
>  drivers/mfd/Makefile              |    1 +
>  drivers/mfd/twl4030-codec.c       |  241 +++++++++++++++++++++++++++++++++
>  drivers/mfd/twl4030-core.c        |   14 ++
>  include/linux/i2c/twl4030.h       |   18 +++
>  include/linux/mfd/twl4030-codec.h |  271 +++++++++++++++++++++++++++++++++++++
>  6 files changed, 551 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mfd/twl4030-codec.c
>  create mode 100644 include/linux/mfd/twl4030-codec.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 570be13..08f2d07 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -121,6 +121,12 @@ config TWL4030_POWER
>  	  and load scripts controling which resources are switched off/on
>  	  or reset when a sleep, wakeup or warm reset event occurs.
> 
> +config TWL4030_CODEC
> +	bool
> +	depends on TWL4030_CORE
> +	select MFD_CORE
> +	default n
> +
>  config MFD_TMIO
>  	bool
>  	default n
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f3b277b..af0fc90 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_MENELAUS)		+= menelaus.o
> 
>  obj-$(CONFIG_TWL4030_CORE)	+= twl4030-core.o twl4030-irq.o
>  obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
> +obj-$(CONFIG_TWL4030_CODEC)	+= twl4030-codec.o
> 
>  obj-$(CONFIG_MFD_MC13783)	+= mc13783-core.o
> 
> diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
> new file mode 100644
> index 0000000..9710307
> --- /dev/null
> +++ b/drivers/mfd/twl4030-codec.c
> @@ -0,0 +1,241 @@
> +/*
> + * MFD driver for twl4030 codec submodule
> + *
> + * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
> + *
> + * Copyright:   (C) 2009 Nokia Corporation
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program 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., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/fs.h>
> +#include <linux/platform_device.h>
> +#include <linux/i2c/twl4030.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/twl4030-codec.h>
> +
> +#define TWL4030_CODEC_CELLS	2
> +
> +static struct platform_device *twl4030_codec_dev;
> +
> +struct twl4030_codec_resource {
> +	int request_count;
> +	u8 reg;
> +	u8 mask;
> +};
> +
> +struct twl4030_codec {
> +	struct mutex mutex;
> +	struct twl4030_codec_resource resource[TWL4030_CODEC_RES_MAX];
> +	struct mfd_cell cells[TWL4030_CODEC_CELLS];
> +};
> +
> +/*
> + * Modify the resource, the function returns the content of the register
> + * after the modification.
> + */
> +static int twl4030_codec_set_resource(enum twl4030_codec_res id, int enable)
> +{
> +	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
> +	u8 val;
> +
> +	twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
> +			codec->resource[id].reg);
> +
> +	if (enable)
> +		val |= codec->resource[id].mask;
> +	else
> +		val &= ~codec->resource[id].mask;
> +
> +	twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
> +					val, codec->resource[id].reg);
> +
> +	return val;
> +}
> +
> +static inline int twl4030_codec_get_resource(enum twl4030_codec_res id)
> +{
> +	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
> +	u8 val;
> +
> +	twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
> +			codec->resource[id].reg);
> +
> +	return val;
> +}
> +
> +/*
> + * Enable the resource.
> + * The function returns with error or the content of the register
> + */
> +int twl4030_codec_enable_resource(enum twl4030_codec_res id)
> +{
> +	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
> +	int val;
> +
> +	if (id >= TWL4030_CODEC_RES_MAX) {
> +		dev_err(&twl4030_codec_dev->dev,
> +				"Invalid resource ID (%u)\n", id);
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&codec->mutex);
> +	if (!codec->resource[id].request_count)
> +		/* Resource was disabled, enable it */
> +		val = twl4030_codec_set_resource(id, 1);
> +	else
> +		val = twl4030_codec_get_resource(id);
> +
> +	codec->resource[id].request_count++;
> +	mutex_unlock(&codec->mutex);
> +
> +	return val;
> +}
> +EXPORT_SYMBOL_GPL(twl4030_codec_enable_resource);
> +
> +/*
> + * Disable the resource.
> + * The function returns with error or the content of the register
> + */
> +int twl4030_codec_disable_resource(unsigned id)
> +{
> +	struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev);
> +	int val;
> +
> +	if (id >= TWL4030_CODEC_RES_MAX) {
> +		dev_err(&twl4030_codec_dev->dev,
> +				"Invalid resource ID (%u)\n", id);
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&codec->mutex);
> +	if (!codec->resource[id].request_count) {
> +		dev_err(&twl4030_codec_dev->dev,
> +			"Resource has been disabled already (%u)\n", id);
> +		mutex_unlock(&codec->mutex);
> +		return -EPERM;
> +	}
> +	codec->resource[id].request_count--;
> +
> +	if (!codec->resource[id].request_count)
> +		/* Resource can be disabled now */
> +		val = twl4030_codec_set_resource(id, 0);
> +	else
> +		val = twl4030_codec_get_resource(id);
> +
> +	mutex_unlock(&codec->mutex);
> +
> +	return val;
> +}
> +EXPORT_SYMBOL_GPL(twl4030_codec_disable_resource);
> +
> +static int __devinit twl4030_codec_probe(struct platform_device *pdev)
> +{
> +	struct twl4030_codec *codec;
> +	struct twl4030_codec_data *pdata = pdev->dev.platform_data;
> +	struct mfd_cell *cell = NULL;
> +	int ret, childs = 0;
> +
> +	codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL);
> +	if (!codec)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, codec);
> +
> +	twl4030_codec_dev = pdev;
> +	mutex_init(&codec->mutex);
> +
> +	/* Codec power */
> +	codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
> +	codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ;
> +
> +	/* PLL */
> +	codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL;
> +	codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN;
> +
> +	if (pdata->audio) {
> +		cell = &codec->cells[childs];
> +		cell->name = "twl4030_codec_audio";
> +		cell->platform_data = pdata->audio;
> +		cell->data_size = sizeof(*pdata->audio);
> +		childs++;
> +	}
> +	if (pdata->vibra) {
> +		cell = &codec->cells[childs];
> +		cell->name = "twl4030_codec_vibra";
> +		cell->platform_data = pdata->vibra;
> +		cell->data_size = sizeof(*pdata->vibra);
> +		childs++;
> +	}
> +
> +	if (childs)
> +		ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells,
> +				      childs, NULL, 0);
> +	else {
> +		dev_err(&pdev->dev, "No platform data found for childs\n");
> +		ret = -ENODEV;
> +	}
> +
> +	if (!ret)
> +		return 0;
> +
> +	platform_set_drvdata(pdev, NULL);
> +	kfree(codec);
> +	twl4030_codec_dev = NULL;
> +	return ret;
> +}
> +
> +static int __devexit twl4030_codec_remove(struct platform_device *pdev)
> +{
> +	struct twl4030_codec *codec = platform_get_drvdata(pdev);
> +
> +	mfd_remove_devices(&pdev->dev);
> +	platform_set_drvdata(pdev, NULL);
> +	kfree(codec);
> +	twl4030_codec_dev = NULL;
> +
> +	return 0;
> +}
> +
> +MODULE_ALIAS("platform:twl4030_codec");
> +
> +static struct platform_driver twl4030_codec_driver = {
> +	.probe		= twl4030_codec_probe,
> +	.remove		= __devexit_p(twl4030_codec_remove),
> +	.driver		= {
> +		.owner	= THIS_MODULE,
> +		.name	= "twl4030_codec",
> +	},
> +};
> +
> +static int __devinit twl4030_codec_init(void)
> +{
> +	return platform_driver_register(&twl4030_codec_driver);
> +}
> +module_init(twl4030_codec_init);
> +
> +static void __devexit twl4030_codec_exit(void)
> +{
> +	platform_driver_unregister(&twl4030_codec_driver);
> +}
> +module_exit(twl4030_codec_exit);
> +
> +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
> +MODULE_LICENSE("GPL");
> +
> diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
> index e424cf6..0ee81e4 100644
> --- a/drivers/mfd/twl4030-core.c
> +++ b/drivers/mfd/twl4030-core.c
> @@ -114,6 +114,12 @@
>  #define twl_has_watchdog()        false
>  #endif
> 
> +#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
> +#define twl_has_codec()	true
> +#else
> +#define twl_has_codec()	false
> +#endif
> +
>  /* Triton Core internal information (BEGIN) */
> 
>  /* Last - for index max*/
> @@ -557,6 +563,14 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
>  			return PTR_ERR(child);
>  	}
> 
> +	if (twl_has_codec() && pdata->codec) {
> +		child = add_child(1, "twl4030_codec",
> +				pdata->codec, sizeof(*pdata->codec),
> +				false, 0, 0);
> +		if (IS_ERR(child))
> +			return PTR_ERR(child);
> +	}
> +
>  	if (twl_has_regulator()) {
>  		/*
>  		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
> diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
> index 2d02dfd..42d6c72 100644
> --- a/include/linux/i2c/twl4030.h
> +++ b/include/linux/i2c/twl4030.h
> @@ -401,6 +401,23 @@ struct twl4030_power_data {
> 
>  extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
> 
> +struct twl4030_codec_audio_data {
> +	unsigned int	audio_mclk;
> +	unsigned int ramp_delay_value;
> +	unsigned int hs_extmute:1;
> +	void (*set_hs_extmute)(int mute);
> +};
> +
> +struct twl4030_codec_vibra_data {
> +	unsigned int	audio_mclk;
> +	unsigned int	coexist;
> +};
> +
> +struct twl4030_codec_data {
> +	struct twl4030_codec_audio_data		*audio;
> +	struct twl4030_codec_vibra_data		*vibra;
> +};
> +
>  struct twl4030_platform_data {
>  	unsigned				irq_base, irq_end;
>  	struct twl4030_bci_platform_data	*bci;
> @@ -409,6 +426,7 @@ struct twl4030_platform_data {
>  	struct twl4030_keypad_data		*keypad;
>  	struct twl4030_usb_data			*usb;
>  	struct twl4030_power_data		*power;
> +	struct twl4030_codec_data		*codec;
> 
>  	/* LDO regulators */
>  	struct regulator_init_data		*vdac;
> diff --git a/include/linux/mfd/twl4030-codec.h b/include/linux/mfd/twl4030-codec.h
> new file mode 100644
> index 0000000..ef0a304
> --- /dev/null
> +++ b/include/linux/mfd/twl4030-codec.h
> @@ -0,0 +1,271 @@
> +/*
> + * MFD driver for twl4030 codec submodule
> + *
> + * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
> + *
> + * Copyright:   (C) 2009 Nokia Corporation
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program 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., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + *
> + */
> +
> +#ifndef __TWL4030_CODEC_H__
> +#define __TWL4030_CODEC_H__
> +
> +/* Codec registers */
> +#define TWL4030_REG_CODEC_MODE		0x01
> +#define TWL4030_REG_OPTION		0x02
> +#define TWL4030_REG_UNKNOWN		0x03
> +#define TWL4030_REG_MICBIAS_CTL		0x04
> +#define TWL4030_REG_ANAMICL		0x05
> +#define TWL4030_REG_ANAMICR		0x06
> +#define TWL4030_REG_AVADC_CTL		0x07
> +#define TWL4030_REG_ADCMICSEL		0x08
> +#define TWL4030_REG_DIGMIXING		0x09
> +#define TWL4030_REG_ATXL1PGA		0x0A
> +#define TWL4030_REG_ATXR1PGA		0x0B
> +#define TWL4030_REG_AVTXL2PGA		0x0C
> +#define TWL4030_REG_AVTXR2PGA		0x0D
> +#define TWL4030_REG_AUDIO_IF		0x0E
> +#define TWL4030_REG_VOICE_IF		0x0F
> +#define TWL4030_REG_ARXR1PGA		0x10
> +#define TWL4030_REG_ARXL1PGA		0x11
> +#define TWL4030_REG_ARXR2PGA		0x12
> +#define TWL4030_REG_ARXL2PGA		0x13
> +#define TWL4030_REG_VRXPGA		0x14
> +#define TWL4030_REG_VSTPGA		0x15
> +#define TWL4030_REG_VRX2ARXPGA		0x16
> +#define TWL4030_REG_AVDAC_CTL		0x17
> +#define TWL4030_REG_ARX2VTXPGA		0x18
> +#define TWL4030_REG_ARXL1_APGA_CTL	0x19
> +#define TWL4030_REG_ARXR1_APGA_CTL	0x1A
> +#define TWL4030_REG_ARXL2_APGA_CTL	0x1B
> +#define TWL4030_REG_ARXR2_APGA_CTL	0x1C
> +#define TWL4030_REG_ATX2ARXPGA		0x1D
> +#define TWL4030_REG_BT_IF		0x1E
> +#define TWL4030_REG_BTPGA		0x1F
> +#define TWL4030_REG_BTSTPGA		0x20
> +#define TWL4030_REG_EAR_CTL		0x21
> +#define TWL4030_REG_HS_SEL		0x22
> +#define TWL4030_REG_HS_GAIN_SET		0x23
> +#define TWL4030_REG_HS_POPN_SET		0x24
> +#define TWL4030_REG_PREDL_CTL		0x25
> +#define TWL4030_REG_PREDR_CTL		0x26
> +#define TWL4030_REG_PRECKL_CTL		0x27
> +#define TWL4030_REG_PRECKR_CTL		0x28
> +#define TWL4030_REG_HFL_CTL		0x29
> +#define TWL4030_REG_HFR_CTL		0x2A
> +#define TWL4030_REG_ALC_CTL		0x2B
> +#define TWL4030_REG_ALC_SET1		0x2C
> +#define TWL4030_REG_ALC_SET2		0x2D
> +#define TWL4030_REG_BOOST_CTL		0x2E
> +#define TWL4030_REG_SOFTVOL_CTL		0x2F
> +#define TWL4030_REG_DTMF_FREQSEL	0x30
> +#define TWL4030_REG_DTMF_TONEXT1H	0x31
> +#define TWL4030_REG_DTMF_TONEXT1L	0x32
> +#define TWL4030_REG_DTMF_TONEXT2H	0x33
> +#define TWL4030_REG_DTMF_TONEXT2L	0x34
> +#define TWL4030_REG_DTMF_TONOFF		0x35
> +#define TWL4030_REG_DTMF_WANONOFF	0x36
> +#define TWL4030_REG_I2S_RX_SCRAMBLE_H	0x37
> +#define TWL4030_REG_I2S_RX_SCRAMBLE_M	0x38
> +#define TWL4030_REG_I2S_RX_SCRAMBLE_L	0x39
> +#define TWL4030_REG_APLL_CTL		0x3A
> +#define TWL4030_REG_DTMF_CTL		0x3B
> +#define TWL4030_REG_DTMF_PGA_CTL2	0x3C
> +#define TWL4030_REG_DTMF_PGA_CTL1	0x3D
> +#define TWL4030_REG_MISC_SET_1		0x3E
> +#define TWL4030_REG_PCMBTMUX		0x3F
> +#define TWL4030_REG_RX_PATH_SEL		0x43
> +#define TWL4030_REG_VDL_APGA_CTL	0x44
> +#define TWL4030_REG_VIBRA_CTL		0x45
> +#define TWL4030_REG_VIBRA_SET		0x46
> +#define TWL4030_REG_VIBRA_PWM_SET	0x47
> +#define TWL4030_REG_ANAMIC_GAIN		0x48
> +#define TWL4030_REG_MISC_SET_2		0x49
> +
> +/* Bitfield Definitions */
> +
> +/* TWL4030_CODEC_MODE (0x01) Fields */
> +#define TWL4030_APLL_RATE		0xF0
> +#define TWL4030_APLL_RATE_8000		0x00
> +#define TWL4030_APLL_RATE_11025		0x10
> +#define TWL4030_APLL_RATE_12000		0x20
> +#define TWL4030_APLL_RATE_16000		0x40
> +#define TWL4030_APLL_RATE_22050		0x50
> +#define TWL4030_APLL_RATE_24000		0x60
> +#define TWL4030_APLL_RATE_32000		0x80
> +#define TWL4030_APLL_RATE_44100		0x90
> +#define TWL4030_APLL_RATE_48000		0xA0
> +#define TWL4030_APLL_RATE_96000		0xE0
> +#define TWL4030_SEL_16K			0x08
> +#define TWL4030_CODECPDZ		0x02
> +#define TWL4030_OPT_MODE		0x01
> +#define TWL4030_OPTION_1		(1 << 0)
> +#define TWL4030_OPTION_2		(0 << 0)
> +
> +/* TWL4030_OPTION (0x02) Fields */
> +#define TWL4030_ATXL1_EN		(1 << 0)
> +#define TWL4030_ATXR1_EN		(1 << 1)
> +#define TWL4030_ATXL2_VTXL_EN		(1 << 2)
> +#define TWL4030_ATXR2_VTXR_EN		(1 << 3)
> +#define TWL4030_ARXL1_VRX_EN		(1 << 4)
> +#define TWL4030_ARXR1_EN		(1 << 5)
> +#define TWL4030_ARXL2_EN		(1 << 6)
> +#define TWL4030_ARXR2_EN		(1 << 7)
> +
> +/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
> +#define TWL4030_MICBIAS2_CTL		0x40
> +#define TWL4030_MICBIAS1_CTL		0x20
> +#define TWL4030_HSMICBIAS_EN		0x04
> +#define TWL4030_MICBIAS2_EN		0x02
> +#define TWL4030_MICBIAS1_EN		0x01
> +
> +/* ANAMICL (0x05) Fields */
> +#define TWL4030_CNCL_OFFSET_START	0x80
> +#define TWL4030_OFFSET_CNCL_SEL		0x60
> +#define TWL4030_OFFSET_CNCL_SEL_ARX1	0x00
> +#define TWL4030_OFFSET_CNCL_SEL_ARX2	0x20
> +#define TWL4030_OFFSET_CNCL_SEL_VRX	0x40
> +#define TWL4030_OFFSET_CNCL_SEL_ALL	0x60
> +#define TWL4030_MICAMPL_EN		0x10
> +#define TWL4030_CKMIC_EN		0x08
> +#define TWL4030_AUXL_EN			0x04
> +#define TWL4030_HSMIC_EN		0x02
> +#define TWL4030_MAINMIC_EN		0x01
> +
> +/* ANAMICR (0x06) Fields */
> +#define TWL4030_MICAMPR_EN		0x10
> +#define TWL4030_AUXR_EN			0x04
> +#define TWL4030_SUBMIC_EN		0x01
> +
> +/* AVADC_CTL (0x07) Fields */
> +#define TWL4030_ADCL_EN			0x08
> +#define TWL4030_AVADC_CLK_PRIORITY	0x04
> +#define TWL4030_ADCR_EN			0x02
> +
> +/* TWL4030_REG_ADCMICSEL (0x08) Fields */
> +#define TWL4030_DIGMIC1_EN		0x08
> +#define TWL4030_TX2IN_SEL		0x04
> +#define TWL4030_DIGMIC0_EN		0x02
> +#define TWL4030_TX1IN_SEL		0x01
> +
> +/* AUDIO_IF (0x0E) Fields */
> +#define TWL4030_AIF_SLAVE_EN		0x80
> +#define TWL4030_DATA_WIDTH		0x60
> +#define TWL4030_DATA_WIDTH_16S_16W	0x00
> +#define TWL4030_DATA_WIDTH_32S_16W	0x40
> +#define TWL4030_DATA_WIDTH_32S_24W	0x60
> +#define TWL4030_AIF_FORMAT		0x18
> +#define TWL4030_AIF_FORMAT_CODEC	0x00
> +#define TWL4030_AIF_FORMAT_LEFT		0x08
> +#define TWL4030_AIF_FORMAT_RIGHT	0x10
> +#define TWL4030_AIF_FORMAT_TDM		0x18
> +#define TWL4030_AIF_TRI_EN		0x04
> +#define TWL4030_CLK256FS_EN		0x02
> +#define TWL4030_AIF_EN			0x01
> +
> +/* VOICE_IF (0x0F) Fields */
> +#define TWL4030_VIF_SLAVE_EN		0x80
> +#define TWL4030_VIF_DIN_EN		0x40
> +#define TWL4030_VIF_DOUT_EN		0x20
> +#define TWL4030_VIF_SWAP		0x10
> +#define TWL4030_VIF_FORMAT		0x08
> +#define TWL4030_VIF_TRI_EN		0x04
> +#define TWL4030_VIF_SUB_EN		0x02
> +#define TWL4030_VIF_EN			0x01
> +
> +/* EAR_CTL (0x21) */
> +#define TWL4030_EAR_GAIN		0x30
> +
> +/* HS_GAIN_SET (0x23) Fields */
> +#define TWL4030_HSR_GAIN		0x0C
> +#define TWL4030_HSR_GAIN_PWR_DOWN	0x00
> +#define TWL4030_HSR_GAIN_PLUS_6DB	0x04
> +#define TWL4030_HSR_GAIN_0DB		0x08
> +#define TWL4030_HSR_GAIN_MINUS_6DB	0x0C
> +#define TWL4030_HSL_GAIN		0x03
> +#define TWL4030_HSL_GAIN_PWR_DOWN	0x00
> +#define TWL4030_HSL_GAIN_PLUS_6DB	0x01
> +#define TWL4030_HSL_GAIN_0DB		0x02
> +#define TWL4030_HSL_GAIN_MINUS_6DB	0x03
> +
> +/* HS_POPN_SET (0x24) Fields */
> +#define TWL4030_VMID_EN			0x40
> +#define	TWL4030_EXTMUTE			0x20
> +#define TWL4030_RAMP_DELAY		0x1C
> +#define TWL4030_RAMP_DELAY_20MS		0x00
> +#define TWL4030_RAMP_DELAY_40MS		0x04
> +#define TWL4030_RAMP_DELAY_81MS		0x08
> +#define TWL4030_RAMP_DELAY_161MS	0x0C
> +#define TWL4030_RAMP_DELAY_323MS	0x10
> +#define TWL4030_RAMP_DELAY_645MS	0x14
> +#define TWL4030_RAMP_DELAY_1291MS	0x18
> +#define TWL4030_RAMP_DELAY_2581MS	0x1C
> +#define TWL4030_RAMP_EN			0x02
> +
> +/* PREDL_CTL (0x25) */
> +#define TWL4030_PREDL_GAIN		0x30
> +
> +/* PREDR_CTL (0x26) */
> +#define TWL4030_PREDR_GAIN		0x30
> +
> +/* PRECKL_CTL (0x27) */
> +#define TWL4030_PRECKL_GAIN		0x30
> +
> +/* PRECKR_CTL (0x28) */
> +#define TWL4030_PRECKR_GAIN		0x30
> +
> +/* HFL_CTL (0x29, 0x2A) Fields */
> +#define TWL4030_HF_CTL_HB_EN		0x04
> +#define TWL4030_HF_CTL_LOOP_EN		0x08
> +#define TWL4030_HF_CTL_RAMP_EN		0x10
> +#define TWL4030_HF_CTL_REF_EN		0x20
> +
> +/* APLL_CTL (0x3A) Fields */
> +#define TWL4030_APLL_EN			0x10
> +#define TWL4030_APLL_INFREQ		0x0F
> +#define TWL4030_APLL_INFREQ_19200KHZ	0x05
> +#define TWL4030_APLL_INFREQ_26000KHZ	0x06
> +#define TWL4030_APLL_INFREQ_38400KHZ	0x0F
> +
> +/* REG_MISC_SET_1 (0x3E) Fields */
> +#define TWL4030_CLK64_EN		0x80
> +#define TWL4030_SCRAMBLE_EN		0x40
> +#define TWL4030_FMLOOP_EN		0x20
> +#define TWL4030_SMOOTH_ANAVOL_EN	0x02
> +#define TWL4030_DIGMIC_LR_SWAP_EN	0x01
> +
> +/* VIBRA_CTL (0x45) */
> +#define TWL4030_VIBRA_EN		0x01
> +#define TWL4030_VIBRA_DIR		0x02
> +#define TWL4030_VIBRA_AUDIO_SEL_L1	(0x00 << 2)
> +#define TWL4030_VIBRA_AUDIO_SEL_R1	(0x01 << 2)
> +#define TWL4030_VIBRA_AUDIO_SEL_L2	(0x02 << 2)
> +#define TWL4030_VIBRA_AUDIO_SEL_R2	(0x03 << 2)
> +#define TWL4030_VIBRA_SEL		0x10
> +#define TWL4030_VIBRA_DIR_SEL		0x20
> +
> +/* TWL4030 codec resource IDs */
> +enum twl4030_codec_res {
> +	TWL4030_CODEC_RES_POWER = 0,
> +	TWL4030_CODEC_RES_APLL,
> +	TWL4030_CODEC_RES_MAX,
> +};
> +
> +int twl4030_codec_disable_resource(enum twl4030_codec_res id);
> +int twl4030_codec_enable_resource(enum twl4030_codec_res id);
> +
> +#endif	/* End of __TWL4030_CODEC_H__ */
> --
> 1.6.5.1
> 

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [alsa-devel] [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core
  2009-10-23 14:07   ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Samuel Ortiz
@ 2009-10-25 17:18     ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2009-10-25 17:18 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: Peter Ujfalusi, tony, alsa-devel, linux-omap, linux-kernel

On Fri, Oct 23, 2009 at 04:07:05PM +0200, Samuel Ortiz wrote:

> As agreed, Mark is taking this one. So:
> Acked-by: Samuel Ortiz <sameo@linux.intel.com>

Applied all, if there's a merge problem with the MFD code then there's a
twl4030-mfd branch at

  git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git

which I'm happy for you to merge if it makes life easier.  Due to other
changes the patches end up depending on (just textually I think) there's
a big raft of other stuff in there too, sadly.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-10-25 17:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-22 10:26 [PATCH 0/4 v2] MFD/OMAP/ASoC: MFD device for twl4030 codec submodule Peter Ujfalusi
2009-10-22 10:26 ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Peter Ujfalusi
2009-10-22 10:26   ` [PATCH 2/4 v2] OMAP: Platform support for twl4030_codec MFD Peter Ujfalusi
2009-10-22 10:26     ` [PATCH 3/4 v2] ASoC: TWL4030: use the twl4030-codec.h for register descriptions Peter Ujfalusi
2009-10-22 10:26       ` [PATCH 4/4 v2] ASoC: TWL4030: Driver registration via twl4030_codec MFD Peter Ujfalusi
2009-10-22 16:56         ` Mark Brown
2009-10-23  5:27           ` Peter Ujfalusi
2009-10-23 12:59             ` [alsa-devel] " Mark Brown
2009-10-23 14:07   ` [PATCH 1/4 v2] MFD: twl4030: add twl4030_codec MFD as a new child to the core Samuel Ortiz
2009-10-25 17:18     ` [alsa-devel] " Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).