^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2014 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Author: Nicolin Chen <nicoleotsuka@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_data/dma-imx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "fsl_asrc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define IDEAL_RATIO_DECIMAL_DEPTH 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define DIVIDER_NUM 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define pair_err(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define pair_dbg(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Corresponding to process_option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static unsigned int supported_asrc_rate[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 64000, 88200, 96000, 128000, 176400, 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .count = ARRAY_SIZE(supported_asrc_rate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .list = supported_asrc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * The following tables map the relationship between asrc_inclk/asrc_outclk in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * fsl_asrc.h and the registers of ASRCSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static unsigned char input_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static unsigned char output_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* i.MX53 uses the same map for input and output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static unsigned char input_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * i.MX8QM/i.MX8QXP uses the same map for input and output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * clk_map_imx8qm[0] is for i.MX8QM asrc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * clk_map_imx8qm[1] is for i.MX8QM asrc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * clk_map_imx8qxp[0] is for i.MX8QXP asrc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * clk_map_imx8qxp[1] is for i.MX8QXP asrc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static unsigned char clk_map_imx8qm[2][ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xf, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0x0, 0x1, 0x2, 0x3, 0x7, 0x8, 0xf, 0xf, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * According to RM, the divider range is 1 ~ 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * prescaler is power of 2 from 1 ~ 128.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int asrc_clk_divider[DIVIDER_NUM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Check if the divider is available for internal ratio mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 rem, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u64 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (clk_rate == 0 || rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) n = clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rem = do_div(n, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *div = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (rem != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) for (i = 0; i < DIVIDER_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (n == asrc_clk_divider[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (i == DIVIDER_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @inrate: input sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @outrate: output sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @pre_proc: return value for pre-processing option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @post_proc: return value for post-processing option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Make sure to exclude following unsupported cases before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * calling this function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * 1) inrate > 8.125 * outrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * 2) inrate > 16.125 * outrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void fsl_asrc_sel_proc(int inrate, int outrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int *pre_proc, int *post_proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) bool post_proc_cond2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) bool post_proc_cond0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* select pre_proc between [0, 2] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (inrate * 8 > 33 * outrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *pre_proc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else if (inrate * 8 > 15 * outrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (inrate > 152000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *pre_proc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *pre_proc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else if (inrate < 76000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *pre_proc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) else if (inrate > 152000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *pre_proc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *pre_proc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Condition for selection of post-processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) (inrate > 56000 && outrate < 56000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) post_proc_cond0 = inrate * 23 < outrate * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (post_proc_cond2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *post_proc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) else if (post_proc_cond0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *post_proc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *post_proc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * fsl_asrc_request_pair - Request ASRC pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * @channels: number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * It assigns pair by the order of A->C->B because allocation of pair B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * while pair A and pair C are comparatively independent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enum asrc_pair_index index = ASRC_INVALID_PAIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct device *dev = &asrc->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned long lock_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) spin_lock_irqsave(&asrc->lock, lock_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (asrc->pair[i] != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (i != ASRC_PAIR_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (index == ASRC_INVALID_PAIR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_err(dev, "all pairs are busy now\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else if (asrc->channel_avail < channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_err(dev, "can't afford required channels: %d\n", channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) asrc->channel_avail -= channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) asrc->pair[index] = pair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pair->channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) pair->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) spin_unlock_irqrestore(&asrc->lock, lock_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * fsl_asrc_release_pair - Release ASRC pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * @pair: pair to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * It clears the resource from asrc and releases the occupied channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned long lock_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Make sure the pair is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ASRCTR_ASRCEi_MASK(index), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) spin_lock_irqsave(&asrc->lock, lock_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) asrc->channel_avail += pair->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) asrc->pair[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pair->error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_unlock_irqrestore(&asrc->lock, lock_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * fsl_asrc_set_watermarks- configure input and output thresholds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * @in: input threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @out: output threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ASRMCRi_EXTTHRSHi_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ASRMCRi_INFIFO_THRESHOLD_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ASRMCRi_OUTFIFO_THRESHOLD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ASRMCRi_EXTTHRSHi |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ASRMCRi_INFIFO_THRESHOLD(in) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ASRMCRi_OUTFIFO_THRESHOLD(out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * @div: divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u32 ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) for (ps = 0; div > 8; ps++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) div >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @inrate: input rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * @outrate: output rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * The ratio is a 32-bit fixed point value with 26 fractional bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int inrate, int outrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!outrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) pair_err("output rate should not be zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Calculate the intergal part of the ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* ... and then the 26 depth decimal part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) inrate %= outrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) inrate <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (inrate < outrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) inrate -= outrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!inrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * fsl_asrc_config_pair - Configure the assigned ASRC pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @use_ideal_rate: boolean configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * It configures those ASRC registers according to a configuration instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * of struct asrc_config which includes in/output sample rate, width, channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * and clock settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * The ideal ratio configuration can work with a flexible clock rate setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * Using IDEAL_RATIO_RATE gives a faster converting speed but overloads ASRC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * For a regular audio playback, the clock rate should not be slower than an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * clock rate aligning with the output sample rate; For a use case requiring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * faster conversion, set use_ideal_rate to have the faster speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct fsl_asrc_pair_priv *pair_priv = pair->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct asrc_config *config = pair_priv->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct fsl_asrc_priv *asrc_priv = asrc->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) enum asrc_word_width input_word_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) enum asrc_word_width output_word_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) u32 inrate, outrate, indiv, outdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u32 clk_index[2], div[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u64 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int in, out, channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int pre_proc, post_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) bool ideal, div_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pair_err("invalid pair config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Validate channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (config->channel_num < 1 || config->channel_num > 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pair_err("does not support %d channels\n", config->channel_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) switch (snd_pcm_format_width(config->input_format)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) input_word_width = ASRC_WIDTH_8_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) input_word_width = ASRC_WIDTH_16_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) input_word_width = ASRC_WIDTH_24_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pair_err("does not support this input format, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) config->input_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) switch (snd_pcm_format_width(config->output_format)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) output_word_width = ASRC_WIDTH_16_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) output_word_width = ASRC_WIDTH_24_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pair_err("does not support this output format, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) config->output_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) inrate = config->input_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) outrate = config->output_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ideal = config->inclk == INCLK_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Validate input and output sample rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (inrate == supported_asrc_rate[in])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (in == ARRAY_SIZE(supported_asrc_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) pair_err("unsupported input sample rate: %dHz\n", inrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) for (out = 0; out < ARRAY_SIZE(supported_asrc_rate); out++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (outrate == supported_asrc_rate[out])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (out == ARRAY_SIZE(supported_asrc_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pair_err("unsupported output sample rate: %dHz\n", outrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if ((outrate >= 5512 && outrate <= 30000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) (outrate > 24 * inrate || inrate > 8 * outrate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pair_err("exceed supported ratio range [1/24, 8] for \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) inrate/outrate: %d/%d\n", inrate, outrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Validate input and output clock sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* We only have output clock for ideal ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) clk_rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * The divider range is [1, 1024], defined by the hardware. For non-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * ideal ratio configuration, clock rate has to be strictly aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * with the sample rate. For ideal ratio configuration, clock rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * only result in different converting speeds. So remainder does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * matter, as long as we keep the divider within its valid range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (div[IN] == 0 || (!ideal && !div_avail)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pair_err("failed to support input sample rate %dHz by asrck_%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) inrate, clk_index[ideal ? OUT : IN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) div[IN] = min_t(u32, 1024, div[IN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) clk = asrc_priv->asrck_clk[clk_index[OUT]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) clk_rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ideal && use_ideal_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Output divider has the same limitation as the input one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (div[OUT] == 0 || (!ideal && !div_avail)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pair_err("failed to support output sample rate %dHz by asrck_%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) outrate, clk_index[OUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) div[OUT] = min_t(u32, 1024, div[OUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* Set the channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) channels = config->channel_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (asrc_priv->soc->channel_bits < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) channels /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Update channels for current pair */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) regmap_update_bits(asrc->regmap, REG_ASRCNCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Default setting: Automatic selection for processing mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ASRCTR_USRi_MASK(index), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* Set the input and output clock sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) regmap_update_bits(asrc->regmap, REG_ASRCSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ASRCSR_AICSi_MASK(index) | ASRCSR_AOCSi_MASK(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ASRCSR_AICS(index, clk_index[IN]) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ASRCSR_AOCS(index, clk_index[OUT]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* Calculate the input clock divisors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) indiv = fsl_asrc_cal_asrck_divisor(pair, div[IN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) outdiv = fsl_asrc_cal_asrck_divisor(pair, div[OUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* Suppose indiv and outdiv includes prescaler, so add its MASK too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ASRCDRi_AOCPi_MASK(index) | ASRCDRi_AICPi_MASK(index) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ASRCDRi_AOCDi_MASK(index) | ASRCDRi_AICDi_MASK(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ASRCDRi_AOCP(index, outdiv) | ASRCDRi_AICP(index, indiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Implement word_width configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ASRMCR1i_OW16_MASK | ASRMCR1i_IWD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ASRMCR1i_OW16(output_word_width) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ASRMCR1i_IWD(input_word_width));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* Enable BUFFER STALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Set default thresholds for input and output FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ASRC_INPUTFIFO_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Configure the following only for Ideal Ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!ideal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Clear ASTSx bit to use Ideal Ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ASRCTR_ATSi_MASK(index), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* Enable Ideal Ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ASRCTR_IDR(index) | ASRCTR_USR(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* Apply configurations for pre- and post-processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) regmap_update_bits(asrc->regmap, REG_ASRCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ASRCFG_PREMOD(index, pre_proc) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ASRCFG_POSTMOD(index, post_proc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * fsl_asrc_start_pair - Start the assigned ASRC pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * It enables the assigned pair and makes it stopped at the stall level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int reg, retry = 10, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* Enable the current pair */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Wait for status of initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) regmap_read(asrc->regmap, REG_ASRCFG, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) reg &= ASRCFG_INIRQi_MASK(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) } while (!reg && --retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Make the input fifo to ASRC STALL level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) regmap_read(asrc->regmap, REG_ASRCNCR, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) for (i = 0; i < pair->channels * 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) regmap_write(asrc->regmap, REG_ASRDI(index), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* Enable overload interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * fsl_asrc_stop_pair - Stop the assigned ASRC pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Stop the current pair */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ASRCTR_ASRCEi_MASK(index), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * @pair: pointer to pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * @dir: DMA direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) bool dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct fsl_asrc *asrc = pair->asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) enum asrc_pair_index index = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) char name[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sprintf(name, "%cx%c", dir == IN ? 'r' : 't', index + 'a');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return dma_request_slave_channel(&asrc->pdev->dev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct fsl_asrc_priv *asrc_priv = asrc->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* Odd channel number is not valid for older ASRC (channel_bits==3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (asrc_priv->soc->channel_bits == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) snd_pcm_hw_constraint_step(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) SNDRV_PCM_HW_PARAM_CHANNELS, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return snd_pcm_hw_constraint_list(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Select proper clock source for internal ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct fsl_asrc_pair *pair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int in_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int out_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct fsl_asrc_pair_priv *pair_priv = pair->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct asrc_config *config = pair_priv->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int clk_rate, clk_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int i = 0, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) rate[IN] = in_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) rate[OUT] = out_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Select proper clock source for internal ratio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) for (j = 0; j < 2; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) clk_index = asrc_priv->clk_map[j][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* Only match a perfect clock source with no remainder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) select_clk[j] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* Switch to ideal ratio mode if there is no proper clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == ASRC_CLK_MAP_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) select_clk[IN] = INCLK_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) select_clk[OUT] = OUTCLK_ASRCK1_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) config->inclk = select_clk[IN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) config->outclk = select_clk[OUT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct fsl_asrc_priv *asrc_priv = asrc->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct fsl_asrc_pair *pair = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct fsl_asrc_pair_priv *pair_priv = pair->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned int channels = params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned int rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct asrc_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ret = fsl_asrc_request_pair(channels, pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_err(dai->dev, "fail to request asrc pair\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) pair_priv->config = &config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) config.pair = pair->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) config.channel_num = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) config.input_format = params_format(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) config.output_format = asrc->asrc_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) config.input_sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) config.output_sample_rate = asrc->asrc_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) config.input_format = asrc->asrc_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) config.output_format = params_format(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) config.input_sample_rate = asrc->asrc_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) config.output_sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) fsl_asrc_select_clk(asrc_priv, pair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) config.input_sample_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) config.output_sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = fsl_asrc_config_pair(pair, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dev_err(dai->dev, "fail to config asrc pair\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct fsl_asrc_pair *pair = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) fsl_asrc_release_pair(pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct fsl_asrc_pair *pair = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) fsl_asrc_start_pair(pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) fsl_asrc_stop_pair(pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static const struct snd_soc_dai_ops fsl_asrc_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .startup = fsl_asrc_dai_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .hw_params = fsl_asrc_dai_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .hw_free = fsl_asrc_dai_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .trigger = fsl_asrc_dai_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) &asrc->dma_params_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) #define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) SNDRV_PCM_FMTBIT_S16_LE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) SNDRV_PCM_FMTBIT_S24_3LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static struct snd_soc_dai_driver fsl_asrc_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .probe = fsl_asrc_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .stream_name = "ASRC-Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .channels_max = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .rate_min = 5512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .rates = SNDRV_PCM_RATE_KNOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .formats = FSL_ASRC_FORMATS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) SNDRV_PCM_FMTBIT_S8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .stream_name = "ASRC-Capture",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .channels_max = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .rate_min = 5512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .rates = SNDRV_PCM_RATE_KNOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .formats = FSL_ASRC_FORMATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .ops = &fsl_asrc_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) case REG_ASRCTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case REG_ASRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) case REG_ASRCNCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case REG_ASRCFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) case REG_ASRCSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case REG_ASRCDR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) case REG_ASRCDR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case REG_ASRSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case REG_ASRPM1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case REG_ASRPM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case REG_ASRPM3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case REG_ASRPM4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case REG_ASRPM5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case REG_ASRTFR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case REG_ASRCCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case REG_ASRDOA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case REG_ASRDOB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case REG_ASRDOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) case REG_ASRIDRHA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) case REG_ASRIDRLA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case REG_ASRIDRHB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) case REG_ASRIDRLB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case REG_ASRIDRHC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case REG_ASRIDRLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) case REG_ASR76K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case REG_ASR56K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) case REG_ASRMCRA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) case REG_ASRFSTA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) case REG_ASRMCRB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case REG_ASRFSTB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case REG_ASRMCRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case REG_ASRFSTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) case REG_ASRMCR1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) case REG_ASRMCR1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) case REG_ASRMCR1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static bool fsl_asrc_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) case REG_ASRSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case REG_ASRDIA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case REG_ASRDIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case REG_ASRDIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case REG_ASRDOA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) case REG_ASRDOB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case REG_ASRDOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case REG_ASRFSTA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case REG_ASRFSTB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case REG_ASRFSTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case REG_ASRCFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) case REG_ASRCTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case REG_ASRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case REG_ASRCNCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case REG_ASRCFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case REG_ASRCSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case REG_ASRCDR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) case REG_ASRCDR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case REG_ASRSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case REG_ASRPM1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) case REG_ASRPM2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case REG_ASRPM3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) case REG_ASRPM4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) case REG_ASRPM5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case REG_ASRTFR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) case REG_ASRCCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case REG_ASRDIA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case REG_ASRDIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) case REG_ASRDIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case REG_ASRIDRHA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case REG_ASRIDRLA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case REG_ASRIDRHB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) case REG_ASRIDRLB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) case REG_ASRIDRHC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case REG_ASRIDRLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case REG_ASR76K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case REG_ASR56K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case REG_ASRMCRA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case REG_ASRMCRB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case REG_ASRMCRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case REG_ASRMCR1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case REG_ASRMCR1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case REG_ASRMCR1C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static struct reg_default fsl_asrc_reg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) { REG_ASRCTR, 0x0000 }, { REG_ASRIER, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) { REG_ASRCNCR, 0x0000 }, { REG_ASRCFG, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) { REG_ASRCSR, 0x0000 }, { REG_ASRCDR1, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) { REG_ASRCDR2, 0x0000 }, { REG_ASRSTR, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) { REG_ASRRA, 0x0000 }, { REG_ASRRB, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) { REG_ASRRC, 0x0000 }, { REG_ASRPM1, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) { REG_ASRPM2, 0x0000 }, { REG_ASRPM3, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) { REG_ASRPM4, 0x0000 }, { REG_ASRPM5, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) { REG_ASRTFR1, 0x0000 }, { REG_ASRCCR, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) { REG_ASRDIA, 0x0000 }, { REG_ASRDOA, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) { REG_ASRDIB, 0x0000 }, { REG_ASRDOB, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) { REG_ASRDIC, 0x0000 }, { REG_ASRDOC, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) { REG_ASRIDRHA, 0x0000 }, { REG_ASRIDRLA, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) { REG_ASRIDRHB, 0x0000 }, { REG_ASRIDRLB, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) { REG_ASRIDRHC, 0x0000 }, { REG_ASRIDRLC, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) { REG_ASR76K, 0x0A47 }, { REG_ASR56K, 0x0DF3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) { REG_ASRMCRA, 0x0000 }, { REG_ASRFSTA, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) { REG_ASRMCRB, 0x0000 }, { REG_ASRFSTB, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) { REG_ASRMCRC, 0x0000 }, { REG_ASRFSTC, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) { REG_ASRMCR1A, 0x0000 }, { REG_ASRMCR1B, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) { REG_ASRMCR1C, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static const struct regmap_config fsl_asrc_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .max_register = REG_ASRMCR1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .reg_defaults = fsl_asrc_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .num_reg_defaults = ARRAY_SIZE(fsl_asrc_reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .readable_reg = fsl_asrc_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .volatile_reg = fsl_asrc_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .writeable_reg = fsl_asrc_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * fsl_asrc_init - Initialize ASRC registers with a default configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * @asrc: ASRC context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static int fsl_asrc_init(struct fsl_asrc *asrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) unsigned long ipg_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* Disable interrupt by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) regmap_write(asrc->regmap, REG_ASRIER, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* Apply recommended settings for parameters from Reference Manual */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* Base address for task queue FIFO. Set to 0x7C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) regmap_update_bits(asrc->regmap, REG_ASRTFR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * Set the period of the 76KHz and 56KHz sampling clocks based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * the ASRC processing clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * On iMX6, ipg_clk = 133MHz, REG_ASR76K = 0x06D6, REG_ASR56K = 0x0947
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ipg_rate = clk_get_rate(asrc->ipg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * fsl_asrc_isr- Interrupt handler for ASRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * @irq: irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * @dev_id: ASRC context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct device *dev = &asrc->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) enum asrc_pair_index index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) regmap_read(asrc->regmap, REG_ASRSTR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* Clean overload error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * We here use dev_dbg() for all exceptions because ASRC itself does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * not care if FIFO overflowed or underrun while a warning in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * interrupt would result a ridged conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!asrc->pair[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (status & ASRSTR_ATQOL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) dev_dbg(dev, "ASRC Task Queue FIFO overload\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (status & ASRSTR_AOOL(index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) pair_dbg("Output Task Overload\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (status & ASRSTR_AIOL(index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) pair_dbg("Input Task Overload\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (status & ASRSTR_AODO(index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) pair_dbg("Output Data Buffer has overflowed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (status & ASRSTR_AIDU(index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pair_dbg("Input Data Buffer has underflowed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return REG_ASRDx(dir, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int fsl_asrc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct fsl_asrc_priv *asrc_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct fsl_asrc *asrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) int irq, ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) u32 map_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) char tmp[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (!asrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (!asrc_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) asrc->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) asrc->private = asrc_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* Get the addresses and IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) regs = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) asrc->paddr = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "mem", regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) &fsl_asrc_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (IS_ERR(asrc->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) dev_err(&pdev->dev, "failed to init regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return PTR_ERR(asrc->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) dev_name(&pdev->dev), asrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (IS_ERR(asrc->mem_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dev_err(&pdev->dev, "failed to get mem clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return PTR_ERR(asrc->mem_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (IS_ERR(asrc->ipg_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) dev_err(&pdev->dev, "failed to get ipg clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return PTR_ERR(asrc->ipg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (IS_ERR(asrc->spba_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) dev_warn(&pdev->dev, "failed to get spba clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) sprintf(tmp, "asrck_%x", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (IS_ERR(asrc_priv->asrck_clk[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return PTR_ERR(asrc_priv->asrck_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) asrc_priv->soc = of_device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (!asrc_priv->soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dev_err(&pdev->dev, "failed to get soc data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) asrc->use_edma = asrc_priv->soc->use_edma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) asrc->get_dma_channel = fsl_asrc_get_dma_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) asrc->request_pair = fsl_asrc_request_pair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) asrc->release_pair = fsl_asrc_release_pair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) asrc->get_fifo_addr = fsl_asrc_get_fifo_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) asrc_priv->clk_map[IN] = input_clk_map_imx35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) asrc_priv->clk_map[OUT] = output_clk_map_imx35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) asrc_priv->clk_map[IN] = input_clk_map_imx53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) asrc_priv->clk_map[OUT] = output_clk_map_imx53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) of_device_is_compatible(np, "fsl,imx8qxp-asrc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) dev_err(&pdev->dev, "failed to get clk map index\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (map_idx > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) dev_err(&pdev->dev, "unsupported clk map index\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) ret = fsl_asrc_init(asrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) asrc->channel_avail = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = of_property_read_u32(np, "fsl,asrc-rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) &asrc->asrc_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dev_err(&pdev->dev, "failed to get output rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) ret = of_property_read_u32(np, "fsl,asrc-width", &width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dev_err(&pdev->dev, "failed to decide output format\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) switch (width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) "unsupported width, use default S24_LE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) platform_set_drvdata(pdev, asrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) spin_lock_init(&asrc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) regcache_cache_only(asrc->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) &fsl_asrc_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dev_err(&pdev->dev, "failed to register ASoC DAI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static int fsl_asrc_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct fsl_asrc *asrc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) struct fsl_asrc_priv *asrc_priv = asrc->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) u32 asrctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ret = clk_prepare_enable(asrc->mem_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ret = clk_prepare_enable(asrc->ipg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) goto disable_mem_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (!IS_ERR(asrc->spba_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ret = clk_prepare_enable(asrc->spba_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) goto disable_ipg_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto disable_asrck_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /* Stop all pairs provisionally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) regmap_read(asrc->regmap, REG_ASRCTR, &asrctr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) ASRCTR_ASRCEi_ALL_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* Restore all registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) regcache_cache_only(asrc->regmap, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) regcache_mark_dirty(asrc->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) regcache_sync(asrc->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) regmap_update_bits(asrc->regmap, REG_ASRCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) /* Restart enabled pairs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) regmap_update_bits(asrc->regmap, REG_ASRCTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ASRCTR_ASRCEi_ALL_MASK, asrctr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) disable_asrck_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) for (i--; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) clk_disable_unprepare(asrc_priv->asrck_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (!IS_ERR(asrc->spba_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) clk_disable_unprepare(asrc->spba_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) disable_ipg_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) clk_disable_unprepare(asrc->ipg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) disable_mem_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) clk_disable_unprepare(asrc->mem_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static int fsl_asrc_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct fsl_asrc *asrc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct fsl_asrc_priv *asrc_priv = asrc->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) regmap_read(asrc->regmap, REG_ASRCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) &asrc_priv->regcache_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) regcache_cache_only(asrc->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) clk_disable_unprepare(asrc_priv->asrck_clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (!IS_ERR(asrc->spba_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) clk_disable_unprepare(asrc->spba_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) clk_disable_unprepare(asrc->ipg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) clk_disable_unprepare(asrc->mem_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static const struct dev_pm_ops fsl_asrc_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .use_edma = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .channel_bits = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .use_edma = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) .channel_bits = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .use_edma = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .channel_bits = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .use_edma = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .channel_bits = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static const struct of_device_id fsl_asrc_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) { .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) { .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) { .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) { .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static struct platform_driver fsl_asrc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) .probe = fsl_asrc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .name = "fsl-asrc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .of_match_table = fsl_asrc_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .pm = &fsl_asrc_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) module_platform_driver(fsl_asrc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) MODULE_ALIAS("platform:fsl-asrc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) MODULE_LICENSE("GPL v2");