linux/sound/i2c/cs8427.c
<<
>>
Prefs
   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
  20static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
  21
  22MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  23MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
  24MODULE_LICENSE("GPL");
  25
  26#define CS8427_ADDR                     (0x20>>1) /* fixed address */
  27
  28struct 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
  37struct 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
  45int 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
  61EXPORT_SYMBOL(snd_cs8427_reg_write);
  62
  63static 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
  81static 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
  98static 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
 133static void snd_cs8427_free(struct snd_i2c_device *device)
 134{
 135        kfree(device->private_data);
 136}
 137
 138int 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}
 247EXPORT_SYMBOL(snd_cs8427_init);
 248
 249int 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
 298EXPORT_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 */
 305static 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
 345static 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
 355static 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
 370static 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
 378static 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
 403static 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
 411static 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
 423static 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
 447static 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
 455static 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
 462static 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
 515int 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
 547EXPORT_SYMBOL(snd_cs8427_iec958_build);
 548
 549int 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
 566EXPORT_SYMBOL(snd_cs8427_iec958_active);
 567
 568int 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
 608EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
 609