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