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_7_9_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_7_9_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 << 1) | ((value >> 8) & 0x0001);
  37        data[1] = value & 0x00ff;
  38
  39        if (reg < codec->reg_cache_size)
  40                cache[reg] = value;
  41        ret = codec->hw_write(codec->control_data, data, 2);
  42        if (ret == 2)
  43                return 0;
  44        if (ret < 0)
  45                return ret;
  46        else
  47                return -EIO;
  48}
  49
  50#if defined(CONFIG_SPI_MASTER)
  51static int snd_soc_7_9_spi_write(void *control_data, const char *data,
  52                                 int len)
  53{
  54        struct spi_device *spi = control_data;
  55        struct spi_transfer t;
  56        struct spi_message m;
  57        u8 msg[2];
  58
  59        if (len <= 0)
  60                return 0;
  61
  62        msg[0] = data[0];
  63        msg[1] = data[1];
  64
  65        spi_message_init(&m);
  66        memset(&t, 0, (sizeof t));
  67
  68        t.tx_buf = &msg[0];
  69        t.len = len;
  70
  71        spi_message_add_tail(&t, &m);
  72        spi_sync(spi, &m);
  73
  74        return len;
  75}
  76#else
  77#define snd_soc_7_9_spi_write NULL
  78#endif
  79
  80static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
  81                              unsigned int value)
  82{
  83        u16 *reg_cache = codec->reg_cache;
  84        u8 data[3];
  85
  86        data[0] = reg;
  87        data[1] = (value >> 8) & 0xff;
  88        data[2] = value & 0xff;
  89
  90        if (!snd_soc_codec_volatile_register(codec, reg))
  91                reg_cache[reg] = value;
  92
  93        if (codec->hw_write(codec->control_data, data, 3) == 3)
  94                return 0;
  95        else
  96                return -EIO;
  97}
  98
  99static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
 100                                      unsigned int reg)
 101{
 102        u16 *cache = codec->reg_cache;
 103
 104        if (reg >= codec->reg_cache_size ||
 105            snd_soc_codec_volatile_register(codec, reg))
 106                return codec->hw_read(codec, reg);
 107        else
 108                return cache[reg];
 109}
 110
 111#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 112static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
 113                                          unsigned int r)
 114{
 115        struct i2c_msg xfer[2];
 116        u8 reg = r;
 117        u16 data;
 118        int ret;
 119        struct i2c_client *client = codec->control_data;
 120
 121        /* Write register */
 122        xfer[0].addr = client->addr;
 123        xfer[0].flags = 0;
 124        xfer[0].len = 1;
 125        xfer[0].buf = &reg;
 126
 127        /* Read data */
 128        xfer[1].addr = client->addr;
 129        xfer[1].flags = I2C_M_RD;
 130        xfer[1].len = 2;
 131        xfer[1].buf = (u8 *)&data;
 132
 133        ret = i2c_transfer(client->adapter, xfer, 2);
 134        if (ret != 2) {
 135                dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
 136                return 0;
 137        }
 138
 139        return (data >> 8) | ((data & 0xff) << 8);
 140}
 141#else
 142#define snd_soc_8_16_read_i2c NULL
 143#endif
 144
 145static struct {
 146        int addr_bits;
 147        int data_bits;
 148        int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
 149        int (*spi_write)(void *, const char *, int);
 150        unsigned int (*read)(struct snd_soc_codec *, unsigned int);
 151        unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
 152} io_types[] = {
 153        { 7, 9, snd_soc_7_9_write, snd_soc_7_9_spi_write, snd_soc_7_9_read },
 154        { 8, 16, snd_soc_8_16_write, NULL, snd_soc_8_16_read,
 155          snd_soc_8_16_read_i2c },
 156};
 157
 158/**
 159 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
 160 *
 161 * @codec: CODEC to configure.
 162 * @type: Type of cache.
 163 * @addr_bits: Number of bits of register address data.
 164 * @data_bits: Number of bits of data per register.
 165 * @control: Control bus used.
 166 *
 167 * Register formats are frequently shared between many I2C and SPI
 168 * devices.  In order to promote code reuse the ASoC core provides
 169 * some standard implementations of CODEC read and write operations
 170 * which can be set up using this function.
 171 *
 172 * The caller is responsible for allocating and initialising the
 173 * actual cache.
 174 *
 175 * Note that at present this code cannot be used by CODECs with
 176 * volatile registers.
 177 */
 178int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 179                               int addr_bits, int data_bits,
 180                               enum snd_soc_control_type control)
 181{
 182        int i;
 183
 184        for (i = 0; i < ARRAY_SIZE(io_types); i++)
 185                if (io_types[i].addr_bits == addr_bits &&
 186                    io_types[i].data_bits == data_bits)
 187                        break;
 188        if (i == ARRAY_SIZE(io_types)) {
 189                printk(KERN_ERR
 190                       "No I/O functions for %d bit address %d bit data\n",
 191                       addr_bits, data_bits);
 192                return -EINVAL;
 193        }
 194
 195        codec->write = io_types[i].write;
 196        codec->read = io_types[i].read;
 197
 198        switch (control) {
 199        case SND_SOC_CUSTOM:
 200                break;
 201
 202        case SND_SOC_I2C:
 203#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 204                codec->hw_write = (hw_write_t)i2c_master_send;
 205#endif
 206                if (io_types[i].i2c_read)
 207                        codec->hw_read = io_types[i].i2c_read;
 208                break;
 209
 210        case SND_SOC_SPI:
 211                if (io_types[i].spi_write)
 212                        codec->hw_write = io_types[i].spi_write;
 213                break;
 214        }
 215
 216        return 0;
 217}
 218EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
 219