~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/i2c/cs8427.c

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp