Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Socionext UniPhier AIO ALSA driver.
0004  *
0005  * Copyright (c) 2016-2018 Socionext Inc.
0006  */
0007 
0008 #ifndef SND_UNIPHIER_AIO_H__
0009 #define SND_UNIPHIER_AIO_H__
0010 
0011 #include <linux/spinlock.h>
0012 #include <linux/types.h>
0013 #include <sound/pcm.h>
0014 #include <sound/soc.h>
0015 #include <sound/soc-dai.h>
0016 
0017 struct platform_device;
0018 
0019 enum ID_PORT_TYPE {
0020     PORT_TYPE_UNKNOWN,
0021     PORT_TYPE_I2S,
0022     PORT_TYPE_SPDIF,
0023     PORT_TYPE_EVE,
0024     PORT_TYPE_CONV,
0025 };
0026 
0027 enum ID_PORT_DIR {
0028     PORT_DIR_OUTPUT,
0029     PORT_DIR_INPUT,
0030 };
0031 
0032 enum IEC61937_PC {
0033     IEC61937_PC_AC3   = 0x0001,
0034     IEC61937_PC_PAUSE = 0x0003,
0035     IEC61937_PC_MPA   = 0x0004,
0036     IEC61937_PC_MP3   = 0x0005,
0037     IEC61937_PC_DTS1  = 0x000b,
0038     IEC61937_PC_DTS2  = 0x000c,
0039     IEC61937_PC_DTS3  = 0x000d,
0040     IEC61937_PC_AAC   = 0x0007,
0041 };
0042 
0043 /* IEC61937 Repetition period of data-burst in IEC60958 frames */
0044 #define IEC61937_FRM_STR_AC3       1536
0045 #define IEC61937_FRM_STR_MPA       1152
0046 #define IEC61937_FRM_STR_MP3       1152
0047 #define IEC61937_FRM_STR_DTS1      512
0048 #define IEC61937_FRM_STR_DTS2      1024
0049 #define IEC61937_FRM_STR_DTS3      2048
0050 #define IEC61937_FRM_STR_AAC       1024
0051 
0052 /* IEC61937 Repetition period of Pause data-burst in IEC60958 frames */
0053 #define IEC61937_FRM_PAU_AC3       3
0054 #define IEC61937_FRM_PAU_MPA       32
0055 #define IEC61937_FRM_PAU_MP3       32
0056 #define IEC61937_FRM_PAU_DTS1      3
0057 #define IEC61937_FRM_PAU_DTS2      3
0058 #define IEC61937_FRM_PAU_DTS3      3
0059 #define IEC61937_FRM_PAU_AAC       32
0060 
0061 /* IEC61937 Pa and Pb */
0062 #define IEC61937_HEADER_SIGN       0x1f4e72f8
0063 
0064 #define AUD_HW_PCMIN1    0
0065 #define AUD_HW_PCMIN2    1
0066 #define AUD_HW_PCMIN3    2
0067 #define AUD_HW_IECIN1    3
0068 #define AUD_HW_DIECIN1   4
0069 
0070 #define AUD_NAME_PCMIN1     "aio-pcmin1"
0071 #define AUD_NAME_PCMIN2     "aio-pcmin2"
0072 #define AUD_NAME_PCMIN3     "aio-pcmin3"
0073 #define AUD_NAME_IECIN1     "aio-iecin1"
0074 #define AUD_NAME_DIECIN1    "aio-diecin1"
0075 
0076 #define AUD_HW_HPCMOUT1    0
0077 #define AUD_HW_PCMOUT1     1
0078 #define AUD_HW_PCMOUT2     2
0079 #define AUD_HW_PCMOUT3     3
0080 #define AUD_HW_EPCMOUT1    4
0081 #define AUD_HW_EPCMOUT2    5
0082 #define AUD_HW_EPCMOUT3    6
0083 #define AUD_HW_EPCMOUT6    9
0084 #define AUD_HW_HIECOUT1    10
0085 #define AUD_HW_IECOUT1     11
0086 #define AUD_HW_CMASTER     31
0087 
0088 #define AUD_NAME_HPCMOUT1        "aio-hpcmout1"
0089 #define AUD_NAME_PCMOUT1         "aio-pcmout1"
0090 #define AUD_NAME_PCMOUT2         "aio-pcmout2"
0091 #define AUD_NAME_PCMOUT3         "aio-pcmout3"
0092 #define AUD_NAME_EPCMOUT1        "aio-epcmout1"
0093 #define AUD_NAME_EPCMOUT2        "aio-epcmout2"
0094 #define AUD_NAME_EPCMOUT3        "aio-epcmout3"
0095 #define AUD_NAME_EPCMOUT6        "aio-epcmout6"
0096 #define AUD_NAME_HIECOUT1        "aio-hiecout1"
0097 #define AUD_NAME_IECOUT1         "aio-iecout1"
0098 #define AUD_NAME_CMASTER         "aio-cmaster"
0099 #define AUD_NAME_HIECCOMPOUT1    "aio-hieccompout1"
0100 #define AUD_NAME_IECCOMPOUT1     "aio-ieccompout1"
0101 
0102 #define AUD_GNAME_HDMI    "aio-hdmi"
0103 #define AUD_GNAME_LINE    "aio-line"
0104 #define AUD_GNAME_AUX     "aio-aux"
0105 #define AUD_GNAME_IEC     "aio-iec"
0106 
0107 #define AUD_CLK_IO        0
0108 #define AUD_CLK_A1        1
0109 #define AUD_CLK_F1        2
0110 #define AUD_CLK_A2        3
0111 #define AUD_CLK_F2        4
0112 #define AUD_CLK_A         5
0113 #define AUD_CLK_F         6
0114 #define AUD_CLK_APLL      7
0115 #define AUD_CLK_RX0       8
0116 #define AUD_CLK_USB0      9
0117 #define AUD_CLK_HSC0      10
0118 
0119 #define AUD_PLL_A1        0
0120 #define AUD_PLL_F1        1
0121 #define AUD_PLL_A2        2
0122 #define AUD_PLL_F2        3
0123 #define AUD_PLL_APLL      4
0124 #define AUD_PLL_RX0       5
0125 #define AUD_PLL_USB0      6
0126 #define AUD_PLL_HSC0      7
0127 
0128 #define AUD_PLLDIV_1_2    0
0129 #define AUD_PLLDIV_1_3    1
0130 #define AUD_PLLDIV_1_1    2
0131 #define AUD_PLLDIV_2_3    3
0132 
0133 #define AUD_VOL_INIT         0x4000 /* +0dB */
0134 #define AUD_VOL_MAX          0xffff /* +6dB */
0135 #define AUD_VOL_FADE_TIME    20 /* 20ms */
0136 
0137 #define AUD_RING_SIZE            (128 * 1024)
0138 
0139 #define AUD_MIN_FRAGMENT         4
0140 #define AUD_MAX_FRAGMENT         8
0141 #define AUD_MIN_FRAGMENT_SIZE    (4 * 1024)
0142 #define AUD_MAX_FRAGMENT_SIZE    (16 * 1024)
0143 
0144 /* max 5 slots, 10 channels, 2 channel in 1 slot */
0145 #define AUD_MAX_SLOTSEL    5
0146 
0147 /*
0148  * This is a selector for virtual register map of AIO.
0149  *
0150  * map:  Specify the index of virtual register map.
0151  * hw :  Specify the ID of real register map, selector uses this value.
0152  *       A meaning of this value depends specification of SoC.
0153  */
0154 struct uniphier_aio_selector {
0155     int map;
0156     int hw;
0157 };
0158 
0159 /**
0160  * 'SoftWare MAPping' setting of UniPhier AIO registers.
0161  *
0162  * We have to setup 'virtual' register maps to access 'real' registers of AIO.
0163  * This feature is legacy and meaningless but AIO needs this to work.
0164  *
0165  * Each hardware blocks have own virtual register maps as following:
0166  *
0167  * Address Virtual                      Real
0168  * ------- ---------                    ---------------
0169  * 0x12000 DMAC map0 --> [selector] --> DMAC hardware 3
0170  * 0x12080 DMAC map1 --> [selector] --> DMAC hardware 1
0171  * ...
0172  * 0x42000 Port map0 --> [selector] --> Port hardware 1
0173  * 0x42400 Port map1 --> [selector] --> Port hardware 2
0174  * ...
0175  *
0176  * ch   : Input or output channel of DMAC
0177  * rb   : Ring buffer
0178  * iport: PCM input port
0179  * iif  : Input interface
0180  * oport: PCM output port
0181  * oif  : Output interface
0182  * och  : Output channel of DMAC for sampling rate converter
0183  *
0184  * These are examples for sound data paths:
0185  *
0186  * For caputure device:
0187  *   (outer of AIO) -> iport -> iif -> ch -> rb -> (CPU)
0188  * For playback device:
0189  *   (CPU) -> rb -> ch -> oif -> oport -> (outer of AIO)
0190  * For sampling rate converter device:
0191  *   (CPU) -> rb -> ch -> oif -> (HW SRC) -> iif -> och -> orb -> (CPU)
0192  */
0193 struct uniphier_aio_swmap {
0194     int type;
0195     int dir;
0196 
0197     struct uniphier_aio_selector ch;
0198     struct uniphier_aio_selector rb;
0199     struct uniphier_aio_selector iport;
0200     struct uniphier_aio_selector iif;
0201     struct uniphier_aio_selector oport;
0202     struct uniphier_aio_selector oif;
0203     struct uniphier_aio_selector och;
0204 };
0205 
0206 struct uniphier_aio_spec {
0207     const char *name;
0208     const char *gname;
0209     struct uniphier_aio_swmap swm;
0210 };
0211 
0212 struct uniphier_aio_pll {
0213     bool enable;
0214     unsigned int freq;
0215 };
0216 
0217 struct uniphier_aio_chip_spec {
0218     const struct uniphier_aio_spec *specs;
0219     int num_specs;
0220     const struct uniphier_aio_pll *plls;
0221     int num_plls;
0222     struct snd_soc_dai_driver *dais;
0223     int num_dais;
0224 
0225     /* DMA access mode, this is workaround for DMA hungup */
0226     int addr_ext;
0227 };
0228 
0229 struct uniphier_aio_sub {
0230     struct uniphier_aio *aio;
0231 
0232     /* Guard sub->rd_offs and wr_offs from IRQ handler. */
0233     spinlock_t lock;
0234 
0235     const struct uniphier_aio_swmap *swm;
0236     const struct uniphier_aio_spec *spec;
0237 
0238     /* For PCM audio */
0239     struct snd_pcm_substream *substream;
0240     struct snd_pcm_hw_params params;
0241     int vol;
0242 
0243     /* For compress audio */
0244     struct snd_compr_stream *cstream;
0245     struct snd_compr_params cparams;
0246     unsigned char *compr_area;
0247     dma_addr_t compr_addr;
0248     size_t compr_bytes;
0249     int pass_through;
0250     enum IEC61937_PC iec_pc;
0251     bool iec_header;
0252 
0253     /* Both PCM and compress audio */
0254     bool use_mmap;
0255     int setting;
0256     int running;
0257     u64 rd_offs;
0258     u64 wr_offs;
0259     u32 threshold;
0260     u64 rd_org;
0261     u64 wr_org;
0262     u64 rd_total;
0263     u64 wr_total;
0264 };
0265 
0266 struct uniphier_aio {
0267     struct uniphier_aio_chip *chip;
0268 
0269     struct uniphier_aio_sub sub[2];
0270 
0271     unsigned int fmt;
0272     /* Set one of AUD_CLK_X */
0273     int clk_in;
0274     int clk_out;
0275     /* Set one of AUD_PLL_X */
0276     int pll_in;
0277     int pll_out;
0278     /* Set one of AUD_PLLDIV_X */
0279     int plldiv;
0280 };
0281 
0282 struct uniphier_aio_chip {
0283     struct platform_device *pdev;
0284     const struct uniphier_aio_chip_spec *chip_spec;
0285 
0286     struct uniphier_aio *aios;
0287     int num_aios;
0288     int num_wup_aios;
0289     struct uniphier_aio_pll *plls;
0290     int num_plls;
0291 
0292     struct clk *clk;
0293     struct reset_control *rst;
0294     struct regmap *regmap;
0295     struct regmap *regmap_sg;
0296     int active;
0297 };
0298 
0299 static inline struct uniphier_aio *uniphier_priv(struct snd_soc_dai *dai)
0300 {
0301     struct uniphier_aio_chip *chip = snd_soc_dai_get_drvdata(dai);
0302 
0303     return &chip->aios[dai->id];
0304 }
0305 
0306 int uniphier_aiodma_soc_register_platform(struct platform_device *pdev);
0307 extern const struct snd_compress_ops uniphier_aio_compress_ops;
0308 
0309 int uniphier_aio_dai_probe(struct snd_soc_dai *dai);
0310 int uniphier_aio_dai_remove(struct snd_soc_dai *dai);
0311 int uniphier_aio_probe(struct platform_device *pdev);
0312 int uniphier_aio_remove(struct platform_device *pdev);
0313 extern const struct snd_soc_dai_ops uniphier_aio_i2s_ops;
0314 extern const struct snd_soc_dai_ops uniphier_aio_spdif_ops;
0315 
0316 u64 aio_rb_cnt(struct uniphier_aio_sub *sub);
0317 u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub);
0318 u64 aio_rb_space(struct uniphier_aio_sub *sub);
0319 u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub);
0320 
0321 void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable);
0322 int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
0323              unsigned int freq);
0324 void aio_chip_init(struct uniphier_aio_chip *chip);
0325 int aio_init(struct uniphier_aio_sub *sub);
0326 void aio_port_reset(struct uniphier_aio_sub *sub);
0327 int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
0328                const struct snd_pcm_hw_params *params);
0329 void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable);
0330 int aio_port_get_volume(struct uniphier_aio_sub *sub);
0331 void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol);
0332 int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through);
0333 int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
0334                   enum IEC61937_PC pc);
0335 void aio_src_reset(struct uniphier_aio_sub *sub);
0336 int aio_src_set_param(struct uniphier_aio_sub *sub,
0337               const struct snd_pcm_hw_params *params);
0338 int aio_srcif_set_param(struct uniphier_aio_sub *sub);
0339 int aio_srcch_set_param(struct uniphier_aio_sub *sub);
0340 void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable);
0341 
0342 int aiodma_ch_set_param(struct uniphier_aio_sub *sub);
0343 void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable);
0344 int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th);
0345 int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
0346              int period);
0347 void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
0348             int period);
0349 bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub);
0350 void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub);
0351 
0352 #endif /* SND_UNIPHIER_AIO_H__ */