From 3ef8b6a33d67d6a7e2d10ed0eede148d88c01152 Mon Sep 17 00:00:00 2001 From: Bhanu Murthy V Date: Fri, 14 Sep 2018 11:42:39 -0700 Subject: driver: camera: Read sensor bus configuration Add reading i2c bus driver configuration from device tree. Add reading SPI bus driver configuration from device tree. The bus configuration is required to register with RCE driver for sensors. Bug 2433156 Change-Id: I012c98ff417096669cfbf6cf20b83fd0299af150 Signed-off-by: Bhanu Murthy V Reviewed-on: https://git-master.nvidia.com/r/1851317 (cherry picked from commit 5bc239e0ccea141af75ad55a9f6acd1f1c620d45) Reviewed-on: https://git-master.nvidia.com/r/2006761 Reviewed-by: svc-mobile-coverity Tested-by: Ian Kaszubski Reviewed-by: Vincent Chung GVS: Gerrit_Virtual_Submit Reviewed-by: Frank Chen Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../media/platform/tegra/camera/sensor_common.c | 164 +++++++++++++++++++++ .../media/platform/tegra/camera/tegracam_core.c | 2 +- 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/tegra/camera/sensor_common.c b/drivers/media/platform/tegra/camera/sensor_common.c index ff99682eb..42864af76 100644 --- a/drivers/media/platform/tegra/camera/sensor_common.c +++ b/drivers/media/platform/tegra/camera/sensor_common.c @@ -537,6 +537,166 @@ int sensor_common_parse_num_modes(const struct device *dev) } EXPORT_SYMBOL(sensor_common_parse_num_modes); +static int sensor_common_init_i2c_device_config( + struct device *dev, struct device_node *np, + struct sensor_cfg *cfg) +{ + struct i2c_sensor_cfg *i2c_sensor = &cfg->u.i2c_sensor; + struct device_node *node = NULL; + struct device_node *parent = NULL; + int err = 0; + u32 value = 0; + bool is_mux_valid = 0; + + of_node_get(np); + cfg->type = CAMERA_DEVICE_I2C_SENSOR; + err = of_property_read_u32(np, "reg", &value); + if (err) { + dev_err(dev, "sensor address unavailable\n"); + return err; + } + + /* Reading more devices has to be supported */ + i2c_sensor->num_devs = 1; + i2c_sensor->sd[0].addr = value; + + parent = of_get_parent(np); + /* verify the parent is mux or i2c bus */ + is_mux_valid = + of_property_read_bool(parent, "i2c-mux,deselect-on-exit"); + i2c_sensor->mux.is_mux_valid = is_mux_valid; + of_node_put(np); + + if (is_mux_valid) { + + /* at mux port read the mux channel */ + err = of_property_read_u32(parent, "reg", &value); + if (err) { + dev_err(dev, "mux channel unavailable\n"); + return err; + } + i2c_sensor->mux.mux_channel = value; + + /* move to mux node */ + node = of_get_parent(parent); + err = of_property_read_u32(node, "reg", &value); + if (err) { + dev_err(dev, "mux address unavailable\n"); + return err; + } + i2c_sensor->mux.mux_addr = value; + of_node_put(parent); + + /* move to i2c bus node */ + parent = of_get_parent(node); + of_node_put(node); + } + + /* read parent which is i2c bus */ + err = of_property_read_u32_index(parent, "reg", 1, &value); + if (err) { + dev_err(dev, "i2c bus regbase unavailable\n"); + return err; + } + i2c_sensor->bus.reg_base = value; + + err = of_property_read_u32(parent, "clock-frequency", &value); + if (err) { + dev_err(dev, "bus clock frequency unavailable\n"); + return err; + } + i2c_sensor->bus.clk_rate = value; + + of_node_put(parent); + /* + * Read any additional flags to configure I2C for any + * special properties of the device like-high-speed mode, + * 10bit addressing etc., + */ + + return 0; +} + +static int sensor_common_init_spi_device_config( + struct device *dev, struct device_node *np, + struct sensor_cfg *cfg) +{ + struct spi_sensor_cfg *spi_sensor = &cfg->u.spi_sensor; + struct device_node *parent = NULL; + int err = 0; + u32 value = 0; + + of_node_get(np); + cfg->type = CAMERA_DEVICE_SPI_SENSOR; + err = of_property_read_u32(np, "reg", &value); + if (err) { + dev_err(dev, "sensor address unavailable\n"); + return err; + } + + /* Reading more devices has to be supported */ + spi_sensor->num_devs = 1; + spi_sensor->sd[0].addr = value; + + parent = of_get_parent(np); + of_node_put(np); + /* TODO: Add logic for spi mux if available */ + + /* read parent which is spi bus */ + err = of_property_read_u32_index(parent, "reg", 1, &value); + if (err) { + dev_err(dev, "spi bus regbase unavailable\n"); + return err; + } + spi_sensor->bus.reg_base = value; + + err = of_property_read_u32(parent, "spi-max-frequency", &value); + if (err) { + dev_err(dev, "bus clock frequency unavailable\n"); + return err; + } + spi_sensor->bus.clk_rate = value; + + of_node_put(parent); + /* Read any additional flags to configure SPI */ + + return 0; +} + +static int sensor_common_init_device_config( + struct device *dev, struct device_node *np, + struct sensor_cfg *cfg) +{ + struct device_node *parent = NULL; + char *tmp; + int err = 0; + + if (!np) + return -EINVAL; + + parent = of_get_parent(np); + if (!parent) + return -EINVAL; + + tmp = strnstr(parent->name, "i2c", 4); + if (tmp != NULL) { + err = sensor_common_init_i2c_device_config(dev, np, cfg); + if (err) + goto exit; + } + + tmp = strnstr(parent->name, "spi", 4); + if (tmp != NULL) { + err = sensor_common_init_spi_device_config(dev, np, cfg); + if (err) + goto exit; + } + +exit: + of_node_put(parent); + return err; +} + int sensor_common_init_sensor_properties( struct device *dev, struct device_node *np, struct sensor_properties *sensor) @@ -549,6 +709,10 @@ int sensor_common_init_sensor_properties( if (sensor == NULL) return -EINVAL; + err = sensor_common_init_device_config(dev, np, &sensor->cfg); + if (err) + return err; + /* get number of modes */ for (i = 0; num_modes < MAX_NUM_SENSOR_MODES; i++) { snprintf(temp_str, sizeof(temp_str), "%s%d", diff --git a/drivers/media/platform/tegra/camera/tegracam_core.c b/drivers/media/platform/tegra/camera/tegracam_core.c index 6e5249c1d..5a17322ff 100644 --- a/drivers/media/platform/tegra/camera/tegracam_core.c +++ b/drivers/media/platform/tegra/camera/tegracam_core.c @@ -22,7 +22,7 @@ /* use semantic versioning convention */ #define TEGRACAM_MAJOR_VERSION 2 #define TEGRACAM_MINOR_VERSION 0 -#define TEGRACAM_PATCH_VERSION 0 +#define TEGRACAM_PATCH_VERSION 1 u32 tegracam_version(u8 major, u8 minor, u8 patch) { -- cgit v1.2.2