All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20100527130338.737142664@mandriva.com>

diff --git a/a/1.txt b/N1/1.txt
index 782528f..42ff4c2 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,983 +1,3 @@
-This patch is adding a ASoC driver for the cs42l51 from Cirrus Logic.
-Master mode and spi mode are not supported.
-
-Signed-off-by: Arnaud Patard <apatard@mandriva.com>
-
-Index: sound-2.6/sound/soc/codecs/cs42l51.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ sound-2.6/sound/soc/codecs/cs42l51.c	2010-05-27 14:09:52.079674615 +0200
-@@ -0,0 +1,763 @@
-+/*
-+ * cs42l51.c
-+ *
-+ * ASoC Driver for Cirrus Logic CS42L51 codecs
-+ *
-+ * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
-+ *
-+ * Based on cs4270.c - Copyright (c) Freescale Semiconductor
-+ *
-+ * 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.
-+ *
-+ * For now:
-+ *  - Only I2C is support. Not SPI
-+ *  - master mode *NOT* supported
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <sound/core.h>
-+#include <sound/soc.h>
-+#include <sound/soc-dapm.h>
-+#include <sound/tlv.h>
-+#include <sound/initval.h>
-+#include <sound/pcm_params.h>
-+#include <sound/pcm.h>
-+#include <linux/i2c.h>
-+
-+#include "cs42l51.h"
-+
-+enum master_slave_mode {
-+	MODE_SLAVE,
-+	MODE_SLAVE_AUTO,
-+	MODE_MASTER,
-+};
-+
-+struct cs42l51_private {
-+	unsigned int mclk;
-+	unsigned int audio_mode;	/* The mode (I2S or left-justified) */
-+	enum master_slave_mode func;
-+	struct snd_soc_codec codec;
-+	u8 reg_cache[CS42L51_NUMREGS];
-+};
-+
-+static struct snd_soc_codec *cs42l51_codec;
-+
-+#define CS42L51_FORMATS ( \
-+		SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S16_BE  | \
-+		SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
-+		SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
-+		SNDRV_PCM_FMTBIT_S24_LE  | SNDRV_PCM_FMTBIT_S24_BE)
-+
-+static int cs42l51_fill_cache(struct snd_soc_codec *codec)
-+{
-+	u8 *cache = codec->reg_cache + 1;
-+	struct i2c_client *i2c_client = codec->control_data;
-+	s32 length;
-+
-+	length = i2c_smbus_read_i2c_block_data(i2c_client,
-+			CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
-+	if (length != CS42L51_NUMREGS) {
-+		dev_err(&i2c_client->dev,
-+				"I2C read failure, addr=0x%x (ret=%d vs %d)\n",
-+				i2c_client->addr, length, CS42L51_NUMREGS);
-+		return -EIO;
-+	}
-+
-+	return 0;
-+}
-+
-+static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
-+	const struct i2c_device_id *id)
-+{
-+	struct snd_soc_codec *codec;
-+	struct cs42l51_private *cs42l51;
-+	int ret = 0;
-+	int reg;
-+
-+	if (cs42l51_codec)
-+		return -EBUSY;
-+
-+	/* Verify that we have a CS42L51 */
-+	ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
-+	if (ret < 0) {
-+		dev_err(&i2c_client->dev, "failed to read I2C\n");
-+		goto error;
-+	}
-+
-+	if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
-+	    (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
-+		dev_err(&i2c_client->dev, "Invalid chip id\n");
-+		ret = -ENODEV;
-+		goto error;
-+	}
-+
-+	dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
-+				ret & 7);
-+
-+	cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
-+	if (!cs42l51) {
-+		dev_err(&i2c_client->dev, "could not allocate codec\n");
-+		return -ENOMEM;
-+	}
-+	codec = &cs42l51->codec;
-+
-+	mutex_init(&codec->mutex);
-+	INIT_LIST_HEAD(&codec->dapm_widgets);
-+	INIT_LIST_HEAD(&codec->dapm_paths);
-+
-+	codec->dev = &i2c_client->dev;
-+	codec->name = "CS42L51";
-+	codec->owner = THIS_MODULE;
-+	codec->dai = &cs42l51_dai;
-+	codec->num_dai = 1;
-+	snd_soc_codec_set_drvdata(codec, cs42l51);
-+
-+	codec->control_data = i2c_client;
-+	codec->reg_cache = cs42l51->reg_cache;
-+	codec->reg_cache_size = CS42L51_NUMREGS;
-+	i2c_set_clientdata(i2c_client, codec);
-+
-+	ret = cs42l51_fill_cache(codec);
-+	if (ret < 0) {
-+		dev_err(&i2c_client->dev, "failed to fill register cache\n");
-+		goto error_alloc;
-+	}
-+
-+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
-+	if (ret < 0) {
-+		dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
-+		goto error_alloc;
-+	}
-+
-+	/*
-+	 * DAC configuration
-+	 * - Use signal processor
-+	 * - auto mute
-+	 * - vol changes immediate
-+	 * - no de-emphasize
-+	 */
-+	reg = CS42L51_DAC_CTL_DATA_SEL(1)
-+		| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
-+	ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
-+	if (ret < 0)
-+		goto error_alloc;
-+
-+	cs42l51_dai.dev = codec->dev;
-+	cs42l51_codec = codec;
-+
-+	ret = snd_soc_register_codec(codec);
-+	if (ret != 0) {
-+		dev_err(codec->dev, "Failed to register codec: %d\n", ret);
-+		goto error_alloc;
-+	}
-+
-+	ret = snd_soc_register_dai(&cs42l51_dai);
-+	if (ret < 0) {
-+		dev_err(&i2c_client->dev, "failed to register DAIe\n");
-+		goto error_reg;
-+	}
-+
-+	return 0;
-+
-+error_reg:
-+	snd_soc_unregister_codec(codec);
-+error_alloc:
-+	kfree(cs42l51);
-+error:
-+	return ret;
-+}
-+
-+static int cs42l51_i2c_remove(struct i2c_client *client)
-+{
-+	struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
-+	snd_soc_unregister_dai(&cs42l51_dai);
-+	snd_soc_unregister_codec(cs42l51_codec);
-+	cs42l51_codec = NULL;
-+	kfree(cs42l51);
-+	return 0;
-+}
-+
-+
-+static const struct i2c_device_id cs42l51_id[] = {
-+	{"cs42l51", 0},
-+	{}
-+};
-+MODULE_DEVICE_TABLE(i2c, cs42l51_id);
-+
-+static struct i2c_driver cs42l51_i2c_driver = {
-+	.driver = {
-+		.name = "CS42L51 I2C",
-+		.owner = THIS_MODULE,
-+	},
-+	.id_table = cs42l51_id,
-+	.probe = cs42l51_i2c_probe,
-+	.remove = cs42l51_i2c_remove,
-+};
-+
-+static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
-+			struct snd_ctl_elem_value *ucontrol)
-+{
-+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-+	unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
-+
-+	switch (value) {
-+	default:
-+	case 0:
-+		ucontrol->value.integer.value[0] = 0;
-+		break;
-+	/* same value : (L+R)/2 and (R+L)/2 */
-+	case 1:
-+	case 2:
-+		ucontrol->value.integer.value[0] = 1;
-+		break;
-+	case 3:
-+		ucontrol->value.integer.value[0] = 2;
-+		break;
-+	}
-+
-+	return 0;
-+}
-+
-+#define CHAN_MIX_NORMAL	0x00
-+#define CHAN_MIX_BOTH	0x55
-+#define CHAN_MIX_SWAP	0xFF
-+
-+static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
-+			struct snd_ctl_elem_value *ucontrol)
-+{
-+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-+	unsigned char val;
-+
-+	switch (ucontrol->value.integer.value[0]) {
-+	default:
-+	case 0:
-+		val = CHAN_MIX_NORMAL;
-+		break;
-+	case 1:
-+		val = CHAN_MIX_BOTH;
-+		break;
-+	case 2:
-+		val = CHAN_MIX_SWAP;
-+		break;
-+	}
-+
-+	snd_soc_write(codec, CS42L51_PCM_MIXER, val);
-+
-+	return 1;
-+}
-+
-+static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
-+static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
-+/* This is a lie. after -102 db, it stays at -102 */
-+/* maybe a range would be better */
-+static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
-+
-+static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
-+static const char *chan_mix[] = {
-+	"L R",
-+	"L+R",
-+	"R L",
-+};
-+
-+static const struct soc_enum cs42l51_chan_mix =
-+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);
-+
-+static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
-+	SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
-+			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
-+			7, 0xffffff99, 0x18, adc_pcm_tlv),
-+	SOC_DOUBLE_R("PCM Playback Switch",
-+			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
-+	SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
-+			CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
-+			8, 0xffffff19, 0x18, aout_tlv),
-+	SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
-+			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
-+			7, 0xffffff99, 0x18, adc_pcm_tlv),
-+	SOC_DOUBLE_R("ADC Mixer Switch",
-+			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
-+	SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
-+	SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
-+	SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
-+	SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
-+	SOC_DOUBLE_TLV("Mic Boost Volume",
-+			CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
-+	SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
-+	SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
-+	SOC_ENUM_EXT("PCM channel mixer",
-+			cs42l51_chan_mix,
-+			cs42l51_get_chan_mix, cs42l51_set_chan_mix),
-+};
-+
-+/*
-+ * to power down, one must:
-+ * 1.) Enable the PDN bit
-+ * 2.) enable power-down for the select channels
-+ * 3.) disable the PDN bit.
-+ */
-+static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
-+		struct snd_kcontrol *kcontrol, int event)
-+{
-+	unsigned long value;
-+
-+	value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
-+	value &= ~CS42L51_POWER_CTL1_PDN;
-+
-+	switch (event) {
-+	case SND_SOC_DAPM_PRE_PMD:
-+		value |= CS42L51_POWER_CTL1_PDN;
-+		break;
-+	default:
-+	case SND_SOC_DAPM_POST_PMD:
-+		break;
-+	}
-+	snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
-+		CS42L51_POWER_CTL1_PDN, value);
-+
-+	return 0;
-+}
-+
-+static const char *cs42l51_dac_names[] = {"Direct PCM",
-+	"DSP PCM", "ADC"};
-+static const struct soc_enum cs42l51_dac_mux_enum =
-+	SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);
-+static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
-+	SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
-+
-+static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
-+	"MIC Left", "MIC+preamp Left"};
-+static const struct soc_enum cs42l51_adcl_mux_enum =
-+	SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);
-+static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
-+	SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
-+
-+static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
-+	"MIC Right", "MIC+preamp Right"};
-+static const struct soc_enum cs42l51_adcr_mux_enum =
-+	SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);
-+static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
-+	SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
-+
-+static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
-+	SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
-+	SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+	SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+	SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
-+		CS42L51_POWER_CTL1, 1, 1,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+	SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
-+		CS42L51_POWER_CTL1, 2, 1,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+	SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
-+		CS42L51_POWER_CTL1, 5, 1,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+	SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
-+		CS42L51_POWER_CTL1, 6, 1,
-+		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
-+
-+	/* analog/mic */
-+	SND_SOC_DAPM_INPUT("AIN1L"),
-+	SND_SOC_DAPM_INPUT("AIN1R"),
-+	SND_SOC_DAPM_INPUT("AIN2L"),
-+	SND_SOC_DAPM_INPUT("AIN2R"),
-+	SND_SOC_DAPM_INPUT("MICL"),
-+	SND_SOC_DAPM_INPUT("MICR"),
-+
-+	SND_SOC_DAPM_MIXER("Mic Preamp Left",
-+		CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
-+	SND_SOC_DAPM_MIXER("Mic Preamp Right",
-+		CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
-+
-+	/* HP */
-+	SND_SOC_DAPM_OUTPUT("HPL"),
-+	SND_SOC_DAPM_OUTPUT("HPR"),
-+
-+	/* mux */
-+	SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
-+		&cs42l51_dac_mux_controls),
-+	SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
-+		&cs42l51_adcl_mux_controls),
-+	SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
-+		&cs42l51_adcr_mux_controls),
-+};
-+
-+static const struct snd_soc_dapm_route cs42l51_routes[] = {
-+	{"HPL", NULL, "Left DAC"},
-+	{"HPR", NULL, "Right DAC"},
-+
-+	{"Left ADC", NULL, "Left PGA"},
-+	{"Right ADC", NULL, "Right PGA"},
-+
-+	{"Mic Preamp Left",  NULL,  "MICL"},
-+	{"Mic Preamp Right", NULL,  "MICR"},
-+
-+	{"PGA-ADC Mux Left",  "AIN1 Left",        "AIN1L" },
-+	{"PGA-ADC Mux Left",  "AIN2 Left",        "AIN2L" },
-+	{"PGA-ADC Mux Left",  "MIC Left",         "MICL"  },
-+	{"PGA-ADC Mux Left",  "MIC+preamp Left",  "Mic Preamp Left" },
-+	{"PGA-ADC Mux Right", "AIN1 Right",       "AIN1R" },
-+	{"PGA-ADC Mux Right", "AIN2 Right",       "AIN2R" },
-+	{"PGA-ADC Mux Right", "MIC Right",        "MICR" },
-+	{"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
-+
-+	{"Left PGA", NULL, "PGA-ADC Mux Left"},
-+	{"Right PGA", NULL, "PGA-ADC Mux Right"},
-+};
-+
-+static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
-+		unsigned int format)
-+{
-+	struct snd_soc_codec *codec = codec_dai->codec;
-+	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
-+	int ret = 0;
-+
-+	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
-+	case SND_SOC_DAIFMT_I2S:
-+	case SND_SOC_DAIFMT_LEFT_J:
-+	case SND_SOC_DAIFMT_RIGHT_J:
-+		cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
-+		break;
-+	default:
-+		dev_err(codec->dev, "invalid DAI format\n");
-+		ret = -EINVAL;
-+	}
-+
-+	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
-+	case SND_SOC_DAIFMT_CBM_CFM:
-+		cs42l51->func = MODE_MASTER;
-+		break;
-+	case SND_SOC_DAIFMT_CBS_CFS:
-+		cs42l51->func = MODE_SLAVE_AUTO;
-+		break;
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+struct cs42l51_ratios {
-+	unsigned int ratio;
-+	unsigned char speed_mode;
-+	unsigned char mclk;
-+};
-+
-+static struct cs42l51_ratios slave_ratios[] = {
-+	{  512, CS42L51_QSM_MODE, 0 }, {  768, CS42L51_QSM_MODE, 0 },
-+	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
-+	{ 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
-+	{  256, CS42L51_HSM_MODE, 0 }, {  384, CS42L51_HSM_MODE, 0 },
-+	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
-+	{ 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
-+	{  128, CS42L51_SSM_MODE, 0 }, {  192, CS42L51_SSM_MODE, 0 },
-+	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
-+	{  512, CS42L51_SSM_MODE, 0 }, {  768, CS42L51_SSM_MODE, 0 },
-+	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
-+	{  256, CS42L51_DSM_MODE, 0 }, {  384, CS42L51_DSM_MODE, 0 },
-+};
-+
-+static struct cs42l51_ratios slave_auto_ratios[] = {
-+	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
-+	{ 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
-+	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
-+	{ 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
-+	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
-+	{  512, CS42L51_SSM_MODE, 1 }, {  768, CS42L51_SSM_MODE, 1 },
-+	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
-+	{  256, CS42L51_DSM_MODE, 1 }, {  384, CS42L51_DSM_MODE, 1 },
-+};
-+
-+static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
-+		int clk_id, unsigned int freq, int dir)
-+{
-+	struct snd_soc_codec *codec = codec_dai->codec;
-+	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
-+	struct cs42l51_ratios *ratios = NULL;
-+	int nr_ratios = 0;
-+	unsigned int rates = 0;
-+	unsigned int rate_min = -1;
-+	unsigned int rate_max = 0;
-+	int i;
-+
-+	cs42l51->mclk = freq;
-+
-+	switch (cs42l51->func) {
-+	case MODE_MASTER:
-+		return -EINVAL;
-+	case MODE_SLAVE:
-+		ratios = slave_ratios;
-+		nr_ratios = ARRAY_SIZE(slave_ratios);
-+		break;
-+	case MODE_SLAVE_AUTO:
-+		ratios = slave_auto_ratios;
-+		nr_ratios = ARRAY_SIZE(slave_auto_ratios);
-+		break;
-+	}
-+
-+	for (i = 0; i < nr_ratios; i++) {
-+		unsigned int rate = freq / ratios[i].ratio;
-+		rates |= snd_pcm_rate_to_rate_bit(rate);
-+		if (rate < rate_min)
-+			rate_min = rate;
-+		if (rate > rate_max)
-+			rate_max = rate;
-+	}
-+	rates &= ~SNDRV_PCM_RATE_KNOT;
-+
-+	if (!rates) {
-+		dev_err(codec->dev, "could not find a valid sample rate\n");
-+		return -EINVAL;
-+	}
-+
-+	codec_dai->playback.rates = rates;
-+	codec_dai->playback.rate_min = rate_min;
-+	codec_dai->playback.rate_max = rate_max;
-+
-+	codec_dai->capture.rates = rates;
-+	codec_dai->capture.rate_min = rate_min;
-+	codec_dai->capture.rate_max = rate_max;
-+
-+	return 0;
-+}
-+
-+static int cs42l51_hw_params(struct snd_pcm_substream *substream,
-+		struct snd_pcm_hw_params *params,
-+		struct snd_soc_dai *dai)
-+{
-+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-+	struct snd_soc_device *socdev = rtd->socdev;
-+	struct snd_soc_codec *codec = socdev->card->codec;
-+	struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
-+	int ret;
-+	unsigned int i;
-+	unsigned int rate;
-+	unsigned int ratio;
-+	struct cs42l51_ratios *ratios = NULL;
-+	int nr_ratios = 0;
-+	int intf_ctl, power_ctl, fmt;
-+
-+	switch (cs42l51->func) {
-+	case MODE_MASTER:
-+		return -EINVAL;
-+	case MODE_SLAVE:
-+		ratios = slave_ratios;
-+		nr_ratios = ARRAY_SIZE(slave_ratios);
-+		break;
-+	case MODE_SLAVE_AUTO:
-+		ratios = slave_auto_ratios;
-+		nr_ratios = ARRAY_SIZE(slave_auto_ratios);
-+		break;
-+	}
-+
-+	/* Figure out which MCLK/LRCK ratio to use */
-+	rate = params_rate(params);     /* Sampling rate, in Hz */
-+	ratio = cs42l51->mclk / rate;    /* MCLK/LRCK ratio */
-+	for (i = 0; i < nr_ratios; i++) {
-+		if (ratios[i].ratio == ratio)
-+			break;
-+	}
-+
-+	if (i == nr_ratios) {
-+		/* We did not find a matching ratio */
-+		dev_err(codec->dev, "could not find matching ratio\n");
-+		return -EINVAL;
-+	}
-+
-+	intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
-+	power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
-+
-+	intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
-+			| CS42L51_INTF_CTL_DAC_FORMAT(7));
-+	power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
-+			| CS42L51_MIC_POWER_CTL_MCLK_DIV2);
-+
-+	switch (cs42l51->func) {
-+	case MODE_MASTER:
-+		intf_ctl |= CS42L51_INTF_CTL_MASTER;
-+		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
-+		break;
-+	case MODE_SLAVE:
-+		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
-+		break;
-+	case MODE_SLAVE_AUTO:
-+		power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
-+		break;
-+	}
-+
-+	switch (cs42l51->audio_mode) {
-+	case SND_SOC_DAIFMT_I2S:
-+		intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
-+		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
-+		break;
-+	case SND_SOC_DAIFMT_LEFT_J:
-+		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
-+		break;
-+	case SND_SOC_DAIFMT_RIGHT_J:
-+		switch (params_format(params)) {
-+		case SNDRV_PCM_FORMAT_S16_LE:
-+		case SNDRV_PCM_FORMAT_S16_BE:
-+			fmt = CS42L51_DAC_DIF_RJ16;
-+			break;
-+		case SNDRV_PCM_FORMAT_S18_3LE:
-+		case SNDRV_PCM_FORMAT_S18_3BE:
-+			fmt = CS42L51_DAC_DIF_RJ18;
-+			break;
-+		case SNDRV_PCM_FORMAT_S20_3LE:
-+		case SNDRV_PCM_FORMAT_S20_3BE:
-+			fmt = CS42L51_DAC_DIF_RJ20;
-+			break;
-+		case SNDRV_PCM_FORMAT_S24_LE:
-+		case SNDRV_PCM_FORMAT_S24_BE:
-+			fmt = CS42L51_DAC_DIF_RJ24;
-+			break;
-+		default:
-+			dev_err(codec->dev, "unknown format\n");
-+			return -EINVAL;
-+		}
-+		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
-+		break;
-+	default:
-+		dev_err(codec->dev, "unknown format\n");
-+		return -EINVAL;
-+	}
-+
-+	if (ratios[i].mclk)
-+		power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
-+
-+	ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
-+	if (ret < 0)
-+		return ret;
-+
-+	ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
-+	if (ret < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
-+{
-+	struct snd_soc_codec *codec = dai->codec;
-+	int reg;
-+	int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
-+
-+	reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
-+
-+	if (mute)
-+		reg |= mask;
-+	else
-+		reg &= ~mask;
-+
-+	return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
-+}
-+
-+static struct snd_soc_dai_ops cs42l51_dai_ops = {
-+	.hw_params      = cs42l51_hw_params,
-+	.set_sysclk     = cs42l51_set_dai_sysclk,
-+	.set_fmt        = cs42l51_set_dai_fmt,
-+	.digital_mute   = cs42l51_dai_mute,
-+};
-+
-+struct snd_soc_dai cs42l51_dai = {
-+	.name = "CS42L51 HiFi",
-+	.playback = {
-+		.stream_name = "Playback",
-+		.channels_min = 1,
-+		.channels_max = 2,
-+		.rates = SNDRV_PCM_RATE_8000_96000,
-+		.formats = CS42L51_FORMATS,
-+	},
-+	.capture = {
-+		.stream_name = "Capture",
-+		.channels_min = 1,
-+		.channels_max = 2,
-+		.rates = SNDRV_PCM_RATE_8000_96000,
-+		.formats = CS42L51_FORMATS,
-+	},
-+	.ops = &cs42l51_dai_ops,
-+};
-+EXPORT_SYMBOL_GPL(cs42l51_dai);
-+
-+
-+static int cs42l51_probe(struct platform_device *pdev)
-+{
-+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-+	struct snd_soc_codec *codec;
-+	int ret = 0;
-+
-+	if (!cs42l51_codec) {
-+		dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
-+		return -EINVAL;
-+	}
-+
-+	socdev->card->codec = cs42l51_codec;
-+	codec = socdev->card->codec;
-+
-+	/* Register PCMs */
-+	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
-+	if (ret < 0) {
-+		dev_err(&pdev->dev, "failed to create PCMs\n");
-+		return ret;
-+	}
-+
-+	snd_soc_add_controls(codec, cs42l51_snd_controls,
-+		ARRAY_SIZE(cs42l51_snd_controls));
-+	snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
-+		ARRAY_SIZE(cs42l51_dapm_widgets));
-+	snd_soc_dapm_add_routes(codec, cs42l51_routes,
-+		ARRAY_SIZE(cs42l51_routes));
-+
-+	return 0;
-+}
-+
-+
-+static int cs42l51_remove(struct platform_device *pdev)
-+{
-+	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-+
-+	snd_soc_free_pcms(socdev);
-+	snd_soc_dapm_free(socdev);
-+
-+	return 0;
-+}
-+
-+struct snd_soc_codec_device soc_codec_device_cs42l51 = {
-+	.probe =	cs42l51_probe,
-+	.remove =	cs42l51_remove
-+};
-+EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
-+
-+static int __init cs42l51_init(void)
-+{
-+	int ret;
-+
-+	ret = i2c_add_driver(&cs42l51_i2c_driver);
-+	if (ret != 0) {
-+		printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
-+		return ret;
-+	}
-+	return 0;
-+}
-+module_init(cs42l51_init);
-+
-+static void __exit cs42l51_exit(void)
-+{
-+	i2c_del_driver(&cs42l51_i2c_driver);
-+}
-+module_exit(cs42l51_exit);
-+
-+MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
-+MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
-+MODULE_LICENSE("GPL");
-Index: sound-2.6/sound/soc/codecs/cs42l51.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ sound-2.6/sound/soc/codecs/cs42l51.h	2010-05-27 14:09:52.103694289 +0200
-@@ -0,0 +1,163 @@
-+/*
-+ * cs42l51.h
-+ *
-+ * ASoC Driver for Cirrus Logic CS42L51 codecs
-+ *
-+ * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * 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.
-+ */
-+#ifndef _CS42L51_H
-+#define _CS42L51_H
-+
-+#define CS42L51_CHIP_ID			0x1B
-+#define CS42L51_CHIP_REV_A		0x00
-+#define CS42L51_CHIP_REV_B		0x01
-+
-+#define CS42L51_CHIP_REV_ID		0x01
-+#define CS42L51_MK_CHIP_REV(a, b)	((a)<<3|(b))
-+
-+#define CS42L51_POWER_CTL1		0x02
-+#define CS42L51_POWER_CTL1_PDN_DACB	(1<<6)
-+#define CS42L51_POWER_CTL1_PDN_DACA	(1<<5)
-+#define CS42L51_POWER_CTL1_PDN_PGAB	(1<<4)
-+#define CS42L51_POWER_CTL1_PDN_PGAA	(1<<3)
-+#define CS42L51_POWER_CTL1_PDN_ADCB	(1<<2)
-+#define CS42L51_POWER_CTL1_PDN_ADCA	(1<<1)
-+#define CS42L51_POWER_CTL1_PDN		(1<<0)
-+
-+#define CS42L51_MIC_POWER_CTL		0x03
-+#define CS42L51_MIC_POWER_CTL_AUTO	(1<<7)
-+#define CS42L51_MIC_POWER_CTL_SPEED(x)	(((x)&3)<<5)
-+#define CS42L51_QSM_MODE		3
-+#define CS42L51_HSM_MODE		2
-+#define	CS42L51_SSM_MODE		1
-+#define CS42L51_DSM_MODE		0
-+#define CS42L51_MIC_POWER_CTL_3ST_SP	(1<<4)
-+#define CS42L51_MIC_POWER_CTL_PDN_MICB	(1<<3)
-+#define CS42L51_MIC_POWER_CTL_PDN_MICA	(1<<2)
-+#define CS42L51_MIC_POWER_CTL_PDN_BIAS	(1<<1)
-+#define CS42L51_MIC_POWER_CTL_MCLK_DIV2	(1<<0)
-+
-+#define CS42L51_INTF_CTL		0x04
-+#define CS42L51_INTF_CTL_LOOPBACK	(1<<7)
-+#define CS42L51_INTF_CTL_MASTER		(1<<6)
-+#define CS42L51_INTF_CTL_DAC_FORMAT(x)	(((x)&7)<<3)
-+#define CS42L51_DAC_DIF_LJ24		0x00
-+#define CS42L51_DAC_DIF_I2S		0x01
-+#define CS42L51_DAC_DIF_RJ24		0x02
-+#define CS42L51_DAC_DIF_RJ20		0x03
-+#define CS42L51_DAC_DIF_RJ18		0x04
-+#define CS42L51_DAC_DIF_RJ16		0x05
-+#define CS42L51_INTF_CTL_ADC_I2S	(1<<2)
-+#define CS42L51_INTF_CTL_DIGMIX		(1<<1)
-+#define CS42L51_INTF_CTL_MICMIX		(1<<0)
-+
-+#define CS42L51_MIC_CTL			0x05
-+#define CS42L51_MIC_CTL_ADC_SNGVOL	(1<<7)
-+#define CS42L51_MIC_CTL_ADCD_DBOOST	(1<<6)
-+#define CS42L51_MIC_CTL_ADCA_DBOOST	(1<<5)
-+#define CS42L51_MIC_CTL_MICBIAS_SEL	(1<<4)
-+#define CS42L51_MIC_CTL_MICBIAS_LVL(x)	(((x)&3)<<2)
-+#define CS42L51_MIC_CTL_MICB_BOOST	(1<<1)
-+#define CS42L51_MIC_CTL_MICA_BOOST	(1<<0)
-+
-+#define CS42L51_ADC_CTL			0x06
-+#define CS42L51_ADC_CTL_ADCB_HPFEN	(1<<7)
-+#define CS42L51_ADC_CTL_ADCB_HPFRZ	(1<<6)
-+#define CS42L51_ADC_CTL_ADCA_HPFEN	(1<<5)
-+#define CS42L51_ADC_CTL_ADCA_HPFRZ	(1<<4)
-+#define CS42L51_ADC_CTL_SOFTB		(1<<3)
-+#define CS42L51_ADC_CTL_ZCROSSB		(1<<2)
-+#define CS42L51_ADC_CTL_SOFTA		(1<<1)
-+#define CS42L51_ADC_CTL_ZCROSSA		(1<<0)
-+
-+#define CS42L51_ADC_INPUT		0x07
-+#define CS42L51_ADC_INPUT_AINB_MUX(x)	(((x)&3)<<6)
-+#define CS42L51_ADC_INPUT_AINA_MUX(x)	(((x)&3)<<4)
-+#define CS42L51_ADC_INPUT_INV_ADCB	(1<<3)
-+#define CS42L51_ADC_INPUT_INV_ADCA	(1<<2)
-+#define CS42L51_ADC_INPUT_ADCB_MUTE	(1<<1)
-+#define CS42L51_ADC_INPUT_ADCA_MUTE	(1<<0)
-+
-+#define CS42L51_DAC_OUT_CTL		0x08
-+#define CS42L51_DAC_OUT_CTL_HP_GAIN(x)	(((x)&7)<<5)
-+#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL	(1<<4)
-+#define CS42L51_DAC_OUT_CTL_INV_PCMB	(1<<3)
-+#define CS42L51_DAC_OUT_CTL_INV_PCMA	(1<<2)
-+#define CS42L51_DAC_OUT_CTL_DACB_MUTE	(1<<1)
-+#define CS42L51_DAC_OUT_CTL_DACA_MUTE	(1<<0)
-+
-+#define CS42L51_DAC_CTL			0x09
-+#define CS42L51_DAC_CTL_DATA_SEL(x)	(((x)&3)<<6)
-+#define CS42L51_DAC_CTL_FREEZE		(1<<5)
-+#define CS42L51_DAC_CTL_DEEMPH		(1<<3)
-+#define CS42L51_DAC_CTL_AMUTE		(1<<2)
-+#define CS42L51_DAC_CTL_DACSZ(x)	(((x)&3)<<0)
-+
-+#define CS42L51_ALC_PGA_CTL		0x0A
-+#define CS42L51_ALC_PGB_CTL		0x0B
-+#define CS42L51_ALC_PGX_ALCX_SRDIS	(1<<7)
-+#define CS42L51_ALC_PGX_ALCX_ZCDIS	(1<<6)
-+#define CS42L51_ALC_PGX_PGX_VOL(x)	(((x)&0x1f)<<0)
-+
-+#define CS42L51_ADCA_ATT		0x0C
-+#define CS42L51_ADCB_ATT		0x0D
-+
-+#define CS42L51_ADCA_VOL		0x0E
-+#define CS42L51_ADCB_VOL		0x0F
-+#define CS42L51_PCMA_VOL		0x10
-+#define CS42L51_PCMB_VOL		0x11
-+#define CS42L51_MIX_MUTE_ADCMIX		(1<<7)
-+#define CS42L51_MIX_VOLUME(x)		(((x)&0x7f)<<0)
-+
-+#define CS42L51_BEEP_FREQ		0x12
-+#define CS42L51_BEEP_VOL		0x13
-+#define CS42L51_BEEP_CONF		0x14
-+
-+#define CS42L51_TONE_CTL		0x15
-+#define CS42L51_TONE_CTL_TREB(x)	(((x)&0xf)<<4)
-+#define CS42L51_TONE_CTL_BASS(x)	(((x)&0xf)<<0)
-+
-+#define CS42L51_AOUTA_VOL		0x16
-+#define CS42L51_AOUTB_VOL		0x17
-+#define CS42L51_PCM_MIXER		0x18
-+#define CS42L51_LIMIT_THRES_DIS		0x19
-+#define CS42L51_LIMIT_REL		0x1A
-+#define CS42L51_LIMIT_ATT		0x1B
-+#define CS42L51_ALC_EN			0x1C
-+#define CS42L51_ALC_REL			0x1D
-+#define CS42L51_ALC_THRES		0x1E
-+#define CS42L51_NOISE_CONF		0x1F
-+
-+#define CS42L51_STATUS			0x20
-+#define CS42L51_STATUS_SP_CLKERR	(1<<6)
-+#define CS42L51_STATUS_SPEA_OVFL	(1<<5)
-+#define CS42L51_STATUS_SPEB_OVFL	(1<<4)
-+#define CS42L51_STATUS_PCMA_OVFL	(1<<3)
-+#define CS42L51_STATUS_PCMB_OVFL	(1<<2)
-+#define CS42L51_STATUS_ADCA_OVFL	(1<<1)
-+#define CS42L51_STATUS_ADCB_OVFL	(1<<0)
-+
-+#define CS42L51_CHARGE_FREQ		0x21
-+
-+#define CS42L51_FIRSTREG	0x01
-+/*
-+ * Hack: with register 0x21, it makes 33 registers. Looks like someone in the
-+ * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using
-+ * 32 regs
-+ */
-+#define CS42L51_LASTREG		0x20
-+#define CS42L51_NUMREGS		(CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
-+
-+extern struct snd_soc_dai cs42l51_dai;
-+extern struct snd_soc_codec_device soc_codec_device_cs42l51;
-+#endif
-Index: sound-2.6/sound/soc/codecs/Kconfig
-===================================================================
---- sound-2.6.orig/sound/soc/codecs/Kconfig	2010-05-27 14:09:32.812174230 +0200
-+++ sound-2.6/sound/soc/codecs/Kconfig	2010-05-27 14:09:52.107735223 +0200
-@@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS
- 	select SND_SOC_AK4642 if I2C
- 	select SND_SOC_AK4671 if I2C
- 	select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
-+	select SND_SOC_CS42L51 if I2C
- 	select SND_SOC_CS4270 if I2C
- 	select SND_SOC_MAX9877 if I2C
- 	select SND_SOC_DA7210 if I2C
-@@ -120,6 +121,9 @@ config SND_SOC_AK4671
- config SND_SOC_CQ0093VC
- 	tristate
- 
-+config SND_SOC_CS42L51
-+	tristate
-+
- # Cirrus Logic CS4270 Codec
- config SND_SOC_CS4270
- 	tristate
-Index: sound-2.6/sound/soc/codecs/Makefile
-===================================================================
---- sound-2.6.orig/sound/soc/codecs/Makefile	2010-05-27 14:09:32.836174105 +0200
-+++ sound-2.6/sound/soc/codecs/Makefile	2010-05-27 14:09:52.107735223 +0200
-@@ -9,6 +9,7 @@ snd-soc-ak4535-objs := ak4535.o
- snd-soc-ak4642-objs := ak4642.o
- snd-soc-ak4671-objs := ak4671.o
- snd-soc-cq93vc-objs := cq93vc.o
-+snd-soc-cs42l51-objs := cs42l51.o
- snd-soc-cs4270-objs := cs4270.o
- snd-soc-cx20442-objs := cx20442.o
- snd-soc-da7210-objs := da7210.o
-@@ -74,6 +75,7 @@ obj-$(CONFIG_SND_SOC_AK4535)	+= snd-soc-
- obj-$(CONFIG_SND_SOC_AK4642)	+= snd-soc-ak4642.o
- obj-$(CONFIG_SND_SOC_AK4671)	+= snd-soc-ak4671.o
- obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
-+obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o
- obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
- obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
- obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o
+An embedded and charset-unspecified text was scrubbed...
+Name: cs42l51_support.patch
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100527/2a0cd5a1/attachment.el>
diff --git a/a/content_digest b/N1/content_digest
index 107b687..2d4730d 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,1000 +1,12 @@
  "ref\020100527125737.524554667@mandriva.com\0"
- "From\0apatard@mandriva.com\0"
+ "From\0apatard@mandriva.com (apatard at mandriva.com)\0"
  "Subject\0[patch 4/6] cs42l51: add asoc driver\0"
  "Date\0Thu, 27 May 2010 14:57:41 +0200\0"
- "To\0alsa-devel@alsa-project.org\0"
- "Cc\0nico@fluxnic.net"
-  broonie@opensource.wolfsonmicro.com
-  saeed@marvell.com
-  Arnaud Patard <apatard@mandriva.com>
-  tbm@cyrius.com
-  linux-arm-kernel@lists.infradead.org
- " lrg@slimlogic.co.uk\0"
+ "To\0linux-arm-kernel@lists.infradead.org\0"
  "\00:1\0"
- "fn\0cs42l51_support.patch\0"
  "b\0"
- "This patch is adding a ASoC driver for the cs42l51 from Cirrus Logic.\n"
- "Master mode and spi mode are not supported.\n"
- "\n"
- "Signed-off-by: Arnaud Patard <apatard@mandriva.com>\n"
- "\n"
- "Index: sound-2.6/sound/soc/codecs/cs42l51.c\n"
- "===================================================================\n"
- "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n"
- "+++ sound-2.6/sound/soc/codecs/cs42l51.c\t2010-05-27 14:09:52.079674615 +0200\n"
- "@@ -0,0 +1,763 @@\n"
- "+/*\n"
- "+ * cs42l51.c\n"
- "+ *\n"
- "+ * ASoC Driver for Cirrus Logic CS42L51 codecs\n"
- "+ *\n"
- "+ * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>\n"
- "+ *\n"
- "+ * Based on cs4270.c - Copyright (c) Freescale Semiconductor\n"
- "+ *\n"
- "+ * This program is free software; you can redistribute it and/or modify\n"
- "+ * it under the terms of the GNU General Public License version 2 as\n"
- "+ * published by the Free Software Foundation.\n"
- "+ *\n"
- "+ * This program is distributed in the hope that it will be useful,\n"
- "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
- "+ * GNU General Public License for more details.\n"
- "+ *\n"
- "+ * For now:\n"
- "+ *  - Only I2C is support. Not SPI\n"
- "+ *  - master mode *NOT* supported\n"
- "+ */\n"
- "+\n"
- "+#include <linux/module.h>\n"
- "+#include <linux/platform_device.h>\n"
- "+#include <linux/slab.h>\n"
- "+#include <sound/core.h>\n"
- "+#include <sound/soc.h>\n"
- "+#include <sound/soc-dapm.h>\n"
- "+#include <sound/tlv.h>\n"
- "+#include <sound/initval.h>\n"
- "+#include <sound/pcm_params.h>\n"
- "+#include <sound/pcm.h>\n"
- "+#include <linux/i2c.h>\n"
- "+\n"
- "+#include \"cs42l51.h\"\n"
- "+\n"
- "+enum master_slave_mode {\n"
- "+\tMODE_SLAVE,\n"
- "+\tMODE_SLAVE_AUTO,\n"
- "+\tMODE_MASTER,\n"
- "+};\n"
- "+\n"
- "+struct cs42l51_private {\n"
- "+\tunsigned int mclk;\n"
- "+\tunsigned int audio_mode;\t/* The mode (I2S or left-justified) */\n"
- "+\tenum master_slave_mode func;\n"
- "+\tstruct snd_soc_codec codec;\n"
- "+\tu8 reg_cache[CS42L51_NUMREGS];\n"
- "+};\n"
- "+\n"
- "+static struct snd_soc_codec *cs42l51_codec;\n"
- "+\n"
- "+#define CS42L51_FORMATS ( \\\n"
- "+\t\tSNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S16_BE  | \\\n"
- "+\t\tSNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \\\n"
- "+\t\tSNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \\\n"
- "+\t\tSNDRV_PCM_FMTBIT_S24_LE  | SNDRV_PCM_FMTBIT_S24_BE)\n"
- "+\n"
- "+static int cs42l51_fill_cache(struct snd_soc_codec *codec)\n"
- "+{\n"
- "+\tu8 *cache = codec->reg_cache + 1;\n"
- "+\tstruct i2c_client *i2c_client = codec->control_data;\n"
- "+\ts32 length;\n"
- "+\n"
- "+\tlength = i2c_smbus_read_i2c_block_data(i2c_client,\n"
- "+\t\t\tCS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);\n"
- "+\tif (length != CS42L51_NUMREGS) {\n"
- "+\t\tdev_err(&i2c_client->dev,\n"
- "+\t\t\t\t\"I2C read failure, addr=0x%x (ret=%d vs %d)\\n\",\n"
- "+\t\t\t\ti2c_client->addr, length, CS42L51_NUMREGS);\n"
- "+\t\treturn -EIO;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int cs42l51_i2c_probe(struct i2c_client *i2c_client,\n"
- "+\tconst struct i2c_device_id *id)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec;\n"
- "+\tstruct cs42l51_private *cs42l51;\n"
- "+\tint ret = 0;\n"
- "+\tint reg;\n"
- "+\n"
- "+\tif (cs42l51_codec)\n"
- "+\t\treturn -EBUSY;\n"
- "+\n"
- "+\t/* Verify that we have a CS42L51 */\n"
- "+\tret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"failed to read I2C\\n\");\n"
- "+\t\tgoto error;\n"
- "+\t}\n"
- "+\n"
- "+\tif ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&\n"
- "+\t    (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"Invalid chip id\\n\");\n"
- "+\t\tret = -ENODEV;\n"
- "+\t\tgoto error;\n"
- "+\t}\n"
- "+\n"
- "+\tdev_info(&i2c_client->dev, \"found device cs42l51 rev %d\\n\",\n"
- "+\t\t\t\tret & 7);\n"
- "+\n"
- "+\tcs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);\n"
- "+\tif (!cs42l51) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"could not allocate codec\\n\");\n"
- "+\t\treturn -ENOMEM;\n"
- "+\t}\n"
- "+\tcodec = &cs42l51->codec;\n"
- "+\n"
- "+\tmutex_init(&codec->mutex);\n"
- "+\tINIT_LIST_HEAD(&codec->dapm_widgets);\n"
- "+\tINIT_LIST_HEAD(&codec->dapm_paths);\n"
- "+\n"
- "+\tcodec->dev = &i2c_client->dev;\n"
- "+\tcodec->name = \"CS42L51\";\n"
- "+\tcodec->owner = THIS_MODULE;\n"
- "+\tcodec->dai = &cs42l51_dai;\n"
- "+\tcodec->num_dai = 1;\n"
- "+\tsnd_soc_codec_set_drvdata(codec, cs42l51);\n"
- "+\n"
- "+\tcodec->control_data = i2c_client;\n"
- "+\tcodec->reg_cache = cs42l51->reg_cache;\n"
- "+\tcodec->reg_cache_size = CS42L51_NUMREGS;\n"
- "+\ti2c_set_clientdata(i2c_client, codec);\n"
- "+\n"
- "+\tret = cs42l51_fill_cache(codec);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"failed to fill register cache\\n\");\n"
- "+\t\tgoto error_alloc;\n"
- "+\t}\n"
- "+\n"
- "+\tret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"Failed to set cache I/O: %d\\n\", ret);\n"
- "+\t\tgoto error_alloc;\n"
- "+\t}\n"
- "+\n"
- "+\t/*\n"
- "+\t * DAC configuration\n"
- "+\t * - Use signal processor\n"
- "+\t * - auto mute\n"
- "+\t * - vol changes immediate\n"
- "+\t * - no de-emphasize\n"
- "+\t */\n"
- "+\treg = CS42L51_DAC_CTL_DATA_SEL(1)\n"
- "+\t\t| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);\n"
- "+\tret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);\n"
- "+\tif (ret < 0)\n"
- "+\t\tgoto error_alloc;\n"
- "+\n"
- "+\tcs42l51_dai.dev = codec->dev;\n"
- "+\tcs42l51_codec = codec;\n"
- "+\n"
- "+\tret = snd_soc_register_codec(codec);\n"
- "+\tif (ret != 0) {\n"
- "+\t\tdev_err(codec->dev, \"Failed to register codec: %d\\n\", ret);\n"
- "+\t\tgoto error_alloc;\n"
- "+\t}\n"
- "+\n"
- "+\tret = snd_soc_register_dai(&cs42l51_dai);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(&i2c_client->dev, \"failed to register DAIe\\n\");\n"
- "+\t\tgoto error_reg;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+\n"
- "+error_reg:\n"
- "+\tsnd_soc_unregister_codec(codec);\n"
- "+error_alloc:\n"
- "+\tkfree(cs42l51);\n"
- "+error:\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static int cs42l51_i2c_remove(struct i2c_client *client)\n"
- "+{\n"
- "+\tstruct cs42l51_private *cs42l51 = i2c_get_clientdata(client);\n"
- "+\tsnd_soc_unregister_dai(&cs42l51_dai);\n"
- "+\tsnd_soc_unregister_codec(cs42l51_codec);\n"
- "+\tcs42l51_codec = NULL;\n"
- "+\tkfree(cs42l51);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+\n"
- "+static const struct i2c_device_id cs42l51_id[] = {\n"
- "+\t{\"cs42l51\", 0},\n"
- "+\t{}\n"
- "+};\n"
- "+MODULE_DEVICE_TABLE(i2c, cs42l51_id);\n"
- "+\n"
- "+static struct i2c_driver cs42l51_i2c_driver = {\n"
- "+\t.driver = {\n"
- "+\t\t.name = \"CS42L51 I2C\",\n"
- "+\t\t.owner = THIS_MODULE,\n"
- "+\t},\n"
- "+\t.id_table = cs42l51_id,\n"
- "+\t.probe = cs42l51_i2c_probe,\n"
- "+\t.remove = cs42l51_i2c_remove,\n"
- "+};\n"
- "+\n"
- "+static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,\n"
- "+\t\t\tstruct snd_ctl_elem_value *ucontrol)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);\n"
- "+\tunsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;\n"
- "+\n"
- "+\tswitch (value) {\n"
- "+\tdefault:\n"
- "+\tcase 0:\n"
- "+\t\tucontrol->value.integer.value[0] = 0;\n"
- "+\t\tbreak;\n"
- "+\t/* same value : (L+R)/2 and (R+L)/2 */\n"
- "+\tcase 1:\n"
- "+\tcase 2:\n"
- "+\t\tucontrol->value.integer.value[0] = 1;\n"
- "+\t\tbreak;\n"
- "+\tcase 3:\n"
- "+\t\tucontrol->value.integer.value[0] = 2;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+#define CHAN_MIX_NORMAL\t0x00\n"
- "+#define CHAN_MIX_BOTH\t0x55\n"
- "+#define CHAN_MIX_SWAP\t0xFF\n"
- "+\n"
- "+static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,\n"
- "+\t\t\tstruct snd_ctl_elem_value *ucontrol)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);\n"
- "+\tunsigned char val;\n"
- "+\n"
- "+\tswitch (ucontrol->value.integer.value[0]) {\n"
- "+\tdefault:\n"
- "+\tcase 0:\n"
- "+\t\tval = CHAN_MIX_NORMAL;\n"
- "+\t\tbreak;\n"
- "+\tcase 1:\n"
- "+\t\tval = CHAN_MIX_BOTH;\n"
- "+\t\tbreak;\n"
- "+\tcase 2:\n"
- "+\t\tval = CHAN_MIX_SWAP;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tsnd_soc_write(codec, CS42L51_PCM_MIXER, val);\n"
- "+\n"
- "+\treturn 1;\n"
- "+}\n"
- "+\n"
- "+static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);\n"
- "+static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);\n"
- "+/* This is a lie. after -102 db, it stays at -102 */\n"
- "+/* maybe a range would be better */\n"
- "+static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);\n"
- "+\n"
- "+static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);\n"
- "+static const char *chan_mix[] = {\n"
- "+\t\"L R\",\n"
- "+\t\"L+R\",\n"
- "+\t\"R L\",\n"
- "+};\n"
- "+\n"
- "+static const struct soc_enum cs42l51_chan_mix =\n"
- "+\tSOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);\n"
- "+\n"
- "+static const struct snd_kcontrol_new cs42l51_snd_controls[] = {\n"
- "+\tSOC_DOUBLE_R_SX_TLV(\"PCM Playback Volume\",\n"
- "+\t\t\tCS42L51_PCMA_VOL, CS42L51_PCMB_VOL,\n"
- "+\t\t\t7, 0xffffff99, 0x18, adc_pcm_tlv),\n"
- "+\tSOC_DOUBLE_R(\"PCM Playback Switch\",\n"
- "+\t\t\tCS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),\n"
- "+\tSOC_DOUBLE_R_SX_TLV(\"Analog Playback Volume\",\n"
- "+\t\t\tCS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,\n"
- "+\t\t\t8, 0xffffff19, 0x18, aout_tlv),\n"
- "+\tSOC_DOUBLE_R_SX_TLV(\"ADC Mixer Volume\",\n"
- "+\t\t\tCS42L51_ADCA_VOL, CS42L51_ADCB_VOL,\n"
- "+\t\t\t7, 0xffffff99, 0x18, adc_pcm_tlv),\n"
- "+\tSOC_DOUBLE_R(\"ADC Mixer Switch\",\n"
- "+\t\t\tCS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),\n"
- "+\tSOC_SINGLE(\"Playback Deemphasis Switch\", CS42L51_DAC_CTL, 3, 1, 0),\n"
- "+\tSOC_SINGLE(\"Auto-Mute Switch\", CS42L51_DAC_CTL, 2, 1, 0),\n"
- "+\tSOC_SINGLE(\"Soft Ramp Switch\", CS42L51_DAC_CTL, 1, 1, 0),\n"
- "+\tSOC_SINGLE(\"Zero Cross Switch\", CS42L51_DAC_CTL, 0, 0, 0),\n"
- "+\tSOC_DOUBLE_TLV(\"Mic Boost Volume\",\n"
- "+\t\t\tCS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),\n"
- "+\tSOC_SINGLE_TLV(\"Bass Volume\", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),\n"
- "+\tSOC_SINGLE_TLV(\"Treble Volume\", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),\n"
- "+\tSOC_ENUM_EXT(\"PCM channel mixer\",\n"
- "+\t\t\tcs42l51_chan_mix,\n"
- "+\t\t\tcs42l51_get_chan_mix, cs42l51_set_chan_mix),\n"
- "+};\n"
- "+\n"
- "+/*\n"
- "+ * to power down, one must:\n"
- "+ * 1.) Enable the PDN bit\n"
- "+ * 2.) enable power-down for the select channels\n"
- "+ * 3.) disable the PDN bit.\n"
- "+ */\n"
- "+static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,\n"
- "+\t\tstruct snd_kcontrol *kcontrol, int event)\n"
- "+{\n"
- "+\tunsigned long value;\n"
- "+\n"
- "+\tvalue = snd_soc_read(w->codec, CS42L51_POWER_CTL1);\n"
- "+\tvalue &= ~CS42L51_POWER_CTL1_PDN;\n"
- "+\n"
- "+\tswitch (event) {\n"
- "+\tcase SND_SOC_DAPM_PRE_PMD:\n"
- "+\t\tvalue |= CS42L51_POWER_CTL1_PDN;\n"
- "+\t\tbreak;\n"
- "+\tdefault:\n"
- "+\tcase SND_SOC_DAPM_POST_PMD:\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\tsnd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,\n"
- "+\t\tCS42L51_POWER_CTL1_PDN, value);\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static const char *cs42l51_dac_names[] = {\"Direct PCM\",\n"
- "+\t\"DSP PCM\", \"ADC\"};\n"
- "+static const struct soc_enum cs42l51_dac_mux_enum =\n"
- "+\tSOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);\n"
- "+static const struct snd_kcontrol_new cs42l51_dac_mux_controls =\n"
- "+\tSOC_DAPM_ENUM(\"Route\", cs42l51_dac_mux_enum);\n"
- "+\n"
- "+static const char *cs42l51_adcl_names[] = {\"AIN1 Left\", \"AIN2 Left\",\n"
- "+\t\"MIC Left\", \"MIC+preamp Left\"};\n"
- "+static const struct soc_enum cs42l51_adcl_mux_enum =\n"
- "+\tSOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);\n"
- "+static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =\n"
- "+\tSOC_DAPM_ENUM(\"Route\", cs42l51_adcl_mux_enum);\n"
- "+\n"
- "+static const char *cs42l51_adcr_names[] = {\"AIN1 Right\", \"AIN2 Right\",\n"
- "+\t\"MIC Right\", \"MIC+preamp Right\"};\n"
- "+static const struct soc_enum cs42l51_adcr_mux_enum =\n"
- "+\tSOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);\n"
- "+static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =\n"
- "+\tSOC_DAPM_ENUM(\"Route\", cs42l51_adcr_mux_enum);\n"
- "+\n"
- "+static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {\n"
- "+\tSND_SOC_DAPM_MICBIAS(\"Mic Bias\", CS42L51_MIC_POWER_CTL, 1, 1),\n"
- "+\tSND_SOC_DAPM_PGA_E(\"Left PGA\", CS42L51_POWER_CTL1, 3, 1, NULL, 0,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\tSND_SOC_DAPM_PGA_E(\"Right PGA\", CS42L51_POWER_CTL1, 4, 1, NULL, 0,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\tSND_SOC_DAPM_ADC_E(\"Left ADC\", \"Left HiFi Capture\",\n"
- "+\t\tCS42L51_POWER_CTL1, 1, 1,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\tSND_SOC_DAPM_ADC_E(\"Right ADC\", \"Right HiFi Capture\",\n"
- "+\t\tCS42L51_POWER_CTL1, 2, 1,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\tSND_SOC_DAPM_DAC_E(\"Left DAC\", \"Left HiFi Playback\",\n"
- "+\t\tCS42L51_POWER_CTL1, 5, 1,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\tSND_SOC_DAPM_DAC_E(\"Right DAC\", \"Right HiFi Playback\",\n"
- "+\t\tCS42L51_POWER_CTL1, 6, 1,\n"
- "+\t\tcs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),\n"
- "+\n"
- "+\t/* analog/mic */\n"
- "+\tSND_SOC_DAPM_INPUT(\"AIN1L\"),\n"
- "+\tSND_SOC_DAPM_INPUT(\"AIN1R\"),\n"
- "+\tSND_SOC_DAPM_INPUT(\"AIN2L\"),\n"
- "+\tSND_SOC_DAPM_INPUT(\"AIN2R\"),\n"
- "+\tSND_SOC_DAPM_INPUT(\"MICL\"),\n"
- "+\tSND_SOC_DAPM_INPUT(\"MICR\"),\n"
- "+\n"
- "+\tSND_SOC_DAPM_MIXER(\"Mic Preamp Left\",\n"
- "+\t\tCS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),\n"
- "+\tSND_SOC_DAPM_MIXER(\"Mic Preamp Right\",\n"
- "+\t\tCS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),\n"
- "+\n"
- "+\t/* HP */\n"
- "+\tSND_SOC_DAPM_OUTPUT(\"HPL\"),\n"
- "+\tSND_SOC_DAPM_OUTPUT(\"HPR\"),\n"
- "+\n"
- "+\t/* mux */\n"
- "+\tSND_SOC_DAPM_MUX(\"DAC Mux\", SND_SOC_NOPM, 0, 0,\n"
- "+\t\t&cs42l51_dac_mux_controls),\n"
- "+\tSND_SOC_DAPM_MUX(\"PGA-ADC Mux Left\", SND_SOC_NOPM, 0, 0,\n"
- "+\t\t&cs42l51_adcl_mux_controls),\n"
- "+\tSND_SOC_DAPM_MUX(\"PGA-ADC Mux Right\", SND_SOC_NOPM, 0, 0,\n"
- "+\t\t&cs42l51_adcr_mux_controls),\n"
- "+};\n"
- "+\n"
- "+static const struct snd_soc_dapm_route cs42l51_routes[] = {\n"
- "+\t{\"HPL\", NULL, \"Left DAC\"},\n"
- "+\t{\"HPR\", NULL, \"Right DAC\"},\n"
- "+\n"
- "+\t{\"Left ADC\", NULL, \"Left PGA\"},\n"
- "+\t{\"Right ADC\", NULL, \"Right PGA\"},\n"
- "+\n"
- "+\t{\"Mic Preamp Left\",  NULL,  \"MICL\"},\n"
- "+\t{\"Mic Preamp Right\", NULL,  \"MICR\"},\n"
- "+\n"
- "+\t{\"PGA-ADC Mux Left\",  \"AIN1 Left\",        \"AIN1L\" },\n"
- "+\t{\"PGA-ADC Mux Left\",  \"AIN2 Left\",        \"AIN2L\" },\n"
- "+\t{\"PGA-ADC Mux Left\",  \"MIC Left\",         \"MICL\"  },\n"
- "+\t{\"PGA-ADC Mux Left\",  \"MIC+preamp Left\",  \"Mic Preamp Left\" },\n"
- "+\t{\"PGA-ADC Mux Right\", \"AIN1 Right\",       \"AIN1R\" },\n"
- "+\t{\"PGA-ADC Mux Right\", \"AIN2 Right\",       \"AIN2R\" },\n"
- "+\t{\"PGA-ADC Mux Right\", \"MIC Right\",        \"MICR\" },\n"
- "+\t{\"PGA-ADC Mux Right\", \"MIC+preamp Right\", \"Mic Preamp Right\" },\n"
- "+\n"
- "+\t{\"Left PGA\", NULL, \"PGA-ADC Mux Left\"},\n"
- "+\t{\"Right PGA\", NULL, \"PGA-ADC Mux Right\"},\n"
- "+};\n"
- "+\n"
- "+static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,\n"
- "+\t\tunsigned int format)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec = codec_dai->codec;\n"
- "+\tstruct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);\n"
- "+\tint ret = 0;\n"
- "+\n"
- "+\tswitch (format & SND_SOC_DAIFMT_FORMAT_MASK) {\n"
- "+\tcase SND_SOC_DAIFMT_I2S:\n"
- "+\tcase SND_SOC_DAIFMT_LEFT_J:\n"
- "+\tcase SND_SOC_DAIFMT_RIGHT_J:\n"
- "+\t\tcs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;\n"
- "+\t\tbreak;\n"
- "+\tdefault:\n"
- "+\t\tdev_err(codec->dev, \"invalid DAI format\\n\");\n"
- "+\t\tret = -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tswitch (format & SND_SOC_DAIFMT_MASTER_MASK) {\n"
- "+\tcase SND_SOC_DAIFMT_CBM_CFM:\n"
- "+\t\tcs42l51->func = MODE_MASTER;\n"
- "+\t\tbreak;\n"
- "+\tcase SND_SOC_DAIFMT_CBS_CFS:\n"
- "+\t\tcs42l51->func = MODE_SLAVE_AUTO;\n"
- "+\t\tbreak;\n"
- "+\tdefault:\n"
- "+\t\tret = -EINVAL;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+struct cs42l51_ratios {\n"
- "+\tunsigned int ratio;\n"
- "+\tunsigned char speed_mode;\n"
- "+\tunsigned char mclk;\n"
- "+};\n"
- "+\n"
- "+static struct cs42l51_ratios slave_ratios[] = {\n"
- "+\t{  512, CS42L51_QSM_MODE, 0 }, {  768, CS42L51_QSM_MODE, 0 },\n"
- "+\t{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },\n"
- "+\t{ 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },\n"
- "+\t{  256, CS42L51_HSM_MODE, 0 }, {  384, CS42L51_HSM_MODE, 0 },\n"
- "+\t{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },\n"
- "+\t{ 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },\n"
- "+\t{  128, CS42L51_SSM_MODE, 0 }, {  192, CS42L51_SSM_MODE, 0 },\n"
- "+\t{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },\n"
- "+\t{  512, CS42L51_SSM_MODE, 0 }, {  768, CS42L51_SSM_MODE, 0 },\n"
- "+\t{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },\n"
- "+\t{  256, CS42L51_DSM_MODE, 0 }, {  384, CS42L51_DSM_MODE, 0 },\n"
- "+};\n"
- "+\n"
- "+static struct cs42l51_ratios slave_auto_ratios[] = {\n"
- "+\t{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },\n"
- "+\t{ 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },\n"
- "+\t{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },\n"
- "+\t{ 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },\n"
- "+\t{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },\n"
- "+\t{  512, CS42L51_SSM_MODE, 1 }, {  768, CS42L51_SSM_MODE, 1 },\n"
- "+\t{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },\n"
- "+\t{  256, CS42L51_DSM_MODE, 1 }, {  384, CS42L51_DSM_MODE, 1 },\n"
- "+};\n"
- "+\n"
- "+static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,\n"
- "+\t\tint clk_id, unsigned int freq, int dir)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec = codec_dai->codec;\n"
- "+\tstruct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);\n"
- "+\tstruct cs42l51_ratios *ratios = NULL;\n"
- "+\tint nr_ratios = 0;\n"
- "+\tunsigned int rates = 0;\n"
- "+\tunsigned int rate_min = -1;\n"
- "+\tunsigned int rate_max = 0;\n"
- "+\tint i;\n"
- "+\n"
- "+\tcs42l51->mclk = freq;\n"
- "+\n"
- "+\tswitch (cs42l51->func) {\n"
- "+\tcase MODE_MASTER:\n"
- "+\t\treturn -EINVAL;\n"
- "+\tcase MODE_SLAVE:\n"
- "+\t\tratios = slave_ratios;\n"
- "+\t\tnr_ratios = ARRAY_SIZE(slave_ratios);\n"
- "+\t\tbreak;\n"
- "+\tcase MODE_SLAVE_AUTO:\n"
- "+\t\tratios = slave_auto_ratios;\n"
- "+\t\tnr_ratios = ARRAY_SIZE(slave_auto_ratios);\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tfor (i = 0; i < nr_ratios; i++) {\n"
- "+\t\tunsigned int rate = freq / ratios[i].ratio;\n"
- "+\t\trates |= snd_pcm_rate_to_rate_bit(rate);\n"
- "+\t\tif (rate < rate_min)\n"
- "+\t\t\trate_min = rate;\n"
- "+\t\tif (rate > rate_max)\n"
- "+\t\t\trate_max = rate;\n"
- "+\t}\n"
- "+\trates &= ~SNDRV_PCM_RATE_KNOT;\n"
- "+\n"
- "+\tif (!rates) {\n"
- "+\t\tdev_err(codec->dev, \"could not find a valid sample rate\\n\");\n"
- "+\t\treturn -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tcodec_dai->playback.rates = rates;\n"
- "+\tcodec_dai->playback.rate_min = rate_min;\n"
- "+\tcodec_dai->playback.rate_max = rate_max;\n"
- "+\n"
- "+\tcodec_dai->capture.rates = rates;\n"
- "+\tcodec_dai->capture.rate_min = rate_min;\n"
- "+\tcodec_dai->capture.rate_max = rate_max;\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int cs42l51_hw_params(struct snd_pcm_substream *substream,\n"
- "+\t\tstruct snd_pcm_hw_params *params,\n"
- "+\t\tstruct snd_soc_dai *dai)\n"
- "+{\n"
- "+\tstruct snd_soc_pcm_runtime *rtd = substream->private_data;\n"
- "+\tstruct snd_soc_device *socdev = rtd->socdev;\n"
- "+\tstruct snd_soc_codec *codec = socdev->card->codec;\n"
- "+\tstruct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);\n"
- "+\tint ret;\n"
- "+\tunsigned int i;\n"
- "+\tunsigned int rate;\n"
- "+\tunsigned int ratio;\n"
- "+\tstruct cs42l51_ratios *ratios = NULL;\n"
- "+\tint nr_ratios = 0;\n"
- "+\tint intf_ctl, power_ctl, fmt;\n"
- "+\n"
- "+\tswitch (cs42l51->func) {\n"
- "+\tcase MODE_MASTER:\n"
- "+\t\treturn -EINVAL;\n"
- "+\tcase MODE_SLAVE:\n"
- "+\t\tratios = slave_ratios;\n"
- "+\t\tnr_ratios = ARRAY_SIZE(slave_ratios);\n"
- "+\t\tbreak;\n"
- "+\tcase MODE_SLAVE_AUTO:\n"
- "+\t\tratios = slave_auto_ratios;\n"
- "+\t\tnr_ratios = ARRAY_SIZE(slave_auto_ratios);\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\t/* Figure out which MCLK/LRCK ratio to use */\n"
- "+\trate = params_rate(params);     /* Sampling rate, in Hz */\n"
- "+\tratio = cs42l51->mclk / rate;    /* MCLK/LRCK ratio */\n"
- "+\tfor (i = 0; i < nr_ratios; i++) {\n"
- "+\t\tif (ratios[i].ratio == ratio)\n"
- "+\t\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tif (i == nr_ratios) {\n"
- "+\t\t/* We did not find a matching ratio */\n"
- "+\t\tdev_err(codec->dev, \"could not find matching ratio\\n\");\n"
- "+\t\treturn -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tintf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);\n"
- "+\tpower_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);\n"
- "+\n"
- "+\tintf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S\n"
- "+\t\t\t| CS42L51_INTF_CTL_DAC_FORMAT(7));\n"
- "+\tpower_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)\n"
- "+\t\t\t| CS42L51_MIC_POWER_CTL_MCLK_DIV2);\n"
- "+\n"
- "+\tswitch (cs42l51->func) {\n"
- "+\tcase MODE_MASTER:\n"
- "+\t\tintf_ctl |= CS42L51_INTF_CTL_MASTER;\n"
- "+\t\tpower_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);\n"
- "+\t\tbreak;\n"
- "+\tcase MODE_SLAVE:\n"
- "+\t\tpower_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);\n"
- "+\t\tbreak;\n"
- "+\tcase MODE_SLAVE_AUTO:\n"
- "+\t\tpower_ctl |= CS42L51_MIC_POWER_CTL_AUTO;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tswitch (cs42l51->audio_mode) {\n"
- "+\tcase SND_SOC_DAIFMT_I2S:\n"
- "+\t\tintf_ctl |= CS42L51_INTF_CTL_ADC_I2S;\n"
- "+\t\tintf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);\n"
- "+\t\tbreak;\n"
- "+\tcase SND_SOC_DAIFMT_LEFT_J:\n"
- "+\t\tintf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);\n"
- "+\t\tbreak;\n"
- "+\tcase SND_SOC_DAIFMT_RIGHT_J:\n"
- "+\t\tswitch (params_format(params)) {\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S16_LE:\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S16_BE:\n"
- "+\t\t\tfmt = CS42L51_DAC_DIF_RJ16;\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S18_3LE:\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S18_3BE:\n"
- "+\t\t\tfmt = CS42L51_DAC_DIF_RJ18;\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S20_3LE:\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S20_3BE:\n"
- "+\t\t\tfmt = CS42L51_DAC_DIF_RJ20;\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S24_LE:\n"
- "+\t\tcase SNDRV_PCM_FORMAT_S24_BE:\n"
- "+\t\t\tfmt = CS42L51_DAC_DIF_RJ24;\n"
- "+\t\t\tbreak;\n"
- "+\t\tdefault:\n"
- "+\t\t\tdev_err(codec->dev, \"unknown format\\n\");\n"
- "+\t\t\treturn -EINVAL;\n"
- "+\t\t}\n"
- "+\t\tintf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);\n"
- "+\t\tbreak;\n"
- "+\tdefault:\n"
- "+\t\tdev_err(codec->dev, \"unknown format\\n\");\n"
- "+\t\treturn -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tif (ratios[i].mclk)\n"
- "+\t\tpower_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;\n"
- "+\n"
- "+\tret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);\n"
- "+\tif (ret < 0)\n"
- "+\t\treturn ret;\n"
- "+\n"
- "+\tret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);\n"
- "+\tif (ret < 0)\n"
- "+\t\treturn ret;\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)\n"
- "+{\n"
- "+\tstruct snd_soc_codec *codec = dai->codec;\n"
- "+\tint reg;\n"
- "+\tint mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;\n"
- "+\n"
- "+\treg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);\n"
- "+\n"
- "+\tif (mute)\n"
- "+\t\treg |= mask;\n"
- "+\telse\n"
- "+\t\treg &= ~mask;\n"
- "+\n"
- "+\treturn snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);\n"
- "+}\n"
- "+\n"
- "+static struct snd_soc_dai_ops cs42l51_dai_ops = {\n"
- "+\t.hw_params      = cs42l51_hw_params,\n"
- "+\t.set_sysclk     = cs42l51_set_dai_sysclk,\n"
- "+\t.set_fmt        = cs42l51_set_dai_fmt,\n"
- "+\t.digital_mute   = cs42l51_dai_mute,\n"
- "+};\n"
- "+\n"
- "+struct snd_soc_dai cs42l51_dai = {\n"
- "+\t.name = \"CS42L51 HiFi\",\n"
- "+\t.playback = {\n"
- "+\t\t.stream_name = \"Playback\",\n"
- "+\t\t.channels_min = 1,\n"
- "+\t\t.channels_max = 2,\n"
- "+\t\t.rates = SNDRV_PCM_RATE_8000_96000,\n"
- "+\t\t.formats = CS42L51_FORMATS,\n"
- "+\t},\n"
- "+\t.capture = {\n"
- "+\t\t.stream_name = \"Capture\",\n"
- "+\t\t.channels_min = 1,\n"
- "+\t\t.channels_max = 2,\n"
- "+\t\t.rates = SNDRV_PCM_RATE_8000_96000,\n"
- "+\t\t.formats = CS42L51_FORMATS,\n"
- "+\t},\n"
- "+\t.ops = &cs42l51_dai_ops,\n"
- "+};\n"
- "+EXPORT_SYMBOL_GPL(cs42l51_dai);\n"
- "+\n"
- "+\n"
- "+static int cs42l51_probe(struct platform_device *pdev)\n"
- "+{\n"
- "+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n"
- "+\tstruct snd_soc_codec *codec;\n"
- "+\tint ret = 0;\n"
- "+\n"
- "+\tif (!cs42l51_codec) {\n"
- "+\t\tdev_err(&pdev->dev, \"CS42L51 codec not yet registered\\n\");\n"
- "+\t\treturn -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tsocdev->card->codec = cs42l51_codec;\n"
- "+\tcodec = socdev->card->codec;\n"
- "+\n"
- "+\t/* Register PCMs */\n"
- "+\tret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(&pdev->dev, \"failed to create PCMs\\n\");\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\n"
- "+\tsnd_soc_add_controls(codec, cs42l51_snd_controls,\n"
- "+\t\tARRAY_SIZE(cs42l51_snd_controls));\n"
- "+\tsnd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,\n"
- "+\t\tARRAY_SIZE(cs42l51_dapm_widgets));\n"
- "+\tsnd_soc_dapm_add_routes(codec, cs42l51_routes,\n"
- "+\t\tARRAY_SIZE(cs42l51_routes));\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+\n"
- "+static int cs42l51_remove(struct platform_device *pdev)\n"
- "+{\n"
- "+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n"
- "+\n"
- "+\tsnd_soc_free_pcms(socdev);\n"
- "+\tsnd_soc_dapm_free(socdev);\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+struct snd_soc_codec_device soc_codec_device_cs42l51 = {\n"
- "+\t.probe =\tcs42l51_probe,\n"
- "+\t.remove =\tcs42l51_remove\n"
- "+};\n"
- "+EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);\n"
- "+\n"
- "+static int __init cs42l51_init(void)\n"
- "+{\n"
- "+\tint ret;\n"
- "+\n"
- "+\tret = i2c_add_driver(&cs42l51_i2c_driver);\n"
- "+\tif (ret != 0) {\n"
- "+\t\tprintk(KERN_ERR \"%s: can't add i2c driver\\n\", __func__);\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\treturn 0;\n"
- "+}\n"
- "+module_init(cs42l51_init);\n"
- "+\n"
- "+static void __exit cs42l51_exit(void)\n"
- "+{\n"
- "+\ti2c_del_driver(&cs42l51_i2c_driver);\n"
- "+}\n"
- "+module_exit(cs42l51_exit);\n"
- "+\n"
- "+MODULE_AUTHOR(\"Arnaud Patard <apatard@mandriva.com>\");\n"
- "+MODULE_DESCRIPTION(\"Cirrus Logic CS42L51 ALSA SoC Codec Driver\");\n"
- "+MODULE_LICENSE(\"GPL\");\n"
- "Index: sound-2.6/sound/soc/codecs/cs42l51.h\n"
- "===================================================================\n"
- "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n"
- "+++ sound-2.6/sound/soc/codecs/cs42l51.h\t2010-05-27 14:09:52.103694289 +0200\n"
- "@@ -0,0 +1,163 @@\n"
- "+/*\n"
- "+ * cs42l51.h\n"
- "+ *\n"
- "+ * ASoC Driver for Cirrus Logic CS42L51 codecs\n"
- "+ *\n"
- "+ * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>\n"
- "+ *\n"
- "+ * This program is free software; you can redistribute it and/or modify\n"
- "+ * it under the terms of the GNU General Public License as published by\n"
- "+ * the Free Software Foundation; either version 2 of the License, or\n"
- "+ * (at your option) any later version.\n"
- "+ *\n"
- "+ * This program is distributed in the hope that it will be useful,\n"
- "+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
- "+ * GNU General Public License for more details.\n"
- "+ */\n"
- "+#ifndef _CS42L51_H\n"
- "+#define _CS42L51_H\n"
- "+\n"
- "+#define CS42L51_CHIP_ID\t\t\t0x1B\n"
- "+#define CS42L51_CHIP_REV_A\t\t0x00\n"
- "+#define CS42L51_CHIP_REV_B\t\t0x01\n"
- "+\n"
- "+#define CS42L51_CHIP_REV_ID\t\t0x01\n"
- "+#define CS42L51_MK_CHIP_REV(a, b)\t((a)<<3|(b))\n"
- "+\n"
- "+#define CS42L51_POWER_CTL1\t\t0x02\n"
- "+#define CS42L51_POWER_CTL1_PDN_DACB\t(1<<6)\n"
- "+#define CS42L51_POWER_CTL1_PDN_DACA\t(1<<5)\n"
- "+#define CS42L51_POWER_CTL1_PDN_PGAB\t(1<<4)\n"
- "+#define CS42L51_POWER_CTL1_PDN_PGAA\t(1<<3)\n"
- "+#define CS42L51_POWER_CTL1_PDN_ADCB\t(1<<2)\n"
- "+#define CS42L51_POWER_CTL1_PDN_ADCA\t(1<<1)\n"
- "+#define CS42L51_POWER_CTL1_PDN\t\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_MIC_POWER_CTL\t\t0x03\n"
- "+#define CS42L51_MIC_POWER_CTL_AUTO\t(1<<7)\n"
- "+#define CS42L51_MIC_POWER_CTL_SPEED(x)\t(((x)&3)<<5)\n"
- "+#define CS42L51_QSM_MODE\t\t3\n"
- "+#define CS42L51_HSM_MODE\t\t2\n"
- "+#define\tCS42L51_SSM_MODE\t\t1\n"
- "+#define CS42L51_DSM_MODE\t\t0\n"
- "+#define CS42L51_MIC_POWER_CTL_3ST_SP\t(1<<4)\n"
- "+#define CS42L51_MIC_POWER_CTL_PDN_MICB\t(1<<3)\n"
- "+#define CS42L51_MIC_POWER_CTL_PDN_MICA\t(1<<2)\n"
- "+#define CS42L51_MIC_POWER_CTL_PDN_BIAS\t(1<<1)\n"
- "+#define CS42L51_MIC_POWER_CTL_MCLK_DIV2\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_INTF_CTL\t\t0x04\n"
- "+#define CS42L51_INTF_CTL_LOOPBACK\t(1<<7)\n"
- "+#define CS42L51_INTF_CTL_MASTER\t\t(1<<6)\n"
- "+#define CS42L51_INTF_CTL_DAC_FORMAT(x)\t(((x)&7)<<3)\n"
- "+#define CS42L51_DAC_DIF_LJ24\t\t0x00\n"
- "+#define CS42L51_DAC_DIF_I2S\t\t0x01\n"
- "+#define CS42L51_DAC_DIF_RJ24\t\t0x02\n"
- "+#define CS42L51_DAC_DIF_RJ20\t\t0x03\n"
- "+#define CS42L51_DAC_DIF_RJ18\t\t0x04\n"
- "+#define CS42L51_DAC_DIF_RJ16\t\t0x05\n"
- "+#define CS42L51_INTF_CTL_ADC_I2S\t(1<<2)\n"
- "+#define CS42L51_INTF_CTL_DIGMIX\t\t(1<<1)\n"
- "+#define CS42L51_INTF_CTL_MICMIX\t\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_MIC_CTL\t\t\t0x05\n"
- "+#define CS42L51_MIC_CTL_ADC_SNGVOL\t(1<<7)\n"
- "+#define CS42L51_MIC_CTL_ADCD_DBOOST\t(1<<6)\n"
- "+#define CS42L51_MIC_CTL_ADCA_DBOOST\t(1<<5)\n"
- "+#define CS42L51_MIC_CTL_MICBIAS_SEL\t(1<<4)\n"
- "+#define CS42L51_MIC_CTL_MICBIAS_LVL(x)\t(((x)&3)<<2)\n"
- "+#define CS42L51_MIC_CTL_MICB_BOOST\t(1<<1)\n"
- "+#define CS42L51_MIC_CTL_MICA_BOOST\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_ADC_CTL\t\t\t0x06\n"
- "+#define CS42L51_ADC_CTL_ADCB_HPFEN\t(1<<7)\n"
- "+#define CS42L51_ADC_CTL_ADCB_HPFRZ\t(1<<6)\n"
- "+#define CS42L51_ADC_CTL_ADCA_HPFEN\t(1<<5)\n"
- "+#define CS42L51_ADC_CTL_ADCA_HPFRZ\t(1<<4)\n"
- "+#define CS42L51_ADC_CTL_SOFTB\t\t(1<<3)\n"
- "+#define CS42L51_ADC_CTL_ZCROSSB\t\t(1<<2)\n"
- "+#define CS42L51_ADC_CTL_SOFTA\t\t(1<<1)\n"
- "+#define CS42L51_ADC_CTL_ZCROSSA\t\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_ADC_INPUT\t\t0x07\n"
- "+#define CS42L51_ADC_INPUT_AINB_MUX(x)\t(((x)&3)<<6)\n"
- "+#define CS42L51_ADC_INPUT_AINA_MUX(x)\t(((x)&3)<<4)\n"
- "+#define CS42L51_ADC_INPUT_INV_ADCB\t(1<<3)\n"
- "+#define CS42L51_ADC_INPUT_INV_ADCA\t(1<<2)\n"
- "+#define CS42L51_ADC_INPUT_ADCB_MUTE\t(1<<1)\n"
- "+#define CS42L51_ADC_INPUT_ADCA_MUTE\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_DAC_OUT_CTL\t\t0x08\n"
- "+#define CS42L51_DAC_OUT_CTL_HP_GAIN(x)\t(((x)&7)<<5)\n"
- "+#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL\t(1<<4)\n"
- "+#define CS42L51_DAC_OUT_CTL_INV_PCMB\t(1<<3)\n"
- "+#define CS42L51_DAC_OUT_CTL_INV_PCMA\t(1<<2)\n"
- "+#define CS42L51_DAC_OUT_CTL_DACB_MUTE\t(1<<1)\n"
- "+#define CS42L51_DAC_OUT_CTL_DACA_MUTE\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_DAC_CTL\t\t\t0x09\n"
- "+#define CS42L51_DAC_CTL_DATA_SEL(x)\t(((x)&3)<<6)\n"
- "+#define CS42L51_DAC_CTL_FREEZE\t\t(1<<5)\n"
- "+#define CS42L51_DAC_CTL_DEEMPH\t\t(1<<3)\n"
- "+#define CS42L51_DAC_CTL_AMUTE\t\t(1<<2)\n"
- "+#define CS42L51_DAC_CTL_DACSZ(x)\t(((x)&3)<<0)\n"
- "+\n"
- "+#define CS42L51_ALC_PGA_CTL\t\t0x0A\n"
- "+#define CS42L51_ALC_PGB_CTL\t\t0x0B\n"
- "+#define CS42L51_ALC_PGX_ALCX_SRDIS\t(1<<7)\n"
- "+#define CS42L51_ALC_PGX_ALCX_ZCDIS\t(1<<6)\n"
- "+#define CS42L51_ALC_PGX_PGX_VOL(x)\t(((x)&0x1f)<<0)\n"
- "+\n"
- "+#define CS42L51_ADCA_ATT\t\t0x0C\n"
- "+#define CS42L51_ADCB_ATT\t\t0x0D\n"
- "+\n"
- "+#define CS42L51_ADCA_VOL\t\t0x0E\n"
- "+#define CS42L51_ADCB_VOL\t\t0x0F\n"
- "+#define CS42L51_PCMA_VOL\t\t0x10\n"
- "+#define CS42L51_PCMB_VOL\t\t0x11\n"
- "+#define CS42L51_MIX_MUTE_ADCMIX\t\t(1<<7)\n"
- "+#define CS42L51_MIX_VOLUME(x)\t\t(((x)&0x7f)<<0)\n"
- "+\n"
- "+#define CS42L51_BEEP_FREQ\t\t0x12\n"
- "+#define CS42L51_BEEP_VOL\t\t0x13\n"
- "+#define CS42L51_BEEP_CONF\t\t0x14\n"
- "+\n"
- "+#define CS42L51_TONE_CTL\t\t0x15\n"
- "+#define CS42L51_TONE_CTL_TREB(x)\t(((x)&0xf)<<4)\n"
- "+#define CS42L51_TONE_CTL_BASS(x)\t(((x)&0xf)<<0)\n"
- "+\n"
- "+#define CS42L51_AOUTA_VOL\t\t0x16\n"
- "+#define CS42L51_AOUTB_VOL\t\t0x17\n"
- "+#define CS42L51_PCM_MIXER\t\t0x18\n"
- "+#define CS42L51_LIMIT_THRES_DIS\t\t0x19\n"
- "+#define CS42L51_LIMIT_REL\t\t0x1A\n"
- "+#define CS42L51_LIMIT_ATT\t\t0x1B\n"
- "+#define CS42L51_ALC_EN\t\t\t0x1C\n"
- "+#define CS42L51_ALC_REL\t\t\t0x1D\n"
- "+#define CS42L51_ALC_THRES\t\t0x1E\n"
- "+#define CS42L51_NOISE_CONF\t\t0x1F\n"
- "+\n"
- "+#define CS42L51_STATUS\t\t\t0x20\n"
- "+#define CS42L51_STATUS_SP_CLKERR\t(1<<6)\n"
- "+#define CS42L51_STATUS_SPEA_OVFL\t(1<<5)\n"
- "+#define CS42L51_STATUS_SPEB_OVFL\t(1<<4)\n"
- "+#define CS42L51_STATUS_PCMA_OVFL\t(1<<3)\n"
- "+#define CS42L51_STATUS_PCMB_OVFL\t(1<<2)\n"
- "+#define CS42L51_STATUS_ADCA_OVFL\t(1<<1)\n"
- "+#define CS42L51_STATUS_ADCB_OVFL\t(1<<0)\n"
- "+\n"
- "+#define CS42L51_CHARGE_FREQ\t\t0x21\n"
- "+\n"
- "+#define CS42L51_FIRSTREG\t0x01\n"
- "+/*\n"
- "+ * Hack: with register 0x21, it makes 33 registers. Looks like someone in the\n"
- "+ * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using\n"
- "+ * 32 regs\n"
- "+ */\n"
- "+#define CS42L51_LASTREG\t\t0x20\n"
- "+#define CS42L51_NUMREGS\t\t(CS42L51_LASTREG - CS42L51_FIRSTREG + 1)\n"
- "+\n"
- "+extern struct snd_soc_dai cs42l51_dai;\n"
- "+extern struct snd_soc_codec_device soc_codec_device_cs42l51;\n"
- "+#endif\n"
- "Index: sound-2.6/sound/soc/codecs/Kconfig\n"
- "===================================================================\n"
- "--- sound-2.6.orig/sound/soc/codecs/Kconfig\t2010-05-27 14:09:32.812174230 +0200\n"
- "+++ sound-2.6/sound/soc/codecs/Kconfig\t2010-05-27 14:09:52.107735223 +0200\n"
- "@@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS\n"
- " \tselect SND_SOC_AK4642 if I2C\n"
- " \tselect SND_SOC_AK4671 if I2C\n"
- " \tselect SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC\n"
- "+\tselect SND_SOC_CS42L51 if I2C\n"
- " \tselect SND_SOC_CS4270 if I2C\n"
- " \tselect SND_SOC_MAX9877 if I2C\n"
- " \tselect SND_SOC_DA7210 if I2C\n"
- "@@ -120,6 +121,9 @@ config SND_SOC_AK4671\n"
- " config SND_SOC_CQ0093VC\n"
- " \ttristate\n"
- " \n"
- "+config SND_SOC_CS42L51\n"
- "+\ttristate\n"
- "+\n"
- " # Cirrus Logic CS4270 Codec\n"
- " config SND_SOC_CS4270\n"
- " \ttristate\n"
- "Index: sound-2.6/sound/soc/codecs/Makefile\n"
- "===================================================================\n"
- "--- sound-2.6.orig/sound/soc/codecs/Makefile\t2010-05-27 14:09:32.836174105 +0200\n"
- "+++ sound-2.6/sound/soc/codecs/Makefile\t2010-05-27 14:09:52.107735223 +0200\n"
- "@@ -9,6 +9,7 @@ snd-soc-ak4535-objs := ak4535.o\n"
- " snd-soc-ak4642-objs := ak4642.o\n"
- " snd-soc-ak4671-objs := ak4671.o\n"
- " snd-soc-cq93vc-objs := cq93vc.o\n"
- "+snd-soc-cs42l51-objs := cs42l51.o\n"
- " snd-soc-cs4270-objs := cs4270.o\n"
- " snd-soc-cx20442-objs := cx20442.o\n"
- " snd-soc-da7210-objs := da7210.o\n"
- "@@ -74,6 +75,7 @@ obj-$(CONFIG_SND_SOC_AK4535)\t+= snd-soc-\n"
- " obj-$(CONFIG_SND_SOC_AK4642)\t+= snd-soc-ak4642.o\n"
- " obj-$(CONFIG_SND_SOC_AK4671)\t+= snd-soc-ak4671.o\n"
- " obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o\n"
- "+obj-$(CONFIG_SND_SOC_CS42L51)\t+= snd-soc-cs42l51.o\n"
- " obj-$(CONFIG_SND_SOC_CS4270)\t+= snd-soc-cs4270.o\n"
- " obj-$(CONFIG_SND_SOC_CX20442)\t+= snd-soc-cx20442.o\n"
- " obj-$(CONFIG_SND_SOC_DA7210)\t+= snd-soc-da7210.o"
+ "An embedded and charset-unspecified text was scrubbed...\n"
+ "Name: cs42l51_support.patch\n"
+ URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100527/2a0cd5a1/attachment.el>
 
-c7713cd6d197de3144848a7ae41683a46cc5dbb95700bb938ebd9443f153d30b
+2e29542c1886cc01a7fb42856a6d5974f90394a77f7ec64ba34299cb92489aec

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.