text: /*
   * pcm.h
   *
   * Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
   * PCM version Copyright (c) Ton van Overbeek <tvoverbeek @ gmail.com>
   *
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modification, are permitted
   * provided that the following conditions are met:
   *
   *     1.  Redistributions of source code must retain the above copyright notice, this list of
   *         conditions and the following disclaimer.
   *     2.  Redistributions in binary form must reproduce the above copyright notice, this list
   *         of conditions and the following disclaimer in the documentation and/or other materials
   *         provided with the distribution.
   *     3.  Neither the name of the owner nor the names of its contributors may be used to endorse
   *         or promote products derived from this software without specific prior written permission.
   * 
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   */
  
  #ifndef __PCM_H__
  #define __PCM_H__
  
  
  /*
   *
   * Pin mapping of alternate pin configuration for PCM
   *
   * GPIO   ALT PCM_CLK   ALT PCM-FS   ALT PCM_DIN   ALT PCM_DOUT
   *
   *  18        0             
   *  19                      0
   *  20                                   0
   *  21                                                 0
   *  28        2 
   *  29                      2
   *  30                                   2
   *  31                                                 2
   *
   */
  
  
  typedef struct
  {
      uint32_t cs;
  #define RPI_PCM_CS_STBY                         (1 << 25)
  #define RPI_PCM_CS_SYNC                         (1 << 24)
  #define RPI_PCM_CS_RXSEX                        (1 << 23)
  #define RPI_PCM_CS_RXF                          (1 << 22)
  #define RPI_PCM_CS_TXE                          (1 << 21)
  #define RPI_PCM_CS_RXD                          (1 << 20)
  #define RPI_PCM_CS_TXD                          (1 << 19)
  #define RPI_PCM_CS_RXR                          (1 << 18)
  #define RPI_PCM_CS_TXW                          (1 << 17)
  #define RPI_PCM_CS_RXERR                        (1 << 16)
  #define RPI_PCM_CS_TXERR                        (1 << 15)
  #define RPI_PCM_CS_RXSYNC                       (1 << 14)
  #define RPI_PCM_CS_TXSYNC                       (1 << 13)
  #define RPI_PCM_CS_DMAEN                        (1 << 9)
  #define RPI_PCM_CS_RXTHR(val)                   ((val & 0x03) << 7)
  #define RPI_PCM_CS_TXTHR(val)                   ((val & 0x03) << 5)
  #define RPI_PCM_CS_RXCLR                        (1 << 4)
  #define RPI_PCM_CS_TXCLR                        (1 << 3)
  #define RPI_PCM_CS_TXON                         (1 << 2)
  #define RPI_PCM_CS_RXON                         (1 << 1)
  #define RPI_PCM_CS_EN                           (1 << 0)
      uint32_t fifo;
      uint32_t mode;
  #define RPI_PCM_MODE_CLK_DIS                    (1 << 28)
  #define RPI_PCM_MODE_PDMN                       (1 << 27)
  #define RPI_PCM_MODE_PDME                       (1 << 26)
  #define RPI_PCM_MODE_FRXP                       (1 << 25)
  #define RPI_PCM_MODE_FTXP                       (1 << 24)
  #define RPI_PCM_MODE_CLKM                       (1 << 23)
  #define RPI_PCM_MODE_CLKI                       (1 << 22)
  #define RPI_PCM_MODE_FSM                        (1 << 21)
  #define RPI_PCM_MODE_FSI                        (1 << 20)
  #define RPI_PCM_MODE_FLEN(val)                  ((val & 0x3ff) << 10)
  #define RPI_PCM_MODE_FSLEN(val)                 ((val & 0x3ff) << 0)
      uint32_t rxc;
  #define RPI_PCM_RXC_CH1WEX                      (1 << 31)
  #define RPI_PCM_RXC_CH1EN                       (1 << 30)
  #define RPI_PCM_RXC_CH1POS(val)                 ((val & 0x3ff) << 20)
  #define RPI_PCM_RXC_CH1WID(val)                 ((val & 0x0f) << 16)
  #define RPI_PCM_RXC_CH2WEX                      (1 << 15)
  #define RPI_PCM_RXC_CH2EN                       (1 << 14)
  #define RPI_PCM_RXC_CH2POS(val)                 ((val & 0x3ff) << 4)
  #define RPI_PCM_RXC_CH2WID(val)                 ((val & 0x0f) << 0)
      uint32_t txc;
  #define RPI_PCM_TXC_CH1WEX                      (1 << 31)
  #define RPI_PCM_TXC_CH1EN                       (1 << 30)
  #define RPI_PCM_TXC_CH1POS(val)                 ((val & 0x3ff) << 20)
  #define RPI_PCM_TXC_CH1WID(val)                 ((val & 0x0f) << 16)
  #define RPI_PCM_TXC_CH2WEX                      (1 << 15)
  #define RPI_PCM_TXC_CH2EN                       (1 << 14)
  #define RPI_PCM_TXC_CH2POS(val)                 ((val & 0x3ff) << 4)
  #define RPI_PCM_TXC_CH2WID(val)                 ((val & 0x0f) << 0)
      uint32_t dreq;
  #define RPI_PCM_DREQ_TX_PANIC(val)              ((val & 0x7f) << 24)
  #define RPI_PCM_DREQ_RX_PANIC(val)              ((val & 0x7f) << 16)
  #define RPI_PCM_DREQ_TX(val)                    ((val & 0x7f) << 8)
  #define RPI_PCM_DREQ_RX(val)                    ((val & 0x7f) << 0)
      uint32_t inten;
  #define RPI_PCM_INTEN_RXERR                     (1 << 3)
  #define RPI_PCM_INTEN_TXERR                     (1 << 2)
  #define RPI_PCM_INTEN_RXR                       (1 << 1)
  #define RPI_PCM_INTEN_TXW                       (1 << 0)
      uint32_t intstc;
  #define RPI_PCM_INTSTC_RXERR                    (1 << 3)
  #define RPI_PCM_INTSTC_TXERR                    (1 << 2)
  #define RPI_PCM_INTSTC_RXR                      (1 << 1)
  #define RPI_PCM_INTSTC_TXW                      (1 << 0)
      uint32_t gray;
  #define RPI_PCM_GRAY_RXFIFOLEVEL(val)           ((val & 0x3f) << 16)
  #define RPI_PCM_GRAY_FLUSHED(val)               ((val & 0x3f) << 10
  #define RPI_PCM_GRAY_RXLEVEL(val)               ((val & 0x3f) << 4)
  #define RPI_PCM_GRAY_FLUSH                      (1 << 2)
  #define RPI_PCM_GRAY_CLR                        (1 << 1)
  #define RPI_PCM_GRAY_EN                         (1 << 0)
  } __attribute__((packed, aligned(4))) pcm_t;
  
  
  #define PCM_OFFSET                               (0x00203000)
  #define PCM_PERIPH_PHYS                          (0x7e203000)
  
  #define NUM_PCMFUNS        4
  #define PCMFUN_CLK         0
  #define PCMFUN_FS          1
  #define PCMFUN_DIN         2
  #define PCMFUN_DOUT        3
  
  typedef struct
  {
      int pinnum;
      int altnum;
  } pcm_pin_table_t;
  
  typedef struct
  {
      const int count;
      const pcm_pin_table_t *pins;
  } pcm_pin_tables_t;
  
  
  int pcm_pin_alt(int pcmfun, int pinnum);
  
  
  #endif /* __PCM_H__ */
  