OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [sound/] [i2c/] [cs8427.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  Routines for control of the CS8427 via i2c bus
3
 *  IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
4
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
5
 *
6
 *
7
 *   This program is free software; you can redistribute it and/or modify
8
 *   it under the terms of the GNU General Public License as published by
9
 *   the Free Software Foundation; either version 2 of the License, or
10
 *   (at your option) any later version.
11
 *
12
 *   This program is distributed in the hope that it will be useful,
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *   GNU General Public License for more details.
16
 *
17
 *   You should have received a copy of the GNU General Public License
18
 *   along with this program; if not, write to the Free Software
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20
 *
21
 */
22
 
23
#include <sound/driver.h>
24
#include <linux/slab.h>
25
#include <linux/delay.h>
26
#include <linux/init.h>
27
#include <sound/core.h>
28
#include <sound/control.h>
29
#include <sound/pcm.h>
30
#include <sound/cs8427.h>
31
#include <sound/asoundef.h>
32
 
33
static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
34
 
35
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
36
MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
37
MODULE_LICENSE("GPL");
38
 
39
#define CS8427_ADDR                     (0x20>>1) /* fixed address */
40
 
41
struct cs8427_stream {
42
        struct snd_pcm_substream *substream;
43
        char hw_status[24];             /* hardware status */
44
        char def_status[24];            /* default status */
45
        char pcm_status[24];            /* PCM private status */
46
        char hw_udata[32];
47
        struct snd_kcontrol *pcm_ctl;
48
};
49
 
50
struct cs8427 {
51
        unsigned char regmap[0x14];     /* map of first 1 + 13 registers */
52
        unsigned int rate;
53
        unsigned int reset_timeout;
54
        struct cs8427_stream playback;
55
        struct cs8427_stream capture;
56
};
57
 
58
static unsigned char swapbits(unsigned char val)
59
{
60
        int bit;
61
        unsigned char res = 0;
62
        for (bit = 0; bit < 8; bit++) {
63
                res <<= 1;
64
                res |= val & 1;
65
                val >>= 1;
66
        }
67
        return res;
68
}
69
 
70
int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
71
                         unsigned char val)
72
{
73
        int err;
74
        unsigned char buf[2];
75
 
76
        buf[0] = reg & 0x7f;
77
        buf[1] = val;
78
        if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
79
                snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x "
80
                           "to CS8427 (%i)\n", buf[0], buf[1], err);
81
                return err < 0 ? err : -EIO;
82
        }
83
        return 0;
84
}
85
 
86
EXPORT_SYMBOL(snd_cs8427_reg_write);
87
 
88
static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
89
{
90
        int err;
91
        unsigned char buf;
92
 
93
        if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
94
                snd_printk(KERN_ERR "unable to send register 0x%x byte "
95
                           "to CS8427\n", reg);
96
                return err < 0 ? err : -EIO;
97
        }
98
        if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
99
                snd_printk(KERN_ERR "unable to read register 0x%x byte "
100
                           "from CS8427\n", reg);
101
                return err < 0 ? err : -EIO;
102
        }
103
        return buf;
104
}
105
 
106
static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
107
{
108
        struct cs8427 *chip = device->private_data;
109
        int err;
110
 
111
        udata = udata ? CS8427_BSEL : 0;
112
        if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
113
                chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
114
                chip->regmap[CS8427_REG_CSDATABUF] |= udata;
115
                err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
116
                                           chip->regmap[CS8427_REG_CSDATABUF]);
117
                if (err < 0)
118
                        return err;
119
        }
120
        return 0;
121
}
122
 
123
static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
124
                                    int udata,
125
                                    unsigned char *ndata,
126
                                    int count)
127
{
128
        struct cs8427 *chip = device->private_data;
129
        char *hw_data = udata ?
130
                chip->playback.hw_udata : chip->playback.hw_status;
131
        char data[32];
132
        int err, idx;
133
 
134
        if (!memcmp(hw_data, ndata, count))
135
                return 0;
136
        if ((err = snd_cs8427_select_corudata(device, udata)) < 0)
137
                return err;
138
        memcpy(hw_data, ndata, count);
139
        if (udata) {
140
                memset(data, 0, sizeof(data));
141
                if (memcmp(hw_data, data, count) == 0) {
142
                        chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
143
                        chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |
144
                                CS8427_EFTUI;
145
                        err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
146
                                                   chip->regmap[CS8427_REG_UDATABUF]);
147
                        return err < 0 ? err : 0;
148
                }
149
        }
150
        data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
151
        for (idx = 0; idx < count; idx++)
152
                data[idx + 1] = swapbits(ndata[idx]);
153
        if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
154
                return -EIO;
155
        return 1;
156
}
157
 
158
static void snd_cs8427_free(struct snd_i2c_device *device)
159
{
160
        kfree(device->private_data);
161
}
162
 
163
int snd_cs8427_create(struct snd_i2c_bus *bus,
164
                      unsigned char addr,
165
                      unsigned int reset_timeout,
166
                      struct snd_i2c_device **r_cs8427)
167
{
168
        static unsigned char initvals1[] = {
169
          CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
170
          /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,
171
             TCBL=output */
172
          CS8427_SWCLK | CS8427_TCBLDIR,
173
          /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,
174
             normal stereo operation */
175
          0x00,
176
          /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,
177
             Rx=>serial */
178
          CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
179
          /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,
180
             output time base = OMCK, input time base = recovered input clock,
181
             recovered input clock source is ILRCK changed to AES3INPUT
182
             (workaround, see snd_cs8427_reset) */
183
          CS8427_RXDILRCK,
184
          /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,
185
             24-bit, 64*Fsi */
186
          CS8427_SIDEL | CS8427_SILRPOL,
187
          /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format
188
             = I2S, 24-bit, 64*Fsi */
189
          CS8427_SODEL | CS8427_SOLRPOL,
190
        };
191
        static unsigned char initvals2[] = {
192
          CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
193
          /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,
194
             biphase, parity status bits */
195
          /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/
196
          0xff, /* set everything */
197
          /* CS8427_REG_CSDATABUF:
198
             Registers 32-55 window to CS buffer
199
             Inhibit D->E transfers from overwriting first 5 bytes of CS data.
200
             Inhibit D->E transfers (all) of CS data.
201
             Allow E->F transfer of CS data.
202
             One byte mode; both A/B channels get same written CB data.
203
             A channel info is output to chip's EMPH* pin. */
204
          CS8427_CBMR | CS8427_DETCI,
205
          /* CS8427_REG_UDATABUF:
206
             Use internal buffer to transmit User (U) data.
207
             Chip's U pin is an output.
208
             Transmit all O's for user data.
209
             Inhibit D->E transfers.
210
             Inhibit E->F transfers. */
211
          CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
212
        };
213
        int err;
214
        struct cs8427 *chip;
215
        struct snd_i2c_device *device;
216
        unsigned char buf[24];
217
 
218
        if ((err = snd_i2c_device_create(bus, "CS8427",
219
                                         CS8427_ADDR | (addr & 7),
220
                                         &device)) < 0)
221
                return err;
222
        chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
223
        if (chip == NULL) {
224
                snd_i2c_device_free(device);
225
                return -ENOMEM;
226
        }
227
        device->private_free = snd_cs8427_free;
228
 
229
        snd_i2c_lock(bus);
230
        err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
231
        if (err != CS8427_VER8427A) {
232
                /* give second chance */
233
                snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
234
                           "let me try again...\n", err);
235
                err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
236
        }
237
        if (err != CS8427_VER8427A) {
238
                snd_i2c_unlock(bus);
239
                snd_printk(KERN_ERR "unable to find CS8427 signature "
240
                           "(expected 0x%x, read 0x%x),\n",
241
                           CS8427_VER8427A, err);
242
                snd_printk(KERN_ERR "   initialization is not completed\n");
243
                return -EFAULT;
244
        }
245
        /* turn off run bit while making changes to configuration */
246
        err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
247
        if (err < 0)
248
                goto __fail;
249
        /* send initial values */
250
        memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
251
        if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
252
                err = err < 0 ? err : -EIO;
253
                goto __fail;
254
        }
255
        /* Turn off CS8427 interrupt stuff that is not used in hardware */
256
        memset(buf, 0, 7);
257
        /* from address 9 to 15 */
258
        buf[0] = 9;      /* register */
259
        if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
260
                goto __fail;
261
        /* send transfer initialization sequence */
262
        memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
263
        if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
264
                err = err < 0 ? err : -EIO;
265
                goto __fail;
266
        }
267
        /* write default channel status bytes */
268
        buf[0] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 0));
269
        buf[1] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 8));
270
        buf[2] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 16));
271
        buf[3] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 24));
272
        memset(buf + 4, 0, 24 - 4);
273
        if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)
274
                goto __fail;
275
        memcpy(chip->playback.def_status, buf, 24);
276
        memcpy(chip->playback.pcm_status, buf, 24);
277
        snd_i2c_unlock(bus);
278
 
279
        /* turn on run bit and rock'n'roll */
280
        if (reset_timeout < 1)
281
                reset_timeout = 1;
282
        chip->reset_timeout = reset_timeout;
283
        snd_cs8427_reset(device);
284
 
285
#if 0   // it's nice for read tests
286
        {
287
        char buf[128];
288
        int xx;
289
        buf[0] = 0x81;
290
        snd_i2c_sendbytes(device, buf, 1);
291
        snd_i2c_readbytes(device, buf, 127);
292
        for (xx = 0; xx < 127; xx++)
293
                printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
294
        }
295
#endif
296
 
297
        if (r_cs8427)
298
                *r_cs8427 = device;
299
        return 0;
300
 
301
      __fail:
302
        snd_i2c_unlock(bus);
303
        snd_i2c_device_free(device);
304
        return err < 0 ? err : -EIO;
305
}
306
 
307
EXPORT_SYMBOL(snd_cs8427_create);
308
 
309
/*
310
 * Reset the chip using run bit, also lock PLL using ILRCK and
311
 * put back AES3INPUT. This workaround is described in latest
312
 * CS8427 datasheet, otherwise TXDSERIAL will not work.
313
 */
314
static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
315
{
316
        struct cs8427 *chip;
317
        unsigned long end_time;
318
        int data, aes3input = 0;
319
 
320
        snd_assert(cs8427, return);
321
        chip = cs8427->private_data;
322
        snd_i2c_lock(cs8427->bus);
323
        if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
324
            CS8427_RXDAES3INPUT)  /* AES3 bit is set */
325
                aes3input = 1;
326
        chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
327
        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
328
                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
329
        udelay(200);
330
        chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;
331
        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
332
                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
333
        udelay(200);
334
        snd_i2c_unlock(cs8427->bus);
335
        end_time = jiffies + chip->reset_timeout;
336
        while (time_after_eq(end_time, jiffies)) {
337
                snd_i2c_lock(cs8427->bus);
338
                data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS);
339
                snd_i2c_unlock(cs8427->bus);
340
                if (!(data & CS8427_UNLOCK))
341
                        break;
342
                schedule_timeout_uninterruptible(1);
343
        }
344
        snd_i2c_lock(cs8427->bus);
345
        chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
346
        if (aes3input)
347
                chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
348
        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
349
                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
350
        snd_i2c_unlock(cs8427->bus);
351
}
352
 
353
static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,
354
                                     struct snd_ctl_elem_info *uinfo)
355
{
356
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
357
        uinfo->count = 1;
358
        uinfo->value.integer.min = 0;
359
        uinfo->value.integer.max = 255;
360
        return 0;
361
}
362
 
363
static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,
364
                                    struct snd_ctl_elem_value *ucontrol)
365
{
366
        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
367
        int data;
368
 
369
        snd_i2c_lock(device->bus);
370
        data = snd_cs8427_reg_read(device, kcontrol->private_value);
371
        snd_i2c_unlock(device->bus);
372
        if (data < 0)
373
                return data;
374
        ucontrol->value.integer.value[0] = data;
375
        return 0;
376
}
377
 
378
static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,
379
                                    struct snd_ctl_elem_info *uinfo)
380
{
381
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
382
        uinfo->count = 10;
383
        return 0;
384
}
385
 
386
static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
387
                                   struct snd_ctl_elem_value *ucontrol)
388
{
389
        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
390
        unsigned char reg = CS8427_REG_QSUBCODE;
391
        int err;
392
 
393
        snd_i2c_lock(device->bus);
394
        if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
395
                snd_printk(KERN_ERR "unable to send register 0x%x byte "
396
                           "to CS8427\n", reg);
397
                snd_i2c_unlock(device->bus);
398
                return err < 0 ? err : -EIO;
399
        }
400
        err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10);
401
        if (err != 10) {
402
                snd_printk(KERN_ERR "unable to read Q-subcode bytes "
403
                           "from CS8427\n");
404
                snd_i2c_unlock(device->bus);
405
                return err < 0 ? err : -EIO;
406
        }
407
        snd_i2c_unlock(device->bus);
408
        return 0;
409
}
410
 
411
static int snd_cs8427_spdif_info(struct snd_kcontrol *kcontrol,
412
                                 struct snd_ctl_elem_info *uinfo)
413
{
414
        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
415
        uinfo->count = 1;
416
        return 0;
417
}
418
 
419
static int snd_cs8427_spdif_get(struct snd_kcontrol *kcontrol,
420
                                struct snd_ctl_elem_value *ucontrol)
421
{
422
        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
423
        struct cs8427 *chip = device->private_data;
424
 
425
        snd_i2c_lock(device->bus);
426
        memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24);
427
        snd_i2c_unlock(device->bus);
428
        return 0;
429
}
430
 
431
static int snd_cs8427_spdif_put(struct snd_kcontrol *kcontrol,
432
                                struct snd_ctl_elem_value *ucontrol)
433
{
434
        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
435
        struct cs8427 *chip = device->private_data;
436
        unsigned char *status = kcontrol->private_value ?
437
                chip->playback.pcm_status : chip->playback.def_status;
438
        struct snd_pcm_runtime *runtime = chip->playback.substream ?
439
                chip->playback.substream->runtime : NULL;
440
        int err, change;
441
 
442
        snd_i2c_lock(device->bus);
443
        change = memcmp(ucontrol->value.iec958.status, status, 24) != 0;
444
        memcpy(status, ucontrol->value.iec958.status, 24);
445
        if (change && (kcontrol->private_value ?
446
                       runtime != NULL : runtime == NULL)) {
447
                err = snd_cs8427_send_corudata(device, 0, status, 24);
448
                if (err < 0)
449
                        change = err;
450
        }
451
        snd_i2c_unlock(device->bus);
452
        return change;
453
}
454
 
455
static int snd_cs8427_spdif_mask_info(struct snd_kcontrol *kcontrol,
456
                                      struct snd_ctl_elem_info *uinfo)
457
{
458
        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
459
        uinfo->count = 1;
460
        return 0;
461
}
462
 
463
static int snd_cs8427_spdif_mask_get(struct snd_kcontrol *kcontrol,
464
                                      struct snd_ctl_elem_value *ucontrol)
465
{
466
        memset(ucontrol->value.iec958.status, 0xff, 24);
467
        return 0;
468
}
469
 
470
static struct snd_kcontrol_new snd_cs8427_iec958_controls[] = {
471
{
472
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
473
        .info =         snd_cs8427_in_status_info,
474
        .name =         "IEC958 CS8427 Input Status",
475
        .access =       (SNDRV_CTL_ELEM_ACCESS_READ |
476
                         SNDRV_CTL_ELEM_ACCESS_VOLATILE),
477
        .get =          snd_cs8427_in_status_get,
478
        .private_value = 15,
479
},
480
{
481
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
482
        .info =         snd_cs8427_in_status_info,
483
        .name =         "IEC958 CS8427 Error Status",
484
        .access =       (SNDRV_CTL_ELEM_ACCESS_READ |
485
                         SNDRV_CTL_ELEM_ACCESS_VOLATILE),
486
        .get =          snd_cs8427_in_status_get,
487
        .private_value = 16,
488
},
489
{
490
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
491
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
492
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
493
        .info =         snd_cs8427_spdif_mask_info,
494
        .get =          snd_cs8427_spdif_mask_get,
495
},
496
{
497
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
498
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
499
        .info =         snd_cs8427_spdif_info,
500
        .get =          snd_cs8427_spdif_get,
501
        .put =          snd_cs8427_spdif_put,
502
        .private_value = 0
503
},
504
{
505
        .access =       (SNDRV_CTL_ELEM_ACCESS_READWRITE |
506
                         SNDRV_CTL_ELEM_ACCESS_INACTIVE),
507
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
508
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
509
        .info =         snd_cs8427_spdif_info,
510
        .get =          snd_cs8427_spdif_get,
511
        .put =          snd_cs8427_spdif_put,
512
        .private_value = 1
513
},
514
{
515
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
516
        .info =         snd_cs8427_qsubcode_info,
517
        .name =         "IEC958 Q-subcode Capture Default",
518
        .access =       (SNDRV_CTL_ELEM_ACCESS_READ |
519
                         SNDRV_CTL_ELEM_ACCESS_VOLATILE),
520
        .get =          snd_cs8427_qsubcode_get
521
}};
522
 
523
int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
524
                            struct snd_pcm_substream *play_substream,
525
                            struct snd_pcm_substream *cap_substream)
526
{
527
        struct cs8427 *chip = cs8427->private_data;
528
        struct snd_kcontrol *kctl;
529
        unsigned int idx;
530
        int err;
531
 
532
        snd_assert(play_substream && cap_substream, return -EINVAL);
533
        for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
534
                kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
535
                if (kctl == NULL)
536
                        return -ENOMEM;
537
                kctl->id.device = play_substream->pcm->device;
538
                kctl->id.subdevice = play_substream->number;
539
                err = snd_ctl_add(cs8427->bus->card, kctl);
540
                if (err < 0)
541
                        return err;
542
                if (! strcmp(kctl->id.name,
543
                             SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM)))
544
                        chip->playback.pcm_ctl = kctl;
545
        }
546
 
547
        chip->playback.substream = play_substream;
548
        chip->capture.substream = cap_substream;
549
        snd_assert(chip->playback.pcm_ctl, return -EIO);
550
        return 0;
551
}
552
 
553
EXPORT_SYMBOL(snd_cs8427_iec958_build);
554
 
555
int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
556
{
557
        struct cs8427 *chip;
558
 
559
        snd_assert(cs8427, return -ENXIO);
560
        chip = cs8427->private_data;
561
        if (active)
562
                memcpy(chip->playback.pcm_status,
563
                       chip->playback.def_status, 24);
564
        chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
565
        snd_ctl_notify(cs8427->bus->card,
566
                       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
567
                       &chip->playback.pcm_ctl->id);
568
        return 0;
569
}
570
 
571
EXPORT_SYMBOL(snd_cs8427_iec958_active);
572
 
573
int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
574
{
575
        struct cs8427 *chip;
576
        char *status;
577
        int err, reset;
578
 
579
        snd_assert(cs8427, return -ENXIO);
580
        chip = cs8427->private_data;
581
        status = chip->playback.pcm_status;
582
        snd_i2c_lock(cs8427->bus);
583
        if (status[0] & IEC958_AES0_PROFESSIONAL) {
584
                status[0] &= ~IEC958_AES0_PRO_FS;
585
                switch (rate) {
586
                case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;
587
                case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;
588
                case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;
589
                default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
590
                }
591
        } else {
592
                status[3] &= ~IEC958_AES3_CON_FS;
593
                switch (rate) {
594
                case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;
595
                case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;
596
                case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;
597
                }
598
        }
599
        err = snd_cs8427_send_corudata(cs8427, 0, status, 24);
600
        if (err > 0)
601
                snd_ctl_notify(cs8427->bus->card,
602
                               SNDRV_CTL_EVENT_MASK_VALUE,
603
                               &chip->playback.pcm_ctl->id);
604
        reset = chip->rate != rate;
605
        chip->rate = rate;
606
        snd_i2c_unlock(cs8427->bus);
607
        if (reset)
608
                snd_cs8427_reset(cs8427);
609
        return err < 0 ? err : 0;
610
}
611
 
612
EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
613
 
614
static int __init alsa_cs8427_module_init(void)
615
{
616
        return 0;
617
}
618
 
619
static void __exit alsa_cs8427_module_exit(void)
620
{
621
}
622
 
623
module_init(alsa_cs8427_module_init)
624
module_exit(alsa_cs8427_module_exit)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.