cx88-alsa.c (7b61ba8ff838dbee422d428fbd882ab83db4b2d9) cx88-alsa.c (399426cadf5b0539a5b2a4d805257ce8acc6aba2)
1/*
2 * Support for audio capture
3 * PCI function #1 of the cx2388x.
4 *
5 * (c) 2007 Trent Piepho <xyzzy@speakeasy.org>
6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
7 * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>

--- 10 unchanged lines hidden (view full) ---

19 * GNU General Public License for more details.
20 */
21
22#include "cx88.h"
23#include "cx88-reg.h"
24
25#include <linux/module.h>
26#include <linux/init.h>
1/*
2 * Support for audio capture
3 * PCI function #1 of the cx2388x.
4 *
5 * (c) 2007 Trent Piepho <xyzzy@speakeasy.org>
6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
7 * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>

--- 10 unchanged lines hidden (view full) ---

19 * GNU General Public License for more details.
20 */
21
22#include "cx88.h"
23#include "cx88-reg.h"
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/delay.h>
27#include <linux/device.h>
28#include <linux/interrupt.h>
29#include <linux/vmalloc.h>
30#include <linux/dma-mapping.h>
31#include <linux/pci.h>
32#include <linux/slab.h>
33
28#include <linux/device.h>
29#include <linux/interrupt.h>
30#include <linux/vmalloc.h>
31#include <linux/dma-mapping.h>
32#include <linux/pci.h>
33#include <linux/slab.h>
34
34#include <asm/delay.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/control.h>
39#include <sound/initval.h>
40#include <sound/tlv.h>
41#include <media/i2c/wm8775.h>
42
43#define dprintk(level, fmt, arg...) do { \
44 if (debug + 1 > level) \
45 printk(KERN_DEBUG pr_fmt("%s: alsa: " fmt), \
46 chip->core->name, ##arg); \
47} while (0)
48
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/control.h>
39#include <sound/initval.h>
40#include <sound/tlv.h>
41#include <media/i2c/wm8775.h>
42
43#define dprintk(level, fmt, arg...) do { \
44 if (debug + 1 > level) \
45 printk(KERN_DEBUG pr_fmt("%s: alsa: " fmt), \
46 chip->core->name, ##arg); \
47} while (0)
48
49/****************************************************************************
50 Data type declarations - Can be moded to a header file later
51 ****************************************************************************/
49/*
50 * Data type declarations - Can be moded to a header file later
51 */
52
53struct cx88_audio_buffer {
54 unsigned int bpl;
55 struct cx88_riscmem risc;
56 void *vaddr;
57 struct scatterlist *sglist;
58 int sglen;
59 int nr_pages;

--- 17 unchanged lines hidden (view full) ---

77 unsigned int dma_size;
78 unsigned int period_size;
79 unsigned int num_periods;
80
81 struct cx88_audio_buffer *buf;
82
83 struct snd_pcm_substream *substream;
84};
52
53struct cx88_audio_buffer {
54 unsigned int bpl;
55 struct cx88_riscmem risc;
56 void *vaddr;
57 struct scatterlist *sglist;
58 int sglen;
59 int nr_pages;

--- 17 unchanged lines hidden (view full) ---

77 unsigned int dma_size;
78 unsigned int period_size;
79 unsigned int num_periods;
80
81 struct cx88_audio_buffer *buf;
82
83 struct snd_pcm_substream *substream;
84};
85typedef struct cx88_audio_dev snd_cx88_card_t;
86
85
86/*
87 * Module global static vars
88 */
87
89
88
89/****************************************************************************
90 Module global static vars
91 ****************************************************************************/
92
93static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
94static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
95static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
96
97module_param_array(enable, bool, NULL, 0444);
98MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
99
100module_param_array(index, int, NULL, 0444);
101MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
102
90static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
91static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
92static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
93
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
96
97module_param_array(index, int, NULL, 0444);
98MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
99
100/*
101 * Module macros
102 */
103
103
104/****************************************************************************
105 Module macros
106 ****************************************************************************/
107
108MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
109MODULE_AUTHOR("Ricardo Cerqueira");
110MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
111MODULE_LICENSE("GPL");
112MODULE_VERSION(CX88_VERSION);
113
114MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}");
115static unsigned int debug;
116module_param(debug, int, 0644);
117MODULE_PARM_DESC(debug, "enable debug messages");
118
104MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
105MODULE_AUTHOR("Ricardo Cerqueira");
106MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
107MODULE_LICENSE("GPL");
108MODULE_VERSION(CX88_VERSION);
109
110MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}");
111static unsigned int debug;
112module_param(debug, int, 0644);
113MODULE_PARM_DESC(debug, "enable debug messages");
114
119/****************************************************************************
120 Module specific funtions
121 ****************************************************************************/
115/*
116 * Module specific functions
117 */
122
123/*
124 * BOARD Specific: Sets audio DMA
125 */
126
118
119/*
120 * BOARD Specific: Sets audio DMA
121 */
122
127static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
123static int _cx88_start_audio_dma(struct cx88_audio_dev *chip)
128{
129 struct cx88_audio_buffer *buf = chip->buf;
130 struct cx88_core *core = chip->core;
131 const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
132
133 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
134 cx_clear(MO_AUD_DMACNTRL, 0x11);
135
136 /* setup fifo + format - out channel */
137 cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma);
138
139 /* sets bpl size */
140 cx_write(MO_AUDD_LNGTH, buf->bpl);
141
142 /* reset counter */
143 cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
144 atomic_set(&chip->count, 0);
145
124{
125 struct cx88_audio_buffer *buf = chip->buf;
126 struct cx88_core *core = chip->core;
127 const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
128
129 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
130 cx_clear(MO_AUD_DMACNTRL, 0x11);
131
132 /* setup fifo + format - out channel */
133 cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma);
134
135 /* sets bpl size */
136 cx_write(MO_AUDD_LNGTH, buf->bpl);
137
138 /* reset counter */
139 cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
140 atomic_set(&chip->count, 0);
141
146 dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n",
147 buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1,
142 dprintk(1,
143 "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n",
144 buf->bpl, cx_read(audio_ch->cmds_start + 8) >> 1,
148 chip->num_periods, buf->bpl * chip->num_periods);
149
150 /* Enables corresponding bits at AUD_INT_STAT */
151 cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
152 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
153
154 /* Clean any pending interrupt bits already set */
155 cx_write(MO_AUD_INTSTAT, ~0);
156
157 /* enable audio irqs */
158 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
159
160 /* start dma */
145 chip->num_periods, buf->bpl * chip->num_periods);
146
147 /* Enables corresponding bits at AUD_INT_STAT */
148 cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
149 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
150
151 /* Clean any pending interrupt bits already set */
152 cx_write(MO_AUD_INTSTAT, ~0);
153
154 /* enable audio irqs */
155 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
156
157 /* start dma */
161 cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
162 cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
163
158
159 /* Enables Risc Processor */
160 cx_set(MO_DEV_CNTRL2, (1 << 5));
161 /* audio downstream FIFO and RISC enable */
162 cx_set(MO_AUD_DMACNTRL, 0x11);
163
164 if (debug)
165 cx88_sram_channel_dump(chip->core, audio_ch);
166
167 return 0;
168}
169
170/*
171 * BOARD Specific: Resets audio DMA
172 */
164 if (debug)
165 cx88_sram_channel_dump(chip->core, audio_ch);
166
167 return 0;
168}
169
170/*
171 * BOARD Specific: Resets audio DMA
172 */
173static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
173static int _cx88_stop_audio_dma(struct cx88_audio_dev *chip)
174{
175 struct cx88_core *core = chip->core;
176
177 dprintk(1, "Stopping audio DMA\n");
178
179 /* stop dma */
180 cx_clear(MO_AUD_DMACNTRL, 0x11);
181
182 /* disable irqs */
183 cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
184 cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
185 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
186
187 if (debug)
174{
175 struct cx88_core *core = chip->core;
176
177 dprintk(1, "Stopping audio DMA\n");
178
179 /* stop dma */
180 cx_clear(MO_AUD_DMACNTRL, 0x11);
181
182 /* disable irqs */
183 cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
184 cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
185 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
186
187 if (debug)
188 cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
188 cx88_sram_channel_dump(chip->core,
189 &cx88_sram_channels[SRAM_CH25]);
189
190 return 0;
191}
192
193#define MAX_IRQ_LOOP 50
194
195/*
196 * BOARD Specific: IRQ dma bits

--- 9 unchanged lines hidden (view full) ---

206 NULL, /* reserved */
207 "opc_err", "par_err", "rip_err", /* 16-18 */
208 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
209};
210
211/*
212 * BOARD Specific: Threats IRQ audio specific calls
213 */
190
191 return 0;
192}
193
194#define MAX_IRQ_LOOP 50
195
196/*
197 * BOARD Specific: IRQ dma bits

--- 9 unchanged lines hidden (view full) ---

207 NULL, /* reserved */
208 "opc_err", "par_err", "rip_err", /* 16-18 */
209 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
210};
211
212/*
213 * BOARD Specific: Threats IRQ audio specific calls
214 */
214static void cx8801_aud_irq(snd_cx88_card_t *chip)
215static void cx8801_aud_irq(struct cx88_audio_dev *chip)
215{
216 struct cx88_core *core = chip->core;
217 u32 status, mask;
218
219 status = cx_read(MO_AUD_INTSTAT);
220 mask = cx_read(MO_AUD_INTMSK);
221 if (0 == (status & mask))
222 return;

--- 21 unchanged lines hidden (view full) ---

244 /* FIXME: Any other status should deserve a special handling? */
245}
246
247/*
248 * BOARD Specific: Handles IRQ calls
249 */
250static irqreturn_t cx8801_irq(int irq, void *dev_id)
251{
216{
217 struct cx88_core *core = chip->core;
218 u32 status, mask;
219
220 status = cx_read(MO_AUD_INTSTAT);
221 mask = cx_read(MO_AUD_INTMSK);
222 if (0 == (status & mask))
223 return;

--- 21 unchanged lines hidden (view full) ---

245 /* FIXME: Any other status should deserve a special handling? */
246}
247
248/*
249 * BOARD Specific: Handles IRQ calls
250 */
251static irqreturn_t cx8801_irq(int irq, void *dev_id)
252{
252 snd_cx88_card_t *chip = dev_id;
253 struct cx88_audio_dev *chip = dev_id;
253 struct cx88_core *core = chip->core;
254 u32 status;
255 int loop, handled = 0;
256
257 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
258 status = cx_read(MO_PCI_INTSTAT) &
259 (core->pci_irqmask | PCI_INT_AUDINT);
260 if (status == 0)

--- 20 unchanged lines hidden (view full) ---

281
282static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages)
283{
284 struct cx88_audio_buffer *buf = chip->buf;
285 struct page *pg;
286 int i;
287
288 buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
254 struct cx88_core *core = chip->core;
255 u32 status;
256 int loop, handled = 0;
257
258 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
259 status = cx_read(MO_PCI_INTSTAT) &
260 (core->pci_irqmask | PCI_INT_AUDINT);
261 if (status == 0)

--- 20 unchanged lines hidden (view full) ---

282
283static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages)
284{
285 struct cx88_audio_buffer *buf = chip->buf;
286 struct page *pg;
287 int i;
288
289 buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
289 if (buf->vaddr == NULL) {
290 if (!buf->vaddr) {
290 dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
291 return -ENOMEM;
292 }
293
294 dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
291 dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
292 return -ENOMEM;
293 }
294
295 dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
295 (unsigned long)buf->vaddr,
296 nr_pages << PAGE_SHIFT);
296 (unsigned long)buf->vaddr, nr_pages << PAGE_SHIFT);
297
298 memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
299 buf->nr_pages = nr_pages;
300
301 buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
297
298 memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
299 buf->nr_pages = nr_pages;
300
301 buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
302 if (buf->sglist == NULL)
302 if (!buf->sglist)
303 goto vzalloc_err;
304
305 sg_init_table(buf->sglist, buf->nr_pages);
306 for (i = 0; i < buf->nr_pages; i++) {
307 pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
303 goto vzalloc_err;
304
305 sg_init_table(buf->sglist, buf->nr_pages);
306 for (i = 0; i < buf->nr_pages; i++) {
307 pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
308 if (pg == NULL)
308 if (!pg)
309 goto vmalloc_to_page_err;
310 sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
311 }
312 return 0;
313
314vmalloc_to_page_err:
315 vfree(buf->sglist);
316 buf->sglist = NULL;

--- 19 unchanged lines hidden (view full) ---

336
337static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev)
338{
339 struct cx88_audio_buffer *buf = dev->buf;
340
341 if (!buf->sglen)
342 return 0;
343
309 goto vmalloc_to_page_err;
310 sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
311 }
312 return 0;
313
314vmalloc_to_page_err:
315 vfree(buf->sglist);
316 buf->sglist = NULL;

--- 19 unchanged lines hidden (view full) ---

336
337static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev)
338{
339 struct cx88_audio_buffer *buf = dev->buf;
340
341 if (!buf->sglen)
342 return 0;
343
344 dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE);
344 dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen,
345 PCI_DMA_FROMDEVICE);
345 buf->sglen = 0;
346 return 0;
347}
348
349static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf)
350{
351 vfree(buf->sglist);
352 buf->sglist = NULL;
353 vfree(buf->vaddr);
354 buf->vaddr = NULL;
355 return 0;
356}
357
346 buf->sglen = 0;
347 return 0;
348}
349
350static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf)
351{
352 vfree(buf->sglist);
353 buf->sglist = NULL;
354 vfree(buf->vaddr);
355 buf->vaddr = NULL;
356 return 0;
357}
358
358
359static int dsp_buffer_free(snd_cx88_card_t *chip)
359static int dsp_buffer_free(struct cx88_audio_dev *chip)
360{
361 struct cx88_riscmem *risc = &chip->buf->risc;
362
360{
361 struct cx88_riscmem *risc = &chip->buf->risc;
362
363 BUG_ON(!chip->dma_size);
363 WARN_ON(!chip->dma_size);
364
365 dprintk(2, "Freeing buffer\n");
366 cx88_alsa_dma_unmap(chip);
367 cx88_alsa_dma_free(chip->buf);
368 if (risc->cpu)
364
365 dprintk(2, "Freeing buffer\n");
366 cx88_alsa_dma_unmap(chip);
367 cx88_alsa_dma_free(chip->buf);
368 if (risc->cpu)
369 pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma);
369 pci_free_consistent(chip->pci, risc->size,
370 risc->cpu, risc->dma);
370 kfree(chip->buf);
371
372 chip->buf = NULL;
373
374 return 0;
375}
376
371 kfree(chip->buf);
372
373 chip->buf = NULL;
374
375 return 0;
376}
377
377/****************************************************************************
378 ALSA PCM Interface
379 ****************************************************************************/
378/*
379 * ALSA PCM Interface
380 */
380
381/*
382 * Digital hardware definition
383 */
384#define DEFAULT_FIFO_SIZE 4096
385static const struct snd_pcm_hardware snd_cx88_digital_hw = {
386 .info = SNDRV_PCM_INFO_MMAP |
387 SNDRV_PCM_INFO_INTERLEAVED |
388 SNDRV_PCM_INFO_BLOCK_TRANSFER |
389 SNDRV_PCM_INFO_MMAP_VALID,
390 .formats = SNDRV_PCM_FMTBIT_S16_LE,
391
392 .rates = SNDRV_PCM_RATE_48000,
393 .rate_min = 48000,
394 .rate_max = 48000,
395 .channels_min = 2,
396 .channels_max = 2,
381
382/*
383 * Digital hardware definition
384 */
385#define DEFAULT_FIFO_SIZE 4096
386static const struct snd_pcm_hardware snd_cx88_digital_hw = {
387 .info = SNDRV_PCM_INFO_MMAP |
388 SNDRV_PCM_INFO_INTERLEAVED |
389 SNDRV_PCM_INFO_BLOCK_TRANSFER |
390 SNDRV_PCM_INFO_MMAP_VALID,
391 .formats = SNDRV_PCM_FMTBIT_S16_LE,
392
393 .rates = SNDRV_PCM_RATE_48000,
394 .rate_min = 48000,
395 .rate_max = 48000,
396 .channels_min = 2,
397 .channels_max = 2,
397 /* Analog audio output will be full of clicks and pops if there
398 are not exactly four lines in the SRAM FIFO buffer. */
399 .period_bytes_min = DEFAULT_FIFO_SIZE/4,
400 .period_bytes_max = DEFAULT_FIFO_SIZE/4,
398 /*
399 * Analog audio output will be full of clicks and pops if there
400 * are not exactly four lines in the SRAM FIFO buffer.
401 */
402 .period_bytes_min = DEFAULT_FIFO_SIZE / 4,
403 .period_bytes_max = DEFAULT_FIFO_SIZE / 4,
401 .periods_min = 1,
402 .periods_max = 1024,
404 .periods_min = 1,
405 .periods_max = 1024,
403 .buffer_bytes_max = (1024*1024),
406 .buffer_bytes_max = (1024 * 1024),
404};
405
406/*
407 * audio pcm capture open callback
408 */
409static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
410{
407};
408
409/*
410 * audio pcm capture open callback
411 */
412static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
413{
411 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
414 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream);
412 struct snd_pcm_runtime *runtime = substream->runtime;
413 int err;
414
415 if (!chip) {
416 pr_err("BUG: cx88 can't find device struct. Can't proceed with open\n");
417 return -ENODEV;
418 }
419
415 struct snd_pcm_runtime *runtime = substream->runtime;
416 int err;
417
418 if (!chip) {
419 pr_err("BUG: cx88 can't find device struct. Can't proceed with open\n");
420 return -ENODEV;
421 }
422
420 err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
423 err = snd_pcm_hw_constraint_pow2(runtime, 0,
424 SNDRV_PCM_HW_PARAM_PERIODS);
421 if (err < 0)
422 goto _error;
423
424 chip->substream = substream;
425
426 runtime->hw = snd_cx88_digital_hw;
427
428 if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) {

--- 19 unchanged lines hidden (view full) ---

448}
449
450/*
451 * hw_params callback
452 */
453static int snd_cx88_hw_params(struct snd_pcm_substream *substream,
454 struct snd_pcm_hw_params *hw_params)
455{
425 if (err < 0)
426 goto _error;
427
428 chip->substream = substream;
429
430 runtime->hw = snd_cx88_digital_hw;
431
432 if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) {

--- 19 unchanged lines hidden (view full) ---

452}
453
454/*
455 * hw_params callback
456 */
457static int snd_cx88_hw_params(struct snd_pcm_substream *substream,
458 struct snd_pcm_hw_params *hw_params)
459{
456 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
460 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream);
457
458 struct cx88_audio_buffer *buf;
459 int ret;
460
461 if (substream->runtime->dma_area) {
462 dsp_buffer_free(chip);
463 substream->runtime->dma_area = NULL;
464 }
465
466 chip->period_size = params_period_bytes(hw_params);
467 chip->num_periods = params_periods(hw_params);
468 chip->dma_size = chip->period_size * params_periods(hw_params);
469
461
462 struct cx88_audio_buffer *buf;
463 int ret;
464
465 if (substream->runtime->dma_area) {
466 dsp_buffer_free(chip);
467 substream->runtime->dma_area = NULL;
468 }
469
470 chip->period_size = params_period_bytes(hw_params);
471 chip->num_periods = params_periods(hw_params);
472 chip->dma_size = chip->period_size * params_periods(hw_params);
473
470 BUG_ON(!chip->dma_size);
471 BUG_ON(chip->num_periods & (chip->num_periods-1));
474 WARN_ON(!chip->dma_size);
475 WARN_ON(chip->num_periods & (chip->num_periods - 1));
472
473 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
476
477 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
474 if (buf == NULL)
478 if (!buf)
475 return -ENOMEM;
476
477 chip->buf = buf;
478 buf->bpl = chip->period_size;
479
480 ret = cx88_alsa_dma_init(chip,
479 return -ENOMEM;
480
481 chip->buf = buf;
482 buf->bpl = chip->period_size;
483
484 ret = cx88_alsa_dma_init(chip,
481 (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
485 (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
482 if (ret < 0)
483 goto error;
484
485 ret = cx88_alsa_dma_map(chip);
486 if (ret < 0)
487 goto error;
488
489 ret = cx88_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
490 chip->period_size, chip->num_periods, 1);
491 if (ret < 0)
492 goto error;
493
494 /* Loop back to start of program */
486 if (ret < 0)
487 goto error;
488
489 ret = cx88_alsa_dma_map(chip);
490 if (ret < 0)
491 goto error;
492
493 ret = cx88_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
494 chip->period_size, chip->num_periods, 1);
495 if (ret < 0)
496 goto error;
497
498 /* Loop back to start of program */
495 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
499 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
496 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
497
498 substream->runtime->dma_area = chip->buf->vaddr;
499 substream->runtime->dma_bytes = chip->dma_size;
500 substream->runtime->dma_addr = 0;
501 return 0;
502
503error:
504 kfree(buf);
505 return ret;
506}
507
508/*
509 * hw free callback
510 */
511static int snd_cx88_hw_free(struct snd_pcm_substream *substream)
512{
500 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
501
502 substream->runtime->dma_area = chip->buf->vaddr;
503 substream->runtime->dma_bytes = chip->dma_size;
504 substream->runtime->dma_addr = 0;
505 return 0;
506
507error:
508 kfree(buf);
509 return ret;
510}
511
512/*
513 * hw free callback
514 */
515static int snd_cx88_hw_free(struct snd_pcm_substream *substream)
516{
517 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream);
513
518
514 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
515
516 if (substream->runtime->dma_area) {
517 dsp_buffer_free(chip);
518 substream->runtime->dma_area = NULL;
519 }
520
521 return 0;
522}
523

--- 5 unchanged lines hidden (view full) ---

529 return 0;
530}
531
532/*
533 * trigger callback
534 */
535static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
536{
519 if (substream->runtime->dma_area) {
520 dsp_buffer_free(chip);
521 substream->runtime->dma_area = NULL;
522 }
523
524 return 0;
525}
526

--- 5 unchanged lines hidden (view full) ---

532 return 0;
533}
534
535/*
536 * trigger callback
537 */
538static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
539{
537 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
540 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream);
538 int err;
539
540 /* Local interrupts are already disabled by ALSA */
541 spin_lock(&chip->reg_lock);
542
543 switch (cmd) {
544 case SNDRV_PCM_TRIGGER_START:
545 err = _cx88_start_audio_dma(chip);

--- 11 unchanged lines hidden (view full) ---

557 return err;
558}
559
560/*
561 * pointer callback
562 */
563static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
564{
541 int err;
542
543 /* Local interrupts are already disabled by ALSA */
544 spin_lock(&chip->reg_lock);
545
546 switch (cmd) {
547 case SNDRV_PCM_TRIGGER_START:
548 err = _cx88_start_audio_dma(chip);

--- 11 unchanged lines hidden (view full) ---

560 return err;
561}
562
563/*
564 * pointer callback
565 */
566static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
567{
565 snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
568 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream);
566 struct snd_pcm_runtime *runtime = substream->runtime;
567 u16 count;
568
569 count = atomic_read(&chip->count);
570
571// dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__,
572// count, new, count & (runtime->periods-1),
573// runtime->period_size * (count & (runtime->periods-1)));
569 struct snd_pcm_runtime *runtime = substream->runtime;
570 u16 count;
571
572 count = atomic_read(&chip->count);
573
574// dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__,
575// count, new, count & (runtime->periods-1),
576// runtime->period_size * (count & (runtime->periods-1)));
574 return runtime->period_size * (count & (runtime->periods-1));
577 return runtime->period_size * (count & (runtime->periods - 1));
575}
576
577/*
578 * page callback (needed for mmap)
579 */
580static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
578}
579
580/*
581 * page callback (needed for mmap)
582 */
583static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
581 unsigned long offset)
584 unsigned long offset)
582{
583 void *pageptr = substream->runtime->dma_area + offset;
584
585 return vmalloc_to_page(pageptr);
586}
587
588/*
589 * operators

--- 8 unchanged lines hidden (view full) ---

598 .trigger = snd_cx88_card_trigger,
599 .pointer = snd_cx88_pointer,
600 .page = snd_cx88_page,
601};
602
603/*
604 * create a PCM device
605 */
585{
586 void *pageptr = substream->runtime->dma_area + offset;
587
588 return vmalloc_to_page(pageptr);
589}
590
591/*
592 * operators

--- 8 unchanged lines hidden (view full) ---

601 .trigger = snd_cx88_card_trigger,
602 .pointer = snd_cx88_pointer,
603 .page = snd_cx88_page,
604};
605
606/*
607 * create a PCM device
608 */
606static int snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name)
609static int snd_cx88_pcm(struct cx88_audio_dev *chip, int device,
610 const char *name)
607{
608 int err;
609 struct snd_pcm *pcm;
610
611 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
612 if (err < 0)
613 return err;
614 pcm->private_data = chip;
615 strcpy(pcm->name, name);
616 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
617
618 return 0;
619}
620
611{
612 int err;
613 struct snd_pcm *pcm;
614
615 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
616 if (err < 0)
617 return err;
618 pcm->private_data = chip;
619 strcpy(pcm->name, name);
620 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
621
622 return 0;
623}
624
621/****************************************************************************
622 CONTROL INTERFACE
623 ****************************************************************************/
625/*
626 * CONTROL INTERFACE
627 */
624static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *info)
626{
627 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
628 info->count = 2;
629 info->value.integer.min = 0;
630 info->value.integer.max = 0x3f;
631
632 return 0;
633}
634
635static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *value)
637{
628static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_info *info)
630{
631 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
632 info->count = 2;
633 info->value.integer.min = 0;
634 info->value.integer.max = 0x3f;
635
636 return 0;
637}
638
639static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *value)
641{
638 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
642 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
639 struct cx88_core *core = chip->core;
640 int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f),
641 bal = cx_read(AUD_BAL_CTL);
642
643 value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
644 vol -= (bal & 0x3f);
645 value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
646
647 return 0;
648}
649
650static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
643 struct cx88_core *core = chip->core;
644 int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f),
645 bal = cx_read(AUD_BAL_CTL);
646
647 value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
648 vol -= (bal & 0x3f);
649 value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
650
651 return 0;
652}
653
654static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_value *value)
655 struct snd_ctl_elem_value *value)
652{
656{
653 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
657 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
654 struct cx88_core *core = chip->core;
655 int left = value->value.integer.value[0];
656 int right = value->value.integer.value[1];
657 int v, b;
658
659 /* Pass volume & balance onto any WM8775 */
660 if (left >= right) {
661 v = left << 10;

--- 5 unchanged lines hidden (view full) ---

667 wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v);
668 wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b);
669}
670
671/* OK - TODO: test it */
672static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *value)
674{
658 struct cx88_core *core = chip->core;
659 int left = value->value.integer.value[0];
660 int right = value->value.integer.value[1];
661 int v, b;
662
663 /* Pass volume & balance onto any WM8775 */
664 if (left >= right) {
665 v = left << 10;

--- 5 unchanged lines hidden (view full) ---

671 wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v);
672 wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b);
673}
674
675/* OK - TODO: test it */
676static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *value)
678{
675 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
679 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
676 struct cx88_core *core = chip->core;
677 int left, right, v, b;
678 int changed = 0;
679 u32 old;
680
681 if (core->sd_wm8775)
682 snd_cx88_wm8775_volume_put(kcontrol, value);
683

--- 33 unchanged lines hidden (view full) ---

717 .get = snd_cx88_volume_get,
718 .put = snd_cx88_volume_put,
719 .tlv.p = snd_cx88_db_scale,
720};
721
722static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
723 struct snd_ctl_elem_value *value)
724{
680 struct cx88_core *core = chip->core;
681 int left, right, v, b;
682 int changed = 0;
683 u32 old;
684
685 if (core->sd_wm8775)
686 snd_cx88_wm8775_volume_put(kcontrol, value);
687

--- 33 unchanged lines hidden (view full) ---

721 .get = snd_cx88_volume_get,
722 .put = snd_cx88_volume_put,
723 .tlv.p = snd_cx88_db_scale,
724};
725
726static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *value)
728{
725 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
729 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
726 struct cx88_core *core = chip->core;
727 u32 bit = kcontrol->private_value;
728
729 value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
730 return 0;
731}
732
733static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
730 struct cx88_core *core = chip->core;
731 u32 bit = kcontrol->private_value;
732
733 value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
734 return 0;
735}
736
737static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *value)
738 struct snd_ctl_elem_value *value)
735{
739{
736 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
740 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
737 struct cx88_core *core = chip->core;
738 u32 bit = kcontrol->private_value;
739 int ret = 0;
740 u32 vol;
741
742 spin_lock_irq(&chip->reg_lock);
743 vol = cx_read(AUD_VOL_CTL);
744 if (value->value.integer.value[0] != !(vol & bit)) {
745 vol ^= bit;
746 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
747 /* Pass mute onto any WM8775 */
741 struct cx88_core *core = chip->core;
742 u32 bit = kcontrol->private_value;
743 int ret = 0;
744 u32 vol;
745
746 spin_lock_irq(&chip->reg_lock);
747 vol = cx_read(AUD_VOL_CTL);
748 if (value->value.integer.value[0] != !(vol & bit)) {
749 vol ^= bit;
750 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
751 /* Pass mute onto any WM8775 */
748 if (core->sd_wm8775 && ((1<<6) == bit))
749 wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit));
752 if (core->sd_wm8775 && ((1 << 6) == bit))
753 wm8775_s_ctrl(core,
754 V4L2_CID_AUDIO_MUTE, 0 != (vol & bit));
750 ret = 1;
751 }
752 spin_unlock_irq(&chip->reg_lock);
753 return ret;
754}
755
756static const struct snd_kcontrol_new snd_cx88_dac_switch = {
757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
758 .name = "Audio-Out Switch",
759 .info = snd_ctl_boolean_mono_info,
760 .get = snd_cx88_switch_get,
761 .put = snd_cx88_switch_put,
755 ret = 1;
756 }
757 spin_unlock_irq(&chip->reg_lock);
758 return ret;
759}
760
761static const struct snd_kcontrol_new snd_cx88_dac_switch = {
762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
763 .name = "Audio-Out Switch",
764 .info = snd_ctl_boolean_mono_info,
765 .get = snd_cx88_switch_get,
766 .put = snd_cx88_switch_put,
762 .private_value = (1<<8),
767 .private_value = (1 << 8),
763};
764
765static const struct snd_kcontrol_new snd_cx88_source_switch = {
766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
767 .name = "Analog-TV Switch",
768 .info = snd_ctl_boolean_mono_info,
769 .get = snd_cx88_switch_get,
770 .put = snd_cx88_switch_put,
768};
769
770static const struct snd_kcontrol_new snd_cx88_source_switch = {
771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
772 .name = "Analog-TV Switch",
773 .info = snd_ctl_boolean_mono_info,
774 .get = snd_cx88_switch_get,
775 .put = snd_cx88_switch_put,
771 .private_value = (1<<6),
776 .private_value = (1 << 6),
772};
773
774static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
777};
778
779static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *value)
780 struct snd_ctl_elem_value *value)
776{
781{
777 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
782 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
778 struct cx88_core *core = chip->core;
779 s32 val;
780
781 val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS);
782 value->value.integer.value[0] = val ? 1 : 0;
783 return 0;
784}
785
786static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
783 struct cx88_core *core = chip->core;
784 s32 val;
785
786 val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS);
787 value->value.integer.value[0] = val ? 1 : 0;
788 return 0;
789}
790
791static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *value)
792 struct snd_ctl_elem_value *value)
788{
793{
789 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
794 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol);
790 struct cx88_core *core = chip->core;
791
792 wm8775_s_ctrl(core, V4L2_CID_AUDIO_LOUDNESS,
793 value->value.integer.value[0] != 0);
794 return 0;
795}
796
797static struct snd_kcontrol_new snd_cx88_alc_switch = {
798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
799 .name = "Line-In ALC Switch",
800 .info = snd_ctl_boolean_mono_info,
801 .get = snd_cx88_alc_get,
802 .put = snd_cx88_alc_put,
803};
804
795 struct cx88_core *core = chip->core;
796
797 wm8775_s_ctrl(core, V4L2_CID_AUDIO_LOUDNESS,
798 value->value.integer.value[0] != 0);
799 return 0;
800}
801
802static struct snd_kcontrol_new snd_cx88_alc_switch = {
803 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
804 .name = "Line-In ALC Switch",
805 .info = snd_ctl_boolean_mono_info,
806 .get = snd_cx88_alc_get,
807 .put = snd_cx88_alc_put,
808};
809
805/****************************************************************************
806 Basic Flow for Sound Devices
807 ****************************************************************************/
810/*
811 * Basic Flow for Sound Devices
812 */
808
809/*
810 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
811 * Only boards with eeprom and byte 1 at eeprom=1 have it
812 */
813
814static const struct pci_device_id cx88_audio_pci_tbl[] = {
815 {0x14f1, 0x8801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
816 {0x14f1, 0x8811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
817 {0, }
818};
819MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
820
821/*
822 * Chip-specific destructor
823 */
824
813
814/*
815 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
816 * Only boards with eeprom and byte 1 at eeprom=1 have it
817 */
818
819static const struct pci_device_id cx88_audio_pci_tbl[] = {
820 {0x14f1, 0x8801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
821 {0x14f1, 0x8811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
822 {0, }
823};
824MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
825
826/*
827 * Chip-specific destructor
828 */
829
825static int snd_cx88_free(snd_cx88_card_t *chip)
830static int snd_cx88_free(struct cx88_audio_dev *chip)
826{
831{
827
828 if (chip->irq >= 0)
829 free_irq(chip->irq, chip);
830
831 cx88_core_put(chip->core, chip->pci);
832
833 pci_disable_device(chip->pci);
834 return 0;
835}
836
837/*
838 * Component Destructor
839 */
840static void snd_cx88_dev_free(struct snd_card *card)
841{
832 if (chip->irq >= 0)
833 free_irq(chip->irq, chip);
834
835 cx88_core_put(chip->core, chip->pci);
836
837 pci_disable_device(chip->pci);
838 return 0;
839}
840
841/*
842 * Component Destructor
843 */
844static void snd_cx88_dev_free(struct snd_card *card)
845{
842 snd_cx88_card_t *chip = card->private_data;
846 struct cx88_audio_dev *chip = card->private_data;
843
844 snd_cx88_free(chip);
845}
846
847
848 snd_cx88_free(chip);
849}
850
847
848/*
849 * Alsa Constructor - Component probe
850 */
851
852static int devno;
853static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,
851/*
852 * Alsa Constructor - Component probe
853 */
854
855static int devno;
856static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci,
854 snd_cx88_card_t **rchip,
857 struct cx88_audio_dev **rchip,
855 struct cx88_core **core_ptr)
856{
858 struct cx88_core **core_ptr)
859{
857 snd_cx88_card_t *chip;
858 struct cx88_core *core;
859 int err;
860 unsigned char pci_lat;
860 struct cx88_audio_dev *chip;
861 struct cx88_core *core;
862 int err;
863 unsigned char pci_lat;
861
862 *rchip = NULL;
863
864 err = pci_enable_device(pci);
865 if (err < 0)
866 return err;
867
868 pci_set_master(pci);
869
870 chip = card->private_data;
871
872 core = cx88_core_get(pci);
864
865 *rchip = NULL;
866
867 err = pci_enable_device(pci);
868 if (err < 0)
869 return err;
870
871 pci_set_master(pci);
872
873 chip = card->private_data;
874
875 core = cx88_core_get(pci);
873 if (core == NULL) {
876 if (!core) {
874 err = -EINVAL;
875 return err;
876 }
877
878 err = pci_set_dma_mask(pci, DMA_BIT_MASK(32));
879 if (err) {
880 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name);
881 cx88_core_put(core, pci);
882 return err;
883 }
884
877 err = -EINVAL;
878 return err;
879 }
880
881 err = pci_set_dma_mask(pci, DMA_BIT_MASK(32));
882 if (err) {
883 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name);
884 cx88_core_put(core, pci);
885 return err;
886 }
887
885
886 /* pci init */
887 chip->card = card;
888 chip->pci = pci;
889 chip->irq = -1;
890 spin_lock_init(&chip->reg_lock);
891
892 chip->core = core;
893
894 /* get irq */
895 err = request_irq(chip->pci->irq, cx8801_irq,
896 IRQF_SHARED, chip->core->name, chip);
897 if (err < 0) {
898 dprintk(0, "%s: can't get IRQ %d\n",
888 /* pci init */
889 chip->card = card;
890 chip->pci = pci;
891 chip->irq = -1;
892 spin_lock_init(&chip->reg_lock);
893
894 chip->core = core;
895
896 /* get irq */
897 err = request_irq(chip->pci->irq, cx8801_irq,
898 IRQF_SHARED, chip->core->name, chip);
899 if (err < 0) {
900 dprintk(0, "%s: can't get IRQ %d\n",
899 chip->core->name, chip->pci->irq);
901 chip->core->name, chip->pci->irq);
900 return err;
901 }
902
903 /* print pci info */
904 pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat);
905
902 return err;
903 }
904
905 /* print pci info */
906 pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat);
907
906 dprintk(1, "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
908 dprintk(1,
909 "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
907 core->name, devno,
910 core->name, devno,
908 pci_name(pci), pci->revision, pci->irq,
909 pci_lat, (unsigned long long)pci_resource_start(pci, 0));
911 pci_name(pci), pci->revision, pci->irq,
912 pci_lat, (unsigned long long)pci_resource_start(pci, 0));
910
911 chip->irq = pci->irq;
912 synchronize_irq(chip->irq);
913
914 *rchip = chip;
915 *core_ptr = core;
916
917 return 0;
918}
919
920static int cx88_audio_initdev(struct pci_dev *pci,
921 const struct pci_device_id *pci_id)
922{
913
914 chip->irq = pci->irq;
915 synchronize_irq(chip->irq);
916
917 *rchip = chip;
918 *core_ptr = core;
919
920 return 0;
921}
922
923static int cx88_audio_initdev(struct pci_dev *pci,
924 const struct pci_device_id *pci_id)
925{
923 struct snd_card *card;
924 snd_cx88_card_t *chip;
925 struct cx88_core *core = NULL;
926 int err;
926 struct snd_card *card;
927 struct cx88_audio_dev *chip;
928 struct cx88_core *core = NULL;
929 int err;
927
928 if (devno >= SNDRV_CARDS)
929 return (-ENODEV);
930
931 if (!enable[devno]) {
932 ++devno;
933 return (-ENOENT);
934 }
935
936 err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
930
931 if (devno >= SNDRV_CARDS)
932 return (-ENODEV);
933
934 if (!enable[devno]) {
935 ++devno;
936 return (-ENOENT);
937 }
938
939 err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
937 sizeof(snd_cx88_card_t), &card);
940 sizeof(struct cx88_audio_dev), &card);
938 if (err < 0)
939 return err;
940
941 card->private_free = snd_cx88_dev_free;
942
943 err = snd_cx88_create(card, pci, &chip, &core);
944 if (err < 0)
945 goto error;

--- 19 unchanged lines hidden (view full) ---

965 strcpy(card->driver, "CX88x");
966 sprintf(card->shortname, "Conexant CX%x", pci->device);
967 sprintf(card->longname, "%s at %#llx",
968 card->shortname,
969 (unsigned long long)pci_resource_start(pci, 0));
970 strcpy(card->mixername, "CX88");
971
972 dprintk(0, "%s/%i: ALSA support for cx2388x boards\n",
941 if (err < 0)
942 return err;
943
944 card->private_free = snd_cx88_dev_free;
945
946 err = snd_cx88_create(card, pci, &chip, &core);
947 if (err < 0)
948 goto error;

--- 19 unchanged lines hidden (view full) ---

968 strcpy(card->driver, "CX88x");
969 sprintf(card->shortname, "Conexant CX%x", pci->device);
970 sprintf(card->longname, "%s at %#llx",
971 card->shortname,
972 (unsigned long long)pci_resource_start(pci, 0));
973 strcpy(card->mixername, "CX88");
974
975 dprintk(0, "%s/%i: ALSA support for cx2388x boards\n",
973 card->driver, devno);
976 card->driver, devno);
974
975 err = snd_card_register(card);
976 if (err < 0)
977 goto error;
978 pci_set_drvdata(pci, card);
979
980 devno++;
981 return 0;
982
983error:
984 snd_card_free(card);
985 return err;
986}
977
978 err = snd_card_register(card);
979 if (err < 0)
980 goto error;
981 pci_set_drvdata(pci, card);
982
983 devno++;
984 return 0;
985
986error:
987 snd_card_free(card);
988 return err;
989}
990
987/*
988 * ALSA destructor
989 */
990static void cx88_audio_finidev(struct pci_dev *pci)
991{
992 struct snd_card *card = pci_get_drvdata(pci);
993
994 snd_card_free(card);

--- 16 unchanged lines hidden ---
991/*
992 * ALSA destructor
993 */
994static void cx88_audio_finidev(struct pci_dev *pci)
995{
996 struct snd_card *card = pci_get_drvdata(pci);
997
998 snd_card_free(card);

--- 16 unchanged lines hidden ---