mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-13 12:53:27 +00:00
Merge remote-tracking branch 'asoc/topic/core' into asoc-next
This commit is contained in:
commit
d6ee232c7f
@ -331,7 +331,6 @@ struct soc_enum;
|
|||||||
struct snd_soc_jack;
|
struct snd_soc_jack;
|
||||||
struct snd_soc_jack_zone;
|
struct snd_soc_jack_zone;
|
||||||
struct snd_soc_jack_pin;
|
struct snd_soc_jack_pin;
|
||||||
struct snd_soc_cache_ops;
|
|
||||||
#include <sound/soc-dapm.h>
|
#include <sound/soc-dapm.h>
|
||||||
#include <sound/soc-dpcm.h>
|
#include <sound/soc-dpcm.h>
|
||||||
|
|
||||||
@ -349,10 +348,6 @@ enum snd_soc_control_type {
|
|||||||
SND_SOC_REGMAP,
|
SND_SOC_REGMAP,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum snd_soc_compress_type {
|
|
||||||
SND_SOC_FLAT_COMPRESSION = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum snd_soc_pcm_subclass {
|
enum snd_soc_pcm_subclass {
|
||||||
SND_SOC_PCM_CLASS_PCM = 0,
|
SND_SOC_PCM_CLASS_PCM = 0,
|
||||||
SND_SOC_PCM_CLASS_BE = 1,
|
SND_SOC_PCM_CLASS_BE = 1,
|
||||||
@ -404,12 +399,6 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
|
|||||||
unsigned int reg, unsigned int value);
|
unsigned int reg, unsigned int value);
|
||||||
int snd_soc_cache_read(struct snd_soc_codec *codec,
|
int snd_soc_cache_read(struct snd_soc_codec *codec,
|
||||||
unsigned int reg, unsigned int *value);
|
unsigned int reg, unsigned int *value);
|
||||||
int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg);
|
|
||||||
int snd_soc_default_readable_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg);
|
|
||||||
int snd_soc_default_writable_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg);
|
|
||||||
int snd_soc_platform_read(struct snd_soc_platform *platform,
|
int snd_soc_platform_read(struct snd_soc_platform *platform,
|
||||||
unsigned int reg);
|
unsigned int reg);
|
||||||
int snd_soc_platform_write(struct snd_soc_platform *platform,
|
int snd_soc_platform_write(struct snd_soc_platform *platform,
|
||||||
@ -542,22 +531,6 @@ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
|
|||||||
int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
|
int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol);
|
struct snd_ctl_elem_value *ucontrol);
|
||||||
|
|
||||||
/**
|
|
||||||
* struct snd_soc_reg_access - Describes whether a given register is
|
|
||||||
* readable, writable or volatile.
|
|
||||||
*
|
|
||||||
* @reg: the register number
|
|
||||||
* @read: whether this register is readable
|
|
||||||
* @write: whether this register is writable
|
|
||||||
* @vol: whether this register is volatile
|
|
||||||
*/
|
|
||||||
struct snd_soc_reg_access {
|
|
||||||
u16 reg;
|
|
||||||
u16 read;
|
|
||||||
u16 write;
|
|
||||||
u16 vol;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct snd_soc_jack_pin - Describes a pin to update based on jack detection
|
* struct snd_soc_jack_pin - Describes a pin to update based on jack detection
|
||||||
*
|
*
|
||||||
@ -658,19 +631,6 @@ struct snd_soc_compr_ops {
|
|||||||
int (*trigger)(struct snd_compr_stream *);
|
int (*trigger)(struct snd_compr_stream *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SoC cache ops */
|
|
||||||
struct snd_soc_cache_ops {
|
|
||||||
const char *name;
|
|
||||||
enum snd_soc_compress_type id;
|
|
||||||
int (*init)(struct snd_soc_codec *codec);
|
|
||||||
int (*exit)(struct snd_soc_codec *codec);
|
|
||||||
int (*read)(struct snd_soc_codec *codec, unsigned int reg,
|
|
||||||
unsigned int *value);
|
|
||||||
int (*write)(struct snd_soc_codec *codec, unsigned int reg,
|
|
||||||
unsigned int value);
|
|
||||||
int (*sync)(struct snd_soc_codec *codec);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* component interface */
|
/* component interface */
|
||||||
struct snd_soc_component_driver {
|
struct snd_soc_component_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -684,10 +644,12 @@ struct snd_soc_component_driver {
|
|||||||
struct snd_soc_component {
|
struct snd_soc_component {
|
||||||
const char *name;
|
const char *name;
|
||||||
int id;
|
int id;
|
||||||
int num_dai;
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
|
struct snd_soc_dai_driver *dai_drv;
|
||||||
|
int num_dai;
|
||||||
|
|
||||||
const struct snd_soc_component_driver *driver;
|
const struct snd_soc_component_driver *driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -704,8 +666,6 @@ struct snd_soc_codec {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct list_head card_list;
|
struct list_head card_list;
|
||||||
int num_dai;
|
int num_dai;
|
||||||
enum snd_soc_compress_type compress_type;
|
|
||||||
size_t reg_size; /* reg_cache_size * reg_word_size */
|
|
||||||
int (*volatile_register)(struct snd_soc_codec *, unsigned int);
|
int (*volatile_register)(struct snd_soc_codec *, unsigned int);
|
||||||
int (*readable_register)(struct snd_soc_codec *, unsigned int);
|
int (*readable_register)(struct snd_soc_codec *, unsigned int);
|
||||||
int (*writable_register)(struct snd_soc_codec *, unsigned int);
|
int (*writable_register)(struct snd_soc_codec *, unsigned int);
|
||||||
@ -729,10 +689,7 @@ struct snd_soc_codec {
|
|||||||
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
|
unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
|
||||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||||
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
||||||
int (*bulk_write_raw)(struct snd_soc_codec *, unsigned int, const void *, size_t);
|
|
||||||
void *reg_cache;
|
void *reg_cache;
|
||||||
const void *reg_def_copy;
|
|
||||||
const struct snd_soc_cache_ops *cache_ops;
|
|
||||||
struct mutex cache_rw_mutex;
|
struct mutex cache_rw_mutex;
|
||||||
int val_bytes;
|
int val_bytes;
|
||||||
|
|
||||||
@ -785,9 +742,6 @@ struct snd_soc_codec_driver {
|
|||||||
short reg_cache_step;
|
short reg_cache_step;
|
||||||
short reg_word_size;
|
short reg_word_size;
|
||||||
const void *reg_cache_default;
|
const void *reg_cache_default;
|
||||||
short reg_access_size;
|
|
||||||
const struct snd_soc_reg_access *reg_access_default;
|
|
||||||
enum snd_soc_compress_type compress_type;
|
|
||||||
|
|
||||||
/* codec bias level */
|
/* codec bias level */
|
||||||
int (*set_bias_level)(struct snd_soc_codec *,
|
int (*set_bias_level)(struct snd_soc_codec *,
|
||||||
@ -955,12 +909,6 @@ struct snd_soc_codec_conf {
|
|||||||
* associated per device
|
* associated per device
|
||||||
*/
|
*/
|
||||||
const char *name_prefix;
|
const char *name_prefix;
|
||||||
|
|
||||||
/*
|
|
||||||
* set this to the desired compression type if you want to
|
|
||||||
* override the one supplied in codec->driver->compress_type
|
|
||||||
*/
|
|
||||||
enum snd_soc_compress_type compress_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_soc_aux_dev {
|
struct snd_soc_aux_dev {
|
||||||
@ -1132,8 +1080,6 @@ struct soc_enum {
|
|||||||
unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
|
unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
|
||||||
unsigned int snd_soc_write(struct snd_soc_codec *codec,
|
unsigned int snd_soc_write(struct snd_soc_codec *codec,
|
||||||
unsigned int reg, unsigned int val);
|
unsigned int reg, unsigned int val);
|
||||||
unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg, const void *data, size_t len);
|
|
||||||
|
|
||||||
/* device driver data */
|
/* device driver data */
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ struct snd_soc_codec;
|
|||||||
struct snd_soc_platform;
|
struct snd_soc_platform;
|
||||||
struct snd_soc_card;
|
struct snd_soc_card;
|
||||||
struct snd_soc_dapm_widget;
|
struct snd_soc_dapm_widget;
|
||||||
|
struct snd_soc_dapm_path;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log register events
|
* Log register events
|
||||||
|
@ -11,12 +11,9 @@
|
|||||||
* option) any later version.
|
* option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/i2c.h>
|
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
#include <linux/bitmap.h>
|
|
||||||
#include <linux/rbtree.h>
|
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <trace/events/asoc.h>
|
#include <trace/events/asoc.h>
|
||||||
|
|
||||||
@ -66,6 +63,85 @@ static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_soc_cache_init(struct snd_soc_codec *codec)
|
||||||
|
{
|
||||||
|
const struct snd_soc_codec_driver *codec_drv = codec->driver;
|
||||||
|
size_t reg_size;
|
||||||
|
|
||||||
|
reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
|
||||||
|
|
||||||
|
mutex_init(&codec->cache_rw_mutex);
|
||||||
|
|
||||||
|
dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
|
||||||
|
codec->name);
|
||||||
|
|
||||||
|
if (codec_drv->reg_cache_default)
|
||||||
|
codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
|
||||||
|
reg_size, GFP_KERNEL);
|
||||||
|
else
|
||||||
|
codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
|
||||||
|
if (!codec->reg_cache)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: keep in mind that this function might be called
|
||||||
|
* multiple times.
|
||||||
|
*/
|
||||||
|
int snd_soc_cache_exit(struct snd_soc_codec *codec)
|
||||||
|
{
|
||||||
|
dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
|
||||||
|
codec->name);
|
||||||
|
if (!codec->reg_cache)
|
||||||
|
return 0;
|
||||||
|
kfree(codec->reg_cache);
|
||||||
|
codec->reg_cache = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
if (!value)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&codec->cache_rw_mutex);
|
||||||
|
*value = snd_soc_get_cache_val(codec->reg_cache, reg,
|
||||||
|
codec->driver->reg_word_size);
|
||||||
|
mutex_unlock(&codec->cache_rw_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_soc_cache_read);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
mutex_lock(&codec->cache_rw_mutex);
|
||||||
|
snd_soc_set_cache_val(codec->reg_cache, reg, value,
|
||||||
|
codec->driver->reg_word_size);
|
||||||
|
mutex_unlock(&codec->cache_rw_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_soc_cache_write);
|
||||||
|
|
||||||
static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -78,8 +154,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
|||||||
ret = snd_soc_cache_read(codec, i, &val);
|
ret = snd_soc_cache_read(codec, i, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (codec->reg_def_copy)
|
if (codec_drv->reg_cache_default)
|
||||||
if (snd_soc_get_cache_val(codec->reg_def_copy,
|
if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
|
||||||
i, codec_drv->reg_word_size) == val)
|
i, codec_drv->reg_word_size) == val)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -94,150 +170,6 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg, unsigned int value)
|
|
||||||
{
|
|
||||||
snd_soc_set_cache_val(codec->reg_cache, reg, value,
|
|
||||||
codec->driver->reg_word_size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg, unsigned int *value)
|
|
||||||
{
|
|
||||||
*value = snd_soc_get_cache_val(codec->reg_cache, reg,
|
|
||||||
codec->driver->reg_word_size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
|
|
||||||
{
|
|
||||||
if (!codec->reg_cache)
|
|
||||||
return 0;
|
|
||||||
kfree(codec->reg_cache);
|
|
||||||
codec->reg_cache = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
|
|
||||||
{
|
|
||||||
if (codec->reg_def_copy)
|
|
||||||
codec->reg_cache = kmemdup(codec->reg_def_copy,
|
|
||||||
codec->reg_size, GFP_KERNEL);
|
|
||||||
else
|
|
||||||
codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
|
|
||||||
if (!codec->reg_cache)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* an array of all supported compression types */
|
|
||||||
static const struct snd_soc_cache_ops cache_types[] = {
|
|
||||||
/* Flat *must* be the first entry for fallback */
|
|
||||||
{
|
|
||||||
.id = SND_SOC_FLAT_COMPRESSION,
|
|
||||||
.name = "flat",
|
|
||||||
.init = snd_soc_flat_cache_init,
|
|
||||||
.exit = snd_soc_flat_cache_exit,
|
|
||||||
.read = snd_soc_flat_cache_read,
|
|
||||||
.write = snd_soc_flat_cache_write,
|
|
||||||
.sync = snd_soc_flat_cache_sync
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
int snd_soc_cache_init(struct snd_soc_codec *codec)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
|
|
||||||
if (cache_types[i].id == codec->compress_type)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Fall back to flat compression */
|
|
||||||
if (i == ARRAY_SIZE(cache_types)) {
|
|
||||||
dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n",
|
|
||||||
codec->compress_type);
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_init(&codec->cache_rw_mutex);
|
|
||||||
codec->cache_ops = &cache_types[i];
|
|
||||||
|
|
||||||
if (codec->cache_ops->init) {
|
|
||||||
if (codec->cache_ops->name)
|
|
||||||
dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n",
|
|
||||||
codec->cache_ops->name, codec->name);
|
|
||||||
return codec->cache_ops->init(codec);
|
|
||||||
}
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: keep in mind that this function might be called
|
|
||||||
* multiple times.
|
|
||||||
*/
|
|
||||||
int snd_soc_cache_exit(struct snd_soc_codec *codec)
|
|
||||||
{
|
|
||||||
if (codec->cache_ops && codec->cache_ops->exit) {
|
|
||||||
if (codec->cache_ops->name)
|
|
||||||
dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n",
|
|
||||||
codec->cache_ops->name, codec->name);
|
|
||||||
return codec->cache_ops->exit(codec);
|
|
||||||
}
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&codec->cache_rw_mutex);
|
|
||||||
|
|
||||||
if (value && codec->cache_ops && codec->cache_ops->read) {
|
|
||||||
ret = codec->cache_ops->read(codec, reg, value);
|
|
||||||
mutex_unlock(&codec->cache_rw_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&codec->cache_rw_mutex);
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_cache_read);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&codec->cache_rw_mutex);
|
|
||||||
|
|
||||||
if (codec->cache_ops && codec->cache_ops->write) {
|
|
||||||
ret = codec->cache_ops->write(codec, reg, value);
|
|
||||||
mutex_unlock(&codec->cache_rw_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&codec->cache_rw_mutex);
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_cache_write);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_soc_cache_sync: Sync the register cache with the hardware.
|
* snd_soc_cache_sync: Sync the register cache with the hardware.
|
||||||
*
|
*
|
||||||
@ -249,92 +181,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_write);
|
|||||||
*/
|
*/
|
||||||
int snd_soc_cache_sync(struct snd_soc_codec *codec)
|
int snd_soc_cache_sync(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
|
const char *name = "flat";
|
||||||
int ret;
|
int ret;
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if (!codec->cache_sync) {
|
if (!codec->cache_sync)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (!codec->cache_ops || !codec->cache_ops->sync)
|
dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
|
||||||
return -ENOSYS;
|
codec->name);
|
||||||
|
|
||||||
if (codec->cache_ops->name)
|
|
||||||
name = codec->cache_ops->name;
|
|
||||||
else
|
|
||||||
name = "unknown";
|
|
||||||
|
|
||||||
if (codec->cache_ops->name)
|
|
||||||
dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n",
|
|
||||||
codec->cache_ops->name, codec->name);
|
|
||||||
trace_snd_soc_cache_sync(codec, name, "start");
|
trace_snd_soc_cache_sync(codec, name, "start");
|
||||||
ret = codec->cache_ops->sync(codec);
|
ret = snd_soc_flat_cache_sync(codec);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
codec->cache_sync = 0;
|
codec->cache_sync = 0;
|
||||||
trace_snd_soc_cache_sync(codec, name, "end");
|
trace_snd_soc_cache_sync(codec, name, "end");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
|
EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
|
||||||
|
|
||||||
static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg)
|
|
||||||
{
|
|
||||||
const struct snd_soc_codec_driver *codec_drv;
|
|
||||||
unsigned int min, max, index;
|
|
||||||
|
|
||||||
codec_drv = codec->driver;
|
|
||||||
min = 0;
|
|
||||||
max = codec_drv->reg_access_size - 1;
|
|
||||||
do {
|
|
||||||
index = (min + max) / 2;
|
|
||||||
if (codec_drv->reg_access_default[index].reg == reg)
|
|
||||||
return index;
|
|
||||||
if (codec_drv->reg_access_default[index].reg < reg)
|
|
||||||
min = index + 1;
|
|
||||||
else
|
|
||||||
max = index;
|
|
||||||
} while (min <= max);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
if (reg >= codec->driver->reg_cache_size)
|
|
||||||
return 1;
|
|
||||||
index = snd_soc_get_reg_access_index(codec, reg);
|
|
||||||
if (index < 0)
|
|
||||||
return 0;
|
|
||||||
return codec->driver->reg_access_default[index].vol;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
|
|
||||||
|
|
||||||
int snd_soc_default_readable_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
if (reg >= codec->driver->reg_cache_size)
|
|
||||||
return 1;
|
|
||||||
index = snd_soc_get_reg_access_index(codec, reg);
|
|
||||||
if (index < 0)
|
|
||||||
return 0;
|
|
||||||
return codec->driver->reg_access_default[index].read;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
|
|
||||||
|
|
||||||
int snd_soc_default_writable_register(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
if (reg >= codec->driver->reg_cache_size)
|
|
||||||
return 1;
|
|
||||||
index = snd_soc_get_reg_access_index(codec, reg);
|
|
||||||
if (index < 0)
|
|
||||||
return 0;
|
|
||||||
return codec->driver->reg_access_default[index].write;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
|
|
||||||
|
@ -1589,17 +1589,13 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
|
|||||||
soc_remove_codec(codec);
|
soc_remove_codec(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
|
static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
|
||||||
enum snd_soc_compress_type compress_type)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (codec->cache_init)
|
if (codec->cache_init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* override the compress_type if necessary */
|
|
||||||
if (compress_type && codec->compress_type != compress_type)
|
|
||||||
codec->compress_type = compress_type;
|
|
||||||
ret = snd_soc_cache_init(codec);
|
ret = snd_soc_cache_init(codec);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(codec->dev,
|
dev_err(codec->dev,
|
||||||
@ -1614,8 +1610,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
|
|||||||
static int snd_soc_instantiate_card(struct snd_soc_card *card)
|
static int snd_soc_instantiate_card(struct snd_soc_card *card)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_codec *codec;
|
||||||
struct snd_soc_codec_conf *codec_conf;
|
|
||||||
enum snd_soc_compress_type compress_type;
|
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
int ret, i, order, dai_fmt;
|
int ret, i, order, dai_fmt;
|
||||||
|
|
||||||
@ -1639,19 +1633,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
|
|||||||
list_for_each_entry(codec, &codec_list, list) {
|
list_for_each_entry(codec, &codec_list, list) {
|
||||||
if (codec->cache_init)
|
if (codec->cache_init)
|
||||||
continue;
|
continue;
|
||||||
/* by default we don't override the compress_type */
|
ret = snd_soc_init_codec_cache(codec);
|
||||||
compress_type = 0;
|
|
||||||
/* check to see if we need to override the compress_type */
|
|
||||||
for (i = 0; i < card->num_configs; ++i) {
|
|
||||||
codec_conf = &card->codec_conf[i];
|
|
||||||
if (!strcmp(codec->name, codec_conf->dev_name)) {
|
|
||||||
compress_type = codec_conf->compress_type;
|
|
||||||
if (compress_type && compress_type
|
|
||||||
!= codec->compress_type)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = snd_soc_init_codec_cache(codec, compress_type);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto base_error;
|
goto base_error;
|
||||||
}
|
}
|
||||||
@ -2297,13 +2279,6 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_write);
|
EXPORT_SYMBOL_GPL(snd_soc_write);
|
||||||
|
|
||||||
unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
return codec->bulk_write_raw(codec, reg, data, len);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_soc_update_bits - update codec register bits
|
* snd_soc_update_bits - update codec register bits
|
||||||
* @codec: audio codec
|
* @codec: audio codec
|
||||||
@ -4063,6 +4038,7 @@ __snd_soc_register_component(struct device *dev,
|
|||||||
|
|
||||||
cmpnt->dev = dev;
|
cmpnt->dev = dev;
|
||||||
cmpnt->driver = cmpnt_drv;
|
cmpnt->driver = cmpnt_drv;
|
||||||
|
cmpnt->dai_drv = dai_drv;
|
||||||
cmpnt->num_dai = num_dai;
|
cmpnt->num_dai = num_dai;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4287,7 +4263,6 @@ int snd_soc_register_codec(struct device *dev,
|
|||||||
struct snd_soc_dai_driver *dai_drv,
|
struct snd_soc_dai_driver *dai_drv,
|
||||||
int num_dai)
|
int num_dai)
|
||||||
{
|
{
|
||||||
size_t reg_size;
|
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_codec *codec;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
@ -4304,11 +4279,6 @@ int snd_soc_register_codec(struct device *dev,
|
|||||||
goto fail_codec;
|
goto fail_codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_drv->compress_type)
|
|
||||||
codec->compress_type = codec_drv->compress_type;
|
|
||||||
else
|
|
||||||
codec->compress_type = SND_SOC_FLAT_COMPRESSION;
|
|
||||||
|
|
||||||
codec->write = codec_drv->write;
|
codec->write = codec_drv->write;
|
||||||
codec->read = codec_drv->read;
|
codec->read = codec_drv->read;
|
||||||
codec->volatile_register = codec_drv->volatile_register;
|
codec->volatile_register = codec_drv->volatile_register;
|
||||||
@ -4325,35 +4295,6 @@ int snd_soc_register_codec(struct device *dev,
|
|||||||
codec->num_dai = num_dai;
|
codec->num_dai = num_dai;
|
||||||
mutex_init(&codec->mutex);
|
mutex_init(&codec->mutex);
|
||||||
|
|
||||||
/* allocate CODEC register cache */
|
|
||||||
if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
|
|
||||||
reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
|
|
||||||
codec->reg_size = reg_size;
|
|
||||||
/* it is necessary to make a copy of the default register cache
|
|
||||||
* because in the case of using a compression type that requires
|
|
||||||
* the default register cache to be marked as the
|
|
||||||
* kernel might have freed the array by the time we initialize
|
|
||||||
* the cache.
|
|
||||||
*/
|
|
||||||
if (codec_drv->reg_cache_default) {
|
|
||||||
codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
|
|
||||||
reg_size, GFP_KERNEL);
|
|
||||||
if (!codec->reg_def_copy) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto fail_codec_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
|
|
||||||
if (!codec->volatile_register)
|
|
||||||
codec->volatile_register = snd_soc_default_volatile_register;
|
|
||||||
if (!codec->readable_register)
|
|
||||||
codec->readable_register = snd_soc_default_readable_register;
|
|
||||||
if (!codec->writable_register)
|
|
||||||
codec->writable_register = snd_soc_default_writable_register;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < num_dai; i++) {
|
for (i = 0; i < num_dai; i++) {
|
||||||
fixup_codec_formats(&dai_drv[i].playback);
|
fixup_codec_formats(&dai_drv[i].playback);
|
||||||
fixup_codec_formats(&dai_drv[i].capture);
|
fixup_codec_formats(&dai_drv[i].capture);
|
||||||
@ -4412,7 +4353,6 @@ found:
|
|||||||
dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
|
dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
|
||||||
|
|
||||||
snd_soc_cache_exit(codec);
|
snd_soc_cache_exit(codec);
|
||||||
kfree(codec->reg_def_copy);
|
|
||||||
kfree(codec->name);
|
kfree(codec->name);
|
||||||
kfree(codec);
|
kfree(codec);
|
||||||
}
|
}
|
||||||
@ -4624,12 +4564,31 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
|
|||||||
if (pos->dev->of_node != args.np)
|
if (pos->dev->of_node != args.np)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!pos->driver->of_xlate_dai_name) {
|
if (pos->driver->of_xlate_dai_name) {
|
||||||
ret = -ENOSYS;
|
ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
|
||||||
break;
|
} else {
|
||||||
|
int id = -1;
|
||||||
|
|
||||||
|
switch (args.args_count) {
|
||||||
|
case 0:
|
||||||
|
id = 0; /* same as dai_drv[0] */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
id = args.args[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* not supported */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id < 0 || id >= pos->num_dai) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
} else {
|
||||||
|
*dai_name = pos->dai_drv[id].name;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&client_mutex);
|
mutex_unlock(&client_mutex);
|
||||||
|
@ -65,31 +65,6 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Primitive bulk write support for soc-cache. The data pointed to by
|
|
||||||
* `data' needs to already be in the form the hardware expects. Any
|
|
||||||
* data written through this function will not go through the cache as
|
|
||||||
* it only handles writing to volatile or out of bounds registers.
|
|
||||||
*
|
|
||||||
* This is currently only supported for devices using the regmap API
|
|
||||||
* wrappers.
|
|
||||||
*/
|
|
||||||
static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
|
|
||||||
unsigned int reg,
|
|
||||||
const void *data, size_t len)
|
|
||||||
{
|
|
||||||
/* To ensure that we don't get out of sync with the cache, check
|
|
||||||
* whether the base register is volatile or if we've directly asked
|
|
||||||
* to bypass the cache. Out of bounds registers are considered
|
|
||||||
* volatile.
|
|
||||||
*/
|
|
||||||
if (!codec->cache_bypass
|
|
||||||
&& !snd_soc_codec_volatile_register(codec, reg)
|
|
||||||
&& reg < codec->driver->reg_cache_size)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return regmap_raw_write(codec->control_data, reg, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_soc_codec_set_cache_io: Set up standard I/O functions.
|
* snd_soc_codec_set_cache_io: Set up standard I/O functions.
|
||||||
*
|
*
|
||||||
@ -119,7 +94,6 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
|
|||||||
memset(&config, 0, sizeof(config));
|
memset(&config, 0, sizeof(config));
|
||||||
codec->write = hw_write;
|
codec->write = hw_write;
|
||||||
codec->read = hw_read;
|
codec->read = hw_read;
|
||||||
codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
|
|
||||||
|
|
||||||
config.reg_bits = addr_bits;
|
config.reg_bits = addr_bits;
|
||||||
config.val_bits = data_bits;
|
config.val_bits = data_bits;
|
||||||
|
@ -721,7 +721,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
|
|||||||
list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
|
list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
|
||||||
list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
|
list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
|
||||||
|
|
||||||
dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n",
|
dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n",
|
||||||
stream ? "capture" : "playback", fe->dai_link->name,
|
stream ? "capture" : "playback", fe->dai_link->name,
|
||||||
stream ? "<-" : "->", be->dai_link->name);
|
stream ? "<-" : "->", be->dai_link->name);
|
||||||
|
|
||||||
@ -749,7 +749,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
|
|||||||
if (dpcm->fe == fe)
|
if (dpcm->fe == fe)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_dbg(fe->dev, " reparent %s path %s %s %s\n",
|
dev_dbg(fe->dev, "reparent %s path %s %s %s\n",
|
||||||
stream ? "capture" : "playback",
|
stream ? "capture" : "playback",
|
||||||
dpcm->fe->dai_link->name,
|
dpcm->fe->dai_link->name,
|
||||||
stream ? "<-" : "->", dpcm->be->dai_link->name);
|
stream ? "<-" : "->", dpcm->be->dai_link->name);
|
||||||
@ -773,7 +773,7 @@ static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
|
|||||||
if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
|
if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n",
|
dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n",
|
||||||
stream ? "capture" : "playback", fe->dai_link->name,
|
stream ? "capture" : "playback", fe->dai_link->name,
|
||||||
stream ? "<-" : "->", dpcm->be->dai_link->name);
|
stream ? "<-" : "->", dpcm->be->dai_link->name);
|
||||||
|
|
||||||
@ -2116,7 +2116,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
|
|||||||
|
|
||||||
pcm->private_free = platform->driver->pcm_free;
|
pcm->private_free = platform->driver->pcm_free;
|
||||||
out:
|
out:
|
||||||
dev_info(rtd->card->dev, " %s <-> %s mapping ok\n", codec_dai->name,
|
dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", codec_dai->name,
|
||||||
cpu_dai->name);
|
cpu_dai->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,11 @@ static const struct snd_pcm_hardware dummy_dma_hardware = {
|
|||||||
|
|
||||||
static int dummy_dma_open(struct snd_pcm_substream *substream)
|
static int dummy_dma_open(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
|
|
||||||
|
/* BE's dont need dummy params */
|
||||||
|
if (!rtd->dai_link->no_pcm)
|
||||||
|
snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user