sound/soc/codecs/uda1380.c | 44 ++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-)
If any of these I2C operations fail, the driver may continue execution
with invalid data, leading to incorrect device state or silent failures.
Fix this by:
- Adding proper return value checks for all I2C operations
- Converting pr_debug() to dev_err() with %pe format for human-readable
error codes
- Moving variable declaration to function beginning (C90 style)
- Providing detailed error messages including register address and
expected values
This ensures the driver properly detects and reports I2C communication
failures, maintaining correct device state.
Signed-off-by: Wenyuan Li <2063309626@qq.com>
---
sound/soc/codecs/uda1380.c | 44 ++++++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 9e9c540a45ca..4d2a653b8c59 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -95,6 +95,8 @@ static int uda1380_write(struct snd_soc_component *component, unsigned int reg,
{
struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
u8 data[3];
+ unsigned int val;
+ int ret;
/* data is
* data[0] is register offset
@@ -112,22 +114,36 @@ static int uda1380_write(struct snd_soc_component *component, unsigned int reg,
*/
if (!snd_soc_component_active(component) && (reg >= UDA1380_MVOL))
return 0;
+
pr_debug("uda1380: hw write %x val %x\n", reg, value);
- if (i2c_master_send(uda1380->i2c, data, 3) == 3) {
- unsigned int val;
- i2c_master_send(uda1380->i2c, data, 1);
- i2c_master_recv(uda1380->i2c, data, 2);
- val = (data[0]<<8) | data[1];
- if (val != value) {
- pr_debug("uda1380: READ BACK VAL %x\n",
- (data[0]<<8) | data[1]);
- return -EIO;
- }
- if (reg >= 0x10)
- clear_bit(reg - 0x10, &uda1380_cache_dirty);
- return 0;
- } else
+ ret = i2c_master_send(uda1380->i2c, data, 3);
+ if (ret != 3) {
+ dev_err(component->dev, "write failed: %pe\n", ERR_PTR(ret));
+ return ret < 0 ? ret : -EIO;
+ }
+
+ ret = i2c_master_send(uda1380->i2c, data, 1);
+ if (ret != 1) {
+ dev_err(component->dev, "send address failed: %pe\n", ERR_PTR(ret));
+ return ret < 0 ? ret : -EIO;
+ }
+
+ ret = i2c_master_recv(uda1380->i2c, data, 2);
+ if (ret != 2) {
+ dev_err(component->dev, "read back failed: %pe\n", ERR_PTR(ret));
+ return ret < 0 ? ret : -EIO;
+ }
+
+ val = (data[0] << 8) | data[1];
+ if (val != value) {
+ dev_err(component->dev, "read back val %x (expected %x)\n", val, value);
return -EIO;
+ }
+
+ if (reg >= 0x10)
+ clear_bit(reg - 0x10, &uda1380_cache_dirty);
+
+ return 0;
}
static void uda1380_sync_cache(struct snd_soc_component *component)
--
2.43.0
On Thu, Mar 19, 2026 at 02:26:33PM +0800, Wenyuan Li wrote:
> If any of these I2C operations fail, the driver may continue execution
> with invalid data, leading to incorrect device state or silent failures.
>
> Fix this by:
> - Adding proper return value checks for all I2C operations
> - Converting pr_debug() to dev_err() with %pe format for human-readable
> error codes
> - Moving variable declaration to function beginning (C90 style)
> - Providing detailed error messages including register address and
> expected values
This is multiple different changes, as covered in submitting-patches.rst
it should really be a patch series with one change per patch.
> + ret = i2c_master_send(uda1380->i2c, data, 3);
> + if (ret != 3) {
> + dev_err(component->dev, "write failed: %pe\n", ERR_PTR(ret));
> + return ret < 0 ? ret : -EIO;
> + }
i2c_master_send() doesn't return a pointer, it returns an errno or the
transfer length.
Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
© 2016 - 2026 Red Hat, Inc.