ASoC: Add ADAU1977 CODEC driver

This patch adds support for the ADAU1977, ADAU1978 and ADAU1979 audio CODEC
devices. They are a family of 4-channel differential input audio ADC devices.
They can be connected to either a SPI or I2C bus. The driver is implemented in
three modules, one main module (adau1977.ko) which implements the device logic
and one module each for SPI (adau1977-spi.ko) and I2C (adau1977-i2c.ko) bus
access.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
Lars-Peter Clausen 2014-02-18 15:57:35 +01:00 committed by Mark Brown
parent a32eb702f8
commit 603597c937
7 changed files with 1256 additions and 0 deletions

View File

@ -0,0 +1,45 @@
/*
* ADAU1977/ADAU1978/ADAU1979 driver
*
* Copyright 2014 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#ifndef __LINUX_PLATFORM_DATA_ADAU1977_H__
#define __LINUX_PLATFORM_DATA_ADAU1977_H__
/**
* enum adau1977_micbias - ADAU1977 MICBIAS pin voltage setting
* @ADAU1977_MICBIAS_5V0: MICBIAS is set to 5.0 V
* @ADAU1977_MICBIAS_5V5: MICBIAS is set to 5.5 V
* @ADAU1977_MICBIAS_6V0: MICBIAS is set to 6.0 V
* @ADAU1977_MICBIAS_6V5: MICBIAS is set to 6.5 V
* @ADAU1977_MICBIAS_7V0: MICBIAS is set to 7.0 V
* @ADAU1977_MICBIAS_7V5: MICBIAS is set to 7.5 V
* @ADAU1977_MICBIAS_8V0: MICBIAS is set to 8.0 V
* @ADAU1977_MICBIAS_8V5: MICBIAS is set to 8.5 V
* @ADAU1977_MICBIAS_9V0: MICBIAS is set to 9.0 V
*/
enum adau1977_micbias {
ADAU1977_MICBIAS_5V0 = 0x0,
ADAU1977_MICBIAS_5V5 = 0x1,
ADAU1977_MICBIAS_6V0 = 0x2,
ADAU1977_MICBIAS_6V5 = 0x3,
ADAU1977_MICBIAS_7V0 = 0x4,
ADAU1977_MICBIAS_7V5 = 0x5,
ADAU1977_MICBIAS_8V0 = 0x6,
ADAU1977_MICBIAS_8V5 = 0x7,
ADAU1977_MICBIAS_9V0 = 0x8,
};
/**
* struct adau1977_platform_data - Platform configuration data for the ADAU1977
* @micbias: Specifies the voltage for the MICBIAS pin
*/
struct adau1977_platform_data {
enum adau1977_micbias micbias;
};
#endif

View File

@ -24,6 +24,8 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ADAU1373 if I2C
select SND_SOC_ADAV801 if SPI_MASTER
select SND_SOC_ADAV803 if I2C
select SND_SOC_ADAU1977_SPI if SPI_MASTER
select SND_SOC_ADAU1977_I2C if I2C
select SND_SOC_ADAU1701 if I2C
select SND_SOC_ADS117X
select SND_SOC_AK4104 if SPI_MASTER
@ -200,6 +202,19 @@ config SND_SOC_ADAU1701
config SND_SOC_ADAU1373
tristate
config SND_SOC_ADAU1977
tristate
config SND_SOC_ADAU1977_SPI
tristate
select SND_SOC_ADAU1977
select REGMAP_SPI
config SND_SOC_ADAU1977_I2C
tristate
select SND_SOC_ADAU1977
select REGMAP_I2C
config SND_SOC_ADAV80X
tristate

View File

@ -7,6 +7,9 @@ snd-soc-ad1980-objs := ad1980.o
snd-soc-ad73311-objs := ad73311.o
snd-soc-adau1701-objs := adau1701.o
snd-soc-adau1373-objs := adau1373.o
snd-soc-adau1977-objs := adau1977.o
snd-soc-adau1977-spi-objs := adau1977-spi.o
snd-soc-adau1977-i2c-objs := adau1977-i2c.o
snd-soc-adav80x-objs := adav80x.o
snd-soc-adav801-objs := adav801.o
snd-soc-adav803-objs := adav803.o
@ -139,6 +142,9 @@ obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
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_ADAU1701) += snd-soc-adau1701.o
obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o

View File

@ -0,0 +1,59 @@
/*
* ADAU1977/ADAU1978/ADAU1979 driver
*
* Copyright 2014 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "adau1977.h"
static int adau1977_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap_config config;
config = adau1977_regmap_config;
config.val_bits = 8;
config.reg_bits = 8;
return adau1977_probe(&client->dev,
devm_regmap_init_i2c(client, &config),
id->driver_data, NULL);
}
static int adau1977_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
return 0;
}
static const struct i2c_device_id adau1977_i2c_ids[] = {
{ "adau1977", ADAU1977 },
{ "adau1978", ADAU1978 },
{ "adau1979", ADAU1978 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids);
static struct i2c_driver adau1977_i2c_driver = {
.driver = {
.name = "adau1977",
.owner = THIS_MODULE,
},
.probe = adau1977_i2c_probe,
.remove = adau1977_i2c_remove,
.id_table = adau1977_i2c_ids,
};
module_i2c_driver(adau1977_i2c_driver);
MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,76 @@
/*
* ADAU1977/ADAU1978/ADAU1979 driver
*
* Copyright 2014 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
#include "adau1977.h"
static void adau1977_spi_switch_mode(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
/*
* To get the device into SPI mode CLATCH has to be pulled low three
* times. Do this by issuing three dummy reads.
*/
spi_w8r8(spi, 0x00);
spi_w8r8(spi, 0x00);
spi_w8r8(spi, 0x00);
}
static int adau1977_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct regmap_config config;
if (!id)
return -EINVAL;
config = adau1977_regmap_config;
config.val_bits = 8;
config.reg_bits = 16;
config.read_flag_mask = 0x1;
return adau1977_probe(&spi->dev,
devm_regmap_init_spi(spi, &config),
id->driver_data, adau1977_spi_switch_mode);
}
static int adau1977_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
return 0;
}
static const struct spi_device_id adau1977_spi_ids[] = {
{ "adau1977", ADAU1977 },
{ "adau1978", ADAU1978 },
{ "adau1979", ADAU1978 },
{ }
};
MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
static struct spi_driver adau1977_spi_driver = {
.driver = {
.name = "adau1977",
.owner = THIS_MODULE,
},
.probe = adau1977_spi_probe,
.remove = adau1977_spi_remove,
.id_table = adau1977_spi_ids,
};
module_spi_driver(adau1977_spi_driver);
MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL");

1018
sound/soc/codecs/adau1977.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/*
* ADAU1977/ADAU1978/ADAU1979 driver
*
* Copyright 2014 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2.
*/
#ifndef __SOUND_SOC_CODECS_ADAU1977_H__
#define __SOUND_SOC_CODECS_ADAU1977_H__
#include <linux/regmap.h>
struct device;
enum adau1977_type {
ADAU1977,
ADAU1978,
ADAU1979,
};
int adau1977_probe(struct device *dev, struct regmap *regmap,
enum adau1977_type type, void (*switch_mode)(struct device *dev));
extern const struct regmap_config adau1977_regmap_config;
enum adau1977_clk_id {
ADAU1977_SYSCLK,
};
enum adau1977_sysclk_src {
ADAU1977_SYSCLK_SRC_MCLK,
ADAU1977_SYSCLK_SRC_LRCLK,
};
#endif