Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002  *
0003  * Copyright (c) 2018 Baylibre SAS.
0004  * Author: Jerome Brunet <jbrunet@baylibre.com>
0005  */
0006 
0007 #ifndef _MESON_AXG_TDM_H
0008 #define _MESON_AXG_TDM_H
0009 
0010 #include <linux/clk.h>
0011 #include <linux/regmap.h>
0012 #include <sound/pcm.h>
0013 #include <sound/soc.h>
0014 #include <sound/soc-dai.h>
0015 
0016 #define AXG_TDM_NUM_LANES   4
0017 #define AXG_TDM_CHANNEL_MAX 128
0018 #define AXG_TDM_RATES       (SNDRV_PCM_RATE_5512 |      \
0019                  SNDRV_PCM_RATE_8000_192000)
0020 #define AXG_TDM_FORMATS     (SNDRV_PCM_FMTBIT_S8 |      \
0021                  SNDRV_PCM_FMTBIT_S16_LE |  \
0022                  SNDRV_PCM_FMTBIT_S20_LE |  \
0023                  SNDRV_PCM_FMTBIT_S24_LE |  \
0024                  SNDRV_PCM_FMTBIT_S32_LE)
0025 
0026 struct axg_tdm_iface {
0027     struct clk *sclk;
0028     struct clk *lrclk;
0029     struct clk *mclk;
0030     unsigned long mclk_rate;
0031 
0032     /* format is common to all the DAIs of the iface */
0033     unsigned int fmt;
0034     unsigned int slots;
0035     unsigned int slot_width;
0036 
0037     /* For component wide symmetry */
0038     int rate;
0039 };
0040 
0041 static inline bool axg_tdm_lrclk_invert(unsigned int fmt)
0042 {
0043     return ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) ^
0044         !!(fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_NB_IF));
0045 }
0046 
0047 static inline bool axg_tdm_sclk_invert(unsigned int fmt)
0048 {
0049     return fmt & (SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_IB_NF);
0050 }
0051 
0052 struct axg_tdm_stream {
0053     struct axg_tdm_iface *iface;
0054     struct list_head formatter_list;
0055     struct mutex lock;
0056     unsigned int channels;
0057     unsigned int width;
0058     unsigned int physical_width;
0059     u32 *mask;
0060     bool ready;
0061 };
0062 
0063 struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface);
0064 void axg_tdm_stream_free(struct axg_tdm_stream *ts);
0065 int axg_tdm_stream_start(struct axg_tdm_stream *ts);
0066 void axg_tdm_stream_stop(struct axg_tdm_stream *ts);
0067 
0068 static inline int axg_tdm_stream_reset(struct axg_tdm_stream *ts)
0069 {
0070     axg_tdm_stream_stop(ts);
0071     return axg_tdm_stream_start(ts);
0072 }
0073 
0074 int axg_tdm_set_tdm_slots(struct snd_soc_dai *dai, u32 *tx_mask,
0075               u32 *rx_mask, unsigned int slots,
0076               unsigned int slot_width);
0077 
0078 #endif /* _MESON_AXG_TDM_H */