linux/sound/soc/sprd/sprd-mcdt.c
<<
>>
Prefs
   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 int 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        return 0;
 988}
 989
 990static const struct of_device_id sprd_mcdt_of_match[] = {
 991        { .compatible = "sprd,sc9860-mcdt", },
 992        { }
 993};
 994MODULE_DEVICE_TABLE(of, sprd_mcdt_of_match);
 995
 996static struct platform_driver sprd_mcdt_driver = {
 997        .probe = sprd_mcdt_probe,
 998        .remove = sprd_mcdt_remove,
 999        .driver = {
1000                .name = "sprd-mcdt",
1001                .of_match_table = sprd_mcdt_of_match,
1002        },
1003};
1004
1005module_platform_driver(sprd_mcdt_driver);
1006
1007MODULE_DESCRIPTION("Spreadtrum Multi-Channel Data Transfer Driver");
1008MODULE_LICENSE("GPL v2");
1009