dai: supply caps and other info from within drivers

This change gathers some of the information inside of the DAI drivers,
which was previously inferred using external logic.

Signed-off-by: Slawomir Blauciak <slawomir.blauciak@linux.intel.com>
This commit is contained in:
Slawomir Blauciak 2019-04-30 14:01:33 +02:00 committed by Tomasz Lauda
parent 6e4faef8e7
commit 980171e607
15 changed files with 136 additions and 96 deletions

View File

@ -1,4 +1,4 @@
comp_func_map
dma_ops
dai_ops
dai_driver
freq_table

View File

@ -230,25 +230,12 @@ static struct comp_dev *dai_new(struct sof_ipc_comp *comp)
}
/* request GP LP DMA with shared access privilege */
/* TODO: hda: retrieve req'ed caps from the dai,
* dmas are not cross-compatible.
*/
switch (dai->type) {
case SOF_DAI_INTEL_HDA:
dir = dai->direction == SOF_IPC_STREAM_PLAYBACK ?
DMA_DIR_MEM_TO_DEV : DMA_DIR_DEV_TO_MEM;
caps = DMA_CAP_HDA;
dma_dev = DMA_DEV_HDA;
break;
case SOF_DAI_INTEL_SSP:
case SOF_DAI_INTEL_DMIC:
case SOF_DAI_INTEL_SOUNDWIRE:
default:
dir = DMA_DIR_MEM_TO_DEV | DMA_DIR_DEV_TO_MEM;
caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP;
dma_dev = DMA_DEV_SSP | DMA_DEV_DMIC | DMA_DEV_SOUNDWIRE;
break;
}
dir = dai->direction == SOF_IPC_STREAM_PLAYBACK ?
DMA_DIR_MEM_TO_DEV : DMA_DIR_DEV_TO_MEM;
caps = dai_get_info(dd->dai, DAI_INFO_DMA_CAPS);
dma_dev = dai_get_info(dd->dai, DAI_INFO_DMA_DEV);
dd->dma = dma_get(dir, caps, dma_dev, DMA_ACCESS_SHARED);
if (!dd->dma) {
trace_dai_error("dai_new() error: dma_get() failed to get "
@ -353,7 +340,7 @@ static int dai_capture_params(struct comp_dev *dev)
config->src_dev = dd->dai->plat_data.fifo[1].handshake;
/* TODO: Make this code platform-specific or move it driver callback */
if (dd->dai->type == SOF_DAI_INTEL_DMIC) {
if (dai_get_info(dd->dai, DAI_INFO_TYPE) == SOF_DAI_INTEL_DMIC) {
/* For DMIC the DMA src and dest widths should always be 4 bytes
* due to 32 bit FIFO packer. Setting width to 2 bytes for
* 16 bit format would result in recording at double rate.

View File

@ -592,10 +592,15 @@ static int ssp_probe(struct dai *dai)
return 0;
}
const struct dai_ops ssp_ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
const struct dai_driver ssp_driver = {
.type = SOF_DAI_INTEL_SSP,
.dma_caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP,
.dma_dev = DMA_DEV_SSP,
.ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
},
};

View File

@ -1579,13 +1579,18 @@ static int dmic_remove(struct dai *dai)
return 0;
}
const struct dai_ops dmic_ops = {
.trigger = dmic_trigger,
.set_config = dmic_set_config,
.pm_context_store = dmic_context_store,
.pm_context_restore = dmic_context_restore,
.probe = dmic_probe,
.remove = dmic_remove,
const struct dai_driver dmic_driver = {
.type = SOF_DAI_INTEL_DMIC,
.dma_caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP,
.dma_dev = DMA_DEV_DMIC,
.ops = {
.trigger = dmic_trigger,
.set_config = dmic_set_config,
.pm_context_store = dmic_context_store,
.pm_context_restore = dmic_context_restore,
.probe = dmic_probe,
.remove = dmic_remove,
},
};
#endif

View File

@ -47,11 +47,16 @@ static int hda_dummy(struct dai *dai)
return 0;
}
const struct dai_ops hda_ops = {
.trigger = hda_trigger,
.set_config = hda_set_config,
.pm_context_store = hda_dummy,
.pm_context_restore = hda_dummy,
.probe = hda_dummy,
.remove = hda_dummy,
const struct dai_driver hda_driver = {
.type = SOF_DAI_INTEL_HDA,
.dma_caps = DMA_CAP_HDA,
.dma_dev = DMA_DEV_HDA,
.ops = {
.trigger = hda_trigger,
.set_config = hda_set_config,
.pm_context_store = hda_dummy,
.pm_context_restore = hda_dummy,
.probe = hda_dummy,
.remove = hda_dummy,
},
};

View File

@ -89,11 +89,16 @@ static int soundwire_remove(struct dai *dai)
return 0;
}
const struct dai_ops soundwire_ops = {
.trigger = soundwire_trigger,
.set_config = soundwire_set_config,
.pm_context_store = soundwire_context_store,
.pm_context_restore = soundwire_context_restore,
.probe = soundwire_probe,
.remove = soundwire_remove,
const struct dai_driver soundwire_driver = {
.type = SOF_DAI_INTEL_SOUNDWIRE,
.dma_caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP,
.dma_dev = DMA_DEV_SOUNDWIRE,
.ops = {
.trigger = soundwire_trigger,
.set_config = soundwire_set_config,
.pm_context_store = soundwire_context_store,
.pm_context_restore = soundwire_context_restore,
.probe = soundwire_probe,
.remove = soundwire_remove,
},
};

View File

@ -877,11 +877,16 @@ static int ssp_remove(struct dai *dai)
return 0;
}
const struct dai_ops ssp_ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
.remove = ssp_remove,
const struct dai_driver ssp_driver = {
.type = SOF_DAI_INTEL_SSP,
.dma_caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP,
.dma_dev = DMA_DEV_SSP,
.ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
.remove = ssp_remove,
},
};

View File

@ -496,10 +496,15 @@ static int ssp_probe(struct dai *dai)
return 0;
}
const struct dai_ops ssp_ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
const struct dai_driver ssp_driver = {
.type = SOF_DAI_INTEL_SSP,
.dma_caps = DMA_CAP_GP_LP | DMA_CAP_GP_HP,
.dma_dev = DMA_DEV_SSP,
.ops = {
.trigger = ssp_trigger,
.set_config = ssp_set_config,
.pm_context_store = ssp_context_store,
.pm_context_restore = ssp_context_restore,
.probe = ssp_probe,
},
};

View File

@ -62,6 +62,10 @@
#define DAI_NUM_SLOT_MAPS 8
#define DAI_INFO_TYPE 0
#define DAI_INFO_DMA_CAPS 1
#define DAI_INFO_DMA_DEV 2
/* DAI flags */
/** \brief IRQ used for copy() timer */
@ -86,6 +90,13 @@ struct dai_ops {
int (*remove)(struct dai *dai);
};
struct dai_driver {
uint32_t type; /**< type, one of SOF_DAI_... */
uint32_t dma_caps;
uint32_t dma_dev;
struct dai_ops ops;
};
/**
* \brief DAI slot map to audio channel
*/
@ -113,12 +124,11 @@ struct dai_plat_data {
};
struct dai {
uint32_t type; /**< type, one of SOF_DAI_... */
uint32_t index; /**< index */
spinlock_t lock;
int sref; /**< simple ref counter, guarded by lock */
struct dai_plat_data plat_data;
const struct dai_ops *ops;
const struct dai_driver *drv;
void *private;
};
@ -174,7 +184,7 @@ void dai_put(struct dai *dai);
static inline int dai_set_config(struct dai *dai,
struct sof_ipc_dai_config *config)
{
return dai->ops->set_config(dai, config);
return dai->drv->ops.set_config(dai, config);
}
/**
@ -182,7 +192,7 @@ static inline int dai_set_config(struct dai *dai,
*/
static inline int dai_trigger(struct dai *dai, int cmd, int direction)
{
return dai->ops->trigger(dai, cmd, direction);
return dai->drv->ops.trigger(dai, cmd, direction);
}
/**
@ -190,7 +200,7 @@ static inline int dai_trigger(struct dai *dai, int cmd, int direction)
*/
static inline int dai_pm_context_store(struct dai *dai)
{
return dai->ops->pm_context_store(dai);
return dai->drv->ops.pm_context_store(dai);
}
/**
@ -198,7 +208,7 @@ static inline int dai_pm_context_store(struct dai *dai)
*/
static inline int dai_pm_context_restore(struct dai *dai)
{
return dai->ops->pm_context_restore(dai);
return dai->drv->ops.pm_context_restore(dai);
}
/**
@ -206,7 +216,7 @@ static inline int dai_pm_context_restore(struct dai *dai)
*/
static inline int dai_probe(struct dai *dai)
{
return dai->ops->probe(dai);
return dai->drv->ops.probe(dai);
}
/**
@ -214,7 +224,32 @@ static inline int dai_probe(struct dai *dai)
*/
static inline int dai_remove(struct dai *dai)
{
return dai->ops->remove(dai);
return dai->drv->ops.remove(dai);
}
/**
* \brief Get driver specific DAI information
*/
static inline int dai_get_info(struct dai *dai, int info)
{
int ret;
switch (info) {
case DAI_INFO_TYPE:
ret = dai->drv->type;
break;
case DAI_INFO_DMA_CAPS:
ret = dai->drv->dma_caps;
break;
case DAI_INFO_DMA_DEV:
ret = dai->drv->dma_dev;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
/** @}*/

View File

@ -335,7 +335,7 @@ struct dmic_pdata {
int32_t gain;
};
extern const struct dai_ops dmic_ops;
extern const struct dai_driver dmic_driver;
#endif /* DMIC_HW_VERSION */
#endif /* __INCLUDE_DMIC__ */

View File

@ -33,7 +33,7 @@
#include <sof/dai.h>
extern const struct dai_ops hda_ops;
extern const struct dai_driver hda_driver;
#endif /* __INCLUDE_HDA__ */

View File

@ -66,7 +66,7 @@
#define SSCR5 0x78
#endif
extern const struct dai_ops ssp_ops;
extern const struct dai_driver ssp_driver;
/* SSCR0 bits */
#define SSCR0_DSS_MASK (0x0000000f)

View File

@ -43,7 +43,6 @@
static struct dai ssp[] = {
{
.type = SOF_DAI_INTEL_SSP,
.index = 0,
.plat_data = {
.base = SSP0_BASE,
@ -57,10 +56,9 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP0_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
{
.type = SOF_DAI_INTEL_SSP,
.index = 1,
.plat_data = {
.base = SSP1_BASE,
@ -74,10 +72,9 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP1_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
{
.type = SOF_DAI_INTEL_SSP,
.index = 2,
.plat_data = {
.base = SSP2_BASE,
@ -91,11 +88,10 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP2_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
#if defined CONFIG_CHERRYTRAIL
{
.type = SOF_DAI_INTEL_SSP,
.index = 3,
.plat_data = {
.base = SSP3_BASE,
@ -109,10 +105,9 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP3_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
{
.type = SOF_DAI_INTEL_SSP,
.index = 4,
.plat_data = {
.base = SSP4_BASE,
@ -126,10 +121,9 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP4_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
{
.type = SOF_DAI_INTEL_SSP,
.index = 5,
.plat_data = {
.base = SSP5_BASE,
@ -143,7 +137,7 @@ static struct dai ssp[] = {
.handshake = DMA_HANDSHAKE_SSP5_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
#endif
};

View File

@ -43,7 +43,6 @@
static struct dai ssp[2] = {
{
.type = SOF_DAI_INTEL_SSP,
.index = 0,
.plat_data = {
.base = SSP0_BASE,
@ -57,10 +56,9 @@ static struct dai ssp[2] = {
.handshake = DMA_HANDSHAKE_SSP0_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
},
{
.type = SOF_DAI_INTEL_SSP,
.index = 1,
.plat_data = {
.base = SSP1_BASE,
@ -74,7 +72,7 @@ static struct dai ssp[2] = {
.handshake = DMA_HANDSHAKE_SSP1_RX,
}
},
.ops = &ssp_ops,
.drv = &ssp_driver,
}};
static struct dai_type_info dti[] = {

View File

@ -62,7 +62,6 @@ static struct dai dmic[2] = {
/* Primary FIFO A */
{
.type = SOF_DAI_INTEL_DMIC,
.index = 0,
.plat_data = {
.base = DMIC_BASE,
@ -76,11 +75,10 @@ static struct dai dmic[2] = {
.handshake = DMA_HANDSHAKE_DMIC_CH0,
}
},
.ops = &dmic_ops,
.drv = &dmic_driver,
},
/* Secondary FIFO B */
{
.type = SOF_DAI_INTEL_DMIC,
.index = 1,
.plat_data = {
.base = DMIC_BASE,
@ -94,7 +92,7 @@ static struct dai dmic[2] = {
.handshake = DMA_HANDSHAKE_DMIC_CH1,
}
},
.ops = &dmic_ops,
.drv = &dmic_driver,
}
};
@ -130,9 +128,8 @@ int dai_init(void)
#if CONFIG_CAVS_SSP
/* init ssp */
for (i = 0; i < ARRAY_SIZE(ssp); i++) {
ssp[i].type = SOF_DAI_INTEL_SSP;
ssp[i].index = i;
ssp[i].ops = &ssp_ops;
ssp[i].drv = &ssp_driver;
ssp[i].plat_data.base = SSP_BASE(i);
ssp[i].plat_data.irq = IRQ_EXT_SSPx_LVL5(i, 0);
ssp[i].plat_data.fifo[SOF_IPC_STREAM_PLAYBACK].offset =
@ -149,9 +146,8 @@ int dai_init(void)
#endif
/* init hd/a, note that size depends on the platform caps */
for (i = 0; i < ARRAY_SIZE(hda); i++) {
hda[i].type = SOF_DAI_INTEL_HDA;
hda[i].index = i;
hda[i].ops = &hda_ops;
hda[i].drv = &hda_driver;
spinlock_init(&hda[i].lock);
}