linux/sound/pci/aw2/aw2-alsa.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*****************************************************************************
   3 *
   4 * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
   5 * Jean-Christian Hassler <jhassler@free.fr>
   6 *
   7 * This file is part of the Audiowerk2 ALSA driver
   8 *
   9 *****************************************************************************/
  10#include <linux/init.h>
  11#include <linux/pci.h>
  12#include <linux/dma-mapping.h>
  13#include <linux/slab.h>
  14#include <linux/interrupt.h>
  15#include <linux/delay.h>
  16#include <linux/io.h>
  17#include <linux/module.h>
  18#include <sound/core.h>
  19#include <sound/initval.h>
  20#include <sound/pcm.h>
  21#include <sound/pcm_params.h>
  22#include <sound/control.h>
  23
  24#include "saa7146.h"
  25#include "aw2-saa7146.h"
  26
  27MODULE_AUTHOR("Cedric Bregardis <cedric.bregardis@free.fr>, "
  28              "Jean-Christian Hassler <jhassler@free.fr>");
  29MODULE_DESCRIPTION("Emagic Audiowerk 2 sound driver");
  30MODULE_LICENSE("GPL");
  31
  32/*********************************
  33 * DEFINES
  34 ********************************/
  35#define CTL_ROUTE_ANALOG 0
  36#define CTL_ROUTE_DIGITAL 1
  37
  38/*********************************
  39 * TYPEDEFS
  40 ********************************/
  41  /* hardware definition */
  42static const struct snd_pcm_hardware snd_aw2_playback_hw = {
  43        .info = (SNDRV_PCM_INFO_MMAP |
  44                 SNDRV_PCM_INFO_INTERLEAVED |
  45                 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
  46        .formats = SNDRV_PCM_FMTBIT_S16_LE,
  47        .rates = SNDRV_PCM_RATE_44100,
  48        .rate_min = 44100,
  49        .rate_max = 44100,
  50        .channels_min = 2,
  51        .channels_max = 4,
  52        .buffer_bytes_max = 32768,
  53        .period_bytes_min = 4096,
  54        .period_bytes_max = 32768,
  55        .periods_min = 1,
  56        .periods_max = 1024,
  57};
  58
  59static const struct snd_pcm_hardware snd_aw2_capture_hw = {
  60        .info = (SNDRV_PCM_INFO_MMAP |
  61                 SNDRV_PCM_INFO_INTERLEAVED |
  62                 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
  63        .formats = SNDRV_PCM_FMTBIT_S16_LE,
  64        .rates = SNDRV_PCM_RATE_44100,
  65        .rate_min = 44100,
  66        .rate_max = 44100,
  67        .channels_min = 2,
  68        .channels_max = 2,
  69        .buffer_bytes_max = 32768,
  70        .period_bytes_min = 4096,
  71        .period_bytes_max = 32768,
  72        .periods_min = 1,
  73        .periods_max = 1024,
  74};
  75
  76struct aw2_pcm_device {
  77        struct snd_pcm *pcm;
  78        unsigned int stream_number;
  79        struct aw2 *chip;
  80};
  81
  82struct aw2 {
  83        struct snd_aw2_saa7146 saa7146;
  84
  85        struct pci_dev *pci;
  86        int irq;
  87        spinlock_t reg_lock;
  88        struct mutex mtx;
  89
  90        unsigned long iobase_phys;
  91        void __iomem *iobase_virt;
  92
  93        struct snd_card *card;
  94
  95        struct aw2_pcm_device device_playback[NB_STREAM_PLAYBACK];
  96        struct aw2_pcm_device device_capture[NB_STREAM_CAPTURE];
  97};
  98
  99/*********************************
 100 * FUNCTION DECLARATIONS
 101 ********************************/
 102static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci);
 103static int snd_aw2_probe(struct pci_dev *pci,
 104                         const struct pci_device_id *pci_id);
 105static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
 106static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
 107static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
 108static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream);
 109static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream);
 110static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream);
 111static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
 112                                        int cmd);
 113static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
 114                                       int cmd);
 115static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
 116                                                      *substream);
 117static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
 118                                                     *substream);
 119static int snd_aw2_new_pcm(struct aw2 *chip);
 120
 121static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
 122                                               struct snd_ctl_elem_info *uinfo);
 123static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
 124                                              struct snd_ctl_elem_value
 125                                              *ucontrol);
 126static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
 127                                              struct snd_ctl_elem_value
 128                                              *ucontrol);
 129
 130/*********************************
 131 * VARIABLES
 132 ********************************/
 133static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 134static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 135static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 136
 137module_param_array(index, int, NULL, 0444);
 138MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard.");
 139module_param_array(id, charp, NULL, 0444);
 140MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
 141module_param_array(enable, bool, NULL, 0444);
 142MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
 143
 144static const struct pci_device_id snd_aw2_ids[] = {
 145        {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0,
 146         0, 0, 0},
 147        {0}
 148};
 149
 150MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
 151
 152/* pci_driver definition */
 153static struct pci_driver aw2_driver = {
 154        .name = KBUILD_MODNAME,
 155        .id_table = snd_aw2_ids,
 156        .probe = snd_aw2_probe,
 157};
 158
 159module_pci_driver(aw2_driver);
 160
 161/* operators for playback PCM alsa interface */
 162static const struct snd_pcm_ops snd_aw2_playback_ops = {
 163        .open = snd_aw2_pcm_playback_open,
 164        .close = snd_aw2_pcm_playback_close,
 165        .prepare = snd_aw2_pcm_prepare_playback,
 166        .trigger = snd_aw2_pcm_trigger_playback,
 167        .pointer = snd_aw2_pcm_pointer_playback,
 168};
 169
 170/* operators for capture PCM alsa interface */
 171static const struct snd_pcm_ops snd_aw2_capture_ops = {
 172        .open = snd_aw2_pcm_capture_open,
 173        .close = snd_aw2_pcm_capture_close,
 174        .prepare = snd_aw2_pcm_prepare_capture,
 175        .trigger = snd_aw2_pcm_trigger_capture,
 176        .pointer = snd_aw2_pcm_pointer_capture,
 177};
 178
 179static const struct snd_kcontrol_new aw2_control = {
 180        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 181        .name = "PCM Capture Route",
 182        .index = 0,
 183        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 184        .private_value = 0xffff,
 185        .info = snd_aw2_control_switch_capture_info,
 186        .get = snd_aw2_control_switch_capture_get,
 187        .put = snd_aw2_control_switch_capture_put
 188};
 189
 190/*********************************
 191 * FUNCTION IMPLEMENTATIONS
 192 ********************************/
 193
 194/* component-destructor */
 195static void snd_aw2_free(struct snd_card *card)
 196{
 197        struct aw2 *chip = card->private_data;
 198
 199        /* Free hardware */
 200        snd_aw2_saa7146_free(&chip->saa7146);
 201}
 202
 203/* chip-specific constructor */
 204static int snd_aw2_create(struct snd_card *card,
 205                          struct pci_dev *pci)
 206{
 207        struct aw2 *chip = card->private_data;
 208        int err;
 209
 210        /* initialize the PCI entry */
 211        err = pcim_enable_device(pci);
 212        if (err < 0)
 213                return err;
 214        pci_set_master(pci);
 215
 216        /* check PCI availability (32bit DMA) */
 217        if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
 218                dev_err(card->dev, "Impossible to set 32bit mask DMA\n");
 219                return -ENXIO;
 220        }
 221
 222        /* initialize the stuff */
 223        chip->card = card;
 224        chip->pci = pci;
 225        chip->irq = -1;
 226
 227        /* (1) PCI resource allocation */
 228        err = pcim_iomap_regions(pci, 1 << 0, "Audiowerk2");
 229        if (err < 0)
 230                return err;
 231        chip->iobase_phys = pci_resource_start(pci, 0);
 232        chip->iobase_virt = pcim_iomap_table(pci)[0];
 233
 234        /* (2) initialization of the chip hardware */
 235        snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
 236
 237        if (devm_request_irq(&pci->dev, pci->irq, snd_aw2_saa7146_interrupt,
 238                             IRQF_SHARED, KBUILD_MODNAME, chip)) {
 239                dev_err(card->dev, "Cannot grab irq %d\n", pci->irq);
 240                return -EBUSY;
 241        }
 242        chip->irq = pci->irq;
 243        card->sync_irq = chip->irq;
 244        card->private_free = snd_aw2_free;
 245
 246        dev_info(card->dev,
 247                 "Audiowerk 2 sound card (saa7146 chipset) detected and managed\n");
 248        return 0;
 249}
 250
 251/* constructor */
 252static int snd_aw2_probe(struct pci_dev *pci,
 253                         const struct pci_device_id *pci_id)
 254{
 255        static int dev;
 256        struct snd_card *card;
 257        struct aw2 *chip;
 258        int err;
 259
 260        /* (1) Continue if device is not enabled, else inc dev */
 261        if (dev >= SNDRV_CARDS)
 262                return -ENODEV;
 263        if (!enable[dev]) {
 264                dev++;
 265                return -ENOENT;
 266        }
 267
 268        /* (2) Create card instance */
 269        err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
 270                                sizeof(*chip), &card);
 271        if (err < 0)
 272                return err;
 273        chip = card->private_data;
 274
 275        /* (3) Create main component */
 276        err = snd_aw2_create(card, pci);
 277        if (err < 0)
 278                goto error;
 279
 280        /* initialize mutex */
 281        mutex_init(&chip->mtx);
 282        /* init spinlock */
 283        spin_lock_init(&chip->reg_lock);
 284        /* (4) Define driver ID and name string */
 285        strcpy(card->driver, "aw2");
 286        strcpy(card->shortname, "Audiowerk2");
 287
 288        sprintf(card->longname, "%s with SAA7146 irq %i",
 289                card->shortname, chip->irq);
 290
 291        /* (5) Create other components */
 292        snd_aw2_new_pcm(chip);
 293
 294        /* (6) Register card instance */
 295        err = snd_card_register(card);
 296        if (err < 0)
 297                goto error;
 298
 299        /* (7) Set PCI driver data */
 300        pci_set_drvdata(pci, card);
 301
 302        dev++;
 303        return 0;
 304
 305 error:
 306        snd_card_free(card);
 307        return err;
 308}
 309
 310/* open callback */
 311static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream)
 312{
 313        struct snd_pcm_runtime *runtime = substream->runtime;
 314
 315        dev_dbg(substream->pcm->card->dev, "Playback_open\n");
 316        runtime->hw = snd_aw2_playback_hw;
 317        return 0;
 318}
 319
 320/* close callback */
 321static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream)
 322{
 323        return 0;
 324
 325}
 326
 327static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream)
 328{
 329        struct snd_pcm_runtime *runtime = substream->runtime;
 330
 331        dev_dbg(substream->pcm->card->dev, "Capture_open\n");
 332        runtime->hw = snd_aw2_capture_hw;
 333        return 0;
 334}
 335
 336/* close callback */
 337static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream)
 338{
 339        /* TODO: something to do ? */
 340        return 0;
 341}
 342
 343/* prepare callback for playback */
 344static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream)
 345{
 346        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 347        struct aw2 *chip = pcm_device->chip;
 348        struct snd_pcm_runtime *runtime = substream->runtime;
 349        unsigned long period_size, buffer_size;
 350
 351        mutex_lock(&chip->mtx);
 352
 353        period_size = snd_pcm_lib_period_bytes(substream);
 354        buffer_size = snd_pcm_lib_buffer_bytes(substream);
 355
 356        snd_aw2_saa7146_pcm_init_playback(&chip->saa7146,
 357                                          pcm_device->stream_number,
 358                                          runtime->dma_addr, period_size,
 359                                          buffer_size);
 360
 361        /* Define Interrupt callback */
 362        snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number,
 363                                                    (snd_aw2_saa7146_it_cb)
 364                                                    snd_pcm_period_elapsed,
 365                                                    (void *)substream);
 366
 367        mutex_unlock(&chip->mtx);
 368
 369        return 0;
 370}
 371
 372/* prepare callback for capture */
 373static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
 374{
 375        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 376        struct aw2 *chip = pcm_device->chip;
 377        struct snd_pcm_runtime *runtime = substream->runtime;
 378        unsigned long period_size, buffer_size;
 379
 380        mutex_lock(&chip->mtx);
 381
 382        period_size = snd_pcm_lib_period_bytes(substream);
 383        buffer_size = snd_pcm_lib_buffer_bytes(substream);
 384
 385        snd_aw2_saa7146_pcm_init_capture(&chip->saa7146,
 386                                         pcm_device->stream_number,
 387                                         runtime->dma_addr, period_size,
 388                                         buffer_size);
 389
 390        /* Define Interrupt callback */
 391        snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number,
 392                                                   (snd_aw2_saa7146_it_cb)
 393                                                   snd_pcm_period_elapsed,
 394                                                   (void *)substream);
 395
 396        mutex_unlock(&chip->mtx);
 397
 398        return 0;
 399}
 400
 401/* playback trigger callback */
 402static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
 403                                        int cmd)
 404{
 405        int status = 0;
 406        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 407        struct aw2 *chip = pcm_device->chip;
 408        spin_lock(&chip->reg_lock);
 409        switch (cmd) {
 410        case SNDRV_PCM_TRIGGER_START:
 411                snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146,
 412                                                           pcm_device->
 413                                                           stream_number);
 414                break;
 415        case SNDRV_PCM_TRIGGER_STOP:
 416                snd_aw2_saa7146_pcm_trigger_stop_playback(&chip->saa7146,
 417                                                          pcm_device->
 418                                                          stream_number);
 419                break;
 420        default:
 421                status = -EINVAL;
 422        }
 423        spin_unlock(&chip->reg_lock);
 424        return status;
 425}
 426
 427/* capture trigger callback */
 428static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
 429                                       int cmd)
 430{
 431        int status = 0;
 432        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 433        struct aw2 *chip = pcm_device->chip;
 434        spin_lock(&chip->reg_lock);
 435        switch (cmd) {
 436        case SNDRV_PCM_TRIGGER_START:
 437                snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146,
 438                                                          pcm_device->
 439                                                          stream_number);
 440                break;
 441        case SNDRV_PCM_TRIGGER_STOP:
 442                snd_aw2_saa7146_pcm_trigger_stop_capture(&chip->saa7146,
 443                                                         pcm_device->
 444                                                         stream_number);
 445                break;
 446        default:
 447                status = -EINVAL;
 448        }
 449        spin_unlock(&chip->reg_lock);
 450        return status;
 451}
 452
 453/* playback pointer callback */
 454static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
 455                                                      *substream)
 456{
 457        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 458        struct aw2 *chip = pcm_device->chip;
 459        unsigned int current_ptr;
 460
 461        /* get the current hardware pointer */
 462        struct snd_pcm_runtime *runtime = substream->runtime;
 463        current_ptr =
 464                snd_aw2_saa7146_get_hw_ptr_playback(&chip->saa7146,
 465                                                    pcm_device->stream_number,
 466                                                    runtime->dma_area,
 467                                                    runtime->buffer_size);
 468
 469        return bytes_to_frames(substream->runtime, current_ptr);
 470}
 471
 472/* capture pointer callback */
 473static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
 474                                                     *substream)
 475{
 476        struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
 477        struct aw2 *chip = pcm_device->chip;
 478        unsigned int current_ptr;
 479
 480        /* get the current hardware pointer */
 481        struct snd_pcm_runtime *runtime = substream->runtime;
 482        current_ptr =
 483                snd_aw2_saa7146_get_hw_ptr_capture(&chip->saa7146,
 484                                                   pcm_device->stream_number,
 485                                                   runtime->dma_area,
 486                                                   runtime->buffer_size);
 487
 488        return bytes_to_frames(substream->runtime, current_ptr);
 489}
 490
 491/* create a pcm device */
 492static int snd_aw2_new_pcm(struct aw2 *chip)
 493{
 494        struct snd_pcm *pcm_playback_ana;
 495        struct snd_pcm *pcm_playback_num;
 496        struct snd_pcm *pcm_capture;
 497        struct aw2_pcm_device *pcm_device;
 498        int err = 0;
 499
 500        /* Create new Alsa PCM device */
 501
 502        err = snd_pcm_new(chip->card, "Audiowerk2 analog playback", 0, 1, 0,
 503                          &pcm_playback_ana);
 504        if (err < 0) {
 505                dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
 506                return err;
 507        }
 508
 509        /* Creation ok */
 510        pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA];
 511
 512        /* Set PCM device name */
 513        strcpy(pcm_playback_ana->name, "Analog playback");
 514        /* Associate private data to PCM device */
 515        pcm_playback_ana->private_data = pcm_device;
 516        /* set operators of PCM device */
 517        snd_pcm_set_ops(pcm_playback_ana, SNDRV_PCM_STREAM_PLAYBACK,
 518                        &snd_aw2_playback_ops);
 519        /* store PCM device */
 520        pcm_device->pcm = pcm_playback_ana;
 521        /* give base chip pointer to our internal pcm device
 522           structure */
 523        pcm_device->chip = chip;
 524        /* Give stream number to PCM device */
 525        pcm_device->stream_number = NUM_STREAM_PLAYBACK_ANA;
 526
 527        /* pre-allocation of buffers */
 528        /* Preallocate continuous pages. */
 529        snd_pcm_set_managed_buffer_all(pcm_playback_ana,
 530                                       SNDRV_DMA_TYPE_DEV,
 531                                       &chip->pci->dev,
 532                                       64 * 1024, 64 * 1024);
 533
 534        err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0,
 535                          &pcm_playback_num);
 536
 537        if (err < 0) {
 538                dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
 539                return err;
 540        }
 541        /* Creation ok */
 542        pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG];
 543
 544        /* Set PCM device name */
 545        strcpy(pcm_playback_num->name, "Digital playback");
 546        /* Associate private data to PCM device */
 547        pcm_playback_num->private_data = pcm_device;
 548        /* set operators of PCM device */
 549        snd_pcm_set_ops(pcm_playback_num, SNDRV_PCM_STREAM_PLAYBACK,
 550                        &snd_aw2_playback_ops);
 551        /* store PCM device */
 552        pcm_device->pcm = pcm_playback_num;
 553        /* give base chip pointer to our internal pcm device
 554           structure */
 555        pcm_device->chip = chip;
 556        /* Give stream number to PCM device */
 557        pcm_device->stream_number = NUM_STREAM_PLAYBACK_DIG;
 558
 559        /* pre-allocation of buffers */
 560        /* Preallocate continuous pages. */
 561        snd_pcm_set_managed_buffer_all(pcm_playback_num,
 562                                       SNDRV_DMA_TYPE_DEV,
 563                                       &chip->pci->dev,
 564                                       64 * 1024, 64 * 1024);
 565
 566        err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1,
 567                          &pcm_capture);
 568
 569        if (err < 0) {
 570                dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
 571                return err;
 572        }
 573
 574        /* Creation ok */
 575        pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA];
 576
 577        /* Set PCM device name */
 578        strcpy(pcm_capture->name, "Capture");
 579        /* Associate private data to PCM device */
 580        pcm_capture->private_data = pcm_device;
 581        /* set operators of PCM device */
 582        snd_pcm_set_ops(pcm_capture, SNDRV_PCM_STREAM_CAPTURE,
 583                        &snd_aw2_capture_ops);
 584        /* store PCM device */
 585        pcm_device->pcm = pcm_capture;
 586        /* give base chip pointer to our internal pcm device
 587           structure */
 588        pcm_device->chip = chip;
 589        /* Give stream number to PCM device */
 590        pcm_device->stream_number = NUM_STREAM_CAPTURE_ANA;
 591
 592        /* pre-allocation of buffers */
 593        /* Preallocate continuous pages. */
 594        snd_pcm_set_managed_buffer_all(pcm_capture,
 595                                       SNDRV_DMA_TYPE_DEV,
 596                                       &chip->pci->dev,
 597                                       64 * 1024, 64 * 1024);
 598
 599        /* Create control */
 600        err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip));
 601        if (err < 0) {
 602                dev_err(chip->card->dev, "snd_ctl_add error (0x%X)\n", err);
 603                return err;
 604        }
 605
 606        return 0;
 607}
 608
 609static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
 610                                               struct snd_ctl_elem_info *uinfo)
 611{
 612        static const char * const texts[2] = {
 613                "Analog", "Digital"
 614        };
 615        return snd_ctl_enum_info(uinfo, 1, 2, texts);
 616}
 617
 618static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
 619                                              struct snd_ctl_elem_value
 620                                              *ucontrol)
 621{
 622        struct aw2 *chip = snd_kcontrol_chip(kcontrol);
 623        if (snd_aw2_saa7146_is_using_digital_input(&chip->saa7146))
 624                ucontrol->value.enumerated.item[0] = CTL_ROUTE_DIGITAL;
 625        else
 626                ucontrol->value.enumerated.item[0] = CTL_ROUTE_ANALOG;
 627        return 0;
 628}
 629
 630static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
 631                                              struct snd_ctl_elem_value
 632                                              *ucontrol)
 633{
 634        struct aw2 *chip = snd_kcontrol_chip(kcontrol);
 635        int changed = 0;
 636        int is_disgital =
 637            snd_aw2_saa7146_is_using_digital_input(&chip->saa7146);
 638
 639        if (((ucontrol->value.integer.value[0] == CTL_ROUTE_DIGITAL)
 640             && !is_disgital)
 641            || ((ucontrol->value.integer.value[0] == CTL_ROUTE_ANALOG)
 642                && is_disgital)) {
 643                snd_aw2_saa7146_use_digital_input(&chip->saa7146, !is_disgital);
 644                changed = 1;
 645        }
 646        return changed;
 647}
 648