18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR MIT) 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * Copyright (c) 2018 Baylibre SAS. 48c2ecf20Sopenharmony_ci * Author: Jerome Brunet <jbrunet@baylibre.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef _MESON_AXG_TDM_H 88c2ecf20Sopenharmony_ci#define _MESON_AXG_TDM_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/clk.h> 118c2ecf20Sopenharmony_ci#include <linux/regmap.h> 128c2ecf20Sopenharmony_ci#include <sound/pcm.h> 138c2ecf20Sopenharmony_ci#include <sound/soc.h> 148c2ecf20Sopenharmony_ci#include <sound/soc-dai.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define AXG_TDM_NUM_LANES 4 178c2ecf20Sopenharmony_ci#define AXG_TDM_CHANNEL_MAX 128 188c2ecf20Sopenharmony_ci#define AXG_TDM_RATES (SNDRV_PCM_RATE_5512 | \ 198c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_8000_192000) 208c2ecf20Sopenharmony_ci#define AXG_TDM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 218c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S16_LE | \ 228c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S20_LE | \ 238c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | \ 248c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct axg_tdm_iface { 278c2ecf20Sopenharmony_ci struct clk *sclk; 288c2ecf20Sopenharmony_ci struct clk *lrclk; 298c2ecf20Sopenharmony_ci struct clk *mclk; 308c2ecf20Sopenharmony_ci unsigned long mclk_rate; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci /* format is common to all the DAIs of the iface */ 338c2ecf20Sopenharmony_ci unsigned int fmt; 348c2ecf20Sopenharmony_ci unsigned int slots; 358c2ecf20Sopenharmony_ci unsigned int slot_width; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci /* For component wide symmetry */ 388c2ecf20Sopenharmony_ci int rate; 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline bool axg_tdm_lrclk_invert(unsigned int fmt) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci return ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) ^ 448c2ecf20Sopenharmony_ci !!(fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_NB_IF)); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic inline bool axg_tdm_sclk_invert(unsigned int fmt) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci return fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_IB_NF); 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistruct axg_tdm_stream { 538c2ecf20Sopenharmony_ci struct axg_tdm_iface *iface; 548c2ecf20Sopenharmony_ci struct list_head formatter_list; 558c2ecf20Sopenharmony_ci struct mutex lock; 568c2ecf20Sopenharmony_ci unsigned int channels; 578c2ecf20Sopenharmony_ci unsigned int width; 588c2ecf20Sopenharmony_ci unsigned int physical_width; 598c2ecf20Sopenharmony_ci u32 *mask; 608c2ecf20Sopenharmony_ci bool ready; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface); 648c2ecf20Sopenharmony_civoid axg_tdm_stream_free(struct axg_tdm_stream *ts); 658c2ecf20Sopenharmony_ciint axg_tdm_stream_start(struct axg_tdm_stream *ts); 668c2ecf20Sopenharmony_civoid axg_tdm_stream_stop(struct axg_tdm_stream *ts); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic inline int axg_tdm_stream_reset(struct axg_tdm_stream *ts) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci axg_tdm_stream_stop(ts); 718c2ecf20Sopenharmony_ci return axg_tdm_stream_start(ts); 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ciint axg_tdm_set_tdm_slots(struct snd_soc_dai *dai, u32 *tx_mask, 758c2ecf20Sopenharmony_ci u32 *rx_mask, unsigned int slots, 768c2ecf20Sopenharmony_ci unsigned int slot_width); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci#endif /* _MESON_AXG_TDM_H */ 79