lkml.org 
[lkml]   [2011]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [alsa-devel] [PATCH 1/2] ALSA: ASoc: TLV320AIC3X: ad SPI and clock on GPIO2 or BCLK


    Dne 2.4.2011 10:26, Mark Brown napsal(a):
    > On Thu, Mar 24, 2011 at 11:20:45AM +0100, Prchal Ji?? wrote:
    >> Hi,
    >> this patch ads SPI communication for codecs TLV320AIC3X and clock input on GPIO2 or BCLK.
    >> Tested on TLV320AIC3106 and AT91SAM9260.
    >> TODO: Set the model in SPI probe the right way. I don't know how.
    >
    > Register two SPI drivers with different names.
    ???

    >> This codec communicates on SPI in 1st byte: 7 MSB is register address, 1 LSB is read/write, 2nd byte data. For this
    >> reason there is new functions in soc-cache.c snd_soc_7_8_*.
    >
    > This looks mostly good but there's some cleanups needed, mostly from
    > extra stuff which snuck in there, and you need to rebase against current
    > code.
    What cleanup? I copy functions snd_soc_8_8_* and made change to 7_8.

    > As covered in SubmittingPatches you should always CC maintainers on
    > patches.
    Who is maintainer? I didn't find anyone, so I CC to author.

    >> config SND_SOC_AD73311
    >> tristate
    >> -
    >> +
    >
    > Random whitespace change, should be removed.
    Yes.

    >> * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
    >> + * Jiri Prchal, <jiri.prchal@aksignal.cz
    >
    > If you're going to do this you probably want a > in there.
    OK

    >> {
    >> struct snd_soc_codec *codec = codec_dai->codec;
    >> struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
    >> + u8 data;
    >> +
    >> + /* set external clock on GPIO2 or BCLK */
    >> + data = snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG);
    >> + data &= 0x0f;
    >> + data |= ((clk_id << PLLCLK_IN_SHIFT) | (clk_id << CLKDIV_IN_SHIFT));
    >> + snd_soc_write(codec, AIC3X_CLKGEN_CTRL_REG, data);
    >
    > This looks like an unrelated change which is specific to your board.
    > You should add an interface for configuring this functionality .
    No, it's for all, who uses other clock source. Interface is standard function:
    /* Set the codec system clock for DAC and ADC */
    ret = snd_soc_dai_set_sysclk(codec_dai,
    CLKIN_BCLK, cdu_audio[i].codecclk,
    SND_SOC_CLOCK_IN);

    >> if (ret != 0) {
    >> - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
    >> + dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
    >
    > Why are you decapitalising th estart of the sentance here?
    Corrected.

    >> +static struct spi_driver aic3x_spi_driver = {
    >> + .driver = {
    >> + .name = "tlv320aic3x-codec",
    >> + .owner = THIS_MODULE,
    >
    > Remove the -codec from the driver name.
    Why? In I2C part it must be there, so should it be same?

    >> +/* special functions for codecs with 7 bit register address and LSB read/write (like TLV320AIC3X) */
    >> +static unsigned int snd_soc_7_8_read(struct snd_soc_codec *codec,
    >> + unsigned int reg)
    >> +{
    >> + int ret;
    >> + unsigned int val;
    >
    > This won't apply against the current kernel and should be a separate
    > patch, it's a generic thing rather than part of the CODEC driver.
    I split it to another PATCH.

    > --
    > To unsubscribe from this list: send the line "unsubscribe alsa-devel" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at http://vger.kernel.org/majordomo-info.html
    >

    diff -uprN -X linux-2.6.38-vanilla/Documentation/dontdiff linux-2.6.38-vanilla/sound/soc/codecs/Kconfig
    linux-2.6.38-patch/sound/soc/codecs/Kconfig
    --- linux-2.6.38-vanilla/sound/soc/codecs/Kconfig 2011-03-15 02:20:32.000000000 +0100
    +++ linux-2.6.38-patch/sound/soc/codecs/Kconfig 2011-04-04 08:30:12.115356779 +0200
    @@ -37,7 +37,7 @@ config SND_SOC_ALL_CODECS
    select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
    select SND_SOC_TLV320AIC23 if I2C
    select SND_SOC_TLV320AIC26 if SPI_MASTER
    - select SND_SOC_TLV320AIC3X if I2C
    + select SND_SOC_TLV320AIC3X if SND_SOC_I2C_AND_SPI
    select SND_SOC_TPA6130A2 if I2C
    select SND_SOC_TLV320DAC33 if I2C
    select SND_SOC_TWL4030 if TWL4030_CORE
    diff -uprN -X linux-2.6.38-vanilla/Documentation/dontdiff linux-2.6.38-vanilla/sound/soc/codecs/tlv320aic3x.c
    linux-2.6.38-patch/sound/soc/codecs/tlv320aic3x.c
    --- linux-2.6.38-vanilla/sound/soc/codecs/tlv320aic3x.c 2011-03-15 02:20:32.000000000 +0100
    +++ linux-2.6.38-patch/sound/soc/codecs/tlv320aic3x.c 2011-04-04 08:31:33.521844547 +0200
    @@ -2,7 +2,9 @@
    * ALSA SoC TLV320AIC3X codec driver
    *
    * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
    + * Jiri Prchal, <jiri.prchal@aksignal.cz>
    * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
    + * (C) 2011 AK signal Brno
    *
    * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
    *
    @@ -42,6 +44,7 @@
    #include <linux/regulator/consumer.h>
    #include <linux/platform_device.h>
    #include <linux/slab.h>
    +#include <linux/spi/spi.h>
    #include <sound/core.h>
    #include <sound/pcm.h>
    #include <sound/pcm_params.h>
    @@ -864,9 +867,15 @@ static int aic3x_hw_params(struct snd_pc
    snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
    }

    - /* Route Left DAC to left channel input and
    - * right DAC to right channel input */
    - data = (LDAC2LCH | RDAC2RCH);
    + /* If is stereo: Route Left DAC to left channel input and
    + * right DAC to right channel input
    + * else mono: route left input to both DAC
    + */
    + if (params_channels(params) == 2)
    + data = (LDAC2LCH | RDAC2RCH);
    + else
    + data = (LDAC2LCH | RDAC2LCH);
    +
    data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
    if (params_rate(params) >= 64000)
    data |= DUAL_RATE_MODE;
    @@ -984,6 +993,13 @@ static int aic3x_set_dai_sysclk(struct s
    {
    struct snd_soc_codec *codec = codec_dai->codec;
    struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
    + u8 data;
    +
    + /* set external clock on GPIO2 or BCLK */
    + data = snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG);
    + data &= 0x0f;
    + data |= ((clk_id << PLLCLK_IN_SHIFT) | (clk_id << CLKDIV_IN_SHIFT));
    + snd_soc_write(codec, AIC3X_CLKGEN_CTRL_REG, data);

    aic3x->sysclk = freq;
    return 0;
    @@ -1371,7 +1387,10 @@ static int aic3x_probe(struct snd_soc_co
    aic3x->codec = codec;
    codec->dapm.idle_bias_off = 1;

    - ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
    + if (aic3x->control_type == SND_SOC_I2C)
    + ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
    + else
    + ret = snd_soc_codec_set_cache_io(codec, 7, 8, aic3x->control_type);
    if (ret != 0) {
    dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
    return ret;
    @@ -1472,6 +1491,54 @@ static struct snd_soc_codec_driver soc_c
    .resume = aic3x_resume,
    };

    +#if defined(CONFIG_SPI_MASTER)
    +static int aic3x_spi_probe(struct spi_device *spi)
    +{
    + struct aic3x_pdata *pdata = spi->dev.platform_data;
    + struct aic3x_priv *aic3x;
    + int ret;
    +
    + aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
    + if (aic3x == NULL) {
    + dev_err(&spi->dev, "failed to create private data\n");
    + return -ENOMEM;
    + }
    +
    + aic3x->control_type = SND_SOC_SPI;
    + spi_set_drvdata(spi, aic3x);
    +
    + if (pdata) {
    + aic3x->gpio_reset = pdata->gpio_reset;
    + aic3x->setup = pdata->setup;
    + } else {
    + aic3x->gpio_reset = -1;
    + }
    +
    + aic3x->model = AIC3X_MODEL_3X;
    +
    + ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_aic3x, &aic3x_dai, 1);
    + if (ret < 0)
    + kfree(aic3x);
    + return ret;
    +}
    +
    +static int __devexit aic3x_spi_remove(struct spi_device *spi)
    +{
    + snd_soc_unregister_codec(&spi->dev);
    + kfree(spi_get_drvdata(spi));
    + return 0;
    +}
    +
    +static struct spi_driver aic3x_spi_driver = {
    + .driver = {
    + .name = "tlv320aic3x-codec",
    + .owner = THIS_MODULE,
    + },
    + .probe = aic3x_spi_probe,
    + .remove = __devexit_p(aic3x_spi_remove),
    +};
    +#endif /* CONFIG_SPI_MASTER */
    +
    #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
    /*
    * AIC3X 2 wire address can be up to 4 devices with device addresses
    @@ -1557,6 +1624,13 @@ static int __init aic3x_modinit(void)
    ret);
    }
    #endif
    +#if defined(CONFIG_SPI_MASTER)
    + ret = spi_register_driver(&aic3x_spi_driver);
    + if (ret != 0) {
    + printk(KERN_ERR "Failed to register AIC3X SPI driver: %d\n",
    + ret);
    + }
    +#endif
    return ret;
    }
    module_init(aic3x_modinit);
    @@ -1566,6 +1640,9 @@ static void __exit aic3x_exit(void)
    #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
    i2c_del_driver(&aic3x_i2c_driver);
    #endif
    +#if defined(CONFIG_SPI_MASTER)
    + spi_unregister_driver(&aic3x_spi_driver);
    +#endif
    }
    module_exit(aic3x_exit);

    diff -uprN -X linux-2.6.38-vanilla/Documentation/dontdiff linux-2.6.38-vanilla/sound/soc/codecs/tlv320aic3x.h
    linux-2.6.38-patch/sound/soc/codecs/tlv320aic3x.h
    --- linux-2.6.38-vanilla/sound/soc/codecs/tlv320aic3x.h 2011-03-15 02:20:32.000000000 +0100
    +++ linux-2.6.38-patch/sound/soc/codecs/tlv320aic3x.h 2011-03-25 12:15:06.620049184 +0100
    @@ -163,6 +163,10 @@
    #define DUAL_RATE_MODE ((1 << 5) | (1 << 6))
    #define LDAC2LCH (0x1 << 3)
    #define RDAC2RCH (0x1 << 1)
    +#define LDAC2RCH (0x2 << 3)
    +#define RDAC2LCH (0x2 << 1)
    +#define LDAC2MONOMIX (0x3 << 3)
    +#define RDAC2MONOMIX (0x3 << 1)

    /* PLL registers bitfields */
    #define PLLP_SHIFT 0
    @@ -178,6 +182,13 @@
    #define PLL_CLKIN_SHIFT 4
    #define MCLK_SOURCE 0x0
    #define PLL_CLKDIV_SHIFT 0
    +#define PLLCLK_IN_SHIFT 4
    +#define CLKDIV_IN_SHIFT 6
    +/* clock in source */
    +#define CLKIN_MCLK 0
    +#define CLKIN_GPIO2 1
    +#define CLKIN_BCLK 2
    +

    /* Software reset register bits */
    #define SOFT_RESET 0x80

    \
     
     \ /
      Last update: 2011-04-04 09:53    [W:0.053 / U:0.656 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site