root/sound/soc/sprd/sprd-mcdt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sprd_mcdt_update
  2. sprd_mcdt_dac_set_watermark
  3. sprd_mcdt_adc_set_watermark
  4. sprd_mcdt_dac_dma_enable
  5. sprd_mcdt_adc_dma_enable
  6. sprd_mcdt_ap_int_enable
  7. sprd_mcdt_dac_write_fifo
  8. sprd_mcdt_adc_read_fifo
  9. sprd_mcdt_dac_dma_chn_select
  10. sprd_mcdt_adc_dma_chn_select
  11. sprd_mcdt_dma_ack_shift
  12. sprd_mcdt_dac_dma_ack_select
  13. sprd_mcdt_adc_dma_ack_select
  14. sprd_mcdt_chan_fifo_sts
  15. sprd_mcdt_dac_fifo_clear
  16. sprd_mcdt_adc_fifo_clear
  17. sprd_mcdt_dac_fifo_avail
  18. sprd_mcdt_adc_fifo_avail
  19. sprd_mcdt_int_type_shift
  20. sprd_mcdt_chan_int_en
  21. sprd_mcdt_chan_int_clear
  22. sprd_mcdt_chan_int_sts
  23. sprd_mcdt_irq_handler
  24. sprd_mcdt_chan_write
  25. sprd_mcdt_chan_read
  26. sprd_mcdt_chan_int_enable
  27. sprd_mcdt_chan_int_disable
  28. sprd_mcdt_chan_dma_enable
  29. sprd_mcdt_chan_dma_disable
  30. sprd_mcdt_request_chan
  31. sprd_mcdt_free_chan
  32. sprd_mcdt_init_chans
  33. sprd_mcdt_probe
  34. sprd_mcdt_remove

   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 
  88 enum 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 
  97 enum 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 
 108 struct 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 
 115 static LIST_HEAD(sprd_mcdt_chan_list);
 116 static DEFINE_MUTEX(sprd_mcdt_list_mutex);
 117 
 118 static 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 
 128 static 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 
 140 static 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 
 152 static 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 
 163 static 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 
 172 static 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 
 182 static 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 
 190 static 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 
 198 static 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 
 234 static 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 
 270 static 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 
 295 static 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 
 317 static 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 
 339 static 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 
 388 static 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 
 393 static 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 
 400 static 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 
 413 static 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 
 426 static 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 
 453 static 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 
 478 static 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 
 500 static 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 
 522 static 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  */
 569 int 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 }
 605 EXPORT_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  */
 620 int 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 }
 651 EXPORT_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  */
 671 int 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 }
 719 EXPORT_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  */
 725 void 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 }
 759 EXPORT_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  */
 773 int 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 }
 821 EXPORT_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  */
 827 void 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 }
 857 EXPORT_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  */
 866 struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel,
 867                                               enum sprd_mcdt_channel_type type)
 868 {
 869         struct sprd_mcdt_chan *temp, *chan = NULL;
 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                         chan = temp;
 876                         break;
 877                 }
 878         }
 879 
 880         if (chan)
 881                 list_del(&chan->list);
 882 
 883         mutex_unlock(&sprd_mcdt_list_mutex);
 884 
 885         return chan;
 886 }
 887 EXPORT_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  */
 893 void 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 }
 912 EXPORT_SYMBOL_GPL(sprd_mcdt_free_chan);
 913 
 914 static 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 
 942 static 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         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 953         mcdt->base = devm_ioremap_resource(&pdev->dev, res);
 954         if (IS_ERR(mcdt->base))
 955                 return PTR_ERR(mcdt->base);
 956 
 957         mcdt->dev = &pdev->dev;
 958         spin_lock_init(&mcdt->lock);
 959         platform_set_drvdata(pdev, mcdt);
 960 
 961         irq = platform_get_irq(pdev, 0);
 962         if (irq < 0)
 963                 return irq;
 964 
 965         ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler,
 966                                0, "sprd-mcdt", mcdt);
 967         if (ret) {
 968                 dev_err(&pdev->dev, "Failed to request MCDT IRQ\n");
 969                 return ret;
 970         }
 971 
 972         sprd_mcdt_init_chans(mcdt, res);
 973 
 974         return 0;
 975 }
 976 
 977 static int sprd_mcdt_remove(struct platform_device *pdev)
 978 {
 979         struct sprd_mcdt_chan *chan, *temp;
 980 
 981         mutex_lock(&sprd_mcdt_list_mutex);
 982 
 983         list_for_each_entry_safe(chan, temp, &sprd_mcdt_chan_list, list)
 984                 list_del(&chan->list);
 985 
 986         mutex_unlock(&sprd_mcdt_list_mutex);
 987 
 988         return 0;
 989 }
 990 
 991 static const struct of_device_id sprd_mcdt_of_match[] = {
 992         { .compatible = "sprd,sc9860-mcdt", },
 993         { }
 994 };
 995 MODULE_DEVICE_TABLE(of, sprd_mcdt_of_match);
 996 
 997 static struct platform_driver sprd_mcdt_driver = {
 998         .probe = sprd_mcdt_probe,
 999         .remove = sprd_mcdt_remove,
1000         .driver = {
1001                 .name = "sprd-mcdt",
1002                 .of_match_table = sprd_mcdt_of_match,
1003         },
1004 };
1005 
1006 module_platform_driver(sprd_mcdt_driver);
1007 
1008 MODULE_DESCRIPTION("Spreadtrum Multi-Channel Data Transfer Driver");
1009 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */