提交 f187700c 编写于 作者: T Takashi Iwai

Merge branch 'for-3.1' of...

Merge branch 'for-3.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6 into topic/asoc
......@@ -534,6 +534,7 @@ 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*
......
......@@ -312,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);
......@@ -658,6 +662,10 @@ struct snd_soc_platform_driver {
/* 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 {
......
......@@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701
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
......
......@@ -22,6 +22,7 @@ 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
......@@ -29,3 +30,4 @@ 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
......@@ -138,11 +138,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
pr_debug("%s enter\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
diff = sport_curr_offset_tx(sport);
frames = bytes_to_frames(substream->runtime, diff);
} else {
diff = sport_curr_offset_rx(sport);
frames = bytes_to_frames(substream->runtime, diff);
}
/*
* TX at least can report one frame beyond the end of the
* buffer if we hit the wraparound case - clamp to within the
* buffer as the ALSA APIs require.
*/
if (diff == snd_pcm_lib_buffer_bytes(substream))
diff = 0;
frames = bytes_to_frames(substream->runtime, diff);
return frames;
}
......
/*
* 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
......@@ -137,6 +138,9 @@ config SND_SOC_ADAU1701
select SIGMA
tristate
config SND_SOC_ADAV80X
tristate
config SND_SOC_ADS117X
tristate
......
......@@ -5,6 +5,7 @@ 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
......@@ -99,6 +100,7 @@ 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
......
此差异已折叠。
/*
* 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
......@@ -1713,6 +1713,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
reg);
msleep(5);
}
wm8994->fll[id].in = freq_in;
......
......@@ -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"),
......
......@@ -133,9 +133,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
break;
case 1:
reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
break;
default:
WARN(1, "Unknown DCS readback method\n");
......@@ -149,13 +149,13 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes);
/* HPOUT1L */
offset = reg_l;
/* HPOUT1R */
offset = reg_r;
offset += hubs->dcs_codes;
dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1R */
offset = reg_r;
/* HPOUT1L */
offset = reg_l;
offset += hubs->dcs_codes;
dcs_cfg |= (u8)offset;
......@@ -167,8 +167,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
WM8993_DCS_TRIG_DAC_WR_0 |
WM8993_DCS_TRIG_DAC_WR_1);
} else {
dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
dcs_cfg |= reg_r;
dcs_cfg = reg_r << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
dcs_cfg |= reg_l;
}
/* Save the callibrated offset if we're in class W mode and
......
......@@ -171,6 +171,14 @@ config SND_SOC_SMDK_WM8580_PCM
help
Say Y if you want to add support for SoC audio on the SMDK.
config SND_SOC_SMDK_WM8994_PCM
tristate "SoC PCM Audio support for WM8994 on SMDK"
depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310)
select SND_SOC_WM8994
select SND_SAMSUNG_PCM
help
Say Y if you want to add support for SoC audio on the SMDK
config SND_SOC_SPEYSIDE
tristate "Audio support for Wolfson Speyside"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
......
......@@ -35,6 +35,7 @@ snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
snd-soc-goni-wm8994-objs := goni_wm8994.o
snd-soc-smdk-spdif-objs := smdk_spdif.o
snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
snd-soc-speyside-objs := speyside.o
snd-soc-speyside-wm8962-objs := speyside_wm8962.o
......@@ -55,5 +56,6 @@ obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o
obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
obj-$(CONFIG_SND_SOC_SPEYSIDE_WM8962) += snd-soc-speyside-wm8962.o
/*
* linux/sound/soc/samsung/i2s-regs.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung I2S driver's register header
*
* 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 __SND_SOC_SAMSUNG_I2S_REGS_H
#define __SND_SOC_SAMSUNG_I2S_REGS_H
#define I2SCON 0x0
#define I2SMOD 0x4
#define I2SFIC 0x8
#define I2SPSR 0xc
#define I2STXD 0x10
#define I2SRXD 0x14
#define I2SFICS 0x18
#define I2STXDS 0x1c
#define I2SAHB 0x20
#define I2SSTR0 0x24
#define I2SSIZE 0x28
#define I2STRNCNT 0x2c
#define I2SLVL0ADDR 0x30
#define I2SLVL1ADDR 0x34
#define I2SLVL2ADDR 0x38
#define I2SLVL3ADDR 0x3c
#define CON_RSTCLR (1 << 31)
#define CON_FRXOFSTATUS (1 << 26)
#define CON_FRXORINTEN (1 << 25)
#define CON_FTXSURSTAT (1 << 24)
#define CON_FTXSURINTEN (1 << 23)
#define CON_TXSDMA_PAUSE (1 << 20)
#define CON_TXSDMA_ACTIVE (1 << 18)
#define CON_FTXURSTATUS (1 << 17)
#define CON_FTXURINTEN (1 << 16)
#define CON_TXFIFO2_EMPTY (1 << 15)
#define CON_TXFIFO1_EMPTY (1 << 14)
#define CON_TXFIFO2_FULL (1 << 13)
#define CON_TXFIFO1_FULL (1 << 12)
#define CON_LRINDEX (1 << 11)
#define CON_TXFIFO_EMPTY (1 << 10)
#define CON_RXFIFO_EMPTY (1 << 9)
#define CON_TXFIFO_FULL (1 << 8)
#define CON_RXFIFO_FULL (1 << 7)
#define CON_TXDMA_PAUSE (1 << 6)
#define CON_RXDMA_PAUSE (1 << 5)
#define CON_TXCH_PAUSE (1 << 4)
#define CON_RXCH_PAUSE (1 << 3)
#define CON_TXDMA_ACTIVE (1 << 2)
#define CON_RXDMA_ACTIVE (1 << 1)
#define CON_ACTIVE (1 << 0)
#define MOD_OPCLK_CDCLK_OUT (0 << 30)
#define MOD_OPCLK_CDCLK_IN (1 << 30)
#define MOD_OPCLK_BCLK_OUT (2 << 30)
#define MOD_OPCLK_PCLK (3 << 30)
#define MOD_OPCLK_MASK (3 << 30)
#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
#define MOD_BLCS_SHIFT 26
#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
#define MOD_BLCP_SHIFT 24
#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
#define MOD_C1DD_HHALF (1 << 19)
#define MOD_C1DD_LHALF (1 << 18)
#define MOD_DC2_EN (1 << 17)
#define MOD_DC1_EN (1 << 16)
#define MOD_BLC_16BIT (0 << 13)
#define MOD_BLC_8BIT (1 << 13)
#define MOD_BLC_24BIT (2 << 13)
#define MOD_BLC_MASK (3 << 13)
#define MOD_IMS_SYSMUX (1 << 10)
#define MOD_SLAVE (1 << 11)
#define MOD_TXONLY (0 << 8)
#define MOD_RXONLY (1 << 8)
#define MOD_TXRX (2 << 8)
#define MOD_MASK (3 << 8)
#define MOD_LR_LLOW (0 << 7)
#define MOD_LR_RLOW (1 << 7)
#define MOD_SDF_IIS (0 << 5)
#define MOD_SDF_MSB (1 << 5)
#define MOD_SDF_LSB (2 << 5)
#define MOD_SDF_MASK (3 << 5)
#define MOD_RCLK_256FS (0 << 3)
#define MOD_RCLK_512FS (1 << 3)
#define MOD_RCLK_384FS (2 << 3)
#define MOD_RCLK_768FS (3 << 3)
#define MOD_RCLK_MASK (3 << 3)
#define MOD_BCLK_32FS (0 << 1)
#define MOD_BCLK_48FS (1 << 1)
#define MOD_BCLK_16FS (2 << 1)
#define MOD_BCLK_24FS (3 << 1)
#define MOD_BCLK_MASK (3 << 1)
#define MOD_8BIT (1 << 0)
#define MOD_CDCLKCON (1 << 12)
#define PSR_PSREN (1 << 15)
#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
#define FIC_TXFLUSH (1 << 15)
#define FIC_RXFLUSH (1 << 7)
#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
#define AHB_INTENLVL0 (1 << 24)
#define AHB_LVL0INT (1 << 20)
#define AHB_CLRLVL0INT (1 << 16)
#define AHB_DMARLD (1 << 5)
#define AHB_INTMASK (1 << 3)
#define AHB_DMAEN (1 << 0)
#define AHB_LVLINTMASK (0xf << 20)
#define I2SSIZE_TRNMSK (0xffff)
#define I2SSIZE_SHIFT (16)
#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */
......@@ -22,109 +22,7 @@
#include "dma.h"
#include "i2s.h"
#define I2SCON 0x0
#define I2SMOD 0x4
#define I2SFIC 0x8
#define I2SPSR 0xc
#define I2STXD 0x10
#define I2SRXD 0x14
#define I2SFICS 0x18
#define I2STXDS 0x1c
#define CON_RSTCLR (1 << 31)
#define CON_FRXOFSTATUS (1 << 26)
#define CON_FRXORINTEN (1 << 25)
#define CON_FTXSURSTAT (1 << 24)
#define CON_FTXSURINTEN (1 << 23)
#define CON_TXSDMA_PAUSE (1 << 20)
#define CON_TXSDMA_ACTIVE (1 << 18)
#define CON_FTXURSTATUS (1 << 17)
#define CON_FTXURINTEN (1 << 16)
#define CON_TXFIFO2_EMPTY (1 << 15)
#define CON_TXFIFO1_EMPTY (1 << 14)
#define CON_TXFIFO2_FULL (1 << 13)
#define CON_TXFIFO1_FULL (1 << 12)
#define CON_LRINDEX (1 << 11)
#define CON_TXFIFO_EMPTY (1 << 10)
#define CON_RXFIFO_EMPTY (1 << 9)
#define CON_TXFIFO_FULL (1 << 8)
#define CON_RXFIFO_FULL (1 << 7)
#define CON_TXDMA_PAUSE (1 << 6)
#define CON_RXDMA_PAUSE (1 << 5)
#define CON_TXCH_PAUSE (1 << 4)
#define CON_RXCH_PAUSE (1 << 3)
#define CON_TXDMA_ACTIVE (1 << 2)
#define CON_RXDMA_ACTIVE (1 << 1)
#define CON_ACTIVE (1 << 0)
#define MOD_OPCLK_CDCLK_OUT (0 << 30)
#define MOD_OPCLK_CDCLK_IN (1 << 30)
#define MOD_OPCLK_BCLK_OUT (2 << 30)
#define MOD_OPCLK_PCLK (3 << 30)
#define MOD_OPCLK_MASK (3 << 30)
#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
#define MOD_BLCS_SHIFT 26
#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
#define MOD_BLCP_SHIFT 24
#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
#define MOD_C1DD_HHALF (1 << 19)
#define MOD_C1DD_LHALF (1 << 18)
#define MOD_DC2_EN (1 << 17)
#define MOD_DC1_EN (1 << 16)
#define MOD_BLC_16BIT (0 << 13)
#define MOD_BLC_8BIT (1 << 13)
#define MOD_BLC_24BIT (2 << 13)
#define MOD_BLC_MASK (3 << 13)
#define MOD_IMS_SYSMUX (1 << 10)
#define MOD_SLAVE (1 << 11)
#define MOD_TXONLY (0 << 8)
#define MOD_RXONLY (1 << 8)
#define MOD_TXRX (2 << 8)
#define MOD_MASK (3 << 8)
#define MOD_LR_LLOW (0 << 7)
#define MOD_LR_RLOW (1 << 7)
#define MOD_SDF_IIS (0 << 5)
#define MOD_SDF_MSB (1 << 5)
#define MOD_SDF_LSB (2 << 5)
#define MOD_SDF_MASK (3 << 5)
#define MOD_RCLK_256FS (0 << 3)
#define MOD_RCLK_512FS (1 << 3)
#define MOD_RCLK_384FS (2 << 3)
#define MOD_RCLK_768FS (3 << 3)
#define MOD_RCLK_MASK (3 << 3)
#define MOD_BCLK_32FS (0 << 1)
#define MOD_BCLK_48FS (1 << 1)
#define MOD_BCLK_16FS (2 << 1)
#define MOD_BCLK_24FS (3 << 1)
#define MOD_BCLK_MASK (3 << 1)
#define MOD_8BIT (1 << 0)
#define MOD_CDCLKCON (1 << 12)
#define PSR_PSREN (1 << 15)
#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
#define FIC_TXFLUSH (1 << 15)
#define FIC_RXFLUSH (1 << 7)
#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
#include "i2s-regs.h"
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
......
/*
* sound/soc/samsung/smdk_wm8994pcm.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd
* http://www.samsung.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 <sound/soc.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "../codecs/wm8994.h"
#include "dma.h"
#include "pcm.h"
/*
* Board Settings:
* o '1' means 'ON'
* o '0' means 'OFF'
* o 'X' means 'Don't care'
*
* SMDKC210, SMDKV310: CFG3- 1001, CFG5-1000, CFG7-111111
*/
/*
* Configure audio route as :-
* $ amixer sset 'DAC1' on,on
* $ amixer sset 'Right Headphone Mux' 'DAC'
* $ amixer sset 'Left Headphone Mux' 'DAC'
* $ amixer sset 'DAC1R Mixer AIF1.1' on
* $ amixer sset 'DAC1L Mixer AIF1.1' on
* $ amixer sset 'IN2L' on
* $ amixer sset 'IN2L PGA IN2LN' on
* $ amixer sset 'MIXINL IN2L' on
* $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
* $ amixer sset 'IN2R' on
* $ amixer sset 'IN2R PGA IN2RN' on
* $ amixer sset 'MIXINR IN2R' on
* $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
*/
/* SMDK has a 16.9344MHZ crystal attached to WM8994 */
#define SMDK_WM8994_FREQ 16934400
static int smdk_wm8994_pcm_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->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned long mclk_freq;
int rfs, ret;
switch(params_rate(params)) {
case 8000:
rfs = 512;
break;
default:
dev_err(cpu_dai->dev, "%s:%d Sampling Rate %u not supported!\n",
__func__, __LINE__, params_rate(params));
return -EINVAL;
}
mclk_freq = params_rate(params) * rfs;
/* Set the codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
| SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0)
return ret;
/* Set the cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
| SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0)
return ret;
ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
mclk_freq, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
SMDK_WM8994_FREQ, mclk_freq);
if (ret < 0)
return ret;
/* Set PCM source clock on CPU */
ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
mclk_freq, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
/* Set SCLK_DIV for making bclk */
ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
if (ret < 0)
return ret;
return 0;
}
static struct snd_soc_ops smdk_wm8994_pcm_ops = {
.hw_params = smdk_wm8994_pcm_hw_params,
};
static struct snd_soc_dai_link smdk_dai[] = {
{
.name = "WM8994 PAIF PCM",
.stream_name = "Primary PCM",
.cpu_dai_name = "samsung-pcm.0",
.codec_dai_name = "wm8994-aif1",
.platform_name = "samsung-audio",
.codec_name = "wm8994-codec",
.ops = &smdk_wm8994_pcm_ops,
},
};
static struct snd_soc_card smdk_pcm = {
.name = "SMDK-PCM",
.dai_link = smdk_dai,
.num_links = 1,
};
static int __devinit snd_smdk_probe(struct platform_device *pdev)
{
int ret = 0;
smdk_pcm.dev = &pdev->dev;
ret = snd_soc_register_card(&smdk_pcm);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
return ret;
}
return 0;
}
static int __devexit snd_smdk_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&smdk_pcm);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver snd_smdk_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "samsung-smdk-pcm",
},
.probe = snd_smdk_probe,
.remove = __devexit_p(snd_smdk_remove),
};
static int __init smdk_audio_init(void)
{
return platform_driver_register(&snd_smdk_driver);
}
module_init(smdk_audio_init);
static void __exit smdk_audio_exit(void)
{
platform_driver_unregister(&snd_smdk_driver);
}
module_exit(smdk_audio_exit);
MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
MODULE_DESCRIPTION("ALSA SoC SMDK WM8994 for PCM");
MODULE_LICENSE("GPL");
......@@ -30,14 +30,16 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
WM8962_FLL_MCLK, 32768,
44100 * 256);
if (ret < 0)
pr_err("Failed to start FLL\n");
pr_err("Failed to start FLL: %d\n", ret);
ret = snd_soc_dai_set_sysclk(codec_dai,
WM8962_SYSCLK_FLL,
44100 * 256,
SND_SOC_CLOCK_IN);
if (ret < 0)
if (ret < 0) {
pr_err("Failed to set SYSCLK: %d\n");
return ret;
}
}
break;
......@@ -59,13 +61,15 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
case SND_SOC_BIAS_STANDBY:
ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
32768, SND_SOC_CLOCK_IN);
if (ret < 0)
if (ret < 0) {
pr_err("Failed to switch away from FLL: %d\n", ret);
return ret;
}
ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
0, 0, 0);
if (ret < 0) {
pr_err("Failed to stop FLL\n");
pr_err("Failed to stop FLL: %d\n", ret);
return ret;
}
break;
......
......@@ -986,6 +986,39 @@ static int soc_probe_codec(struct snd_soc_card *card,
return ret;
}
static int soc_probe_platform(struct snd_soc_card *card,
struct snd_soc_platform *platform)
{
int ret = 0;
const struct snd_soc_platform_driver *driver = platform->driver;
platform->card = card;
if (!try_module_get(platform->dev->driver->owner))
return -ENODEV;
if (driver->probe) {
ret = driver->probe(platform);
if (ret < 0) {
dev_err(platform->dev,
"asoc: failed to probe platform %s: %d\n",
platform->name, ret);
goto err_probe;
}
}
/* mark platform as probed and add to card platform list */
platform->probed = 1;
list_add(&platform->card_list, &card->platform_dev_list);
return 0;
err_probe:
module_put(platform->dev->driver->owner);
return ret;
}
static void rtd_release(struct device *dev) {}
static int soc_post_component_init(struct snd_soc_card *card,
......@@ -1109,21 +1142,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
/* probe the platform */
if (!platform->probed &&
platform->driver->probe_order == order) {
if (!try_module_get(platform->dev->driver->owner))
return -ENODEV;
if (platform->driver->probe) {
ret = platform->driver->probe(platform);
if (ret < 0) {
printk(KERN_ERR "asoc: failed to probe platform %s\n",
platform->name);
module_put(platform->dev->driver->owner);
return ret;
}
}
/* mark platform as probed and add to card platform list */
platform->probed = 1;
list_add(&platform->card_list, &card->platform_dev_list);
ret = soc_probe_platform(card, platform);
if (ret < 0)
return ret;
}
/* probe the CODEC DAI */
......@@ -1619,6 +1640,36 @@ int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
int snd_soc_platform_read(struct snd_soc_platform *platform,
unsigned int reg)
{
unsigned int ret;
if (!platform->driver->read) {
dev_err(platform->dev, "platform has no read back\n");
return -1;
}
ret = platform->driver->read(platform, reg);
dev_dbg(platform->dev, "read %x => %x\n", reg, ret);
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_platform_read);
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val)
{
if (!platform->driver->write) {
dev_err(platform->dev, "platform has no write back\n");
return -1;
}
dev_dbg(platform->dev, "write %x = %x\n", reg, val);
return platform->driver->write(platform, reg, val);
}
EXPORT_SYMBOL_GPL(snd_soc_platform_write);
/**
* snd_soc_new_ac97_codec - initailise AC97 device
* @codec: audio codec
......
......@@ -222,12 +222,18 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
if (i2sclock % (2 * srate))
reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
if (!i2s->clk_refs)
clk_enable(i2s->clk_i2s);
tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
if (!i2s->clk_refs)
clk_disable(i2s->clk_i2s);
return 0;
}
......@@ -348,7 +354,6 @@ struct snd_soc_dai_driver tegra_i2s_dai[] = {
static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra_i2s * i2s;
char clk_name[12]; /* tegra-i2s.0 */
struct resource *mem, *memregion, *dmareq;
int ret;
......@@ -383,8 +388,7 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
}
dev_set_drvdata(&pdev->dev, i2s);
snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
i2s->clk_i2s = clk_get_sys(clk_name, NULL);
i2s->clk_i2s = clk_get(&pdev->dev, NULL);
if (IS_ERR(i2s->clk_i2s)) {
dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
ret = PTR_ERR(i2s->clk_i2s);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册