diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2011-03-22 06:37:03 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-03-26 13:44:14 -0400 |
commit | 5fb609d435f0679ed322ddeb1fdafe6142463fdf (patch) | |
tree | c0da5a9fca23fab307305acf6be95272eb2e8c52 /sound/soc/soc-cache.c | |
parent | f3594f5c5c489d159f6d487a889d9d68ca4c0123 (diff) |
ASoC: soc-cache: Introduce raw bulk write support
As it has become more common to have to write firmware or similar
large chunks of data to the hardware, add a function to perform
raw bulk writes that bypass the cache. This only handles volatile
registers as we should avoid getting out of sync with the actual
cache.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r-- | sound/soc/soc-cache.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9f6737413a6e..8bcd4e1cee91 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -625,6 +625,44 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data, | |||
625 | #define snd_soc_16_16_spi_write NULL | 625 | #define snd_soc_16_16_spi_write NULL |
626 | #endif | 626 | #endif |
627 | 627 | ||
628 | /* Primitive bulk write support for soc-cache. The data pointed to by `data' needs | ||
629 | * to already be in the form the hardware expects including any leading register specific | ||
630 | * data. Any data written through this function will not go through the cache as it | ||
631 | * only handles writing to volatile or out of bounds registers. | ||
632 | */ | ||
633 | static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, | ||
634 | const void *data, size_t len) | ||
635 | { | ||
636 | int ret; | ||
637 | |||
638 | /* Ensure that the base register is volatile. Subsequently | ||
639 | * any other register that is touched by this routine should be | ||
640 | * volatile as well to ensure that we don't get out of sync with | ||
641 | * the cache. | ||
642 | */ | ||
643 | if (!snd_soc_codec_volatile_register(codec, reg) | ||
644 | && reg < codec->driver->reg_cache_size) | ||
645 | return -EINVAL; | ||
646 | |||
647 | switch (codec->control_type) { | ||
648 | case SND_SOC_I2C: | ||
649 | ret = i2c_master_send(codec->control_data, data, len); | ||
650 | break; | ||
651 | case SND_SOC_SPI: | ||
652 | ret = do_spi_write(codec->control_data, data, len); | ||
653 | break; | ||
654 | default: | ||
655 | BUG(); | ||
656 | } | ||
657 | |||
658 | if (ret == len) | ||
659 | return 0; | ||
660 | if (ret < 0) | ||
661 | return ret; | ||
662 | else | ||
663 | return -EIO; | ||
664 | } | ||
665 | |||
628 | static struct { | 666 | static struct { |
629 | int addr_bits; | 667 | int addr_bits; |
630 | int data_bits; | 668 | int data_bits; |
@@ -708,6 +746,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
708 | 746 | ||
709 | codec->write = io_types[i].write; | 747 | codec->write = io_types[i].write; |
710 | codec->read = io_types[i].read; | 748 | codec->read = io_types[i].read; |
749 | codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; | ||
711 | 750 | ||
712 | switch (control) { | 751 | switch (control) { |
713 | case SND_SOC_CUSTOM: | 752 | case SND_SOC_CUSTOM: |