Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*****************************************************************************
0003  *
0004  * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
0005  * Jean-Christian Hassler <jhassler@free.fr>
0006  *
0007  * This file is part of the Audiowerk2 ALSA driver
0008  *
0009  *****************************************************************************/
0010 
0011 #define AW2_SAA7146_M
0012 
0013 #include <linux/init.h>
0014 #include <linux/pci.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/delay.h>
0017 #include <linux/io.h>
0018 #include <sound/core.h>
0019 #include <sound/initval.h>
0020 #include <sound/pcm.h>
0021 #include <sound/pcm_params.h>
0022 
0023 #include "saa7146.h"
0024 #include "aw2-saa7146.h"
0025 
0026 #include "aw2-tsl.c"
0027 
0028 #define WRITEREG(value, addr) writel((value), chip->base_addr + (addr))
0029 #define READREG(addr) readl(chip->base_addr + (addr))
0030 
0031 static struct snd_aw2_saa7146_cb_param
0032  arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
0033 static struct snd_aw2_saa7146_cb_param
0034  arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
0035 
0036 static int snd_aw2_saa7146_get_limit(int size);
0037 
0038 /* chip-specific destructor */
0039 int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip)
0040 {
0041     /* disable all irqs */
0042     WRITEREG(0, IER);
0043 
0044     /* reset saa7146 */
0045     WRITEREG((MRST_N << 16), MC1);
0046 
0047     /* Unset base addr */
0048     chip->base_addr = NULL;
0049 
0050     return 0;
0051 }
0052 
0053 void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
0054                void __iomem *pci_base_addr)
0055 {
0056     /* set PCI burst/threshold
0057 
0058        Burst length definition
0059        VALUE    BURST LENGTH
0060        000      1 Dword
0061        001      2 Dwords
0062        010      4 Dwords
0063        011      8 Dwords
0064        100      16 Dwords
0065        101      32 Dwords
0066        110      64 Dwords
0067        111      128 Dwords
0068 
0069        Threshold definition
0070        VALUE    WRITE MODE              READ MODE
0071        00       1 Dword of valid data   1 empty Dword
0072        01       4 Dwords of valid data  4 empty Dwords
0073        10       8 Dwords of valid data  8 empty Dwords
0074        11       16 Dwords of valid data 16 empty Dwords */
0075 
0076     unsigned int acon2;
0077     unsigned int acon1 = 0;
0078     int i;
0079 
0080     /* Set base addr */
0081     chip->base_addr = pci_base_addr;
0082 
0083     /* disable all irqs */
0084     WRITEREG(0, IER);
0085 
0086     /* reset saa7146 */
0087     WRITEREG((MRST_N << 16), MC1);
0088 
0089     /* enable audio interface */
0090 #ifdef __BIG_ENDIAN
0091     acon1 |= A1_SWAP;
0092     acon1 |= A2_SWAP;
0093 #endif
0094     /* WS0_CTRL, WS0_SYNC: input TSL1, I2S */
0095 
0096     /* At initialization WS1 and WS2 are disabled (configured as input) */
0097     acon1 |= 0 * WS1_CTRL;
0098     acon1 |= 0 * WS2_CTRL;
0099 
0100     /* WS4 is not used. So it must not restart A2.
0101        This is why it is configured as output (force to low) */
0102     acon1 |= 3 * WS4_CTRL;
0103 
0104     /* WS3_CTRL, WS3_SYNC: output TSL2, I2S */
0105     acon1 |= 2 * WS3_CTRL;
0106 
0107     /* A1 and A2 are active and asynchronous */
0108     acon1 |= 3 * AUDIO_MODE;
0109     WRITEREG(acon1, ACON1);
0110 
0111     /* The following comes from original windows driver.
0112        It is needed to have a correct behavior of input and output
0113        simultenously, but I don't know why ! */
0114     WRITEREG(3 * (BurstA1_in) + 3 * (ThreshA1_in) +
0115          3 * (BurstA1_out) + 3 * (ThreshA1_out) +
0116          3 * (BurstA2_out) + 3 * (ThreshA2_out), PCI_BT_A);
0117 
0118     /* enable audio port pins */
0119     WRITEREG((EAP << 16) | EAP, MC1);
0120 
0121     /* enable I2C */
0122     WRITEREG((EI2C << 16) | EI2C, MC1);
0123     /* enable interrupts */
0124     WRITEREG(A1_out | A2_out | A1_in | IIC_S | IIC_E, IER);
0125 
0126     /* audio configuration */
0127     acon2 = A2_CLKSRC | BCLK1_OEN;
0128     WRITEREG(acon2, ACON2);
0129 
0130     /* By default use analog input */
0131     snd_aw2_saa7146_use_digital_input(chip, 0);
0132 
0133     /* TSL setup */
0134     for (i = 0; i < 8; ++i) {
0135         WRITEREG(tsl1[i], TSL1 + (i * 4));
0136         WRITEREG(tsl2[i], TSL2 + (i * 4));
0137     }
0138 
0139 }
0140 
0141 void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
0142                        int stream_number,
0143                        unsigned long dma_addr,
0144                        unsigned long period_size,
0145                        unsigned long buffer_size)
0146 {
0147     unsigned long dw_page, dw_limit;
0148 
0149     /* Configure DMA for substream
0150        Configuration informations: ALSA has allocated continuous memory
0151        pages. So we don't need to use MMU of saa7146.
0152      */
0153 
0154     /* No MMU -> nothing to do with PageA1, we only configure the limit of
0155        PageAx_out register */
0156     /* Disable MMU */
0157     dw_page = (0L << 11);
0158 
0159     /* Configure Limit for DMA access.
0160        The limit register defines an address limit, which generates
0161        an interrupt if passed by the actual PCI address pointer.
0162        '0001' means an interrupt will be generated if the lower
0163        6 bits (64 bytes) of the PCI address are zero. '0010'
0164        defines a limit of 128 bytes, '0011' one of 256 bytes, and
0165        so on up to 1 Mbyte defined by '1111'. This interrupt range
0166        can be calculated as follows:
0167        Range = 2^(5 + Limit) bytes.
0168      */
0169     dw_limit = snd_aw2_saa7146_get_limit(period_size);
0170     dw_page |= (dw_limit << 4);
0171 
0172     if (stream_number == 0) {
0173         WRITEREG(dw_page, PageA2_out);
0174 
0175         /* Base address for DMA transfert. */
0176         /* This address has been reserved by ALSA. */
0177         /* This is a physical address */
0178         WRITEREG(dma_addr, BaseA2_out);
0179 
0180         /* Define upper limit for DMA access */
0181         WRITEREG(dma_addr + buffer_size, ProtA2_out);
0182 
0183     } else if (stream_number == 1) {
0184         WRITEREG(dw_page, PageA1_out);
0185 
0186         /* Base address for DMA transfert. */
0187         /* This address has been reserved by ALSA. */
0188         /* This is a physical address */
0189         WRITEREG(dma_addr, BaseA1_out);
0190 
0191         /* Define upper limit for DMA access */
0192         WRITEREG(dma_addr + buffer_size, ProtA1_out);
0193     } else {
0194         pr_err("aw2: snd_aw2_saa7146_pcm_init_playback: "
0195                "Substream number is not 0 or 1 -> not managed\n");
0196     }
0197 }
0198 
0199 void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
0200                       int stream_number, unsigned long dma_addr,
0201                       unsigned long period_size,
0202                       unsigned long buffer_size)
0203 {
0204     unsigned long dw_page, dw_limit;
0205 
0206     /* Configure DMA for substream
0207        Configuration informations: ALSA has allocated continuous memory
0208        pages. So we don't need to use MMU of saa7146.
0209      */
0210 
0211     /* No MMU -> nothing to do with PageA1, we only configure the limit of
0212        PageAx_out register */
0213     /* Disable MMU */
0214     dw_page = (0L << 11);
0215 
0216     /* Configure Limit for DMA access.
0217        The limit register defines an address limit, which generates
0218        an interrupt if passed by the actual PCI address pointer.
0219        '0001' means an interrupt will be generated if the lower
0220        6 bits (64 bytes) of the PCI address are zero. '0010'
0221        defines a limit of 128 bytes, '0011' one of 256 bytes, and
0222        so on up to 1 Mbyte defined by '1111'. This interrupt range
0223        can be calculated as follows:
0224        Range = 2^(5 + Limit) bytes.
0225      */
0226     dw_limit = snd_aw2_saa7146_get_limit(period_size);
0227     dw_page |= (dw_limit << 4);
0228 
0229     if (stream_number == 0) {
0230         WRITEREG(dw_page, PageA1_in);
0231 
0232         /* Base address for DMA transfert. */
0233         /* This address has been reserved by ALSA. */
0234         /* This is a physical address */
0235         WRITEREG(dma_addr, BaseA1_in);
0236 
0237         /* Define upper limit for DMA access  */
0238         WRITEREG(dma_addr + buffer_size, ProtA1_in);
0239     } else {
0240         pr_err("aw2: snd_aw2_saa7146_pcm_init_capture: "
0241                "Substream number is not 0 -> not managed\n");
0242     }
0243 }
0244 
0245 void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number,
0246                          snd_aw2_saa7146_it_cb
0247                          p_it_callback,
0248                          void *p_callback_param)
0249 {
0250     if (stream_number < NB_STREAM_PLAYBACK) {
0251         arr_substream_it_playback_cb[stream_number].p_it_callback =
0252             (snd_aw2_saa7146_it_cb) p_it_callback;
0253         arr_substream_it_playback_cb[stream_number].p_callback_param =
0254             (void *)p_callback_param;
0255     }
0256 }
0257 
0258 void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number,
0259                         snd_aw2_saa7146_it_cb
0260                         p_it_callback,
0261                         void *p_callback_param)
0262 {
0263     if (stream_number < NB_STREAM_CAPTURE) {
0264         arr_substream_it_capture_cb[stream_number].p_it_callback =
0265             (snd_aw2_saa7146_it_cb) p_it_callback;
0266         arr_substream_it_capture_cb[stream_number].p_callback_param =
0267             (void *)p_callback_param;
0268     }
0269 }
0270 
0271 void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146 *chip,
0272                         int stream_number)
0273 {
0274     unsigned int acon1 = 0;
0275     /* In aw8 driver, dma transfert is always active. It is
0276        started and stopped in a larger "space" */
0277     acon1 = READREG(ACON1);
0278     if (stream_number == 0) {
0279         WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
0280 
0281         /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
0282         acon1 |= 2 * WS2_CTRL;
0283         WRITEREG(acon1, ACON1);
0284 
0285     } else if (stream_number == 1) {
0286         WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
0287 
0288         /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
0289         acon1 |= 1 * WS1_CTRL;
0290         WRITEREG(acon1, ACON1);
0291     }
0292 }
0293 
0294 void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146 *chip,
0295                            int stream_number)
0296 {
0297     unsigned int acon1 = 0;
0298     acon1 = READREG(ACON1);
0299     if (stream_number == 0) {
0300         /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
0301         acon1 &= ~(3 * WS2_CTRL);
0302         WRITEREG(acon1, ACON1);
0303 
0304         WRITEREG((TR_E_A2_OUT << 16), MC1);
0305     } else if (stream_number == 1) {
0306         /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
0307         acon1 &= ~(3 * WS1_CTRL);
0308         WRITEREG(acon1, ACON1);
0309 
0310         WRITEREG((TR_E_A1_OUT << 16), MC1);
0311     }
0312 }
0313 
0314 void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146 *chip,
0315                            int stream_number)
0316 {
0317     /* In aw8 driver, dma transfert is always active. It is
0318        started and stopped in a larger "space" */
0319     if (stream_number == 0)
0320         WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
0321 }
0322 
0323 void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip,
0324                           int stream_number)
0325 {
0326     if (stream_number == 0)
0327         WRITEREG((TR_E_A1_IN << 16), MC1);
0328 }
0329 
0330 irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id)
0331 {
0332     unsigned int isr;
0333     __always_unused unsigned int iicsta;
0334     struct snd_aw2_saa7146 *chip = dev_id;
0335 
0336     isr = READREG(ISR);
0337     if (!isr)
0338         return IRQ_NONE;
0339 
0340     WRITEREG(isr, ISR);
0341 
0342     if (isr & (IIC_S | IIC_E)) {
0343         iicsta = READREG(IICSTA);
0344         WRITEREG(0x100, IICSTA);
0345     }
0346 
0347     if (isr & A1_out) {
0348         if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
0349             arr_substream_it_playback_cb[1].
0350                 p_it_callback(arr_substream_it_playback_cb[1].
0351                       p_callback_param);
0352         }
0353     }
0354     if (isr & A2_out) {
0355         if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
0356             arr_substream_it_playback_cb[0].
0357                 p_it_callback(arr_substream_it_playback_cb[0].
0358                       p_callback_param);
0359         }
0360 
0361     }
0362     if (isr & A1_in) {
0363         if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
0364             arr_substream_it_capture_cb[0].
0365                 p_it_callback(arr_substream_it_capture_cb[0].
0366                       p_callback_param);
0367         }
0368     }
0369     return IRQ_HANDLED;
0370 }
0371 
0372 unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
0373                          int stream_number,
0374                          unsigned char *start_addr,
0375                          unsigned int buffer_size)
0376 {
0377     long pci_adp = 0;
0378     size_t ptr = 0;
0379 
0380     if (stream_number == 0) {
0381         pci_adp = READREG(PCI_ADP3);
0382         ptr = pci_adp - (long)start_addr;
0383 
0384         if (ptr == buffer_size)
0385             ptr = 0;
0386     }
0387     if (stream_number == 1) {
0388         pci_adp = READREG(PCI_ADP1);
0389         ptr = pci_adp - (size_t) start_addr;
0390 
0391         if (ptr == buffer_size)
0392             ptr = 0;
0393     }
0394     return ptr;
0395 }
0396 
0397 unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
0398                         int stream_number,
0399                         unsigned char *start_addr,
0400                         unsigned int buffer_size)
0401 {
0402     size_t pci_adp = 0;
0403     size_t ptr = 0;
0404     if (stream_number == 0) {
0405         pci_adp = READREG(PCI_ADP2);
0406         ptr = pci_adp - (size_t) start_addr;
0407 
0408         if (ptr == buffer_size)
0409             ptr = 0;
0410     }
0411     return ptr;
0412 }
0413 
0414 void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
0415                        int use_digital)
0416 {
0417     /* FIXME: switch between analog and digital input does not always work.
0418        It can produce a kind of white noise. It seams that received data
0419        are inverted sometime (endian inversion). Why ? I don't know, maybe
0420        a problem of synchronization... However for the time being I have
0421        not found the problem. Workaround: switch again (and again) between
0422        digital and analog input until it works. */
0423     if (use_digital)
0424         WRITEREG(0x40, GPIO_CTRL);
0425     else
0426         WRITEREG(0x50, GPIO_CTRL);
0427 }
0428 
0429 int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
0430 {
0431     unsigned int reg_val = READREG(GPIO_CTRL);
0432     if ((reg_val & 0xFF) == 0x40)
0433         return 1;
0434     else
0435         return 0;
0436 }
0437 
0438 
0439 static int snd_aw2_saa7146_get_limit(int size)
0440 {
0441     int limitsize = 32;
0442     int limit = 0;
0443     while (limitsize < size) {
0444         limitsize *= 2;
0445         limit++;
0446     }
0447     return limit;
0448 }