Commit ba252af8 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/asoc' into for-linus

* topic/asoc: (135 commits)
  ASoC: Apostrophe patrol
  ASoC: codec tlv320aic23 fix bogus divide by 0 message
  ASoC: fix NULL pointer dereference in soc_suspend()
  ASoC: Fix build error in twl4030.c
  ASoC: SSM2602: assign last substream to the master when shutting down
  ASoC: Blackfin: document how anomaly 05000250 is handled
  ASoC: Blackfin: set the transfer size according the ac97_frame size
  ASoC: SSM2602: remove unsupported sample rates
  ASoC: TWL4030: Check the interface format for 4 channel mode
  ASoC: TWL4030: Use reg_cache in twl4030_init_chip
  ASoC: Initialise dev for the dummy S/PDIF DAI
  ASoC: Add dummy S/PDIF codec support
  ASoC: correct print specifiers for unsigneds
  ASoC: Modify mpc5200 AC97 driver to use V9 of spin_event_timeout()
  ASoC: Switch FSL SSI DAI over to symmetric_rates
  ASoC: Mark MPC5200 AC97 as BROKEN until PowerPC merge issues are resolved
  ASoC: Fabric bindings for STAC9766 on the Efika
  ASoC: Support for AC97 on Phytec pmc030 base board.
  ASoC: AC97 driver for mpc5200
  ASoC: Main rewite of the mpc5200 audio DMA code
  ...
parents 07a2039b 74b8f955
......@@ -62,6 +62,7 @@ Audio DAPM widgets fall into a number of types:-
o Mic - Mic (and optional Jack)
o Line - Line Input/Output (and optional Jack)
o Speaker - Speaker
o Supply - Power or clock supply widget used by other widgets.
o Pre - Special PRE widget (exec before all others)
o Post - Special POST widget (exec after all others)
......
......@@ -4574,7 +4574,8 @@ F: drivers/pcmcia/pxa2xx*
F: drivers/spi/pxa2xx*
F: drivers/usb/gadget/pxa2*
F: include/sound/pxa2xx-lib.h
F: sound/soc/pxa/pxa2xx*
F: sound/arm/pxa*
F: sound/soc/pxa
PXA168 SUPPORT
P: Eric Miao
......@@ -5302,11 +5303,12 @@ P: Liam Girdwood
M: lrg@slimlogic.co.uk
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc
T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
L: alsa-devel@alsa-project.org (subscribers-only)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
F: sound/soc/
F: include/sound/soc*
SPARC + UltraSPARC (sparc/sparc64)
P: David S. Miller
......
......@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
#define MPC52xx_PSC_SR_UNEX_RX 0x0001
#define MPC52xx_PSC_SR_DATA_VAL 0x0002
#define MPC52xx_PSC_SR_DATA_OVR 0x0004
#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
......@@ -61,6 +65,12 @@
#define MPC52xx_PSC_RXTX_FIFO_EMPTY 0x0001
/* PSC interrupt status/mask bits */
#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001
#define MPC52xx_PSC_IMR_DATA_VALID 0x0002
#define MPC52xx_PSC_IMR_DATA_OVR 0x0004
#define MPC52xx_PSC_IMR_CMD_SEND 0x0008
#define MPC52xx_PSC_IMR_ERROR 0x0040
#define MPC52xx_PSC_IMR_DEOF 0x0080
#define MPC52xx_PSC_IMR_TXRDY 0x0100
#define MPC52xx_PSC_IMR_RXRDY 0x0200
#define MPC52xx_PSC_IMR_DB 0x0400
......@@ -117,6 +127,7 @@
#define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24)
#define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24)
#define MPC52xx_PSC_SICR_AWR (1 << 30)
#define MPC52xx_PSC_SICR_GENCLK (1 << 23)
#define MPC52xx_PSC_SICR_I2S (1 << 22)
#define MPC52xx_PSC_SICR_CLKPOL (1 << 21)
......
......@@ -44,24 +44,6 @@ struct snd_pcm_substream;
#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
/*
* DAI Left/Right Clocks.
*
* Specifies whether the DAI can support different samples for similtanious
* playback and capture. This usually requires a seperate physical frame
* clock for playback and capture.
*/
#define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */
#define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */
/*
* TDM
*
* Time Division Multiplexing. Allows PCM data to be multplexed with other
* data on the DAI.
*/
#define SND_SOC_DAIFMT_TDM (1 << 6)
/*
* DAI hardware signal inversions.
*
......@@ -96,6 +78,10 @@ struct snd_pcm_substream;
#define SND_SOC_CLOCK_IN 0
#define SND_SOC_CLOCK_OUT 1
#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE |\
SNDRV_PCM_FMTBIT_S32_BE)
struct snd_soc_dai_ops;
struct snd_soc_dai;
struct snd_ac97_bus_ops;
......@@ -208,6 +194,7 @@ struct snd_soc_dai {
/* DAI capabilities */
struct snd_soc_pcm_stream capture;
struct snd_soc_pcm_stream playback;
unsigned int symmetric_rates:1;
/* DAI runtime info */
struct snd_pcm_runtime *runtime;
......@@ -219,11 +206,8 @@ struct snd_soc_dai {
/* DAI private data */
void *private_data;
/* parent codec/platform */
union {
struct snd_soc_codec *codec;
/* parent platform */
struct snd_soc_platform *platform;
};
struct list_head list;
};
......
......@@ -140,16 +140,30 @@
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags}
#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert}
#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
.shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags}
/* generic register modifier widget */
/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \
.event_flags = wflags}
/* dapm kcontrol types */
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
......@@ -265,8 +279,6 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
/* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
int event);
int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
enum snd_soc_bias_level level);
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
......@@ -298,6 +310,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */
snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */
snd_soc_dapm_supply, /* power/clock supply */
};
/*
......@@ -357,6 +370,8 @@ struct snd_soc_dapm_widget {
unsigned char suspend:1; /* was active before suspend */
unsigned char pmdown:1; /* waiting for timeout */
int (*power_check)(struct snd_soc_dapm_widget *w);
/* external events */
unsigned short event_flags; /* flags to specify event types */
int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
......@@ -368,6 +383,9 @@ struct snd_soc_dapm_widget {
/* widget input and outputs */
struct list_head sources;
struct list_head sinks;
/* used during DAPM updates */
struct list_head power_list;
};
#endif
......@@ -118,6 +118,14 @@
.info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\
xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
.info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = (unsigned long)&(struct soc_mixer_control) \
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
.max = xmax, .invert = xinvert} }
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
xhandler_get, xhandler_put, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
......@@ -206,10 +214,6 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios);
#endif
/* codec IO */
#define snd_soc_read(codec, reg) codec->read(codec, reg)
#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value)
/* codec register bit access */
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
unsigned short mask, unsigned short value);
......@@ -331,6 +335,7 @@ struct snd_soc_codec {
struct module *owner;
struct mutex mutex;
struct device *dev;
struct snd_soc_device *socdev;
struct list_head list;
......@@ -364,6 +369,8 @@ struct snd_soc_codec {
enum snd_soc_bias_level bias_level;
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
struct list_head up_list;
struct list_head down_list;
/* codec DAI's */
struct snd_soc_dai *dai;
......@@ -417,6 +424,12 @@ struct snd_soc_dai_link {
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_codec *codec);
/* Symmetry requirements */
unsigned int symmetric_rates:1;
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate;
/* DAI pcm */
struct snd_pcm *pcm;
};
......@@ -490,6 +503,19 @@ struct soc_enum {
void *dapm;
};
/* codec IO */
static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
return codec->read(codec, reg);
}
static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int val)
{
return codec->write(codec, reg, val);
}
#include <sound/soc-dai.h>
#endif
/*
* linux/sound/wm9081.h -- Platform data for WM9081
*
* Copyright 2009 Wolfson Microelectronics. PLC.
*
* 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.
*/
#ifndef __LINUX_SND_WM_9081_H
#define __LINUX_SND_WM_9081_H
struct wm9081_retune_mobile_setting {
const char *name;
unsigned int rate;
u16 config[20];
};
struct wm9081_retune_mobile_config {
struct wm9081_retune_mobile_setting *configs;
int num_configs;
};
#endif
......@@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
}
ldev->selfptr_headphone.ptr = ldev;
ldev->selfptr_lineout.ptr = ldev;
sdev->ofdev.dev.driver_data = ldev;
dev_set_drvdata(&sdev->ofdev.dev, ldev);
list_add(&ldev->list, &layouts_list);
layouts_list_items++;
......@@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
int i;
for (i=0; i<MAX_CODECS_PER_BUS; i++) {
......@@ -1114,7 +1114,7 @@ static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
#ifdef CONFIG_PM
static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_off(&ldev->gpio);
......@@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta
static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
{
struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev);
if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
ldev->gpio.methods->all_amps_restore(&ldev->gpio);
......
......@@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
return -ENODEV;
}
dev->ofdev.dev.driver_data = control;
dev_set_drvdata(&dev->ofdev.dev, control);
return 0;
}
static int i2sbus_remove(struct macio_dev* dev)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct i2sbus_dev *i2sdev, *tmp;
list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
......@@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev)
#ifdef CONFIG_PM
static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
......@@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
static int i2sbus_resume(struct macio_dev* dev)
{
struct i2sbus_control *control = dev->ofdev.dev.driver_data;
struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev);
struct codec_info_item *cii;
struct i2sbus_dev* i2sdev;
int err, ret = 0;
......
......@@ -32,7 +32,9 @@ source "sound/soc/fsl/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/pxa/Kconfig"
source "sound/soc/s3c24xx/Kconfig"
source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/txx9/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
......
......@@ -10,4 +10,6 @@ obj-$(CONFIG_SND_SOC) += fsl/
obj-$(CONFIG_SND_SOC) += omap/
obj-$(CONFIG_SND_SOC) += pxa/
obj-$(CONFIG_SND_SOC) += s3c24xx/
obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += txx9/
......@@ -41,3 +41,11 @@ config SND_AT32_SOC_PLAYPAQ_SLAVE
and FRAME signals on the PlayPaq. Unless you want to play
with the AT32 as the SSC master, you probably want to say N here,
as this will give you better sound quality.
config SND_AT91_SOC_AFEB9260
tristate "SoC Audio support for AFEB9260 board"
depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
select SND_ATMEL_SOC_SSC
select SND_SOC_TLV320AIC23
help
Say Y here to support sound on AFEB9260 board.
......@@ -13,3 +13,4 @@ snd-soc-playpaq-objs := playpaq_wm8510.o
obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
......@@ -117,7 +117,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
* Find actual rate, compare to requested rate
*/
actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1));
pr_debug("playpaq_wm8510: Request rate = %d, actual rate = %d\n",
pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n",
rate, actual_rate);
......
/*
* afeb9260.c -- SoC audio for AFEB9260
*
* Copyright (C) 2009 Sergey Lapin <slapin@ossfans.org>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/atmel-ssc.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <linux/gpio.h>
#include "../codecs/tlv320aic23.h"
#include "atmel-pcm.h"
#include "atmel_ssc_dai.h"
#define CODEC_CLOCK 12000000
static int afeb9260_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 *codec_dai = rtd->dai->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int err;
/* Set codec DAI configuration */
err = snd_soc_dai_set_fmt(codec_dai,
SND_SOC_DAIFMT_I2S|
SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set codec DAI configuration\n");
return err;
}
/* Set cpu DAI configuration */
err = snd_soc_dai_set_fmt(cpu_dai,
SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_IF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set cpu DAI configuration\n");
return err;
}
/* Set the codec system clock for DAC and ADC */
err =
snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
if (err < 0) {
printk(KERN_ERR "can't set codec system clock\n");
return err;
}
return err;
}
static struct snd_soc_ops afeb9260_ops = {
.hw_params = afeb9260_hw_params,
};
static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_LINE("Line In", NULL),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
};
static const struct snd_soc_dapm_route audio_map[] = {
{"Headphone Jack", NULL, "LHPOUT"},
{"Headphone Jack", NULL, "RHPOUT"},
{"LLINEIN", NULL, "Line In"},
{"RLINEIN", NULL, "Line In"},
{"MICIN", NULL, "Mic Jack"},
};
static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
{
/* Add afeb9260 specific widgets */
snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
ARRAY_SIZE(tlv320aic23_dapm_widgets));
/* Set up afeb9260 specific audio path audio_map */
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
snd_soc_dapm_enable_pin(codec, "Headphone Jack");
snd_soc_dapm_enable_pin(codec, "Line In");
snd_soc_dapm_enable_pin(codec, "Mic Jack");
snd_soc_dapm_sync(codec);
return 0;
}
/* Digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link afeb9260_dai = {
.name = "TLV320AIC23",
.stream_name = "AIC23",
.cpu_dai = &atmel_ssc_dai[0],
.codec_dai = &tlv320aic23_dai,
.init = afeb9260_tlv320aic23_init,
.ops = &afeb9260_ops,
};
/* Audio machine driver */
static struct snd_soc_card snd_soc_machine_afeb9260 = {
.name = "AFEB9260",
.platform = &atmel_soc_platform,
.dai_link = &afeb9260_dai,
.num_links = 1,
};
/* Audio subsystem */
static struct snd_soc_device afeb9260_snd_devdata = {
.card = &snd_soc_machine_afeb9260,
.codec_dev = &soc_codec_dev_tlv320aic23,
};
static struct platform_device *afeb9260_snd_device;
static int __init afeb9260_soc_init(void)
{
int err;
struct device *dev;
struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data;
struct ssc_device *ssc = NULL;
if (!(machine_is_afeb9260()))
return -ENODEV;
ssc = ssc_request(0);
if (IS_ERR(ssc)) {
printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
err = PTR_ERR(ssc);
ssc = NULL;
goto err_ssc;
}
ssc_p->ssc = ssc;
afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
if (!afeb9260_snd_device) {
printk(KERN_ERR "ASoC: Platform device allocation failed\n");
return -ENOMEM;
}
platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata);
afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev;
err = platform_device_add(afeb9260_snd_device);
if (err)
goto err1;
dev = &afeb9260_snd_device->dev;
return 0;
err1:
platform_device_del(afeb9260_snd_device);
platform_device_put(afeb9260_snd_device);
err_ssc:
return err;
}
static void __exit afeb9260_soc_exit(void)
{
platform_device_unregister(afeb9260_snd_device);
}
module_init(afeb9260_soc_init);
module_exit(afeb9260_soc_exit);
MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
MODULE_DESCRIPTION("ALSA SoC for AFEB9260");
MODULE_LICENSE("GPL");
......@@ -31,6 +31,15 @@
#include "bf5xx-sport.h"
#include "bf5xx-ac97.h"
/* Anomaly notes:
* 05000250 - AD1980 is running in TDM mode and RFS/TFS are generated by SPORT
* contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1,
* while the max AC97 data size is 13*16. The DIV is always larger
* than data size. AD73311 and ad2602 are not running in TDM mode.
* AD1836 and AD73322 depend on external RFS/TFS only. So, this
* anomaly does not affect blackfin sound drivers.
*/
static int *cmd_count;
static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
......
......@@ -190,7 +190,7 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport)
desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
/* Copy the descriptor which will be damaged to backup */
temp_desc = *desc;
desc->x_count = 0xa;
desc->x_count = sport->dummy_count / 2;
desc->y_count = 0;
desc->next_desc_addr = sport->dummy_rx_desc;
local_irq_restore(flags);
......@@ -309,7 +309,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport)
desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
/* Store the descriptor which will be damaged */
temp_desc = *desc;
desc->x_count = 0xa;
desc->x_count = sport->dummy_count / 2;
desc->y_count = 0;
desc->next_desc_addr = sport->dummy_tx_desc;
local_irq_restore(flags);
......
......@@ -18,7 +18,9 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4535 if I2C
select SND_SOC_CS4270 if I2C
select SND_SOC_PCM3008
select SND_SOC_SPDIF
select SND_SOC_SSM2602 if I2C
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
select SND_SOC_TLV320AIC23 if I2C
select SND_SOC_TLV320AIC26 if SPI_MASTER
select SND_SOC_TLV320AIC3X if I2C
......@@ -35,8 +37,12 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
select SND_SOC_WM8903 if I2C
select SND_SOC_WM8940 if I2C
select SND_SOC_WM8960 if I2C
select SND_SOC_WM8971 if I2C
select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8990 if I2C
select SND_SOC_WM9081 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
select SND_SOC_WM9713 if SND_SOC_AC97_BUS
......@@ -86,9 +92,15 @@ config SND_SOC_L3
config SND_SOC_PCM3008
tristate
config SND_SOC_SPDIF
tristate
config SND_SOC_SSM2602
tristate
config SND_SOC_STAC9766
tristate
config SND_SOC_TLV320AIC23
tristate
......@@ -138,12 +150,24 @@ config SND_SOC_WM8900
config SND_SOC_WM8903
tristate
config SND_SOC_WM8940
tristate
config SND_SOC_WM8960
tristate
config SND_SOC_WM8971
tristate
config SND_SOC_WM8988
tristate
config SND_SOC_WM8990
tristate
config SND_SOC_WM9081
tristate
config SND_SOC_WM9705
tristate
......
......@@ -6,7 +6,9 @@ snd-soc-ak4535-objs := ak4535.o
snd-soc-cs4270-objs := cs4270.o
snd-soc-l3-objs := l3.o
snd-soc-pcm3008-objs := pcm3008.o
snd-soc-spdif-objs := spdif_transciever.o
snd-soc-ssm2602-objs := ssm2602.o
snd-soc-stac9766-objs := stac9766.o
snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
......@@ -23,8 +25,12 @@ snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
snd-soc-wm8900-objs := wm8900.o
snd-soc-wm8903-objs := wm8903.o
snd-soc-wm8940-objs := wm8940.o
snd-soc-wm8960-objs := wm8960.o
snd-soc-wm8971-objs := wm8971.o
snd-soc-wm8988-objs := wm8988.o
snd-soc-wm8990-objs := wm8990.o
snd-soc-wm9081-objs := wm9081.o
snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
......@@ -37,7 +43,9 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.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
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
......@@ -55,7 +63,11 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
......@@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = {
.channels_min = 1,
.channels_max = 2,
.rates = STD_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "AC97 Capture",
.channels_min = 1,
.channels_max = 2,
.rates = STD_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &ac97_dai_ops,
};
EXPORT_SYMBOL_GPL(ac97_dai);
......
......@@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = {
.channels_min = 2,
.channels_max = 6,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
.formats = SND_SOC_STD_AC97_FMTS, },
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
.formats = SND_SOC_STD_AC97_FMTS, },
};
EXPORT_SYMBOL_GPL(ad1980_dai);
......
......@@ -18,7 +18,7 @@
* - The machine driver's 'startup' function must call
* cs4270_set_dai_sysclk() with the value of MCLK.
* - Only I2S and left-justified modes are supported
* - Power management is not supported
* - Power management is supported
*/
#include <linux/module.h>
......@@ -27,6 +27,7 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include "cs4270.h"
......@@ -56,6 +57,7 @@
#define CS4270_FIRSTREG 0x01
#define CS4270_LASTREG 0x08
#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
#define CS4270_I2C_INCR 0x80
/* Bit masks for the CS4270 registers */
#define CS4270_CHIPID_ID 0xF0
......@@ -64,6 +66,8 @@
#define CS4270_PWRCTL_PDN_ADC 0x20
#define CS4270_PWRCTL_PDN_DAC 0x02
#define CS4270_PWRCTL_PDN 0x01
#define CS4270_PWRCTL_PDN_ALL \
(CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
#define CS4270_MODE_SPEED_MASK 0x30
#define CS4270_MODE_1X 0x00
#define CS4270_MODE_2X 0x10
......@@ -109,6 +113,7 @@ struct cs4270_private {
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
unsigned int slave_mode;
unsigned int manual_mute;
};
/**
......@@ -295,7 +300,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
s32 length;
length = i2c_smbus_read_i2c_block_data(i2c_client,
CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
if (length != CS4270_NUMREGS) {
dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
......@@ -453,7 +458,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
}
/**
* cs4270_mute - enable/disable the CS4270 external mute
* cs4270_dai_mute - enable/disable the CS4270 external mute
* @dai: the SOC DAI
* @mute: 0 = disable mute, 1 = enable mute
*
......@@ -462,21 +467,52 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
* board does not have the MUTEA or MUTEB pins connected to such circuitry,
* then this function will do nothing.
*/
static int cs4270_mute(struct snd_soc_dai *dai, int mute)
static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
struct cs4270_private *cs4270 = codec->private_data;
int reg6;
reg6 = snd_soc_read(codec, CS4270_MUTE);
if (mute)
reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
else
else {
reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
reg6 |= cs4270->manual_mute;
}
return snd_soc_write(codec, CS4270_MUTE, reg6);
}
/**
* cs4270_soc_put_mute - put callback for the 'Master Playback switch'
* alsa control.
* @kcontrol: mixer control
* @ucontrol: control element information
*
* This function basically passes the arguments on to the generic
* snd_soc_put_volsw() function and saves the mute information in
* our private data structure. This is because we want to prevent
* cs4270_dai_mute() neglecting the user's decision to manually
* mute the codec's output.
*
* Returns 0 for success.
*/
static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct cs4270_private *cs4270 = codec->private_data;
int left = !ucontrol->value.integer.value[0];
int right = !ucontrol->value.integer.value[1];
cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
(right ? CS4270_MUTE_DAC_B : 0);
return snd_soc_put_volsw(kcontrol, ucontrol);
}
/* A list of non-DAPM controls that the CS4270 supports */
static const struct snd_kcontrol_new cs4270_snd_controls[] = {
SOC_DOUBLE_R("Master Playback Volume",
......@@ -486,7 +522,9 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0)
SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
snd_soc_get_volsw, cs4270_soc_put_mute),
};
/*
......@@ -506,7 +544,7 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
.hw_params = cs4270_hw_params,
.set_sysclk = cs4270_set_dai_sysclk,
.set_fmt = cs4270_set_dai_fmt,
.digital_mute = cs4270_mute,
.digital_mute = cs4270_dai_mute,
};
struct snd_soc_dai cs4270_dai = {
......@@ -753,6 +791,57 @@ static struct i2c_device_id cs4270_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs4270_id);
#ifdef CONFIG_PM
/* This suspend/resume implementation can handle both - a simple standby
* where the codec remains powered, and a full suspend, where the voltage
* domain the codec is connected to is teared down and/or any other hardware
* reset condition is asserted.
*
* The codec's own power saving features are enabled in the suspend callback,
* and all registers are written back to the hardware when resuming.
*/
static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(client);
struct snd_soc_codec *codec = &cs4270->codec;
int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
return snd_soc_write(codec, CS4270_PWRCTL, reg);
}
static int cs4270_i2c_resume(struct i2c_client *client)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(client);
struct snd_soc_codec *codec = &cs4270->codec;
int reg;
/* In case the device was put to hard reset during sleep, we need to
* wait 500ns here before any I2C communication. */
ndelay(500);
/* first restore the entire register cache ... */
for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
u8 val = snd_soc_read(codec, reg);
if (i2c_smbus_write_byte_data(client, reg, val)) {
dev_err(codec->dev, "i2c write failed\n");
return -EIO;
}
}
/* ... then disable the power-down bits */
reg = snd_soc_read(codec, CS4270_PWRCTL);
reg &= ~CS4270_PWRCTL_PDN_ALL;
return snd_soc_write(codec, CS4270_PWRCTL, reg);
}
#else
#define cs4270_i2c_suspend NULL
#define cs4270_i2c_resume NULL
#endif /* CONFIG_PM */
/*
* cs4270_i2c_driver - I2C device identification
*
......@@ -767,6 +856,8 @@ static struct i2c_driver cs4270_i2c_driver = {
.id_table = cs4270_id,
.probe = cs4270_i2c_probe,
.remove = cs4270_i2c_remove,
.suspend = cs4270_i2c_suspend,
.resume = cs4270_i2c_resume,
};
/*
......
/*
* ALSA SoC SPDIF DIT driver
*
* This driver is used by controllers which can operate in DIT (SPDI/F) where
* no codec is needed. This file provides stub codec that can be used
* in these configurations. TI DaVinci Audio controller uses this driver.
*
* Author: Steve Chen, <schen@mvista.com>
* Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
* Copyright: (C) 2009 Texas Instruments, India
*
* 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.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <sound/soc.h>
#include <sound/pcm.h>
#include "spdif_transciever.h"
#define STUB_RATES SNDRV_PCM_RATE_8000_96000
#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
struct snd_soc_dai dit_stub_dai = {
.name = "DIT",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 384,
.rates = STUB_RATES,
.formats = STUB_FORMATS,
},
};
static int spdif_dit_probe(struct platform_device *pdev)
{
dit_stub_dai.dev = &pdev->dev;
return snd_soc_register_dai(&dit_stub_dai);
}
static int spdif_dit_remove(struct platform_device *pdev)
{
snd_soc_unregister_dai(&dit_stub_dai);
return 0;
}
static struct platform_driver spdif_dit_driver = {
.probe = spdif_dit_probe,
.remove = spdif_dit_remove,
.driver = {
.name = "spdif-dit",
.owner = THIS_MODULE,
},
};
static int __init dit_modinit(void)
{
return platform_driver_register(&spdif_dit_driver);
}
static void __exit dit_exit(void)
{
platform_driver_unregister(&spdif_dit_driver);
}
module_init(dit_modinit);
module_exit(dit_exit);
/*
* ALSA SoC DIT/DIR driver header
*
* Author: Steve Chen, <schen@mvista.com>
* Copyright: (C) 2008 MontaVista Software, Inc., <source@mvista.com>
*
* 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.
*/
#ifndef CODEC_STUBS_H
#define CODEC_STUBS_H
extern struct snd_soc_dai dit_stub_dai;
#endif /* CODEC_STUBS_H */
......@@ -336,11 +336,13 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
master_runtime->sample_bits,
master_runtime->rate);
if (master_runtime->rate != 0)
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
master_runtime->rate,
master_runtime->rate);
if (master_runtime->sample_bits != 0)
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
master_runtime->sample_bits,
......@@ -372,6 +374,11 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct ssm2602_priv *ssm2602 = codec->private_data;
if (ssm2602->master_substream == substream)
ssm2602->master_substream = ssm2602->slave_substream;
ssm2602->slave_substream = NULL;
/* deactivate */
if (!codec->active)
ssm2602_write(codec, SSM2602_ACTIVE, 0);
......@@ -497,11 +504,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_96000)
#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
......
This diff is collapsed.
/*
* stac9766.h -- STAC9766 Soc Audio driver
*/
#ifndef _STAC9766_H
#define _STAC9766_H
#define AC97_STAC_PAGE0 0x1000
#define AC97_STAC_DA_CONTROL (AC97_STAC_PAGE0 | 0x6A)
#define AC97_STAC_ANALOG_SPECIAL (AC97_STAC_PAGE0 | 0x6E)
#define AC97_STAC_STEREO_MIC 0x78
/* STAC9766 DAI ID's */
#define STAC9766_DAI_AC97_ANALOG 0
#define STAC9766_DAI_AC97_DIGITAL 1
extern struct snd_soc_dai stac9766_dai[];
extern struct snd_soc_codec_device soc_codec_dev_stac9766;
#endif
......@@ -86,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
*/
if ((reg < 0 || reg > 9) && (reg != 15)) {
printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
return -1;
}
......@@ -98,7 +98,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
if (codec->hw_write(codec->control_data, data, 2) == 2)
return 0;
printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
value, reg);
return -EIO;
......@@ -273,14 +273,14 @@ static const unsigned short sr_valid_mask[] = {
* Every divisor is a factor of 11*12
*/
#define SR_MULT (11*12)
#define A(x) (x) ? (SR_MULT/x) : 0
#define A(x) (SR_MULT/x)
static const unsigned char sr_adc_mult_table[] = {
A(2), A(2), A(12), A(12), A(0), A(0), A(3), A(1),
A(2), A(2), A(11), A(11), A(0), A(0), A(0), A(1)
A(2), A(2), A(12), A(12), 0, 0, A(3), A(1),
A(2), A(2), A(11), A(11), 0, 0, 0, A(1)
};
static const unsigned char sr_dac_mult_table[] = {
A(2), A(12), A(2), A(12), A(0), A(0), A(3), A(1),
A(2), A(11), A(2), A(11), A(0), A(0), A(0), A(1)
A(2), A(12), A(2), A(12), 0, 0, A(3), A(1),
A(2), A(11), A(2), A(11), 0, 0, 0, A(1)
};
static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
......@@ -523,6 +523,8 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_I2S:
iface_reg |= TLV320AIC23_FOR_I2S;
break;
case SND_SOC_DAIFMT_DSP_A:
iface_reg |= TLV320AIC23_LRP_ON;
case SND_SOC_DAIFMT_DSP_B:
iface_reg |= TLV320AIC23_FOR_DSP;
break;
......
This diff is collapsed.
......@@ -92,8 +92,9 @@
#define TWL4030_REG_VIBRA_PWM_SET 0x47
#define TWL4030_REG_ANAMIC_GAIN 0x48
#define TWL4030_REG_MISC_SET_2 0x49
#define TWL4030_REG_SW_SHADOW 0x4A
#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
/* Bitfield Definitions */
......@@ -110,9 +111,22 @@
#define TWL4030_APLL_RATE_44100 0x90
#define TWL4030_APLL_RATE_48000 0xA0
#define TWL4030_APLL_RATE_96000 0xE0
#define TWL4030_SEL_16K 0x04
#define TWL4030_SEL_16K 0x08
#define TWL4030_CODECPDZ 0x02
#define TWL4030_OPT_MODE 0x01
#define TWL4030_OPTION_1 (1 << 0)
#define TWL4030_OPTION_2 (0 << 0)
/* TWL4030_OPTION (0x02) Fields */
#define TWL4030_ATXL1_EN (1 << 0)
#define TWL4030_ATXR1_EN (1 << 1)
#define TWL4030_ATXL2_VTXL_EN (1 << 2)
#define TWL4030_ATXR2_VTXR_EN (1 << 3)
#define TWL4030_ARXL1_VRX_EN (1 << 4)
#define TWL4030_ARXR1_EN (1 << 5)
#define TWL4030_ARXL2_EN (1 << 6)
#define TWL4030_ARXR2_EN (1 << 7)
/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
......@@ -171,6 +185,17 @@
#define TWL4030_CLK256FS_EN 0x02
#define TWL4030_AIF_EN 0x01
/* VOICE_IF (0x0F) Fields */
#define TWL4030_VIF_SLAVE_EN 0x80
#define TWL4030_VIF_DIN_EN 0x40
#define TWL4030_VIF_DOUT_EN 0x20
#define TWL4030_VIF_SWAP 0x10
#define TWL4030_VIF_FORMAT 0x08
#define TWL4030_VIF_TRI_EN 0x04
#define TWL4030_VIF_SUB_EN 0x02
#define TWL4030_VIF_EN 0x01
/* EAR_CTL (0x21) */
#define TWL4030_EAR_GAIN 0x30
......@@ -236,7 +261,19 @@
#define TWL4030_SMOOTH_ANAVOL_EN 0x02
#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
extern struct snd_soc_dai twl4030_dai;
/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
#define TWL4030_HFL_EN 0x01
#define TWL4030_HFR_EN 0x02
#define TWL4030_DAI_HIFI 0
#define TWL4030_DAI_VOICE 1
extern struct snd_soc_dai twl4030_dai[2];
extern struct snd_soc_codec_device soc_codec_dev_twl4030;
struct twl4030_setup_data {
unsigned int ramp_delay_value;
unsigned int sysclk;
};
#endif /* End of __TWL4030_AUDIO_H__ */
......@@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
if (reg >= UDA134X_REGS_NUM) {
printk(KERN_ERR "%s unkown register: reg: %d",
printk(KERN_ERR "%s unkown register: reg: %u",
__func__, reg);
return -EINVAL;
}
......@@ -296,7 +296,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
struct uda134x_priv *uda134x = codec->private_data;
pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
clk_id, freq, dir);
/* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
......
......@@ -1108,7 +1108,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
if (ret < 0)
return ret;
dev_dbg(wm8350->dev,
"FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
"FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
fll_div.ratio);
......
......@@ -13,6 +13,7 @@
#define _WM8350_H
#include <sound/soc.h>
#include <linux/mfd/wm8350/audio.h>
extern struct snd_soc_dai wm8350_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8350;
......
......@@ -954,7 +954,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
factors->outdiv *= 2;
if (factors->outdiv > 32) {
dev_err(wm8400->wm8400->dev,
"Unsupported FLL output frequency %dHz\n",
"Unsupported FLL output frequency %uHz\n",
Fout);
return -EINVAL;
}
......@@ -1003,7 +1003,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
factors->k = K / 10;
dev_dbg(wm8400->wm8400->dev,
"FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
"FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
Fref, Fout,
factors->n, factors->k, factors->fratio, factors->outdiv);
......@@ -1473,8 +1473,8 @@ static int wm8400_codec_probe(struct platform_device *dev)
codec = &priv->codec;
codec->private_data = priv;
codec->control_data = dev->dev.driver_data;
priv->wm8400 = dev->dev.driver_data;
codec->control_data = dev_get_drvdata(&dev->dev);
priv->wm8400 = dev_get_drvdata(&dev->dev);
ret = regulator_bulk_get(priv->wm8400->dev,
ARRAY_SIZE(power), &power[0]);
......
......@@ -298,7 +298,7 @@ static void pll_factors(unsigned int target, unsigned int source)
if ((Ndiv < 6) || (Ndiv > 12))
printk(KERN_WARNING
"WM8510 N value %d outwith recommended range!d\n",
"WM8510 N value %u outwith recommended range!d\n",
Ndiv);
pll_div.n = Ndiv;
......
......@@ -415,7 +415,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
unsigned int K, Ndiv, Nmod;
int i;
pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
pr_debug("wm8580: PLL %uHz->%uHz\n", source, target);
/* Scale the output frequency up; the PLL should run in the
* region of 90-100MHz.
......@@ -447,7 +447,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
if ((Ndiv < 5) || (Ndiv > 13)) {
printk(KERN_ERR
"WM8580 N=%d outside supported range\n", Ndiv);
"WM8580 N=%u outside supported range\n", Ndiv);
return -EINVAL;
}
......
......@@ -666,14 +666,14 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
codec->hw_write = (hw_write_t)wm8731_spi_write;
codec->dev = &spi->dev;
spi->dev.driver_data = wm8731;
dev_set_drvdata(&spi->dev, wm8731);
return wm8731_register(wm8731);
}
static int __devexit wm8731_spi_remove(struct spi_device *spi)
{
struct wm8731_priv *wm8731 = spi->dev.driver_data;
struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev);
wm8731_unregister(wm8731);
......
......@@ -703,7 +703,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
if ((Ndiv < 6) || (Ndiv > 12))
printk(KERN_WARNING
"wm8753: unsupported N = %d\n", Ndiv);
"wm8753: unsupported N = %u\n", Ndiv);
pll_div->n = Ndiv;
Nmod = target % source;
......@@ -1822,14 +1822,14 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
codec->hw_write = (hw_write_t)wm8753_spi_write;
codec->dev = &spi->dev;
spi->dev.driver_data = wm8753;
dev_set_drvdata(&spi->dev, wm8753);
return wm8753_register(wm8753);
}
static int __devexit wm8753_spi_remove(struct spi_device *spi)
{
struct wm8753_priv *wm8753 = spi->dev.driver_data;
struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev);
wm8753_unregister(wm8753);
return 0;
}
......
......@@ -778,11 +778,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
}
if (target > 100000000)
printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d"
" Fout=%d\n", target, Fref, Fout);
printk(KERN_WARNING "wm8900: FLL rate %u out of range, Fref=%u"
" Fout=%u\n", target, Fref, Fout);
if (div > 32) {
printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
"Fref=%d, Fout=%d, target=%d\n",
"Fref=%u, Fout=%u, target=%u\n",
div, Fref, Fout, target);
return -EINVAL;
}
......
......@@ -217,7 +217,6 @@ struct wm8903_priv {
int sysclk;
/* Reference counts */
int charge_pump_users;
int class_w_users;
int playback_active;
int capture_active;
......@@ -373,6 +372,15 @@ static void wm8903_reset(struct snd_soc_codec *codec)
#define WM8903_OUTPUT_INT 0x2
#define WM8903_OUTPUT_IN 0x1
static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
WARN_ON(event != SND_SOC_DAPM_POST_PMU);
mdelay(4);
return 0;
}
/*
* Event for headphone and line out amplifier power changes. Special
* power up/down sequences are required in order to maximise pop/click
......@@ -382,19 +390,20 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct wm8903_priv *wm8903 = codec->private_data;
struct i2c_client *i2c = codec->control_data;
u16 val;
u16 reg;
u16 dcs_reg;
u16 dcs_bit;
int shift;
u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
switch (w->reg) {
case WM8903_POWER_MANAGEMENT_2:
reg = WM8903_ANALOGUE_HP_0;
dcs_bit = 0 + w->shift;
break;
case WM8903_POWER_MANAGEMENT_3:
reg = WM8903_ANALOGUE_LINEOUT_0;
dcs_bit = 2 + w->shift;
break;
default:
BUG();
......@@ -419,18 +428,6 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
/* Short the output */
val &= ~(WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
wm8903->charge_pump_users++;
dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
wm8903->charge_pump_users);
if (wm8903->charge_pump_users == 1) {
dev_dbg(&i2c->dev, "Enabling charge pump\n");
wm8903_write(codec, WM8903_CHARGE_PUMP_0,
cp_reg | WM8903_CP_ENA);
mdelay(4);
}
}
if (event & SND_SOC_DAPM_POST_PMU) {
......@@ -446,6 +443,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
val |= (WM8903_OUTPUT_OUT << shift);
wm8903_write(codec, reg, val);
/* Enable the DC servo */
dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
dcs_reg |= dcs_bit;
wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
/* Remove the short */
val |= (WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
......@@ -458,25 +460,17 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
val &= ~(WM8903_OUTPUT_SHORT << shift);
wm8903_write(codec, reg, val);
/* Disable the DC servo */
dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
dcs_reg &= ~dcs_bit;
wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
/* Then disable the intermediate and output stages */
val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
WM8903_OUTPUT_IN) << shift);
wm8903_write(codec, reg, val);
}
if (event & SND_SOC_DAPM_POST_PMD) {
wm8903->charge_pump_users--;
dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
wm8903->charge_pump_users);
if (wm8903->charge_pump_users == 0) {
dev_dbg(&i2c->dev, "Disabling charge pump\n");
wm8903_write(codec, WM8903_CHARGE_PUMP_0,
cp_reg & ~WM8903_CP_ENA);
}
}
return 0;
}
......@@ -539,6 +533,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
/* ALSA can only do steps of .01dB */
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0);
static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
......@@ -657,6 +652,16 @@ static const struct soc_enum rinput_inv_enum =
SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
static const char *sidetone_text[] = {
"None", "Left", "Right"
};
static const struct soc_enum lsidetone_enum =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text);
static const struct soc_enum rsidetone_enum =
SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
static const struct snd_kcontrol_new wm8903_snd_controls[] = {
/* Input PGAs - No TLV since the scale depends on PGA mode */
......@@ -700,6 +705,9 @@ SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
SOC_ENUM("ADC Companding Mode", adc_companding),
SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
12, 0, digital_sidetone_tlv),
/* DAC */
SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
......@@ -762,6 +770,12 @@ static const struct snd_kcontrol_new rinput_mux =
static const struct snd_kcontrol_new rinput_inv_mux =
SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
static const struct snd_kcontrol_new lsidetone_mux =
SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum);
static const struct snd_kcontrol_new rsidetone_mux =
SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
static const struct snd_kcontrol_new left_output_mixer[] = {
SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
......@@ -828,6 +842,9 @@ SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
......@@ -844,26 +861,29 @@ SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
1, 0, NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
0, 0, NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
NULL, 0, wm8903_output_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
NULL, 0),
SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
};
static const struct snd_soc_dapm_route intercon[] = {
......@@ -909,7 +929,19 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "Right Input PGA", NULL, "Right Input Mode Mux" },
{ "ADCL", NULL, "Left Input PGA" },
{ "ADCL", NULL, "CLK_DSP" },
{ "ADCR", NULL, "Right Input PGA" },
{ "ADCR", NULL, "CLK_DSP" },
{ "DACL Sidetone", "Left", "ADCL" },
{ "DACL Sidetone", "Right", "ADCR" },
{ "DACR Sidetone", "Left", "ADCL" },
{ "DACR Sidetone", "Right", "ADCR" },
{ "DACL", NULL, "DACL Sidetone" },
{ "DACL", NULL, "CLK_DSP" },
{ "DACR", NULL, "DACR Sidetone" },
{ "DACR", NULL, "CLK_DSP" },
{ "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
{ "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
......@@ -951,6 +983,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{ "ROP", NULL, "Right Speaker PGA" },
{ "RON", NULL, "Right Speaker PGA" },
{ "Left Headphone Output PGA", NULL, "Charge Pump" },
{ "Right Headphone Output PGA", NULL, "Charge Pump" },
{ "Left Line Output PGA", NULL, "Charge Pump" },
{ "Right Line Output PGA", NULL, "Charge Pump" },
};
static int wm8903_add_widgets(struct snd_soc_codec *codec)
......@@ -985,6 +1022,11 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
wm8903_write(codec, WM8903_CLOCK_RATES_2,
WM8903_CLK_SYS_ENA);
/* Change DC servo dither level in startup sequence */
wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11);
wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257);
wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2);
wm8903_run_sequence(codec, 0);
wm8903_sync_reg_cache(codec, codec->reg_cache);
......@@ -1277,14 +1319,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
if (wm8903->master_substream) {
master_runtime = wm8903->master_substream->runtime;
dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
master_runtime->sample_bits,
master_runtime->rate);
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
master_runtime->rate,
master_runtime->rate);
dev_dbg(&i2c->dev, "Constraining to %d bits\n",
master_runtime->sample_bits);
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
......@@ -1523,6 +1559,7 @@ struct snd_soc_dai wm8903_dai = {
.formats = WM8903_FORMATS,
},
.ops = &wm8903_dai_ops,
.symmetric_rates = 1,
};
EXPORT_SYMBOL_GPL(wm8903_dai);
......
This diff is collapsed.
/*
* wm8940.h -- WM8940 Soc Audio driver
*
* 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.
*/
#ifndef _WM8940_H
#define _WM8940_H
struct wm8940_setup_data {
/* Vref to analogue output resistance */
#define WM8940_VROI_1K 0
#define WM8940_VROI_30K 1
unsigned int vroi:1;
};
extern struct snd_soc_dai wm8940_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8940;
/* WM8940 register space */
#define WM8940_SOFTRESET 0x00
#define WM8940_POWER1 0x01
#define WM8940_POWER2 0x02
#define WM8940_POWER3 0x03
#define WM8940_IFACE 0x04
#define WM8940_COMPANDINGCTL 0x05
#define WM8940_CLOCK 0x06
#define WM8940_ADDCNTRL 0x07
#define WM8940_GPIO 0x08
#define WM8940_CTLINT 0x09
#define WM8940_DAC 0x0A
#define WM8940_DACVOL 0x0B
#define WM8940_ADC 0x0E
#define WM8940_ADCVOL 0x0F
#define WM8940_NOTCH1 0x10
#define WM8940_NOTCH2 0x11
#define WM8940_NOTCH3 0x12
#define WM8940_NOTCH4 0x13
#define WM8940_NOTCH5 0x14
#define WM8940_NOTCH6 0x15
#define WM8940_NOTCH7 0x16
#define WM8940_NOTCH8 0x17
#define WM8940_DACLIM1 0x18
#define WM8940_DACLIM2 0x19
#define WM8940_ALC1 0x20
#define WM8940_ALC2 0x21
#define WM8940_ALC3 0x22
#define WM8940_NOISEGATE 0x23
#define WM8940_PLLN 0x24
#define WM8940_PLLK1 0x25
#define WM8940_PLLK2 0x26
#define WM8940_PLLK3 0x27
#define WM8940_ALC4 0x2A
#define WM8940_INPUTCTL 0x2C
#define WM8940_PGAGAIN 0x2D
#define WM8940_ADCBOOST 0x2F
#define WM8940_OUTPUTCTL 0x31
#define WM8940_SPKMIX 0x32
#define WM8940_SPKVOL 0x36
#define WM8940_MONOMIX 0x38
#define WM8940_CACHEREGNUM 0x57
/* Clock divider Id's */
#define WM8940_BCLKDIV 0
#define WM8940_MCLKDIV 1
#define WM8940_OPCLKDIV 2
/* MCLK clock dividers */
#define WM8940_MCLKDIV_1 0
#define WM8940_MCLKDIV_1_5 1
#define WM8940_MCLKDIV_2 2
#define WM8940_MCLKDIV_3 3
#define WM8940_MCLKDIV_4 4
#define WM8940_MCLKDIV_6 5
#define WM8940_MCLKDIV_8 6
#define WM8940_MCLKDIV_12 7
/* BCLK clock dividers */
#define WM8940_BCLKDIV_1 0
#define WM8940_BCLKDIV_2 1
#define WM8940_BCLKDIV_4 2
#define WM8940_BCLKDIV_8 3
#define WM8940_BCLKDIV_16 4
#define WM8940_BCLKDIV_32 5
/* PLL Out Dividers */
#define WM8940_OPCLKDIV_1 0
#define WM8940_OPCLKDIV_2 1
#define WM8940_OPCLKDIV_3 2
#define WM8940_OPCLKDIV_4 3
#endif /* _WM8940_H */
This diff is collapsed.
/*
* wm8960.h -- WM8960 Soc Audio driver
*
* 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.
*/
#ifndef _WM8960_H
#define _WM8960_H
/* WM8960 register space */
#define WM8960_CACHEREGNUM 56
#define WM8960_LINVOL 0x0
#define WM8960_RINVOL 0x1
#define WM8960_LOUT1 0x2
#define WM8960_ROUT1 0x3
#define WM8960_CLOCK1 0x4
#define WM8960_DACCTL1 0x5
#define WM8960_DACCTL2 0x6
#define WM8960_IFACE1 0x7
#define WM8960_CLOCK2 0x8
#define WM8960_IFACE2 0x9
#define WM8960_LDAC 0xa
#define WM8960_RDAC 0xb
#define WM8960_RESET 0xf
#define WM8960_3D 0x10
#define WM8960_ALC1 0x11
#define WM8960_ALC2 0x12
#define WM8960_ALC3 0x13
#define WM8960_NOISEG 0x14
#define WM8960_LADC 0x15
#define WM8960_RADC 0x16
#define WM8960_ADDCTL1 0x17
#define WM8960_ADDCTL2 0x18
#define WM8960_POWER1 0x19
#define WM8960_POWER2 0x1a
#define WM8960_ADDCTL3 0x1b
#define WM8960_APOP1 0x1c
#define WM8960_APOP2 0x1d
#define WM8960_LINPATH 0x20
#define WM8960_RINPATH 0x21
#define WM8960_LOUTMIX 0x22
#define WM8960_ROUTMIX 0x25
#define WM8960_MONOMIX1 0x26
#define WM8960_MONOMIX2 0x27
#define WM8960_LOUT2 0x28
#define WM8960_ROUT2 0x29
#define WM8960_MONO 0x2a
#define WM8960_INBMIX1 0x2b
#define WM8960_INBMIX2 0x2c
#define WM8960_BYPASS1 0x2d
#define WM8960_BYPASS2 0x2e
#define WM8960_POWER3 0x2f
#define WM8960_ADDCTL4 0x30
#define WM8960_CLASSD1 0x31
#define WM8960_CLASSD3 0x33
#define WM8960_PLL1 0x34
#define WM8960_PLL2 0x35
#define WM8960_PLL3 0x36
#define WM8960_PLL4 0x37
/*
* WM8960 Clock dividers
*/
#define WM8960_SYSCLKDIV 0
#define WM8960_DACDIV 1
#define WM8960_OPCLKDIV 2
#define WM8960_DCLKDIV 3
#define WM8960_TOCLKSEL 4
#define WM8960_SYSCLKSEL 5
#define WM8960_SYSCLK_DIV_1 (0 << 1)
#define WM8960_SYSCLK_DIV_2 (2 << 1)
#define WM8960_SYSCLK_MCLK (0 << 0)
#define WM8960_SYSCLK_PLL (1 << 0)
#define WM8960_DAC_DIV_1 (0 << 3)
#define WM8960_DAC_DIV_1_5 (1 << 3)
#define WM8960_DAC_DIV_2 (2 << 3)
#define WM8960_DAC_DIV_3 (3 << 3)
#define WM8960_DAC_DIV_4 (4 << 3)
#define WM8960_DAC_DIV_5_5 (5 << 3)
#define WM8960_DAC_DIV_6 (6 << 3)
#define WM8960_DCLK_DIV_1_5 (0 << 6)
#define WM8960_DCLK_DIV_2 (1 << 6)
#define WM8960_DCLK_DIV_3 (2 << 6)
#define WM8960_DCLK_DIV_4 (3 << 6)
#define WM8960_DCLK_DIV_6 (4 << 6)
#define WM8960_DCLK_DIV_8 (5 << 6)
#define WM8960_DCLK_DIV_12 (6 << 6)
#define WM8960_DCLK_DIV_16 (7 << 6)
#define WM8960_TOCLK_F19 (0 << 1)
#define WM8960_TOCLK_F21 (1 << 1)
#define WM8960_OPCLK_DIV_1 (0 << 0)
#define WM8960_OPCLK_DIV_2 (1 << 0)
#define WM8960_OPCLK_DIV_3 (2 << 0)
#define WM8960_OPCLK_DIV_4 (3 << 0)
#define WM8960_OPCLK_DIV_5_5 (4 << 0)
#define WM8960_OPCLK_DIV_6 (5 << 0)
extern struct snd_soc_dai wm8960_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8960;
#define WM8960_DRES_400R 0
#define WM8960_DRES_200R 1
#define WM8960_DRES_600R 2
#define WM8960_DRES_150R 3
#define WM8960_DRES_MAX 3
struct wm8960_data {
int dres;
};
#endif
This diff is collapsed.
/*
* Copyright 2005 Openedhand Ltd.
*
* Author: Richard Purdie <richard@openedhand.com>
*
* Based on WM8753.h
*
* 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.
*
*/
#ifndef _WM8988_H
#define _WM8988_H
/* WM8988 register space */
#define WM8988_LINVOL 0x00
#define WM8988_RINVOL 0x01
#define WM8988_LOUT1V 0x02
#define WM8988_ROUT1V 0x03
#define WM8988_ADCDAC 0x05
#define WM8988_IFACE 0x07
#define WM8988_SRATE 0x08
#define WM8988_LDAC 0x0a
#define WM8988_RDAC 0x0b
#define WM8988_BASS 0x0c
#define WM8988_TREBLE 0x0d
#define WM8988_RESET 0x0f
#define WM8988_3D 0x10
#define WM8988_ALC1 0x11
#define WM8988_ALC2 0x12
#define WM8988_ALC3 0x13
#define WM8988_NGATE 0x14
#define WM8988_LADC 0x15
#define WM8988_RADC 0x16
#define WM8988_ADCTL1 0x17
#define WM8988_ADCTL2 0x18
#define WM8988_PWR1 0x19
#define WM8988_PWR2 0x1a
#define WM8988_ADCTL3 0x1b
#define WM8988_ADCIN 0x1f
#define WM8988_LADCIN 0x20
#define WM8988_RADCIN 0x21
#define WM8988_LOUTM1 0x22
#define WM8988_LOUTM2 0x23
#define WM8988_ROUTM1 0x24
#define WM8988_ROUTM2 0x25
#define WM8988_LOUT2V 0x28
#define WM8988_ROUT2V 0x29
#define WM8988_LPPB 0x43
#define WM8988_NUM_REG 0x44
#define WM8988_SYSCLK 0
extern struct snd_soc_dai wm8988_dai;
extern struct snd_soc_codec_device soc_codec_dev_wm8988;
#endif
......@@ -998,7 +998,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
if ((Ndiv < 6) || (Ndiv > 12))
printk(KERN_WARNING
"WM8990 N value outwith recommended range! N = %d\n", Ndiv);
"WM8990 N value outwith recommended range! N = %u\n", Ndiv);
pll_div->n = Ndiv;
Nmod = target % source;
......
This diff is collapsed.
This diff is collapsed.
......@@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9705_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.formats = SND_SOC_STD_AC97_FMTS,
},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9705_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.formats = SND_SOC_STD_AC97_FMTS,
},
.ops = &wm9705_dai_ops,
},
......
......@@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9712_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9712_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9712_dai_ops_hifi,
},
{
......@@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = {
.channels_min = 1,
.channels_max = 1,
.rates = WM9712_AC97_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9712_dai_ops_aux,
}
};
......@@ -585,6 +585,8 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
}
soc_ac97_ops.reset(codec->ac97);
if (soc_ac97_ops.warm_reset)
soc_ac97_ops.warm_reset(codec->ac97);
if (ac97_read(codec, 0) != wm9712_reg[0])
goto err;
return 0;
......
......@@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
};
static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
u16 status, rate;
BUG_ON(event != SND_SOC_DAPM_PRE_PMD);
/* Gracefully shut down the voice interface. */
status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000;
rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
schedule_timeout_interruptible(msecs_to_jiffies(1));
ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
ac97_write(codec, AC97_EXTENDED_MID, status);
return 0;
}
/* We have to create a fake left and right HP mixers because
* the codec only has a single control that is shared by both channels.
* This makes it impossible to determine the audio path using the current
......@@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1,
wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
......@@ -689,7 +710,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
Ndiv = target / source;
if ((Ndiv < 5) || (Ndiv > 12))
printk(KERN_WARNING
"WM9713 PLL N value %d out of recommended range!\n",
"WM9713 PLL N value %u out of recommended range!\n",
Ndiv);
pll_div->n = Ndiv;
......@@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
u16 status, rate;
/* Gracefully shut down the voice interface. */
status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
schedule_timeout_interruptible(msecs_to_jiffies(1));
ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
ac97_write(codec, AC97_EXTENDED_MID, status);
}
static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
......@@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
.hw_params = wm9713_pcm_hw_params,
.shutdown = wm9713_voiceshutdown,
.set_clkdiv = wm9713_set_dai_clkdiv,
.set_pll = wm9713_set_dai_pll,
.set_fmt = wm9713_set_dai_fmt,
......@@ -1035,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = {
.channels_min = 1,
.channels_max = 2,
.rates = WM9713_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.capture = {
.stream_name = "HiFi Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM9713_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9713_dai_ops_hifi,
},
{
......@@ -1051,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = {
.channels_min = 1,
.channels_max = 1,
.rates = WM9713_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &wm9713_dai_ops_aux,
},
{
......@@ -1069,6 +1074,7 @@ struct snd_soc_dai wm9713_dai[] = {
.rates = WM9713_PCM_RATES,
.formats = WM9713_PCM_FORMATS,},
.ops = &wm9713_dai_ops_voice,
.symmetric_rates = 1,
},
};
EXPORT_SYMBOL_GPL(wm9713_dai);
......
config SND_SOC_OF_SIMPLE
tristate
config SND_MPC52xx_DMA
tristate
# ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers
# for the SSI and the Elo DMA controller. You will still need to select
# a platform driver and a codec driver.
......@@ -22,7 +25,34 @@ config SND_SOC_MPC8610_HPCD
config SND_SOC_MPC5200_I2S
tristate "Freescale MPC5200 PSC in I2S mode driver"
depends on PPC_MPC52xx && PPC_BESTCOMM
select SND_SOC_OF_SIMPLE
select SND_MPC52xx_DMA
select PPC_BESTCOMM_GEN_BD
help
Say Y here to support the MPC5200 PSCs in I2S mode.
config SND_SOC_MPC5200_AC97
tristate "Freescale MPC5200 PSC in AC97 mode driver"
depends on PPC_MPC52xx && PPC_BESTCOMM
select AC97_BUS
select SND_MPC52xx_DMA
select PPC_BESTCOMM_GEN_BD
help
Say Y here to support the MPC5200 PSCs in AC97 mode.
config SND_MPC52xx_SOC_PCM030
tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712"
depends on PPC_MPC5200_SIMPLE && BROKEN
select SND_SOC_MPC5200_AC97
select SND_SOC_WM9712
help
Say Y if you want to add support for sound on the Phytec pcm030
baseboard.
config SND_MPC52xx_SOC_EFIKA
tristate "SoC AC97 Audio support for bbplan Efika and STAC9766"
depends on PPC_EFIKA && BROKEN
select SND_SOC_MPC5200_AC97
select SND_SOC_STAC9766
help
Say Y if you want to add support for sound on the Efika.
......@@ -10,5 +10,12 @@ snd-soc-fsl-ssi-objs := fsl_ssi.o
snd-soc-fsl-dma-objs := fsl_dma.o
obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o
# MPC5200 Platform Support
obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
# MPC5200 Machine Support
obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
This diff is collapsed.
......@@ -375,18 +375,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *first_runtime =
ssi_private->first_stream->runtime;
if (!first_runtime->rate || !first_runtime->sample_bits) {
if (!first_runtime->sample_bits) {
dev_err(substream->pcm->card->dev,
"set sample rate and size in %s stream first\n",
"set sample size in %s stream first\n",
substream->stream == SNDRV_PCM_STREAM_PLAYBACK
? "capture" : "playback");
return -EAGAIN;
}
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
first_runtime->rate, first_runtime->rate);
/* If we're in synchronous mode, then we need to constrain
* the sample size as well. We don't support independent sample
* rates in asynchronous mode.
......@@ -674,7 +670,7 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
ssi_private->dev = ssi_info->dev;
ssi_private->asynchronous = ssi_info->asynchronous;
ssi_private->dev->driver_data = fsl_ssi_dai;
dev_set_drvdata(ssi_private->dev, fsl_ssi_dai);
/* Initialize the the device_attribute structure */
dev_attr->attr.name = "ssi-stats";
......@@ -693,6 +689,7 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
fsl_ssi_dai->name = ssi_private->name;
fsl_ssi_dai->id = ssi_info->id;
fsl_ssi_dai->dev = ssi_info->dev;
fsl_ssi_dai->symmetric_rates = 1;
ret = snd_soc_register_dai(fsl_ssi_dai);
if (ret != 0) {
......
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