File Index
Files and directories
Sign in
FILE

sprd-mcdt.c

File preview with syntax highlighting.

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