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
27 MODULE_AUTHOR("Cedric Bregardis <cedric.bregardis@free.fr>, "
28 "Jean-Christian Hassler <jhassler@free.fr>");
29 MODULE_DESCRIPTION("Emagic Audiowerk 2 sound driver");
30 MODULE_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 */
42 static 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
59 static 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
76 struct aw2_pcm_device {
77 struct snd_pcm *pcm;
78 unsigned int stream_number;
79 struct aw2 *chip;
80 };
81
82 struct 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 ********************************/
102 static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci);
103 static int snd_aw2_probe(struct pci_dev *pci,
104 const struct pci_device_id *pci_id);
105 static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
106 static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
107 static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
108 static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream);
109 static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream);
110 static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream);
111 static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
112 int cmd);
113 static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
114 int cmd);
115 static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
116 *substream);
117 static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
118 *substream);
119 static int snd_aw2_new_pcm(struct aw2 *chip);
120
121 static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_info *uinfo);
123 static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
124 struct snd_ctl_elem_value
125 *ucontrol);
126 static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value
128 *ucontrol);
129
130 /*********************************
131 * VARIABLES
132 ********************************/
133 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
134 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
135 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
136
137 module_param_array(index, int, NULL, 0444);
138 MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard.");
139 module_param_array(id, charp, NULL, 0444);
140 MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
141 module_param_array(enable, bool, NULL, 0444);
142 MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
143
144 static 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
150 MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
151
152 /* pci_driver definition */
153 static struct pci_driver aw2_driver = {
154 .name = KBUILD_MODNAME,
155 .id_table = snd_aw2_ids,
156 .probe = snd_aw2_probe,
157 };
158
159 module_pci_driver(aw2_driver);
160
161 /* operators for playback PCM alsa interface */
162 static 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 */
171 static 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
179 static 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 */
snd_aw2_free(struct snd_card * card)195 static 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 */
snd_aw2_create(struct snd_card * card,struct pci_dev * pci)204 static 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 chip->iobase_virt = pcim_iomap_region(pci, 0, "Audiowerk2");
229 if (IS_ERR(chip->iobase_virt))
230 return PTR_ERR(chip->iobase_virt);
231 chip->iobase_phys = pci_resource_start(pci, 0);
232
233 /* (2) initialization of the chip hardware */
234 snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
235
236 if (devm_request_irq(&pci->dev, pci->irq, snd_aw2_saa7146_interrupt,
237 IRQF_SHARED, KBUILD_MODNAME, chip)) {
238 dev_err(card->dev, "Cannot grab irq %d\n", pci->irq);
239 return -EBUSY;
240 }
241 chip->irq = pci->irq;
242 card->sync_irq = chip->irq;
243 card->private_free = snd_aw2_free;
244
245 dev_info(card->dev,
246 "Audiowerk 2 sound card (saa7146 chipset) detected and managed\n");
247 return 0;
248 }
249
250 /* constructor */
snd_aw2_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)251 static int snd_aw2_probe(struct pci_dev *pci,
252 const struct pci_device_id *pci_id)
253 {
254 static int dev;
255 struct snd_card *card;
256 struct aw2 *chip;
257 int err;
258
259 /* (1) Continue if device is not enabled, else inc dev */
260 if (dev >= SNDRV_CARDS)
261 return -ENODEV;
262 if (!enable[dev]) {
263 dev++;
264 return -ENOENT;
265 }
266
267 /* (2) Create card instance */
268 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
269 sizeof(*chip), &card);
270 if (err < 0)
271 return err;
272 chip = card->private_data;
273
274 /* (3) Create main component */
275 err = snd_aw2_create(card, pci);
276 if (err < 0)
277 goto error;
278
279 /* initialize mutex */
280 mutex_init(&chip->mtx);
281 /* init spinlock */
282 spin_lock_init(&chip->reg_lock);
283 /* (4) Define driver ID and name string */
284 strcpy(card->driver, "aw2");
285 strcpy(card->shortname, "Audiowerk2");
286
287 sprintf(card->longname, "%s with SAA7146 irq %i",
288 card->shortname, chip->irq);
289
290 /* (5) Create other components */
291 snd_aw2_new_pcm(chip);
292
293 /* (6) Register card instance */
294 err = snd_card_register(card);
295 if (err < 0)
296 goto error;
297
298 /* (7) Set PCI driver data */
299 pci_set_drvdata(pci, card);
300
301 dev++;
302 return 0;
303
304 error:
305 snd_card_free(card);
306 return err;
307 }
308
309 /* open callback */
snd_aw2_pcm_playback_open(struct snd_pcm_substream * substream)310 static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream)
311 {
312 struct snd_pcm_runtime *runtime = substream->runtime;
313
314 dev_dbg(substream->pcm->card->dev, "Playback_open\n");
315 runtime->hw = snd_aw2_playback_hw;
316 return 0;
317 }
318
319 /* close callback */
snd_aw2_pcm_playback_close(struct snd_pcm_substream * substream)320 static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream)
321 {
322 return 0;
323
324 }
325
snd_aw2_pcm_capture_open(struct snd_pcm_substream * substream)326 static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream)
327 {
328 struct snd_pcm_runtime *runtime = substream->runtime;
329
330 dev_dbg(substream->pcm->card->dev, "Capture_open\n");
331 runtime->hw = snd_aw2_capture_hw;
332 return 0;
333 }
334
335 /* close callback */
snd_aw2_pcm_capture_close(struct snd_pcm_substream * substream)336 static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream)
337 {
338 /* TODO: something to do ? */
339 return 0;
340 }
341
342 /* prepare callback for playback */
snd_aw2_pcm_prepare_playback(struct snd_pcm_substream * substream)343 static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream)
344 {
345 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
346 struct aw2 *chip = pcm_device->chip;
347 struct snd_pcm_runtime *runtime = substream->runtime;
348 unsigned long period_size, buffer_size;
349
350 mutex_lock(&chip->mtx);
351
352 period_size = snd_pcm_lib_period_bytes(substream);
353 buffer_size = snd_pcm_lib_buffer_bytes(substream);
354
355 snd_aw2_saa7146_pcm_init_playback(&chip->saa7146,
356 pcm_device->stream_number,
357 runtime->dma_addr, period_size,
358 buffer_size);
359
360 /* Define Interrupt callback */
361 snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number,
362 (snd_aw2_saa7146_it_cb)
363 snd_pcm_period_elapsed,
364 (void *)substream);
365
366 mutex_unlock(&chip->mtx);
367
368 return 0;
369 }
370
371 /* prepare callback for capture */
snd_aw2_pcm_prepare_capture(struct snd_pcm_substream * substream)372 static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream)
373 {
374 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
375 struct aw2 *chip = pcm_device->chip;
376 struct snd_pcm_runtime *runtime = substream->runtime;
377 unsigned long period_size, buffer_size;
378
379 mutex_lock(&chip->mtx);
380
381 period_size = snd_pcm_lib_period_bytes(substream);
382 buffer_size = snd_pcm_lib_buffer_bytes(substream);
383
384 snd_aw2_saa7146_pcm_init_capture(&chip->saa7146,
385 pcm_device->stream_number,
386 runtime->dma_addr, period_size,
387 buffer_size);
388
389 /* Define Interrupt callback */
390 snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number,
391 (snd_aw2_saa7146_it_cb)
392 snd_pcm_period_elapsed,
393 (void *)substream);
394
395 mutex_unlock(&chip->mtx);
396
397 return 0;
398 }
399
400 /* playback trigger callback */
snd_aw2_pcm_trigger_playback(struct snd_pcm_substream * substream,int cmd)401 static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream,
402 int cmd)
403 {
404 int status = 0;
405 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
406 struct aw2 *chip = pcm_device->chip;
407 spin_lock(&chip->reg_lock);
408 switch (cmd) {
409 case SNDRV_PCM_TRIGGER_START:
410 snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146,
411 pcm_device->
412 stream_number);
413 break;
414 case SNDRV_PCM_TRIGGER_STOP:
415 snd_aw2_saa7146_pcm_trigger_stop_playback(&chip->saa7146,
416 pcm_device->
417 stream_number);
418 break;
419 default:
420 status = -EINVAL;
421 }
422 spin_unlock(&chip->reg_lock);
423 return status;
424 }
425
426 /* capture trigger callback */
snd_aw2_pcm_trigger_capture(struct snd_pcm_substream * substream,int cmd)427 static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream,
428 int cmd)
429 {
430 int status = 0;
431 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
432 struct aw2 *chip = pcm_device->chip;
433 spin_lock(&chip->reg_lock);
434 switch (cmd) {
435 case SNDRV_PCM_TRIGGER_START:
436 snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146,
437 pcm_device->
438 stream_number);
439 break;
440 case SNDRV_PCM_TRIGGER_STOP:
441 snd_aw2_saa7146_pcm_trigger_stop_capture(&chip->saa7146,
442 pcm_device->
443 stream_number);
444 break;
445 default:
446 status = -EINVAL;
447 }
448 spin_unlock(&chip->reg_lock);
449 return status;
450 }
451
452 /* playback pointer callback */
snd_aw2_pcm_pointer_playback(struct snd_pcm_substream * substream)453 static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream
454 *substream)
455 {
456 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
457 struct aw2 *chip = pcm_device->chip;
458 unsigned int current_ptr;
459
460 /* get the current hardware pointer */
461 struct snd_pcm_runtime *runtime = substream->runtime;
462 current_ptr =
463 snd_aw2_saa7146_get_hw_ptr_playback(&chip->saa7146,
464 pcm_device->stream_number,
465 runtime->dma_area,
466 runtime->buffer_size);
467
468 return bytes_to_frames(substream->runtime, current_ptr);
469 }
470
471 /* capture pointer callback */
snd_aw2_pcm_pointer_capture(struct snd_pcm_substream * substream)472 static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
473 *substream)
474 {
475 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream);
476 struct aw2 *chip = pcm_device->chip;
477 unsigned int current_ptr;
478
479 /* get the current hardware pointer */
480 struct snd_pcm_runtime *runtime = substream->runtime;
481 current_ptr =
482 snd_aw2_saa7146_get_hw_ptr_capture(&chip->saa7146,
483 pcm_device->stream_number,
484 runtime->dma_area,
485 runtime->buffer_size);
486
487 return bytes_to_frames(substream->runtime, current_ptr);
488 }
489
490 /* create a pcm device */
snd_aw2_new_pcm(struct aw2 * chip)491 static int snd_aw2_new_pcm(struct aw2 *chip)
492 {
493 struct snd_pcm *pcm_playback_ana;
494 struct snd_pcm *pcm_playback_num;
495 struct snd_pcm *pcm_capture;
496 struct aw2_pcm_device *pcm_device;
497 int err = 0;
498
499 /* Create new Alsa PCM device */
500
501 err = snd_pcm_new(chip->card, "Audiowerk2 analog playback", 0, 1, 0,
502 &pcm_playback_ana);
503 if (err < 0) {
504 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
505 return err;
506 }
507
508 /* Creation ok */
509 pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA];
510
511 /* Set PCM device name */
512 strcpy(pcm_playback_ana->name, "Analog playback");
513 /* Associate private data to PCM device */
514 pcm_playback_ana->private_data = pcm_device;
515 /* set operators of PCM device */
516 snd_pcm_set_ops(pcm_playback_ana, SNDRV_PCM_STREAM_PLAYBACK,
517 &snd_aw2_playback_ops);
518 /* store PCM device */
519 pcm_device->pcm = pcm_playback_ana;
520 /* give base chip pointer to our internal pcm device
521 structure */
522 pcm_device->chip = chip;
523 /* Give stream number to PCM device */
524 pcm_device->stream_number = NUM_STREAM_PLAYBACK_ANA;
525
526 /* pre-allocation of buffers */
527 /* Preallocate continuous pages. */
528 snd_pcm_set_managed_buffer_all(pcm_playback_ana,
529 SNDRV_DMA_TYPE_DEV,
530 &chip->pci->dev,
531 64 * 1024, 64 * 1024);
532
533 err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0,
534 &pcm_playback_num);
535
536 if (err < 0) {
537 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
538 return err;
539 }
540 /* Creation ok */
541 pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG];
542
543 /* Set PCM device name */
544 strcpy(pcm_playback_num->name, "Digital playback");
545 /* Associate private data to PCM device */
546 pcm_playback_num->private_data = pcm_device;
547 /* set operators of PCM device */
548 snd_pcm_set_ops(pcm_playback_num, SNDRV_PCM_STREAM_PLAYBACK,
549 &snd_aw2_playback_ops);
550 /* store PCM device */
551 pcm_device->pcm = pcm_playback_num;
552 /* give base chip pointer to our internal pcm device
553 structure */
554 pcm_device->chip = chip;
555 /* Give stream number to PCM device */
556 pcm_device->stream_number = NUM_STREAM_PLAYBACK_DIG;
557
558 /* pre-allocation of buffers */
559 /* Preallocate continuous pages. */
560 snd_pcm_set_managed_buffer_all(pcm_playback_num,
561 SNDRV_DMA_TYPE_DEV,
562 &chip->pci->dev,
563 64 * 1024, 64 * 1024);
564
565 err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1,
566 &pcm_capture);
567
568 if (err < 0) {
569 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err);
570 return err;
571 }
572
573 /* Creation ok */
574 pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA];
575
576 /* Set PCM device name */
577 strcpy(pcm_capture->name, "Capture");
578 /* Associate private data to PCM device */
579 pcm_capture->private_data = pcm_device;
580 /* set operators of PCM device */
581 snd_pcm_set_ops(pcm_capture, SNDRV_PCM_STREAM_CAPTURE,
582 &snd_aw2_capture_ops);
583 /* store PCM device */
584 pcm_device->pcm = pcm_capture;
585 /* give base chip pointer to our internal pcm device
586 structure */
587 pcm_device->chip = chip;
588 /* Give stream number to PCM device */
589 pcm_device->stream_number = NUM_STREAM_CAPTURE_ANA;
590
591 /* pre-allocation of buffers */
592 /* Preallocate continuous pages. */
593 snd_pcm_set_managed_buffer_all(pcm_capture,
594 SNDRV_DMA_TYPE_DEV,
595 &chip->pci->dev,
596 64 * 1024, 64 * 1024);
597
598 /* Create control */
599 err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip));
600 if (err < 0) {
601 dev_err(chip->card->dev, "snd_ctl_add error (0x%X)\n", err);
602 return err;
603 }
604
605 return 0;
606 }
607
snd_aw2_control_switch_capture_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)608 static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_info *uinfo)
610 {
611 static const char * const texts[2] = {
612 "Analog", "Digital"
613 };
614 return snd_ctl_enum_info(uinfo, 1, 2, texts);
615 }
616
snd_aw2_control_switch_capture_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)617 static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol,
618 struct snd_ctl_elem_value
619 *ucontrol)
620 {
621 struct aw2 *chip = snd_kcontrol_chip(kcontrol);
622 if (snd_aw2_saa7146_is_using_digital_input(&chip->saa7146))
623 ucontrol->value.enumerated.item[0] = CTL_ROUTE_DIGITAL;
624 else
625 ucontrol->value.enumerated.item[0] = CTL_ROUTE_ANALOG;
626 return 0;
627 }
628
snd_aw2_control_switch_capture_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)629 static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol,
630 struct snd_ctl_elem_value
631 *ucontrol)
632 {
633 struct aw2 *chip = snd_kcontrol_chip(kcontrol);
634 int changed = 0;
635 int is_disgital =
636 snd_aw2_saa7146_is_using_digital_input(&chip->saa7146);
637
638 if (((ucontrol->value.integer.value[0] == CTL_ROUTE_DIGITAL)
639 && !is_disgital)
640 || ((ucontrol->value.integer.value[0] == CTL_ROUTE_ANALOG)
641 && is_disgital)) {
642 snd_aw2_saa7146_use_digital_input(&chip->saa7146, !is_disgital);
643 changed = 1;
644 }
645 return changed;
646 }
647