Unverified Commit ca514c0f authored by Nuno Sá's avatar Nuno Sá Committed by Mark Brown
Browse files

ASOC: Add ADAU7118 8 Channel PDM-to-I2S/TDM Converter driver



This patch adds support for the 8 channel PDM-to-I2S/TDM converter. The
ADAU7118 converts four stereo pulse density modulation (PDM) bitstreams
into one pulse code modulation (PCM) output stream. The source for the PDM
data can be eight microphones or other PDM sources. The PCM audio data is
output on a serial audio interface port in either inter-IC serial (I2S) or
time domain multiplexed (TDM) format.

Signed-off-by: default avatarNuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20191010074234.7344-1-nuno.sa@analog.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4bbee14d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1002,6 +1002,7 @@ F: drivers/media/i2c/adv7842*
ANALOG DEVICES INC ASOC CODEC DRIVERS
M:	Lars-Peter Clausen <lars@metafoo.de>
M:	Nuno Sá <nuno.sa@analog.com>
L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
W:	http://wiki.analog.com/
W:	http://ez.analog.com/community/linux-device-drivers
+28 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ config SND_SOC_ALL_CODECS
	select SND_SOC_ADAU1977_I2C if I2C
	select SND_SOC_ADAU1701 if I2C
	select SND_SOC_ADAU7002
	select SND_SOC_ADAU7118_I2C if I2C
	select SND_SOC_ADAU7118_HW
	select SND_SOC_ADS117X
	select SND_SOC_AK4104 if SPI_MASTER
	select SND_SOC_AK4118 if I2C
@@ -396,6 +398,32 @@ config SND_SOC_ADAU1977_I2C
config SND_SOC_ADAU7002
	tristate "Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter"

config SND_SOC_ADAU7118
	tristate

config SND_SOC_ADAU7118_HW
	tristate "Analog Devices ADAU7118 8 Channel PDM-to-I2S/TDM Converter - HW Mode"
	select SND_SOC_ADAU7118
	help
	  Enable support for the Analog Devices ADAU7118 8 Channel PDM-to-I2S/TDM
	  Converter. In this mode, the device works in standalone mode which
	  means that there is no bus to comunicate with it. Stereo mode is not
	  supported in this mode.

	  To compile this driver as a module, choose M here: the module
	  will be called snd-soc-adau7118-hw.

config SND_SOC_ADAU7118_I2C
	tristate "Analog Devices ADAU7118 8 Channel PDM-to-I2S/TDM Converter - I2C"
	select SND_SOC_ADAU7118
	select REGMAP_I2C
	help
	  Enable support for the Analog Devices ADAU7118 8 Channel PDM-to-I2S/TDM
	  Converter over I2C. This gives full support over the device.

	  To compile this driver as a module, choose M here: the module
	  will be called snd-soc-adau7118-i2c.

config SND_SOC_ADAV80X
	tristate

+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ snd-soc-adau1977-objs := adau1977.o
snd-soc-adau1977-spi-objs := adau1977-spi.o
snd-soc-adau1977-i2c-objs := adau1977-i2c.o
snd-soc-adau7002-objs := adau7002.o
snd-soc-adau7118-objs := adau7118.o
snd-soc-adau7118-i2c-objs := adau7118-i2c.o
snd-soc-adau7118-hw-objs := adau7118-hw.o
snd-soc-adav80x-objs := adav80x.o
snd-soc-adav801-objs := adav801.o
snd-soc-adav803-objs := adav803.o
@@ -305,6 +308,9 @@ obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o
obj-$(CONFIG_SND_SOC_ADAU1977_SPI)	+= snd-soc-adau1977-spi.o
obj-$(CONFIG_SND_SOC_ADAU1977_I2C)	+= snd-soc-adau1977-i2c.o
obj-$(CONFIG_SND_SOC_ADAU7002)	+= snd-soc-adau7002.o
obj-$(CONFIG_SND_SOC_ADAU7118)	+= snd-soc-adau7118.o
obj-$(CONFIG_SND_SOC_ADAU7118_I2C)	+= snd-soc-adau7118-i2c.o
obj-$(CONFIG_SND_SOC_ADAU7118_HW)	+= snd-soc-adau7118-hw.o
obj-$(CONFIG_SND_SOC_ADAV80X)  += snd-soc-adav80x.o
obj-$(CONFIG_SND_SOC_ADAV801)  += snd-soc-adav801.o
obj-$(CONFIG_SND_SOC_ADAV803)  += snd-soc-adav803.o
+43 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
//
// Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter Standalone Hw
// driver
//
// Copyright 2019 Analog Devices Inc.

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>

#include "adau7118.h"

static int adau7118_probe_hw(struct platform_device *pdev)
{
	return adau7118_probe(&pdev->dev, NULL, true);
}

static const struct of_device_id adau7118_of_match[] = {
	{ .compatible = "adi,adau7118" },
	{}
};
MODULE_DEVICE_TABLE(of, adau7118_of_match);

static const struct platform_device_id adau7118_id[] = {
	{ .name	= "adau7118" },
	{ }
};
MODULE_DEVICE_TABLE(platform, adau7118_id);

static struct platform_driver adau7118_driver_hw = {
	.driver = {
		.name = "adau7118",
		.of_match_table = adau7118_of_match,
	},
	.probe = adau7118_probe_hw,
	.id_table = adau7118_id,
};
module_platform_driver(adau7118_driver_hw);

MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver for standalone hw mode");
MODULE_LICENSE("GPL");
+82 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
//
// Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver over I2C
//
// Copyright 2019 Analog Devices Inc.

#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>

#include "adau7118.h"

static const struct reg_default adau7118_reg_defaults[] = {
	{ ADAU7118_REG_VENDOR_ID, 0x41 },
	{ ADAU7118_REG_DEVICE_ID1, 0x71 },
	{ ADAU7118_REG_DEVICE_ID2, 0x18 },
	{ ADAU7118_REG_REVISION_ID, 0x00 },
	{ ADAU7118_REG_ENABLES, 0x3F },
	{ ADAU7118_REG_DEC_RATIO_CLK_MAP, 0xC0 },
	{ ADAU7118_REG_HPF_CONTROL, 0xD0 },
	{ ADAU7118_REG_SPT_CTRL1, 0x41 },
	{ ADAU7118_REG_SPT_CTRL2, 0x00 },
	{ ADAU7118_REG_SPT_CX(0), 0x01 },
	{ ADAU7118_REG_SPT_CX(1), 0x11 },
	{ ADAU7118_REG_SPT_CX(2), 0x21 },
	{ ADAU7118_REG_SPT_CX(3), 0x31 },
	{ ADAU7118_REG_SPT_CX(4), 0x41 },
	{ ADAU7118_REG_SPT_CX(5), 0x51 },
	{ ADAU7118_REG_SPT_CX(6), 0x61 },
	{ ADAU7118_REG_SPT_CX(7), 0x71 },
	{ ADAU7118_REG_DRIVE_STRENGTH, 0x2a },
	{ ADAU7118_REG_RESET, 0x00 },
};

static const struct regmap_config adau7118_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.reg_defaults = adau7118_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(adau7118_reg_defaults),
	.cache_type = REGCACHE_RBTREE,
	.max_register = ADAU7118_REG_RESET,
};

static int adau7118_probe_i2c(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct regmap *map;

	map = devm_regmap_init_i2c(i2c, &adau7118_regmap_config);
	if (IS_ERR(map)) {
		dev_err(&i2c->dev, "Failed to init regmap %ld\n", PTR_ERR(map));
		return PTR_ERR(map);
	}

	return adau7118_probe(&i2c->dev, map, false);
}

static const struct of_device_id adau7118_of_match[] = {
	{ .compatible = "adi,adau7118" },
	{}
};
MODULE_DEVICE_TABLE(of, adau7118_of_match);

static const struct i2c_device_id adau7118_id[] = {
	{"adau7118", 0},
	{}
};
MODULE_DEVICE_TABLE(i2c, adau7118_id);

static struct i2c_driver adau7118_driver = {
	.driver = {
		.name = "adau7118",
		.of_match_table = adau7118_of_match,
	},
	.probe = adau7118_probe_i2c,
	.id_table = adau7118_id,
};
module_i2c_driver(adau7118_driver);

MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver over I2C");
MODULE_LICENSE("GPL");
Loading