aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/soc-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r--sound/soc/soc-cache.c797
1 files changed, 137 insertions, 660 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d214f02cbb6..00e70b6c7da 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -11,716 +11,193 @@
* option) any later version.
*/
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
#include <sound/soc.h>
+#include <linux/export.h>
+#include <linux/slab.h>
-static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
-
- return codec->hw_read(codec, reg);
- }
-
- return cache[reg];
-}
-
-static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u16 *cache = codec->reg_cache;
- u8 data[2];
- int ret;
-
- data[0] = (reg << 4) | ((value >> 8) & 0x000f);
- data[1] = value & 0x00ff;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
- }
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- ret = codec->hw_write(codec->control_data, data, 2);
- if (ret == 2)
- return 0;
- if (ret < 0)
- return ret;
- else
- return -EIO;
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_4_12_spi_write(void *control_data, const char *data,
- int len)
-{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[2];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[1];
- msg[1] = data[0];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-#else
-#define snd_soc_4_12_spi_write NULL
-#endif
-
-static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
-
- return codec->hw_read(codec, reg);
- }
-
- return cache[reg];
-}
-
-static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u16 *cache = codec->reg_cache;
- u8 data[2];
- int ret;
-
- data[0] = (reg << 1) | ((value >> 8) & 0x0001);
- data[1] = value & 0x00ff;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
- }
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- ret = codec->hw_write(codec->control_data, data, 2);
- if (ret == 2)
- return 0;
- if (ret < 0)
- return ret;
- else
- return -EIO;
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_7_9_spi_write(void *control_data, const char *data,
- int len)
-{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[2];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
+#include <trace/events/asoc.h>
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-#else
-#define snd_soc_7_9_spi_write NULL
-#endif
-
-static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
+static bool snd_soc_set_cache_val(void *base, unsigned int idx,
+ unsigned int val, unsigned int word_size)
{
- u8 *cache = codec->reg_cache;
- u8 data[2];
-
- reg &= 0xff;
- data[0] = reg;
- data[1] = value & 0xff;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
+ switch (word_size) {
+ case 1: {
+ u8 *cache = base;
+ if (cache[idx] == val)
+ return true;
+ cache[idx] = val;
+ break;
}
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- if (codec->hw_write(codec->control_data, data, 2) == 2)
- return 0;
- else
- return -EIO;
-}
-
-static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *cache = codec->reg_cache;
-
- reg &= 0xff;
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
-
- return codec->hw_read(codec, reg);
+ case 2: {
+ u16 *cache = base;
+ if (cache[idx] == val)
+ return true;
+ cache[idx] = val;
+ break;
}
-
- return cache[reg];
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_8_8_spi_write(void *control_data, const char *data,
- int len)
-{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[2];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-#else
-#define snd_soc_8_8_spi_write NULL
-#endif
-
-static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u16 *reg_cache = codec->reg_cache;
- u8 data[3];
-
- data[0] = reg;
- data[1] = (value >> 8) & 0xff;
- data[2] = value & 0xff;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- reg_cache[reg] = value;
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
+ default:
+ WARN(1, "Invalid word_size %d\n", word_size);
+ break;
}
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- if (codec->hw_write(codec->control_data, data, 3) == 3)
- return 0;
- else
- return -EIO;
+ return false;
}
-static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
- unsigned int reg)
+static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
+ unsigned int word_size)
{
- u16 *cache = codec->reg_cache;
+ if (!base)
+ return -1;
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
-
- return codec->hw_read(codec, reg);
- } else {
- return cache[reg];
+ switch (word_size) {
+ case 1: {
+ const u8 *cache = base;
+ return cache[idx];
}
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_8_16_spi_write(void *control_data, const char *data,
- int len)
-{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[3];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
- msg[2] = data[2];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-#else
-#define snd_soc_8_16_spi_write NULL
-#endif
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
- unsigned int r)
-{
- struct i2c_msg xfer[2];
- u8 reg = r;
- u8 data;
- int ret;
- struct i2c_client *client = codec->control_data;
-
- /* Write register */
- xfer[0].addr = client->addr;
- xfer[0].flags = 0;
- xfer[0].len = 1;
- xfer[0].buf = &reg;
-
- /* Read data */
- xfer[1].addr = client->addr;
- xfer[1].flags = I2C_M_RD;
- xfer[1].len = 1;
- xfer[1].buf = &data;
-
- ret = i2c_transfer(client->adapter, xfer, 2);
- if (ret != 2) {
- dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
- return 0;
+ case 2: {
+ const u16 *cache = base;
+ return cache[idx];
}
-
- return data;
-}
-#else
-#define snd_soc_8_8_read_i2c NULL
-#endif
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
- unsigned int r)
-{
- struct i2c_msg xfer[2];
- u8 reg = r;
- u16 data;
- int ret;
- struct i2c_client *client = codec->control_data;
-
- /* Write register */
- xfer[0].addr = client->addr;
- xfer[0].flags = 0;
- xfer[0].len = 1;
- xfer[0].buf = &reg;
-
- /* Read data */
- xfer[1].addr = client->addr;
- xfer[1].flags = I2C_M_RD;
- xfer[1].len = 2;
- xfer[1].buf = (u8 *)&data;
-
- ret = i2c_transfer(client->adapter, xfer, 2);
- if (ret != 2) {
- dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
- return 0;
+ default:
+ WARN(1, "Invalid word_size %d\n", word_size);
+ break;
}
-
- return (data >> 8) | ((data & 0xff) << 8);
+ /* unreachable */
+ return -1;
}
-#else
-#define snd_soc_8_16_read_i2c NULL
-#endif
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
- unsigned int r)
+int snd_soc_cache_init(struct snd_soc_codec *codec)
{
- struct i2c_msg xfer[2];
- u16 reg = r;
- u8 data;
- int ret;
- struct i2c_client *client = codec->control_data;
-
- /* Write register */
- xfer[0].addr = client->addr;
- xfer[0].flags = 0;
- xfer[0].len = 2;
- xfer[0].buf = (u8 *)&reg;
+ const struct snd_soc_codec_driver *codec_drv = codec->driver;
+ size_t reg_size;
- /* Read data */
- xfer[1].addr = client->addr;
- xfer[1].flags = I2C_M_RD;
- xfer[1].len = 1;
- xfer[1].buf = &data;
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
- ret = i2c_transfer(client->adapter, xfer, 2);
- if (ret != 2) {
- dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
+ if (!reg_size)
return 0;
- }
-
- return data;
-}
-#else
-#define snd_soc_16_8_read_i2c NULL
-#endif
-
-static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u8 *cache = codec->reg_cache;
-
- reg &= 0xff;
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
- return codec->hw_read(codec, reg);
- }
-
- return cache[reg];
-}
-
-static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
-{
- u8 *cache = codec->reg_cache;
- u8 data[3];
- int ret;
-
- data[0] = (reg >> 8) & 0xff;
- data[1] = reg & 0xff;
- data[2] = value;
+ mutex_init(&codec->cache_rw_mutex);
- reg &= 0xff;
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
+ dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
+ codec->name);
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
- }
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- ret = codec->hw_write(codec->control_data, data, 3);
- if (ret == 3)
- return 0;
- if (ret < 0)
- return ret;
+ if (codec_drv->reg_cache_default)
+ codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
else
- return -EIO;
+ codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
+ if (!codec->reg_cache)
+ return -ENOMEM;
+
+ return 0;
}
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_16_8_spi_write(void *control_data, const char *data,
- int len)
+/*
+ * NOTE: keep in mind that this function might be called
+ * multiple times.
+ */
+int snd_soc_cache_exit(struct snd_soc_codec *codec)
{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[3];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
- msg[2] = data[2];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
+ dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
+ codec->name);
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+ return 0;
}
-#else
-#define snd_soc_16_8_spi_write NULL
-#endif
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
- unsigned int r)
+/**
+ * snd_soc_cache_read: Fetch the value of a given register from the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The value to be returned.
+ */
+int snd_soc_cache_read(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int *value)
{
- struct i2c_msg xfer[2];
- u16 reg = cpu_to_be16(r);
- u16 data;
- int ret;
- struct i2c_client *client = codec->control_data;
-
- /* Write register */
- xfer[0].addr = client->addr;
- xfer[0].flags = 0;
- xfer[0].len = 2;
- xfer[0].buf = (u8 *)&reg;
+ if (!value)
+ return -EINVAL;
- /* Read data */
- xfer[1].addr = client->addr;
- xfer[1].flags = I2C_M_RD;
- xfer[1].len = 2;
- xfer[1].buf = (u8 *)&data;
+ mutex_lock(&codec->cache_rw_mutex);
+ if (!ZERO_OR_NULL_PTR(codec->reg_cache))
+ *value = snd_soc_get_cache_val(codec->reg_cache, reg,
+ codec->driver->reg_word_size);
+ mutex_unlock(&codec->cache_rw_mutex);
- ret = i2c_transfer(client->adapter, xfer, 2);
- if (ret != 2) {
- dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
- return 0;
- }
-
- return be16_to_cpu(data);
+ return 0;
}
-#else
-#define snd_soc_16_16_read_i2c NULL
-#endif
+EXPORT_SYMBOL_GPL(snd_soc_cache_read);
-static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
- unsigned int reg)
+/**
+ * snd_soc_cache_write: Set the value of a given register in the cache.
+ *
+ * @codec: CODEC to configure.
+ * @reg: The register index.
+ * @value: The new register value.
+ */
+int snd_soc_cache_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
{
- u16 *cache = codec->reg_cache;
-
- if (reg >= codec->driver->reg_cache_size ||
- snd_soc_codec_volatile_register(codec, reg)) {
- if (codec->cache_only)
- return -1;
-
- return codec->hw_read(codec, reg);
- }
+ mutex_lock(&codec->cache_rw_mutex);
+ if (!ZERO_OR_NULL_PTR(codec->reg_cache))
+ snd_soc_set_cache_val(codec->reg_cache, reg, value,
+ codec->driver->reg_word_size);
+ mutex_unlock(&codec->cache_rw_mutex);
- return cache[reg];
+ return 0;
}
+EXPORT_SYMBOL_GPL(snd_soc_cache_write);
-static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
+static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
{
- u16 *cache = codec->reg_cache;
- u8 data[4];
+ int i;
int ret;
-
- data[0] = (reg >> 8) & 0xff;
- data[1] = reg & 0xff;
- data[2] = (value >> 8) & 0xff;
- data[3] = value & 0xff;
-
- if (!snd_soc_codec_volatile_register(codec, reg) &&
- reg < codec->driver->reg_cache_size)
- cache[reg] = value;
-
- if (codec->cache_only) {
- codec->cache_sync = 1;
- return 0;
+ const struct snd_soc_codec_driver *codec_drv;
+ unsigned int val;
+
+ codec_drv = codec->driver;
+ for (i = 0; i < codec_drv->reg_cache_size; ++i) {
+ ret = snd_soc_cache_read(codec, i, &val);
+ if (ret)
+ return ret;
+ if (codec_drv->reg_cache_default)
+ if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
+ i, codec_drv->reg_word_size) == val)
+ continue;
+
+ ret = snd_soc_write(codec, i, val);
+ if (ret)
+ return ret;
+ dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
+ i, val);
}
-
- dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
-
- ret = codec->hw_write(codec->control_data, data, 4);
- if (ret == 4)
- return 0;
- if (ret < 0)
- return ret;
- else
- return -EIO;
-}
-
-#if defined(CONFIG_SPI_MASTER)
-static int snd_soc_16_16_spi_write(void *control_data, const char *data,
- int len)
-{
- struct spi_device *spi = control_data;
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[4];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
- msg[2] = data[2];
- msg[3] = data[3];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
+ return 0;
}
-#else
-#define snd_soc_16_16_spi_write NULL
-#endif
-
-static struct {
- int addr_bits;
- int data_bits;
- int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
- int (*spi_write)(void *, const char *, int);
- unsigned int (*read)(struct snd_soc_codec *, unsigned int);
- unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
-} io_types[] = {
- {
- .addr_bits = 4, .data_bits = 12,
- .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
- .spi_write = snd_soc_4_12_spi_write,
- },
- {
- .addr_bits = 7, .data_bits = 9,
- .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
- .spi_write = snd_soc_7_9_spi_write,
- },
- {
- .addr_bits = 8, .data_bits = 8,
- .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
- .i2c_read = snd_soc_8_8_read_i2c,
- .spi_write = snd_soc_8_8_spi_write,
- },
- {
- .addr_bits = 8, .data_bits = 16,
- .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
- .i2c_read = snd_soc_8_16_read_i2c,
- .spi_write = snd_soc_8_16_spi_write,
- },
- {
- .addr_bits = 16, .data_bits = 8,
- .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
- .i2c_read = snd_soc_16_8_read_i2c,
- .spi_write = snd_soc_16_8_spi_write,
- },
- {
- .addr_bits = 16, .data_bits = 16,
- .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
- .i2c_read = snd_soc_16_16_read_i2c,
- .spi_write = snd_soc_16_16_spi_write,
- },
-};
/**
- * snd_soc_codec_set_cache_io: Set up standard I/O functions.
+ * snd_soc_cache_sync: Sync the register cache with the hardware.
*
* @codec: CODEC to configure.
- * @type: Type of cache.
- * @addr_bits: Number of bits of register address data.
- * @data_bits: Number of bits of data per register.
- * @control: Control bus used.
- *
- * Register formats are frequently shared between many I2C and SPI
- * devices. In order to promote code reuse the ASoC core provides
- * some standard implementations of CODEC read and write operations
- * which can be set up using this function.
- *
- * The caller is responsible for allocating and initialising the
- * actual cache.
*
- * Note that at present this code cannot be used by CODECs with
- * volatile registers.
+ * Any registers that should not be synced should be marked as
+ * volatile. In general drivers can choose not to use the provided
+ * syncing functionality if they so require.
*/
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
+int snd_soc_cache_sync(struct snd_soc_codec *codec)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(io_types); i++)
- if (io_types[i].addr_bits == addr_bits &&
- io_types[i].data_bits == data_bits)
- break;
- if (i == ARRAY_SIZE(io_types)) {
- printk(KERN_ERR
- "No I/O functions for %d bit address %d bit data\n",
- addr_bits, data_bits);
- return -EINVAL;
- }
-
- codec->driver->write = io_types[i].write;
- codec->driver->read = io_types[i].read;
-
- switch (control) {
- case SND_SOC_CUSTOM:
- break;
-
- case SND_SOC_I2C:
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
- codec->hw_write = (hw_write_t)i2c_master_send;
-#endif
- if (io_types[i].i2c_read)
- codec->hw_read = io_types[i].i2c_read;
-
- codec->control_data = container_of(codec->dev,
- struct i2c_client,
- dev);
- break;
-
- case SND_SOC_SPI:
- if (io_types[i].spi_write)
- codec->hw_write = io_types[i].spi_write;
+ const char *name = "flat";
+ int ret;
- codec->control_data = container_of(codec->dev,
- struct spi_device,
- dev);
- break;
- }
+ if (!codec->cache_sync)
+ return 0;
- return 0;
+ dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
+ codec->name);
+ trace_snd_soc_cache_sync(codec, name, "start");
+ ret = snd_soc_flat_cache_sync(codec);
+ if (!ret)
+ codec->cache_sync = 0;
+ trace_snd_soc_cache_sync(codec, name, "end");
+ return ret;
}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+EXPORT_SYMBOL_GPL(snd_soc_cache_sync);