linux/sound/pci/aw2/aw2-saa7146.c
<<
>>
Prefs
   1/*****************************************************************************
   2 *
   3 * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
   4 * Jean-Christian Hassler <jhassler@free.fr>
   5 *
   6 * This file is part of the Audiowerk2 ALSA driver
   7 *
   8 * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; version 2.
  11 *
  12 * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
  20 * USA.
  21 *
  22 *****************************************************************************/
  23
  24#define AW2_SAA7146_M
  25
  26#include <linux/init.h>
  27#include <linux/pci.h>
  28#include <linux/interrupt.h>
  29#include <linux/delay.h>
  30#include <linux/io.h>
  31#include <sound/core.h>
  32#include <sound/initval.h>
  33#include <sound/pcm.h>
  34#include <sound/pcm_params.h>
  35
  36#include "saa7146.h"
  37#include "aw2-saa7146.h"
  38
  39#include "aw2-tsl.c"
  40
  41#define WRITEREG(value, addr) writel((value), chip->base_addr + (addr))
  42#define READREG(addr) readl(chip->base_addr + (addr))
  43
  44static struct snd_aw2_saa7146_cb_param
  45 arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
  46static struct snd_aw2_saa7146_cb_param
  47 arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
  48
  49static int snd_aw2_saa7146_get_limit(int size);
  50
  51/* chip-specific destructor */
  52int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip)
  53{
  54        /* disable all irqs */
  55        WRITEREG(0, IER);
  56
  57        /* reset saa7146 */
  58        WRITEREG((MRST_N << 16), MC1);
  59
  60        /* Unset base addr */
  61        chip->base_addr = NULL;
  62
  63        return 0;
  64}
  65
  66void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
  67                           void __iomem *pci_base_addr)
  68{
  69        /* set PCI burst/threshold
  70
  71           Burst length definition
  72           VALUE    BURST LENGTH
  73           000      1 Dword
  74           001      2 Dwords
  75           010      4 Dwords
  76           011      8 Dwords
  77           100      16 Dwords
  78           101      32 Dwords
  79           110      64 Dwords
  80           111      128 Dwords
  81
  82           Threshold definition
  83           VALUE    WRITE MODE              READ MODE
  84           00       1 Dword of valid data   1 empty Dword
  85           01       4 Dwords of valid data  4 empty Dwords
  86           10       8 Dwords of valid data  8 empty Dwords
  87           11       16 Dwords of valid data 16 empty Dwords */
  88
  89        unsigned int acon2;
  90        unsigned int acon1 = 0;
  91        int i;
  92
  93        /* Set base addr */
  94        chip->base_addr = pci_base_addr;
  95
  96        /* disable all irqs */
  97        WRITEREG(0, IER);
  98
  99        /* reset saa7146 */
 100        WRITEREG((MRST_N << 16), MC1);
 101
 102        /* enable audio interface */
 103#ifdef __BIG_ENDIAN
 104        acon1 |= A1_SWAP;
 105        acon1 |= A2_SWAP;
 106#endif
 107        /* WS0_CTRL, WS0_SYNC: input TSL1, I2S */
 108
 109        /* At initialization WS1 and WS2 are disabled (configured as input) */
 110        acon1 |= 0 * WS1_CTRL;
 111        acon1 |= 0 * WS2_CTRL;
 112
 113        /* WS4 is not used. So it must not restart A2.
 114           This is why it is configured as output (force to low) */
 115        acon1 |= 3 * WS4_CTRL;
 116
 117        /* WS3_CTRL, WS3_SYNC: output TSL2, I2S */
 118        acon1 |= 2 * WS3_CTRL;
 119
 120        /* A1 and A2 are active and asynchronous */
 121        acon1 |= 3 * AUDIO_MODE;
 122        WRITEREG(acon1, ACON1);
 123
 124        /* The following comes from original windows driver.
 125           It is needed to have a correct behavior of input and output
 126           simultenously, but I don't know why ! */
 127        WRITEREG(3 * (BurstA1_in) + 3 * (ThreshA1_in) +
 128                 3 * (BurstA1_out) + 3 * (ThreshA1_out) +
 129                 3 * (BurstA2_out) + 3 * (ThreshA2_out), PCI_BT_A);
 130
 131        /* enable audio port pins */
 132        WRITEREG((EAP << 16) | EAP, MC1);
 133
 134        /* enable I2C */
 135        WRITEREG((EI2C << 16) | EI2C, MC1);
 136        /* enable interrupts */
 137        WRITEREG(A1_out | A2_out | A1_in | IIC_S | IIC_E, IER);
 138
 139        /* audio configuration */
 140        acon2 = A2_CLKSRC | BCLK1_OEN;
 141        WRITEREG(acon2, ACON2);
 142
 143        /* By default use analog input */
 144        snd_aw2_saa7146_use_digital_input(chip, 0);
 145
 146        /* TSL setup */
 147        for (i = 0; i < 8; ++i) {
 148                WRITEREG(tsl1[i], TSL1 + (i * 4));
 149                WRITEREG(tsl2[i], TSL2 + (i * 4));
 150        }
 151
 152}
 153
 154void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
 155                                       int stream_number,
 156                                       unsigned long dma_addr,
 157                                       unsigned long period_size,
 158                                       unsigned long buffer_size)
 159{
 160        unsigned long dw_page, dw_limit;
 161
 162        /* Configure DMA for substream
 163           Configuration informations: ALSA has allocated continuous memory
 164           pages. So we don't need to use MMU of saa7146.
 165         */
 166
 167        /* No MMU -> nothing to do with PageA1, we only configure the limit of
 168           PageAx_out register */
 169        /* Disable MMU */
 170        dw_page = (0L << 11);
 171
 172        /* Configure Limit for DMA access.
 173           The limit register defines an address limit, which generates
 174           an interrupt if passed by the actual PCI address pointer.
 175           '0001' means an interrupt will be generated if the lower
 176           6 bits (64 bytes) of the PCI address are zero. '0010'
 177           defines a limit of 128 bytes, '0011' one of 256 bytes, and
 178           so on up to 1 Mbyte defined by '1111'. This interrupt range
 179           can be calculated as follows:
 180           Range = 2^(5 + Limit) bytes.
 181         */
 182        dw_limit = snd_aw2_saa7146_get_limit(period_size);
 183        dw_page |= (dw_limit << 4);
 184
 185        if (stream_number == 0) {
 186                WRITEREG(dw_page, PageA2_out);
 187
 188                /* Base address for DMA transfert. */
 189                /* This address has been reserved by ALSA. */
 190                /* This is a physical address */
 191                WRITEREG(dma_addr, BaseA2_out);
 192
 193                /* Define upper limit for DMA access */
 194                WRITEREG(dma_addr + buffer_size, ProtA2_out);
 195
 196        } else if (stream_number == 1) {
 197                WRITEREG(dw_page, PageA1_out);
 198
 199                /* Base address for DMA transfert. */
 200                /* This address has been reserved by ALSA. */
 201                /* This is a physical address */
 202                WRITEREG(dma_addr, BaseA1_out);
 203
 204                /* Define upper limit for DMA access */
 205                WRITEREG(dma_addr + buffer_size, ProtA1_out);
 206        } else {
 207                pr_err("aw2: snd_aw2_saa7146_pcm_init_playback: "
 208                       "Substream number is not 0 or 1 -> not managed\n");
 209        }
 210}
 211
 212void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
 213                                      int stream_number, unsigned long dma_addr,
 214                                      unsigned long period_size,
 215                                      unsigned long buffer_size)
 216{
 217        unsigned long dw_page, dw_limit;
 218
 219        /* Configure DMA for substream
 220           Configuration informations: ALSA has allocated continuous memory
 221           pages. So we don't need to use MMU of saa7146.
 222         */
 223
 224        /* No MMU -> nothing to do with PageA1, we only configure the limit of
 225           PageAx_out register */
 226        /* Disable MMU */
 227        dw_page = (0L << 11);
 228
 229        /* Configure Limit for DMA access.
 230           The limit register defines an address limit, which generates
 231           an interrupt if passed by the actual PCI address pointer.
 232           '0001' means an interrupt will be generated if the lower
 233           6 bits (64 bytes) of the PCI address are zero. '0010'
 234           defines a limit of 128 bytes, '0011' one of 256 bytes, and
 235           so on up to 1 Mbyte defined by '1111'. This interrupt range
 236           can be calculated as follows:
 237           Range = 2^(5 + Limit) bytes.
 238         */
 239        dw_limit = snd_aw2_saa7146_get_limit(period_size);
 240        dw_page |= (dw_limit << 4);
 241
 242        if (stream_number == 0) {
 243                WRITEREG(dw_page, PageA1_in);
 244
 245                /* Base address for DMA transfert. */
 246                /* This address has been reserved by ALSA. */
 247                /* This is a physical address */
 248                WRITEREG(dma_addr, BaseA1_in);
 249
 250                /* Define upper limit for DMA access  */
 251                WRITEREG(dma_addr + buffer_size, ProtA1_in);
 252        } else {
 253                pr_err("aw2: snd_aw2_saa7146_pcm_init_capture: "
 254                       "Substream number is not 0 -> not managed\n");
 255        }
 256}
 257
 258void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number,
 259                                                 snd_aw2_saa7146_it_cb
 260                                                 p_it_callback,
 261                                                 void *p_callback_param)
 262{
 263        if (stream_number < NB_STREAM_PLAYBACK) {
 264                arr_substream_it_playback_cb[stream_number].p_it_callback =
 265                    (snd_aw2_saa7146_it_cb) p_it_callback;
 266                arr_substream_it_playback_cb[stream_number].p_callback_param =
 267                    (void *)p_callback_param;
 268        }
 269}
 270
 271void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number,
 272                                                snd_aw2_saa7146_it_cb
 273                                                p_it_callback,
 274                                                void *p_callback_param)
 275{
 276        if (stream_number < NB_STREAM_CAPTURE) {
 277                arr_substream_it_capture_cb[stream_number].p_it_callback =
 278                    (snd_aw2_saa7146_it_cb) p_it_callback;
 279                arr_substream_it_capture_cb[stream_number].p_callback_param =
 280                    (void *)p_callback_param;
 281        }
 282}
 283
 284void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146 *chip,
 285                                                int stream_number)
 286{
 287        unsigned int acon1 = 0;
 288        /* In aw8 driver, dma transfert is always active. It is
 289           started and stopped in a larger "space" */
 290        acon1 = READREG(ACON1);
 291        if (stream_number == 0) {
 292                WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
 293
 294                /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
 295                acon1 |= 2 * WS2_CTRL;
 296                WRITEREG(acon1, ACON1);
 297
 298        } else if (stream_number == 1) {
 299                WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
 300
 301                /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
 302                acon1 |= 1 * WS1_CTRL;
 303                WRITEREG(acon1, ACON1);
 304        }
 305}
 306
 307void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146 *chip,
 308                                               int stream_number)
 309{
 310        unsigned int acon1 = 0;
 311        acon1 = READREG(ACON1);
 312        if (stream_number == 0) {
 313                /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
 314                acon1 &= ~(3 * WS2_CTRL);
 315                WRITEREG(acon1, ACON1);
 316
 317                WRITEREG((TR_E_A2_OUT << 16), MC1);
 318        } else if (stream_number == 1) {
 319                /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
 320                acon1 &= ~(3 * WS1_CTRL);
 321                WRITEREG(acon1, ACON1);
 322
 323                WRITEREG((TR_E_A1_OUT << 16), MC1);
 324        }
 325}
 326
 327void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146 *chip,
 328                                               int stream_number)
 329{
 330        /* In aw8 driver, dma transfert is always active. It is
 331           started and stopped in a larger "space" */
 332        if (stream_number == 0)
 333                WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
 334}
 335
 336void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip,
 337                                              int stream_number)
 338{
 339        if (stream_number == 0)
 340                WRITEREG((TR_E_A1_IN << 16), MC1);
 341}
 342
 343irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id)
 344{
 345        unsigned int isr;
 346        unsigned int iicsta;
 347        struct snd_aw2_saa7146 *chip = dev_id;
 348
 349        isr = READREG(ISR);
 350        if (!isr)
 351                return IRQ_NONE;
 352
 353        WRITEREG(isr, ISR);
 354
 355        if (isr & (IIC_S | IIC_E)) {
 356                iicsta = READREG(IICSTA);
 357                WRITEREG(0x100, IICSTA);
 358        }
 359
 360        if (isr & A1_out) {
 361                if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
 362                        arr_substream_it_playback_cb[1].
 363                            p_it_callback(arr_substream_it_playback_cb[1].
 364                                          p_callback_param);
 365                }
 366        }
 367        if (isr & A2_out) {
 368                if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
 369                        arr_substream_it_playback_cb[0].
 370                            p_it_callback(arr_substream_it_playback_cb[0].
 371                                          p_callback_param);
 372                }
 373
 374        }
 375        if (isr & A1_in) {
 376                if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
 377                        arr_substream_it_capture_cb[0].
 378                            p_it_callback(arr_substream_it_capture_cb[0].
 379                                          p_callback_param);
 380                }
 381        }
 382        return IRQ_HANDLED;
 383}
 384
 385unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
 386                                                 int stream_number,
 387                                                 unsigned char *start_addr,
 388                                                 unsigned int buffer_size)
 389{
 390        long pci_adp = 0;
 391        size_t ptr = 0;
 392
 393        if (stream_number == 0) {
 394                pci_adp = READREG(PCI_ADP3);
 395                ptr = pci_adp - (long)start_addr;
 396
 397                if (ptr == buffer_size)
 398                        ptr = 0;
 399        }
 400        if (stream_number == 1) {
 401                pci_adp = READREG(PCI_ADP1);
 402                ptr = pci_adp - (size_t) start_addr;
 403
 404                if (ptr == buffer_size)
 405                        ptr = 0;
 406        }
 407        return ptr;
 408}
 409
 410unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
 411                                                int stream_number,
 412                                                unsigned char *start_addr,
 413                                                unsigned int buffer_size)
 414{
 415        size_t pci_adp = 0;
 416        size_t ptr = 0;
 417        if (stream_number == 0) {
 418                pci_adp = READREG(PCI_ADP2);
 419                ptr = pci_adp - (size_t) start_addr;
 420
 421                if (ptr == buffer_size)
 422                        ptr = 0;
 423        }
 424        return ptr;
 425}
 426
 427void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
 428                                       int use_digital)
 429{
 430        /* FIXME: switch between analog and digital input does not always work.
 431           It can produce a kind of white noise. It seams that received data
 432           are inverted sometime (endian inversion). Why ? I don't know, maybe
 433           a problem of synchronization... However for the time being I have
 434           not found the problem. Workaround: switch again (and again) between
 435           digital and analog input until it works. */
 436        if (use_digital)
 437                WRITEREG(0x40, GPIO_CTRL);
 438        else
 439                WRITEREG(0x50, GPIO_CTRL);
 440}
 441
 442int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
 443{
 444        unsigned int reg_val = READREG(GPIO_CTRL);
 445        if ((reg_val & 0xFF) == 0x40)
 446                return 1;
 447        else
 448                return 0;
 449}
 450
 451
 452static int snd_aw2_saa7146_get_limit(int size)
 453{
 454        int limitsize = 32;
 455        int limit = 0;
 456        while (limitsize < size) {
 457                limitsize *= 2;
 458                limit++;
 459        }
 460        return limit;
 461}
 462