Commit 13b137ef authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/asoc' into for-linus

parents e8fd86ef 44008559
......@@ -533,6 +533,8 @@ L: device-drivers-devel@blackfin.uclinux.org
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
W: http://wiki.analog.com/
S: Supported
F: sound/soc/codecs/adau*
F: sound/soc/codecs/adav*
F: sound/soc/codecs/ad1*
F: sound/soc/codecs/ssm*
......
......@@ -209,6 +209,10 @@ struct snd_soc_dai_driver {
struct snd_soc_pcm_stream capture;
struct snd_soc_pcm_stream playback;
unsigned int symmetric_rates:1;
/* probe ordering - for components with runtime dependencies */
int probe_order;
int remove_order;
};
/*
......
......@@ -348,6 +348,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
/* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
......@@ -429,6 +431,7 @@ struct snd_soc_dapm_path {
/* status */
u32 connect:1; /* source and sink widgets are connected */
u32 walked:1; /* path has been walked */
u32 weak:1; /* path ignored for power management */
int (*connected)(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink);
......@@ -444,6 +447,7 @@ struct snd_soc_dapm_widget {
char *name; /* widget name */
char *sname; /* stream name */
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
struct list_head list;
struct snd_soc_dapm_context *dapm;
......@@ -507,10 +511,11 @@ struct snd_soc_dapm_context {
struct device *dev; /* from parent - for debug */
struct snd_soc_codec *codec; /* parent codec */
struct snd_soc_platform *platform; /* parent platform */
struct snd_soc_card *card; /* parent card */
/* used during DAPM updates */
int dev_power;
enum snd_soc_bias_level target_bias_level;
struct list_head list;
#ifdef CONFIG_DEBUG_FS
......
......@@ -202,6 +202,16 @@
#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
/*
* Component probe and remove ordering levels for components with runtime
* dependencies.
*/
#define SND_SOC_COMP_ORDER_FIRST -2
#define SND_SOC_COMP_ORDER_EARLY -1
#define SND_SOC_COMP_ORDER_NORMAL 0
#define SND_SOC_COMP_ORDER_LATE 1
#define SND_SOC_COMP_ORDER_LAST 2
/*
* Bias levels
*
......@@ -214,10 +224,10 @@
* @OFF: Power Off. No restrictions on transition times.
*/
enum snd_soc_bias_level {
SND_SOC_BIAS_OFF,
SND_SOC_BIAS_STANDBY,
SND_SOC_BIAS_PREPARE,
SND_SOC_BIAS_ON,
SND_SOC_BIAS_OFF = 0,
SND_SOC_BIAS_STANDBY = 1,
SND_SOC_BIAS_PREPARE = 2,
SND_SOC_BIAS_ON = 3,
};
struct snd_jack;
......@@ -258,6 +268,11 @@ enum snd_soc_compress_type {
SND_SOC_RBTREE_COMPRESSION
};
enum snd_soc_pcm_subclass {
SND_SOC_PCM_CLASS_PCM = 0,
SND_SOC_PCM_CLASS_BE = 1,
};
int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
unsigned int freq, int dir);
int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
......@@ -297,6 +312,10 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec,
unsigned int reg);
int snd_soc_default_writable_register(struct snd_soc_codec *codec,
unsigned int reg);
int snd_soc_platform_read(struct snd_soc_platform *platform,
unsigned int reg);
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
......@@ -349,6 +368,8 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
const char *prefix);
int snd_soc_add_controls(struct snd_soc_codec *codec,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
......@@ -612,6 +633,10 @@ struct snd_soc_codec_driver {
void (*seq_notifier)(struct snd_soc_dapm_context *,
enum snd_soc_dapm_type, int);
/* probe ordering - for components with runtime dependencies */
int probe_order;
int remove_order;
};
/* SoC platform interface */
......@@ -623,10 +648,17 @@ struct snd_soc_platform_driver {
int (*resume)(struct snd_soc_dai *dai);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
struct snd_pcm *);
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* Default control and setup, added after probe() is run */
const struct snd_kcontrol_new *controls;
int num_controls;
const struct snd_soc_dapm_widget *dapm_widgets;
int num_dapm_widgets;
const struct snd_soc_dapm_route *dapm_routes;
int num_dapm_routes;
/*
* For platform caused delay reporting.
* Optional.
......@@ -636,6 +668,14 @@ struct snd_soc_platform_driver {
/* platform stream ops */
struct snd_pcm_ops *ops;
/* probe ordering - for components with runtime dependencies */
int probe_order;
int remove_order;
/* platform IO - used for platform DAPM */
unsigned int (*read)(struct snd_soc_platform *, unsigned int);
int (*write)(struct snd_soc_platform *, unsigned int, unsigned int);
};
struct snd_soc_platform {
......@@ -650,6 +690,8 @@ struct snd_soc_platform {
struct snd_soc_card *card;
struct list_head list;
struct list_head card_list;
struct snd_soc_dapm_context dapm;
};
struct snd_soc_dai_link {
......@@ -725,8 +767,10 @@ struct snd_soc_card {
/* callbacks */
int (*set_bias_level)(struct snd_soc_card *,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
int (*set_bias_level_post)(struct snd_soc_card *,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
long pmdown_time;
......@@ -789,6 +833,9 @@ struct snd_soc_pcm_runtime {
struct device dev;
struct snd_soc_card *card;
struct snd_soc_dai_link *dai_link;
struct mutex pcm_mutex;
enum snd_soc_pcm_subclass pcm_subclass;
struct snd_pcm_ops ops;
unsigned int complete:1;
unsigned int dev_registered:1;
......
......@@ -9,6 +9,7 @@
struct snd_soc_jack;
struct snd_soc_codec;
struct snd_soc_platform;
struct snd_soc_card;
struct snd_soc_dapm_widget;
......@@ -59,6 +60,50 @@ DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read,
);
DECLARE_EVENT_CLASS(snd_soc_preg,
TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
unsigned int val),
TP_ARGS(platform, reg, val),
TP_STRUCT__entry(
__string( name, platform->name )
__field( int, id )
__field( unsigned int, reg )
__field( unsigned int, val )
),
TP_fast_assign(
__assign_str(name, platform->name);
__entry->id = platform->id;
__entry->reg = reg;
__entry->val = val;
),
TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name),
(int)__entry->id, (unsigned int)__entry->reg,
(unsigned int)__entry->val)
);
DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write,
TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
unsigned int val),
TP_ARGS(platform, reg, val)
);
DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read,
TP_PROTO(struct snd_soc_platform *platform, unsigned int reg,
unsigned int val),
TP_ARGS(platform, reg, val)
);
DECLARE_EVENT_CLASS(snd_soc_card,
TP_PROTO(struct snd_soc_card *card, int val),
......
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
snd-soc-core-objs += soc-pcm.o soc-io.o
obj-$(CONFIG_SND_SOC) += snd-soc-core.o
obj-$(CONFIG_SND_SOC) += codecs/
......
......@@ -364,9 +364,11 @@ static struct snd_pcm_ops atmel_pcm_ops = {
\*--------------------------------------------------------------------------*/
static u64 atmel_pcm_dmamask = 0xffffffff;
static int atmel_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
if (!card->dev->dma_mask)
......@@ -382,7 +384,7 @@ static int atmel_pcm_new(struct snd_card *card,
}
if (dai->driver->capture.channels_min) {
pr_debug("at32-pcm:"
pr_debug("atmel-pcm:"
"Allocating PCM capture DMA buffer\n");
ret = atmel_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
......
......@@ -60,7 +60,7 @@ struct atmel_ssc_mask {
* This structure, shared between the PCM driver and the interface,
* contains all information required by the PCM driver to perform the
* PDC DMA operation. All fields except dma_intr_handler() are initialized
* by the interface. The dms_intr_handler() pointer is set by the PCM
* by the interface. The dma_intr_handler() pointer is set by the PCM
* driver and called by the interface SSC interrupt handler if it is
* non-NULL.
*/
......
......@@ -402,7 +402,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
&& bits > 16) {
printk(KERN_WARNING
"atmel_ssc_dai: sample size %d"
"atmel_ssc_dai: sample size %d "
"is too large for I2S\n", bits);
return -EINVAL;
}
......@@ -838,10 +838,8 @@ int atmel_ssc_set_audio(int ssc_id)
}
ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
if (!ssc_pdev) {
ssc_free(ssc);
if (!ssc_pdev)
return -ENOMEM;
}
/* If we can grab the SSC briefly to parent the DAI device off it */
ssc = ssc_request(ssc_id);
......
......@@ -92,6 +92,7 @@ static struct snd_soc_ops at91sam9g20ek_ops = {
};
static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
static int mclk_on;
......
......@@ -319,10 +319,11 @@ static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
static int au1xpsc_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai,
struct snd_pcm *pcm)
static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
card->dev, AU1XPSC_BUFFER_MIN_BYTES, (4096 * 1024) - 1);
......
......@@ -10,13 +10,36 @@ config SND_BF5XX_I2S
config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio support for BF52x ezkit"
depends on SND_BF5XX_I2S
depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
select SND_BF5XX_SOC_I2S
select SND_SOC_SSM2602
select I2C
help
Say Y if you want to add support for SoC audio on BF527-EZKIT.
config SND_SOC_BFIN_EVAL_ADAU1701
tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
depends on SND_BF5XX_I2S
select SND_BF5XX_SOC_I2S
select SND_SOC_ADAU1701
select I2C
help
Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
board connected to one of the Blackfin evaluation boards like the
BF5XX-STAMP or BF5XX-EZKIT.
config SND_SOC_BFIN_EVAL_ADAV80X
tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
select SND_BF5XX_SOC_I2S
select SND_SOC_ADAV80X
help
Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or
EVAL-ADAV803 board connected to one of the Blackfin evaluation boards
like the BF5XX-STAMP or BF5XX-EZKIT.
Note: This driver assumes that the ADAV80X digital record and playback
interfaces are connected to the first SPORT port on the BF5XX board.
config SND_BF5XX_SOC_AD73311
tristate "SoC AD73311 Audio support for Blackfin"
depends on SND_BF5XX_I2S
......
......@@ -21,9 +21,13 @@ snd-ad1980-objs := bf5xx-ad1980.o
snd-ssm2602-objs := bf5xx-ssm2602.o
snd-ad73311-objs := bf5xx-ad73311.o
snd-ad193x-objs := bf5xx-ad193x.o
snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
......@@ -418,9 +418,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
pr_debug("%s enter\n", __func__);
......
......@@ -168,7 +168,7 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
ret = snd_pcm_hw_constraint_integer(runtime, \
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
goto out;
......@@ -257,9 +257,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
pr_debug("%s enter\n", __func__);
......@@ -304,8 +306,8 @@ static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
static struct platform_driver bfin_i2s_pcm_driver = {
.driver = {
.name = "bfin-i2s-pcm-audio",
.owner = THIS_MODULE,
.name = "bfin-i2s-pcm-audio",
.owner = THIS_MODULE,
},
.probe = bfin_i2s_soc_platform_probe,
......
......@@ -283,9 +283,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
if (!card->dev->dma_mask)
......
/*
* Machine driver for EVAL-ADAU1701MINIZ on Analog Devices bfin
* evaluation boards.
*
* Copyright 2011 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include "../codecs/adau1701.h"
static const struct snd_soc_dapm_widget bfin_eval_adau1701_dapm_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", NULL),
SND_SOC_DAPM_LINE("Line Out", NULL),
SND_SOC_DAPM_LINE("Line In", NULL),
};
static const struct snd_soc_dapm_route bfin_eval_adau1701_dapm_routes[] = {
{ "Speaker", NULL, "OUT0" },
{ "Speaker", NULL, "OUT1" },
{ "Line Out", NULL, "OUT2" },
{ "Line Out", NULL, "OUT3" },
{ "IN0", NULL, "Line In" },
{ "IN1", NULL, "Line In" },
};
static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
SND_SOC_CLOCK_IN);
return ret;
}
static struct snd_soc_ops bfin_eval_adau1701_ops = {
.hw_params = bfin_eval_adau1701_hw_params,
};
static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
{
.name = "adau1701",
.stream_name = "adau1701",
.cpu_dai_name = "bfin-i2s.0",
.codec_dai_name = "adau1701",
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops,
},
{
.name = "adau1701",
.stream_name = "adau1701",
.cpu_dai_name = "bfin-i2s.1",
.codec_dai_name = "adau1701",
.platform_name = "bfin-i2s-pcm-audio",
.codec_name = "adau1701.0-0034",
.ops = &bfin_eval_adau1701_ops,
},
};
static struct snd_soc_card bfin_eval_adau1701 = {
.name = "bfin-eval-adau1701",
.dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM],
.num_links = 1,
.dapm_widgets = bfin_eval_adau1701_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1701_dapm_widgets),
.dapm_routes = bfin_eval_adau1701_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1701_dapm_routes),
};
static int bfin_eval_adau1701_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &bfin_eval_adau1701;
card->dev = &pdev->dev;
return snd_soc_register_card(&bfin_eval_adau1701);
}
static int __devexit bfin_eval_adau1701_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver bfin_eval_adau1701_driver = {
.driver = {
.name = "bfin-eval-adau1701",
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
},
.probe = bfin_eval_adau1701_probe,
.remove = __devexit_p(bfin_eval_adau1701_remove),
};
static int __init bfin_eval_adau1701_init(void)
{
return platform_driver_register(&bfin_eval_adau1701_driver);
}
module_init(bfin_eval_adau1701_init);
static void __exit bfin_eval_adau1701_exit(void)
{
platform_driver_unregister(&bfin_eval_adau1701_driver);
}
module_exit(bfin_eval_adau1701_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bfin-eval-adau1701");
/*
* Machine driver for EVAL-ADAV801 and EVAL-ADAV803 on Analog Devices bfin
* evaluation boards.
*
* Copyright 2011 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include "../codecs/adav80x.h"
static const struct snd_soc_dapm_widget bfin_eval_adav80x_dapm_widgets[] = {
SND_SOC_DAPM_LINE("Line Out", NULL),
SND_SOC_DAPM_LINE("Line In", NULL),
};
static const struct snd_soc_dapm_route bfin_eval_adav80x_dapm_routes[] = {
{ "Line Out", NULL, "VOUTL" },
{ "Line Out", NULL, "VOUTR" },
{ "VINL", NULL, "Line In" },
{ "VINR", NULL, "Line In" },
};
static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret)
return ret;
ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
27000000, params_rate(params) * 256);
if (ret)
return ret;
ret = snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_PLL1,
params_rate(params) * 256, SND_SOC_CLOCK_IN);
return ret;
}
static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *codec_dai = rtd->codec_dai;
snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK1, 0,
SND_SOC_CLOCK_OUT);
snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK2, 0,
SND_SOC_CLOCK_OUT);
snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK3, 0,
SND_SOC_CLOCK_OUT);
snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_XTAL, 2700000, 0);
return 0;
}
static struct snd_soc_ops bfin_eval_adav80x_ops = {
.hw_params = bfin_eval_adav80x_hw_params,
};
static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
{
.name = "adav80x",
.stream_name = "ADAV80x HiFi",
.cpu_dai_name = "bfin-i2s.0",
.codec_dai_name = "adav80x-hifi",
.platform_name = "bfin-i2s-pcm-audio",
.init = bfin_eval_adav80x_codec_init,
.ops = &bfin_eval_adav80x_ops,
},
};
static struct snd_soc_card bfin_eval_adav80x = {
.name = "bfin-eval-adav80x",
.dai_link = bfin_eval_adav80x_dais,
.num_links = ARRAY_SIZE(bfin_eval_adav80x_dais),
.dapm_widgets = bfin_eval_adav80x_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(bfin_eval_adav80x_dapm_widgets),
.dapm_routes = bfin_eval_adav80x_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(bfin_eval_adav80x_dapm_routes),
};
enum bfin_eval_adav80x_type {
BFIN_EVAL_ADAV801,
BFIN_EVAL_ADAV803,
};
static int bfin_eval_adav80x_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &bfin_eval_adav80x;
const char *codec_name;
switch (platform_get_device_id(pdev)->driver_data) {
case BFIN_EVAL_ADAV801:
codec_name = "spi0.1";
break;
case BFIN_EVAL_ADAV803:
codec_name = "adav803.0-0034";
break;
default:
return -EINVAL;
}
bfin_eval_adav80x_dais[0].codec_name = codec_name;
card->dev = &pdev->dev;
return snd_soc_register_card(&bfin_eval_adav80x);
}
static int __devexit bfin_eval_adav80x_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static const struct platform_device_id bfin_eval_adav80x_ids[] = {
{ "bfin-eval-adav801", BFIN_EVAL_ADAV801 },
{ "bfin-eval-adav803", BFIN_EVAL_ADAV803 },
{ },
};
MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids);
static struct platform_driver bfin_eval_adav80x_driver = {
.driver = {
.name = "bfin-eval-adav80x",
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
},
.probe = bfin_eval_adav80x_probe,
.remove = __devexit_p(bfin_eval_adav80x_remove),
.id_table = bfin_eval_adav80x_ids,
};
static int __init bfin_eval_adav80x_init(void)
{
return platform_driver_register(&bfin_eval_adav80x_driver);
}
module_init(bfin_eval_adav80x_init);
static void __exit bfin_eval_adav80x_exit(void)
{
platform_driver_unregister(&bfin_eval_adav80x_driver);
}
module_exit(bfin_eval_adav80x_exit);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
MODULE_LICENSE("GPL");
......@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
select SND_SOC_AD1980 if SND_SOC_AC97_BUS
select SND_SOC_AD73311
select SND_SOC_ADAV80X
select SND_SOC_ADS117X
select SND_SOC_AK4104 if SPI_MASTER
select SND_SOC_AK4535 if I2C
......@@ -42,6 +43,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_SN95031 if INTEL_SCU_IPC
select SND_SOC_SPDIF
select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
select SND_SOC_STA32X if I2C
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
select SND_SOC_TLV320AIC23 if I2C
select SND_SOC_TLV320AIC26 if SPI_MASTER
......@@ -71,6 +73,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8770 if SPI_MASTER
select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8782
select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
select SND_SOC_WM8903 if I2C
......@@ -84,6 +87,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8971 if I2C
select SND_SOC_WM8974 if I2C
select SND_SOC_WM8978 if I2C
select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8990 if I2C
......@@ -130,7 +134,14 @@ config SND_SOC_AD1980
config SND_SOC_AD73311
tristate
config SND_SOC_ADAU1701
select SIGMA
tristate
config SND_SOC_ADAV80X
tristate
config SND_SOC_ADS117X
tristate
......@@ -216,6 +227,9 @@ config SND_SOC_SPDIF
config SND_SOC_SSM2602
tristate
config SND_SOC_STA32X
tristate
config SND_SOC_STAC9766
tristate
......@@ -299,6 +313,9 @@ config SND_SOC_WM8770
config SND_SOC_WM8776
tristate
config SND_SOC_WM8782
tristate
config SND_SOC_WM8804
tristate
......@@ -338,6 +355,9 @@ config SND_SOC_WM8974
config SND_SOC_WM8978
tristate
config SND_SOC_WM8983
tristate
config SND_SOC_WM8985
tristate
......
......@@ -4,6 +4,8 @@ snd-soc-ad1836-objs := ad1836.o
snd-soc-ad193x-objs := ad193x.o
snd-soc-ad1980-objs := ad1980.o
snd-soc-ad73311-objs := ad73311.o
snd-soc-adau1701-objs := adau1701.o
snd-soc-adav80x-objs := adav80x.o
snd-soc-ads117x-objs := ads117x.o
snd-soc-ak4104-objs := ak4104.o
snd-soc-ak4535-objs := ak4535.o
......@@ -28,6 +30,7 @@ snd-soc-alc5623-objs := alc5623.o
snd-soc-sn95031-objs := sn95031.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
snd-soc-sta32x-objs := sta32x.o
snd-soc-stac9766-objs := stac9766.o
snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
......@@ -55,6 +58,7 @@ snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
snd-soc-wm8770-objs := wm8770.o
snd-soc-wm8776-objs := wm8776.o
snd-soc-wm8782-objs := wm8782.o
snd-soc-wm8804-objs := wm8804.o
snd-soc-wm8900-objs := wm8900.o
snd-soc-wm8903-objs := wm8903.o
......@@ -68,6 +72,7 @@ snd-soc-wm8962-objs := wm8962.o
snd-soc-wm8971-objs := wm8971.o
snd-soc-wm8974-objs := wm8974.o
snd-soc-wm8978-objs := wm8978.o
snd-soc-wm8983-objs := wm8983.o
snd-soc-wm8985-objs := wm8985.o
snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
......@@ -95,6 +100,8 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
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_ADAU1701) += snd-soc-adau1701.o
obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
......@@ -120,6 +127,7 @@ obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
......@@ -147,6 +155,7 @@ obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o
obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
......@@ -160,6 +169,7 @@ obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
obj-$(CONFIG_SND_SOC_WM8983) += snd-soc-wm8983.o
obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
......
This diff is collapsed.
/*
* File: sound/soc/codecs/ad1836.h
* Based on:
* Author: Barry Song <Barry.Song@analog.com>
* Audio Codec driver supporting:
* AD1835A, AD1836, AD1837A, AD1838A, AD1839A
*
* Created: Aug 04, 2009
* Description: definitions for AD1836 registers
* Copyright 2009-2011 Analog Devices Inc.
*
* Modified:
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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.
* Licensed under the GPL-2 or later.
*/
#ifndef __AD1836_H__
......@@ -21,39 +12,30 @@
#define AD1836_DAC_CTRL1 0
#define AD1836_DAC_POWERDOWN 2
#define AD1836_DAC_SERFMT_MASK 0xE0
#define AD1836_DAC_SERFMT_MASK 0xE0
#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
#define AD1836_DAC_WORD_LEN_MASK 0x18
#define AD1836_DAC_WORD_LEN_OFFSET 3
#define AD1836_DAC_CTRL2 1
#define AD1836_DACL1_MUTE 0
#define AD1836_DACR1_MUTE 1
#define AD1836_DACL2_MUTE 2
#define AD1836_DACR2_MUTE 3
#define AD1836_DACL3_MUTE 4
#define AD1836_DACR3_MUTE 5
#define AD1836_DAC_L1_VOL 2
#define AD1836_DAC_R1_VOL 3
#define AD1836_DAC_L2_VOL 4
#define AD1836_DAC_R2_VOL 5
#define AD1836_DAC_L3_VOL 6
#define AD1836_DAC_R3_VOL 7
/* These macros are one-based. So AD183X_MUTE_LEFT(1) will return the mute bit
* for the first ADC/DAC */
#define AD1836_MUTE_LEFT(x) (((x) * 2) - 2)
#define AD1836_MUTE_RIGHT(x) (((x) * 2) - 1)
#define AD1836_DAC_L_VOL(x) ((x) * 2)
#define AD1836_DAC_R_VOL(x) (1 + ((x) * 2))
#define AD1836_ADC_CTRL1 12
#define AD1836_ADC_POWERDOWN 7
#define AD1836_ADC_HIGHPASS_FILTER 8
#define AD1836_ADC_CTRL2 13
#define AD1836_ADCL1_MUTE 0
#define AD1836_ADCR1_MUTE 1
#define AD1836_ADCL2_MUTE 2
#define AD1836_ADCR2_MUTE 3
#define AD1836_ADC_WORD_LEN_MASK 0x30
#define AD1836_ADC_WORD_OFFSET 5
#define AD1836_ADC_SERFMT_MASK (7 << 6)
#define AD1836_ADC_SERFMT_MASK (7 << 6)
#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
#define AD1836_ADC_AUX (0x6 << 6)
......
This diff is collapsed.
/*
* header file for ADAU1701 SigmaDSP processor
*
* Copyright 2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef _ADAU1701_H
#define _ADAU1701_H
enum adau1701_clk_src {
ADAU1701_CLK_SRC_OSC,
ADAU1701_CLK_SRC_MCLK,
};
#endif
This diff is collapsed.
/*
* header file for ADAV80X parts
*
* Copyright 2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef _ADAV80X_H
#define _ADAV80X_H
enum adav80x_pll_src {
ADAV80X_PLL_SRC_XIN,
ADAV80X_PLL_SRC_XTAL,
ADAV80X_PLL_SRC_MCLKI,
};
enum adav80x_pll {
ADAV80X_PLL1 = 0,
ADAV80X_PLL2 = 1,
};
enum adav80x_clk_src {
ADAV80X_CLK_XIN = 0,
ADAV80X_CLK_MCLKI = 1,
ADAV80X_CLK_PLL1 = 2,
ADAV80X_CLK_PLL2 = 3,
ADAV80X_CLK_XTAL = 6,
ADAV80X_CLK_SYSCLK1 = 6,
ADAV80X_CLK_SYSCLK2 = 7,
ADAV80X_CLK_SYSCLK3 = 8,
};
#endif
......@@ -457,7 +457,7 @@ static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
.set_sysclk = ak4641_set_dai_sysclk,
};
struct snd_soc_dai_driver ak4641_dai[] = {
static struct snd_soc_dai_driver ak4641_dai[] = {
{
.name = "ak4641-hifi",
.id = 1,
......
......@@ -636,10 +636,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
#endif /* CONFIG_PM */
/*
* ASoC codec device structure
*
* Assign this variable to the codec_dev field of the machine driver's
* snd_soc_device structure.
* ASoC codec driver structure
*/
static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
.probe = cs4270_probe,
......
......@@ -1397,8 +1397,6 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
if (freq == max98088->sysclk)
return 0;
max98088->sysclk = freq; /* remember current sysclk */
/* Setup clocks for slave mode, and using the PLL
* PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
* 0x02 (when master clk is 20MHz to 30MHz)..
......
......@@ -1517,8 +1517,6 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
if (freq == max98095->sysclk)
return 0;
max98095->sysclk = freq; /* remember current sysclk */
/* Setup clocks for slave mode, and using the PLL
* PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
* 0x02 (when master clk is 20MHz to 40MHz)..
......@@ -2261,11 +2259,11 @@ static int max98095_probe(struct snd_soc_codec *codec)
ret = snd_soc_read(codec, M98095_0FF_REV_ID);
if (ret < 0) {
dev_err(codec->dev, "Failed to read device revision: %d\n",
dev_err(codec->dev, "Failure reading hardware revision: %d\n",
ret);
goto err_access;
}
dev_info(codec->dev, "revision %c\n", ret + 'A');
dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
......@@ -2342,8 +2340,8 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
max98095->control_data = i2c;
max98095->pdata = i2c->dev.platform_data;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_max98095, &max98095_dai[0], 3);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
max98095_dai, ARRAY_SIZE(max98095_dai));
if (ret < 0)
kfree(max98095);
return ret;
......
This diff is collapsed.
/*
* Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
*
* Copyright: 2011 Raumfeld GmbH
* Author: Johannes Stezenbach <js@sig21.net>
*
* based on code from:
* Wolfson Microelectronics PLC.
* Mark Brown <broonie@opensource.wolfsonmicro.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.
*/
#ifndef _ASOC_STA_32X_H
#define _ASOC_STA_32X_H
/* STA326 register addresses */
#define STA32X_REGISTER_COUNT 0x2d
#define STA32X_CONFA 0x00
#define STA32X_CONFB 0x01
#define STA32X_CONFC 0x02
#define STA32X_CONFD 0x03
#define STA32X_CONFE 0x04
#define STA32X_CONFF 0x05
#define STA32X_MMUTE 0x06
#define STA32X_MVOL 0x07
#define STA32X_C1VOL 0x08
#define STA32X_C2VOL 0x09
#define STA32X_C3VOL 0x0a
#define STA32X_AUTO1 0x0b
#define STA32X_AUTO2 0x0c
#define STA32X_AUTO3 0x0d
#define STA32X_C1CFG 0x0e
#define STA32X_C2CFG 0x0f
#define STA32X_C3CFG 0x10
#define STA32X_TONE 0x11
#define STA32X_L1AR 0x12
#define STA32X_L1ATRT 0x13
#define STA32X_L2AR 0x14
#define STA32X_L2ATRT 0x15
#define STA32X_CFADDR2 0x16
#define STA32X_B1CF1 0x17
#define STA32X_B1CF2 0x18
#define STA32X_B1CF3 0x19
#define STA32X_B2CF1 0x1a
#define STA32X_B2CF2 0x1b
#define STA32X_B2CF3 0x1c
#define STA32X_A1CF1 0x1d
#define STA32X_A1CF2 0x1e
#define STA32X_A1CF3 0x1f
#define STA32X_A2CF1 0x20
#define STA32X_A2CF2 0x21
#define STA32X_A2CF3 0x22
#define STA32X_B0CF1 0x23
#define STA32X_B0CF2 0x24
#define STA32X_B0CF3 0x25
#define STA32X_CFUD 0x26
#define STA32X_MPCC1 0x27
#define STA32X_MPCC2 0x28
/* Reserved 0x29 */
/* Reserved 0x2a */
#define STA32X_Reserved 0x2a
#define STA32X_FDRC1 0x2b
#define STA32X_FDRC2 0x2c
/* Reserved 0x2d */
/* STA326 register field definitions */
/* 0x00 CONFA */
#define STA32X_CONFA_MCS_MASK 0x03
#define STA32X_CONFA_MCS_SHIFT 0
#define STA32X_CONFA_IR_MASK 0x18
#define STA32X_CONFA_IR_SHIFT 3
#define STA32X_CONFA_TWRB 0x20
#define STA32X_CONFA_TWAB 0x40
#define STA32X_CONFA_FDRB 0x80
/* 0x01 CONFB */
#define STA32X_CONFB_SAI_MASK 0x0f
#define STA32X_CONFB_SAI_SHIFT 0
#define STA32X_CONFB_SAIFB 0x10
#define STA32X_CONFB_DSCKE 0x20
#define STA32X_CONFB_C1IM 0x40
#define STA32X_CONFB_C2IM 0x80
/* 0x02 CONFC */
#define STA32X_CONFC_OM_MASK 0x03
#define STA32X_CONFC_OM_SHIFT 0
#define STA32X_CONFC_CSZ_MASK 0x7c
#define STA32X_CONFC_CSZ_SHIFT 2
/* 0x03 CONFD */
#define STA32X_CONFD_HPB 0x01
#define STA32X_CONFD_HPB_SHIFT 0
#define STA32X_CONFD_DEMP 0x02
#define STA32X_CONFD_DEMP_SHIFT 1
#define STA32X_CONFD_DSPB 0x04
#define STA32X_CONFD_DSPB_SHIFT 2
#define STA32X_CONFD_PSL 0x08
#define STA32X_CONFD_PSL_SHIFT 3
#define STA32X_CONFD_BQL 0x10
#define STA32X_CONFD_BQL_SHIFT 4
#define STA32X_CONFD_DRC 0x20
#define STA32X_CONFD_DRC_SHIFT 5
#define STA32X_CONFD_ZDE 0x40
#define STA32X_CONFD_ZDE_SHIFT 6
#define STA32X_CONFD_MME 0x80
#define STA32X_CONFD_MME_SHIFT 7
/* 0x04 CONFE */
#define STA32X_CONFE_MPCV 0x01
#define STA32X_CONFE_MPCV_SHIFT 0
#define STA32X_CONFE_MPC 0x02
#define STA32X_CONFE_MPC_SHIFT 1
#define STA32X_CONFE_AME 0x08
#define STA32X_CONFE_AME_SHIFT 3
#define STA32X_CONFE_PWMS 0x10
#define STA32X_CONFE_PWMS_SHIFT 4
#define STA32X_CONFE_ZCE 0x40
#define STA32X_CONFE_ZCE_SHIFT 6
#define STA32X_CONFE_SVE 0x80
#define STA32X_CONFE_SVE_SHIFT 7
/* 0x05 CONFF */
#define STA32X_CONFF_OCFG_MASK 0x03
#define STA32X_CONFF_OCFG_SHIFT 0
#define STA32X_CONFF_IDE 0x04
#define STA32X_CONFF_IDE_SHIFT 3
#define STA32X_CONFF_BCLE 0x08
#define STA32X_CONFF_ECLE 0x20
#define STA32X_CONFF_PWDN 0x40
#define STA32X_CONFF_EAPD 0x80
/* 0x06 MMUTE */
#define STA32X_MMUTE_MMUTE 0x01
/* 0x0b AUTO1 */
#define STA32X_AUTO1_AMEQ_MASK 0x03
#define STA32X_AUTO1_AMEQ_SHIFT 0
#define STA32X_AUTO1_AMV_MASK 0xc0
#define STA32X_AUTO1_AMV_SHIFT 2
#define STA32X_AUTO1_AMGC_MASK 0x30
#define STA32X_AUTO1_AMGC_SHIFT 4
#define STA32X_AUTO1_AMPS 0x80
/* 0x0c AUTO2 */
#define STA32X_AUTO2_AMAME 0x01
#define STA32X_AUTO2_AMAM_MASK 0x0e
#define STA32X_AUTO2_AMAM_SHIFT 1
#define STA32X_AUTO2_XO_MASK 0xf0
#define STA32X_AUTO2_XO_SHIFT 4
/* 0x0d AUTO3 */
#define STA32X_AUTO3_PEQ_MASK 0x1f
#define STA32X_AUTO3_PEQ_SHIFT 0
/* 0x0e 0x0f 0x10 CxCFG */
#define STA32X_CxCFG_TCB 0x01 /* only C1 and C2 */
#define STA32X_CxCFG_TCB_SHIFT 0
#define STA32X_CxCFG_EQBP 0x02 /* only C1 and C2 */
#define STA32X_CxCFG_EQBP_SHIFT 1
#define STA32X_CxCFG_VBP 0x03
#define STA32X_CxCFG_VBP_SHIFT 2
#define STA32X_CxCFG_BO 0x04
#define STA32X_CxCFG_LS_MASK 0x30
#define STA32X_CxCFG_LS_SHIFT 4
#define STA32X_CxCFG_OM_MASK 0xc0
#define STA32X_CxCFG_OM_SHIFT 6
/* 0x11 TONE */
#define STA32X_TONE_BTC_SHIFT 0
#define STA32X_TONE_TTC_SHIFT 4
/* 0x12 0x13 0x14 0x15 limiter attack/release */
#define STA32X_LxA_SHIFT 0
#define STA32X_LxR_SHIFT 4
/* 0x26 CFUD */
#define STA32X_CFUD_W1 0x01
#define STA32X_CFUD_WA 0x02
#define STA32X_CFUD_R1 0x04
#define STA32X_CFUD_RA 0x08
/* biquad filter coefficient table offsets */
#define STA32X_C1_BQ_BASE 0
#define STA32X_C2_BQ_BASE 20
#define STA32X_CH_BQ_NUM 4
#define STA32X_BQ_NUM_COEF 5
#define STA32X_XO_HP_BQ_BASE 40
#define STA32X_XO_LP_BQ_BASE 45
#define STA32X_C1_PRESCALE 50
#define STA32X_C2_PRESCALE 51
#define STA32X_C1_POSTSCALE 52
#define STA32X_C2_POSTSCALE 53
#define STA32X_C3_POSTSCALE 54
#define STA32X_TW_POSTSCALE 55
#define STA32X_C1_MIX1 56
#define STA32X_C1_MIX2 57
#define STA32X_C2_MIX1 58
#define STA32X_C2_MIX2 59
#define STA32X_C3_MIX1 60
#define STA32X_C3_MIX2 61
#endif /* _ASOC_STA_32X_H */
......@@ -226,11 +226,13 @@ static const char *aic3x_adc_hpf[] =
#define RDAC_ENUM 1
#define LHPCOM_ENUM 2
#define RHPCOM_ENUM 3
#define LINE1L_ENUM 4
#define LINE1R_ENUM 5
#define LINE2L_ENUM 6
#define LINE2R_ENUM 7
#define ADC_HPF_ENUM 8
#define LINE1L_2_L_ENUM 4
#define LINE1L_2_R_ENUM 5
#define LINE1R_2_L_ENUM 6
#define LINE1R_2_R_ENUM 7
#define LINE2L_ENUM 8
#define LINE2R_ENUM 9
#define ADC_HPF_ENUM 10
static const struct soc_enum aic3x_enum[] = {
SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux),
......@@ -238,6 +240,8 @@ static const struct soc_enum aic3x_enum[] = {
SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux),
SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux),
SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
SOC_ENUM_SINGLE(LINE1L_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
SOC_ENUM_SINGLE(LINE1R_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
......@@ -490,12 +494,16 @@ static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
};
/* Left Line1 Mux */
static const struct snd_kcontrol_new aic3x_left_line1_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_ENUM]);
static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_L_ENUM]);
static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_R_ENUM]);
/* Right Line1 Mux */
static const struct snd_kcontrol_new aic3x_right_line1_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_ENUM]);
static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_R_ENUM]);
static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls =
SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_L_ENUM]);
/* Left Line2 Mux */
static const struct snd_kcontrol_new aic3x_left_line2_mux_controls =
......@@ -535,9 +543,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
&aic3x_left_pga_mixer_controls[0],
ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_line1_mux_controls),
&aic3x_left_line1l_mux_controls),
SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_line1_mux_controls),
&aic3x_left_line1r_mux_controls),
SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_line2_mux_controls),
......@@ -548,9 +556,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
&aic3x_right_pga_mixer_controls[0],
ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
&aic3x_right_line1_mux_controls),
&aic3x_right_line1l_mux_controls),
SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
&aic3x_right_line1_mux_controls),
&aic3x_right_line1r_mux_controls),
SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
&aic3x_right_line2_mux_controls),
......
......@@ -954,9 +954,9 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
/*
* MICGAIN volume control:
* from -6 to 30 dB in 6 dB steps
* from 6 to 30 dB in 6 dB steps
*/
static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
/*
* AFMGAIN volume control:
......
/*
* sound/soc/codecs/wm8782.c
* simple, strap-pin configured 24bit 2ch ADC
*
* Copyright: 2011 Raumfeld GmbH
* Author: Johannes Stezenbach <js@sig21.net>
*
* based on ad73311.c
* Copyright: Analog Device Inc.
* Author: Cliff Cai <cliff.cai@analog.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.
*/
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
static struct snd_soc_dai_driver wm8782_dai = {
.name = "wm8782",
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
/* For configurations with FSAMPEN=0 */
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE |
SNDRV_PCM_FMTBIT_S24_LE,
},
};
static struct snd_soc_codec_driver soc_codec_dev_wm8782;
static __devinit int wm8782_probe(struct platform_device *pdev)
{
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_wm8782, &wm8782_dai, 1);
}
static int __devexit wm8782_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver wm8782_codec_driver = {
.driver = {
.name = "wm8782",
.owner = THIS_MODULE,
},
.probe = wm8782_probe,
.remove = wm8782_remove,
};
static int __init wm8782_init(void)
{
return platform_driver_register(&wm8782_codec_driver);
}
module_init(wm8782_init);
static void __exit wm8782_exit(void)
{
platform_driver_unregister(&wm8782_codec_driver);
}
module_exit(wm8782_exit);
MODULE_DESCRIPTION("ASoC WM8782 driver");
MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
MODULE_LICENSE("GPL");
......@@ -1167,6 +1167,7 @@ static int wm8900_resume(struct snd_soc_codec *codec)
ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
if (ret != 0) {
dev_err(codec->dev, "Failed to restart FLL\n");
kfree(cache);
return ret;
}
}
......
......@@ -2560,6 +2560,7 @@ static __devexit int wm8904_i2c_remove(struct i2c_client *client)
static const struct i2c_device_id wm8904_i2c_id[] = {
{ "wm8904", WM8904 },
{ "wm8912", WM8912 },
{ "wm8918", WM8904 }, /* Actually a subset, updates to follow */
{ }
};
MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
......
......@@ -41,14 +41,12 @@
#define HPOUT2L 4
#define HPOUT2R 8
#define WM8915_NUM_SUPPLIES 6
#define WM8915_NUM_SUPPLIES 4
static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
"DCVDD",
"DBVDD",
"AVDD1",
"AVDD2",
"CPVDD",
"MICVDD",
};
struct wm8915_priv {
......@@ -57,6 +55,7 @@ struct wm8915_priv {
int ldo1ena;
int sysclk;
int sysclk_src;
int fll_src;
int fll_fref;
......@@ -76,6 +75,7 @@ struct wm8915_priv {
struct wm8915_pdata pdata;
int rx_rate[WM8915_AIFS];
int bclk_rate[WM8915_AIFS];
/* Platform dependant ReTune mobile configuration */
int num_retune_mobile_texts;
......@@ -113,8 +113,6 @@ WM8915_REGULATOR_EVENT(0)
WM8915_REGULATOR_EVENT(1)
WM8915_REGULATOR_EVENT(2)
WM8915_REGULATOR_EVENT(3)
WM8915_REGULATOR_EVENT(4)
WM8915_REGULATOR_EVENT(5)
static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
[WM8915_SOFTWARE_RESET] = 0x8915,
......@@ -1565,6 +1563,50 @@ static int wm8915_reset(struct snd_soc_codec *codec)
return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
}
static const int bclk_divs[] = {
1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
};
static void wm8915_update_bclk(struct snd_soc_codec *codec)
{
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
int aif, best, cur_val, bclk_rate, bclk_reg, i;
/* Don't bother if we're in a low frequency idle mode that
* can't support audio.
*/
if (wm8915->sysclk < 64000)
return;
for (aif = 0; aif < WM8915_AIFS; aif++) {
switch (aif) {
case 0:
bclk_reg = WM8915_AIF1_BCLK;
break;
case 1:
bclk_reg = WM8915_AIF2_BCLK;
break;
}
bclk_rate = wm8915->bclk_rate[aif];
/* Pick a divisor for BCLK as close as we can get to ideal */
best = 0;
for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
if (cur_val < 0) /* BCLK table is sorted */
break;
best = i;
}
bclk_rate = wm8915->sysclk / bclk_divs[best];
dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);
snd_soc_update_bits(codec, bclk_reg,
WM8915_AIF1_BCLK_DIV_MASK, best);
}
}
static int wm8915_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
......@@ -1717,10 +1759,6 @@ static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
static const int bclk_divs[] = {
1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
};
static const int dsp_divs[] = {
48000, 32000, 16000, 8000
};
......@@ -1731,17 +1769,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
int bits, i, bclk_rate, best, cur_val;
int bits, i, bclk_rate;
int aifdata = 0;
int bclk = 0;
int lrclk = 0;
int dsp = 0;
int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;
if (!wm8915->sysclk) {
dev_err(codec->dev, "SYSCLK not configured\n");
return -EINVAL;
}
int aifdata_reg, lrclk_reg, dsp_shift;
switch (dai->id) {
case 0:
......@@ -1753,7 +1785,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
}
bclk_reg = WM8915_AIF1_BCLK;
dsp_shift = 0;
break;
case 1:
......@@ -1765,7 +1796,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
}
bclk_reg = WM8915_AIF2_BCLK;
dsp_shift = WM8915_DSP2_DIV_SHIFT;
break;
default:
......@@ -1779,6 +1809,9 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
return bclk_rate;
}
wm8915->bclk_rate[dai->id] = bclk_rate;
wm8915->rx_rate[dai->id] = params_rate(params);
/* Needs looking at for TDM */
bits = snd_pcm_format_width(params_format(params));
if (bits < 0)
......@@ -1796,18 +1829,7 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
}
dsp |= i << dsp_shift;
/* Pick a divisor for BCLK as close as we can get to ideal */
best = 0;
for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
if (cur_val < 0) /* BCLK table is sorted */
break;
best = i;
}
bclk_rate = wm8915->sysclk / bclk_divs[best];
dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);
bclk |= best;
wm8915_update_bclk(codec);
lrclk = bclk_rate / params_rate(params);
dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
......@@ -1817,14 +1839,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
WM8915_AIF1TX_WL_MASK |
WM8915_AIF1TX_SLOT_LEN_MASK,
aifdata);
snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
lrclk);
snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
wm8915->rx_rate[dai->id] = params_rate(params);
return 0;
}
......@@ -1838,6 +1857,9 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
int src;
int old;
if (freq == wm8915->sysclk && clk_id == wm8915->sysclk_src)
return 0;
/* Disable SYSCLK while we reconfigure */
old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA;
snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
......@@ -1882,6 +1904,8 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
return -EINVAL;
}
wm8915_update_bclk(codec);
snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
......@@ -1889,6 +1913,8 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
WM8915_SYSCLK_ENA, old);
wm8915->sysclk_src = clk_id;
return 0;
}
......@@ -2007,6 +2033,7 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
unsigned int Fref, unsigned int Fout)
{
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c = to_i2c_client(codec->dev);
struct _fll_div fll_div;
unsigned long timeout;
int ret, reg;
......@@ -2093,7 +2120,18 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
else
timeout = msecs_to_jiffies(2);
wait_for_completion_timeout(&wm8915->fll_lock, timeout);
/* Allow substantially longer if we've actually got the IRQ */
if (i2c->irq)
timeout *= 1000;
ret = wait_for_completion_timeout(&wm8915->fll_lock, timeout);
if (ret == 0 && i2c->irq) {
dev_err(codec->dev, "Timed out waiting for FLL\n");
ret = -ETIMEDOUT;
} else {
ret = 0;
}
dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
......@@ -2101,7 +2139,7 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
wm8915->fll_fout = Fout;
wm8915->fll_src = source;
return 0;
return ret;
}
#ifdef CONFIG_GPIOLIB
......@@ -2293,6 +2331,12 @@ static void wm8915_micd(struct snd_soc_codec *codec)
SND_JACK_HEADSET | SND_JACK_BTN_0);
wm8915->jack_mic = true;
wm8915->detecting = false;
/* Increase poll rate to give better responsiveness
* for buttons */
snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
WM8915_MICD_RATE_MASK,
5 << WM8915_MICD_RATE_SHIFT);
}
/* If we detected a lower impedence during initial startup
......@@ -2333,15 +2377,17 @@ static void wm8915_micd(struct snd_soc_codec *codec)
SND_JACK_HEADPHONE,
SND_JACK_HEADSET |
SND_JACK_BTN_0);
/* Increase the detection rate a bit for
* responsiveness.
*/
snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
WM8915_MICD_RATE_MASK,
7 << WM8915_MICD_RATE_SHIFT);
wm8915->detecting = false;
}
}
/* Increase poll rate to give better responsiveness for buttons */
if (!wm8915->detecting)
snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
WM8915_MICD_RATE_MASK,
5 << WM8915_MICD_RATE_SHIFT);
}
static irqreturn_t wm8915_irq(int irq, void *data)
......@@ -2383,6 +2429,20 @@ static irqreturn_t wm8915_irq(int irq, void *data)
}
}
static irqreturn_t wm8915_edge_irq(int irq, void *data)
{
irqreturn_t ret = IRQ_NONE;
irqreturn_t val;
do {
val = wm8915_irq(irq, data);
if (val != IRQ_NONE)
ret = val;
} while (val != IRQ_NONE);
return ret;
}
static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
{
struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
......@@ -2482,8 +2542,6 @@ static int wm8915_probe(struct snd_soc_codec *codec)
wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
/* This should really be moved into the regulator core */
for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
......@@ -2709,8 +2767,14 @@ static int wm8915_probe(struct snd_soc_codec *codec)
irq_flags |= IRQF_ONESHOT;
ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
irq_flags, "wm8915", codec);
if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
ret = request_threaded_irq(i2c->irq, NULL,
wm8915_edge_irq,
irq_flags, "wm8915", codec);
else
ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
irq_flags, "wm8915", codec);
if (ret == 0) {
/* Unmask the interrupt */
snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
......
......@@ -297,8 +297,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
if (ret)
goto error_ret;
ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
if (ret)
goto error_ret;
error_ret:
return ret;
......@@ -683,8 +681,6 @@ static int wm8940_resume(struct snd_soc_codec *codec)
}
}
ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
if (ret)
goto error_ret;
error_ret:
return ret;
......@@ -730,9 +726,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
if (ret)
return ret;
ret = wm8940_add_widgets(codec);
if (ret)
return ret;
return ret;
}
......
......@@ -78,6 +78,8 @@ struct wm8962_priv {
#ifdef CONFIG_GPIOLIB
struct gpio_chip gpio_chip;
#endif
int irq;
};
/* We can't use the same notifier block for more than one supply and
......@@ -1982,6 +1984,7 @@ static const unsigned int classd_tlv[] = {
0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
};
static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
/* The VU bits for the headphones are in a different register to the mute
* bits and only take effect on the PGA if it is actually powered.
......@@ -2119,6 +2122,18 @@ SOC_SINGLE_TLV("HPMIXR MIXINR Volume", WM8962_HEADPHONE_MIXER_4,
SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0,
classd_tlv),
SOC_SINGLE("EQ Switch", WM8962_EQ1, WM8962_EQ_ENA_SHIFT, 1, 0),
SOC_DOUBLE_R_TLV("EQ1 Volume", WM8962_EQ2, WM8962_EQ22,
WM8962_EQL_B1_GAIN_SHIFT, 31, 0, eq_tlv),
SOC_DOUBLE_R_TLV("EQ2 Volume", WM8962_EQ2, WM8962_EQ22,
WM8962_EQL_B2_GAIN_SHIFT, 31, 0, eq_tlv),
SOC_DOUBLE_R_TLV("EQ3 Volume", WM8962_EQ2, WM8962_EQ22,
WM8962_EQL_B3_GAIN_SHIFT, 31, 0, eq_tlv),
SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
};
static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
......@@ -2184,6 +2199,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
unsigned long timeout;
int src;
int fll;
......@@ -2203,9 +2220,19 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (fll)
if (fll) {
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
WM8962_FLL_ENA, WM8962_FLL_ENA);
if (wm8962->irq) {
timeout = msecs_to_jiffies(5);
timeout = wait_for_completion_timeout(&wm8962->fll_lock,
timeout);
if (timeout == 0)
dev_err(codec->dev,
"Timed out starting FLL\n");
}
}
break;
case SND_SOC_DAPM_POST_PMD:
......@@ -2763,18 +2790,44 @@ static const int bclk_divs[] = {
1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
};
static const int sysclk_rates[] = {
64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
};
static void wm8962_configure_bclk(struct snd_soc_codec *codec)
{
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
int dspclk, i;
int clocking2 = 0;
int clocking4 = 0;
int aif2 = 0;
if (!wm8962->bclk) {
dev_dbg(codec->dev, "No BCLK rate configured\n");
if (!wm8962->sysclk_rate) {
dev_dbg(codec->dev, "No SYSCLK configured\n");
return;
}
if (!wm8962->bclk || !wm8962->lrclk) {
dev_dbg(codec->dev, "No audio clocks configured\n");
return;
}
for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
if (sysclk_rates[i] == wm8962->sysclk_rate / wm8962->lrclk) {
clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
break;
}
}
if (i == ARRAY_SIZE(sysclk_rates)) {
dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
wm8962->sysclk_rate / wm8962->lrclk);
return;
}
snd_soc_update_bits(codec, WM8962_CLOCKING_4,
WM8962_SYSCLK_RATE_MASK, clocking4);
dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
if (dspclk < 0) {
dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
......@@ -2844,6 +2897,8 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
/* VMID 2*50k */
snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
WM8962_VMID_SEL_MASK, 0x80);
wm8962_configure_bclk(codec);
break;
case SND_SOC_BIAS_STANDBY:
......@@ -2876,8 +2931,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, WM8962_CLOCKING2,
WM8962_CLKREG_OVD,
WM8962_CLKREG_OVD);
wm8962_configure_bclk(codec);
}
/* VMID 2*250k */
......@@ -2918,10 +2971,6 @@ static const struct {
{ 96000, 6 },
};
static const int sysclk_rates[] = {
64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
};
static int wm8962_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
......@@ -2929,41 +2978,27 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec;
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
int rate = params_rate(params);
int i;
int aif0 = 0;
int adctl3 = 0;
int clocking4 = 0;
wm8962->bclk = snd_soc_params_to_bclk(params);
wm8962->lrclk = params_rate(params);
for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
if (sr_vals[i].rate == rate) {
if (sr_vals[i].rate == wm8962->lrclk) {
adctl3 |= sr_vals[i].reg;
break;
}
}
if (i == ARRAY_SIZE(sr_vals)) {
dev_err(codec->dev, "Unsupported rate %dHz\n", rate);
dev_err(codec->dev, "Unsupported rate %dHz\n", wm8962->lrclk);
return -EINVAL;
}
if (rate % 8000 == 0)
if (wm8962->lrclk % 8000 == 0)
adctl3 |= WM8962_SAMPLE_RATE_INT_MODE;
for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
if (sysclk_rates[i] == wm8962->sysclk_rate / rate) {
clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
break;
}
}
if (i == ARRAY_SIZE(sysclk_rates)) {
dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
wm8962->sysclk_rate / rate);
return -EINVAL;
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
break;
......@@ -2985,8 +3020,6 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
WM8962_SAMPLE_RATE_INT_MODE |
WM8962_SAMPLE_RATE_MASK, adctl3);
snd_soc_update_bits(codec, WM8962_CLOCKING_4,
WM8962_SYSCLK_RATE_MASK, clocking4);
wm8962_configure_bclk(codec);
......@@ -3261,16 +3294,31 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
/* This should be a massive overestimate */
timeout = msecs_to_jiffies(1);
ret = 0;
if (fll1 & WM8962_FLL_ENA) {
/* This should be a massive overestimate but go even
* higher if we'll error out
*/
if (wm8962->irq)
timeout = msecs_to_jiffies(5);
else
timeout = msecs_to_jiffies(1);
timeout = wait_for_completion_timeout(&wm8962->fll_lock,
timeout);
wait_for_completion_timeout(&wm8962->fll_lock, timeout);
if (timeout == 0 && wm8962->irq) {
dev_err(codec->dev, "FLL lock timed out");
ret = -ETIMEDOUT;
}
}
wm8962->fll_fref = Fref;
wm8962->fll_fout = Fout;
wm8962->fll_src = source;
return 0;
return ret;
}
static int wm8962_mute(struct snd_soc_dai *dai, int mute)
......@@ -3731,8 +3779,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
int ret;
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
dev);
u16 *reg_cache = codec->reg_cache;
int i, trigger, irq_pol;
bool dmicclk, dmicdat;
......@@ -3871,6 +3917,9 @@ static int wm8962_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
WM8962_HPOUT_VU, WM8962_HPOUT_VU);
/* Stereo control for EQ */
snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0);
wm8962_add_widgets(codec);
/* Save boards having to disable DMIC when not in use */
......@@ -3899,7 +3948,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
wm8962_init_beep(codec);
wm8962_init_gpio(codec);
if (i2c->irq) {
if (wm8962->irq) {
if (pdata && pdata->irq_active_low) {
trigger = IRQF_TRIGGER_LOW;
irq_pol = WM8962_IRQ_POL;
......@@ -3911,12 +3960,13 @@ static int wm8962_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL,
WM8962_IRQ_POL, irq_pol);
ret = request_threaded_irq(i2c->irq, NULL, wm8962_irq,
ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
trigger | IRQF_ONESHOT,
"wm8962", codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
i2c->irq, ret);
wm8962->irq, ret);
wm8962->irq = 0;
/* Non-fatal */
} else {
/* Enable some IRQs by default */
......@@ -3941,12 +3991,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
static int wm8962_remove(struct snd_soc_codec *codec)
{
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
dev);
int i;
if (i2c->irq)
free_irq(i2c->irq, codec);
if (wm8962->irq)
free_irq(wm8962->irq, codec);
cancel_delayed_work_sync(&wm8962->mic_work);
......@@ -3986,6 +4034,8 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8962);
wm8962->irq = i2c->irq;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8962, &wm8962_dai, 1);
if (ret < 0)
......
This diff is collapsed.
This diff is collapsed.
......@@ -876,7 +876,7 @@ SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0,
right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
};
static const struct snd_soc_dapm_route routes[] = {
......@@ -1434,6 +1434,7 @@ static int wm8993_probe(struct snd_soc_codec *codec)
wm8993->hubs_data.hp_startup_mode = 1;
wm8993->hubs_data.dcs_codes = -2;
wm8993->hubs_data.series_startup = 1;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
if (ret != 0) {
......
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include <sound/soc.h>
#include <linux/firmware.h>
#include <linux/completion.h>
#include "wm_hubs.h"
......@@ -79,6 +80,8 @@ struct wm8994_priv {
int mclk[2];
int aifclk[2];
struct wm8994_fll_config fll[2], fll_suspend[2];
struct completion fll_locked[2];
bool fll_locked_irq;
int dac_rates[2];
int lrclk_shared[2];
......
......@@ -727,7 +727,7 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
SND_SOC_DAPM_OUT_DRV("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("LINEOUT"),
SND_SOC_DAPM_OUTPUT("SPKN"),
......
This diff is collapsed.
......@@ -14,6 +14,9 @@
#ifndef _WM_HUBS_H
#define _WM_HUBS_H
#include <linux/completion.h>
#include <linux/interrupt.h>
struct snd_soc_codec;
extern const unsigned int wm_hubs_spkmix_tlv[];
......@@ -23,9 +26,14 @@ struct wm_hubs_data {
int dcs_codes;
int dcs_readback_mode;
int hp_startup_mode;
int series_startup;
int no_series_update;
bool class_w;
u16 class_w_dcs;
bool dcs_done_irq;
struct completion dcs_done;
};
extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
......@@ -36,4 +44,6 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
int jd_scthr, int jd_thr,
int micbias1_lvl, int micbias2_lvl);
extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
#endif
This diff is collapsed.
......@@ -266,9 +266,11 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
static u64 ep93xx_pcm_dmamask = 0xffffffff;
static int ep93xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
if (!card->dev->dma_mask)
......
......@@ -294,9 +294,11 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
* Regardless of where the memory is actually allocated, since the device can
* technically DMA to any 36-bit address, we do need to set the DMA mask to 36.
*/
static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
int ret;
......@@ -939,7 +941,7 @@ static int __devinit fsl_soc_dma_probe(struct platform_device *pdev)
iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
if (iprop)
dma->ssi_fifo_depth = *iprop;
dma->ssi_fifo_depth = be32_to_cpup(iprop);
else
/* Older 8610 DTs didn't have the fifo-depth property */
dma->ssi_fifo_depth = 8;
......
......@@ -678,7 +678,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
kfree(ssi_private);
return ret;
}
ssi_private->ssi = ioremap(res.start, 1 + res.end - res.start);
ssi_private->ssi = of_iomap(np, 0);
if (!ssi_private->ssi) {
dev_err(&pdev->dev, "could not map device resources\n");
kfree(ssi_private);
return -ENOMEM;
}
ssi_private->ssi_phys = res.start;
ssi_private->irq = irq_of_parse_and_map(np, 0);
......@@ -691,7 +696,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
/* Determine the FIFO depth. */
iprop = of_get_property(np, "fsl,fifo-depth", NULL);
if (iprop)
ssi_private->fifo_depth = *iprop;
ssi_private->fifo_depth = be32_to_cpup(iprop);
else
/* Older 8610 DTs didn't have the fifo-depth property */
ssi_private->fifo_depth = 8;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment