Commit 94e26c07 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next

parents 460f623a a5702e1c
...@@ -199,10 +199,10 @@ Ex) ...@@ -199,10 +199,10 @@ Ex)
sound { sound {
compatible = "simple-scu-audio-card"; compatible = "simple-scu-audio-card";
... ...
simple-audio-card,cpu@0 { simple-audio-card,cpu-0 {
sound-dai = <&rcar_sound 0>; sound-dai = <&rcar_sound 0>;
}; };
simple-audio-card,cpu@1 { simple-audio-card,cpu-1 {
sound-dai = <&rcar_sound 1>; sound-dai = <&rcar_sound 1>;
}; };
simple-audio-card,codec { simple-audio-card,codec {
...@@ -441,79 +441,79 @@ rcar_sound: sound@ec500000 { ...@@ -441,79 +441,79 @@ rcar_sound: sound@ec500000 {
"clk_a", "clk_b", "clk_c", "clk_i"; "clk_a", "clk_b", "clk_c", "clk_i";
rcar_sound,dvc { rcar_sound,dvc {
dvc0: dvc@0 { dvc0: dvc-0 {
dmas = <&audma0 0xbc>; dmas = <&audma0 0xbc>;
dma-names = "tx"; dma-names = "tx";
}; };
dvc1: dvc@1 { dvc1: dvc-1 {
dmas = <&audma0 0xbe>; dmas = <&audma0 0xbe>;
dma-names = "tx"; dma-names = "tx";
}; };
}; };
rcar_sound,mix { rcar_sound,mix {
mix0: mix@0 { }; mix0: mix-0 { };
mix1: mix@1 { }; mix1: mix-1 { };
}; };
rcar_sound,ctu { rcar_sound,ctu {
ctu00: ctu@0 { }; ctu00: ctu-0 { };
ctu01: ctu@1 { }; ctu01: ctu-1 { };
ctu02: ctu@2 { }; ctu02: ctu-2 { };
ctu03: ctu@3 { }; ctu03: ctu-3 { };
ctu10: ctu@4 { }; ctu10: ctu-4 { };
ctu11: ctu@5 { }; ctu11: ctu-5 { };
ctu12: ctu@6 { }; ctu12: ctu-6 { };
ctu13: ctu@7 { }; ctu13: ctu-7 { };
}; };
rcar_sound,src { rcar_sound,src {
src0: src@0 { src0: src-0 {
interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x85>, <&audma1 0x9a>; dmas = <&audma0 0x85>, <&audma1 0x9a>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src1: src@1 { src1: src-1 {
interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x87>, <&audma1 0x9c>; dmas = <&audma0 0x87>, <&audma1 0x9c>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src2: src@2 { src2: src-2 {
interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x89>, <&audma1 0x9e>; dmas = <&audma0 0x89>, <&audma1 0x9e>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src3: src@3 { src3: src-3 {
interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8b>, <&audma1 0xa0>; dmas = <&audma0 0x8b>, <&audma1 0xa0>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src4: src@4 { src4: src-4 {
interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8d>, <&audma1 0xb0>; dmas = <&audma0 0x8d>, <&audma1 0xb0>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src5: src@5 { src5: src-5 {
interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x8f>, <&audma1 0xb2>; dmas = <&audma0 0x8f>, <&audma1 0xb2>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src6: src@6 { src6: src-6 {
interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x91>, <&audma1 0xb4>; dmas = <&audma0 0x91>, <&audma1 0xb4>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src7: src@7 { src7: src-7 {
interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x93>, <&audma1 0xb6>; dmas = <&audma0 0x93>, <&audma1 0xb6>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src8: src@8 { src8: src-8 {
interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x95>, <&audma1 0xb8>; dmas = <&audma0 0x95>, <&audma1 0xb8>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
}; };
src9: src@9 { src9: src-9 {
interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x97>, <&audma1 0xba>; dmas = <&audma0 0x97>, <&audma1 0xba>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
...@@ -521,52 +521,52 @@ rcar_sound: sound@ec500000 { ...@@ -521,52 +521,52 @@ rcar_sound: sound@ec500000 {
}; };
rcar_sound,ssi { rcar_sound,ssi {
ssi0: ssi@0 { ssi0: ssi-0 {
interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi1: ssi@1 { ssi1: ssi-1 {
interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi2: ssi@2 { ssi2: ssi-2 {
interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi3: ssi@3 { ssi3: ssi-3 {
interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi4: ssi@4 { ssi4: ssi-4 {
interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi5: ssi@5 { ssi5: ssi-5 {
interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi6: ssi@6 { ssi6: ssi-6 {
interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi7: ssi@7 { ssi7: ssi-7 {
interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi8: ssi@8 { ssi8: ssi-8 {
interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
}; };
ssi9: ssi@9 { ssi9: ssi-9 {
interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
dma-names = "rx", "tx", "rxu", "txu"; dma-names = "rx", "tx", "rxu", "txu";
......
...@@ -89,7 +89,7 @@ struct camelot_pcm { ...@@ -89,7 +89,7 @@ struct camelot_pcm {
#define DMABRG_PREALLOC_BUFFER 32 * 1024 #define DMABRG_PREALLOC_BUFFER 32 * 1024
#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024
static struct snd_pcm_hardware camelot_pcm_hardware = { static const struct snd_pcm_hardware camelot_pcm_hardware = {
.info = (SNDRV_PCM_INFO_MMAP | .info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
...@@ -294,7 +294,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) ...@@ -294,7 +294,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)
return bytes_to_frames(runtime, pos); return bytes_to_frames(runtime, pos);
} }
static struct snd_pcm_ops camelot_pcm_ops = { static const struct snd_pcm_ops camelot_pcm_ops = {
.open = camelot_pcm_open, .open = camelot_pcm_open,
.close = camelot_pcm_close, .close = camelot_pcm_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
...@@ -320,7 +320,7 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -320,7 +320,7 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
return 0; return 0;
} }
static struct snd_soc_platform_driver sh7760_soc_platform = { static const struct snd_soc_platform_driver sh7760_soc_platform = {
.ops = &camelot_pcm_ops, .ops = &camelot_pcm_ops,
.pcm_new = camelot_pcm_new, .pcm_new = camelot_pcm_new,
}; };
......
...@@ -1710,7 +1710,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = { ...@@ -1710,7 +1710,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = {
* pcm ops * pcm ops
*/ */
static struct snd_pcm_hardware fsi_pcm_hardware = { static const struct snd_pcm_hardware fsi_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED | .info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID, SNDRV_PCM_INFO_MMAP_VALID,
...@@ -1755,7 +1755,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) ...@@ -1755,7 +1755,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
return fsi_sample2frame(fsi, io->buff_sample_pos); return fsi_sample2frame(fsi, io->buff_sample_pos);
} }
static struct snd_pcm_ops fsi_pcm_ops = { static const struct snd_pcm_ops fsi_pcm_ops = {
.open = fsi_pcm_open, .open = fsi_pcm_open,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = fsi_hw_params, .hw_params = fsi_hw_params,
...@@ -1818,7 +1818,7 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { ...@@ -1818,7 +1818,7 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = {
}, },
}; };
static struct snd_soc_platform_driver fsi_soc_platform = { static const struct snd_soc_platform_driver fsi_soc_platform = {
.ops = &fsi_pcm_ops, .ops = &fsi_pcm_ops,
.pcm_new = fsi_pcm_new, .pcm_new = fsi_pcm_new,
}; };
......
...@@ -98,7 +98,7 @@ static int migor_hw_free(struct snd_pcm_substream *substream) ...@@ -98,7 +98,7 @@ static int migor_hw_free(struct snd_pcm_substream *substream)
return 0; return 0;
} }
static struct snd_soc_ops migor_dai_ops = { static const struct snd_soc_ops migor_dai_ops = {
.hw_params = migor_hw_params, .hw_params = migor_hw_params,
.hw_free = migor_hw_free, .hw_free = migor_hw_free,
}; };
......
...@@ -586,10 +586,8 @@ int rsnd_adg_probe(struct rsnd_priv *priv) ...@@ -586,10 +586,8 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
int ret; int ret;
adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
if (!adg) { if (!adg)
dev_err(dev, "ADG allocate failed\n");
return -ENOMEM; return -ENOMEM;
}
ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
NULL, NULL, 0, 0); NULL, NULL, 0, 0);
......
...@@ -843,12 +843,28 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, ...@@ -843,12 +843,28 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,
ir, &ic); ir, &ic);
} }
static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, static const struct snd_pcm_hardware rsnd_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
.buffer_bytes_max = 64 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8192,
.periods_min = 1,
.periods_max = 32,
.fifo_size = 256,
};
static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
struct snd_pcm_hw_constraint_list *constraint = &rdai->constraint; struct snd_pcm_hw_constraint_list *constraint = &rdai->constraint;
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int max_channels = rsnd_rdai_channels_get(rdai); unsigned int max_channels = rsnd_rdai_channels_get(rdai);
int ret;
int i; int i;
/* /*
...@@ -865,34 +881,26 @@ static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, ...@@ -865,34 +881,26 @@ static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime,
constraint->count = i + 1; constraint->count = i + 1;
} }
snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware);
snd_pcm_hw_constraint_list(runtime, 0, snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS, constraint); SNDRV_PCM_HW_PARAM_CHANNELS, constraint);
snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
/* /*
* Sampling Rate / Channel Limitation * Sampling Rate / Channel Limitation
* It depends on Clock Master Mode * It depends on Clock Master Mode
*/ */
if (!rsnd_rdai_is_clk_master(rdai)) if (rsnd_rdai_is_clk_master(rdai)) {
return;
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
rsnd_soc_hw_rule_rate, dai, rsnd_soc_hw_rule_rate, dai,
SNDRV_PCM_HW_PARAM_CHANNELS, -1); SNDRV_PCM_HW_PARAM_CHANNELS, -1);
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
rsnd_soc_hw_rule_channels, dai, rsnd_soc_hw_rule_channels, dai,
SNDRV_PCM_HW_PARAM_RATE, -1); SNDRV_PCM_HW_PARAM_RATE, -1);
} }
static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
int ret;
/* rsnd_io_to_runtime() is not yet enabled here */
rsnd_soc_hw_constraint(substream->runtime, dai);
/* /*
* call rsnd_dai_call without spinlock * call rsnd_dai_call without spinlock
...@@ -1104,31 +1112,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) ...@@ -1104,31 +1112,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
/* /*
* pcm ops * pcm ops
*/ */
static struct snd_pcm_hardware rsnd_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
.buffer_bytes_max = 64 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8192,
.periods_min = 1,
.periods_max = 32,
.fifo_size = 256,
};
static int rsnd_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
int ret = 0;
snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware);
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
return ret;
}
static int rsnd_hw_params(struct snd_pcm_substream *substream, static int rsnd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params) struct snd_pcm_hw_params *hw_params)
{ {
...@@ -1157,8 +1140,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) ...@@ -1157,8 +1140,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
return pointer; return pointer;
} }
static struct snd_pcm_ops rsnd_pcm_ops = { static const struct snd_pcm_ops rsnd_pcm_ops = {
.open = rsnd_pcm_open,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = rsnd_hw_params, .hw_params = rsnd_hw_params,
.hw_free = snd_pcm_lib_free_pages, .hw_free = snd_pcm_lib_free_pages,
...@@ -1168,11 +1150,10 @@ static struct snd_pcm_ops rsnd_pcm_ops = { ...@@ -1168,11 +1150,10 @@ static struct snd_pcm_ops rsnd_pcm_ops = {
/* /*
* snd_kcontrol * snd_kcontrol
*/ */
#define kcontrol_to_cfg(kctrl) ((struct rsnd_kctrl_cfg *)kctrl->private_value)
static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, static int rsnd_kctrl_info(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);
if (cfg->texts) { if (cfg->texts) {
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
...@@ -1198,7 +1179,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, ...@@ -1198,7 +1179,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl,
static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, static int rsnd_kctrl_get(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_value *uc) struct snd_ctl_elem_value *uc)
{ {
struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);
int i; int i;
for (i = 0; i < cfg->size; i++) for (i = 0; i < cfg->size; i++)
...@@ -1213,8 +1194,7 @@ static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, ...@@ -1213,8 +1194,7 @@ static int rsnd_kctrl_get(struct snd_kcontrol *kctrl,
static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_value *uc) struct snd_ctl_elem_value *uc)
{ {
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl);
struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl);
int i, change = 0; int i, change = 0;
if (!cfg->accept(cfg->io)) if (!cfg->accept(cfg->io))
...@@ -1231,7 +1211,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, ...@@ -1231,7 +1211,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
} }
if (change && cfg->update) if (change && cfg->update)
cfg->update(cfg->io, mod); cfg->update(cfg->io, cfg->mod);
return change; return change;
} }
...@@ -1283,14 +1263,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, ...@@ -1283,14 +1263,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
.index = rtd->num, .index = rtd->num,
.get = rsnd_kctrl_get, .get = rsnd_kctrl_get,
.put = rsnd_kctrl_put, .put = rsnd_kctrl_put,
.private_value = (unsigned long)cfg,
}; };
int ret; int ret;
if (size > RSND_MAX_CHANNELS) if (size > RSND_MAX_CHANNELS)
return -EINVAL; return -EINVAL;
kctrl = snd_ctl_new1(&knew, mod); kctrl = snd_ctl_new1(&knew, cfg);
if (!kctrl) if (!kctrl)
return -ENOMEM; return -ENOMEM;
...@@ -1306,6 +1285,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, ...@@ -1306,6 +1285,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
cfg->card = card; cfg->card = card;
cfg->kctrl = kctrl; cfg->kctrl = kctrl;
cfg->io = io; cfg->io = io;
cfg->mod = mod;
return 0; return 0;
} }
...@@ -1338,7 +1318,7 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -1338,7 +1318,7 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
} }
static struct snd_soc_platform_driver rsnd_soc_platform = { static const struct snd_soc_platform_driver rsnd_soc_platform = {
.ops = &rsnd_pcm_ops, .ops = &rsnd_pcm_ops,
.pcm_new = rsnd_pcm_new, .pcm_new = rsnd_pcm_new,
}; };
...@@ -1421,10 +1401,8 @@ static int rsnd_probe(struct platform_device *pdev) ...@@ -1421,10 +1401,8 @@ static int rsnd_probe(struct platform_device *pdev)
* init priv data * init priv data
*/ */
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv)
dev_err(dev, "priv allocate failed\n");
return -ENODEV; return -ENODEV;
}
priv->pdev = pdev; priv->pdev = pdev;
priv->flags = (unsigned long)of_device_get_match_data(dev); priv->flags = (unsigned long)of_device_get_match_data(dev);
......
...@@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) ...@@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
clk = devm_clk_get(dev, name); clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
of_node_put(np);
goto rsnd_ctu_probe_done; goto rsnd_ctu_probe_done;
} }
ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
clk, rsnd_mod_get_status, RSND_MOD_CTU, i); clk, rsnd_mod_get_status, RSND_MOD_CTU, i);
if (ret) if (ret) {
of_node_put(np);
goto rsnd_ctu_probe_done; goto rsnd_ctu_probe_done;
}
i++; i++;
} }
......
...@@ -604,8 +604,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, ...@@ -604,8 +604,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
dma_addr_t in_addr; dma_addr_t in_addr;
} dma_addrs[3][2][3] = { } dma_addrs[3][2][3] = {
/* SRC */ /* SRC */
{{{ 0, 0 },
/* Capture */ /* Capture */
{{{ 0, 0 },
{ RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
{ RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
/* Playback */ /* Playback */
......
...@@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) ...@@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
clk = devm_clk_get(dev, name); clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
of_node_put(np);
goto rsnd_dvc_probe_done; goto rsnd_dvc_probe_done;
} }
ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
clk, rsnd_mod_get_status, RSND_MOD_DVC, i); clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
if (ret) if (ret) {
of_node_put(np);
goto rsnd_dvc_probe_done; goto rsnd_dvc_probe_done;
}
i++; i++;
} }
......
...@@ -406,10 +406,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv) ...@@ -406,10 +406,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv)
int ret; int ret;
gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
if (!gen) { if (!gen)
dev_err(dev, "GEN allocate failed\n");
return -ENOMEM; return -ENOMEM;
}
priv->gen = gen; priv->gen = gen;
......
...@@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv) ...@@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
clk = devm_clk_get(dev, name); clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
of_node_put(np);
goto rsnd_mix_probe_done; goto rsnd_mix_probe_done;
} }
ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
clk, rsnd_mod_get_status, RSND_MOD_MIX, i); clk, rsnd_mod_get_status, RSND_MOD_MIX, i);
if (ret) if (ret) {
of_node_put(np);
goto rsnd_mix_probe_done; goto rsnd_mix_probe_done;
}
i++; i++;
} }
......
...@@ -614,6 +614,7 @@ struct rsnd_kctrl_cfg { ...@@ -614,6 +614,7 @@ struct rsnd_kctrl_cfg {
struct rsnd_dai_stream *io; struct rsnd_dai_stream *io;
struct snd_card *card; struct snd_card *card;
struct snd_kcontrol *kctrl; struct snd_kcontrol *kctrl;
struct rsnd_mod *mod;
}; };
#define RSND_MAX_CHANNELS 8 #define RSND_MAX_CHANNELS 8
......
...@@ -27,7 +27,6 @@ struct rsnd_src { ...@@ -27,7 +27,6 @@ struct rsnd_src {
#define RSND_SRC_NAME_SIZE 16 #define RSND_SRC_NAME_SIZE 16
#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id) #define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
#define rsnd_src_to_dma(src) ((src)->dma)
#define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_src_nr(priv) ((priv)->src_nr)
#define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val) #define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val)
...@@ -108,7 +107,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, ...@@ -108,7 +107,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
int is_play = rsnd_io_is_play(io); int is_play = rsnd_io_is_play(io);
/* /*
*
* Playback * Playback
* runtime_rate -> [SRC] -> convert_rate * runtime_rate -> [SRC] -> convert_rate
* *
...@@ -581,20 +579,24 @@ int rsnd_src_probe(struct rsnd_priv *priv) ...@@ -581,20 +579,24 @@ int rsnd_src_probe(struct rsnd_priv *priv)
src->irq = irq_of_parse_and_map(np, 0); src->irq = irq_of_parse_and_map(np, 0);
if (!src->irq) { if (!src->irq) {
ret = -EINVAL; ret = -EINVAL;
of_node_put(np);
goto rsnd_src_probe_done; goto rsnd_src_probe_done;
} }
clk = devm_clk_get(dev, name); clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
of_node_put(np);
goto rsnd_src_probe_done; goto rsnd_src_probe_done;
} }
ret = rsnd_mod_init(priv, rsnd_mod_get(src), ret = rsnd_mod_init(priv, rsnd_mod_get(src),
&rsnd_src_ops, clk, rsnd_mod_get_status, &rsnd_src_ops, clk, rsnd_mod_get_status,
RSND_MOD_SRC, i); RSND_MOD_SRC, i);
if (ret) if (ret) {
of_node_put(np);
goto rsnd_src_probe_done; goto rsnd_src_probe_done;
}
skip: skip:
i++; i++;
......
...@@ -90,6 +90,7 @@ struct rsnd_ssi { ...@@ -90,6 +90,7 @@ struct rsnd_ssi {
#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ #define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */
#define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */ #define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */
#define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */ #define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */
#define RSND_SSI_PROBED (1 << 4)
#define for_each_rsnd_ssi(pos, priv, i) \ #define for_each_rsnd_ssi(pos, priv, i) \
for (i = 0; \ for (i = 0; \
...@@ -98,25 +99,27 @@ struct rsnd_ssi { ...@@ -98,25 +99,27 @@ struct rsnd_ssi {
i++) i++)
#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id) #define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
#define rsnd_ssi_to_dma(mod) ((ssi)->dma)
#define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
#define rsnd_ssi_mode_flags(p) ((p)->flags) #define rsnd_ssi_flags_has(p, f) ((p)->flags & f)
#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f)
#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f))
#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
#define rsnd_ssi_is_multi_slave(mod, io) \ #define rsnd_ssi_is_multi_slave(mod, io) \
(rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod))) (rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))
#define rsnd_ssi_is_run_mods(mod, io) \ #define rsnd_ssi_is_run_mods(mod, io) \
(rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod))) (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod)))
#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod))
int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io) int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io)
{ {
struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI0) if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI0))
return RSND_SSI_HDMI_PORT0; return RSND_SSI_HDMI_PORT0;
if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI1) if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI1))
return RSND_SSI_HDMI_PORT1; return RSND_SSI_HDMI_PORT1;
return 0; return 0;
...@@ -131,7 +134,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) ...@@ -131,7 +134,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
if (!rsnd_ssi_is_dma_mode(mod)) if (!rsnd_ssi_is_dma_mode(mod))
return 0; return 0;
if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) if (!(rsnd_ssi_flags_has(ssi, RSND_SSI_NO_BUSIF)))
use_busif = 1; use_busif = 1;
if (rsnd_io_to_mod_src(io)) if (rsnd_io_to_mod_src(io))
use_busif = 1; use_busif = 1;
...@@ -256,7 +259,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, ...@@ -256,7 +259,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
int chan = rsnd_runtime_channel_for_ssi(io); int chan = rsnd_runtime_channel_for_ssi(io);
int idx, ret; int idx, ret;
unsigned int main_rate; unsigned int main_rate;
...@@ -267,7 +269,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, ...@@ -267,7 +269,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
if (!rsnd_rdai_is_clk_master(rdai)) if (!rsnd_rdai_is_clk_master(rdai))
return 0; return 0;
if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) if (!rsnd_ssi_can_output_clk(mod))
return 0; return 0;
if (rsnd_ssi_is_multi_slave(mod, io)) if (rsnd_ssi_is_multi_slave(mod, io))
...@@ -318,12 +320,11 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod, ...@@ -318,12 +320,11 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,
{ {
struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
if (!rsnd_rdai_is_clk_master(rdai)) if (!rsnd_rdai_is_clk_master(rdai))
return; return;
if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) if (!rsnd_ssi_can_output_clk(mod))
return; return;
if (ssi->usrcnt > 1) if (ssi->usrcnt > 1)
...@@ -346,6 +347,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, ...@@ -346,6 +347,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
u32 wsr; u32 wsr;
int is_tdm; int is_tdm;
if (rsnd_ssi_is_parent(mod, io))
return;
is_tdm = rsnd_runtime_is_ssi_tdm(io); is_tdm = rsnd_runtime_is_ssi_tdm(io);
/* /*
...@@ -484,7 +488,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ...@@ -484,7 +488,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!rsnd_ssi_is_parent(mod, io))
rsnd_ssi_config_init(mod, io); rsnd_ssi_config_init(mod, io);
rsnd_ssi_register_setup(mod); rsnd_ssi_register_setup(mod);
...@@ -782,15 +785,47 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, ...@@ -782,15 +785,47 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
/* /*
* SSI might be called again as PIO fallback * SSI might be called again as PIO fallback
* It is easy to manual handling for IRQ request/free * It is easy to manual handling for IRQ request/free
*
* OTOH, this function might be called many times if platform is
* using MIX. It needs xxx_attach() many times on xxx_probe().
* Because of it, we can't control .probe/.remove calling count by
* mod->status.
* But it don't need to call request_irq() many times.
* Let's control it by RSND_SSI_PROBED flag.
*/ */
if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
ret = request_irq(ssi->irq, ret = request_irq(ssi->irq,
rsnd_ssi_interrupt, rsnd_ssi_interrupt,
IRQF_SHARED, IRQF_SHARED,
dev_name(dev), mod); dev_name(dev), mod);
rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED);
}
return ret; return ret;
} }
static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);
/* Do nothing if non SSI (= SSI parent, multi SSI) mod */
if (pure_ssi_mod != mod)
return 0;
/* PIO will request IRQ again */
if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
free_irq(ssi->irq, mod);
rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED);
}
return 0;
}
static int rsnd_ssi_pointer(struct rsnd_mod *mod, static int rsnd_ssi_pointer(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
snd_pcm_uframes_t *pointer) snd_pcm_uframes_t *pointer)
...@@ -806,6 +841,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod, ...@@ -806,6 +841,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,
static struct rsnd_mod_ops rsnd_ssi_pio_ops = { static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
.name = SSI_NAME, .name = SSI_NAME,
.probe = rsnd_ssi_common_probe, .probe = rsnd_ssi_common_probe,
.remove = rsnd_ssi_common_remove,
.init = rsnd_ssi_init, .init = rsnd_ssi_init,
.quit = rsnd_ssi_quit, .quit = rsnd_ssi_quit,
.start = rsnd_ssi_start, .start = rsnd_ssi_start,
...@@ -840,23 +876,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, ...@@ -840,23 +876,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
return ret; return ret;
} }
static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);
/* Do nothing if non SSI (= SSI parent, multi SSI) mod */
if (pure_ssi_mod != mod)
return 0;
/* PIO will request IRQ again */
free_irq(ssi->irq, mod);
return 0;
}
static int rsnd_ssi_fallback(struct rsnd_mod *mod, static int rsnd_ssi_fallback(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
struct rsnd_priv *priv) struct rsnd_priv *priv)
...@@ -898,7 +917,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { ...@@ -898,7 +917,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
.name = SSI_NAME, .name = SSI_NAME,
.dma_req = rsnd_ssi_dma_req, .dma_req = rsnd_ssi_dma_req,
.probe = rsnd_ssi_dma_probe, .probe = rsnd_ssi_dma_probe,
.remove = rsnd_ssi_dma_remove, .remove = rsnd_ssi_common_remove,
.init = rsnd_ssi_init, .init = rsnd_ssi_init,
.quit = rsnd_ssi_quit, .quit = rsnd_ssi_quit,
.start = rsnd_ssi_start, .start = rsnd_ssi_start,
...@@ -984,13 +1003,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv, ...@@ -984,13 +1003,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
ssi = rsnd_mod_to_ssi(mod); ssi = rsnd_mod_to_ssi(mod);
if (strstr(remote_ep->full_name, "hdmi0")) { if (strstr(remote_ep->full_name, "hdmi0")) {
ssi->flags |= RSND_SSI_HDMI0; rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI0);
dev_dbg(dev, "%s[%d] connected to HDMI0\n", dev_dbg(dev, "%s[%d] connected to HDMI0\n",
rsnd_mod_name(mod), rsnd_mod_id(mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
} }
if (strstr(remote_ep->full_name, "hdmi1")) { if (strstr(remote_ep->full_name, "hdmi1")) {
ssi->flags |= RSND_SSI_HDMI1; rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI1);
dev_dbg(dev, "%s[%d] connected to HDMI1\n", dev_dbg(dev, "%s[%d] connected to HDMI1\n",
rsnd_mod_name(mod), rsnd_mod_id(mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
} }
...@@ -1023,7 +1042,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) ...@@ -1023,7 +1042,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
{ {
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); return !!(rsnd_ssi_flags_has(ssi, RSND_SSI_CLK_PIN_SHARE));
} }
static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io, static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io,
...@@ -1101,18 +1120,20 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ...@@ -1101,18 +1120,20 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
clk = devm_clk_get(dev, name); clk = devm_clk_get(dev, name);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
of_node_put(np);
goto rsnd_ssi_probe_done; goto rsnd_ssi_probe_done;
} }
if (of_get_property(np, "shared-pin", NULL)) if (of_get_property(np, "shared-pin", NULL))
ssi->flags |= RSND_SSI_CLK_PIN_SHARE; rsnd_ssi_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE);
if (of_get_property(np, "no-busif", NULL)) if (of_get_property(np, "no-busif", NULL))
ssi->flags |= RSND_SSI_NO_BUSIF; rsnd_ssi_flags_set(ssi, RSND_SSI_NO_BUSIF);
ssi->irq = irq_of_parse_and_map(np, 0); ssi->irq = irq_of_parse_and_map(np, 0);
if (!ssi->irq) { if (!ssi->irq) {
ret = -EINVAL; ret = -EINVAL;
of_node_put(np);
goto rsnd_ssi_probe_done; goto rsnd_ssi_probe_done;
} }
...@@ -1123,8 +1144,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ...@@ -1123,8 +1144,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
rsnd_ssi_get_status, RSND_MOD_SSI, i); rsnd_ssi_get_status, RSND_MOD_SSI, i);
if (ret) if (ret) {
of_node_put(np);
goto rsnd_ssi_probe_done; goto rsnd_ssi_probe_done;
}
i++; i++;
} }
......
...@@ -250,7 +250,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) ...@@ -250,7 +250,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
{ {
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_ssiu *ssiu; struct rsnd_ssiu *ssiu;
static struct rsnd_mod_ops *ops; struct rsnd_mod_ops *ops;
int i, nr, ret; int i, nr, ret;
/* same number to SSI */ /* same number to SSI */
......
...@@ -333,7 +333,7 @@ static void siu_dai_spbstop(struct siu_port *port_info) ...@@ -333,7 +333,7 @@ static void siu_dai_spbstop(struct siu_port *port_info)
/* API functions */ /* API functions */
/* Playback and capture hardware properties are identical */ /* Playback and capture hardware properties are identical */
static struct snd_pcm_hardware siu_dai_pcm_hw = { static const struct snd_pcm_hardware siu_dai_pcm_hw = {
.info = SNDRV_PCM_INFO_INTERLEAVED, .info = SNDRV_PCM_INFO_INTERLEAVED,
.formats = SNDRV_PCM_FMTBIT_S16, .formats = SNDRV_PCM_FMTBIT_S16,
.rates = SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_8000_48000,
......
...@@ -593,7 +593,7 @@ static void siu_pcm_free(struct snd_pcm *pcm) ...@@ -593,7 +593,7 @@ static void siu_pcm_free(struct snd_pcm *pcm)
dev_dbg(pcm->card->dev, "%s\n", __func__); dev_dbg(pcm->card->dev, "%s\n", __func__);
} }
static struct snd_pcm_ops siu_pcm_ops = { static const struct snd_pcm_ops siu_pcm_ops = {
.open = siu_pcm_open, .open = siu_pcm_open,
.close = siu_pcm_close, .close = siu_pcm_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
......
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