diff mbox

[1/2] ASoC: pcm5102a: Add support for PCM5102A codec

Message ID 1463130853-25096-2-git-send-email-kernel@martin.sperl.org (mailing list archive)
State Accepted
Commit 97d3ddd71fbf663a5da52897757333341a8b254f
Headers show

Commit Message

Martin Sperl May 13, 2016, 9:14 a.m. UTC
From: Florian Meier <florian.meier@koalo.de>

Some definitions to support the PCM5102A codec
by Texas Instruments.

Signed-off-by: Florian Meier <florian.meier@koalo.de>

Changes to original patch by Florian Meier:
* rebased (Makefile and Kconfig
* fixed checkpath errors (spaces, newlines)
* added dt-binding documentation

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 .../devicetree/bindings/sound/pcm5102a.txt         | 13 ++++
 sound/soc/codecs/Kconfig                           |  4 ++
 sound/soc/codecs/Makefile                          |  2 +
 sound/soc/codecs/pcm5102a.c                        | 69 ++++++++++++++++++++++
 4 files changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/pcm5102a.txt
 create mode 100644 sound/soc/codecs/pcm5102a.c

Comments

Rob Herring (Arm) May 16, 2016, 4:26 p.m. UTC | #1
On Fri, May 13, 2016 at 09:14:12AM +0000, kernel@martin.sperl.org wrote:
> From: Florian Meier <florian.meier@koalo.de>
> 
> Some definitions to support the PCM5102A codec
> by Texas Instruments.
> 
> Signed-off-by: Florian Meier <florian.meier@koalo.de>
> 
> Changes to original patch by Florian Meier:
> * rebased (Makefile and Kconfig
> * fixed checkpath errors (spaces, newlines)
> * added dt-binding documentation
> 
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
> ---
>  .../devicetree/bindings/sound/pcm5102a.txt         | 13 ++++
>  sound/soc/codecs/Kconfig                           |  4 ++
>  sound/soc/codecs/Makefile                          |  2 +
>  sound/soc/codecs/pcm5102a.c                        | 69 ++++++++++++++++++++++
>  4 files changed, 88 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/pcm5102a.txt
>  create mode 100644 sound/soc/codecs/pcm5102a.c
> 
> diff --git a/Documentation/devicetree/bindings/sound/pcm5102a.txt b/Documentation/devicetree/bindings/sound/pcm5102a.txt
> new file mode 100644
> index 0000000..c63ab0b6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/pcm5102a.txt
> @@ -0,0 +1,13 @@
> +PCM5102a audio CODECs
> +
> +These devices does not use I2C or SPI.

s/does/do/ or singular device.

What do they use? Describe the interface (or lack of), not 2 possible 
interfaces that it doesn't have.

> +
> +Required properties:
> +
> +  - compatible : set as "ti,pcm5102a"
> +
> +Examples:
> +
> +	pcm5102a: pcm5102a {
> +		compatible = "ti,pcm5102a";
> +	};
Emmanuel Fusté May 22, 2016, 9:29 p.m. UTC | #2
Le 13/05/2016 à 11:14, kernel@martin.sperl.org a écrit :
> From: Florian Meier <florian.meier@koalo.de>
>
> Some definitions to support the PCM5102A codec
> by Texas Instruments.
>
> Signed-off-by: Florian Meier <florian.meier@koalo.de>
>
> Changes to original patch by Florian Meier:
> * rebased (Makefile and Kconfig
> * fixed checkpath errors (spaces, newlines)
> * added dt-binding documentation
>
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
> ---
>  .../devicetree/bindings/sound/pcm5102a.txt         | 13 ++++
>  sound/soc/codecs/Kconfig                           |  4 ++
>  sound/soc/codecs/Makefile                          |  2 +
>  sound/soc/codecs/pcm5102a.c                        | 69 ++++++++++++++++++++++
>  4 files changed, 88 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/pcm5102a.txt
>  create mode 100644 sound/soc/codecs/pcm5102a.c
>
> diff --git a/Documentation/devicetree/bindings/sound/pcm5102a.txt b/Documentation/devicetree/bindings/sound/pcm5102a.txt
> new file mode 100644
> index 0000000..c63ab0b6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/pcm5102a.txt
> @@ -0,0 +1,13 @@
> +PCM5102a audio CODECs
> +
> +These devices does not use I2C or SPI.
> +
> +Required properties:
> +
> +  - compatible : set as "ti,pcm5102a"
> +
> +Examples:
> +
> +	pcm5102a: pcm5102a {
> +		compatible = "ti,pcm5102a";
> +	};
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 7ef3a0c..26ae0b5 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -94,6 +94,7 @@ config SND_SOC_ALL_CODECS
>  	select SND_SOC_PCM3008
>  	select SND_SOC_PCM3168A_I2C if I2C
>  	select SND_SOC_PCM3168A_SPI if SPI_MASTER
> +	select SND_SOC_PCM5102A
>  	select SND_SOC_PCM512x_I2C if I2C
>  	select SND_SOC_PCM512x_SPI if SPI_MASTER
>  	select SND_SOC_RT286 if I2C
> @@ -575,6 +576,9 @@ config SND_SOC_PCM3168A_SPI
>  	select SND_SOC_PCM3168A
>  	select REGMAP_SPI
>
> +config SND_SOC_PCM5102A
> +	tristate
> +
>  config SND_SOC_PCM512x
>  	tristate
>
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index 185a712..4532a74 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -89,6 +89,7 @@ snd-soc-pcm3008-objs := pcm3008.o
>  snd-soc-pcm3168a-objs := pcm3168a.o
>  snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o
>  snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o
> +snd-soc-pcm5102a-objs := pcm5102a.o
>  snd-soc-pcm512x-objs := pcm512x.o
>  snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
>  snd-soc-pcm512x-spi-objs := pcm512x-spi.o
> @@ -298,6 +299,7 @@ obj-$(CONFIG_SND_SOC_PCM3008)	+= snd-soc-pcm3008.o
>  obj-$(CONFIG_SND_SOC_PCM3168A)	+= snd-soc-pcm3168a.o
>  obj-$(CONFIG_SND_SOC_PCM3168A_I2C)	+= snd-soc-pcm3168a-i2c.o
>  obj-$(CONFIG_SND_SOC_PCM3168A_SPI)	+= snd-soc-pcm3168a-spi.o
> +obj-$(CONFIG_SND_SOC_PCM5102A)	+= snd-soc-pcm5102a.o
>  obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
>  obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
>  obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
> diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
> new file mode 100644
> index 0000000..ed51567
> --- /dev/null
> +++ b/sound/soc/codecs/pcm5102a.c
> @@ -0,0 +1,69 @@
> +/*
> + * Driver for the PCM5102A codec
> + *
> + * Author:	Florian Meier <florian.meier@koalo.de>
> + *		Copyright 2013
> + *
> + * 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.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_dai_driver pcm5102a_dai = {
> +	.name = "pcm5102a-hifi",
> +	.playback = {
> +		.channels_min = 2,
> +		.channels_max = 2,
> +		.rates = SNDRV_PCM_RATE_8000_192000,
> +		.formats = SNDRV_PCM_FMTBIT_S16_LE |
> +			   SNDRV_PCM_FMTBIT_S24_LE |
> +			   SNDRV_PCM_FMTBIT_S32_LE
> +	},
> +};
> +
> +static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
> +
> +static int pcm5102a_probe(struct platform_device *pdev)
> +{
> +	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
> +			&pcm5102a_dai, 1);
> +}
> +
> +static int pcm5102a_remove(struct platform_device *pdev)
> +{
> +	snd_soc_unregister_codec(&pdev->dev);
> +	return 0;
> +}
> +
> +static const struct of_device_id pcm5102a_of_match[] = {
> +	{ .compatible = "ti,pcm5102a", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
> +
> +static struct platform_driver pcm5102a_codec_driver = {
> +	.probe		= pcm5102a_probe,
> +	.remove		= pcm5102a_remove,
> +	.driver		= {
> +		.name	= "pcm5102a-codec",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = pcm5102a_of_match,
> +	},
> +};
> +
> +module_platform_driver(pcm5102a_codec_driver);
> +
> +MODULE_DESCRIPTION("ASoC PCM5102A codec driver");
> +MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
> +MODULE_LICENSE("GPL v2");
>
Hello,

There is nothing PCM5102A specific here, and it is pretty generic.
Wouldn't it be better to write instead a simple-i2s-codec for all the 
classics I2S "hifi" DACs which will get the I2S/DAI parameters from DT ?
PCM510x, PCM5122 in HW mode, ES9023, a bunch of ES90xx implementations 
etc... will use exactly the same code with only format and rate 
variation. And for the rate, it is implementation dependent, even in the 
case of pcm5102a.

Emmanuel.
Mark Brown May 23, 2016, 5:08 p.m. UTC | #3
On Sun, May 22, 2016 at 11:29:55PM +0200, Emmanuel Fusté wrote:

> There is nothing PCM5102A specific here, and it is pretty generic.
> Wouldn't it be better to write instead a simple-i2s-codec for all the
> classics I2S "hifi" DACs which will get the I2S/DAI parameters from DT ?
> PCM510x, PCM5122 in HW mode, ES9023, a bunch of ES90xx implementations
> etc... will use exactly the same code with only format and rate variation.
> And for the rate, it is implementation dependent, even in the case of
> pcm5102a.

If we do that then we have no idea what the hardware actually is and
we're creating more effort on the DT side, the DT has to specify all 
the parameters for the device rather than just the name.  Given how
trivial the code is it's not clear that this is a win.
Emmanuel Fusté May 23, 2016, 8:37 p.m. UTC | #4
Le 23/05/2016 à 19:08, Mark Brown a écrit :
> On Sun, May 22, 2016 at 11:29:55PM +0200, Emmanuel Fusté wrote:
>
>> There is nothing PCM5102A specific here, and it is pretty generic.
>> Wouldn't it be better to write instead a simple-i2s-codec for all the
>> classics I2S "hifi" DACs which will get the I2S/DAI parameters from DT ?
>> PCM510x, PCM5122 in HW mode, ES9023, a bunch of ES90xx implementations
>> etc... will use exactly the same code with only format and rate variation.
>> And for the rate, it is implementation dependent, even in the case of
>> pcm5102a.
>
> If we do that then we have no idea what the hardware actually is and
> we're creating more effort on the DT side, the DT has to specify all
> the parameters for the device rather than just the name.  Given how
> trivial the code is it's not clear that this is a win.
>
All the parameters are only rate and format.
And even rate is implementation dependent. Knowing the name of the 
hardware give nothing. You still have to look at the schematic or look 
at the board to know valid rates.
Actually is anything but a PCM5102A codec driver. It is a driver for an 
I2S device accepting PCM rate from 8khz to 192khz with bck rate of 48fs 
or 64fs (32fs is normally supported too by the hw mode used in hifiberry).

Yes this push more effort on the DT side, but I think this is better to 
describe in DT the actual "I2S only" hardware capabilities of the 
implementation of the device guided by wiring or design choice.
Doing code cut&paste and two static assignment adjustment to create a 
"new" driver is completely overkill and nonflexible.

instead of the proposed dt, we could have :

/* pcm5102a in HW mode with external SCK (4wire mode)
  * at 128fs, 192fs or 256fs
  */
	pcm5102a-4w: pcm5102a {
		compatible = "simple-i2s-codec";
		rate = <SNDRV_PCM_RATE_8000_192000>;
		format = < SNDRV_PCM_FMTBIT_S16_LE
			|SNDRV_PCM_FMTBIT_S24_LE
			|SNDRV_PCM_FMTBIT_S32_LE>;
	};
or
/* pcm5102a in HW mode with PLL on BCK (3wire mode)
  * 16to384khz but only with bck rate of 64fs
  */
	pcm5102a-4w: pcm5102a {
		compatible = "simple-i2s-codec";
		rate = <SNDRV_PCM_RATE_8000_192000
			^ SNDRV_PCM_RATE_8000>;
		format = <SNDRV_PCM_FMTBIT_S32_LE>;
	};
Or
/* ES9023 in asynchronous mode mclk > 37Mhz
  * I did not try bck rate <64fs as the sabre family did not generally
  * support it.
  */
	es9023: es9023 {
		compatible = "simple-i2s-codec";
		rate = <SNDRV_PCM_RATE_8000_192000>;
		format = <SNDRV_PCM_FMTBIT_S32_LE>;
	};

We could use I2S friendly property instead of "format" :
		bckrates = <48, 64>;


With two or tree more property (gpio for mute, de-emphasis and filter 
selection), you could cover 98% of I2S DAC with hardware only 
interfaces. It cover too startup mode of most hifi I2C or SPI 
controllable DAC. Which is a good starting point for chip for which a 
driver is not already written.

Emmanuel.
Mark Brown May 23, 2016, 10:29 p.m. UTC | #5
On Mon, May 23, 2016 at 10:37:18PM +0200, Emmanuel Fusté wrote:

> All the parameters are only rate and format.

Off the top of my head clocking constraints are another thing we could
know...

> And even rate is implementation dependent. Knowing the name of the hardware
> give nothing. You still have to look at the schematic or look at the board
> to know valid rates.

Fortunately we have mechanisms for constraining things between multiple
devices, it's not like this is a property unique to registerless CODECs.

> Yes this push more effort on the DT side, but I think this is better to
> describe in DT the actual "I2S only" hardware capabilities of the
> implementation of the device guided by wiring or design choice.
> Doing code cut&paste and two static assignment adjustment to create a "new"
> driver is completely overkill and nonflexible.

If someone was so motivated they could also make one big driver with a
table of per device constraints in it, it doesn't *have* to be separate
files.

> /* pcm5102a in HW mode with external SCK (4wire mode)
>  * at 128fs, 192fs or 256fs
>  */
> 	pcm5102a-4w: pcm5102a {
> 		compatible = "simple-i2s-codec";
> 		rate = <SNDRV_PCM_RATE_8000_192000>;
> 		format = < SNDRV_PCM_FMTBIT_S16_LE
> 			|SNDRV_PCM_FMTBIT_S24_LE
> 			|SNDRV_PCM_FMTBIT_S32_LE>;
> 	};

Those defines look awfully Linux specific...

> /* pcm5102a in HW mode with PLL on BCK (3wire mode)
>  * 16to384khz but only with bck rate of 64fs
>  */
> 	pcm5102a-4w: pcm5102a {
> 		compatible = "simple-i2s-codec";
> 		rate = <SNDRV_PCM_RATE_8000_192000
> 			^ SNDRV_PCM_RATE_8000>;
> 		format = <SNDRV_PCM_FMTBIT_S32_LE>;
> 	};

...and another way of doing the multiple options would be to have the
binding be per device and use the clock binding to describe where the
master clock comes from which then allows us to start and stop that
clock on demand and possibly (as our clock API integration improves)
constrain based on that.  It may be that in future or perhaps even just
for other users of the same board the set of constraints is different
(perhaps they choose some other clock rate for something in the system
due to other constraints which lets the master clock vary more for
example).  

It's also just more work for the second person to come across the
device, at best they have to go and type in the same data over again.

A brief look at the datasheet suggests that there's also a few GPIO
controls we might have wired up where we can expose them and of course
regulators we may want to control in some systems.
Ricard Wanderlof May 24, 2016, 2:44 p.m. UTC | #6
On Mon, 23 May 2016, Emmanuel Fusté wrote:

> /* pcm5102a in HW mode with external SCK (4wire mode)
>  * at 128fs, 192fs or 256fs
>  */
> 	pcm5102a-4w: pcm5102a {
> 		compatible = "simple-i2s-codec";
> 		rate = <SNDRV_PCM_RATE_8000_192000>;
> 		format = < SNDRV_PCM_FMTBIT_S16_LE
> 			|SNDRV_PCM_FMTBIT_S24_LE
> 			|SNDRV_PCM_FMTBIT_S32_LE>;
> 	};
> or
> /* pcm5102a in HW mode with PLL on BCK (3wire mode)
>  * 16to384khz but only with bck rate of 64fs
>  */
> 	pcm5102a-4w: pcm5102a {
> 		compatible = "simple-i2s-codec";
> 		rate = <SNDRV_PCM_RATE_8000_192000
> 			^ SNDRV_PCM_RATE_8000>;
> 		format = <SNDRV_PCM_FMTBIT_S32_LE>;
> 	};
> Or
> /* ES9023 in asynchronous mode mclk > 37Mhz
>  * I did not try bck rate <64fs as the sabre family did not generally
>  * support it.
>  */
> 	es9023: es9023 {
> 		compatible = "simple-i2s-codec";
> 		rate = <SNDRV_PCM_RATE_8000_192000>;
> 		format = <SNDRV_PCM_FMTBIT_S32_LE>;
> 	};
> 
> We could use I2S friendly property instead of "format" :
> 		bckrates = <48, 64>;
> 
> 
> With two or tree more property (gpio for mute, de-emphasis and filter
> selection), you could cover 98% of I2S DAC with hardware only interfaces. It
> cover too startup mode of most hifi I2C or SPI controllable DAC. Which is a
> good starting point for chip for which a driver is not already written.

It seems to me that this only covers the cases where the is codec running 
in slave mode with MCLK derived from the BCLK, but not cases where the 
codec is master and needs to have its MCLK configured appropriately (in 
terms of device-specifc clock source and PLL settings), or am I missing 
something?

/Ricard
Emmanuel Fusté May 24, 2016, 10:33 p.m. UTC | #7
Le 24/05/2016 à 16:44, Ricard Wanderlof a écrit :
>
> On Mon, 23 May 2016, Emmanuel Fusté wrote:
>
>> /* pcm5102a in HW mode with external SCK (4wire mode)
>>  * at 128fs, 192fs or 256fs
>>  */
>> 	pcm5102a-4w: pcm5102a {
>> 		compatible = "simple-i2s-codec";
>> 		rate = <SNDRV_PCM_RATE_8000_192000>;
>> 		format = < SNDRV_PCM_FMTBIT_S16_LE
>> 			|SNDRV_PCM_FMTBIT_S24_LE
>> 			|SNDRV_PCM_FMTBIT_S32_LE>;
>> 	};
>> or
>> /* pcm5102a in HW mode with PLL on BCK (3wire mode)
>>  * 16to384khz but only with bck rate of 64fs
>>  */
>> 	pcm5102a-4w: pcm5102a {
>> 		compatible = "simple-i2s-codec";
>> 		rate = <SNDRV_PCM_RATE_8000_192000
>> 			^ SNDRV_PCM_RATE_8000>;
>> 		format = <SNDRV_PCM_FMTBIT_S32_LE>;
>> 	};
>> Or
>> /* ES9023 in asynchronous mode mclk > 37Mhz
>>  * I did not try bck rate <64fs as the sabre family did not generally
>>  * support it.
>>  */
>> 	es9023: es9023 {
>> 		compatible = "simple-i2s-codec";
>> 		rate = <SNDRV_PCM_RATE_8000_192000>;
>> 		format = <SNDRV_PCM_FMTBIT_S32_LE>;
>> 	};
>>
>> We could use I2S friendly property instead of "format" :
>> 		bckrates = <48, 64>;
>>
>>
>> With two or tree more property (gpio for mute, de-emphasis and filter
>> selection), you could cover 98% of I2S DAC with hardware only interfaces. It
>> cover too startup mode of most hifi I2C or SPI controllable DAC. Which is a
>> good starting point for chip for which a driver is not already written.
>
> It seems to me that this only covers the cases where the is codec running
> in slave mode with MCLK derived from the BCLK, but not cases where the
> codec is master and needs to have its MCLK configured appropriately (in
> terms of device-specifc clock source and PLL settings), or am I missing
> something?
>
> /Ricard
>

It not a codec but a simple I2S DAC.
No I2S master mode.
Like most DAC before the CODEC era and all the big mess around them.
In the ES9023 case, the MCLK could either have no frequency an no phase 
relationship with the I2S clocks.
In this case, the MCLK is surely derived from a clock of the Rpi SOC so 
you are right, and the whole HifiBerry driver should be rewritten with 
proper abstraction like Mark suggested : Clock binding etc ...
But now as Mark say too, clock api integration is a goal, but not there.
The proposed hw param rules is a start to not have to write specific 
machine driver because of clocking constraints.
It is the second time I am scratching my head because of clocking 
constraints and because I want to do something better than writing 
another trivial machine driver.
In my case (BBB or other Ti soc using mcasp) I will have to had 
mux/clk_set_parent switching action and/or clk_set_rate action. But I am 
not persuaded that is it the way to go.

That why, by the time we get proper clock api integration with proper 
constraint and constraint description mechanism, a simple DT 
configurable codec driver in which we push the resulting constraint 
(DAC+SOC+design choice) was appealing.

But you are all right. This is not the long term proper way. And the 
actual ultra simple PCM510xA driver could evolve to support all GPIO and 
later properly express all his clock constraints independently of the 
implementation choices.

Thank your for your patience.

Emmanuel.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/sound/pcm5102a.txt b/Documentation/devicetree/bindings/sound/pcm5102a.txt
new file mode 100644
index 0000000..c63ab0b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/pcm5102a.txt
@@ -0,0 +1,13 @@ 
+PCM5102a audio CODECs
+
+These devices does not use I2C or SPI.
+
+Required properties:
+
+  - compatible : set as "ti,pcm5102a"
+
+Examples:
+
+	pcm5102a: pcm5102a {
+		compatible = "ti,pcm5102a";
+	};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 7ef3a0c..26ae0b5 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -94,6 +94,7 @@  config SND_SOC_ALL_CODECS
 	select SND_SOC_PCM3008
 	select SND_SOC_PCM3168A_I2C if I2C
 	select SND_SOC_PCM3168A_SPI if SPI_MASTER
+	select SND_SOC_PCM5102A
 	select SND_SOC_PCM512x_I2C if I2C
 	select SND_SOC_PCM512x_SPI if SPI_MASTER
 	select SND_SOC_RT286 if I2C
@@ -575,6 +576,9 @@  config SND_SOC_PCM3168A_SPI
 	select SND_SOC_PCM3168A
 	select REGMAP_SPI
 
+config SND_SOC_PCM5102A
+	tristate
+
 config SND_SOC_PCM512x
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 185a712..4532a74 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -89,6 +89,7 @@  snd-soc-pcm3008-objs := pcm3008.o
 snd-soc-pcm3168a-objs := pcm3168a.o
 snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o
 snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o
+snd-soc-pcm5102a-objs := pcm5102a.o
 snd-soc-pcm512x-objs := pcm512x.o
 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 snd-soc-pcm512x-spi-objs := pcm512x-spi.o
@@ -298,6 +299,7 @@  obj-$(CONFIG_SND_SOC_PCM3008)	+= snd-soc-pcm3008.o
 obj-$(CONFIG_SND_SOC_PCM3168A)	+= snd-soc-pcm3168a.o
 obj-$(CONFIG_SND_SOC_PCM3168A_I2C)	+= snd-soc-pcm3168a-i2c.o
 obj-$(CONFIG_SND_SOC_PCM3168A_SPI)	+= snd-soc-pcm3168a-spi.o
+obj-$(CONFIG_SND_SOC_PCM5102A)	+= snd-soc-pcm5102a.o
 obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
new file mode 100644
index 0000000..ed51567
--- /dev/null
+++ b/sound/soc/codecs/pcm5102a.c
@@ -0,0 +1,69 @@ 
+/*
+ * Driver for the PCM5102A codec
+ *
+ * Author:	Florian Meier <florian.meier@koalo.de>
+ *		Copyright 2013
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_dai_driver pcm5102a_dai = {
+	.name = "pcm5102a-hifi",
+	.playback = {
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE |
+			   SNDRV_PCM_FMTBIT_S24_LE |
+			   SNDRV_PCM_FMTBIT_S32_LE
+	},
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
+
+static int pcm5102a_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
+			&pcm5102a_dai, 1);
+}
+
+static int pcm5102a_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id pcm5102a_of_match[] = {
+	{ .compatible = "ti,pcm5102a", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
+
+static struct platform_driver pcm5102a_codec_driver = {
+	.probe		= pcm5102a_probe,
+	.remove		= pcm5102a_remove,
+	.driver		= {
+		.name	= "pcm5102a-codec",
+		.owner	= THIS_MODULE,
+		.of_match_table = pcm5102a_of_match,
+	},
+};
+
+module_platform_driver(pcm5102a_codec_driver);
+
+MODULE_DESCRIPTION("ASoC PCM5102A codec driver");
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_LICENSE("GPL v2");