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.