Files
linux-nv-oot/drivers/media/platform/tegra/cdi/cdi-tca-priv.h
kevixie 5ce08ee3ce nvidia-oot: cameraSW: add data validation to dt reads
+ Add the following data validation checks based on
  gaps identified when inspecting code for
  SHR-9320:
  + FSYNC: Add check to ensure existence of generators
    property before parse
  + FSYNC: Add check to ensure generators in default
    group adhere to LCM rule
  + CDI: Add check to ensure reg_len / dat_len do
    not exceed 2 bytes
  + CDI: Ensure err is set before jumping to err_probe
  + CDI: Jump to err_probe if IOExpander i2c-bus read
    fails
  + CDI-TCA: Return error if reg_len or dat_len
    out of expected range
  + FuSaCap: Ensure isp/vi-max-channels validated
  + VI: Add check for vi-mapping index found (this was
    already caught in existing code, but error message
    was non-specific)
  + camera_common: Add check for err that was set but
    never read
  + RTCPU: Add debug prints for properties not found

Jira CAMERASW-30537
Change-Id: I9953029f594c0153d6c335913944fb8906adedd9
Signed-off-by: kevixie <kevixie@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3280557
Reviewed-by: Vincent Chung <vincentc@nvidia.com>
Reviewed-by: Frank Chen <frankc@nvidia.com>
Reviewed-by: Mohit Ingale <mohiti@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
2025-07-24 10:19:13 +00:00

134 lines
2.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __CDI_TCA9539_PRIV_H__
#define __CDI_TCA9539_PRIV_H__
/* i2c payload size is only 12 bit */
#define MAX_MSG_SIZE (0xFFF - 1)
struct tca9539_priv {
struct i2c_adapter *adap;
int bus;
u32 addr;
u32 reg_len;
u32 dat_len;
u8 init_val[12];
u32 power_port;
u32 fsync_ctrl_port;
bool enable;
};
static int tca9539_raw_wr(
struct device *dev, struct tca9539_priv *tca9539, unsigned int offset, u8 val)
{
int ret = -ENODEV;
u8 *buf_start = NULL;
struct i2c_msg *i2cmsg;
unsigned int num_msgs = 0, total_size, i;
u8 data[3];
size_t size = 1;
dev_dbg(dev, "%s\n", __func__);
if (tca9539->dat_len != 1)
return -EINVAL;
if (tca9539->reg_len != 1)
return -EINVAL;
data[0] = (u8)(offset & 0xff);
data[1] = val;
size += 1;
num_msgs = size / MAX_MSG_SIZE;
num_msgs += (size % MAX_MSG_SIZE) ? 1 : 0;
i2cmsg = kzalloc((sizeof(struct i2c_msg)*num_msgs), GFP_KERNEL);
if (!i2cmsg) {
return -ENOMEM;
}
buf_start = data;
total_size = size;
dev_dbg(dev, "%s: num_msgs: %d\n", __func__, num_msgs);
for (i = 0; i < num_msgs; i++) {
i2cmsg[i].addr = tca9539->addr;
i2cmsg[i].buf = (__u8 *)buf_start;
if (i > 0)
i2cmsg[i].flags = I2C_M_NOSTART;
else
i2cmsg[i].flags = 0;
if (total_size > MAX_MSG_SIZE) {
i2cmsg[i].len = MAX_MSG_SIZE;
buf_start += MAX_MSG_SIZE;
total_size -= MAX_MSG_SIZE;
} else {
i2cmsg[i].len = total_size;
}
dev_dbg(dev, "%s: addr:%x buf:%p, flags:%u len:%u\n",
__func__, i2cmsg[i].addr, (void *)i2cmsg[i].buf,
i2cmsg[i].flags, i2cmsg[i].len);
}
ret = i2c_transfer(tca9539->adap, i2cmsg, num_msgs);
if (ret > 0)
ret = 0;
kfree(i2cmsg);
return ret;
}
static int tca9539_raw_rd(
struct device *dev, struct tca9539_priv *tca9539, unsigned int offset, u8 *val)
{
int ret = -ENODEV;
u8 data[2];
size_t size = 1;
struct i2c_msg i2cmsg[2];
dev_dbg(dev, "%s\n", __func__);
if (tca9539->dat_len != 1)
return -EINVAL;
if (tca9539->reg_len != 1)
return -EINVAL;
data[0] = (u8)(offset & 0xff);
i2cmsg[0].addr = tca9539->addr;
i2cmsg[0].len = tca9539->reg_len;
i2cmsg[0].buf = (__u8 *)data;
i2cmsg[0].flags = I2C_M_NOSTART;
i2cmsg[1].addr = tca9539->addr;
i2cmsg[1].flags = I2C_M_RD;
i2cmsg[1].len = size;
i2cmsg[1].buf = (__u8 *)val;
ret = i2c_transfer(tca9539->adap, i2cmsg, 2);
if (ret > 0)
ret = 0;
return ret;
}
#endif /* __CDI_TCA9539_PRIV_H__ */