linux/sound/i2c/cs8427.c
<<
>>
Prefs
   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
  35static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
  36
  37MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  38MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
  39MODULE_LICENSE("GPL");
  40
  41#define CS8427_ADDR                     (0x20>>1) /* fixed address */
  42
  43struct 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
  52struct 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
  60int 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
  76EXPORT_SYMBOL(snd_cs8427_reg_write);
  77
  78static 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
  96static 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
 113static 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
 148static void snd_cs8427_free(struct snd_i2c_device *device)
 149{
 150        kfree(device->private_data);
 151}
 152
 153int 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
 294EXPORT_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 */
 301static 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
 341static 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
 351static 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
 366static 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
 374static 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
 399static 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
 407static 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
 419static 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
 443static 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
 451static 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
 458static 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
 511int 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
 543EXPORT_SYMBOL(snd_cs8427_iec958_build);
 544
 545int 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
 562EXPORT_SYMBOL(snd_cs8427_iec958_active);
 563
 564int 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
 604EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
 605
 606static int __init alsa_cs8427_module_init(void)
 607{
 608        return 0;
 609}
 610
 611static void __exit alsa_cs8427_module_exit(void)
 612{
 613}
 614
 615module_init(alsa_cs8427_module_init)
 616module_exit(alsa_cs8427_module_exit)
 617
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.