Lines Matching +full:data +full:- +full:rate
4 * SPDX-License-Identifier: Apache-2.0
11 * if you use more than 1 data line, it's obvious you're going
12 * to want to keep the pins of the data lines in ESAI mode.
25 * by 1 up to 256 (configured via xPM0-xPM7). The resulting
28 * up to 16 (configured via xFP0-xFP3). The resulting signal is
42 return -EINVAL; in esai_get_clock_rate_config()
46 LOG_ERR("got NULL clock rate"); in esai_get_clock_rate_config()
47 return -EINVAL; in esai_get_clock_rate_config()
51 LOG_ERR("HCLK rate cannot be higher than EXTAL rate"); in esai_get_clock_rate_config()
52 return -EINVAL; in esai_get_clock_rate_config()
56 LOG_ERR("BCLK rate cannot be higher than EXTAL rate"); in esai_get_clock_rate_config()
57 return -EINVAL; in esai_get_clock_rate_config()
61 LOG_ERR("BCLK rate %u cannot be obtained from EXTAL rate %u", in esai_get_clock_rate_config()
63 return -EINVAL; in esai_get_clock_rate_config()
69 return -EINVAL; in esai_get_clock_rate_config()
79 LOG_ERR("HCLK rate cannot be higher than EXTAL's rate divided by 2"); in esai_get_clock_rate_config()
80 return -EINVAL; in esai_get_clock_rate_config()
83 /* compute HCLK configuration - only required if HCLK pad output is used */ in esai_get_clock_rate_config()
86 /* HCLK rate from pad is the same as EXTAL rate */ in esai_get_clock_rate_config()
87 cfg->hclk_bypass = true; in esai_get_clock_rate_config()
97 cfg->hclk_prescaler_en = true; in esai_get_clock_rate_config()
105 LOG_ERR("cannot obtain HCLK rate %u from EXTAL rate %u", in esai_get_clock_rate_config()
107 return -EINVAL; in esai_get_clock_rate_config()
113 cfg->hclk_div_ratio = hclk_div_ratio; in esai_get_clock_rate_config()
122 if (variable_hclk || cfg->hclk_bypass) { in esai_get_clock_rate_config()
123 /* attempt to find a configuration that satisfies BCLK's rate */ in esai_get_clock_rate_config()
131 cfg->hclk_prescaler_en = true; in esai_get_clock_rate_config()
137 cfg->bclk_div_ratio = 1; in esai_get_clock_rate_config()
138 cfg->hclk_div_ratio = hclk_div_ratio; in esai_get_clock_rate_config()
148 cfg->bclk_div_ratio = bclk_div_ratio; in esai_get_clock_rate_config()
149 cfg->hclk_div_ratio = hclk_div_ratio; in esai_get_clock_rate_config()
156 LOG_ERR("no valid configuration for BCLK rate %u and EXTAL rate %u", in esai_get_clock_rate_config()
158 return -EINVAL; in esai_get_clock_rate_config()
161 /* can the BCLK rate be obtained w/o modifying divided EXTAL? */ in esai_get_clock_rate_config()
165 LOG_ERR("cannot obtain BCLK rate %d from EXTAL rate %d", in esai_get_clock_rate_config()
167 return -EINVAL; in esai_get_clock_rate_config()
171 cfg->bclk_div_ratio = bclk_div_ratio; in esai_get_clock_rate_config()
172 cfg->hclk_div_ratio = hclk_div_ratio; in esai_get_clock_rate_config()
180 switch (cfg->format & DAI_FORMAT_CLOCK_PROVIDER_MASK) { in esai_get_clk_provider_config()
185 xceiver_cfg->bclk_dir = kESAI_ClockInput; in esai_get_clk_provider_config()
186 xceiver_cfg->fsync_dir = kESAI_ClockInput; in esai_get_clk_provider_config()
190 cfg->format & DAI_FORMAT_CLOCK_PROVIDER_MASK); in esai_get_clk_provider_config()
191 return -EINVAL; in esai_get_clk_provider_config()
200 switch (cfg->format & DAI_FORMAT_CLOCK_INVERSION_MASK) { in esai_get_clk_inversion_config()
202 ESAI_INVERT_POLARITY(xceiver_cfg->bclk_polarity); in esai_get_clk_inversion_config()
203 ESAI_INVERT_POLARITY(xceiver_cfg->fsync_polarity); in esai_get_clk_inversion_config()
206 ESAI_INVERT_POLARITY(xceiver_cfg->bclk_polarity); in esai_get_clk_inversion_config()
209 ESAI_INVERT_POLARITY(xceiver_cfg->fsync_polarity); in esai_get_clk_inversion_config()
216 cfg->format & DAI_FORMAT_CLOCK_INVERSION_MASK); in esai_get_clk_inversion_config()
217 return -EINVAL; in esai_get_clk_inversion_config()
226 switch (cfg->format & DAI_FORMAT_PROTOCOL_MASK) { in esai_get_proto_config()
228 xceiver_cfg->bclk_polarity = kESAI_ClockActiveLow; in esai_get_proto_config()
229 xceiver_cfg->fsync_polarity = kESAI_ClockActiveLow; in esai_get_proto_config()
232 xceiver_cfg->bclk_polarity = kESAI_ClockActiveLow; in esai_get_proto_config()
233 xceiver_cfg->fsync_is_bit_wide = true; in esai_get_proto_config()
237 cfg->format & DAI_FORMAT_PROTOCOL_MASK); in esai_get_proto_config()
238 return -EINVAL; in esai_get_proto_config()
250 return -EINVAL; in esai_get_slot_format()
253 cfg->slot_format = ESAI_SLOT_FORMAT(slot_width, word_width); in esai_get_slot_format()
262 cfg->hclk_prescaler_en = false; in esai_get_xceiver_default_config()
263 cfg->hclk_div_ratio = 1; in esai_get_xceiver_default_config()
264 cfg->bclk_div_ratio = 1; in esai_get_xceiver_default_config()
265 cfg->hclk_bypass = false; in esai_get_xceiver_default_config()
267 cfg->hclk_src = kESAI_HckSourceExternal; in esai_get_xceiver_default_config()
268 cfg->hclk_dir = kESAI_ClockOutput; in esai_get_xceiver_default_config()
269 cfg->hclk_polarity = kESAI_ClockActiveHigh; in esai_get_xceiver_default_config()
271 cfg->bclk_dir = kESAI_ClockOutput; in esai_get_xceiver_default_config()
272 cfg->bclk_polarity = kESAI_ClockActiveHigh; in esai_get_xceiver_default_config()
274 cfg->fsync_dir = kESAI_ClockOutput; in esai_get_xceiver_default_config()
275 cfg->fsync_polarity = kESAI_ClockActiveHigh; in esai_get_xceiver_default_config()
277 cfg->fsync_is_bit_wide = false; in esai_get_xceiver_default_config()
278 cfg->zero_pad_en = true; in esai_get_xceiver_default_config()
279 cfg->fsync_early = true; in esai_get_xceiver_default_config()
281 cfg->mode = kESAI_NetworkMode; in esai_get_xceiver_default_config()
282 cfg->data_order = kESAI_ShifterMSB; in esai_get_xceiver_default_config()
283 cfg->data_left_aligned = true; in esai_get_xceiver_default_config()
291 base->TCCR &= ~(ESAI_TCCR_THCKD_MASK | ESAI_TCCR_TFSD_MASK | in esai_commit_config()
297 base->TCCR |= ESAI_TCCR_THCKD(cfg->hclk_dir) | in esai_commit_config()
298 ESAI_TCCR_TFSD(cfg->fsync_dir) | in esai_commit_config()
299 ESAI_TCCR_TCKD(cfg->bclk_dir) | in esai_commit_config()
300 ESAI_TCCR_THCKP(cfg->hclk_polarity) | in esai_commit_config()
301 ESAI_TCCR_TFSP(cfg->fsync_polarity) | in esai_commit_config()
302 ESAI_TCCR_TCKP(cfg->bclk_polarity) | in esai_commit_config()
303 ESAI_TCCR_TFP(cfg->bclk_div_ratio - 1) | in esai_commit_config()
304 ESAI_TCCR_TDC(cfg->fsync_div - 1) | in esai_commit_config()
305 ESAI_TCCR_TPSR(!cfg->hclk_prescaler_en) | in esai_commit_config()
306 ESAI_TCCR_TPM(cfg->hclk_div_ratio - 1); in esai_commit_config()
308 base->TCR &= ~(ESAI_TCR_PADC_MASK | ESAI_TCR_TFSR_MASK | in esai_commit_config()
312 base->TCR |= ESAI_TCR_PADC(cfg->zero_pad_en) | in esai_commit_config()
313 ESAI_TCR_TFSR(cfg->fsync_early) | in esai_commit_config()
314 ESAI_TCR_TFSL(cfg->fsync_is_bit_wide) | in esai_commit_config()
315 ESAI_TCR_TSWS(cfg->slot_format) | in esai_commit_config()
316 ESAI_TCR_TMOD(cfg->mode) | in esai_commit_config()
317 ESAI_TCR_TWA(!cfg->data_left_aligned) | in esai_commit_config()
318 ESAI_TCR_TSHFD(cfg->data_order); in esai_commit_config()
320 base->ECR &= ~(ESAI_ECR_ETI_MASK | in esai_commit_config()
323 base->ECR |= ESAI_ECR_ETI(cfg->hclk_src) | in esai_commit_config()
324 ESAI_ECR_ETO(cfg->hclk_bypass); in esai_commit_config()
326 base->TFCR &= ~(ESAI_TFCR_TFWM_MASK | ESAI_TFCR_TWA_MASK); in esai_commit_config()
327 base->TFCR |= ESAI_TFCR_TFWM(cfg->watermark) | in esai_commit_config()
328 ESAI_TFCR_TWA(cfg->word_alignment); in esai_commit_config()
330 ESAI_TxSetSlotMask(base, cfg->slot_mask); in esai_commit_config()
332 base->RCCR &= ~(ESAI_RCCR_RHCKD_MASK | ESAI_RCCR_RFSD_MASK | in esai_commit_config()
338 base->RCCR |= ESAI_RCCR_RHCKD(cfg->hclk_dir) | in esai_commit_config()
339 ESAI_RCCR_RFSD(cfg->fsync_dir) | in esai_commit_config()
340 ESAI_RCCR_RCKD(cfg->bclk_dir) | in esai_commit_config()
341 ESAI_RCCR_RHCKP(cfg->hclk_polarity) | in esai_commit_config()
342 ESAI_RCCR_RFSP(cfg->fsync_polarity) | in esai_commit_config()
343 ESAI_RCCR_RCKP(cfg->bclk_polarity) | in esai_commit_config()
344 ESAI_RCCR_RFP(cfg->bclk_div_ratio - 1) | in esai_commit_config()
345 ESAI_RCCR_RDC(cfg->fsync_div - 1) | in esai_commit_config()
346 ESAI_RCCR_RPSR(!cfg->hclk_prescaler_en) | in esai_commit_config()
347 ESAI_RCCR_RPM(cfg->hclk_div_ratio - 1); in esai_commit_config()
349 base->RCR &= ~(ESAI_RCR_RFSR_MASK | ESAI_RCR_RFSL_MASK | in esai_commit_config()
353 base->RCR |= ESAI_RCR_RFSR(cfg->fsync_early) | in esai_commit_config()
354 ESAI_RCR_RFSL(cfg->fsync_is_bit_wide) | in esai_commit_config()
355 ESAI_RCR_RSWS(cfg->slot_format) | in esai_commit_config()
356 ESAI_RCR_RMOD(cfg->mode) | in esai_commit_config()
357 ESAI_RCR_RWA(!cfg->data_left_aligned) | in esai_commit_config()
358 ESAI_RCR_RSHFD(cfg->data_order); in esai_commit_config()
360 base->ECR &= ~(ESAI_ECR_ERI_MASK | in esai_commit_config()
363 base->ECR |= ESAI_ECR_ERI(cfg->hclk_src) | in esai_commit_config()
364 ESAI_ECR_ERO(cfg->hclk_bypass); in esai_commit_config()
366 base->RFCR &= ~(ESAI_RFCR_RFWM_MASK | ESAI_RFCR_RWA_MASK); in esai_commit_config()
367 base->RFCR |= ESAI_RFCR_RFWM(cfg->watermark) | in esai_commit_config()
368 ESAI_RFCR_RWA(cfg->word_alignment); in esai_commit_config()
370 EASI_RxSetSlotMask(base, cfg->slot_mask); in esai_commit_config()
379 struct esai_data *data; in esai_config_set() local
387 return -EINVAL; in esai_config_set()
390 if (cfg->type != DAI_IMX_ESAI) { in esai_config_set()
391 LOG_ERR("wrong DAI type: %d", cfg->type); in esai_config_set()
392 return -EINVAL; in esai_config_set()
395 data = dev->data; in esai_config_set()
396 esai_cfg = dev->config; in esai_config_set()
398 base = UINT_TO_ESAI(data->regmap); in esai_config_set()
403 * reset and re-configured. in esai_config_set()
405 ret = esai_update_state(data, DAI_DIR_TX, DAI_STATE_READY); in esai_config_set()
411 ret = esai_update_state(data, DAI_DIR_RX, DAI_STATE_READY); in esai_config_set()
420 base->PCRC &= ~ESAI_PCRC_PC_MASK; in esai_config_set()
421 base->PRRC &= ~ESAI_PRRC_PDC_MASK; in esai_config_set()
424 ESAI_Reset(UINT_TO_ESAI(data->regmap)); in esai_config_set()
430 tx_config.fsync_div = bespoke->tdm_slots; in esai_config_set()
450 ret = esai_get_slot_format(bespoke->tdm_slot_width, in esai_config_set()
451 esai_cfg->word_width, &tx_config); in esai_config_set()
456 tx_config.word_alignment = ESAI_WORD_ALIGNMENT(esai_cfg->word_width); in esai_config_set()
462 * directions set in bespoke data. in esai_config_set()
470 ret = esai_get_clock_rate_config(bespoke->mclk_rate, bespoke->mclk_rate, in esai_config_set()
471 bespoke->bclk_rate, in esai_config_set()
472 !ESAI_PIN_IS_USED(data, ESAI_PIN_HCKT), in esai_config_set()
480 ret = esai_get_clock_rate_config(bespoke->mclk_rate, bespoke->mclk_rate, in esai_config_set()
481 bespoke->bclk_rate, in esai_config_set()
482 !ESAI_PIN_IS_USED(data, ESAI_PIN_HCKR), in esai_config_set()
490 tx_config.watermark = esai_cfg->tx_fifo_watermark; in esai_config_set()
491 rx_config.watermark = esai_cfg->rx_fifo_watermark; in esai_config_set()
493 tx_config.slot_mask = bespoke->tx_slots; in esai_config_set()
494 rx_config.slot_mask = bespoke->rx_slots; in esai_config_set()
510 /* allow each TX data register to be initialized from TX FIFO */ in esai_config_set()
511 base->TFCR |= ESAI_TFCR_TIEN_MASK; in esai_config_set()
515 * TODO: for now, only 1 data line per direction is supported. in esai_config_set()
520 /* re-connect pins based on DTS pin configuration */ in esai_config_set()
521 base->PCRC = data->pcrc; in esai_config_set()
522 base->PRRC = data->prrc; in esai_config_set()
524 data->cfg.rate = bespoke->fsync_rate; in esai_config_set()
525 data->cfg.channels = bespoke->tdm_slots; in esai_config_set()
536 struct esai_data *data = dev->data; in esai_config_get() local
539 return -EINVAL; in esai_config_get()
542 memcpy(cfg, &data->cfg, sizeof(*cfg)); in esai_config_get()
549 struct esai_data *data; in esai_trigger_start() local
553 data = dev->data; in esai_trigger_start()
554 base = UINT_TO_ESAI(data->regmap); in esai_trigger_start()
556 ret = esai_update_state(data, dir, DAI_STATE_RUNNING); in esai_trigger_start()
559 return -EINVAL; in esai_trigger_start()
568 * but playing a song while doing pause-resume very in esai_trigger_start()
587 struct esai_data *data; in esai_trigger_stop() local
591 data = dev->data; in esai_trigger_stop()
592 base = UINT_TO_ESAI(data->regmap); in esai_trigger_stop()
594 ret = esai_update_state(data, dir, DAI_STATE_STOPPING); in esai_trigger_stop()
597 return -EINVAL; in esai_trigger_stop()
618 return -EINVAL; in esai_trigger()
633 return -EINVAL; in esai_trigger()
642 const struct esai_config *cfg = dev->config; in esai_get_properties()
646 return cfg->rx_props; in esai_get_properties()
648 return cfg->tx_props; in esai_get_properties()
679 struct esai_data *data; in esai_init() local
682 cfg = dev->config; in esai_init()
683 data = dev->data; in esai_init()
685 device_map(&data->regmap, cfg->regmap_phys, cfg->regmap_size, K_MEM_CACHE_NONE); in esai_init()
687 ret = esai_parse_pinmodes(cfg, data); in esai_init()