^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) // Copyright (C) 2019 Spreadtrum Communications Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "sprd-mcdt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* MCDT registers definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MCDT_CH0_TXD 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define MCDT_CH0_RXD 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MCDT_DAC0_WTMK 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MCDT_ADC0_WTMK 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MCDT_DMA_EN 0xb0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MCDT_INT_EN0 0xb4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MCDT_INT_EN1 0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MCDT_INT_EN2 0xbc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MCDT_INT_CLR0 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MCDT_INT_CLR1 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MCDT_INT_CLR2 0xc8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MCDT_INT_RAW1 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MCDT_INT_RAW2 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MCDT_INT_RAW3 0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MCDT_INT_MSK1 0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MCDT_INT_MSK2 0xdc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MCDT_INT_MSK3 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MCDT_DAC0_FIFO_ADDR_ST 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MCDT_ADC0_FIFO_ADDR_ST 0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MCDT_CH_FIFO_ST0 0x134
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MCDT_CH_FIFO_ST1 0x138
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MCDT_CH_FIFO_ST2 0x13c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MCDT_INT_MSK_CFG0 0x140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MCDT_INT_MSK_CFG1 0x144
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MCDT_DMA_CFG0 0x148
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MCDT_FIFO_CLR 0x14c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MCDT_DMA_CFG1 0x150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MCDT_DMA_CFG2 0x154
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MCDT_DMA_CFG3 0x158
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MCDT_DMA_CFG4 0x15c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MCDT_DMA_CFG5 0x160
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Channel water mark definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MCDT_CH_FIFO_AE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MCDT_CH_FIFO_AE_MASK GENMASK(24, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MCDT_CH_FIFO_AF_MASK GENMASK(8, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* DMA channel select definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MCDT_DMA_CH0_SEL_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MCDT_DMA_CH0_SEL_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MCDT_DMA_CH1_SEL_MASK GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MCDT_DMA_CH1_SEL_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MCDT_DMA_CH2_SEL_MASK GENMASK(11, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MCDT_DMA_CH2_SEL_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MCDT_DMA_CH3_SEL_MASK GENMASK(15, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MCDT_DMA_CH3_SEL_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MCDT_DMA_CH4_SEL_MASK GENMASK(19, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MCDT_DMA_CH4_SEL_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MCDT_DAC_DMA_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* DMA channel ACK select definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define MCDT_DMA_ACK_SEL_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Channel FIFO definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define MCDT_CH_FIFO_ADDR_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MCDT_CH_FIFO_ADDR_MASK GENMASK(9, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define MCDT_ADC_FIFO_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MCDT_FIFO_LENGTH 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define MCDT_ADC_CHANNEL_NUM 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define MCDT_DAC_CHANNEL_NUM 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define MCDT_CHANNEL_NUM (MCDT_ADC_CHANNEL_NUM + MCDT_DAC_CHANNEL_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) enum sprd_mcdt_fifo_int {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MCDT_ADC_FIFO_AE_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MCDT_ADC_FIFO_AF_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MCDT_DAC_FIFO_AE_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MCDT_DAC_FIFO_AF_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MCDT_ADC_FIFO_OV_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MCDT_DAC_FIFO_OV_INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) enum sprd_mcdt_fifo_sts {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) MCDT_ADC_FIFO_REAL_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MCDT_ADC_FIFO_REAL_EMPTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MCDT_ADC_FIFO_AF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MCDT_ADC_FIFO_AE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MCDT_DAC_FIFO_REAL_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MCDT_DAC_FIFO_REAL_EMPTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MCDT_DAC_FIFO_AF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) MCDT_DAC_FIFO_AE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct sprd_mcdt_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct sprd_mcdt_chan chan[MCDT_CHANNEL_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static LIST_HEAD(sprd_mcdt_chan_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static DEFINE_MUTEX(sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void sprd_mcdt_update(struct sprd_mcdt_dev *mcdt, u32 reg, u32 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u32 orig = readl_relaxed(mcdt->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) tmp = (orig & ~mask) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) writel_relaxed(tmp, mcdt->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void sprd_mcdt_dac_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 full, u32 empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u32 reg = MCDT_DAC0_WTMK + channel * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u32 water_mark =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) (empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) water_mark |= full & MCDT_CH_FIFO_AF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) sprd_mcdt_update(mcdt, reg, water_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void sprd_mcdt_adc_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 full, u32 empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 reg = MCDT_ADC0_WTMK + channel * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 water_mark =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) (empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) water_mark |= full & MCDT_CH_FIFO_AF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) sprd_mcdt_update(mcdt, reg, water_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void sprd_mcdt_dac_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u32 shift = MCDT_DAC_DMA_SHIFT + channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(shift), BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static void sprd_mcdt_adc_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(channel), BIT(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void sprd_mcdt_ap_int_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, BIT(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) BIT(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, 0, BIT(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void sprd_mcdt_dac_write_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 reg = MCDT_CH0_TXD + channel * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) writel_relaxed(val, mcdt->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void sprd_mcdt_adc_read_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u32 reg = MCDT_CH0_RXD + channel * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *val = readl_relaxed(mcdt->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void sprd_mcdt_dac_dma_chn_select(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) enum sprd_mcdt_dma_chan dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) switch (dma_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case SPRD_MCDT_DMA_CH0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) channel << MCDT_DMA_CH0_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) MCDT_DMA_CH0_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case SPRD_MCDT_DMA_CH1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) channel << MCDT_DMA_CH1_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) MCDT_DMA_CH1_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case SPRD_MCDT_DMA_CH2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) channel << MCDT_DMA_CH2_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) MCDT_DMA_CH2_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case SPRD_MCDT_DMA_CH3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) channel << MCDT_DMA_CH3_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) MCDT_DMA_CH3_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case SPRD_MCDT_DMA_CH4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) channel << MCDT_DMA_CH4_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) MCDT_DMA_CH4_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static void sprd_mcdt_adc_dma_chn_select(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) enum sprd_mcdt_dma_chan dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) switch (dma_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case SPRD_MCDT_DMA_CH0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) channel << MCDT_DMA_CH0_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) MCDT_DMA_CH0_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case SPRD_MCDT_DMA_CH1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) channel << MCDT_DMA_CH1_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) MCDT_DMA_CH1_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case SPRD_MCDT_DMA_CH2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) channel << MCDT_DMA_CH2_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MCDT_DMA_CH2_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case SPRD_MCDT_DMA_CH3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) channel << MCDT_DMA_CH3_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) MCDT_DMA_CH3_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case SPRD_MCDT_DMA_CH4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) channel << MCDT_DMA_CH4_SEL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MCDT_DMA_CH4_SEL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static u32 sprd_mcdt_dma_ack_shift(u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return 28;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void sprd_mcdt_dac_dma_ack_select(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) enum sprd_mcdt_dma_chan dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 reg, shift = sprd_mcdt_dma_ack_shift(channel), ack = dma_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case 0 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) reg = MCDT_DMA_CFG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) reg = MCDT_DMA_CFG3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sprd_mcdt_update(mcdt, reg, ack << shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) MCDT_DMA_ACK_SEL_MASK << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void sprd_mcdt_adc_dma_ack_select(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) enum sprd_mcdt_dma_chan dma_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u32 reg, shift = sprd_mcdt_dma_ack_shift(channel), ack = dma_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case 0 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) reg = MCDT_DMA_CFG4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) reg = MCDT_DMA_CFG5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sprd_mcdt_update(mcdt, reg, ack << shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) MCDT_DMA_ACK_SEL_MASK << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static bool sprd_mcdt_chan_fifo_sts(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) enum sprd_mcdt_fifo_sts fifo_sts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u32 reg, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case 0 ... 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) reg = MCDT_CH_FIFO_ST0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case 4 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) reg = MCDT_CH_FIFO_ST1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) reg = MCDT_CH_FIFO_ST2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return false;
^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) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) shift = fifo_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) shift = 8 + fifo_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) shift = 16 + fifo_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) shift = 24 + fifo_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return !!(readl_relaxed(mcdt->base + reg) & BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void sprd_mcdt_dac_fifo_clear(struct sprd_mcdt_dev *mcdt, u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) sprd_mcdt_update(mcdt, MCDT_FIFO_CLR, BIT(channel), BIT(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static void sprd_mcdt_adc_fifo_clear(struct sprd_mcdt_dev *mcdt, u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 shift = MCDT_ADC_FIFO_SHIFT + channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) sprd_mcdt_update(mcdt, MCDT_FIFO_CLR, BIT(shift), BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static u32 sprd_mcdt_dac_fifo_avail(struct sprd_mcdt_dev *mcdt, u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) u32 reg = MCDT_DAC0_FIFO_ADDR_ST + channel * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u32 r_addr = (readl_relaxed(mcdt->base + reg) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) MCDT_CH_FIFO_ADDR_SHIFT) & MCDT_CH_FIFO_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u32 w_addr = readl_relaxed(mcdt->base + reg) & MCDT_CH_FIFO_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (w_addr >= r_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 4 * (MCDT_FIFO_LENGTH - w_addr + r_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 4 * (r_addr - w_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static u32 sprd_mcdt_adc_fifo_avail(struct sprd_mcdt_dev *mcdt, u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u32 reg = MCDT_ADC0_FIFO_ADDR_ST + channel * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) u32 r_addr = (readl_relaxed(mcdt->base + reg) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MCDT_CH_FIFO_ADDR_SHIFT) & MCDT_CH_FIFO_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u32 w_addr = readl_relaxed(mcdt->base + reg) & MCDT_CH_FIFO_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (w_addr >= r_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return 4 * (w_addr - r_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 4 * (MCDT_FIFO_LENGTH - r_addr + w_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static u32 sprd_mcdt_int_type_shift(u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) enum sprd_mcdt_fifo_int int_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return 8 + int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 16 + int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 24 + int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^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) static void sprd_mcdt_chan_int_en(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) enum sprd_mcdt_fifo_int int_type, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case 0 ... 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) reg = MCDT_INT_EN0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case 4 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) reg = MCDT_INT_EN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) reg = MCDT_INT_EN2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) sprd_mcdt_update(mcdt, reg, BIT(shift), BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sprd_mcdt_update(mcdt, reg, 0, BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static void sprd_mcdt_chan_int_clear(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) enum sprd_mcdt_fifo_int int_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case 0 ... 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) reg = MCDT_INT_CLR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case 4 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) reg = MCDT_INT_CLR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) reg = MCDT_INT_CLR2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) sprd_mcdt_update(mcdt, reg, BIT(shift), BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static bool sprd_mcdt_chan_int_sts(struct sprd_mcdt_dev *mcdt, u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) enum sprd_mcdt_fifo_int int_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) case 0 ... 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) reg = MCDT_INT_MSK1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) case 4 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) reg = MCDT_INT_MSK2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case 8 ... 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) reg = MCDT_INT_MSK3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return !!(readl_relaxed(mcdt->base + reg) & BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static irqreturn_t sprd_mcdt_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sprd_mcdt_dev *mcdt = (struct sprd_mcdt_dev *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) spin_lock(&mcdt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) for (i = 0; i < MCDT_ADC_CHANNEL_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (sprd_mcdt_chan_int_sts(mcdt, i, MCDT_ADC_FIFO_AF_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct sprd_mcdt_chan *chan = &mcdt->chan[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) sprd_mcdt_chan_int_clear(mcdt, i, MCDT_ADC_FIFO_AF_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (chan->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) chan->cb->notify(chan->cb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) for (i = 0; i < MCDT_DAC_CHANNEL_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (sprd_mcdt_chan_int_sts(mcdt, i, MCDT_DAC_FIFO_AE_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct sprd_mcdt_chan *chan =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) &mcdt->chan[i + MCDT_ADC_CHANNEL_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sprd_mcdt_chan_int_clear(mcdt, i, MCDT_DAC_FIFO_AE_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (chan->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) chan->cb->notify(chan->cb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_unlock(&mcdt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * sprd_mcdt_chan_write - write data to the MCDT channel's fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * @tx_buf: send buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @size: data size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * Note: We can not write data to the channel fifo when enabling the DMA mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * otherwise the channel fifo data will be invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * If there are not enough space of the channel fifo, it will return errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * to users.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Returns 0 on success, or an appropriate error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int sprd_mcdt_chan_write(struct sprd_mcdt_chan *chan, char *tx_buf, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int avail, i = 0, words = size / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) u32 *buf = (u32 *)tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (chan->dma_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dev_err(mcdt->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) "Can not write data when DMA mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (sprd_mcdt_chan_fifo_sts(mcdt, chan->id, MCDT_DAC_FIFO_REAL_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dev_err(mcdt->dev, "Channel fifo is full now\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) avail = sprd_mcdt_dac_fifo_avail(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (size > avail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dev_err(mcdt->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) "Data size is larger than the available fifo size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) while (i++ < words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) sprd_mcdt_dac_write_fifo(mcdt, chan->id, *buf++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * sprd_mcdt_chan_read - read data from the MCDT channel's fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * @rx_buf: receive buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * @size: data size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * Note: We can not read data from the channel fifo when enabling the DMA mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * otherwise the reading data will be invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Usually user need start to read data once receiving the fifo full interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * Returns data size of reading successfully, or an error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int sprd_mcdt_chan_read(struct sprd_mcdt_chan *chan, char *rx_buf, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int i = 0, avail, words = size / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) u32 *buf = (u32 *)rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (chan->dma_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dev_err(mcdt->dev, "Can not read data when DMA mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -EINVAL;
^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) if (sprd_mcdt_chan_fifo_sts(mcdt, chan->id, MCDT_ADC_FIFO_REAL_EMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dev_err(mcdt->dev, "Channel fifo is empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) avail = sprd_mcdt_adc_fifo_avail(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (size > avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) words = avail / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) while (i++ < words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) sprd_mcdt_adc_read_fifo(mcdt, chan->id, buf++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return words * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * sprd_mcdt_chan_int_enable - enable the interrupt mode for the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * @water_mark: water mark to trigger a interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * @cb: callback when a interrupt happened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * Now it only can enable fifo almost full interrupt for ADC channel and fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * almost empty interrupt for DAC channel. Morevoer for interrupt mode, user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * should use sprd_mcdt_chan_read() or sprd_mcdt_chan_write() to read or write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * data manually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * For ADC channel, user can start to read data once receiving one fifo full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * interrupt. For DAC channel, user can start to write data once receiving one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * fifo empty interrupt or just call sprd_mcdt_chan_write() to write data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * Returns 0 on success, or an error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int sprd_mcdt_chan_int_enable(struct sprd_mcdt_chan *chan, u32 water_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct sprd_mcdt_chan_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (chan->dma_enable || chan->int_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev_err(mcdt->dev, "Failed to set interrupt mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case SPRD_MCDT_ADC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) sprd_mcdt_adc_set_watermark(mcdt, chan->id, water_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) MCDT_FIFO_LENGTH - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) sprd_mcdt_chan_int_en(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) MCDT_ADC_FIFO_AF_INT, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) sprd_mcdt_ap_int_enable(mcdt, chan->id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case SPRD_MCDT_DAC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) sprd_mcdt_dac_set_watermark(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) MCDT_FIFO_LENGTH - 1, water_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) sprd_mcdt_chan_int_en(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) MCDT_DAC_FIFO_AE_INT, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sprd_mcdt_ap_int_enable(mcdt, chan->id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) dev_err(mcdt->dev, "Unsupported channel type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) chan->cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) chan->int_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_int_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * sprd_mcdt_chan_int_disable - disable the interrupt mode for the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) void sprd_mcdt_chan_int_disable(struct sprd_mcdt_chan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!chan->int_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case SPRD_MCDT_ADC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) sprd_mcdt_chan_int_en(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) MCDT_ADC_FIFO_AF_INT, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sprd_mcdt_chan_int_clear(mcdt, chan->id, MCDT_ADC_FIFO_AF_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) sprd_mcdt_ap_int_enable(mcdt, chan->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case SPRD_MCDT_DAC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sprd_mcdt_chan_int_en(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) MCDT_DAC_FIFO_AE_INT, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) sprd_mcdt_chan_int_clear(mcdt, chan->id, MCDT_DAC_FIFO_AE_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) sprd_mcdt_ap_int_enable(mcdt, chan->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) chan->int_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_int_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * sprd_mcdt_chan_dma_enable - enable the DMA mode for the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * @dma_chan: specify which DMA channel will be used for this MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * @water_mark: water mark to trigger a DMA request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Enable the DMA mode for the MCDT channel, that means we can use DMA to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * transfer data to the channel fifo and do not need reading/writing data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * manually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * Returns 0 on success, or an error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int sprd_mcdt_chan_dma_enable(struct sprd_mcdt_chan *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) enum sprd_mcdt_dma_chan dma_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) u32 water_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (chan->dma_enable || chan->int_enable ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dma_chan > SPRD_MCDT_DMA_CH4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) dev_err(mcdt->dev, "Failed to set DMA mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case SPRD_MCDT_ADC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) sprd_mcdt_adc_set_watermark(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) water_mark, MCDT_FIFO_LENGTH - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) sprd_mcdt_adc_dma_enable(mcdt, chan->id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) sprd_mcdt_adc_dma_chn_select(mcdt, chan->id, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) sprd_mcdt_adc_dma_ack_select(mcdt, chan->id, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case SPRD_MCDT_DAC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) sprd_mcdt_dac_set_watermark(mcdt, chan->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) MCDT_FIFO_LENGTH - 1, water_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) sprd_mcdt_dac_dma_enable(mcdt, chan->id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sprd_mcdt_dac_dma_chn_select(mcdt, chan->id, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) sprd_mcdt_dac_dma_ack_select(mcdt, chan->id, dma_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dev_err(mcdt->dev, "Unsupported channel type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) chan->dma_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_dma_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * sprd_mcdt_chan_dma_disable - disable the DMA mode for the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * @chan: the MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) void sprd_mcdt_chan_dma_disable(struct sprd_mcdt_chan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct sprd_mcdt_dev *mcdt = chan->mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) spin_lock_irqsave(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!chan->dma_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case SPRD_MCDT_ADC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) sprd_mcdt_adc_dma_enable(mcdt, chan->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case SPRD_MCDT_DAC_CHAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) sprd_mcdt_dac_dma_enable(mcdt, chan->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) chan->dma_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) spin_unlock_irqrestore(&mcdt->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) EXPORT_SYMBOL_GPL(sprd_mcdt_chan_dma_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * sprd_mcdt_request_chan - request one MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @channel: channel id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * @type: channel type, it can be one ADC channel or DAC channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * Rreturn NULL if no available channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) enum sprd_mcdt_channel_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct sprd_mcdt_chan *temp, *chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mutex_lock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) list_for_each_entry(temp, &sprd_mcdt_chan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (temp->type == type && temp->id == channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) chan = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) list_del(&chan->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) mutex_unlock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) EXPORT_SYMBOL_GPL(sprd_mcdt_request_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * sprd_mcdt_free_chan - free one MCDT channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * @chan: the channel to be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) void sprd_mcdt_free_chan(struct sprd_mcdt_chan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct sprd_mcdt_chan *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) sprd_mcdt_chan_dma_disable(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) sprd_mcdt_chan_int_disable(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) mutex_lock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) list_for_each_entry(temp, &sprd_mcdt_chan_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (temp == chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) mutex_unlock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) list_add_tail(&chan->list, &sprd_mcdt_chan_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) mutex_unlock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) EXPORT_SYMBOL_GPL(sprd_mcdt_free_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static void sprd_mcdt_init_chans(struct sprd_mcdt_dev *mcdt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) for (i = 0; i < MCDT_CHANNEL_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct sprd_mcdt_chan *chan = &mcdt->chan[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (i < MCDT_ADC_CHANNEL_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) chan->id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) chan->type = SPRD_MCDT_ADC_CHAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) chan->fifo_phys = res->start + MCDT_CH0_RXD + i * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) chan->id = i - MCDT_ADC_CHANNEL_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) chan->type = SPRD_MCDT_DAC_CHAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) chan->fifo_phys = res->start + MCDT_CH0_TXD +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) (i - MCDT_ADC_CHANNEL_NUM) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) chan->mcdt = mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) INIT_LIST_HEAD(&chan->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mutex_lock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) list_add_tail(&chan->list, &sprd_mcdt_chan_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mutex_unlock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static int sprd_mcdt_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct sprd_mcdt_dev *mcdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mcdt = devm_kzalloc(&pdev->dev, sizeof(*mcdt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (!mcdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mcdt->base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (IS_ERR(mcdt->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return PTR_ERR(mcdt->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mcdt->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) spin_lock_init(&mcdt->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) platform_set_drvdata(pdev, mcdt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 0, "sprd-mcdt", mcdt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) dev_err(&pdev->dev, "Failed to request MCDT IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) sprd_mcdt_init_chans(mcdt, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static int sprd_mcdt_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct sprd_mcdt_chan *chan, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mutex_lock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) list_for_each_entry_safe(chan, temp, &sprd_mcdt_chan_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) list_del(&chan->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) mutex_unlock(&sprd_mcdt_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static const struct of_device_id sprd_mcdt_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) { .compatible = "sprd,sc9860-mcdt", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) MODULE_DEVICE_TABLE(of, sprd_mcdt_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static struct platform_driver sprd_mcdt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) .probe = sprd_mcdt_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .remove = sprd_mcdt_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .name = "sprd-mcdt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .of_match_table = sprd_mcdt_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) module_platform_driver(sprd_mcdt_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) MODULE_DESCRIPTION("Spreadtrum Multi-Channel Data Transfer Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) MODULE_LICENSE("GPL v2");