Commit 096388b7 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/rt5659', 'asoc/topic/rt5660',...

Merge remote-tracking branches 'asoc/topic/rt5659', 'asoc/topic/rt5660', 'asoc/topic/rt5677' and 'asoc/topic/samsung' into asoc-next
......@@ -12,6 +12,9 @@ Required properties:
Optional properties:
- clocks: The phandle of the master clock to the CODEC
- clock-names: Should be "mclk"
- realtek,in1-differential
- realtek,in3-differential
- realtek,in4-differential
......
RT5660 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "realtek,rt5660".
- reg : The I2C address of the device.
Optional properties:
- clocks: The phandle of the master clock to the CODEC
- clock-names: Should be "mclk"
- realtek,in1-differential
- realtek,in3-differential
Boolean. Indicate MIC1/3 input are differential, rather than single-ended.
- realtek,poweroff-in-suspend
Boolean. If the codec will be powered off in suspend, the resume should be
added delay time for waiting codec power ready.
- realtek,dmic1-data-pin
0: dmic1 is not used
1: using GPIO2 pin as dmic1 data pin
2: using IN1P pin as dmic1 data pin
Pins on the device (for linking into audio routes) for RT5660:
* DMIC L1
* DMIC R1
* IN1P
* IN1N
* IN2P
* IN3P
* IN3N
* SPO
* LOUTL
* LOUTR
Example:
rt5660 {
compatible = "realtek,rt5660";
reg = <0x1c>;
};
RT5663/RT5668 audio CODEC
This device supports I2C only.
Required properties:
- compatible : One of "realtek,rt5663" or "realtek,rt5668".
- reg : The I2C address of the device.
- interrupts : The CODEC's interrupt output.
Optional properties:
Pins on the device (for linking into audio routes) for RT5663/RT5668:
* IN1P
* IN1N
* IN2P
* IN2N
* HPOL
* HPOR
Example:
codec: rt5663@12 {
compatible = "realtek,rt5663";
reg = <0x12>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
};
......@@ -497,9 +497,28 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
},
};
static struct uda134x_platform_data s3c24xx_uda134x = {
.l3 = {
.gpio_clk = S3C2410_GPB(4),
.gpio_data = S3C2410_GPB(3),
.gpio_mode = S3C2410_GPB(2),
.use_gpios = 1,
.data_hold = 1,
.data_setup = 1,
.clock_high = 1,
.mode_hold = 1,
.mode = 1,
.mode_setup = 1,
},
.model = UDA134X_UDA1341,
};
static struct platform_device uda1340_codec = {
.name = "uda134x-codec",
.id = -1,
.dev = {
.platform_data = &s3c24xx_uda134x,
},
};
static struct platform_device *mini2440_devices[] __initdata = {
......
......@@ -2,9 +2,15 @@
#define _L3_H_ 1
struct l3_pins {
void (*setdat)(int);
void (*setclk)(int);
void (*setmode)(int);
void (*setdat)(struct l3_pins *, int);
void (*setclk)(struct l3_pins *, int);
void (*setmode)(struct l3_pins *, int);
int gpio_data;
int gpio_clk;
int gpio_mode;
int use_gpios;
int data_hold;
int data_setup;
int clock_high;
......@@ -13,6 +19,9 @@ struct l3_pins {
int mode_setup;
};
struct device;
int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap);
#endif
/*
* linux/sound/rt5660.h -- Platform data for RT5660
*
* Copyright 2016 Realtek Semiconductor Corp.
* Author: Oder Chiou <oder_chiou@realtek.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 __LINUX_SND_RT5660_H
#define __LINUX_SND_RT5660_H
enum rt5660_dmic1_data_pin {
RT5660_DMIC1_NULL,
RT5660_DMIC1_DATA_GPIO2,
RT5660_DMIC1_DATA_IN1P,
};
struct rt5660_platform_data {
/* IN1 & IN3 can optionally be differential */
bool in1_diff;
bool in3_diff;
bool use_ldo2;
bool poweroff_codec_in_suspend;
enum rt5660_dmic1_data_pin dmic1_data_pin;
};
#endif
......@@ -7,7 +7,6 @@ struct s3c24xx_uda134x_platform_data {
int l3_clk;
int l3_mode;
int l3_data;
void (*power) (int);
int model;
};
......
......@@ -113,6 +113,8 @@ config SND_SOC_ALL_CODECS
select SND_SOC_RT5645 if I2C
select SND_SOC_RT5651 if I2C
select SND_SOC_RT5659 if I2C
select SND_SOC_RT5660 if I2C
select SND_SOC_RT5663 if I2C
select SND_SOC_RT5670 if I2C
select SND_SOC_RT5677 if I2C && SPI_MASTER
select SND_SOC_SGTL5000 if I2C
......@@ -646,6 +648,8 @@ config SND_SOC_RL6231
default y if SND_SOC_RT5645=y
default y if SND_SOC_RT5651=y
default y if SND_SOC_RT5659=y
default y if SND_SOC_RT5660=y
default y if SND_SOC_RT5663=y
default y if SND_SOC_RT5670=y
default y if SND_SOC_RT5677=y
default m if SND_SOC_RT5514=m
......@@ -654,6 +658,8 @@ config SND_SOC_RL6231
default m if SND_SOC_RT5645=m
default m if SND_SOC_RT5651=m
default m if SND_SOC_RT5659=m
default m if SND_SOC_RT5660=m
default m if SND_SOC_RT5663=m
default m if SND_SOC_RT5670=m
default m if SND_SOC_RT5677=m
......@@ -666,6 +672,7 @@ config SND_SOC_RL6347A
config SND_SOC_RT286
tristate
select SND_SOC_RT5663
depends on I2C
config SND_SOC_RT298
......@@ -698,6 +705,12 @@ config SND_SOC_RT5651
config SND_SOC_RT5659
tristate
config SND_SOC_RT5660
tristate
config SND_SOC_RT5663
tristate
config SND_SOC_RT5670
tristate
......
......@@ -113,6 +113,8 @@ snd-soc-rt5640-objs := rt5640.o
snd-soc-rt5645-objs := rt5645.o
snd-soc-rt5651-objs := rt5651.o
snd-soc-rt5659-objs := rt5659.o
snd-soc-rt5660-objs := rt5660.o
snd-soc-rt5663-objs := rt5663.o
snd-soc-rt5670-objs := rt5670.o
snd-soc-rt5677-objs := rt5677.o
snd-soc-rt5677-spi-objs := rt5677-spi.o
......@@ -335,6 +337,8 @@ obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
......
......@@ -20,6 +20,8 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <sound/l3.h>
......@@ -32,11 +34,11 @@ static void sendbyte(struct l3_pins *adap, unsigned int byte)
int i;
for (i = 0; i < 8; i++) {
adap->setclk(0);
adap->setclk(adap, 0);
udelay(adap->data_hold);
adap->setdat(byte & 1);
adap->setdat(adap, byte & 1);
udelay(adap->data_setup);
adap->setclk(1);
adap->setclk(adap, 1);
udelay(adap->clock_high);
byte >>= 1;
}
......@@ -55,10 +57,10 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
for (i = 0; i < len; i++) {
if (i) {
udelay(adap->mode_hold);
adap->setmode(0);
adap->setmode(adap, 0);
udelay(adap->mode);
}
adap->setmode(1);
adap->setmode(adap, 1);
udelay(adap->mode_setup);
sendbyte(adap, buf[i]);
}
......@@ -66,26 +68,71 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
{
adap->setclk(1);
adap->setdat(1);
adap->setmode(1);
adap->setclk(adap, 1);
adap->setdat(adap, 1);
adap->setmode(adap, 1);
udelay(adap->mode);
adap->setmode(0);
adap->setmode(adap, 0);
udelay(adap->mode_setup);
sendbyte(adap, addr);
udelay(adap->mode_hold);
sendbytes(adap, data, len);
adap->setclk(1);
adap->setdat(1);
adap->setmode(0);
adap->setclk(adap, 1);
adap->setdat(adap, 1);
adap->setmode(adap, 0);
return len;
}
EXPORT_SYMBOL_GPL(l3_write);
static void l3_set_clk(struct l3_pins *adap, int val)
{
gpio_set_value(adap->gpio_clk, val);
}
static void l3_set_data(struct l3_pins *adap, int val)
{
gpio_set_value(adap->gpio_data, val);
}
static void l3_set_mode(struct l3_pins *adap, int val)
{
gpio_set_value(adap->gpio_mode, val);
}
int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap)
{
int ret;
if (!adap->use_gpios)
return -EINVAL;
ret = devm_gpio_request_one(dev, adap->gpio_data,
GPIOF_OUT_INIT_LOW, "l3_data");
if (ret < 0)
return ret;
adap->setdat = l3_set_data;
ret = devm_gpio_request_one(dev, adap->gpio_clk,
GPIOF_OUT_INIT_LOW, "l3_clk");
if (ret < 0)
return ret;
adap->setclk = l3_set_clk;
ret = devm_gpio_request_one(dev, adap->gpio_mode,
GPIOF_OUT_INIT_LOW, "l3_mode");
if (ret < 0)
return ret;
adap->setmode = l3_set_mode;
return 0;
}
EXPORT_SYMBOL_GPL(l3_set_gpio_ops);
MODULE_DESCRIPTION("L3 bit-banging driver");
MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
MODULE_LICENSE("GPL");
......@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
......@@ -3565,7 +3566,9 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
static int rt5659_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) {
case SND_SOC_BIAS_PREPARE:
......@@ -3582,6 +3585,17 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
RT5659_PWR_FV1 | RT5659_PWR_FV2);
break;
case SND_SOC_BIAS_STANDBY:
if (dapm->bias_level == SND_SOC_BIAS_OFF) {
ret = clk_prepare_enable(rt5659->mclk);
if (ret) {
dev_err(codec->dev,
"failed to enable MCLK: %d\n", ret);
return ret;
}
}
break;
case SND_SOC_BIAS_OFF:
regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
RT5659_PWR_LDO, 0);
......@@ -3591,6 +3605,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
RT5659_PWR_MB | RT5659_PWR_VREF2);
regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
RT5659_DIG_GATE_CTRL, 0);
clk_disable_unprepare(rt5659->mclk);
break;
default:
......@@ -4022,6 +4037,15 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
regmap_write(rt5659->regmap, RT5659_RESET, 0);
/* Check if MCLK provided */
rt5659->mclk = devm_clk_get(&i2c->dev, "mclk");
if (IS_ERR(rt5659->mclk)) {
if (PTR_ERR(rt5659->mclk) != -ENOENT)
return PTR_ERR(rt5659->mclk);
/* Otherwise mark the mclk pointer to NULL */
rt5659->mclk = NULL;
}
rt5659_calibrate(rt5659);
/* line in diff mode*/
......@@ -4165,6 +4189,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
if (ret)
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
/* Enable IRQ output for GPIO1 pin any way */
regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
}
return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
......
......@@ -180,9 +180,9 @@
#define RT5659_IRQ_CTRL_1 0x00b6
#define RT5659_IRQ_CTRL_2 0x00b7
#define RT5659_IRQ_CTRL_3 0x00b8
#define RT5659_IRQ_CTRL_4 0x00b9
#define RT5659_IRQ_CTRL_5 0x00ba
#define RT5659_IRQ_CTRL_6 0x00bb
#define RT5659_IRQ_CTRL_4 0x00ba
#define RT5659_IRQ_CTRL_5 0x00bb
#define RT5659_IRQ_CTRL_6 0x00bc
#define RT5659_INT_ST_1 0x00be
#define RT5659_INT_ST_2 0x00bf
#define RT5659_GPIO_CTRL_1 0x00c0
......@@ -1796,6 +1796,7 @@ struct rt5659_priv {
struct gpio_desc *gpiod_reset;
struct snd_soc_jack *hs_jack;
struct delayed_work jack_detect_work;
struct clk *mclk;
int sysclk;
int sysclk_src;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
......@@ -40,6 +41,15 @@
#define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING))
/* GPIO indexes defined by ACPI */
enum {
RT5677_GPIO_PLUG_DET = 0,
RT5677_GPIO_MIC_PRESENT_L = 1,
RT5677_GPIO_HOTWORD_DET_L = 2,
RT5677_GPIO_DSP_INT = 3,
RT5677_GPIO_HP_AMP_SHDN_L = 4,
};
static const struct regmap_range_cfg rt5677_ranges[] = {
{
.name = "PR",
......@@ -5020,10 +5030,47 @@ static const struct regmap_config rt5677_regmap = {
static const struct i2c_device_id rt5677_i2c_id[] = {
{ "rt5677", RT5677 },
{ "rt5676", RT5676 },
{ "RT5677CE:00", RT5677 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false };
static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false };
static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false };
static const struct acpi_gpio_mapping bdw_rt5677_gpios[] = {
{ "plug-det-gpios", &plug_det_gpio, 1 },
{ "mic-present-gpios", &mic_present_gpio, 1 },
{ "headphone-enable-gpios", &headphone_enable_gpio, 1 },
{ NULL },
};
static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677,
struct device *dev)
{
int ret;
u32 val;
ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
bdw_rt5677_gpios);
if (ret)
dev_warn(dev, "Failed to add driver gpios\n");
if (!device_property_read_u32(dev, "DCLK", &val))
rt5677->pdata.dmic2_clk_pin = val;
rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1");
rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2");
rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1");
rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2");
rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3");
device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio);
device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio);
device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio);
}
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
struct device *dev)
{
......@@ -5129,8 +5176,12 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
if (pdata)
rt5677->pdata = *pdata;
else
else if (i2c->dev.of_node)
rt5677_read_device_properties(rt5677, &i2c->dev);
else if (ACPI_HANDLE(&i2c->dev))
rt5677_read_acpi_properties(rt5677, &i2c->dev);
else
return -EINVAL;
/* pow-ldo2 and reset are optional. The codec pins may be statically
* connected on the board without gpios. If the gpio device property
......
......@@ -546,6 +546,7 @@ static int uda134x_codec_probe(struct platform_device *pdev)
{
struct uda134x_platform_data *pd = pdev->dev.platform_data;
struct uda134x_priv *uda134x;
int ret;
if (!pd) {
dev_err(&pdev->dev, "Missing L3 bitbang function\n");
......@@ -559,6 +560,12 @@ static int uda134x_codec_probe(struct platform_device *pdev)
uda134x->pd = pd;
platform_set_drvdata(pdev, uda134x);
if (pd->l3.use_gpios) {
ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3);
if (ret < 0)
return ret;
}
uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd,
&uda134x_regmap_config);
if (IS_ERR(uda134x->regmap))
......
config SND_SOC_SAMSUNG
menuconfig SND_SOC_SAMSUNG
tristate "ASoC support for Samsung"
depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
select SND_SOC_GENERIC_DMAENGINE_PCM
help
---help---
Say Y or M if you want to add support for codecs attached to
the Samsung SoCs' Audio interfaces. You will also need to
select the audio interfaces to support below.
if SND_SOC_SAMSUNG
config SND_S3C24XX_I2S
tristate
......@@ -18,22 +20,22 @@ config SND_S3C2412_SOC_I2S
select SND_S3C_I2SV2_SOC
config SND_SAMSUNG_PCM
tristate
tristate "Samsung PCM interface support"
config SND_SAMSUNG_AC97
tristate
select SND_SOC_AC97_BUS
config SND_SAMSUNG_SPDIF
tristate
tristate "Samsung SPDIF transmitter support"
select SND_SOC_SPDIF
config SND_SAMSUNG_I2S
tristate
tristate "Samsung I2S interface support"
config SND_SOC_SAMSUNG_NEO1973_WM8753
tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)"
depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
depends on MACH_NEO1973_GTA02
select SND_S3C24XX_I2S
select SND_SOC_WM8753
select SND_SOC_BT_SCO
......@@ -43,7 +45,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753
config SND_SOC_SAMSUNG_JIVE_WM8750
tristate "SoC I2S Audio support for Jive"
depends on SND_SOC_SAMSUNG && MACH_JIVE && I2C
depends on MACH_JIVE && I2C
select SND_SOC_WM8750
select SND_S3C2412_SOC_I2S
help
......@@ -51,7 +53,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750
config SND_SOC_SAMSUNG_SMDK_WM8580
tristate "SoC I2S Audio support for WM8580 on SMDK"
depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110
depends on I2C
select SND_SOC_WM8580
select SND_SAMSUNG_I2S
......@@ -60,7 +62,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
config SND_SOC_SAMSUNG_SMDK_WM8994
tristate "SoC I2S Audio support for WM8994 on SMDK"
depends on SND_SOC_SAMSUNG
depends on I2C=y
select MFD_WM8994
select SND_SOC_WM8994
......@@ -70,7 +71,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8994
config SND_SOC_SAMSUNG_SMDK2443_WM9710
tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
depends on SND_SOC_SAMSUNG && MACH_SMDK2443
depends on MACH_SMDK2443
select AC97_BUS
select SND_SOC_AC97_CODEC
select SND_SAMSUNG_AC97
......@@ -80,7 +81,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710
config SND_SOC_SAMSUNG_LN2440SBC_ALC650
tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
depends on ARCH_S3C24XX
select AC97_BUS
select SND_SOC_AC97_CODEC
select SND_SAMSUNG_AC97
......@@ -90,7 +91,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650
config SND_SOC_SAMSUNG_S3C24XX_UDA134X
tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
depends on ARCH_S3C24XX
select SND_S3C24XX_I2S
select SND_SOC_L3
select SND_SOC_UDA134X
......@@ -102,21 +103,21 @@ config SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C
depends on ARCH_S3C24XX && I2C
select SND_S3C24XX_I2S
select SND_SOC_TLV320AIC23_I2C
select SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_SIMTEC_HERMES
tristate "SoC I2S Audio support for Simtec Hermes board"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C
depends on ARCH_S3C24XX && I2C
select SND_S3C24XX_I2S
select SND_SOC_TLV320AIC3X
select SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_H1940_UDA1380
tristate "Audio support for the HP iPAQ H1940"
depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C
depends on ARCH_H1940 && I2C
select SND_S3C24XX_I2S
select SND_SOC_UDA1380
help
......@@ -124,7 +125,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380
config SND_SOC_SAMSUNG_RX1950_UDA1380
tristate "Audio support for the HP iPAQ RX1950"
depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C
depends on MACH_RX1950 && I2C
select SND_S3C24XX_I2S
select SND_SOC_UDA1380
help
......@@ -132,7 +133,7 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380
config SND_SOC_SAMSUNG_SMDK_WM9713
tristate "SoC AC97 Audio support for SMDK with WM9713"
depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110
select SND_SOC_WM9713
select SND_SAMSUNG_AC97
help
......@@ -140,20 +141,19 @@ config SND_SOC_SAMSUNG_SMDK_WM9713
config SND_SOC_SMARTQ
tristate "SoC I2S Audio support for SmartQ board"
depends on SND_SOC_SAMSUNG && MACH_SMARTQ && I2C
depends on MACH_SMARTQ && I2C
select SND_SAMSUNG_I2S
select SND_SOC_WM8750
config SND_SOC_SAMSUNG_SMDK_SPDIF
tristate "SoC S/PDIF Audio support for SMDK"
depends on SND_SOC_SAMSUNG
select SND_SAMSUNG_SPDIF
help
Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
config SND_SOC_SMDK_WM8580_PCM
tristate "SoC PCM Audio support for WM8580 on SMDK"
depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110)
depends on MACH_SMDKV210 || MACH_SMDKC110
depends on I2C
select SND_SOC_WM8580
select SND_SAMSUNG_PCM
......@@ -162,7 +162,6 @@ config SND_SOC_SMDK_WM8580_PCM
config SND_SOC_SMDK_WM8994_PCM
tristate "SoC PCM Audio support for WM8994 on SMDK"
depends on SND_SOC_SAMSUNG
depends on I2C=y
select MFD_WM8994
select SND_SOC_WM8994
......@@ -172,7 +171,7 @@ config SND_SOC_SMDK_WM8994_PCM
config SND_SOC_SPEYSIDE
tristate "Audio support for Wolfson Speyside"
depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER
depends on I2C && SPI_MASTER
depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
select SND_SAMSUNG_I2S
select SND_SOC_WM8996
......@@ -182,14 +181,14 @@ config SND_SOC_SPEYSIDE
config SND_SOC_TOBERMORY
tristate "Audio support for Wolfson Tobermory"
depends on SND_SOC_SAMSUNG && INPUT && I2C
depends on INPUT && I2C
depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
select SND_SAMSUNG_I2S
select SND_SOC_WM8962
config SND_SOC_BELLS
tristate "Audio support for Wolfson Bells"
depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER
depends on MFD_ARIZONA && I2C && SPI_MASTER
depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
select SND_SAMSUNG_I2S
select SND_SOC_WM5102
......@@ -200,7 +199,7 @@ config SND_SOC_BELLS
config SND_SOC_LOWLAND
tristate "Audio support for Wolfson Lowland"
depends on SND_SOC_SAMSUNG && I2C
depends on I2C
depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
select SND_SAMSUNG_I2S
select SND_SOC_WM5100
......@@ -208,7 +207,7 @@ config SND_SOC_LOWLAND
config SND_SOC_LITTLEMILL
tristate "Audio support for Wolfson Littlemill"
depends on SND_SOC_SAMSUNG && I2C
depends on I2C
depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
select SND_SAMSUNG_I2S
select MFD_WM8994
......@@ -216,7 +215,7 @@ config SND_SOC_LITTLEMILL
config SND_SOC_SNOW
tristate "Audio support for Google Snow boards"
depends on SND_SOC_SAMSUNG && I2C
depends on I2C
select SND_SOC_MAX98090
select SND_SOC_MAX98095
select SND_SAMSUNG_I2S
......@@ -226,6 +225,8 @@ config SND_SOC_SNOW
config SND_SOC_ARNDALE_RT5631_ALC5631
tristate "Audio support for RT5631(ALC5631) on Arndale Board"
depends on SND_SOC_SAMSUNG && I2C
depends on I2C
select SND_SAMSUNG_I2S
select SND_SOC_RT5631
endif #SND_SOC_SAMSUNG
......@@ -38,16 +38,16 @@ struct s3c_ac97_info {
};
static struct s3c_ac97_info s3c_ac97;
static struct s3c_dma_params s3c_ac97_pcm_out = {
.dma_size = 4,
static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_out = {
.addr_width = 4,
};
static struct s3c_dma_params s3c_ac97_pcm_in = {
.dma_size = 4,
static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_in = {
.addr_width = 4,
};
static struct s3c_dma_params s3c_ac97_mic_in = {
.dma_size = 4,
static struct snd_dmaengine_dai_dma_data s3c_ac97_mic_in = {
.addr_width = 4,
};
static void s3c_ac97_activate(struct snd_ac97 *ac97)
......@@ -74,7 +74,7 @@ static void s3c_ac97_activate(struct snd_ac97 *ac97)
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
pr_err("AC97: Unable to activate!");
pr_err("AC97: Unable to activate!\n");
}
static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
......@@ -100,7 +100,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
pr_err("AC97: Unable to read!");
pr_err("AC97: Unable to read!\n");
stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
addr = (stat >> 16) & 0x7f;
......@@ -137,7 +137,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
pr_err("AC97: Unable to write!");
pr_err("AC97: Unable to write!\n");
ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
......@@ -273,14 +273,14 @@ static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
static int s3c_ac97_dai_probe(struct snd_soc_dai *dai)
{
samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in);
snd_soc_dai_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in);
return 0;
}
static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai)
{
samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in);
snd_soc_dai_init_dma_data(dai, NULL, &s3c_ac97_mic_in);
return 0;
}
......@@ -346,12 +346,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
if (IS_ERR(s3c_ac97.regs))
return PTR_ERR(s3c_ac97.regs);
s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
s3c_ac97_pcm_out.filter_data = ac97_pdata->dma_playback;
s3c_ac97_pcm_out.addr = mem_res->start + S3C_AC97_PCM_DATA;
s3c_ac97_pcm_in.filter_data = ac97_pdata->dma_capture;
s3c_ac97_pcm_in.addr = mem_res->start + S3C_AC97_PCM_DATA;
s3c_ac97_mic_in.filter_data = ac97_pdata->dma_capture_mic;
s3c_ac97_mic_in.addr = mem_res->start + S3C_AC97_MIC_DATA;
init_completion(&s3c_ac97.done);
mutex_init(&s3c_ac97.lock);
......
/*
* dma.h --
*
* 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
......@@ -9,27 +7,15 @@
* ALSA PCM interface for the Samsung SoC
*/
#ifndef _S3C_AUDIO_H
#define _S3C_AUDIO_H
#ifndef _SAMSUNG_DMA_H
#define _SAMSUNG_DMA_H
#include <sound/dmaengine_pcm.h>
#include <linux/dmaengine.h>
struct s3c_dma_params {
void *slave; /* Channel ID */
dma_addr_t dma_addr;
int dma_size; /* Size of the DMA transfer */
char *ch_name;
struct snd_dmaengine_dai_dma_data dma_data;
};
void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
struct s3c_dma_params *playback,
struct s3c_dma_params *capture);
/*
* @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx",
* otherwise actual DMA channel names must be passed to this function.
*/
int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
const char *tx, const char *rx);
#endif
#endif /* _SAMSUNG_DMA_H */
......@@ -16,49 +16,18 @@
*/
#include <linux/module.h>
#include <linux/amba/pl08x.h>
#include <linux/platform_data/dma-s3c24xx.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/dmaengine_pcm.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
#include "dma.h"
void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
struct s3c_dma_params *playback,
struct s3c_dma_params *capture)
{
struct snd_dmaengine_dai_dma_data *playback_data = NULL;
struct snd_dmaengine_dai_dma_data *capture_data = NULL;
if (playback) {
playback_data = &playback->dma_data;
playback_data->filter_data = playback->slave;
playback_data->chan_name = playback->ch_name;
playback_data->addr = playback->dma_addr;
playback_data->addr_width = playback->dma_size;
}
if (capture) {
capture_data = &capture->dma_data;
capture_data->filter_data = capture->slave;
capture_data->chan_name = capture->ch_name;
capture_data->addr = capture->dma_addr;
capture_data->addr_width = capture->dma_size;
}
snd_soc_dai_init_dma_data(dai, playback_data, capture_data);
}
EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
const char *tx, const char *rx)
{
unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
struct snd_dmaengine_pcm_config *pcm_conf;
pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL);
......
......@@ -87,9 +87,9 @@ struct i2s_dai {
/* Driver for this DAI */
struct snd_soc_dai_driver i2s_dai_drv;
/* DMA parameters */
struct s3c_dma_params dma_playback;
struct s3c_dma_params dma_capture;
struct s3c_dma_params idma_playback;
struct snd_dmaengine_dai_dma_data dma_playback;
struct snd_dmaengine_dai_dma_data dma_capture;
struct snd_dmaengine_dai_dma_data idma_playback;
dma_filter_fn filter;
u32 quirks;
u32 suspend_i2smod;
......@@ -692,15 +692,15 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
break;
case 2:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
i2s->dma_playback.dma_size = 4;
i2s->dma_playback.addr_width = 4;
else
i2s->dma_capture.dma_size = 4;
i2s->dma_capture.addr_width = 4;
break;
case 1:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
i2s->dma_playback.dma_size = 2;
i2s->dma_playback.addr_width = 2;
else
i2s->dma_capture.dma_size = 2;
i2s->dma_capture.addr_width = 2;
break;
default:
......@@ -754,7 +754,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
writel(mod, i2s->addr + I2SMOD);
spin_unlock_irqrestore(i2s->lock, flags);
samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
i2s->frmclk = params_rate(params);
......@@ -991,10 +991,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
unsigned long flags;
if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */
samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback,
snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback,
NULL);
} else {
samsung_asoc_init_dma_data(dai, &i2s->dma_playback,
snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
&i2s->dma_capture);
if (i2s->quirks & QUIRK_NEED_RSTCLR)
......@@ -1002,7 +1002,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
idma_reg_addr_init(i2s->addr,
i2s->sec_dai->idma_playback.dma_addr);
i2s->sec_dai->idma_playback.addr);
}
/* Reset any constraint on RFS and BFS */
......@@ -1262,8 +1262,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
return -EINVAL;
}
pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback;
pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
pri_dai->filter = i2s_pdata->dma_filter;
if (&i2s_pdata->type)
......@@ -1302,12 +1302,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
return ret;
}
pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
pri_dai->dma_playback.ch_name = "tx";
pri_dai->dma_capture.ch_name = "rx";
pri_dai->dma_playback.dma_size = 4;
pri_dai->dma_capture.dma_size = 4;
pri_dai->dma_playback.addr = regs_base + I2STXD;
pri_dai->dma_capture.addr = regs_base + I2SRXD;
pri_dai->dma_playback.chan_name = "tx";
pri_dai->dma_capture.chan_name = "rx";
pri_dai->dma_playback.addr_width = 4;
pri_dai->dma_capture.addr_width = 4;
pri_dai->quirks = quirks;
pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
......@@ -1318,31 +1318,33 @@ static int samsung_i2s_probe(struct platform_device *pdev)
sec_dai = i2s_alloc_dai(pdev, true);
if (!sec_dai) {
dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
return -ENOMEM;
ret = -ENOMEM;
goto err_disable_clk;
}
sec_dai->lock = &pri_dai->spinlock;
sec_dai->variant_regs = pri_dai->variant_regs;
sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
sec_dai->dma_playback.ch_name = "tx-sec";
sec_dai->dma_playback.addr = regs_base + I2STXDS;
sec_dai->dma_playback.chan_name = "tx-sec";
if (!np) {
sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
sec_dai->filter = i2s_pdata->dma_filter;
}
sec_dai->dma_playback.dma_size = 4;
sec_dai->dma_playback.addr_width = 4;
sec_dai->addr = pri_dai->addr;
sec_dai->clk = pri_dai->clk;
sec_dai->quirks = quirks;
sec_dai->idma_playback.dma_addr = idma_addr;
sec_dai->idma_playback.addr = idma_addr;
sec_dai->pri_dai = pri_dai;
pri_dai->sec_dai = sec_dai;
}
if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
dev_err(&pdev->dev, "Unable to configure gpio\n");
return -EINVAL;
ret = -EINVAL;
goto err_disable_clk;
}
ret = devm_snd_soc_register_component(&pri_dai->pdev->dev,
......@@ -1366,6 +1368,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
err_free_dai:
if (sec_dai)
i2s_free_sec_dai(sec_dai);
err_disable_clk:
clk_disable_unprepare(pri_dai->clk);
return ret;
}
......
......@@ -22,7 +22,6 @@
#include "i2s.h"
#include "idma.h"
#include "dma.h"
#include "i2s-regs.h"
#define ST_RUNNING (1<<0)
......
......@@ -127,25 +127,25 @@ struct s3c_pcm_info {
struct clk *pclk;
struct clk *cclk;
struct s3c_dma_params *dma_playback;
struct s3c_dma_params *dma_capture;
struct snd_dmaengine_dai_dma_data *dma_playback;
struct snd_dmaengine_dai_dma_data *dma_capture;
};
static struct s3c_dma_params s3c_pcm_stereo_out[] = {
static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_out[] = {
[0] = {
.dma_size = 4,
.addr_width = 4,
},
[1] = {
.dma_size = 4,
.addr_width = 4,
},
};
static struct s3c_dma_params s3c_pcm_stereo_in[] = {
static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_in[] = {
[0] = {
.dma_size = 4,
.addr_width = 4,
},
[1] = {
.dma_size = 4,
.addr_width = 4,
},
};
......@@ -552,15 +552,13 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
}
clk_prepare_enable(pcm->pclk);
s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
+ S3C_PCM_RXFIFO;
s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
+ S3C_PCM_TXFIFO;
s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO;
s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO;
filter = NULL;
if (pcm_pdata) {
s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
s3c_pcm_stereo_in[pdev->id].filter_data = pcm_pdata->dma_capture;
s3c_pcm_stereo_out[pdev->id].filter_data = pcm_pdata->dma_playback;
filter = pcm_pdata->dma_filter;
}
......
......@@ -24,7 +24,6 @@
#include "regs-i2s-v2.h"
#include "s3c-i2s-v2.h"
#include "dma.h"
#undef S3C_IIS_V2_SUPPORTED
......@@ -302,7 +301,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct s3c_i2sv2_info *i2s = to_info(dai);
struct s3c_dma_params *dma_data;
struct snd_dmaengine_dai_dma_data *dma_data;
u32 iismod;
pr_debug("Entered %s\n", __func__);
......
......@@ -60,8 +60,8 @@ struct s3c_i2sv2_info {
unsigned char master;
struct s3c_dma_params *dma_playback;
struct s3c_dma_params *dma_capture;
struct snd_dmaengine_dai_dma_data *dma_playback;
struct snd_dmaengine_dai_dma_data *dma_capture;
u32 suspend_iismod;
u32 suspend_iiscon;
......
......@@ -34,14 +34,14 @@
#include <linux/platform_data/asoc-s3c.h>
static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
.ch_name = "tx",
.dma_size = 4,
static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = {
.chan_name = "tx",
.addr_width = 4,
};
static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
.ch_name = "rx",
.dma_size = 4,
static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = {
.chan_name = "rx",
.addr_width = 4,
};
static struct s3c_i2sv2_info s3c2412_i2s;
......@@ -52,8 +52,8 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
pr_debug("Entered %s\n", __func__);
samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
&s3c2412_i2s_pcm_stereo_in);
snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
&s3c2412_i2s_pcm_stereo_in);
ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
if (ret)
......@@ -163,10 +163,10 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
if (IS_ERR(s3c2412_i2s.regs))
return PTR_ERR(s3c2412_i2s.regs);
s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback;
s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture;
s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD;
s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
ret = s3c_i2sv2_register_component(&pdev->dev, -1,
&s3c2412_i2s_component,
......
......@@ -32,14 +32,14 @@
#include <linux/platform_data/asoc-s3c.h>
static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
.ch_name = "tx",
.dma_size = 2,
static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = {
.chan_name = "tx",
.addr_width = 2,
};
static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
.ch_name = "rx",
.dma_size = 2,
static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = {
.chan_name = "rx",
.addr_width = 2,
};
struct s3c24xx_i2s_info {
......@@ -360,8 +360,8 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
{
pr_debug("Entered %s\n", __func__);
samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
&s3c24xx_i2s_pcm_stereo_in);
snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
&s3c24xx_i2s_pcm_stereo_in);
s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
if (IS_ERR(s3c24xx_i2s.iis_clk)) {
......@@ -469,10 +469,10 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
if (IS_ERR(s3c24xx_i2s.regs))
return PTR_ERR(s3c24xx_i2s.regs);
s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback;
s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture;
s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
......
......@@ -54,8 +54,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
};
#endif
static struct platform_device *s3c24xx_uda134x_snd_device;
static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
......@@ -66,17 +64,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
int ret = 0;
mutex_lock(&clk_lock);
pr_debug("%s %d\n", __func__, clk_users);
if (clk_users == 0) {
xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
xtal = clk_get(rtd->dev, "xtal");
if (IS_ERR(xtal)) {
printk(KERN_ERR "%s cannot get xtal\n", __func__);
dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
ret = PTR_ERR(xtal);
} else {
pclk = clk_get(cpu_dai->dev, "iis");
if (IS_ERR(pclk)) {
printk(KERN_ERR "%s cannot get pclk\n",
__func__);
dev_err(rtd->dev, "%s cannot get pclk\n",
__func__);
clk_put(xtal);
ret = PTR_ERR(pclk);
}
......@@ -102,8 +100,8 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_RATE,
&hw_constraints_rates);
if (ret < 0)
printk(KERN_ERR "%s cannot set constraints\n",
__func__);
dev_err(rtd->dev, "%s cannot set constraints\n",
__func__);
#endif
}
return ret;
......@@ -112,7 +110,6 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
{
mutex_lock(&clk_lock);
pr_debug("%s %d\n", __func__, clk_users);
clk_users -= 1;
if (clk_users == 0) {
clk_put(xtal);
......@@ -159,18 +156,19 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
clk_source = S3C24XX_CLKSRC_PCLK;
div = bi % 33;
}
pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi);
clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
div, clk, err);
dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__,
fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
div, clk, err);
if ((err * 100 / rate) > 5) {
printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
"too different from desired (%ld%%)\n",
err * 100 / rate);
dev_err(rtd->dev, "effective frequency too different "
"from desired (%ld%%)\n", err * 100 / rate);
return -EINVAL;
}
......@@ -227,115 +225,27 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
.num_links = 1,
};
static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
static void setdat(int v)
{
gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
}
static void setclk(int v)
{
gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
}
static void setmode(int v)
{
gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
}
/* FIXME - This must be codec platform data but in which board file ?? */
static struct uda134x_platform_data s3c24xx_uda134x = {
.l3 = {
.setdat = setdat,
.setclk = setclk,
.setmode = setmode,
.data_hold = 1,
.data_setup = 1,
.clock_high = 1,
.mode_hold = 1,
.mode = 1,
.mode_setup = 1,
},
};
static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
{
if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
"l3 %s pin already in use", fun);
return -EBUSY;
}
gpio_direction_output(pin, 0);
return 0;
}
static int s3c24xx_uda134x_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
int ret;
printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
platform_set_drvdata(pdev, card);
card->dev = &pdev->dev;
s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
if (s3c24xx_uda134x_l3_pins == NULL) {
printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
"unable to find platform data\n");
return -ENODEV;
}
s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
"data") < 0)
return -EBUSY;
if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
"clk") < 0) {
gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
return -EBUSY;
}
if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
"mode") < 0) {
gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
return -EBUSY;
}
s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
if (!s3c24xx_uda134x_snd_device) {
printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
"Unable to register\n");
return -ENOMEM;
}
platform_set_drvdata(s3c24xx_uda134x_snd_device,
&snd_soc_s3c24xx_uda134x);
platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));
ret = platform_device_add(s3c24xx_uda134x_snd_device);
if (ret) {
printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
platform_device_put(s3c24xx_uda134x_snd_device);
}
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret)
dev_err(&pdev->dev, "failed to register card: %d\n", ret);
return ret;
}
static int s3c24xx_uda134x_remove(struct platform_device *pdev)
{
platform_device_unregister(s3c24xx_uda134x_snd_device);
gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
return 0;
}
static struct platform_driver s3c24xx_uda134x_driver = {
.probe = s3c24xx_uda134x_probe,
.remove = s3c24xx_uda134x_remove,
.driver = {
.name = "s3c24xx_uda134x",
},
};
module_platform_driver(s3c24xx_uda134x_driver);
MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
......
......@@ -16,7 +16,6 @@
#include <asm/mach-types.h>
#include "../codecs/wm8580.h"
#include "dma.h"
#include "pcm.h"
/*
......
......@@ -15,7 +15,6 @@
#include <sound/pcm_params.h>
#include "../codecs/wm8994.h"
#include "dma.h"
#include "pcm.h"
/*
......
......@@ -90,10 +90,10 @@ struct samsung_spdif_info {
u32 saved_clkcon;
u32 saved_con;
u32 saved_cstas;
struct s3c_dma_params *dma_playback;
struct snd_dmaengine_dai_dma_data *dma_playback;
};
static struct s3c_dma_params spdif_stereo_out;
static struct snd_dmaengine_dai_dma_data spdif_stereo_out;
static struct samsung_spdif_info spdif_info;
static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai)
......@@ -179,7 +179,7 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
void __iomem *regs = spdif->regs;
struct s3c_dma_params *dma_data;
struct snd_dmaengine_dai_dma_data *dma_data;
u32 con, clkcon, cstas;
unsigned long flags;
int i, ratio;
......@@ -425,11 +425,11 @@ static int spdif_probe(struct platform_device *pdev)
goto err4;
}
spdif_stereo_out.dma_size = 2;
spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
spdif_stereo_out.addr_width = 2;
spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF;
filter = NULL;
if (spdif_pdata) {
spdif_stereo_out.slave = spdif_pdata->dma_playback;
spdif_stereo_out.filter_data = spdif_pdata->dma_playback;
filter = spdif_pdata->dma_filter;
}
......
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