2
* Purpose: Card specific routines for M Audio Delta 1010LT
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
10
* This this source file is released under GPL v2 license (no other versions).
11
* See the COPYING file included in the main directory of this source
12
* distribution for the license terms and conditions.
16
#include "oss_config.h"
20
#define CH_STEREO 0x80
22
/* SPI chip select codes */
30
#define WCLOCK_ENABLE 7
32
#define CS8_ADDR 0x20 /* Chip SPI/I2C address */
46
# define PRT_STATUS(v) outb(v&0xff, 0x378)
48
# define PRT_STATUS(v)
51
/* ----- DEFINITION OF GPIOs ----- */
53
#define FPGA_PROGRAM_L 7 /* FPGA program control select line (active low) */
54
#define FPGA_CLK 1 /* FPGA program clock */
55
#define EXT_REG_CLK 0 /* Was GPIO Fast mode (debug) */
56
#define FPGA_D0 3 /* FPGA program data */
58
#define LATCH_EN_L 4 /* Strobe for external latch (active low) */
61
#define FPGA_INIT_STATE 0xFC /* Init state for extern register to allow */
62
/* FPGA initialization. */
66
extern int envy24_gain_sliders;
67
extern int envy24_virtualout;
68
extern int envy24_zerolatency; /* Testing in progress */
71
SPI_select (envy24_devc * devc, int sel)
75
tmp = envy24_read_cci (devc, 0x20);
77
tmp |= (sel & 0x7) << 4;
78
envy24_write_cci (devc, 0x20, tmp);
82
write_d1010lt_codec (envy24_devc * devc, int sel, int bRegister,
87
WriteGPIObit (devc, SPI_DOUT, 0);
88
WriteGPIObit (devc, SPI_CLK, 1);
90
SPI_select (devc, sel);
92
bRegister = (bRegister & 0x0F) | 0xA0; /* Add I2C address field. */
94
/* Assert the CODEC chip select and wait at least 150 nS. */
97
/* Write the register address byte. */
99
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
101
/* Drop SPI clock low. */
102
WriteGPIObit (devc, SPI_CLK, 0);
104
/* Write current data bit. */
105
if (bMask & bRegister)
106
WriteGPIObit (devc, SPI_DOUT, 1);
108
WriteGPIObit (devc, SPI_DOUT, 0);
110
/* Raise SPI clock to "clock data in". */
111
WriteGPIObit (devc, SPI_CLK, 1);
115
/* Write the data byte. */
117
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
119
/* Drop SPI clock low. */
120
WriteGPIObit (devc, SPI_CLK, 0);
122
/* Write current data bit. */
124
WriteGPIObit (devc, SPI_DOUT, 1);
126
WriteGPIObit (devc, SPI_DOUT, 0);
128
/* Raise SPI clock to "clock data in". */
129
WriteGPIObit (devc, SPI_CLK, 1);
132
/* De-assert chip select. */
135
SPI_select (devc, NONE_CS);
139
d1010lt_card_init (envy24_devc * devc)
143
SPI_select (devc, NONE_CS);
145
for (i = 0; i < 4; i++)
147
write_d1010lt_codec (devc, i, 0, 0x07);
148
write_d1010lt_codec (devc, i, 1, 0x03);
149
write_d1010lt_codec (devc, i, 2, 0x60);
150
write_d1010lt_codec (devc, i, 3, 0x19);
151
write_d1010lt_codec (devc, i, 4, 0x7f);
152
write_d1010lt_codec (devc, i, 5, 0x7f);
153
write_d1010lt_codec (devc, i, 6, 0x7f);
154
write_d1010lt_codec (devc, i, 7, 0x7f);
160
envy24_set_d1010lt (int dev, int ctrl, unsigned int cmd, int value)
162
envy24_devc *devc = mixer_devs[dev]->devc;
164
static unsigned char levels[] = { 0x7f, 0x8c, 0x98 };
169
if (cmd == SNDCTL_MIX_READ)
171
return devc->akm_gains[ctrl];
173
else if (cmd == SNDCTL_MIX_WRITE)
175
codec = (ctrl & 0x7) / 2;
176
if (envy24_gain_sliders)
178
level = value & 0xff;
186
if (value < 0 || value > 2)
188
level = levels[value];
191
switch (ctrl & 0x89) /* IN/OUT, LEFT/RIGHT, Gang switches */
193
case 0x00: /* Left output channel only */
194
write_d1010lt_codec (devc, codec, 6, level);
197
case 0x01: /* Right output channel only */
198
write_d1010lt_codec (devc, codec, 7, level);
201
case 0x80: /* Both output channels */
202
write_d1010lt_codec (devc, codec, 6, level);
203
write_d1010lt_codec (devc, codec, 7, level);
206
case 0x08: /* Left input channel only */
207
write_d1010lt_codec (devc, codec, 4, level);
210
case 0x09: /* Right input channel only */
211
write_d1010lt_codec (devc, codec, 5, level);
214
case 0x88: /* Both input channels */
215
write_d1010lt_codec (devc, codec, 4, level);
216
write_d1010lt_codec (devc, codec, 5, level);
220
return devc->akm_gains[ctrl] = value;
227
d1010lt_mix_init (envy24_devc * devc, int dev, int group)
229
int i, mask = devc->outportmask, err, skip;
230
int typ = MIXT_ENUM, range = 3;
233
if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
236
skip = devc->skipdevs;
240
if (envy24_gain_sliders)
242
typ = MIXT_MONOSLIDER;
245
for (i = 0; i < 0xff; i++)
246
devc->akm_gains[i] = 0x7f;
249
for (i = 0; i < 0xff; i++)
250
devc->akm_gains[i] = 0;
252
for (i = 0; i < 8; i += skip)
255
if (!(mask & (1 << i)))
256
continue; /* Not present */
258
if (devc->skipdevs == 2)
261
strcpy (tmp, "ENVY24_SPDOUT");
263
sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
265
if ((err = mixer_ext_create_control (dev, group,
267
envy24_set_d1010lt, typ, tmp,
271
MIXF_WRITEABLE)) < 0)
277
strcpy (tmp, "ENVY24_SPDOUTL");
279
strcpy (tmp, "ENVY24_SPDOUTR");
281
sprintf (tmp, "ENVY24_OUT%d", i + 1);
283
if ((err = mixer_ext_create_control (dev, group,
284
i, envy24_set_d1010lt,
289
MIXF_WRITEABLE)) < 0)
294
mask = devc->inportmask;
295
for (i = 0; i < 8; i += skip)
298
if (!(mask & (1 << i)))
299
continue; /* Not present */
301
if (devc->skipdevs == 2)
304
strcpy (tmp, "ENVY24_SPDIN");
306
sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
308
if ((err = mixer_ext_create_control (dev, group,
310
envy24_set_d1010lt, typ, tmp,
314
MIXF_WRITEABLE)) < 0)
320
strcpy (tmp, "ENVY24_SPDINL");
322
strcpy (tmp, "ENVY24_SPDINR");
324
sprintf (tmp, "ENVY24_IN%d", i + 1);
326
if ((err = mixer_ext_create_control (dev, group,
327
8 + i, envy24_set_d1010lt,
332
MIXF_WRITEABLE)) < 0)
341
write_d1010lt_spdif_reg (envy24_devc * devc, int bRegister, int bData)
346
/* Assert the CODEC chip select and wait at least 150 nS. */
348
SPI_select (devc, CS8_CS);
350
/* Write the SPI address/cmd byte. */
352
bSPI = CS8_ADDR | CS8_WR;
354
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
356
/* Drop SPI clock low. */
357
WriteGPIObit (devc, SPI_CLK, 0);
359
/* Write current data bit. */
361
WriteGPIObit (devc, SPI_DOUT, 1);
363
WriteGPIObit (devc, SPI_DOUT, 0);
365
/* Raise SPI clock to "clock data in". */
366
WriteGPIObit (devc, SPI_CLK, 1);
369
/* Write the address (MAP) byte. */
371
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
373
/* Drop SPI clock low. */
374
WriteGPIObit (devc, SPI_CLK, 0);
376
/* Write current data bit. */
377
if (bMask & bRegister)
378
WriteGPIObit (devc, SPI_DOUT, 1);
380
WriteGPIObit (devc, SPI_DOUT, 0);
382
/* Raise SPI clock to "clock data in". */
383
WriteGPIObit (devc, SPI_CLK, 1);
387
/* Write the data byte. */
389
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
391
/* Drop SPI clock low. */
392
WriteGPIObit (devc, SPI_CLK, 0);
394
/* Write current data bit. */
396
WriteGPIObit (devc, SPI_DOUT, 1);
398
WriteGPIObit (devc, SPI_DOUT, 0);
400
/* Raise SPI clock to "clock data in". */
401
WriteGPIObit (devc, SPI_CLK, 1);
404
/* De-assert chip select. */
406
SPI_select (devc, NONE_CS);
410
read_d1010lt_spdif_reg (envy24_devc * devc, int reg)
413
unsigned char bRet = 0;
417
/****** WRITE MAP ADDRESS FIRST ******/
419
/* Drop the chip select low. */
420
/* Wait at least 150 nS. */
422
SPI_select (devc, CS8_CS);
424
/* Write the SPI address/cmd byte. */
426
bSPI = CS8_ADDR + CS8_WR; /* SPI address field plus WRITE operation. */
428
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
430
/* Drop clock (GPIO5) low. */
431
WriteGPIObit (devc, SPI_CLK, 0);
433
/* Write current data bit. */
435
WriteGPIObit (devc, SPI_DOUT, 1);
437
WriteGPIObit (devc, SPI_DOUT, 0);
439
/* Raise clock (GPIO5). */
440
WriteGPIObit (devc, SPI_CLK, 1);
444
/* Write the address (MAP) byte. */
446
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
448
/* Drop clock (GPIO5) low. */
449
WriteGPIObit (devc, SPI_CLK, 0);
451
/* Write current data bit. */
453
WriteGPIObit (devc, SPI_DOUT, 1);
455
WriteGPIObit (devc, SPI_DOUT, 0);
457
/* Raise clock (GPIO5). */
458
WriteGPIObit (devc, SPI_CLK, 1);
461
/* De-assert chip select(s). */
463
SPI_select (devc, NONE_CS);
466
/****** NOW READ THE DATA ******/
468
/* Drop the chip select low. */
469
/* Wait at least 150 nS. */
471
SPI_select (devc, CS8_CS);
474
/* Write the SPI address/cmd byte. */
476
bSPI = CS8_ADDR + CS8_RD; /* SPI address field plus READ operation. */
478
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
480
/* Drop clock (GPIO5) low. */
481
WriteGPIObit (devc, SPI_CLK, 0);
483
/* Write current data bit. */
485
WriteGPIObit (devc, SPI_DOUT, 1);
487
WriteGPIObit (devc, SPI_DOUT, 0);
489
/* Raise clock (GPIO5). */
490
WriteGPIObit (devc, SPI_CLK, 1);
494
/* Read the data byte. */
498
for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
500
/* Drop clock low. */
501
WriteGPIObit (devc, SPI_CLK, 0);
503
/* Read current data bit. */
504
if (ReadGPIObit (devc, SPI_DIN))
508
WriteGPIObit (devc, SPI_CLK, 1);
512
/* De-assert chip selects. */
514
SPI_select (devc, NONE_CS);
522
set_d1010lt_speed (envy24_devc * devc)
526
tmp = devc->speedbits;
528
switch (devc->syncsource)
531
OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
532
WriteGPIObit (devc, WCLOCK_ENABLE, 0);
533
write_d1010lt_spdif_reg (devc, 4,
534
read_d1010lt_spdif_reg (devc, 4) & (~BIT0));
539
OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
540
WriteGPIObit (devc, WCLOCK_ENABLE, 0);
541
write_d1010lt_spdif_reg (devc, 4,
542
read_d1010lt_spdif_reg (devc, 4) | BIT0);
547
OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
548
WriteGPIObit (devc, WCLOCK_ENABLE, 1);
549
write_d1010lt_spdif_reg (devc, 4,
550
read_d1010lt_spdif_reg (devc, 4) & (~BIT0));
551
if (devc->model_data->svid == 0xd63014ff)
555
* don't aks me why, but it seems to work
557
WriteGPIObit (devc, 6, 0);
558
WriteGPIObit (devc, WCLOCK_ENABLE, 1);
565
d1010lt_get_locked_status (envy24_devc * devc)
571
envy24_auxdrv_t d1010lt_auxdrv = {
577
read_d1010lt_spdif_reg,
578
write_d1010lt_spdif_reg,
580
d1010lt_get_locked_status,
581
cs8427_spdif_mixer_init