static int fpga_i2c_config_init()

in platform/broadcom/sonic-platform-modules-tencent/common/modules/rg_fpga_i2c_bus_drv.c [768:993]


static int fpga_i2c_config_init(fpga_i2c_dev_t *fpga_i2c)
{
    int ret = 0, rv = 0;
    fpga_i2c_reg_t *reg;
    fpga_i2c_reset_cfg_t *reset_cfg;
    struct device *dev;
    uint32_t i2c_offset_reg, i2c_data_buf_len_reg;
    int32_t i2c_offset_val;

    fpga_i2c_bus_device_t *fpga_i2c_bus_device;

    dev = fpga_i2c->dev;
    reg = &fpga_i2c->reg;
    reset_cfg = &fpga_i2c->reset_cfg;

    i2c_offset_val = 0;

    if (dev->of_node) {
        ret = 0;
        ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_addr", &reg->i2c_ext_9548_addr);
        ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_chan", &reg->i2c_ext_9548_chan);
        ret += of_property_read_u32(dev->of_node, "i2c_slave", &reg->i2c_slave);
        ret += of_property_read_u32(dev->of_node, "i2c_reg", &reg->i2c_reg);
        ret += of_property_read_u32(dev->of_node, "i2c_data_len", &reg->i2c_data_len);
        ret += of_property_read_u32(dev->of_node, "i2c_ctrl", &reg->i2c_ctrl);
        ret += of_property_read_u32(dev->of_node, "i2c_status", &reg->i2c_status);
        ret += of_property_read_u32(dev->of_node, "i2c_scale", &reg->i2c_scale);
        ret += of_property_read_u32(dev->of_node, "i2c_filter", &reg->i2c_filter);
        ret += of_property_read_u32(dev->of_node, "i2c_stretch", &reg->i2c_stretch);
        ret += of_property_read_u32(dev->of_node, "i2c_ext_9548_exits_flag", &reg->i2c_ext_9548_exits_flag);
        ret += of_property_read_u32(dev->of_node, "i2c_reg_len", &reg->i2c_reg_len);
        ret += of_property_read_u32(dev->of_node, "i2c_in_9548_chan", &reg->i2c_in_9548_chan);
        ret += of_property_read_u32(dev->of_node, "i2c_data_buf", &reg->i2c_data_buf);
        ret += of_property_read_string(dev->of_node, "dev_name", &fpga_i2c->dev_name);
        ret += of_property_read_u32(dev->of_node, "i2c_scale_value", &fpga_i2c->i2c_scale_value);
        ret += of_property_read_u32(dev->of_node, "i2c_filter_value", &fpga_i2c->i2c_filter_value);
        ret += of_property_read_u32(dev->of_node, "i2c_stretch_value", &fpga_i2c->i2c_stretch_value);
        ret += of_property_read_u32(dev->of_node, "i2c_timeout", &fpga_i2c->i2c_timeout);
        ret += of_property_read_u32(dev->of_node, "i2c_func_mode", &fpga_i2c->i2c_func_mode);
        ret += of_property_read_u32(dev->of_node, "i2c_reset_addr", &reset_cfg->reset_addr);
        ret += of_property_read_u32(dev->of_node, "i2c_reset_on", &reset_cfg->reset_on);
        ret += of_property_read_u32(dev->of_node, "i2c_reset_off", &reset_cfg->reset_off);
        ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_b", &reset_cfg->reset_delay_b);
        ret += of_property_read_u32(dev->of_node, "i2c_rst_delay", &reset_cfg->reset_delay);
        ret += of_property_read_u32(dev->of_node, "i2c_rst_delay_a", &reset_cfg->reset_delay_a);
        ret += of_property_read_u32(dev->of_node, "i2c_adap_reset_flag", &reset_cfg->i2c_adap_reset_flag);

        if (ret != 0) {
            FPGA_I2C_ERROR("dts config error, ret:%d.\n", ret);
            ret = -ENXIO;
            return ret;
        }

        rv = of_property_read_u32(dev->of_node, "i2c_data_buf_len_reg", &i2c_data_buf_len_reg);
        if (rv == 0) {
            ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, &reg->i2c_data_buf_len);
            if (ret < 0) {
                dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n",
                    i2c_data_buf_len_reg, ret);
                return ret;
            }
            FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n",
                i2c_data_buf_len_reg, reg->i2c_data_buf_len);
            if (reg->i2c_data_buf_len == 0) {
                reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT;
            }
        } else {
            ret = of_property_read_u32(dev->of_node, "i2c_data_buf_len", &reg->i2c_data_buf_len);
            if (ret != 0) {
                reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT;
                ret = 0;
            }
        }

        rv = of_property_read_u32(dev->of_node, "i2c_offset_reg", &i2c_offset_reg);
        if (rv == 0) {
            ret = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val);
            if (ret < 0) {
                dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, ret: %d\n",
                    i2c_offset_reg, ret);
                return ret;
            }
            FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n",
                i2c_offset_reg, i2c_offset_val);
            reg->i2c_scale +=i2c_offset_val;
            reg->i2c_filter += i2c_offset_val;
            reg->i2c_stretch += i2c_offset_val;
            reg->i2c_ext_9548_exits_flag += i2c_offset_val;
            reg->i2c_ext_9548_addr += i2c_offset_val;
            reg->i2c_ext_9548_chan += i2c_offset_val;
            reg->i2c_in_9548_chan += i2c_offset_val;
            reg->i2c_slave += i2c_offset_val;
            reg->i2c_reg += i2c_offset_val;
            reg->i2c_reg_len += i2c_offset_val;
            reg->i2c_data_len += i2c_offset_val;
            reg->i2c_ctrl += i2c_offset_val;
            reg->i2c_status += i2c_offset_val;
            reg->i2c_data_buf += i2c_offset_val;
        }

        ret = of_property_read_u32(dev->of_node, "i2c_err_vec", &reg->i2c_err_vec);
        if (ret != 0) {
            reg->i2c_err_vec = DTS_NO_CFG_FLAG;
            FPGA_I2C_VERBOSE("not support i2c_err_vec cfg. ret: %d, set DTS_NO_CFG_FLAG: %d\n",
                ret, reg->i2c_err_vec);
            ret = 0;    /* Not configuring i2c_err_vec is not an error  */
        } else {
            if (i2c_offset_val != 0) {
                reg->i2c_err_vec += i2c_offset_val;
            }
        }
    } else {
        if (dev->platform_data == NULL) {
            dev_err(fpga_i2c->dev, "Failed to get platform data config.\n");
            ret = -ENXIO;
            return ret;
        }
        fpga_i2c_bus_device = dev->platform_data;
        fpga_i2c->dev_name = fpga_i2c_bus_device->dev_name;
        fpga_i2c->adap_nr = fpga_i2c_bus_device->adap_nr;
        fpga_i2c->i2c_scale_value = fpga_i2c_bus_device->i2c_scale_value;
        fpga_i2c->i2c_filter_value = fpga_i2c_bus_device->i2c_filter_value;
        fpga_i2c->i2c_stretch_value = fpga_i2c_bus_device->i2c_stretch_value;
        fpga_i2c->i2c_timeout = fpga_i2c_bus_device->i2c_timeout;
        fpga_i2c->i2c_func_mode = fpga_i2c_bus_device->i2c_func_mode;
        fpga_i2c->i2c_params_check = fpga_i2c_bus_device->i2c_func_mode;

        reset_cfg->reset_addr = fpga_i2c_bus_device->i2c_reset_addr;
        reset_cfg->reset_on = fpga_i2c_bus_device->i2c_reset_on;
        reset_cfg->reset_off = fpga_i2c_bus_device->i2c_reset_off;
        reset_cfg->reset_delay_b = fpga_i2c_bus_device->i2c_rst_delay_b;
        reset_cfg->reset_delay = fpga_i2c_bus_device->i2c_rst_delay;
        reset_cfg->reset_delay_a = fpga_i2c_bus_device->i2c_rst_delay_a;
        reset_cfg->i2c_adap_reset_flag = fpga_i2c_bus_device->i2c_adap_reset_flag;

        reg->i2c_ext_9548_addr = fpga_i2c_bus_device->i2c_ext_9548_addr;
        reg->i2c_ext_9548_chan = fpga_i2c_bus_device->i2c_ext_9548_chan;
        reg->i2c_slave = fpga_i2c_bus_device->i2c_slave;
        reg->i2c_reg = fpga_i2c_bus_device->i2c_reg;
        reg->i2c_data_len = fpga_i2c_bus_device->i2c_data_len;
        reg->i2c_ctrl = fpga_i2c_bus_device->i2c_ctrl;
        reg->i2c_status = fpga_i2c_bus_device->i2c_status;
        reg->i2c_scale = fpga_i2c_bus_device->i2c_scale;
        reg->i2c_filter = fpga_i2c_bus_device->i2c_filter;
        reg->i2c_stretch = fpga_i2c_bus_device->i2c_stretch;
        reg->i2c_ext_9548_exits_flag = fpga_i2c_bus_device->i2c_ext_9548_exits_flag;
        reg->i2c_reg_len = fpga_i2c_bus_device->i2c_reg_len;
        reg->i2c_in_9548_chan = fpga_i2c_bus_device->i2c_in_9548_chan;
        reg->i2c_data_buf = fpga_i2c_bus_device->i2c_data_buf;

        i2c_data_buf_len_reg = fpga_i2c_bus_device->i2c_data_buf_len_reg;
        if (i2c_data_buf_len_reg > 0) {
            ret = fpga_reg_read_32(fpga_i2c, i2c_data_buf_len_reg, &reg->i2c_data_buf_len);
            if (ret < 0) {
                dev_err(fpga_i2c->dev, "Failed to get fpga i2c data buf length, reg addr: 0x%x, ret: %d\n",
                    i2c_data_buf_len_reg, ret);
                return ret;
            }
            FPGA_I2C_VERBOSE("fpga i2c data buf length reg addr: 0x%x, value: %d\n",
                i2c_data_buf_len_reg, reg->i2c_data_buf_len);
            if (reg->i2c_data_buf_len == 0) {
                reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT;
            }
        } else {
            if (fpga_i2c_bus_device->i2c_data_buf_len == 0) {
                reg->i2c_data_buf_len = FPGA_I2C_RDWR_MAX_LEN_DEFAULT;
                FPGA_I2C_VERBOSE("not support i2c_data_buf_len cfg, set default_val:%d\n",
                    reg->i2c_data_buf_len);
            } else {
                reg->i2c_data_buf_len = fpga_i2c_bus_device->i2c_data_buf_len;
            }
        }

        i2c_offset_reg = fpga_i2c_bus_device->i2c_offset_reg;
        if (i2c_offset_reg > 0) {
            rv = fpga_reg_read_32(fpga_i2c, i2c_offset_reg, &i2c_offset_val);
            if (rv < 0) {
                dev_err(fpga_i2c->dev, "Failed to get fpga i2c adapter offset value, reg addr: 0x%x, rv: %d\n",
                    i2c_offset_reg, rv);
                return rv;
            }
            FPGA_I2C_VERBOSE("fpga i2c adapter offset reg addr: 0x%x, value: %d\n",
                i2c_offset_reg, i2c_offset_val);
            reg->i2c_scale +=i2c_offset_val;
            reg->i2c_filter += i2c_offset_val;
            reg->i2c_stretch += i2c_offset_val;
            reg->i2c_ext_9548_exits_flag += i2c_offset_val;
            reg->i2c_ext_9548_addr += i2c_offset_val;
            reg->i2c_ext_9548_chan += i2c_offset_val;
            reg->i2c_in_9548_chan += i2c_offset_val;
            reg->i2c_slave += i2c_offset_val;
            reg->i2c_reg += i2c_offset_val;
            reg->i2c_reg_len += i2c_offset_val;
            reg->i2c_data_len += i2c_offset_val;
            reg->i2c_ctrl += i2c_offset_val;
            reg->i2c_status += i2c_offset_val;
            reg->i2c_data_buf += i2c_offset_val;
        }

        if (fpga_i2c_bus_device->i2c_err_vec == 0) {
            reg->i2c_err_vec = DTS_NO_CFG_FLAG;
            FPGA_I2C_VERBOSE("not support i2c_err_vec cfg, set DTS_NO_CFG_FLAG:%d\n",
                reg->i2c_err_vec);
        } else {
            reg->i2c_err_vec = fpga_i2c_bus_device->i2c_err_vec;
            if (i2c_offset_val != 0) {
                reg->i2c_err_vec += i2c_offset_val;
            }
        }
    }

    FPGA_I2C_VERBOSE("i2c_ext_9548_addr:0x%x, i2c_ext_9548_chan:0x%x, i2c_slave:0x%x, i2c_reg:0x%x, i2c_data_len:0x%x.\n",
        reg->i2c_ext_9548_addr, reg->i2c_ext_9548_chan, reg->i2c_slave, reg->i2c_reg, reg->i2c_data_len);
    FPGA_I2C_VERBOSE("i2c_ctrl:0x%x, i2c_status:0x%x, i2c_scale:0x%x, i2c_filter:0x%x, i2c_stretch:0x%x.\n",
        reg->i2c_ctrl, reg->i2c_status, reg->i2c_scale, reg->i2c_filter, reg->i2c_stretch);
    FPGA_I2C_VERBOSE("i2c_ext_9548_exits_flag:0x%x, i2c_in_9548_chan:0x%x, i2c_data_buf:0x%x, i2c_reg_len:0x%x, i2c_data_buf_len:0x%x.\n",
        reg->i2c_ext_9548_exits_flag, reg->i2c_in_9548_chan, reg->i2c_data_buf, reg->i2c_reg_len, reg->i2c_data_buf_len);
    FPGA_I2C_VERBOSE("dev_name:%s, i2c_scale_value:0x%x, i2c_filter_value:0x%x, i2c_stretch_value:0x%x, i2c_timeout:0x%x.\n",
        fpga_i2c->dev_name, fpga_i2c->i2c_scale_value, fpga_i2c->i2c_filter_value, fpga_i2c->i2c_stretch_value, fpga_i2c->i2c_timeout);
    FPGA_I2C_VERBOSE("i2c_reset_addr:0x%x, i2c_reset_on:0x%x, i2c_reset_off:0x%x, i2c_rst_delay_b:0x%x, i2c_rst_delay:0x%x, i2c_rst_delay_a:0x%x.\n",
        reset_cfg->reset_addr, reset_cfg->reset_on, reset_cfg->reset_off, reset_cfg->reset_delay_b, reset_cfg->reset_delay, reset_cfg->reset_delay_a);
    FPGA_I2C_VERBOSE("i2c_adap_reset_flag:0x%x.\n", reset_cfg->i2c_adap_reset_flag);
    FPGA_I2C_VERBOSE("i2c_err_vec:0x%x\n", reg->i2c_err_vec);

    return ret;
}