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        err = snd_i2c_sendbytes(device, buf, 2);
  54        if (err != 2) {
  55                snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x "
  56                           "to CS8427 (%i)\n", buf[0], buf[1], err);
  57                return err < 0 ? err : -EIO;
  58        }
  59        return 0;
  60}
  61
  62EXPORT_SYMBOL(snd_cs8427_reg_write);
  63
  64static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
  65{
  66        int err;
  67        unsigned char buf;
  68
  69        err = snd_i2c_sendbytes(device, &reg, 1);
  70        if (err != 1) {
  71                snd_printk(KERN_ERR "unable to send register 0x%x byte "
  72                           "to CS8427\n", reg);
  73                return err < 0 ? err : -EIO;
  74        }
  75        err = snd_i2c_readbytes(device, &buf, 1);
  76        if (err != 1) {
  77                snd_printk(KERN_ERR "unable to read register 0x%x byte "
  78                           "from CS8427\n", reg);
  79                return err < 0 ? err : -EIO;
  80        }
  81        return buf;
  82}
  83
  84static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
  85{
  86        struct cs8427 *chip = device->private_data;
  87        int err;
  88
  89        udata = udata ? CS8427_BSEL : 0;
  90        if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
  91                chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
  92                chip->regmap[CS8427_REG_CSDATABUF] |= udata;
  93                err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
  94                                           chip->regmap[CS8427_REG_CSDATABUF]);
  95                if (err < 0)
  96                        return err;
  97        }
  98        return 0;
  99}
 100
 101static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
 102                                    int udata,
 103                                    unsigned char *ndata,
 104                                    int count)
 105{
 106        struct cs8427 *chip = device->private_data;
 107        char *hw_data = udata ?
 108                chip->playback.hw_udata : chip->playback.hw_status;
 109        unsigned char data[32];
 110        int err, idx;
 111
 112        if (!memcmp(hw_data, ndata, count))
 113                return 0;
 114        err = snd_cs8427_select_corudata(device, udata);
 115        if (err < 0)
 116                return err;
 117        memcpy(hw_data, ndata, count);
 118        if (udata) {
 119                memset(data, 0, sizeof(data));
 120                if (memcmp(hw_data, data, count) == 0) {
 121                        chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
 122                        chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |
 123                                CS8427_EFTUI;
 124                        err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
 125                                                   chip->regmap[CS8427_REG_UDATABUF]);
 126                        return err < 0 ? err : 0;
 127                }
 128        }
 129        data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
 130        for (idx = 0; idx < count; idx++)
 131                data[idx + 1] = bitrev8(ndata[idx]);
 132        if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
 133                return -EIO;
 134        return 1;
 135}
 136
 137static void snd_cs8427_free(struct snd_i2c_device *device)
 138{
 139        kfree(device->private_data);
 140}
 141
 142int snd_cs8427_init(struct snd_i2c_bus *bus,
 143                    struct snd_i2c_device *device)
 144{
 145        static unsigned char initvals1[] = {
 146          CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
 147          /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,
 148             TCBL=output */
 149          CS8427_SWCLK | CS8427_TCBLDIR,
 150          /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,
 151             normal stereo operation */
 152          0x00,
 153          /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,
 154             Rx=>serial */
 155          CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
 156          /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,
 157             output time base = OMCK, input time base = recovered input clock,
 158             recovered input clock source is ILRCK changed to AES3INPUT
 159             (workaround, see snd_cs8427_reset) */
 160          CS8427_RXDILRCK,
 161          /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,
 162             24-bit, 64*Fsi */
 163          CS8427_SIDEL | CS8427_SILRPOL,
 164          /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format
 165             = I2S, 24-bit, 64*Fsi */
 166          CS8427_SODEL | CS8427_SOLRPOL,
 167        };
 168        static unsigned char initvals2[] = {
 169          CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
 170          /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,
 171             biphase, parity status bits */
 172          /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/
 173          0xff, /* set everything */
 174          /* CS8427_REG_CSDATABUF:
 175             Registers 32-55 window to CS buffer
 176             Inhibit D->E transfers from overwriting first 5 bytes of CS data.
 177             Inhibit D->E transfers (all) of CS data.
 178             Allow E->F transfer of CS data.
 179             One byte mode; both A/B channels get same written CB data.
 180             A channel info is output to chip's EMPH* pin. */
 181          CS8427_CBMR | CS8427_DETCI,
 182          /* CS8427_REG_UDATABUF:
 183             Use internal buffer to transmit User (U) data.
 184             Chip's U pin is an output.
 185             Transmit all O's for user data.
 186             Inhibit D->E transfers.
 187             Inhibit E->F transfers. */
 188          CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
 189        };
 190        struct cs8427 *chip = device->private_data;
 191        int err;
 192        unsigned char buf[24];
 193
 194        snd_i2c_lock(bus);
 195        err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
 196        if (err != CS8427_VER8427A) {
 197                /* give second chance */
 198                snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
 199                           "let me try again...\n", err);
 200                err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
 201        }
 202        if (err != CS8427_VER8427A) {
 203                snd_i2c_unlock(bus);
 204                snd_printk(KERN_ERR "unable to find CS8427 signature "
 205                           "(expected 0x%x, read 0x%x),\n",
 206                           CS8427_VER8427A, err);
 207                snd_printk(KERN_ERR "   initialization is not completed\n");
 208                return -EFAULT;
 209        }
 210        /* turn off run bit while making changes to configuration */
 211        err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
 212        if (err < 0)
 213                goto __fail;
 214        /* send initial values */
 215        memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
 216        err = snd_i2c_sendbytes(device, initvals1, 7);
 217        if (err != 7) {
 218                err = err < 0 ? err : -EIO;
 219                goto __fail;
 220        }
 221        /* Turn off CS8427 interrupt stuff that is not used in hardware */
 222        memset(buf, 0, 7);
 223        /* from address 9 to 15 */
 224        buf[0] = 9;     /* register */
 225        err = snd_i2c_sendbytes(device, buf, 7);
 226        if (err != 7)
 227                goto __fail;
 228        /* send transfer initialization sequence */
 229        memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
 230        err = snd_i2c_sendbytes(device, initvals2, 4);
 231        if (err != 4) {
 232                err = err < 0 ? err : -EIO;
 233                goto __fail;
 234        }
 235        /* write default channel status bytes */
 236        put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf);
 237        memset(buf + 4, 0, 24 - 4);
 238        if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)
 239                goto __fail;
 240        memcpy(chip->playback.def_status, buf, 24);
 241        memcpy(chip->playback.pcm_status, buf, 24);
 242        snd_i2c_unlock(bus);
 243
 244        /* turn on run bit and rock'n'roll */
 245        snd_cs8427_reset(device);
 246
 247        return 0;
 248
 249__fail:
 250        snd_i2c_unlock(bus);
 251
 252        return err;
 253}
 254EXPORT_SYMBOL(snd_cs8427_init);
 255
 256int snd_cs8427_create(struct snd_i2c_bus *bus,
 257                      unsigned char addr,
 258                      unsigned int reset_timeout,
 259                      struct snd_i2c_device **r_cs8427)
 260{
 261        int err;
 262        struct cs8427 *chip;
 263        struct snd_i2c_device *device;
 264
 265        err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7),
 266                                    &device);
 267        if (err < 0)
 268                return err;
 269        chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
 270        if (chip == NULL) {
 271                snd_i2c_device_free(device);
 272                return -ENOMEM;
 273        }
 274        device->private_free = snd_cs8427_free;
 275
 276        if (reset_timeout < 1)
 277                reset_timeout = 1;
 278        chip->reset_timeout = reset_timeout;
 279
 280        err = snd_cs8427_init(bus, device);
 281        if (err)
 282                goto __fail;
 283
 284#if 0   // it's nice for read tests
 285        {
 286        char buf[128];
 287        int xx;
 288        buf[0] = 0x81;
 289        snd_i2c_sendbytes(device, buf, 1);
 290        snd_i2c_readbytes(device, buf, 127);
 291        for (xx = 0; xx < 127; xx++)
 292                printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
 293        }
 294#endif
 295        
 296        if (r_cs8427)
 297                *r_cs8427 = device;
 298        return 0;
 299
 300      __fail:
 301        snd_i2c_device_free(device);
 302        return err < 0 ? err : -EIO;
 303}
 304
 305EXPORT_SYMBOL(snd_cs8427_create);
 306
 307/*
 308 * Reset the chip using run bit, also lock PLL using ILRCK and
 309 * put back AES3INPUT. This workaround is described in latest
 310 * CS8427 datasheet, otherwise TXDSERIAL will not work.
 311 */
 312static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
 313{
 314        struct cs8427 *chip;
 315        unsigned long end_time;
 316        int data, aes3input = 0;
 317
 318        if (snd_BUG_ON(!cs8427))
 319                return;
 320        chip = cs8427->private_data;
 321        snd_i2c_lock(cs8427->bus);
 322        if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
 323            CS8427_RXDAES3INPUT)  /* AES3 bit is set */
 324                aes3input = 1;
 325        chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
 326        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
 327                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
 328        udelay(200);
 329        chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;
 330        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
 331                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
 332        udelay(200);
 333        snd_i2c_unlock(cs8427->bus);
 334        end_time = jiffies + chip->reset_timeout;
 335        while (time_after_eq(end_time, jiffies)) {
 336                snd_i2c_lock(cs8427->bus);
 337                data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS);
 338                snd_i2c_unlock(cs8427->bus);
 339                if (!(data & CS8427_UNLOCK))
 340                        break;
 341                schedule_timeout_uninterruptible(1);
 342        }
 343        snd_i2c_lock(cs8427->bus);
 344        chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
 345        if (aes3input)
 346                chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
 347        snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
 348                             chip->regmap[CS8427_REG_CLOCKSOURCE]);
 349        snd_i2c_unlock(cs8427->bus);
 350}
 351
 352static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,
 353                                     struct snd_ctl_elem_info *uinfo)
 354{
 355        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 356        uinfo->count = 1;
 357        uinfo->value.integer.min = 0;
 358        uinfo->value.integer.max = 255;
 359        return 0;
 360}
 361
 362static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,
 363                                    struct snd_ctl_elem_value *ucontrol)
 364{
 365        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
 366        int data;
 367
 368        snd_i2c_lock(device->bus);
 369        data = snd_cs8427_reg_read(device, kcontrol->private_value);
 370        snd_i2c_unlock(device->bus);
 371        if (data < 0)
 372                return data;
 373        ucontrol->value.integer.value[0] = data;
 374        return 0;
 375}
 376
 377static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,
 378                                    struct snd_ctl_elem_info *uinfo)
 379{
 380        uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 381        uinfo->count = 10;
 382        return 0;
 383}
 384
 385static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
 386                                   struct snd_ctl_elem_value *ucontrol)
 387{
 388        struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
 389        unsigned char reg = CS8427_REG_QSUBCODE;
 390        int err;
 391
 392        snd_i2c_lock(device->bus);
 393        err = snd_i2c_sendbytes(device, &reg, 1);
 394        if (err != 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
 411static 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
 419static 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
 431static 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
 455static 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
 463static 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
 470static const 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
 523int 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        if (snd_BUG_ON(!play_substream || !cap_substream))
 533                return -EINVAL;
 534        for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
 535                kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
 536                if (kctl == NULL)
 537                        return -ENOMEM;
 538                kctl->id.device = play_substream->pcm->device;
 539                kctl->id.subdevice = play_substream->number;
 540                err = snd_ctl_add(cs8427->bus->card, kctl);
 541                if (err < 0)
 542                        return err;
 543                if (! strcmp(kctl->id.name,
 544                             SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM)))
 545                        chip->playback.pcm_ctl = kctl;
 546        }
 547
 548        chip->playback.substream = play_substream;
 549        chip->capture.substream = cap_substream;
 550        if (snd_BUG_ON(!chip->playback.pcm_ctl))
 551                return -EIO;
 552        return 0;
 553}
 554
 555EXPORT_SYMBOL(snd_cs8427_iec958_build);
 556
 557int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
 558{
 559        struct cs8427 *chip;
 560
 561        if (snd_BUG_ON(!cs8427))
 562                return -ENXIO;
 563        chip = cs8427->private_data;
 564        if (active) {
 565                memcpy(chip->playback.pcm_status,
 566                       chip->playback.def_status, 24);
 567                chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 568        } else {
 569                chip->playback.pcm_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 570        }
 571        snd_ctl_notify(cs8427->bus->card,
 572                       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
 573                       &chip->playback.pcm_ctl->id);
 574        return 0;
 575}
 576
 577EXPORT_SYMBOL(snd_cs8427_iec958_active);
 578
 579int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
 580{
 581        struct cs8427 *chip;
 582        char *status;
 583        int err, reset;
 584
 585        if (snd_BUG_ON(!cs8427))
 586                return -ENXIO;
 587        chip = cs8427->private_data;
 588        status = chip->playback.pcm_status;
 589        snd_i2c_lock(cs8427->bus);
 590        if (status[0] & IEC958_AES0_PROFESSIONAL) {
 591                status[0] &= ~IEC958_AES0_PRO_FS;
 592                switch (rate) {
 593                case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;
 594                case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;
 595                case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;
 596                default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
 597                }
 598        } else {
 599                status[3] &= ~IEC958_AES3_CON_FS;
 600                switch (rate) {
 601                case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;
 602                case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;
 603                case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;
 604                }
 605        }
 606        err = snd_cs8427_send_corudata(cs8427, 0, status, 24);
 607        if (err > 0)
 608                snd_ctl_notify(cs8427->bus->card,
 609                               SNDRV_CTL_EVENT_MASK_VALUE,
 610                               &chip->playback.pcm_ctl->id);
 611        reset = chip->rate != rate;
 612        chip->rate = rate;
 613        snd_i2c_unlock(cs8427->bus);
 614        if (reset)
 615                snd_cs8427_reset(cs8427);
 616        return err < 0 ? err : 0;
 617}
 618
 619EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
 620