linux/sound/soc/soc-cache.c
<<
>>
Prefs
   1/*
   2 * soc-cache.c  --  ASoC register cache helpers
   3 *
   4 * Copyright 2009 Wolfson Microelectronics PLC.
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 *  This program is free software; you can redistribute  it and/or modify it
   9 *  under  the terms of  the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the  License, or (at your
  11 *  option) any later version.
  12 */
  13
  14#include <linux/i2c.h>
  15#include <linux/spi/spi.h>
  16#include <sound/soc.h>
  17
  18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
  19                                     unsigned int reg)
  20{
  21        u16 *cache = codec->reg_cache;
  22        if (reg >= codec->reg_cache_size)
  23                return -1;
  24        return cache[reg];
  25}
  26
  27static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
  28                             unsigned int value)
  29{
  30        u16 *cache = codec->reg_cache;
  31        u8 data[2];
  32        int ret;
  33
  34        BUG_ON(codec->volatile_register);
  35
  36        data[0] = (reg << 4) | ((value >> 8) & 0x000f);
  37        data[1] = value & 0x00ff;
  38
  39        if (reg < codec->reg_cache_size)
  40                cache[reg] = value;
  41
  42        if (codec->cache_only) {
  43                codec->cache_sync = 1;
  44                return 0;
  45        }
  46
  47        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
  48
  49        ret = codec->hw_write(codec->control_data, data, 2);
  50        if (ret == 2)
  51                return 0;
  52        if (ret < 0)
  53                return ret;
  54        else
  55                return -EIO;
  56}
  57
  58#if defined(CONFIG_SPI_MASTER)
  59static int snd_soc_4_12_spi_write(void *control_data, const char *data,
  60                                 int len)
  61{
  62        struct spi_device *spi = control_data;
  63        struct spi_transfer t;
  64        struct spi_message m;
  65        u8 msg[2];
  66
  67        if (len <= 0)
  68                return 0;
  69
  70        msg[0] = data[1];
  71        msg[1] = data[0];
  72
  73        spi_message_init(&m);
  74        memset(&t, 0, (sizeof t));
  75
  76        t.tx_buf = &msg[0];
  77        t.len = len;
  78
  79        spi_message_add_tail(&t, &m);
  80        spi_sync(spi, &m);
  81
  82        return len;
  83}
  84#else
  85#define snd_soc_4_12_spi_write NULL
  86#endif
  87
  88static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
  89                                     unsigned int reg)
  90{
  91        u16 *cache = codec->reg_cache;
  92        if (reg >= codec->reg_cache_size)
  93                return -1;
  94        return cache[reg];
  95}
  96
  97static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
  98                             unsigned int value)
  99{
 100        u16 *cache = codec->reg_cache;
 101        u8 data[2];
 102        int ret;
 103
 104        BUG_ON(codec->volatile_register);
 105
 106        data[0] = (reg << 1) | ((value >> 8) & 0x0001);
 107        data[1] = value & 0x00ff;
 108
 109        if (reg < codec->reg_cache_size)
 110                cache[reg] = value;
 111
 112        if (codec->cache_only) {
 113                codec->cache_sync = 1;
 114                return 0;
 115        }
 116
 117        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
 118
 119        ret = codec->hw_write(codec->control_data, data, 2);
 120        if (ret == 2)
 121                return 0;
 122        if (ret < 0)
 123                return ret;
 124        else
 125                return -EIO;
 126}
 127
 128#if defined(CONFIG_SPI_MASTER)
 129static int snd_soc_7_9_spi_write(void *control_data, const char *data,
 130                                 int len)
 131{
 132        struct spi_device *spi = control_data;
 133        struct spi_transfer t;
 134        struct spi_message m;
 135        u8 msg[2];
 136
 137        if (len <= 0)
 138                return 0;
 139
 140        msg[0] = data[0];
 141        msg[1] = data[1];
 142
 143        spi_message_init(&m);
 144        memset(&t, 0, (sizeof t));
 145
 146        t.tx_buf = &msg[0];
 147        t.len = len;
 148
 149        spi_message_add_tail(&t, &m);
 150        spi_sync(spi, &m);
 151
 152        return len;
 153}
 154#else
 155#define snd_soc_7_9_spi_write NULL
 156#endif
 157
 158static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
 159                             unsigned int value)
 160{
 161        u8 *cache = codec->reg_cache;
 162        u8 data[2];
 163
 164        BUG_ON(codec->volatile_register);
 165
 166        reg &= 0xff;
 167        data[0] = reg;
 168        data[1] = value & 0xff;
 169
 170        if (reg < codec->reg_cache_size)
 171                cache[reg] = value;
 172
 173        if (codec->cache_only) {
 174                codec->cache_sync = 1;
 175                return 0;
 176        }
 177
 178        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
 179
 180        if (codec->hw_write(codec->control_data, data, 2) == 2)
 181                return 0;
 182        else
 183                return -EIO;
 184}
 185
 186static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
 187                                     unsigned int reg)
 188{
 189        u8 *cache = codec->reg_cache;
 190        reg &= 0xff;
 191        if (reg >= codec->reg_cache_size)
 192                return -1;
 193        return cache[reg];
 194}
 195
 196static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
 197                              unsigned int value)
 198{
 199        u16 *reg_cache = codec->reg_cache;
 200        u8 data[3];
 201
 202        data[0] = reg;
 203        data[1] = (value >> 8) & 0xff;
 204        data[2] = value & 0xff;
 205
 206        if (!snd_soc_codec_volatile_register(codec, reg))
 207                reg_cache[reg] = value;
 208
 209        if (codec->cache_only) {
 210                codec->cache_sync = 1;
 211                return 0;
 212        }
 213
 214        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
 215
 216        if (codec->hw_write(codec->control_data, data, 3) == 3)
 217                return 0;
 218        else
 219                return -EIO;
 220}
 221
 222static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
 223                                      unsigned int reg)
 224{
 225        u16 *cache = codec->reg_cache;
 226
 227        if (reg >= codec->reg_cache_size ||
 228            snd_soc_codec_volatile_register(codec, reg)) {
 229                if (codec->cache_only)
 230                        return -EINVAL;
 231
 232                return codec->hw_read(codec, reg);
 233        } else {
 234                return cache[reg];
 235        }
 236}
 237
 238#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 239static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
 240                                          unsigned int r)
 241{
 242        struct i2c_msg xfer[2];
 243        u8 reg = r;
 244        u8 data;
 245        int ret;
 246        struct i2c_client *client = codec->control_data;
 247
 248        /* Write register */
 249        xfer[0].addr = client->addr;
 250        xfer[0].flags = 0;
 251        xfer[0].len = 1;
 252        xfer[0].buf = &reg;
 253
 254        /* Read data */
 255        xfer[1].addr = client->addr;
 256        xfer[1].flags = I2C_M_RD;
 257        xfer[1].len = 1;
 258        xfer[1].buf = &data;
 259
 260        ret = i2c_transfer(client->adapter, xfer, 2);
 261        if (ret != 2) {
 262                dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
 263                return 0;
 264        }
 265
 266        return data;
 267}
 268#else
 269#define snd_soc_8_8_read_i2c NULL
 270#endif
 271
 272#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 273static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
 274                                          unsigned int r)
 275{
 276        struct i2c_msg xfer[2];
 277        u8 reg = r;
 278        u16 data;
 279        int ret;
 280        struct i2c_client *client = codec->control_data;
 281
 282        /* Write register */
 283        xfer[0].addr = client->addr;
 284        xfer[0].flags = 0;
 285        xfer[0].len = 1;
 286        xfer[0].buf = &reg;
 287
 288        /* Read data */
 289        xfer[1].addr = client->addr;
 290        xfer[1].flags = I2C_M_RD;
 291        xfer[1].len = 2;
 292        xfer[1].buf = (u8 *)&data;
 293
 294        ret = i2c_transfer(client->adapter, xfer, 2);
 295        if (ret != 2) {
 296                dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
 297                return 0;
 298        }
 299
 300        return (data >> 8) | ((data & 0xff) << 8);
 301}
 302#else
 303#define snd_soc_8_16_read_i2c NULL
 304#endif
 305
 306#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 307static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
 308                                          unsigned int r)
 309{
 310        struct i2c_msg xfer[2];
 311        u16 reg = r;
 312        u8 data;
 313        int ret;
 314        struct i2c_client *client = codec->control_data;
 315
 316        /* Write register */
 317        xfer[0].addr = client->addr;
 318        xfer[0].flags = 0;
 319        xfer[0].len = 2;
 320        xfer[0].buf = (u8 *)&reg;
 321
 322        /* Read data */
 323        xfer[1].addr = client->addr;
 324        xfer[1].flags = I2C_M_RD;
 325        xfer[1].len = 1;
 326        xfer[1].buf = &data;
 327
 328        ret = i2c_transfer(client->adapter, xfer, 2);
 329        if (ret != 2) {
 330                dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
 331                return 0;
 332        }
 333
 334        return data;
 335}
 336#else
 337#define snd_soc_16_8_read_i2c NULL
 338#endif
 339
 340static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
 341                                     unsigned int reg)
 342{
 343        u8 *cache = codec->reg_cache;
 344
 345        reg &= 0xff;
 346        if (reg >= codec->reg_cache_size)
 347                return -1;
 348        return cache[reg];
 349}
 350
 351static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
 352                             unsigned int value)
 353{
 354        u8 *cache = codec->reg_cache;
 355        u8 data[3];
 356        int ret;
 357
 358        BUG_ON(codec->volatile_register);
 359
 360        data[0] = (reg >> 8) & 0xff;
 361        data[1] = reg & 0xff;
 362        data[2] = value;
 363
 364        reg &= 0xff;
 365        if (reg < codec->reg_cache_size)
 366                cache[reg] = value;
 367
 368        if (codec->cache_only) {
 369                codec->cache_sync = 1;
 370                return 0;
 371        }
 372
 373        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
 374
 375        ret = codec->hw_write(codec->control_data, data, 3);
 376        if (ret == 3)
 377                return 0;
 378        if (ret < 0)
 379                return ret;
 380        else
 381                return -EIO;
 382}
 383
 384#if defined(CONFIG_SPI_MASTER)
 385static int snd_soc_16_8_spi_write(void *control_data, const char *data,
 386                                 int len)
 387{
 388        struct spi_device *spi = control_data;
 389        struct spi_transfer t;
 390        struct spi_message m;
 391        u8 msg[3];
 392
 393        if (len <= 0)
 394                return 0;
 395
 396        msg[0] = data[0];
 397        msg[1] = data[1];
 398        msg[2] = data[2];
 399
 400        spi_message_init(&m);
 401        memset(&t, 0, (sizeof t));
 402
 403        t.tx_buf = &msg[0];
 404        t.len = len;
 405
 406        spi_message_add_tail(&t, &m);
 407        spi_sync(spi, &m);
 408
 409        return len;
 410}
 411#else
 412#define snd_soc_16_8_spi_write NULL
 413#endif
 414
 415#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 416static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
 417                                           unsigned int r)
 418{
 419        struct i2c_msg xfer[2];
 420        u16 reg = cpu_to_be16(r);
 421        u16 data;
 422        int ret;
 423        struct i2c_client *client = codec->control_data;
 424
 425        /* Write register */
 426        xfer[0].addr = client->addr;
 427        xfer[0].flags = 0;
 428        xfer[0].len = 2;
 429        xfer[0].buf = (u8 *)&reg;
 430
 431        /* Read data */
 432        xfer[1].addr = client->addr;
 433        xfer[1].flags = I2C_M_RD;
 434        xfer[1].len = 2;
 435        xfer[1].buf = (u8 *)&data;
 436
 437        ret = i2c_transfer(client->adapter, xfer, 2);
 438        if (ret != 2) {
 439                dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
 440                return 0;
 441        }
 442
 443        return be16_to_cpu(data);
 444}
 445#else
 446#define snd_soc_16_16_read_i2c NULL
 447#endif
 448
 449static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
 450                                       unsigned int reg)
 451{
 452        u16 *cache = codec->reg_cache;
 453
 454        if (reg >= codec->reg_cache_size ||
 455            snd_soc_codec_volatile_register(codec, reg)) {
 456                if (codec->cache_only)
 457                        return -EINVAL;
 458
 459                return codec->hw_read(codec, reg);
 460        }
 461
 462        return cache[reg];
 463}
 464
 465static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
 466                               unsigned int value)
 467{
 468        u16 *cache = codec->reg_cache;
 469        u8 data[4];
 470        int ret;
 471
 472        data[0] = (reg >> 8) & 0xff;
 473        data[1] = reg & 0xff;
 474        data[2] = (value >> 8) & 0xff;
 475        data[3] = value & 0xff;
 476
 477        if (reg < codec->reg_cache_size)
 478                cache[reg] = value;
 479
 480        if (codec->cache_only) {
 481                codec->cache_sync = 1;
 482                return 0;
 483        }
 484
 485        dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
 486
 487        ret = codec->hw_write(codec->control_data, data, 4);
 488        if (ret == 4)
 489                return 0;
 490        if (ret < 0)
 491                return ret;
 492        else
 493                return -EIO;
 494}
 495
 496static struct {
 497        int addr_bits;
 498        int data_bits;
 499        int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
 500        int (*spi_write)(void *, const char *, int);
 501        unsigned int (*read)(struct snd_soc_codec *, unsigned int);
 502        unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
 503} io_types[] = {
 504        {
 505                .addr_bits = 4, .data_bits = 12,
 506                .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
 507                .spi_write = snd_soc_4_12_spi_write,
 508        },
 509        {
 510                .addr_bits = 7, .data_bits = 9,
 511                .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
 512                .spi_write = snd_soc_7_9_spi_write,
 513        },
 514        {
 515                .addr_bits = 8, .data_bits = 8,
 516                .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
 517                .i2c_read = snd_soc_8_8_read_i2c,
 518        },
 519        {
 520                .addr_bits = 8, .data_bits = 16,
 521                .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
 522                .i2c_read = snd_soc_8_16_read_i2c,
 523        },
 524        {
 525                .addr_bits = 16, .data_bits = 8,
 526                .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
 527                .i2c_read = snd_soc_16_8_read_i2c,
 528                .spi_write = snd_soc_16_8_spi_write,
 529        },
 530        {
 531                .addr_bits = 16, .data_bits = 16,
 532                .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
 533                .i2c_read = snd_soc_16_16_read_i2c,
 534        },
 535};
 536
 537/**
 538 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
 539 *
 540 * @codec: CODEC to configure.
 541 * @type: Type of cache.
 542 * @addr_bits: Number of bits of register address data.
 543 * @data_bits: Number of bits of data per register.
 544 * @control: Control bus used.
 545 *
 546 * Register formats are frequently shared between many I2C and SPI
 547 * devices.  In order to promote code reuse the ASoC core provides
 548 * some standard implementations of CODEC read and write operations
 549 * which can be set up using this function.
 550 *
 551 * The caller is responsible for allocating and initialising the
 552 * actual cache.
 553 *
 554 * Note that at present this code cannot be used by CODECs with
 555 * volatile registers.
 556 */
 557int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 558                               int addr_bits, int data_bits,
 559                               enum snd_soc_control_type control)
 560{
 561        int i;
 562
 563        for (i = 0; i < ARRAY_SIZE(io_types); i++)
 564                if (io_types[i].addr_bits == addr_bits &&
 565                    io_types[i].data_bits == data_bits)
 566                        break;
 567        if (i == ARRAY_SIZE(io_types)) {
 568                printk(KERN_ERR
 569                       "No I/O functions for %d bit address %d bit data\n",
 570                       addr_bits, data_bits);
 571                return -EINVAL;
 572        }
 573
 574        codec->write = io_types[i].write;
 575        codec->read = io_types[i].read;
 576
 577        switch (control) {
 578        case SND_SOC_CUSTOM:
 579                break;
 580
 581        case SND_SOC_I2C:
 582#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 583                codec->hw_write = (hw_write_t)i2c_master_send;
 584#endif
 585                if (io_types[i].i2c_read)
 586                        codec->hw_read = io_types[i].i2c_read;
 587                break;
 588
 589        case SND_SOC_SPI:
 590                if (io_types[i].spi_write)
 591                        codec->hw_write = io_types[i].spi_write;
 592                break;
 593        }
 594
 595        return 0;
 596}
 597EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
 598
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.