Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/pcxhr/pcxhr.c
26450 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Driver for Digigram pcxhr compatible soundcards
4
*
5
* main file with alsa callbacks
6
*
7
* Copyright (c) 2004 by Digigram <[email protected]>
8
*/
9
10
11
#include <linux/init.h>
12
#include <linux/interrupt.h>
13
#include <linux/slab.h>
14
#include <linux/pci.h>
15
#include <linux/dma-mapping.h>
16
#include <linux/delay.h>
17
#include <linux/module.h>
18
#include <linux/mutex.h>
19
20
#include <sound/core.h>
21
#include <sound/initval.h>
22
#include <sound/info.h>
23
#include <sound/control.h>
24
#include <sound/pcm.h>
25
#include <sound/pcm_params.h>
26
#include "pcxhr.h"
27
#include "pcxhr_mixer.h"
28
#include "pcxhr_hwdep.h"
29
#include "pcxhr_core.h"
30
#include "pcxhr_mix22.h"
31
32
#define DRIVER_NAME "pcxhr"
33
34
MODULE_AUTHOR("Markus Bollinger <[email protected]>, "
35
"Marc Titinger <[email protected]>");
36
MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
37
MODULE_LICENSE("GPL");
38
39
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
40
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
41
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
42
static bool mono[SNDRV_CARDS]; /* capture mono only */
43
44
module_param_array(index, int, NULL, 0444);
45
MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
46
module_param_array(id, charp, NULL, 0444);
47
MODULE_PARM_DESC(id, "ID string for Digigram " DRIVER_NAME " soundcard");
48
module_param_array(enable, bool, NULL, 0444);
49
MODULE_PARM_DESC(enable, "Enable Digigram " DRIVER_NAME " soundcard");
50
module_param_array(mono, bool, NULL, 0444);
51
MODULE_PARM_DESC(mono, "Mono capture mode (default is stereo)");
52
53
enum {
54
PCI_ID_VX882HR,
55
PCI_ID_PCX882HR,
56
PCI_ID_VX881HR,
57
PCI_ID_PCX881HR,
58
PCI_ID_VX882E,
59
PCI_ID_PCX882E,
60
PCI_ID_VX881E,
61
PCI_ID_PCX881E,
62
PCI_ID_VX1222HR,
63
PCI_ID_PCX1222HR,
64
PCI_ID_VX1221HR,
65
PCI_ID_PCX1221HR,
66
PCI_ID_VX1222E,
67
PCI_ID_PCX1222E,
68
PCI_ID_VX1221E,
69
PCI_ID_PCX1221E,
70
PCI_ID_VX222HR,
71
PCI_ID_VX222E,
72
PCI_ID_PCX22HR,
73
PCI_ID_PCX22E,
74
PCI_ID_VX222HRMIC,
75
PCI_ID_VX222E_MIC,
76
PCI_ID_PCX924HR,
77
PCI_ID_PCX924E,
78
PCI_ID_PCX924HRMIC,
79
PCI_ID_PCX924E_MIC,
80
PCI_ID_VX442HR,
81
PCI_ID_PCX442HR,
82
PCI_ID_VX442E,
83
PCI_ID_PCX442E,
84
PCI_ID_VX822HR,
85
PCI_ID_PCX822HR,
86
PCI_ID_VX822E,
87
PCI_ID_PCX822E,
88
PCI_ID_LAST
89
};
90
91
static const struct pci_device_id pcxhr_ids[] = {
92
{ 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
93
{ 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
94
{ 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
95
{ 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },
96
{ 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },
97
{ 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },
98
{ 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },
99
{ 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },
100
{ 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },
101
{ 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },
102
{ 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },
103
{ 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },
104
{ 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },
105
{ 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },
106
{ 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },
107
{ 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },
108
{ 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },
109
{ 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },
110
{ 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },
111
{ 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },
112
{ 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },
113
{ 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },
114
{ 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },
115
{ 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
116
{ 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
117
{ 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
118
{ 0x10b5, 0x9656, 0x1369, 0xd001, 0, 0, PCI_ID_VX442HR, },
119
{ 0x10b5, 0x9656, 0x1369, 0xd101, 0, 0, PCI_ID_PCX442HR, },
120
{ 0x10b5, 0x9056, 0x1369, 0xd021, 0, 0, PCI_ID_VX442E, },
121
{ 0x10b5, 0x9056, 0x1369, 0xd121, 0, 0, PCI_ID_PCX442E, },
122
{ 0x10b5, 0x9656, 0x1369, 0xd201, 0, 0, PCI_ID_VX822HR, },
123
{ 0x10b5, 0x9656, 0x1369, 0xd301, 0, 0, PCI_ID_PCX822HR, },
124
{ 0x10b5, 0x9056, 0x1369, 0xd221, 0, 0, PCI_ID_VX822E, },
125
{ 0x10b5, 0x9056, 0x1369, 0xd321, 0, 0, PCI_ID_PCX822E, },
126
{ 0, }
127
};
128
129
MODULE_DEVICE_TABLE(pci, pcxhr_ids);
130
131
struct board_parameters {
132
char* board_name;
133
short playback_chips;
134
short capture_chips;
135
short fw_file_set;
136
short firmware_num;
137
};
138
static const struct board_parameters pcxhr_board_params[] = {
139
[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 0, 41 },
140
[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 0, 41 },
141
[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 0, 41 },
142
[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 0, 41 },
143
[PCI_ID_VX882E] = { "VX882e", 4, 4, 1, 41 },
144
[PCI_ID_PCX882E] = { "PCX882e", 4, 4, 1, 41 },
145
[PCI_ID_VX881E] = { "VX881e", 4, 4, 1, 41 },
146
[PCI_ID_PCX881E] = { "PCX881e", 4, 4, 1, 41 },
147
[PCI_ID_VX1222HR] = { "VX1222HR", 6, 1, 2, 42 },
148
[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 2, 42 },
149
[PCI_ID_VX1221HR] = { "VX1221HR", 6, 1, 2, 42 },
150
[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 2, 42 },
151
[PCI_ID_VX1222E] = { "VX1222e", 6, 1, 3, 42 },
152
[PCI_ID_PCX1222E] = { "PCX1222e", 6, 1, 3, 42 },
153
[PCI_ID_VX1221E] = { "VX1221e", 6, 1, 3, 42 },
154
[PCI_ID_PCX1221E] = { "PCX1221e", 6, 1, 3, 42 },
155
[PCI_ID_VX222HR] = { "VX222HR", 1, 1, 4, 44 },
156
[PCI_ID_VX222E] = { "VX222e", 1, 1, 4, 44 },
157
[PCI_ID_PCX22HR] = { "PCX22HR", 1, 0, 4, 44 },
158
[PCI_ID_PCX22E] = { "PCX22e", 1, 0, 4, 44 },
159
[PCI_ID_VX222HRMIC] = { "VX222HR-Mic", 1, 1, 5, 44 },
160
[PCI_ID_VX222E_MIC] = { "VX222e-Mic", 1, 1, 5, 44 },
161
[PCI_ID_PCX924HR] = { "PCX924HR", 1, 1, 5, 44 },
162
[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
163
[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
164
[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
165
[PCI_ID_VX442HR] = { "VX442HR", 2, 2, 0, 41 },
166
[PCI_ID_PCX442HR] = { "PCX442HR", 2, 2, 0, 41 },
167
[PCI_ID_VX442E] = { "VX442e", 2, 2, 1, 41 },
168
[PCI_ID_PCX442E] = { "PCX442e", 2, 2, 1, 41 },
169
[PCI_ID_VX822HR] = { "VX822HR", 4, 1, 2, 42 },
170
[PCI_ID_PCX822HR] = { "PCX822HR", 4, 1, 2, 42 },
171
[PCI_ID_VX822E] = { "VX822e", 4, 1, 3, 42 },
172
[PCI_ID_PCX822E] = { "PCX822e", 4, 1, 3, 42 },
173
};
174
175
/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
176
/* VX222HR, VX222e, PCX22HR and PCX22e */
177
#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)
178
/* some boards do not support 192kHz on digital AES input plugs */
179
#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \
180
(x->fw_file_set == 0) || \
181
(x->fw_file_set == 2))
182
183
static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
184
unsigned int* realfreq)
185
{
186
unsigned int reg;
187
188
if (freq < 6900 || freq > 110000)
189
return -EINVAL;
190
reg = (28224000 * 2) / freq;
191
reg = (reg - 1) / 2;
192
if (reg < 0x200)
193
*pllreg = reg + 0x800;
194
else if (reg < 0x400)
195
*pllreg = reg & 0x1ff;
196
else if (reg < 0x800) {
197
*pllreg = ((reg >> 1) & 0x1ff) + 0x200;
198
reg &= ~1;
199
} else {
200
*pllreg = ((reg >> 2) & 0x1ff) + 0x400;
201
reg &= ~3;
202
}
203
if (realfreq)
204
*realfreq = (28224000 / (reg + 1));
205
return 0;
206
}
207
208
209
#define PCXHR_FREQ_REG_MASK 0x1f
210
#define PCXHR_FREQ_QUARTZ_48000 0x00
211
#define PCXHR_FREQ_QUARTZ_24000 0x01
212
#define PCXHR_FREQ_QUARTZ_12000 0x09
213
#define PCXHR_FREQ_QUARTZ_32000 0x08
214
#define PCXHR_FREQ_QUARTZ_16000 0x04
215
#define PCXHR_FREQ_QUARTZ_8000 0x0c
216
#define PCXHR_FREQ_QUARTZ_44100 0x02
217
#define PCXHR_FREQ_QUARTZ_22050 0x0a
218
#define PCXHR_FREQ_QUARTZ_11025 0x06
219
#define PCXHR_FREQ_PLL 0x05
220
#define PCXHR_FREQ_QUARTZ_192000 0x10
221
#define PCXHR_FREQ_QUARTZ_96000 0x18
222
#define PCXHR_FREQ_QUARTZ_176400 0x14
223
#define PCXHR_FREQ_QUARTZ_88200 0x1c
224
#define PCXHR_FREQ_QUARTZ_128000 0x12
225
#define PCXHR_FREQ_QUARTZ_64000 0x1a
226
227
#define PCXHR_FREQ_WORD_CLOCK 0x0f
228
#define PCXHR_FREQ_SYNC_AES 0x0e
229
#define PCXHR_FREQ_AES_1 0x07
230
#define PCXHR_FREQ_AES_2 0x0b
231
#define PCXHR_FREQ_AES_3 0x03
232
#define PCXHR_FREQ_AES_4 0x0d
233
234
static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
235
unsigned int *reg, unsigned int *freq)
236
{
237
unsigned int val, realfreq, pllreg;
238
struct pcxhr_rmh rmh;
239
int err;
240
241
realfreq = rate;
242
switch (mgr->use_clock_type) {
243
case PCXHR_CLOCK_TYPE_INTERNAL : /* clock by quartz or pll */
244
switch (rate) {
245
case 48000 : val = PCXHR_FREQ_QUARTZ_48000; break;
246
case 24000 : val = PCXHR_FREQ_QUARTZ_24000; break;
247
case 12000 : val = PCXHR_FREQ_QUARTZ_12000; break;
248
case 32000 : val = PCXHR_FREQ_QUARTZ_32000; break;
249
case 16000 : val = PCXHR_FREQ_QUARTZ_16000; break;
250
case 8000 : val = PCXHR_FREQ_QUARTZ_8000; break;
251
case 44100 : val = PCXHR_FREQ_QUARTZ_44100; break;
252
case 22050 : val = PCXHR_FREQ_QUARTZ_22050; break;
253
case 11025 : val = PCXHR_FREQ_QUARTZ_11025; break;
254
case 192000 : val = PCXHR_FREQ_QUARTZ_192000; break;
255
case 96000 : val = PCXHR_FREQ_QUARTZ_96000; break;
256
case 176400 : val = PCXHR_FREQ_QUARTZ_176400; break;
257
case 88200 : val = PCXHR_FREQ_QUARTZ_88200; break;
258
case 128000 : val = PCXHR_FREQ_QUARTZ_128000; break;
259
case 64000 : val = PCXHR_FREQ_QUARTZ_64000; break;
260
default :
261
val = PCXHR_FREQ_PLL;
262
/* get the value for the pll register */
263
err = pcxhr_pll_freq_register(rate, &pllreg, &realfreq);
264
if (err)
265
return err;
266
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
267
rmh.cmd[0] |= IO_NUM_REG_GENCLK;
268
rmh.cmd[1] = pllreg & MASK_DSP_WORD;
269
rmh.cmd[2] = pllreg >> 24;
270
rmh.cmd_len = 3;
271
err = pcxhr_send_msg(mgr, &rmh);
272
if (err < 0) {
273
dev_err(&mgr->pci->dev,
274
"error CMD_ACCESS_IO_WRITE "
275
"for PLL register : %x!\n", err);
276
return err;
277
}
278
}
279
break;
280
case PCXHR_CLOCK_TYPE_WORD_CLOCK:
281
val = PCXHR_FREQ_WORD_CLOCK;
282
break;
283
case PCXHR_CLOCK_TYPE_AES_SYNC:
284
val = PCXHR_FREQ_SYNC_AES;
285
break;
286
case PCXHR_CLOCK_TYPE_AES_1:
287
val = PCXHR_FREQ_AES_1;
288
break;
289
case PCXHR_CLOCK_TYPE_AES_2:
290
val = PCXHR_FREQ_AES_2;
291
break;
292
case PCXHR_CLOCK_TYPE_AES_3:
293
val = PCXHR_FREQ_AES_3;
294
break;
295
case PCXHR_CLOCK_TYPE_AES_4:
296
val = PCXHR_FREQ_AES_4;
297
break;
298
default:
299
return -EINVAL;
300
}
301
*reg = val;
302
*freq = realfreq;
303
return 0;
304
}
305
306
307
static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,
308
unsigned int rate,
309
int *changed)
310
{
311
unsigned int val, realfreq, speed;
312
struct pcxhr_rmh rmh;
313
int err;
314
315
err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
316
if (err)
317
return err;
318
319
/* codec speed modes */
320
if (rate < 55000)
321
speed = 0; /* single speed */
322
else if (rate < 100000)
323
speed = 1; /* dual speed */
324
else
325
speed = 2; /* quad speed */
326
if (mgr->codec_speed != speed) {
327
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */
328
rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
329
if (DSP_EXT_CMD_SET(mgr)) {
330
rmh.cmd[1] = 1;
331
rmh.cmd_len = 2;
332
}
333
err = pcxhr_send_msg(mgr, &rmh);
334
if (err)
335
return err;
336
337
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */
338
rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
339
rmh.cmd[1] = speed;
340
rmh.cmd_len = 2;
341
err = pcxhr_send_msg(mgr, &rmh);
342
if (err)
343
return err;
344
}
345
/* set the new frequency */
346
dev_dbg(&mgr->pci->dev, "clock register : set %x\n", val);
347
err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,
348
val, changed);
349
if (err)
350
return err;
351
352
mgr->sample_rate_real = realfreq;
353
mgr->cur_clock_type = mgr->use_clock_type;
354
355
/* unmute after codec speed modes */
356
if (mgr->codec_speed != speed) {
357
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */
358
rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
359
if (DSP_EXT_CMD_SET(mgr)) {
360
rmh.cmd[1] = 1;
361
rmh.cmd_len = 2;
362
}
363
err = pcxhr_send_msg(mgr, &rmh);
364
if (err)
365
return err;
366
mgr->codec_speed = speed; /* save new codec speed */
367
}
368
369
dev_dbg(&mgr->pci->dev, "%s to %dHz (realfreq=%d)\n", __func__,
370
rate, realfreq);
371
return 0;
372
}
373
374
#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
375
376
#define PCXHR_IRQ_TIMER_FREQ 92000
377
#define PCXHR_IRQ_TIMER_PERIOD 48
378
379
int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
380
{
381
struct pcxhr_rmh rmh;
382
int err, changed;
383
384
if (rate == 0)
385
return 0; /* nothing to do */
386
387
if (mgr->is_hr_stereo)
388
err = hr222_sub_set_clock(mgr, rate, &changed);
389
else
390
err = pcxhr_sub_set_clock(mgr, rate, &changed);
391
392
if (err)
393
return err;
394
395
if (changed) {
396
pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
397
rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */
398
if (rate < PCXHR_IRQ_TIMER_FREQ)
399
rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
400
else
401
rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD * 2;
402
rmh.cmd[2] = rate;
403
rmh.cmd_len = 3;
404
err = pcxhr_send_msg(mgr, &rmh);
405
if (err)
406
return err;
407
}
408
return 0;
409
}
410
411
412
static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,
413
enum pcxhr_clock_type clock_type,
414
int *sample_rate)
415
{
416
struct pcxhr_rmh rmh;
417
unsigned char reg;
418
int err, rate;
419
420
switch (clock_type) {
421
case PCXHR_CLOCK_TYPE_WORD_CLOCK:
422
reg = REG_STATUS_WORD_CLOCK;
423
break;
424
case PCXHR_CLOCK_TYPE_AES_SYNC:
425
reg = REG_STATUS_AES_SYNC;
426
break;
427
case PCXHR_CLOCK_TYPE_AES_1:
428
reg = REG_STATUS_AES_1;
429
break;
430
case PCXHR_CLOCK_TYPE_AES_2:
431
reg = REG_STATUS_AES_2;
432
break;
433
case PCXHR_CLOCK_TYPE_AES_3:
434
reg = REG_STATUS_AES_3;
435
break;
436
case PCXHR_CLOCK_TYPE_AES_4:
437
reg = REG_STATUS_AES_4;
438
break;
439
default:
440
return -EINVAL;
441
}
442
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
443
rmh.cmd_len = 2;
444
rmh.cmd[0] |= IO_NUM_REG_STATUS;
445
if (mgr->last_reg_stat != reg) {
446
rmh.cmd[1] = reg;
447
err = pcxhr_send_msg(mgr, &rmh);
448
if (err)
449
return err;
450
udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */
451
mgr->last_reg_stat = reg;
452
}
453
rmh.cmd[1] = REG_STATUS_CURRENT;
454
err = pcxhr_send_msg(mgr, &rmh);
455
if (err)
456
return err;
457
switch (rmh.stat[1] & 0x0f) {
458
case REG_STATUS_SYNC_32000 : rate = 32000; break;
459
case REG_STATUS_SYNC_44100 : rate = 44100; break;
460
case REG_STATUS_SYNC_48000 : rate = 48000; break;
461
case REG_STATUS_SYNC_64000 : rate = 64000; break;
462
case REG_STATUS_SYNC_88200 : rate = 88200; break;
463
case REG_STATUS_SYNC_96000 : rate = 96000; break;
464
case REG_STATUS_SYNC_128000 : rate = 128000; break;
465
case REG_STATUS_SYNC_176400 : rate = 176400; break;
466
case REG_STATUS_SYNC_192000 : rate = 192000; break;
467
default: rate = 0;
468
}
469
dev_dbg(&mgr->pci->dev, "External clock is at %d Hz\n", rate);
470
*sample_rate = rate;
471
return 0;
472
}
473
474
475
int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
476
enum pcxhr_clock_type clock_type,
477
int *sample_rate)
478
{
479
if (mgr->is_hr_stereo)
480
return hr222_get_external_clock(mgr, clock_type,
481
sample_rate);
482
else
483
return pcxhr_sub_get_external_clock(mgr, clock_type,
484
sample_rate);
485
}
486
487
/*
488
* start or stop playback/capture substream
489
*/
490
static int pcxhr_set_stream_state(struct snd_pcxhr *chip,
491
struct pcxhr_stream *stream)
492
{
493
int err;
494
struct pcxhr_rmh rmh;
495
int stream_mask, start;
496
497
if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN)
498
start = 1;
499
else {
500
if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
501
dev_err(chip->card->dev,
502
"%s CANNOT be stopped\n", __func__);
503
return -EINVAL;
504
}
505
start = 0;
506
}
507
if (!stream->substream)
508
return -EINVAL;
509
510
stream->timer_abs_periods = 0;
511
stream->timer_period_frag = 0; /* reset theoretical stream pos */
512
stream->timer_buf_periods = 0;
513
stream->timer_is_synced = 0;
514
515
stream_mask =
516
stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
517
518
pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
519
pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
520
stream->pipe->first_audio, 0, stream_mask);
521
522
chip = snd_pcm_substream_chip(stream->substream);
523
524
err = pcxhr_send_msg(chip->mgr, &rmh);
525
if (err)
526
dev_err(chip->card->dev,
527
"ERROR %s err=%x;\n", __func__, err);
528
stream->status =
529
start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
530
return err;
531
}
532
533
#define HEADER_FMT_BASE_LIN 0xfed00000
534
#define HEADER_FMT_BASE_FLOAT 0xfad00000
535
#define HEADER_FMT_INTEL 0x00008000
536
#define HEADER_FMT_24BITS 0x00004000
537
#define HEADER_FMT_16BITS 0x00002000
538
#define HEADER_FMT_UPTO11 0x00000200
539
#define HEADER_FMT_UPTO32 0x00000100
540
#define HEADER_FMT_MONO 0x00000080
541
542
static int pcxhr_set_format(struct pcxhr_stream *stream)
543
{
544
int err, is_capture, sample_rate, stream_num;
545
struct snd_pcxhr *chip;
546
struct pcxhr_rmh rmh;
547
unsigned int header;
548
549
chip = snd_pcm_substream_chip(stream->substream);
550
switch (stream->format) {
551
case SNDRV_PCM_FORMAT_U8:
552
header = HEADER_FMT_BASE_LIN;
553
break;
554
case SNDRV_PCM_FORMAT_S16_LE:
555
header = HEADER_FMT_BASE_LIN |
556
HEADER_FMT_16BITS | HEADER_FMT_INTEL;
557
break;
558
case SNDRV_PCM_FORMAT_S16_BE:
559
header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
560
break;
561
case SNDRV_PCM_FORMAT_S24_3LE:
562
header = HEADER_FMT_BASE_LIN |
563
HEADER_FMT_24BITS | HEADER_FMT_INTEL;
564
break;
565
case SNDRV_PCM_FORMAT_S24_3BE:
566
header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
567
break;
568
case SNDRV_PCM_FORMAT_FLOAT_LE:
569
header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
570
break;
571
default:
572
dev_err(chip->card->dev,
573
"error %s() : unknown format\n", __func__);
574
return -EINVAL;
575
}
576
577
sample_rate = chip->mgr->sample_rate;
578
if (sample_rate <= 32000 && sample_rate !=0) {
579
if (sample_rate <= 11025)
580
header |= HEADER_FMT_UPTO11;
581
else
582
header |= HEADER_FMT_UPTO32;
583
}
584
if (stream->channels == 1)
585
header |= HEADER_FMT_MONO;
586
587
is_capture = stream->pipe->is_capture;
588
stream_num = is_capture ? 0 : stream->substream->number;
589
590
pcxhr_init_rmh(&rmh, is_capture ?
591
CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
592
pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
593
stream_num, 0);
594
if (is_capture) {
595
/* bug with old dsp versions: */
596
/* bit 12 also sets the format of the playback stream */
597
if (DSP_EXT_CMD_SET(chip->mgr))
598
rmh.cmd[0] |= 1<<10;
599
else
600
rmh.cmd[0] |= 1<<12;
601
}
602
rmh.cmd[1] = 0;
603
rmh.cmd_len = 2;
604
if (DSP_EXT_CMD_SET(chip->mgr)) {
605
/* add channels and set bit 19 if channels>2 */
606
rmh.cmd[1] = stream->channels;
607
if (!is_capture) {
608
/* playback : add channel mask to command */
609
rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;
610
rmh.cmd_len = 3;
611
}
612
}
613
rmh.cmd[rmh.cmd_len++] = header >> 8;
614
rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;
615
err = pcxhr_send_msg(chip->mgr, &rmh);
616
if (err)
617
dev_err(chip->card->dev,
618
"ERROR %s err=%x;\n", __func__, err);
619
return err;
620
}
621
622
static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
623
{
624
int err, is_capture, stream_num;
625
struct pcxhr_rmh rmh;
626
struct snd_pcm_substream *subs = stream->substream;
627
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
628
629
is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
630
stream_num = is_capture ? 0 : subs->number;
631
632
dev_dbg(chip->card->dev,
633
"%s(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", __func__,
634
is_capture ? 'c' : 'p',
635
chip->chip_idx, (void *)(long)subs->runtime->dma_addr,
636
subs->runtime->dma_bytes, subs->number);
637
638
pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
639
pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
640
stream_num, 0);
641
642
/* max buffer size is 2 MByte */
643
snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
644
/* size in bits */
645
rmh.cmd[1] = subs->runtime->dma_bytes * 8;
646
/* most significant byte */
647
rmh.cmd[2] = subs->runtime->dma_addr >> 24;
648
/* this is a circular buffer */
649
rmh.cmd[2] |= 1<<19;
650
/* least 3 significant bytes */
651
rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;
652
rmh.cmd_len = 4;
653
err = pcxhr_send_msg(chip->mgr, &rmh);
654
if (err)
655
dev_err(chip->card->dev,
656
"ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
657
return err;
658
}
659
660
661
#if 0
662
static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,
663
snd_pcm_uframes_t *sample_count)
664
{
665
struct pcxhr_rmh rmh;
666
int err;
667
pcxhr_t *chip = snd_pcm_substream_chip(stream->substream);
668
pcxhr_init_rmh(&rmh, CMD_PIPE_SAMPLE_COUNT);
669
pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 0, 0,
670
1<<stream->pipe->first_audio);
671
err = pcxhr_send_msg(chip->mgr, &rmh);
672
if (err == 0) {
673
*sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24;
674
*sample_count += (snd_pcm_uframes_t)rmh.stat[1];
675
}
676
dev_dbg(chip->card->dev, "PIPE_SAMPLE_COUNT = %lx\n", *sample_count);
677
return err;
678
}
679
#endif
680
681
static inline int pcxhr_stream_scheduled_get_pipe(struct pcxhr_stream *stream,
682
struct pcxhr_pipe **pipe)
683
{
684
if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN) {
685
*pipe = stream->pipe;
686
return 1;
687
}
688
return 0;
689
}
690
691
static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr)
692
{
693
int i, j, err;
694
struct pcxhr_pipe *pipe;
695
struct snd_pcxhr *chip;
696
int capture_mask = 0;
697
int playback_mask = 0;
698
699
#ifdef CONFIG_SND_DEBUG_VERBOSE
700
ktime_t start_time, stop_time, diff_time;
701
702
start_time = ktime_get();
703
#endif
704
mutex_lock(&mgr->setup_mutex);
705
706
/* check the pipes concerned and build pipe_array */
707
for (i = 0; i < mgr->num_cards; i++) {
708
chip = mgr->chip[i];
709
for (j = 0; j < chip->nb_streams_capt; j++) {
710
if (pcxhr_stream_scheduled_get_pipe(&chip->capture_stream[j], &pipe))
711
capture_mask |= (1 << pipe->first_audio);
712
}
713
for (j = 0; j < chip->nb_streams_play; j++) {
714
if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
715
playback_mask |= (1 << pipe->first_audio);
716
break; /* add only once, as all playback
717
* streams of one chip use the same pipe
718
*/
719
}
720
}
721
}
722
if (capture_mask == 0 && playback_mask == 0) {
723
mutex_unlock(&mgr->setup_mutex);
724
dev_err(&mgr->pci->dev, "%s : no pipes\n", __func__);
725
return;
726
}
727
728
dev_dbg(&mgr->pci->dev, "%s : playback_mask=%x capture_mask=%x\n",
729
__func__, playback_mask, capture_mask);
730
731
/* synchronous stop of all the pipes concerned */
732
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
733
if (err) {
734
mutex_unlock(&mgr->setup_mutex);
735
dev_err(&mgr->pci->dev, "%s : "
736
"error stop pipes (P%x C%x)\n",
737
__func__, playback_mask, capture_mask);
738
return;
739
}
740
741
/* the dsp lost format and buffer info with the stop pipe */
742
for (i = 0; i < mgr->num_cards; i++) {
743
struct pcxhr_stream *stream;
744
chip = mgr->chip[i];
745
for (j = 0; j < chip->nb_streams_capt; j++) {
746
stream = &chip->capture_stream[j];
747
if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
748
err = pcxhr_set_format(stream);
749
err = pcxhr_update_r_buffer(stream);
750
}
751
}
752
for (j = 0; j < chip->nb_streams_play; j++) {
753
stream = &chip->playback_stream[j];
754
if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
755
err = pcxhr_set_format(stream);
756
err = pcxhr_update_r_buffer(stream);
757
}
758
}
759
}
760
/* start all the streams */
761
for (i = 0; i < mgr->num_cards; i++) {
762
struct pcxhr_stream *stream;
763
chip = mgr->chip[i];
764
for (j = 0; j < chip->nb_streams_capt; j++) {
765
stream = &chip->capture_stream[j];
766
if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
767
err = pcxhr_set_stream_state(chip, stream);
768
}
769
for (j = 0; j < chip->nb_streams_play; j++) {
770
stream = &chip->playback_stream[j];
771
if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
772
err = pcxhr_set_stream_state(chip, stream);
773
}
774
}
775
776
/* synchronous start of all the pipes concerned */
777
err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
778
if (err) {
779
mutex_unlock(&mgr->setup_mutex);
780
dev_err(&mgr->pci->dev, "%s : "
781
"error start pipes (P%x C%x)\n",
782
__func__, playback_mask, capture_mask);
783
return;
784
}
785
786
/* put the streams into the running state now
787
* (increment pointer by interrupt)
788
*/
789
mutex_lock(&mgr->lock);
790
for ( i =0; i < mgr->num_cards; i++) {
791
struct pcxhr_stream *stream;
792
chip = mgr->chip[i];
793
for(j = 0; j < chip->nb_streams_capt; j++) {
794
stream = &chip->capture_stream[j];
795
if(stream->status == PCXHR_STREAM_STATUS_STARTED)
796
stream->status = PCXHR_STREAM_STATUS_RUNNING;
797
}
798
for (j = 0; j < chip->nb_streams_play; j++) {
799
stream = &chip->playback_stream[j];
800
if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
801
/* playback will already have advanced ! */
802
stream->timer_period_frag += mgr->granularity;
803
stream->status = PCXHR_STREAM_STATUS_RUNNING;
804
}
805
}
806
}
807
mutex_unlock(&mgr->lock);
808
809
mutex_unlock(&mgr->setup_mutex);
810
811
#ifdef CONFIG_SND_DEBUG_VERBOSE
812
stop_time = ktime_get();
813
diff_time = ktime_sub(stop_time, start_time);
814
dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n",
815
(long)(ktime_to_ns(diff_time)), err);
816
#endif
817
}
818
819
820
/*
821
* trigger callback
822
*/
823
static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
824
{
825
struct pcxhr_stream *stream;
826
struct snd_pcm_substream *s;
827
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
828
829
switch (cmd) {
830
case SNDRV_PCM_TRIGGER_START:
831
dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_START\n");
832
if (snd_pcm_stream_linked(subs)) {
833
snd_pcm_group_for_each_entry(s, subs) {
834
if (snd_pcm_substream_chip(s) != chip)
835
continue;
836
stream = s->runtime->private_data;
837
stream->status =
838
PCXHR_STREAM_STATUS_SCHEDULE_RUN;
839
snd_pcm_trigger_done(s, subs);
840
}
841
pcxhr_start_linked_stream(chip->mgr);
842
} else {
843
stream = subs->runtime->private_data;
844
dev_dbg(chip->card->dev, "Only one Substream %c %d\n",
845
stream->pipe->is_capture ? 'C' : 'P',
846
stream->pipe->first_audio);
847
if (pcxhr_set_format(stream))
848
return -EINVAL;
849
if (pcxhr_update_r_buffer(stream))
850
return -EINVAL;
851
852
stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
853
if (pcxhr_set_stream_state(chip, stream))
854
return -EINVAL;
855
stream->status = PCXHR_STREAM_STATUS_RUNNING;
856
}
857
break;
858
case SNDRV_PCM_TRIGGER_STOP:
859
dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_STOP\n");
860
snd_pcm_group_for_each_entry(s, subs) {
861
stream = s->runtime->private_data;
862
stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;
863
if (pcxhr_set_stream_state(chip, stream))
864
return -EINVAL;
865
snd_pcm_trigger_done(s, subs);
866
}
867
break;
868
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
869
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
870
/* TODO */
871
default:
872
return -EINVAL;
873
}
874
return 0;
875
}
876
877
878
static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
879
{
880
struct pcxhr_rmh rmh;
881
int err;
882
883
pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
884
if (start) {
885
/* last dsp time invalid */
886
mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
887
rmh.cmd[0] |= mgr->granularity;
888
}
889
err = pcxhr_send_msg(mgr, &rmh);
890
if (err < 0)
891
dev_err(&mgr->pci->dev, "error %s err(%x)\n", __func__,
892
err);
893
return err;
894
}
895
896
/*
897
* prepare callback for all pcms
898
*/
899
static int pcxhr_prepare(struct snd_pcm_substream *subs)
900
{
901
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
902
struct pcxhr_mgr *mgr = chip->mgr;
903
int err = 0;
904
905
dev_dbg(chip->card->dev,
906
"%s : period_size(%lx) periods(%x) buffer_size(%lx)\n", __func__,
907
subs->runtime->period_size, subs->runtime->periods,
908
subs->runtime->buffer_size);
909
910
mutex_lock(&mgr->setup_mutex);
911
912
do {
913
/* only the first stream can choose the sample rate */
914
/* set the clock only once (first stream) */
915
if (mgr->sample_rate != subs->runtime->rate) {
916
err = pcxhr_set_clock(mgr, subs->runtime->rate);
917
if (err)
918
break;
919
if (mgr->sample_rate == 0)
920
/* start the DSP-timer */
921
err = pcxhr_hardware_timer(mgr, 1);
922
mgr->sample_rate = subs->runtime->rate;
923
}
924
} while(0); /* do only once (so we can use break instead of goto) */
925
926
mutex_unlock(&mgr->setup_mutex);
927
928
return err;
929
}
930
931
932
/*
933
* HW_PARAMS callback for all pcms
934
*/
935
static int pcxhr_hw_params(struct snd_pcm_substream *subs,
936
struct snd_pcm_hw_params *hw)
937
{
938
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
939
struct pcxhr_mgr *mgr = chip->mgr;
940
struct pcxhr_stream *stream = subs->runtime->private_data;
941
942
mutex_lock(&mgr->setup_mutex);
943
944
/* set up channels */
945
stream->channels = params_channels(hw);
946
/* set up format for the stream */
947
stream->format = params_format(hw);
948
949
mutex_unlock(&mgr->setup_mutex);
950
951
return 0;
952
}
953
954
955
/*
956
* CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
957
*/
958
static const struct snd_pcm_hardware pcxhr_caps =
959
{
960
.info = (SNDRV_PCM_INFO_MMAP |
961
SNDRV_PCM_INFO_INTERLEAVED |
962
SNDRV_PCM_INFO_MMAP_VALID |
963
SNDRV_PCM_INFO_SYNC_START),
964
.formats = (SNDRV_PCM_FMTBIT_U8 |
965
SNDRV_PCM_FMTBIT_S16_LE |
966
SNDRV_PCM_FMTBIT_S16_BE |
967
SNDRV_PCM_FMTBIT_S24_3LE |
968
SNDRV_PCM_FMTBIT_S24_3BE |
969
SNDRV_PCM_FMTBIT_FLOAT_LE),
970
.rates = (SNDRV_PCM_RATE_CONTINUOUS |
971
SNDRV_PCM_RATE_8000_192000),
972
.rate_min = 8000,
973
.rate_max = 192000,
974
.channels_min = 1,
975
.channels_max = 2,
976
.buffer_bytes_max = (32*1024),
977
/* 1 byte == 1 frame U8 mono (PCXHR_GRANULARITY is frames!) */
978
.period_bytes_min = (2*PCXHR_GRANULARITY),
979
.period_bytes_max = (16*1024),
980
.periods_min = 2,
981
.periods_max = (32*1024/PCXHR_GRANULARITY),
982
};
983
984
985
static int pcxhr_open(struct snd_pcm_substream *subs)
986
{
987
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
988
struct pcxhr_mgr *mgr = chip->mgr;
989
struct snd_pcm_runtime *runtime = subs->runtime;
990
struct pcxhr_stream *stream;
991
int err;
992
993
mutex_lock(&mgr->setup_mutex);
994
995
/* copy the struct snd_pcm_hardware struct */
996
runtime->hw = pcxhr_caps;
997
998
if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK ) {
999
dev_dbg(chip->card->dev, "%s playback chip%d subs%d\n",
1000
__func__, chip->chip_idx, subs->number);
1001
stream = &chip->playback_stream[subs->number];
1002
} else {
1003
dev_dbg(chip->card->dev, "%s capture chip%d subs%d\n",
1004
__func__, chip->chip_idx, subs->number);
1005
if (mgr->mono_capture)
1006
runtime->hw.channels_max = 1;
1007
else
1008
runtime->hw.channels_min = 2;
1009
stream = &chip->capture_stream[subs->number];
1010
}
1011
if (stream->status != PCXHR_STREAM_STATUS_FREE){
1012
/* streams in use */
1013
dev_err(chip->card->dev, "%s chip%d subs%d in use\n",
1014
__func__, chip->chip_idx, subs->number);
1015
mutex_unlock(&mgr->setup_mutex);
1016
return -EBUSY;
1017
}
1018
1019
/* float format support is in some cases buggy on stereo cards */
1020
if (mgr->is_hr_stereo)
1021
runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;
1022
1023
/* buffer-size should better be multiple of period-size */
1024
err = snd_pcm_hw_constraint_integer(runtime,
1025
SNDRV_PCM_HW_PARAM_PERIODS);
1026
if (err < 0) {
1027
mutex_unlock(&mgr->setup_mutex);
1028
return err;
1029
}
1030
1031
/* if a sample rate is already used or fixed by external clock,
1032
* the stream cannot change
1033
*/
1034
if (mgr->sample_rate)
1035
runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
1036
else {
1037
if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
1038
int external_rate;
1039
if (pcxhr_get_external_clock(mgr, mgr->use_clock_type,
1040
&external_rate) ||
1041
external_rate == 0) {
1042
/* cannot detect the external clock rate */
1043
mutex_unlock(&mgr->setup_mutex);
1044
return -EBUSY;
1045
}
1046
runtime->hw.rate_min = external_rate;
1047
runtime->hw.rate_max = external_rate;
1048
}
1049
}
1050
1051
stream->status = PCXHR_STREAM_STATUS_OPEN;
1052
stream->substream = subs;
1053
stream->channels = 0; /* not configured yet */
1054
1055
runtime->private_data = stream;
1056
1057
/* better get a divisor of granularity values (96 or 192) */
1058
snd_pcm_hw_constraint_step(runtime, 0,
1059
SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
1060
snd_pcm_hw_constraint_step(runtime, 0,
1061
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
1062
snd_pcm_set_sync(subs);
1063
1064
mgr->ref_count_rate++;
1065
1066
mutex_unlock(&mgr->setup_mutex);
1067
return 0;
1068
}
1069
1070
1071
static int pcxhr_close(struct snd_pcm_substream *subs)
1072
{
1073
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
1074
struct pcxhr_mgr *mgr = chip->mgr;
1075
struct pcxhr_stream *stream = subs->runtime->private_data;
1076
1077
mutex_lock(&mgr->setup_mutex);
1078
1079
dev_dbg(chip->card->dev, "%s chip%d subs%d\n", __func__,
1080
chip->chip_idx, subs->number);
1081
1082
/* sample rate released */
1083
if (--mgr->ref_count_rate == 0) {
1084
mgr->sample_rate = 0; /* the sample rate is no more locked */
1085
pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */
1086
}
1087
1088
stream->status = PCXHR_STREAM_STATUS_FREE;
1089
stream->substream = NULL;
1090
1091
mutex_unlock(&mgr->setup_mutex);
1092
1093
return 0;
1094
}
1095
1096
1097
static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
1098
{
1099
u_int32_t timer_period_frag;
1100
int timer_buf_periods;
1101
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
1102
struct snd_pcm_runtime *runtime = subs->runtime;
1103
struct pcxhr_stream *stream = runtime->private_data;
1104
1105
mutex_lock(&chip->mgr->lock);
1106
1107
/* get the period fragment and the nb of periods in the buffer */
1108
timer_period_frag = stream->timer_period_frag;
1109
timer_buf_periods = stream->timer_buf_periods;
1110
1111
mutex_unlock(&chip->mgr->lock);
1112
1113
return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +
1114
timer_period_frag);
1115
}
1116
1117
1118
static const struct snd_pcm_ops pcxhr_ops = {
1119
.open = pcxhr_open,
1120
.close = pcxhr_close,
1121
.prepare = pcxhr_prepare,
1122
.hw_params = pcxhr_hw_params,
1123
.trigger = pcxhr_trigger,
1124
.pointer = pcxhr_stream_pointer,
1125
};
1126
1127
/*
1128
*/
1129
int pcxhr_create_pcm(struct snd_pcxhr *chip)
1130
{
1131
int err;
1132
struct snd_pcm *pcm;
1133
char name[32];
1134
1135
snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx);
1136
err = snd_pcm_new(chip->card, name, 0,
1137
chip->nb_streams_play,
1138
chip->nb_streams_capt, &pcm);
1139
if (err < 0) {
1140
dev_err(chip->card->dev, "cannot create pcm %s\n", name);
1141
return err;
1142
}
1143
pcm->private_data = chip;
1144
1145
if (chip->nb_streams_play)
1146
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcxhr_ops);
1147
if (chip->nb_streams_capt)
1148
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcxhr_ops);
1149
1150
pcm->info_flags = 0;
1151
pcm->nonatomic = true;
1152
strscpy(pcm->name, name);
1153
1154
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
1155
&chip->mgr->pci->dev,
1156
32*1024, 32*1024);
1157
chip->pcm = pcm;
1158
return 0;
1159
}
1160
1161
static int pcxhr_chip_free(struct snd_pcxhr *chip)
1162
{
1163
kfree(chip);
1164
return 0;
1165
}
1166
1167
static int pcxhr_chip_dev_free(struct snd_device *device)
1168
{
1169
struct snd_pcxhr *chip = device->device_data;
1170
return pcxhr_chip_free(chip);
1171
}
1172
1173
1174
/*
1175
*/
1176
static int pcxhr_create(struct pcxhr_mgr *mgr,
1177
struct snd_card *card, int idx)
1178
{
1179
int err;
1180
struct snd_pcxhr *chip;
1181
static const struct snd_device_ops ops = {
1182
.dev_free = pcxhr_chip_dev_free,
1183
};
1184
1185
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1186
if (!chip)
1187
return -ENOMEM;
1188
1189
chip->card = card;
1190
chip->chip_idx = idx;
1191
chip->mgr = mgr;
1192
card->sync_irq = mgr->irq;
1193
1194
if (idx < mgr->playback_chips)
1195
/* stereo or mono streams */
1196
chip->nb_streams_play = PCXHR_PLAYBACK_STREAMS;
1197
1198
if (idx < mgr->capture_chips) {
1199
if (mgr->mono_capture)
1200
chip->nb_streams_capt = 2; /* 2 mono streams */
1201
else
1202
chip->nb_streams_capt = 1; /* or 1 stereo stream */
1203
}
1204
1205
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1206
if (err < 0) {
1207
pcxhr_chip_free(chip);
1208
return err;
1209
}
1210
1211
mgr->chip[idx] = chip;
1212
1213
return 0;
1214
}
1215
1216
/* proc interface */
1217
static void pcxhr_proc_info(struct snd_info_entry *entry,
1218
struct snd_info_buffer *buffer)
1219
{
1220
struct snd_pcxhr *chip = entry->private_data;
1221
struct pcxhr_mgr *mgr = chip->mgr;
1222
1223
snd_iprintf(buffer, "\n%s\n", mgr->name);
1224
1225
/* stats available when embedded DSP is running */
1226
if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1227
struct pcxhr_rmh rmh;
1228
short ver_maj = (mgr->dsp_version >> 16) & 0xff;
1229
short ver_min = (mgr->dsp_version >> 8) & 0xff;
1230
short ver_build = mgr->dsp_version & 0xff;
1231
snd_iprintf(buffer, "module version %s\n",
1232
PCXHR_DRIVER_VERSION_STRING);
1233
snd_iprintf(buffer, "dsp version %d.%d.%d\n",
1234
ver_maj, ver_min, ver_build);
1235
if (mgr->board_has_analog)
1236
snd_iprintf(buffer, "analog io available\n");
1237
else
1238
snd_iprintf(buffer, "digital only board\n");
1239
1240
/* calc cpu load of the dsp */
1241
pcxhr_init_rmh(&rmh, CMD_GET_DSP_RESOURCES);
1242
if( ! pcxhr_send_msg(mgr, &rmh) ) {
1243
int cur = rmh.stat[0];
1244
int ref = rmh.stat[1];
1245
if (ref > 0) {
1246
if (mgr->sample_rate_real != 0 &&
1247
mgr->sample_rate_real != 48000) {
1248
ref = (ref * 48000) /
1249
mgr->sample_rate_real;
1250
if (mgr->sample_rate_real >=
1251
PCXHR_IRQ_TIMER_FREQ)
1252
ref *= 2;
1253
}
1254
cur = 100 - (100 * cur) / ref;
1255
snd_iprintf(buffer, "cpu load %d%%\n", cur);
1256
snd_iprintf(buffer, "buffer pool %d/%d\n",
1257
rmh.stat[2], rmh.stat[3]);
1258
}
1259
}
1260
snd_iprintf(buffer, "dma granularity : %d\n",
1261
mgr->granularity);
1262
snd_iprintf(buffer, "dsp time errors : %d\n",
1263
mgr->dsp_time_err);
1264
snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
1265
mgr->async_err_pipe_xrun);
1266
snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
1267
mgr->async_err_stream_xrun);
1268
snd_iprintf(buffer, "dsp async last other error : %x\n",
1269
mgr->async_err_other_last);
1270
/* debug zone dsp */
1271
rmh.cmd[0] = 0x4200 + PCXHR_SIZE_MAX_STATUS;
1272
rmh.cmd_len = 1;
1273
rmh.stat_len = PCXHR_SIZE_MAX_STATUS;
1274
rmh.dsp_stat = 0;
1275
rmh.cmd_idx = CMD_LAST_INDEX;
1276
if( ! pcxhr_send_msg(mgr, &rmh) ) {
1277
int i;
1278
if (rmh.stat_len > 8)
1279
rmh.stat_len = 8;
1280
for (i = 0; i < rmh.stat_len; i++)
1281
snd_iprintf(buffer, "debug[%02d] = %06x\n",
1282
i, rmh.stat[i]);
1283
}
1284
} else
1285
snd_iprintf(buffer, "no firmware loaded\n");
1286
snd_iprintf(buffer, "\n");
1287
}
1288
static void pcxhr_proc_sync(struct snd_info_entry *entry,
1289
struct snd_info_buffer *buffer)
1290
{
1291
struct snd_pcxhr *chip = entry->private_data;
1292
struct pcxhr_mgr *mgr = chip->mgr;
1293
static const char *textsHR22[3] = {
1294
"Internal", "AES Sync", "AES 1"
1295
};
1296
static const char *textsPCXHR[7] = {
1297
"Internal", "Word", "AES Sync",
1298
"AES 1", "AES 2", "AES 3", "AES 4"
1299
};
1300
const char **texts;
1301
int max_clock;
1302
if (mgr->is_hr_stereo) {
1303
texts = textsHR22;
1304
max_clock = HR22_CLOCK_TYPE_MAX;
1305
} else {
1306
texts = textsPCXHR;
1307
max_clock = PCXHR_CLOCK_TYPE_MAX;
1308
}
1309
1310
snd_iprintf(buffer, "\n%s\n", mgr->name);
1311
snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
1312
texts[mgr->cur_clock_type]);
1313
snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
1314
mgr->sample_rate_real);
1315
/* commands available when embedded DSP is running */
1316
if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1317
int i, err, sample_rate;
1318
for (i = 1; i <= max_clock; i++) {
1319
err = pcxhr_get_external_clock(mgr, i, &sample_rate);
1320
if (err)
1321
break;
1322
snd_iprintf(buffer, "%s Clock\t\t= %d\n",
1323
texts[i], sample_rate);
1324
}
1325
} else
1326
snd_iprintf(buffer, "no firmware loaded\n");
1327
snd_iprintf(buffer, "\n");
1328
}
1329
1330
static void pcxhr_proc_gpio_read(struct snd_info_entry *entry,
1331
struct snd_info_buffer *buffer)
1332
{
1333
struct snd_pcxhr *chip = entry->private_data;
1334
struct pcxhr_mgr *mgr = chip->mgr;
1335
/* commands available when embedded DSP is running */
1336
if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1337
/* gpio ports on stereo boards only available */
1338
int value = 0;
1339
hr222_read_gpio(mgr, 1, &value); /* GPI */
1340
snd_iprintf(buffer, "GPI: 0x%x\n", value);
1341
hr222_read_gpio(mgr, 0, &value); /* GP0 */
1342
snd_iprintf(buffer, "GPO: 0x%x\n", value);
1343
} else
1344
snd_iprintf(buffer, "no firmware loaded\n");
1345
snd_iprintf(buffer, "\n");
1346
}
1347
static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,
1348
struct snd_info_buffer *buffer)
1349
{
1350
struct snd_pcxhr *chip = entry->private_data;
1351
struct pcxhr_mgr *mgr = chip->mgr;
1352
char line[64];
1353
int value;
1354
/* commands available when embedded DSP is running */
1355
if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)))
1356
return;
1357
while (!snd_info_get_line(buffer, line, sizeof(line))) {
1358
if (sscanf(line, "GPO: 0x%x", &value) != 1)
1359
continue;
1360
hr222_write_gpo(mgr, value); /* GP0 */
1361
}
1362
}
1363
1364
/* Access to the results of the CMD_GET_TIME_CODE RMH */
1365
#define TIME_CODE_VALID_MASK 0x00800000
1366
#define TIME_CODE_NEW_MASK 0x00400000
1367
#define TIME_CODE_BACK_MASK 0x00200000
1368
#define TIME_CODE_WAIT_MASK 0x00100000
1369
1370
/* Values for the CMD_MANAGE_SIGNAL RMH */
1371
#define MANAGE_SIGNAL_TIME_CODE 0x01
1372
#define MANAGE_SIGNAL_MIDI 0x02
1373
1374
/* linear time code read proc*/
1375
static void pcxhr_proc_ltc(struct snd_info_entry *entry,
1376
struct snd_info_buffer *buffer)
1377
{
1378
struct snd_pcxhr *chip = entry->private_data;
1379
struct pcxhr_mgr *mgr = chip->mgr;
1380
struct pcxhr_rmh rmh;
1381
unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm;
1382
int err;
1383
/* commands available when embedded DSP is running */
1384
if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) {
1385
snd_iprintf(buffer, "no firmware loaded\n");
1386
return;
1387
}
1388
if (!mgr->capture_ltc) {
1389
pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL);
1390
rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE;
1391
err = pcxhr_send_msg(mgr, &rmh);
1392
if (err) {
1393
snd_iprintf(buffer, "ltc not activated (%d)\n", err);
1394
return;
1395
}
1396
if (mgr->is_hr_stereo)
1397
hr222_manage_timecode(mgr, 1);
1398
else
1399
pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE,
1400
REG_CONT_VALSMPTE, NULL);
1401
mgr->capture_ltc = 1;
1402
}
1403
pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE);
1404
err = pcxhr_send_msg(mgr, &rmh);
1405
if (err) {
1406
snd_iprintf(buffer, "ltc read error (err=%d)\n", err);
1407
return ;
1408
}
1409
ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf);
1410
ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf);
1411
ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf);
1412
ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf);
1413
1414
snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n",
1415
ltcHrs, ltcMin, ltcSec, ltcFrm);
1416
snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff,
1417
rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff);
1418
/*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n",
1419
rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/
1420
if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) {
1421
snd_iprintf(buffer, "warning: linear timecode not valid\n");
1422
}
1423
}
1424
1425
static void pcxhr_proc_init(struct snd_pcxhr *chip)
1426
{
1427
snd_card_ro_proc_new(chip->card, "info", chip, pcxhr_proc_info);
1428
snd_card_ro_proc_new(chip->card, "sync", chip, pcxhr_proc_sync);
1429
/* gpio available on stereo sound cards only */
1430
if (chip->mgr->is_hr_stereo)
1431
snd_card_rw_proc_new(chip->card, "gpio", chip,
1432
pcxhr_proc_gpio_read,
1433
pcxhr_proc_gpo_write);
1434
snd_card_ro_proc_new(chip->card, "ltc", chip, pcxhr_proc_ltc);
1435
}
1436
/* end of proc interface */
1437
1438
/*
1439
* release all the cards assigned to a manager instance
1440
*/
1441
static int pcxhr_free(struct pcxhr_mgr *mgr)
1442
{
1443
unsigned int i;
1444
1445
for (i = 0; i < mgr->num_cards; i++) {
1446
if (mgr->chip[i])
1447
snd_card_free(mgr->chip[i]->card);
1448
}
1449
1450
/* reset board if some firmware was loaded */
1451
if(mgr->dsp_loaded) {
1452
pcxhr_reset_board(mgr);
1453
dev_dbg(&mgr->pci->dev, "reset pcxhr !\n");
1454
}
1455
1456
/* release irq */
1457
if (mgr->irq >= 0)
1458
free_irq(mgr->irq, mgr);
1459
1460
pci_release_regions(mgr->pci);
1461
1462
/* free hostport purgebuffer */
1463
if (mgr->hostport.area) {
1464
snd_dma_free_pages(&mgr->hostport);
1465
mgr->hostport.area = NULL;
1466
}
1467
1468
kfree(mgr->prmh);
1469
1470
pci_disable_device(mgr->pci);
1471
kfree(mgr);
1472
return 0;
1473
}
1474
1475
/*
1476
* probe function - creates the card manager
1477
*/
1478
static int pcxhr_probe(struct pci_dev *pci,
1479
const struct pci_device_id *pci_id)
1480
{
1481
static int dev;
1482
struct pcxhr_mgr *mgr;
1483
unsigned int i;
1484
int err;
1485
size_t size;
1486
char *card_name;
1487
1488
if (dev >= SNDRV_CARDS)
1489
return -ENODEV;
1490
if (! enable[dev]) {
1491
dev++;
1492
return -ENOENT;
1493
}
1494
1495
/* enable PCI device */
1496
err = pci_enable_device(pci);
1497
if (err < 0)
1498
return err;
1499
pci_set_master(pci);
1500
1501
/* check if we can restrict PCI DMA transfers to 32 bits */
1502
if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) {
1503
dev_err(&pci->dev,
1504
"architecture does not support 32bit PCI busmaster DMA\n");
1505
pci_disable_device(pci);
1506
return -ENXIO;
1507
}
1508
1509
/* alloc card manager */
1510
mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
1511
if (! mgr) {
1512
pci_disable_device(pci);
1513
return -ENOMEM;
1514
}
1515
1516
if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) {
1517
kfree(mgr);
1518
pci_disable_device(pci);
1519
return -ENODEV;
1520
}
1521
card_name =
1522
pcxhr_board_params[pci_id->driver_data].board_name;
1523
mgr->playback_chips =
1524
pcxhr_board_params[pci_id->driver_data].playback_chips;
1525
mgr->capture_chips =
1526
pcxhr_board_params[pci_id->driver_data].capture_chips;
1527
mgr->fw_file_set =
1528
pcxhr_board_params[pci_id->driver_data].fw_file_set;
1529
mgr->firmware_num =
1530
pcxhr_board_params[pci_id->driver_data].firmware_num;
1531
mgr->mono_capture = mono[dev];
1532
mgr->is_hr_stereo = (mgr->playback_chips == 1);
1533
mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);
1534
mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);
1535
1536
if (mgr->is_hr_stereo)
1537
mgr->granularity = PCXHR_GRANULARITY_HR22;
1538
else
1539
mgr->granularity = PCXHR_GRANULARITY;
1540
1541
/* resource assignment */
1542
err = pci_request_regions(pci, card_name);
1543
if (err < 0) {
1544
kfree(mgr);
1545
pci_disable_device(pci);
1546
return err;
1547
}
1548
for (i = 0; i < 3; i++)
1549
mgr->port[i] = pci_resource_start(pci, i);
1550
1551
mgr->pci = pci;
1552
mgr->irq = -1;
1553
1554
if (request_threaded_irq(pci->irq, pcxhr_interrupt,
1555
pcxhr_threaded_irq, IRQF_SHARED,
1556
KBUILD_MODNAME, mgr)) {
1557
dev_err(&pci->dev, "unable to grab IRQ %d\n", pci->irq);
1558
pcxhr_free(mgr);
1559
return -EBUSY;
1560
}
1561
mgr->irq = pci->irq;
1562
1563
snprintf(mgr->name, sizeof(mgr->name),
1564
"Digigram at 0x%lx & 0x%lx, 0x%lx irq %i",
1565
mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
1566
1567
/* ISR lock */
1568
mutex_init(&mgr->lock);
1569
mutex_init(&mgr->msg_lock);
1570
1571
/* init setup mutex*/
1572
mutex_init(&mgr->setup_mutex);
1573
1574
mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
1575
sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
1576
PCXHR_SIZE_MAX_STATUS),
1577
GFP_KERNEL);
1578
if (! mgr->prmh) {
1579
pcxhr_free(mgr);
1580
return -ENOMEM;
1581
}
1582
1583
for (i=0; i < PCXHR_MAX_CARDS; i++) {
1584
struct snd_card *card;
1585
char tmpid[16];
1586
int idx;
1587
1588
if (i >= max(mgr->playback_chips, mgr->capture_chips))
1589
break;
1590
mgr->num_cards++;
1591
1592
if (index[dev] < 0)
1593
idx = index[dev];
1594
else
1595
idx = index[dev] + i;
1596
1597
snprintf(tmpid, sizeof(tmpid), "%s-%d",
1598
id[dev] ? id[dev] : card_name, i);
1599
err = snd_card_new(&pci->dev, idx, tmpid, THIS_MODULE,
1600
0, &card);
1601
1602
if (err < 0) {
1603
dev_err(&pci->dev, "cannot allocate the card %d\n", i);
1604
pcxhr_free(mgr);
1605
return err;
1606
}
1607
1608
strscpy(card->driver, DRIVER_NAME);
1609
snprintf(card->shortname, sizeof(card->shortname),
1610
"Digigram [PCM #%d]", i);
1611
snprintf(card->longname, sizeof(card->longname),
1612
"%s [PCM #%d]", mgr->name, i);
1613
1614
err = pcxhr_create(mgr, card, i);
1615
if (err < 0) {
1616
snd_card_free(card);
1617
pcxhr_free(mgr);
1618
return err;
1619
}
1620
1621
if (i == 0)
1622
/* init proc interface only for chip0 */
1623
pcxhr_proc_init(mgr->chip[i]);
1624
1625
err = snd_card_register(card);
1626
if (err < 0) {
1627
pcxhr_free(mgr);
1628
return err;
1629
}
1630
}
1631
1632
/* create hostport purgebuffer */
1633
size = PAGE_ALIGN(sizeof(struct pcxhr_hostport));
1634
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
1635
size, &mgr->hostport) < 0) {
1636
pcxhr_free(mgr);
1637
return -ENOMEM;
1638
}
1639
/* init purgebuffer */
1640
memset(mgr->hostport.area, 0, size);
1641
1642
/* create a DSP loader */
1643
err = pcxhr_setup_firmware(mgr);
1644
if (err < 0) {
1645
pcxhr_free(mgr);
1646
return err;
1647
}
1648
1649
pci_set_drvdata(pci, mgr);
1650
dev++;
1651
return 0;
1652
}
1653
1654
static void pcxhr_remove(struct pci_dev *pci)
1655
{
1656
pcxhr_free(pci_get_drvdata(pci));
1657
}
1658
1659
static struct pci_driver pcxhr_driver = {
1660
.name = KBUILD_MODNAME,
1661
.id_table = pcxhr_ids,
1662
.probe = pcxhr_probe,
1663
.remove = pcxhr_remove,
1664
};
1665
1666
module_pci_driver(pcxhr_driver);
1667
1668