/* * User frame size shall be 2, 4, 6 or 8 32-bits words length * (i.e. 8, 16, 24 or 32 bytes) * This constraint comes from allowed values for * UNIPERIF_I2S_FMT_NUM_CH register
*/ #define UNIPERIF_MAX_FRAME_SZ 0x20 #define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ)
struct sti_uniperiph_dev_data { unsignedint id; /* Nb available player instances */ unsignedint version; /* player IP version */ unsignedint stream; constchar *dai_names; enum uniperif_type type;
};
int sti_uniperiph_reset(struct uniperif *uni)
{ int count = 10;
/* Reset uniperipheral uni */
SET_UNIPERIF_SOFT_RST_SOFT_RST(uni);
if (uni->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) { while (GET_UNIPERIF_SOFT_RST_SOFT_RST(uni) && count) {
udelay(5);
count--;
}
}
if (!count) {
dev_err(uni->dev, "Failed to reset uniperif\n"); return -EIO;
}
return 0;
}
int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsignedint tx_mask, unsignedint rx_mask, int slots, int slot_width)
{ struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); struct uniperif *uni = priv->dai_data.uni; int i, frame_size, avail_slots;
if (!UNIPERIF_TYPE_IS_TDM(uni)) {
dev_err(uni->dev, "cpu dai not in tdm mode\n"); return -EINVAL;
}
/* store info in unip context */
uni->tdm_slot.slots = slots;
uni->tdm_slot.slot_width = slot_width; /* unip is unidirectionnal */
uni->tdm_slot.mask = (tx_mask != 0) ? tx_mask : rx_mask;
/* number of available timeslots */ for (i = 0, avail_slots = 0; i < uni->tdm_slot.slots; i++) { if ((uni->tdm_slot.mask >> i) & 0x01)
avail_slots++;
}
uni->tdm_slot.avail_slots = avail_slots;
/* set unip word position */ for (i = 0, j = 0, k = 0; (i < slots_num) && (k < WORD_MAX); i++) { if ((slots_mask >> i) & 0x01) {
word16_pos[j] = i * slot_width;
/* * sti_uniperiph_dai_create_ctrl * This function is used to create Ctrl associated to DAI but also pcm device. * Request is done by front end to associate ctrl with pcm device id
*/ staticint sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai)
{ struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); struct uniperif *uni = priv->dai_data.uni; struct snd_kcontrol_new *ctrl; int i;
if (!uni->num_ctrls) return 0;
for (i = 0; i < uni->num_ctrls; i++) { /* * Several Control can have same name. Controls are indexed on * Uniperipheral instance ID
*/
ctrl = &uni->snd_ctrls[i];
ctrl->index = uni->id;
ctrl->device = uni->id;
}
/* The uniperipheral should be in stopped state */ if (uni->state != UNIPERIF_STATE_STOPPED) {
dev_err(uni->dev, "%s: invalid uni state( %d)\n",
__func__, (int)uni->state); return -EBUSY;
}
/* Pinctrl: switch pinstate to sleep */
ret = pinctrl_pm_select_sleep_state(uni->dev); if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = uni_player_resume(uni); if (ret) return ret;
}
/* pinctrl: switch pinstate to default */
ret = pinctrl_pm_select_default_state(uni->dev); if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
/* Get resources and base address */
uni->base = devm_platform_get_and_ioremap_resource(priv->pdev, 0, &uni->mem_region); if (IS_ERR(uni->base)) return PTR_ERR(uni->base);
uni->irq = platform_get_irq(priv->pdev, 0); if (uni->irq < 0) return -ENXIO;
uni->type = dev_data->type;
/* check if player should be configured for tdm */ if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) { if (!of_property_read_string(node, "st,tdm-mode", &mode))
uni->type = SND_ST_UNIPERIF_TYPE_TDM; else
uni->type = SND_ST_UNIPERIF_TYPE_PCM;
}
/* Allocate the private data and the CPU_DAI array */
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL); if (!priv->dai) return -ENOMEM;
priv->pdev = pdev;
ret = sti_uniperiph_cpu_dai_of(node, priv); if (ret < 0) return ret;
dev_set_drvdata(&pdev->dev, priv);
ret = devm_snd_soc_register_component(&pdev->dev,
&sti_uniperiph_dai_component,
priv->dai, 1); if (ret < 0) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.