162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR MIT) 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2018 Baylibre SAS. 462306a36Sopenharmony_ci * Author: Jerome Brunet <jbrunet@baylibre.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef _MESON_AXG_TDM_H 862306a36Sopenharmony_ci#define _MESON_AXG_TDM_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/clk.h> 1162306a36Sopenharmony_ci#include <linux/regmap.h> 1262306a36Sopenharmony_ci#include <sound/pcm.h> 1362306a36Sopenharmony_ci#include <sound/soc.h> 1462306a36Sopenharmony_ci#include <sound/soc-dai.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define AXG_TDM_NUM_LANES 4 1762306a36Sopenharmony_ci#define AXG_TDM_CHANNEL_MAX 128 1862306a36Sopenharmony_ci#define AXG_TDM_RATES (SNDRV_PCM_RATE_5512 | \ 1962306a36Sopenharmony_ci SNDRV_PCM_RATE_8000_192000) 2062306a36Sopenharmony_ci#define AXG_TDM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 2162306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S16_LE | \ 2262306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S20_LE | \ 2362306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | \ 2462306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistruct axg_tdm_iface { 2762306a36Sopenharmony_ci struct clk *sclk; 2862306a36Sopenharmony_ci struct clk *lrclk; 2962306a36Sopenharmony_ci struct clk *mclk; 3062306a36Sopenharmony_ci unsigned long mclk_rate; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* format is common to all the DAIs of the iface */ 3362306a36Sopenharmony_ci unsigned int fmt; 3462306a36Sopenharmony_ci unsigned int slots; 3562306a36Sopenharmony_ci unsigned int slot_width; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* For component wide symmetry */ 3862306a36Sopenharmony_ci int rate; 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic inline bool axg_tdm_lrclk_invert(unsigned int fmt) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci return ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) ^ 4462306a36Sopenharmony_ci !!(fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_NB_IF)); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic inline bool axg_tdm_sclk_invert(unsigned int fmt) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci return fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_IB_NF); 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistruct axg_tdm_stream { 5362306a36Sopenharmony_ci struct axg_tdm_iface *iface; 5462306a36Sopenharmony_ci struct list_head formatter_list; 5562306a36Sopenharmony_ci struct mutex lock; 5662306a36Sopenharmony_ci unsigned int channels; 5762306a36Sopenharmony_ci unsigned int width; 5862306a36Sopenharmony_ci unsigned int physical_width; 5962306a36Sopenharmony_ci u32 *mask; 6062306a36Sopenharmony_ci bool ready; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface); 6462306a36Sopenharmony_civoid axg_tdm_stream_free(struct axg_tdm_stream *ts); 6562306a36Sopenharmony_ciint axg_tdm_stream_start(struct axg_tdm_stream *ts); 6662306a36Sopenharmony_civoid axg_tdm_stream_stop(struct axg_tdm_stream *ts); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistatic inline int axg_tdm_stream_reset(struct axg_tdm_stream *ts) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci axg_tdm_stream_stop(ts); 7162306a36Sopenharmony_ci return axg_tdm_stream_start(ts); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciint axg_tdm_set_tdm_slots(struct snd_soc_dai *dai, u32 *tx_mask, 7562306a36Sopenharmony_ci u32 *rx_mask, unsigned int slots, 7662306a36Sopenharmony_ci unsigned int slot_width); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#endif /* _MESON_AXG_TDM_H */ 79