root/sound/soc/soc-io.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_soc_component_read
  2. snd_soc_component_read32
  3. snd_soc_component_write
  4. snd_soc_component_update_bits_legacy
  5. snd_soc_component_update_bits
  6. snd_soc_component_update_bits_async
  7. snd_soc_component_async_complete
  8. snd_soc_component_test_bits

   1 // SPDX-License-Identifier: GPL-2.0+
   2 //
   3 // soc-io.c  --  ASoC register I/O helpers
   4 //
   5 // Copyright 2009-2011 Wolfson Microelectronics PLC.
   6 //
   7 // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   8 
   9 #include <linux/i2c.h>
  10 #include <linux/spi/spi.h>
  11 #include <linux/regmap.h>
  12 #include <linux/export.h>
  13 #include <sound/soc.h>
  14 
  15 /**
  16  * snd_soc_component_read() - Read register value
  17  * @component: Component to read from
  18  * @reg: Register to read
  19  * @val: Pointer to where the read value is stored
  20  *
  21  * Return: 0 on success, a negative error code otherwise.
  22  */
  23 int snd_soc_component_read(struct snd_soc_component *component,
  24         unsigned int reg, unsigned int *val)
  25 {
  26         int ret;
  27 
  28         if (component->regmap)
  29                 ret = regmap_read(component->regmap, reg, val);
  30         else if (component->driver->read) {
  31                 *val = component->driver->read(component, reg);
  32                 ret = 0;
  33         }
  34         else
  35                 ret = -EIO;
  36 
  37         return ret;
  38 }
  39 EXPORT_SYMBOL_GPL(snd_soc_component_read);
  40 
  41 unsigned int snd_soc_component_read32(struct snd_soc_component *component,
  42                                       unsigned int reg)
  43 {
  44         unsigned int val;
  45         int ret;
  46 
  47         ret = snd_soc_component_read(component, reg, &val);
  48         if (ret < 0)
  49                 return -1;
  50 
  51         return val;
  52 }
  53 EXPORT_SYMBOL_GPL(snd_soc_component_read32);
  54 
  55 /**
  56  * snd_soc_component_write() - Write register value
  57  * @component: Component to write to
  58  * @reg: Register to write
  59  * @val: Value to write to the register
  60  *
  61  * Return: 0 on success, a negative error code otherwise.
  62  */
  63 int snd_soc_component_write(struct snd_soc_component *component,
  64         unsigned int reg, unsigned int val)
  65 {
  66         if (component->regmap)
  67                 return regmap_write(component->regmap, reg, val);
  68         else if (component->driver->write)
  69                 return component->driver->write(component, reg, val);
  70         else
  71                 return -EIO;
  72 }
  73 EXPORT_SYMBOL_GPL(snd_soc_component_write);
  74 
  75 static int snd_soc_component_update_bits_legacy(
  76         struct snd_soc_component *component, unsigned int reg,
  77         unsigned int mask, unsigned int val, bool *change)
  78 {
  79         unsigned int old, new;
  80         int ret;
  81 
  82         mutex_lock(&component->io_mutex);
  83 
  84         ret = snd_soc_component_read(component, reg, &old);
  85         if (ret < 0)
  86                 goto out_unlock;
  87 
  88         new = (old & ~mask) | (val & mask);
  89         *change = old != new;
  90         if (*change)
  91                 ret = snd_soc_component_write(component, reg, new);
  92 out_unlock:
  93         mutex_unlock(&component->io_mutex);
  94 
  95         return ret;
  96 }
  97 
  98 /**
  99  * snd_soc_component_update_bits() - Perform read/modify/write cycle
 100  * @component: Component to update
 101  * @reg: Register to update
 102  * @mask: Mask that specifies which bits to update
 103  * @val: New value for the bits specified by mask
 104  *
 105  * Return: 1 if the operation was successful and the value of the register
 106  * changed, 0 if the operation was successful, but the value did not change.
 107  * Returns a negative error code otherwise.
 108  */
 109 int snd_soc_component_update_bits(struct snd_soc_component *component,
 110         unsigned int reg, unsigned int mask, unsigned int val)
 111 {
 112         bool change;
 113         int ret;
 114 
 115         if (component->regmap)
 116                 ret = regmap_update_bits_check(component->regmap, reg, mask,
 117                         val, &change);
 118         else
 119                 ret = snd_soc_component_update_bits_legacy(component, reg,
 120                         mask, val, &change);
 121 
 122         if (ret < 0)
 123                 return ret;
 124         return change;
 125 }
 126 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
 127 
 128 /**
 129  * snd_soc_component_update_bits_async() - Perform asynchronous
 130  *  read/modify/write cycle
 131  * @component: Component to update
 132  * @reg: Register to update
 133  * @mask: Mask that specifies which bits to update
 134  * @val: New value for the bits specified by mask
 135  *
 136  * This function is similar to snd_soc_component_update_bits(), but the update
 137  * operation is scheduled asynchronously. This means it may not be completed
 138  * when the function returns. To make sure that all scheduled updates have been
 139  * completed snd_soc_component_async_complete() must be called.
 140  *
 141  * Return: 1 if the operation was successful and the value of the register
 142  * changed, 0 if the operation was successful, but the value did not change.
 143  * Returns a negative error code otherwise.
 144  */
 145 int snd_soc_component_update_bits_async(struct snd_soc_component *component,
 146         unsigned int reg, unsigned int mask, unsigned int val)
 147 {
 148         bool change;
 149         int ret;
 150 
 151         if (component->regmap)
 152                 ret = regmap_update_bits_check_async(component->regmap, reg,
 153                         mask, val, &change);
 154         else
 155                 ret = snd_soc_component_update_bits_legacy(component, reg,
 156                         mask, val, &change);
 157 
 158         if (ret < 0)
 159                 return ret;
 160         return change;
 161 }
 162 EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
 163 
 164 /**
 165  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
 166  * @component: Component for which to wait
 167  *
 168  * This function blocks until all asynchronous I/O which has previously been
 169  * scheduled using snd_soc_component_update_bits_async() has completed.
 170  */
 171 void snd_soc_component_async_complete(struct snd_soc_component *component)
 172 {
 173         if (component->regmap)
 174                 regmap_async_complete(component->regmap);
 175 }
 176 EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
 177 
 178 /**
 179  * snd_soc_component_test_bits - Test register for change
 180  * @component: component
 181  * @reg: Register to test
 182  * @mask: Mask that specifies which bits to test
 183  * @value: Value to test against
 184  *
 185  * Tests a register with a new value and checks if the new value is
 186  * different from the old value.
 187  *
 188  * Return: 1 for change, otherwise 0.
 189  */
 190 int snd_soc_component_test_bits(struct snd_soc_component *component,
 191         unsigned int reg, unsigned int mask, unsigned int value)
 192 {
 193         unsigned int old, new;
 194         int ret;
 195 
 196         ret = snd_soc_component_read(component, reg, &old);
 197         if (ret < 0)
 198                 return ret;
 199         new = (old & ~mask) | value;
 200         return old != new;
 201 }
 202 EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);

/* [<][>][^][v][top][bottom][index][help] */