mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
Merge remote-tracking branches 'asoc/topic/pxa', 'asoc/topic/rcar' and 'asoc/topic/rt286' into asoc-next
This commit is contained in:
commit
af70797105
@ -55,6 +55,7 @@ struct rsnd_ssi_platform_info {
|
||||
struct rsnd_src_platform_info {
|
||||
u32 convert_rate; /* sampling rate convert */
|
||||
int dma_id; /* for Gen2 SCU */
|
||||
int irq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "rt286.h"
|
||||
|
||||
#define RT286_VENDOR_ID 0x10ec0286
|
||||
#define RT288_VENDOR_ID 0x10ec0288
|
||||
|
||||
struct rt286_priv {
|
||||
struct regmap *regmap;
|
||||
@ -1171,6 +1172,7 @@ static const struct regmap_config rt286_regmap = {
|
||||
|
||||
static const struct i2c_device_id rt286_i2c_id[] = {
|
||||
{"rt286", 0},
|
||||
{"rt288", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt286_i2c_id);
|
||||
@ -1191,6 +1193,17 @@ static struct dmi_system_id force_combo_jack_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct dmi_system_id dmi_dell_dino[] = {
|
||||
{
|
||||
.ident = "Dell Dino",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "0144P8")
|
||||
}
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int rt286_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@ -1213,7 +1226,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
regmap_read(rt286->regmap,
|
||||
RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret);
|
||||
if (ret != RT286_VENDOR_ID) {
|
||||
if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) {
|
||||
dev_err(&i2c->dev,
|
||||
"Device with ID register %x is not rt286\n", ret);
|
||||
return -ENODEV;
|
||||
@ -1226,7 +1239,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
|
||||
if (pdata)
|
||||
rt286->pdata = *pdata;
|
||||
|
||||
if (dmi_check_system(force_combo_jack_table))
|
||||
if (dmi_check_system(force_combo_jack_table) ||
|
||||
dmi_check_system(dmi_dell_dino))
|
||||
rt286->pdata.cbj_en = true;
|
||||
|
||||
regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3);
|
||||
@ -1265,6 +1279,17 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
|
||||
regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737);
|
||||
regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f);
|
||||
|
||||
if (dmi_check_system(dmi_dell_dino)) {
|
||||
regmap_update_bits(rt286->regmap,
|
||||
RT286_SET_GPIO_MASK, 0x40, 0x40);
|
||||
regmap_update_bits(rt286->regmap,
|
||||
RT286_SET_GPIO_DIRECTION, 0x40, 0x40);
|
||||
regmap_update_bits(rt286->regmap,
|
||||
RT286_SET_GPIO_DATA, 0x40, 0x40);
|
||||
regmap_update_bits(rt286->regmap,
|
||||
RT286_GPIO_CTRL, 0xc, 0x8);
|
||||
}
|
||||
|
||||
if (rt286->i2c->irq) {
|
||||
ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq,
|
||||
IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286);
|
||||
|
@ -117,6 +117,12 @@
|
||||
VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0)
|
||||
#define RT286_PROC_COEF\
|
||||
VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0)
|
||||
#define RT286_SET_GPIO_MASK\
|
||||
VERB_CMD(AC_VERB_SET_GPIO_MASK, RT286_AUDIO_FUNCTION_GROUP, 0)
|
||||
#define RT286_SET_GPIO_DIRECTION\
|
||||
VERB_CMD(AC_VERB_SET_GPIO_DIRECTION, RT286_AUDIO_FUNCTION_GROUP, 0)
|
||||
#define RT286_SET_GPIO_DATA\
|
||||
VERB_CMD(AC_VERB_SET_GPIO_DATA, RT286_AUDIO_FUNCTION_GROUP, 0)
|
||||
|
||||
/* Index registers */
|
||||
#define RT286_A_BIAS_CTRL1 0x01
|
||||
@ -131,6 +137,7 @@
|
||||
#define RT286_POWER_CTRL3 0x0f
|
||||
#define RT286_MIC1_DET_CTRL 0x19
|
||||
#define RT286_MISC_CTRL1 0x20
|
||||
#define RT286_GPIO_CTRL 0x29
|
||||
#define RT286_IRQ_CTRL 0x33
|
||||
#define RT286_PLL_CTRL1 0x49
|
||||
#define RT286_CBJ_CTRL1 0x4f
|
||||
|
@ -140,7 +140,7 @@ config SND_PXA910_SOC
|
||||
Marvell PXA910 reference platform.
|
||||
|
||||
config SND_SOC_TTC_DKB
|
||||
bool "SoC Audio support for TTC DKB"
|
||||
tristate "SoC Audio support for TTC DKB"
|
||||
depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y
|
||||
select PXA_SSP
|
||||
select SND_PXA_SOC_SSP
|
||||
|
@ -259,20 +259,6 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
|
||||
corgi_set_spk),
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
|
||||
*/
|
||||
static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
|
||||
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* corgi digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link corgi_dai = {
|
||||
.name = "WM8731",
|
||||
@ -281,7 +267,6 @@ static struct snd_soc_dai_link corgi_dai = {
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.init = corgi_wm8731_init,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &corgi_ops,
|
||||
@ -300,6 +285,7 @@ static struct snd_soc_card corgi = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
|
||||
.dapm_routes = corgi_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(corgi_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int corgi_probe(struct platform_device *pdev)
|
||||
|
@ -88,24 +88,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"Mic Amp", NULL, "Mic (Internal)"},
|
||||
};
|
||||
|
||||
static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
snd_soc_dapm_nc_pin(dapm, "HPOUTL");
|
||||
snd_soc_dapm_nc_pin(dapm, "HPOUTR");
|
||||
snd_soc_dapm_nc_pin(dapm, "PHONE");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINR");
|
||||
snd_soc_dapm_nc_pin(dapm, "CDINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "CDINR");
|
||||
snd_soc_dapm_nc_pin(dapm, "PCBEEP");
|
||||
snd_soc_dapm_nc_pin(dapm, "MIC2");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_link e740_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
@ -114,7 +96,6 @@ static struct snd_soc_dai_link e740_dai[] = {
|
||||
.codec_dai_name = "wm9705-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm9705-codec",
|
||||
.init = e740_ac97_init,
|
||||
},
|
||||
{
|
||||
.name = "AC97 Aux",
|
||||
@ -136,6 +117,7 @@ static struct snd_soc_card e740 = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct gpio e740_audio_gpios[] = {
|
||||
|
@ -70,24 +70,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"MIC1", NULL, "Mic (Internal)"},
|
||||
};
|
||||
|
||||
static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
snd_soc_dapm_nc_pin(dapm, "LOUT");
|
||||
snd_soc_dapm_nc_pin(dapm, "ROUT");
|
||||
snd_soc_dapm_nc_pin(dapm, "PHONE");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINR");
|
||||
snd_soc_dapm_nc_pin(dapm, "CDINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "CDINR");
|
||||
snd_soc_dapm_nc_pin(dapm, "PCBEEP");
|
||||
snd_soc_dapm_nc_pin(dapm, "MIC2");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_link e750_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
@ -96,7 +78,6 @@ static struct snd_soc_dai_link e750_dai[] = {
|
||||
.codec_dai_name = "wm9705-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm9705-codec",
|
||||
.init = e750_ac97_init,
|
||||
/* use ops to check startup state */
|
||||
},
|
||||
{
|
||||
@ -119,6 +100,7 @@ static struct snd_soc_card e750 = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct gpio e750_audio_gpios[] = {
|
||||
|
@ -127,15 +127,8 @@ static const struct snd_soc_dapm_route hx4700_audio_map[] = {
|
||||
static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int err;
|
||||
|
||||
/* NC codec pins */
|
||||
/* FIXME: is anything connected here? */
|
||||
snd_soc_dapm_nc_pin(dapm, "MOUT1");
|
||||
snd_soc_dapm_nc_pin(dapm, "MICEXT");
|
||||
snd_soc_dapm_nc_pin(dapm, "AUX");
|
||||
|
||||
/* Jack detection API stuff */
|
||||
err = snd_soc_jack_new(codec, "Headphone Jack",
|
||||
SND_JACK_HEADPHONE, &hs_jack);
|
||||
@ -184,6 +177,7 @@ static struct snd_soc_card snd_soc_card_hx4700 = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
|
||||
.dapm_routes = hx4700_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct gpio hx4700_audio_gpios[] = {
|
||||
|
@ -391,25 +391,6 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
|
||||
magician_get_input, magician_set_input),
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a uda1380 as connected on a HTC Magician
|
||||
*/
|
||||
static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
/* NC codec pins */
|
||||
snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
|
||||
snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
|
||||
|
||||
/* FIXME: is anything connected here? */
|
||||
snd_soc_dapm_nc_pin(dapm, "VINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "VINR");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* magician digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link magician_dai[] = {
|
||||
{
|
||||
@ -419,7 +400,6 @@ static struct snd_soc_dai_link magician_dai[] = {
|
||||
.codec_dai_name = "uda1380-hifi-playback",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "uda1380-codec.0-0018",
|
||||
.init = magician_uda1380_init,
|
||||
.ops = &magician_playback_ops,
|
||||
},
|
||||
{
|
||||
@ -446,6 +426,7 @@ static struct snd_soc_card snd_soc_card_magician = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct platform_device *magician_snd_device;
|
||||
|
@ -68,7 +68,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
||||
{"Ext. Speaker", NULL, "ROUT2"},
|
||||
|
||||
/* mic connected to MIC1 */
|
||||
{"Ext. Microphone", NULL, "MIC1"},
|
||||
{"MIC1", NULL, "Ext. Microphone"},
|
||||
};
|
||||
|
||||
static struct snd_soc_card palm27x_asoc;
|
||||
@ -76,18 +76,8 @@ static struct snd_soc_card palm27x_asoc;
|
||||
static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int err;
|
||||
|
||||
/* not connected pins */
|
||||
snd_soc_dapm_nc_pin(dapm, "OUT3");
|
||||
snd_soc_dapm_nc_pin(dapm, "MONOOUT");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINL");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEINR");
|
||||
snd_soc_dapm_nc_pin(dapm, "PCBEEP");
|
||||
snd_soc_dapm_nc_pin(dapm, "PHONE");
|
||||
snd_soc_dapm_nc_pin(dapm, "MIC2");
|
||||
|
||||
/* Jack detection API stuff */
|
||||
err = snd_soc_jack_new(codec, "Headphone Jack",
|
||||
SND_JACK_HEADPHONE, &hs_jack);
|
||||
@ -133,7 +123,8 @@ static struct snd_soc_card palm27x_asoc = {
|
||||
.dapm_widgets = palm27x_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets),
|
||||
.dapm_routes = audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map)
|
||||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int palm27x_asoc_probe(struct platform_device *pdev)
|
||||
|
@ -256,26 +256,6 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
|
||||
spitz_set_spk),
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
|
||||
*/
|
||||
static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
/* NC codec pins */
|
||||
snd_soc_dapm_nc_pin(dapm, "RINPUT1");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINPUT2");
|
||||
snd_soc_dapm_nc_pin(dapm, "RINPUT2");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINPUT3");
|
||||
snd_soc_dapm_nc_pin(dapm, "RINPUT3");
|
||||
snd_soc_dapm_nc_pin(dapm, "OUT3");
|
||||
snd_soc_dapm_nc_pin(dapm, "MONO1");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* spitz digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link spitz_dai = {
|
||||
.name = "wm8750",
|
||||
@ -284,7 +264,6 @@ static struct snd_soc_dai_link spitz_dai = {
|
||||
.codec_dai_name = "wm8750-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm8750.0-001b",
|
||||
.init = spitz_wm8750_init,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &spitz_ops,
|
||||
@ -303,6 +282,7 @@ static struct snd_soc_card snd_soc_spitz = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
|
||||
.dapm_routes = spitz_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(spitz_audio_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int spitz_probe(struct platform_device *pdev)
|
||||
|
@ -76,10 +76,6 @@ static const struct snd_soc_dapm_route ttc_audio_map[] = {
|
||||
static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
|
||||
snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
|
||||
|
||||
/* Headset jack detection */
|
||||
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
|
||||
|
@ -57,8 +57,7 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
|
||||
return (0x6 + ws) << 8;
|
||||
}
|
||||
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
@ -75,12 +74,11 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io,
|
||||
u32 timsel)
|
||||
{
|
||||
int is_play = rsnd_dai_is_play(rdai, io);
|
||||
int is_play = rsnd_io_is_play(io);
|
||||
int id = rsnd_mod_id(mod);
|
||||
int shift = (id % 2) ? 16 : 0;
|
||||
u32 mask, ws;
|
||||
@ -122,7 +120,6 @@ static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
|
||||
}
|
||||
|
||||
int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io,
|
||||
unsigned int src_rate,
|
||||
unsigned int dst_rate)
|
||||
@ -178,7 +175,7 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
|
||||
ret = rsnd_adg_set_src_timsel_gen2(mod, io, val);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "timsel error\n");
|
||||
return ret;
|
||||
@ -190,12 +187,11 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
|
||||
|
||||
return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val);
|
||||
return rsnd_adg_set_src_timsel_gen2(mod, io, val);
|
||||
}
|
||||
|
||||
int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
|
||||
|
@ -149,16 +149,16 @@ char *rsnd_mod_dma_name(struct rsnd_mod *mod)
|
||||
return mod->ops->dma_name(mod);
|
||||
}
|
||||
|
||||
void rsnd_mod_init(struct rsnd_priv *priv,
|
||||
struct rsnd_mod *mod,
|
||||
void rsnd_mod_init(struct rsnd_mod *mod,
|
||||
struct rsnd_mod_ops *ops,
|
||||
struct clk *clk,
|
||||
enum rsnd_mod_type type,
|
||||
int id)
|
||||
{
|
||||
mod->priv = priv;
|
||||
mod->id = id;
|
||||
mod->ops = ops;
|
||||
mod->type = type;
|
||||
mod->clk = clk;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -412,7 +412,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
|
||||
/*
|
||||
* rsnd_dai functions
|
||||
*/
|
||||
#define __rsnd_mod_call(mod, func, rdai...) \
|
||||
#define __rsnd_mod_call(mod, func, param...) \
|
||||
({ \
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
|
||||
struct device *dev = rsnd_priv_to_dev(priv); \
|
||||
@ -422,18 +422,18 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
|
||||
if ((mod->status & mask) == call) { \
|
||||
dev_dbg(dev, "%s[%d] %s\n", \
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \
|
||||
ret = (mod)->ops->func(mod, rdai); \
|
||||
ret = (mod)->ops->func(mod, param); \
|
||||
mod->status = (mod->status & ~mask) | (~call & mask); \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define rsnd_mod_call(mod, func, rdai...) \
|
||||
#define rsnd_mod_call(mod, func, param...) \
|
||||
(!(mod) ? -ENODEV : \
|
||||
!((mod)->ops->func) ? 0 : \
|
||||
__rsnd_mod_call(mod, func, rdai))
|
||||
__rsnd_mod_call(mod, func, param))
|
||||
|
||||
#define rsnd_dai_call(fn, io, rdai...) \
|
||||
#define rsnd_dai_call(fn, io, param...) \
|
||||
({ \
|
||||
struct rsnd_mod *mod; \
|
||||
int ret = 0, i; \
|
||||
@ -441,7 +441,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
|
||||
mod = (io)->mod[i]; \
|
||||
if (!mod) \
|
||||
continue; \
|
||||
ret = rsnd_mod_call(mod, fn, rdai); \
|
||||
ret = rsnd_mod_call(mod, fn, param); \
|
||||
if (ret < 0) \
|
||||
break; \
|
||||
} \
|
||||
@ -477,17 +477,7 @@ static void rsnd_dai_disconnect(struct rsnd_mod *mod,
|
||||
io->mod[mod->type] = NULL;
|
||||
}
|
||||
|
||||
int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
|
||||
{
|
||||
int id = rdai - priv->rdai;
|
||||
|
||||
if ((id < 0) || (id >= rsnd_rdai_nr(priv)))
|
||||
return -EINVAL;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id)
|
||||
struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id)
|
||||
{
|
||||
if ((id < 0) || (id >= rsnd_rdai_nr(priv)))
|
||||
return NULL;
|
||||
@ -499,12 +489,7 @@ static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
return rsnd_dai_get(priv, dai->id);
|
||||
}
|
||||
|
||||
int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io)
|
||||
{
|
||||
return &rdai->playback == io;
|
||||
return rsnd_rdai_get(priv, dai->id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -598,20 +583,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(init, io, rdai);
|
||||
ret = rsnd_dai_call(init, io, priv);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(start, io, rdai);
|
||||
ret = rsnd_dai_call(start, io, priv);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = rsnd_dai_call(stop, io, rdai);
|
||||
ret = rsnd_dai_call(stop, io, priv);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(quit, io, rdai);
|
||||
ret = rsnd_dai_call(quit, io, priv);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
@ -873,15 +858,15 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
||||
priv->rdai = rdai;
|
||||
|
||||
for (i = 0; i < dai_nr; i++) {
|
||||
rdai[i].info = &info->dai_info[i];
|
||||
|
||||
pmod = rdai[i].info->playback.ssi;
|
||||
cmod = rdai[i].info->capture.ssi;
|
||||
pmod = info->dai_info[i].playback.ssi;
|
||||
cmod = info->dai_info[i].capture.ssi;
|
||||
|
||||
/*
|
||||
* init rsnd_dai
|
||||
*/
|
||||
snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
|
||||
rdai[i].priv = priv;
|
||||
|
||||
/*
|
||||
* init snd_soc_dai_driver
|
||||
@ -895,6 +880,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
||||
drv[i].playback.channels_max = 2;
|
||||
|
||||
rdai[i].playback.info = &info->dai_info[i].playback;
|
||||
rdai[i].playback.rdai = rdai + i;
|
||||
rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
|
||||
}
|
||||
if (cmod) {
|
||||
@ -904,6 +890,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
||||
drv[i].capture.channels_max = 2;
|
||||
|
||||
rdai[i].capture.info = &info->dai_info[i].capture;
|
||||
rdai[i].capture.rdai = rdai + i;
|
||||
rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
|
||||
}
|
||||
|
||||
@ -1037,7 +1024,6 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
|
||||
}
|
||||
|
||||
static int __rsnd_kctrl_new(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
struct rsnd_kctrl_cfg *cfg,
|
||||
@ -1060,16 +1046,24 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_ctl_add(card, kctrl);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
snd_ctl_free_one(kctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cfg->update = update;
|
||||
cfg->card = card;
|
||||
cfg->kctrl = kctrl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg)
|
||||
{
|
||||
snd_ctl_remove(cfg->card, cfg->kctrl);
|
||||
}
|
||||
|
||||
int rsnd_kctrl_new_m(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
void (*update)(struct rsnd_mod *mod),
|
||||
@ -1079,11 +1073,10 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod,
|
||||
_cfg->cfg.max = max;
|
||||
_cfg->cfg.size = RSND_DVC_CHANNELS;
|
||||
_cfg->cfg.val = _cfg->val;
|
||||
return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update);
|
||||
return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update);
|
||||
}
|
||||
|
||||
int rsnd_kctrl_new_s(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
void (*update)(struct rsnd_mod *mod),
|
||||
@ -1093,11 +1086,10 @@ int rsnd_kctrl_new_s(struct rsnd_mod *mod,
|
||||
_cfg->cfg.max = max;
|
||||
_cfg->cfg.size = 1;
|
||||
_cfg->cfg.val = &_cfg->val;
|
||||
return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update);
|
||||
return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update);
|
||||
}
|
||||
|
||||
int rsnd_kctrl_new_e(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
struct rsnd_kctrl_cfg_s *_cfg,
|
||||
@ -1109,7 +1101,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
|
||||
_cfg->cfg.size = 1;
|
||||
_cfg->cfg.val = &_cfg->val;
|
||||
_cfg->cfg.texts = texts;
|
||||
return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update);
|
||||
return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1125,11 +1117,11 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
|
||||
int ret;
|
||||
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd);
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->playback, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd);
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->capture, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1140,15 +1132,9 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
|
||||
}
|
||||
|
||||
static void rsnd_pcm_free(struct snd_pcm *pcm)
|
||||
{
|
||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
||||
}
|
||||
|
||||
static struct snd_soc_platform_driver rsnd_soc_platform = {
|
||||
.ops = &rsnd_pcm_ops,
|
||||
.pcm_new = rsnd_pcm_new,
|
||||
.pcm_free = rsnd_pcm_free,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver rsnd_soc_component = {
|
||||
@ -1156,13 +1142,11 @@ static const struct snd_soc_component_driver rsnd_soc_component = {
|
||||
};
|
||||
|
||||
static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
|
||||
struct rsnd_dai *rdai,
|
||||
int is_play)
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture;
|
||||
int ret;
|
||||
|
||||
ret = rsnd_dai_call(probe, io, rdai);
|
||||
ret = rsnd_dai_call(probe, io, priv);
|
||||
if (ret == -EAGAIN) {
|
||||
/*
|
||||
* Fallback to PIO mode
|
||||
@ -1175,7 +1159,7 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
|
||||
* rsnd_dma_init()
|
||||
* rsnd_ssi_fallback()
|
||||
*/
|
||||
rsnd_dai_call(remove, io, rdai);
|
||||
rsnd_dai_call(remove, io, priv);
|
||||
|
||||
/*
|
||||
* remove SRC/DVC from DAI,
|
||||
@ -1186,13 +1170,13 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
|
||||
/*
|
||||
* fallback
|
||||
*/
|
||||
rsnd_dai_call(fallback, io, rdai);
|
||||
rsnd_dai_call(fallback, io, priv);
|
||||
|
||||
/*
|
||||
* retry to "probe".
|
||||
* DAI has SSI which is PIO mode only now.
|
||||
*/
|
||||
ret = rsnd_dai_call(probe, io, rdai);
|
||||
ret = rsnd_dai_call(probe, io, priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1259,11 +1243,11 @@ static int rsnd_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret = rsnd_rdai_continuance_probe(priv, rdai, 1);
|
||||
ret = rsnd_rdai_continuance_probe(priv, &rdai->playback);
|
||||
if (ret)
|
||||
goto exit_snd_probe;
|
||||
|
||||
ret = rsnd_rdai_continuance_probe(priv, rdai, 0);
|
||||
ret = rsnd_rdai_continuance_probe(priv, &rdai->capture);
|
||||
if (ret)
|
||||
goto exit_snd_probe;
|
||||
}
|
||||
@ -1295,8 +1279,8 @@ exit_snd_soc:
|
||||
snd_soc_unregister_platform(dev);
|
||||
exit_snd_probe:
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
rsnd_dai_call(remove, &rdai->playback, rdai);
|
||||
rsnd_dai_call(remove, &rdai->capture, rdai);
|
||||
rsnd_dai_call(remove, &rdai->playback, priv);
|
||||
rsnd_dai_call(remove, &rdai->capture, priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1311,10 +1295,13 @@ static int rsnd_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret |= rsnd_dai_call(remove, &rdai->playback, rdai);
|
||||
ret |= rsnd_dai_call(remove, &rdai->capture, rdai);
|
||||
ret |= rsnd_dai_call(remove, &rdai->playback, priv);
|
||||
ret |= rsnd_dai_call(remove, &rdai->capture, priv);
|
||||
}
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
struct rsnd_dvc {
|
||||
struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_mod mod;
|
||||
struct clk *clk;
|
||||
struct rsnd_kctrl_cfg_m volume;
|
||||
struct rsnd_kctrl_cfg_m mute;
|
||||
struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */
|
||||
@ -118,9 +117,8 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
|
||||
}
|
||||
|
||||
static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
|
||||
@ -129,12 +127,24 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
|
||||
rsnd_kctrl_remove(dvc->volume);
|
||||
rsnd_kctrl_remove(dvc->mute);
|
||||
rsnd_kctrl_remove(dvc->ren);
|
||||
rsnd_kctrl_remove(dvc->rup);
|
||||
rsnd_kctrl_remove(dvc->rdown);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod);
|
||||
struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int dvc_id = rsnd_mod_id(dvc_mod);
|
||||
@ -153,7 +163,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk_prepare_enable(dvc->clk);
|
||||
rsnd_mod_hw_start(dvc_mod);
|
||||
|
||||
/*
|
||||
* fixme
|
||||
@ -173,23 +183,21 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
|
||||
|
||||
rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io);
|
||||
rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
|
||||
clk_disable_unprepare(dvc->clk);
|
||||
rsnd_mod_hw_stop(mod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0x10);
|
||||
|
||||
@ -197,7 +205,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_dvc_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0);
|
||||
|
||||
@ -205,16 +213,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
int is_play = rsnd_io_is_play(io);
|
||||
int ret;
|
||||
|
||||
/* Volume */
|
||||
ret = rsnd_kctrl_new_m(mod, rdai, rtd,
|
||||
rsnd_dai_is_play(rdai, io) ?
|
||||
ret = rsnd_kctrl_new_m(mod, rtd,
|
||||
is_play ?
|
||||
"DVC Out Playback Volume" : "DVC In Capture Volume",
|
||||
rsnd_dvc_volume_update,
|
||||
&dvc->volume, 0x00800000 - 1);
|
||||
@ -222,8 +230,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
return ret;
|
||||
|
||||
/* Mute */
|
||||
ret = rsnd_kctrl_new_m(mod, rdai, rtd,
|
||||
rsnd_dai_is_play(rdai, io) ?
|
||||
ret = rsnd_kctrl_new_m(mod, rtd,
|
||||
is_play ?
|
||||
"DVC Out Mute Switch" : "DVC In Mute Switch",
|
||||
rsnd_dvc_volume_update,
|
||||
&dvc->mute, 1);
|
||||
@ -231,16 +239,16 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
return ret;
|
||||
|
||||
/* Ramp */
|
||||
ret = rsnd_kctrl_new_s(mod, rdai, rtd,
|
||||
rsnd_dai_is_play(rdai, io) ?
|
||||
ret = rsnd_kctrl_new_s(mod, rtd,
|
||||
is_play ?
|
||||
"DVC Out Ramp Switch" : "DVC In Ramp Switch",
|
||||
rsnd_dvc_volume_update,
|
||||
&dvc->ren, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_kctrl_new_e(mod, rdai, rtd,
|
||||
rsnd_dai_is_play(rdai, io) ?
|
||||
ret = rsnd_kctrl_new_e(mod, rtd,
|
||||
is_play ?
|
||||
"DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
|
||||
&dvc->rup,
|
||||
rsnd_dvc_volume_update,
|
||||
@ -248,8 +256,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_kctrl_new_e(mod, rdai, rtd,
|
||||
rsnd_dai_is_play(rdai, io) ?
|
||||
ret = rsnd_kctrl_new_e(mod, rtd,
|
||||
is_play ?
|
||||
"DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
|
||||
&dvc->rdown,
|
||||
rsnd_dvc_volume_update,
|
||||
@ -264,6 +272,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
static struct rsnd_mod_ops rsnd_dvc_ops = {
|
||||
.name = DVC_NAME,
|
||||
.probe = rsnd_dvc_probe_gen2,
|
||||
.remove = rsnd_dvc_remove_gen2,
|
||||
.init = rsnd_dvc_init,
|
||||
.quit = rsnd_dvc_quit,
|
||||
.start = rsnd_dvc_start,
|
||||
@ -356,9 +365,9 @@ int rsnd_dvc_probe(struct platform_device *pdev,
|
||||
return PTR_ERR(clk);
|
||||
|
||||
dvc->info = &info->dvc_info[i];
|
||||
dvc->clk = clk;
|
||||
|
||||
rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i);
|
||||
rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
|
||||
clk, RSND_MOD_DVC, i);
|
||||
|
||||
dev_dbg(dev, "CMD%d probed\n", i);
|
||||
}
|
||||
|
@ -309,8 +309,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
|
||||
RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20),
|
||||
RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
|
||||
RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
|
||||
RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
|
||||
RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
|
||||
RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
|
||||
RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
|
||||
RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
|
||||
RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
|
||||
RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4),
|
||||
RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40),
|
||||
RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40),
|
||||
RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40),
|
||||
@ -403,6 +408,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
|
||||
RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40),
|
||||
RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
|
||||
RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40),
|
||||
/*
|
||||
* ADD US
|
||||
*
|
||||
* SRC_STATUS
|
||||
* SRC_INT_EN
|
||||
* SCU_SYS_STATUS0
|
||||
* SCU_SYS_STATUS1
|
||||
* SCU_SYS_INT_EN0
|
||||
* SCU_SYS_INT_EN1
|
||||
*/
|
||||
};
|
||||
struct rsnd_regmap_field_conf conf_adg[] = {
|
||||
RSND_GEN_S_REG(BRRA, 0x00),
|
||||
|
@ -44,6 +44,8 @@ enum rsnd_reg {
|
||||
RSND_REG_SRC_IFSCR,
|
||||
RSND_REG_SRC_IFSVR,
|
||||
RSND_REG_SRC_SRCCR,
|
||||
RSND_REG_SCU_SYS_STATUS0,
|
||||
RSND_REG_SCU_SYS_INT_EN0,
|
||||
RSND_REG_CMD_ROUTE_SLCT,
|
||||
RSND_REG_DVC_SWRSR,
|
||||
RSND_REG_DVC_DVUIR,
|
||||
@ -94,6 +96,9 @@ enum rsnd_reg {
|
||||
RSND_REG_SHARE23,
|
||||
RSND_REG_SHARE24,
|
||||
RSND_REG_SHARE25,
|
||||
RSND_REG_SHARE26,
|
||||
RSND_REG_SHARE27,
|
||||
RSND_REG_SHARE28,
|
||||
|
||||
RSND_REG_MAX,
|
||||
};
|
||||
@ -135,6 +140,9 @@ enum rsnd_reg {
|
||||
#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
|
||||
#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
|
||||
#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
|
||||
#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26
|
||||
#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27
|
||||
#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28
|
||||
|
||||
struct rsnd_of_data;
|
||||
struct rsnd_priv;
|
||||
@ -182,9 +190,9 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
|
||||
* R-Car sound mod
|
||||
*/
|
||||
enum rsnd_mod_type {
|
||||
RSND_MOD_SRC = 0,
|
||||
RSND_MOD_DVC = 0,
|
||||
RSND_MOD_SRC,
|
||||
RSND_MOD_SSI,
|
||||
RSND_MOD_DVC,
|
||||
RSND_MOD_MAX,
|
||||
};
|
||||
|
||||
@ -192,32 +200,31 @@ struct rsnd_mod_ops {
|
||||
char *name;
|
||||
char* (*dma_name)(struct rsnd_mod *mod);
|
||||
int (*probe)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*remove)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*init)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*quit)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*start)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*stop)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
int (*pcm_new)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd);
|
||||
int (*fallback)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
struct rsnd_priv *priv);
|
||||
};
|
||||
|
||||
struct rsnd_dai_stream;
|
||||
struct rsnd_mod {
|
||||
int id;
|
||||
enum rsnd_mod_type type;
|
||||
struct rsnd_priv *priv;
|
||||
struct rsnd_mod_ops *ops;
|
||||
struct rsnd_dma dma;
|
||||
struct rsnd_dai_stream *io;
|
||||
struct clk *clk;
|
||||
u32 status;
|
||||
};
|
||||
/*
|
||||
@ -248,15 +255,17 @@ struct rsnd_mod {
|
||||
#define __rsnd_mod_call_pcm_new 0
|
||||
#define __rsnd_mod_call_fallback 0
|
||||
|
||||
#define rsnd_mod_to_priv(mod) ((mod)->priv)
|
||||
#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod)))
|
||||
#define rsnd_mod_to_dma(mod) (&(mod)->dma)
|
||||
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
|
||||
#define rsnd_mod_to_io(mod) ((mod)->io)
|
||||
#define rsnd_mod_id(mod) ((mod)->id)
|
||||
#define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk)
|
||||
#define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk)
|
||||
|
||||
void rsnd_mod_init(struct rsnd_priv *priv,
|
||||
struct rsnd_mod *mod,
|
||||
void rsnd_mod_init(struct rsnd_mod *mod,
|
||||
struct rsnd_mod_ops *ops,
|
||||
struct clk *clk,
|
||||
enum rsnd_mod_type type,
|
||||
int id);
|
||||
char *rsnd_mod_name(struct rsnd_mod *mod);
|
||||
@ -270,6 +279,7 @@ struct rsnd_dai_stream {
|
||||
struct snd_pcm_substream *substream;
|
||||
struct rsnd_mod *mod[RSND_MOD_MAX];
|
||||
struct rsnd_dai_path_info *info; /* rcar_snd.h */
|
||||
struct rsnd_dai *rdai;
|
||||
int byte_pos;
|
||||
int period_pos;
|
||||
int byte_per_period;
|
||||
@ -278,12 +288,18 @@ struct rsnd_dai_stream {
|
||||
#define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI])
|
||||
#define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC])
|
||||
#define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC])
|
||||
#define rsnd_io_to_rdai(io) ((io)->rdai)
|
||||
#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
|
||||
#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
|
||||
#define rsnd_io_to_runtime(io) ((io)->substream ? \
|
||||
(io)->substream->runtime : NULL)
|
||||
|
||||
|
||||
struct rsnd_dai {
|
||||
char name[RSND_DAI_NAME_SIZE];
|
||||
struct rsnd_dai_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_dai_stream playback;
|
||||
struct rsnd_dai_stream capture;
|
||||
struct rsnd_priv *priv;
|
||||
|
||||
unsigned int clk_master:1;
|
||||
unsigned int bit_clk_inv:1;
|
||||
@ -293,22 +309,18 @@ struct rsnd_dai {
|
||||
};
|
||||
|
||||
#define rsnd_rdai_nr(priv) ((priv)->rdai_nr)
|
||||
#define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master)
|
||||
#define rsnd_rdai_to_priv(rdai) ((rdai)->priv)
|
||||
#define for_each_rsnd_dai(rdai, priv, i) \
|
||||
for (i = 0; \
|
||||
(i < rsnd_rdai_nr(priv)) && \
|
||||
((rdai) = rsnd_dai_get(priv, i)); \
|
||||
((rdai) = rsnd_rdai_get(priv, i)); \
|
||||
i++)
|
||||
|
||||
struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
|
||||
int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
|
||||
int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
|
||||
#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
|
||||
#define rsnd_io_to_runtime(io) ((io)->substream ? \
|
||||
(io)->substream->runtime : NULL)
|
||||
struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id);
|
||||
|
||||
void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
|
||||
int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
|
||||
#define rsnd_dai_is_clk_master(rdai) ((rdai)->clk_master)
|
||||
|
||||
/*
|
||||
* R-Car Gen1/Gen2
|
||||
@ -339,15 +351,12 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
|
||||
unsigned int src_rate,
|
||||
unsigned int dst_rate);
|
||||
int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io,
|
||||
unsigned int src_rate,
|
||||
unsigned int dst_rate);
|
||||
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io);
|
||||
|
||||
/*
|
||||
@ -427,6 +436,8 @@ struct rsnd_kctrl_cfg {
|
||||
u32 *val;
|
||||
const char * const *texts;
|
||||
void (*update)(struct rsnd_mod *mod);
|
||||
struct snd_card *card;
|
||||
struct snd_kcontrol *kctrl;
|
||||
};
|
||||
|
||||
#define RSND_DVC_CHANNELS 2
|
||||
@ -440,22 +451,22 @@ struct rsnd_kctrl_cfg_s {
|
||||
u32 val;
|
||||
};
|
||||
|
||||
void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg);
|
||||
#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg))
|
||||
|
||||
int rsnd_kctrl_new_m(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
void (*update)(struct rsnd_mod *mod),
|
||||
struct rsnd_kctrl_cfg_m *_cfg,
|
||||
u32 max);
|
||||
int rsnd_kctrl_new_s(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
void (*update)(struct rsnd_mod *mod),
|
||||
struct rsnd_kctrl_cfg_s *_cfg,
|
||||
u32 max);
|
||||
int rsnd_kctrl_new_e(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
const unsigned char *name,
|
||||
struct rsnd_kctrl_cfg_s *_cfg,
|
||||
@ -474,14 +485,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
|
||||
struct rsnd_dai_stream *io,
|
||||
struct snd_pcm_runtime *runtime);
|
||||
int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
int use_busif);
|
||||
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai);
|
||||
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai);
|
||||
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai);
|
||||
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod);
|
||||
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod);
|
||||
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
|
||||
|
||||
#define rsnd_src_nr(priv) ((priv)->src_nr)
|
||||
|
||||
|
@ -12,10 +12,17 @@
|
||||
|
||||
#define SRC_NAME "src"
|
||||
|
||||
/* SRCx_STATUS */
|
||||
#define OUF_SRCO ((1 << 12) | (1 << 13))
|
||||
#define OUF_SRCI ((1 << 9) | (1 << 8))
|
||||
|
||||
/* SCU_SYSTEM_STATUS0/1 */
|
||||
#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id))
|
||||
|
||||
struct rsnd_src {
|
||||
struct rsnd_src_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_mod mod;
|
||||
struct clk *clk;
|
||||
int err;
|
||||
};
|
||||
|
||||
#define RSND_SRC_NAME_SIZE 16
|
||||
@ -107,10 +114,10 @@ struct rsnd_src {
|
||||
* Gen1/Gen2 common functions
|
||||
*/
|
||||
int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
int use_busif)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
|
||||
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
int ssi_id = rsnd_mod_id(ssi_mod);
|
||||
|
||||
@ -140,7 +147,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||
if (shift >= 0)
|
||||
rsnd_mod_bset(ssi_mod, SSI_MODE1,
|
||||
0x3 << shift,
|
||||
rsnd_dai_is_clk_master(rdai) ?
|
||||
rsnd_rdai_is_clk_master(rdai) ?
|
||||
0x2 << shift : 0x1 << shift);
|
||||
}
|
||||
|
||||
@ -174,8 +181,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod)
|
||||
{
|
||||
/*
|
||||
* DMA settings for SSIU
|
||||
@ -185,8 +191,7 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
|
||||
|
||||
@ -202,8 +207,7 @@ int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
|
||||
|
||||
@ -240,8 +244,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
@ -273,12 +276,13 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_src_init(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_init(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
clk_prepare_enable(src->clk);
|
||||
rsnd_mod_hw_start(mod);
|
||||
|
||||
src->err = 0;
|
||||
|
||||
/*
|
||||
* Initialize the operation of the SRC internal circuits
|
||||
@ -290,11 +294,16 @@ static int rsnd_src_init(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
clk_disable_unprepare(src->clk);
|
||||
rsnd_mod_hw_stop(mod);
|
||||
|
||||
if (src->err)
|
||||
dev_warn(dev, "%s[%d] under/over flow err = %d\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -319,8 +328,7 @@ static int rsnd_src_stop(struct rsnd_mod *mod)
|
||||
/*
|
||||
* Gen1 functions
|
||||
*/
|
||||
static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_set_route_gen1(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct src_route_config {
|
||||
@ -348,7 +356,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
|
||||
/*
|
||||
* SRC_ROUTE_SELECT
|
||||
*/
|
||||
val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
|
||||
val = rsnd_io_is_play(io) ? 0x1 : 0x2;
|
||||
val = val << routes[id].shift;
|
||||
mask = routes[id].mask << routes[id].shift;
|
||||
|
||||
@ -357,8 +365,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
@ -416,13 +423,12 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai);
|
||||
ret = rsnd_src_set_convert_rate(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -443,9 +449,8 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
|
||||
@ -455,23 +460,23 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_init_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_init(mod, rdai);
|
||||
ret = rsnd_src_init(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_route_gen1(mod, rdai);
|
||||
ret = rsnd_src_set_route_gen1(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate_gen1(mod, rdai);
|
||||
ret = rsnd_src_set_convert_rate_gen1(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_timing_gen1(mod, rdai);
|
||||
ret = rsnd_src_set_convert_timing_gen1(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -479,7 +484,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_start_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
|
||||
@ -489,7 +494,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
|
||||
@ -510,8 +515,111 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = {
|
||||
/*
|
||||
* Gen2 functions
|
||||
*/
|
||||
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
|
||||
#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
|
||||
static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 sys_int_val, int_val, sys_int_mask;
|
||||
int irq = src->info->irq;
|
||||
int id = rsnd_mod_id(mod);
|
||||
|
||||
sys_int_val =
|
||||
sys_int_mask = OUF_SRC(id);
|
||||
int_val = 0x3300;
|
||||
|
||||
/*
|
||||
* IRQ is not supported on non-DT
|
||||
* see
|
||||
* rsnd_src_probe_gen2()
|
||||
*/
|
||||
if ((irq <= 0) || !enable) {
|
||||
sys_int_val = 0;
|
||||
int_val = 0;
|
||||
}
|
||||
|
||||
rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
|
||||
rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
|
||||
rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
|
||||
}
|
||||
|
||||
static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
u32 val = OUF_SRC(rsnd_mod_id(mod));
|
||||
|
||||
rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val);
|
||||
rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
|
||||
}
|
||||
|
||||
static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
u32 val = OUF_SRC(rsnd_mod_id(mod));
|
||||
bool ret = false;
|
||||
|
||||
if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) ||
|
||||
(rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) {
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
src->err++;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
/* clear error static */
|
||||
rsnd_src_error_clear_gen2(mod);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _rsnd_src_start_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
|
||||
|
||||
rsnd_mod_write(mod, SRC_CTRL, val);
|
||||
|
||||
rsnd_src_error_clear_gen2(mod);
|
||||
|
||||
rsnd_src_start(mod);
|
||||
|
||||
rsnd_src_irq_enable_gen2(mod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
rsnd_src_irq_disable_gen2(mod);
|
||||
|
||||
rsnd_mod_write(mod, SRC_CTRL, 0);
|
||||
|
||||
rsnd_src_error_record_gen2(mod);
|
||||
|
||||
return rsnd_src_stop(mod);
|
||||
}
|
||||
|
||||
static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
|
||||
{
|
||||
struct rsnd_mod *mod = data;
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
|
||||
if (!io)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (rsnd_src_error_record_gen2(mod)) {
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
_rsnd_src_stop_gen2(mod);
|
||||
_rsnd_src_start_gen2(mod);
|
||||
|
||||
dev_dbg(dev, "%s[%d] restart\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
@ -535,7 +643,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai);
|
||||
ret = rsnd_src_set_convert_rate(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -563,8 +671,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
@ -573,59 +680,78 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
int ret;
|
||||
|
||||
if (convert_rate)
|
||||
ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io,
|
||||
ret = rsnd_adg_set_convert_clk_gen2(mod, io,
|
||||
runtime->rate,
|
||||
convert_rate);
|
||||
else
|
||||
ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io);
|
||||
ret = rsnd_adg_set_convert_timing_gen2(mod, io);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int irq = src->info->irq;
|
||||
int ret;
|
||||
|
||||
if (irq > 0) {
|
||||
/*
|
||||
* IRQ is not supported on non-DT
|
||||
* see
|
||||
* rsnd_src_irq_enable_gen2()
|
||||
*/
|
||||
ret = devm_request_irq(dev, irq,
|
||||
rsnd_src_interrupt_gen2,
|
||||
IRQF_SHARED,
|
||||
dev_name(dev), mod);
|
||||
if (ret)
|
||||
goto rsnd_src_probe_gen2_fail;
|
||||
}
|
||||
|
||||
ret = rsnd_dma_init(priv,
|
||||
rsnd_mod_to_dma(mod),
|
||||
rsnd_info_is_playback(priv, src),
|
||||
src->info->dma_id);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "%s[%d] (Gen2) failed\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
else
|
||||
dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
if (ret)
|
||||
goto rsnd_src_probe_gen2_fail;
|
||||
|
||||
dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
|
||||
return ret;
|
||||
|
||||
rsnd_src_probe_gen2_fail:
|
||||
dev_err(dev, "%s[%d] (Gen2) failed\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
|
||||
rsnd_dma_quit(priv, rsnd_mod_to_dma(mod));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_src_init_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_init(mod, rdai);
|
||||
ret = rsnd_src_init(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate_gen2(mod, rdai);
|
||||
ret = rsnd_src_set_convert_rate_gen2(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_timing_gen2(mod, rdai);
|
||||
ret = rsnd_src_set_convert_timing_gen2(mod);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -633,29 +759,23 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_src_start_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
|
||||
rsnd_dma_start(rsnd_mod_to_dma(mod));
|
||||
|
||||
rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
|
||||
|
||||
rsnd_mod_write(mod, SRC_CTRL, val);
|
||||
|
||||
return rsnd_src_start(mod);
|
||||
return _rsnd_src_start_gen2(mod);
|
||||
}
|
||||
|
||||
static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
int ret;
|
||||
|
||||
rsnd_mod_write(mod, SRC_CTRL, 0);
|
||||
ret = _rsnd_src_stop_gen2(mod);
|
||||
|
||||
rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));
|
||||
rsnd_dma_stop(rsnd_mod_to_dma(mod));
|
||||
|
||||
return rsnd_src_stop(mod);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rsnd_mod_ops rsnd_src_gen2_ops = {
|
||||
@ -681,10 +801,11 @@ static void rsnd_of_parse_src(struct platform_device *pdev,
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct device_node *src_node;
|
||||
struct device_node *np;
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct rsnd_src_platform_info *src_info;
|
||||
struct device *dev = &pdev->dev;
|
||||
int nr;
|
||||
int nr, i;
|
||||
|
||||
if (!of_data)
|
||||
return;
|
||||
@ -708,6 +829,13 @@ static void rsnd_of_parse_src(struct platform_device *pdev,
|
||||
info->src_info = src_info;
|
||||
info->src_info_nr = nr;
|
||||
|
||||
i = 0;
|
||||
for_each_child_of_node(src_node, np) {
|
||||
src_info[i].irq = irq_of_parse_and_map(np, 0);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
rsnd_of_parse_src_end:
|
||||
of_node_put(src_node);
|
||||
}
|
||||
@ -761,9 +889,8 @@ int rsnd_src_probe(struct platform_device *pdev,
|
||||
return PTR_ERR(clk);
|
||||
|
||||
src->info = &info->src_info[i];
|
||||
src->clk = clk;
|
||||
|
||||
rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i);
|
||||
rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
|
||||
|
||||
dev_dbg(dev, "SRC%d probed\n", i);
|
||||
}
|
||||
|
@ -60,17 +60,14 @@
|
||||
#define SSI_NAME "ssi"
|
||||
|
||||
struct rsnd_ssi {
|
||||
struct clk *clk;
|
||||
struct rsnd_ssi_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_ssi *parent;
|
||||
struct rsnd_mod mod;
|
||||
|
||||
struct rsnd_dai *rdai;
|
||||
u32 cr_own;
|
||||
u32 cr_clk;
|
||||
int err;
|
||||
unsigned int usrcnt;
|
||||
unsigned int rate;
|
||||
};
|
||||
|
||||
#define for_each_rsnd_ssi(pos, priv, i) \
|
||||
@ -128,7 +125,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
|
||||
static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
|
||||
struct rsnd_priv *priv = rsnd_io_to_priv(io);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int i, j, ret;
|
||||
@ -157,7 +154,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
|
||||
|
||||
ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate);
|
||||
if (0 == ret) {
|
||||
ssi->rate = rate;
|
||||
ssi->cr_clk = FORCE | SWL_32 |
|
||||
SCKD | SWSD | CKDV(j);
|
||||
|
||||
@ -176,26 +172,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
|
||||
|
||||
static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi)
|
||||
{
|
||||
ssi->rate = 0;
|
||||
ssi->cr_clk = 0;
|
||||
rsnd_adg_ssi_clk_stop(&ssi->mod);
|
||||
}
|
||||
|
||||
static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
|
||||
struct rsnd_priv *priv = rsnd_io_to_priv(io);
|
||||
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
u32 cr_mode;
|
||||
u32 cr;
|
||||
|
||||
if (0 == ssi->usrcnt) {
|
||||
clk_prepare_enable(ssi->clk);
|
||||
rsnd_mod_hw_start(&ssi->mod);
|
||||
|
||||
if (rsnd_dai_is_clk_master(rdai)) {
|
||||
if (rsnd_rdai_is_clk_master(rdai)) {
|
||||
if (rsnd_ssi_clk_from_parent(ssi))
|
||||
rsnd_ssi_hw_start(ssi->parent, rdai, io);
|
||||
rsnd_ssi_hw_start(ssi->parent, io);
|
||||
else
|
||||
rsnd_ssi_master_clk_start(ssi, io);
|
||||
}
|
||||
@ -214,7 +209,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
|
||||
rsnd_mod_write(&ssi->mod, SSICR, cr);
|
||||
|
||||
/* enable WS continue */
|
||||
if (rsnd_dai_is_clk_master(rdai))
|
||||
if (rsnd_rdai_is_clk_master(rdai))
|
||||
rsnd_mod_write(&ssi->mod, SSIWSR, CONT);
|
||||
|
||||
/* clear error status */
|
||||
@ -226,10 +221,11 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
|
||||
rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
|
||||
}
|
||||
|
||||
static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
|
||||
struct rsnd_dai *rdai)
|
||||
static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod);
|
||||
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
u32 cr;
|
||||
|
||||
@ -256,14 +252,14 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
|
||||
rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */
|
||||
rsnd_ssi_status_check(&ssi->mod, IIRQ);
|
||||
|
||||
if (rsnd_dai_is_clk_master(rdai)) {
|
||||
if (rsnd_rdai_is_clk_master(rdai)) {
|
||||
if (rsnd_ssi_clk_from_parent(ssi))
|
||||
rsnd_ssi_hw_stop(ssi->parent, rdai);
|
||||
rsnd_ssi_hw_stop(ssi->parent);
|
||||
else
|
||||
rsnd_ssi_master_clk_stop(ssi);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(ssi->clk);
|
||||
rsnd_mod_hw_stop(&ssi->mod);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s[%d] hw stopped\n",
|
||||
@ -274,10 +270,11 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
|
||||
* SSI mod common functions
|
||||
*/
|
||||
static int rsnd_ssi_init(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
u32 cr;
|
||||
|
||||
@ -311,13 +308,12 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
|
||||
cr |= SDTA;
|
||||
if (rdai->sys_delay)
|
||||
cr |= DEL;
|
||||
if (rsnd_dai_is_play(rdai, io))
|
||||
if (rsnd_io_is_play(io))
|
||||
cr |= TRMD;
|
||||
|
||||
/*
|
||||
* set ssi parameter
|
||||
*/
|
||||
ssi->rdai = rdai;
|
||||
ssi->cr_own = cr;
|
||||
ssi->err = -1; /* ignore 1st error */
|
||||
|
||||
@ -325,16 +321,15 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_ssi_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
if (ssi->err > 0)
|
||||
dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
|
||||
dev_warn(dev, "%s[%d] under/over flow err = %d\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err);
|
||||
|
||||
ssi->rdai = NULL;
|
||||
ssi->cr_own = 0;
|
||||
ssi->err = 0;
|
||||
|
||||
@ -353,32 +348,32 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
|
||||
}
|
||||
|
||||
static int rsnd_ssi_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
|
||||
rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod));
|
||||
rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod));
|
||||
|
||||
rsnd_ssi_hw_start(ssi, rdai, io);
|
||||
rsnd_ssi_hw_start(ssi, io);
|
||||
|
||||
rsnd_src_ssi_irq_enable(mod, rdai);
|
||||
rsnd_src_ssi_irq_enable(mod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_ssi_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
|
||||
rsnd_src_ssi_irq_disable(mod, rdai);
|
||||
rsnd_src_ssi_irq_disable(mod);
|
||||
|
||||
rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
|
||||
|
||||
rsnd_ssi_hw_stop(ssi, rdai);
|
||||
rsnd_ssi_hw_stop(ssi);
|
||||
|
||||
rsnd_src_ssiu_stop(mod, rdai);
|
||||
rsnd_src_ssiu_stop(mod);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -386,16 +381,17 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
|
||||
static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
|
||||
{
|
||||
struct rsnd_ssi *ssi = data;
|
||||
struct rsnd_dai *rdai = ssi->rdai;
|
||||
struct rsnd_mod *mod = &ssi->mod;
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
int is_dma = rsnd_ssi_is_dma_mode(mod);
|
||||
u32 status = rsnd_mod_read(mod, SSISR);
|
||||
|
||||
if (!io)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* PIO only */
|
||||
if (status & DIRQ) {
|
||||
if (!is_dma && (status & DIRQ)) {
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
u32 *buf = (u32 *)(runtime->dma_area +
|
||||
rsnd_dai_pointer_offset(io, 0));
|
||||
@ -405,7 +401,7 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
|
||||
* directly as 32bit data
|
||||
* see rsnd_ssi_init()
|
||||
*/
|
||||
if (rsnd_dai_is_play(rdai, io))
|
||||
if (rsnd_io_is_play(io))
|
||||
rsnd_mod_write(mod, SSITDR, *buf);
|
||||
else
|
||||
*buf = rsnd_mod_read(mod, SSIRDR);
|
||||
@ -415,14 +411,13 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
|
||||
|
||||
/* PIO / DMA */
|
||||
if (status & (UIRQ | OIRQ)) {
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
* restart SSI
|
||||
*/
|
||||
rsnd_ssi_stop(mod, rdai);
|
||||
rsnd_ssi_start(mod, rdai);
|
||||
rsnd_ssi_stop(mod, priv);
|
||||
rsnd_ssi_start(mod, priv);
|
||||
|
||||
dev_dbg(dev, "%s[%d] restart\n",
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod));
|
||||
@ -437,9 +432,8 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
|
||||
* SSI PIO
|
||||
*/
|
||||
static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
int ret;
|
||||
@ -468,9 +462,8 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
|
||||
};
|
||||
|
||||
static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int dma_id = ssi->info->dma_id;
|
||||
@ -503,14 +496,13 @@ rsnd_ssi_dma_probe_fail:
|
||||
}
|
||||
|
||||
static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int irq = ssi->info->irq;
|
||||
|
||||
rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
|
||||
rsnd_dma_quit(priv, rsnd_mod_to_dma(mod));
|
||||
|
||||
/* PIO will request IRQ again */
|
||||
devm_free_irq(dev, irq, ssi);
|
||||
@ -519,9 +511,8 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_ssi_fallback(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
@ -540,25 +531,25 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod,
|
||||
}
|
||||
|
||||
static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
|
||||
|
||||
rsnd_ssi_start(mod, rdai);
|
||||
|
||||
rsnd_dma_start(dma);
|
||||
|
||||
rsnd_ssi_start(mod, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
|
||||
|
||||
rsnd_dma_stop(dma);
|
||||
rsnd_ssi_stop(mod, priv);
|
||||
|
||||
rsnd_ssi_stop(mod, rdai);
|
||||
rsnd_dma_stop(dma);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -734,7 +725,6 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
||||
return PTR_ERR(clk);
|
||||
|
||||
ssi->info = pinfo;
|
||||
ssi->clk = clk;
|
||||
|
||||
ops = &rsnd_ssi_non_ops;
|
||||
if (pinfo->dma_id > 0)
|
||||
@ -742,7 +732,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
||||
else if (rsnd_ssi_pio_available(ssi))
|
||||
ops = &rsnd_ssi_pio_ops;
|
||||
|
||||
rsnd_mod_init(priv, &ssi->mod, ops, RSND_MOD_SSI, i);
|
||||
rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i);
|
||||
|
||||
rsnd_ssi_parent_clk_setup(priv, ssi);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user