};
What are your thoughts about this, and do you think the form shown above
(and probably not the one in the patch) would be fitting, or is there a
better approach to this?
drivers/i2c/busses/i2c-qcom-cci.c | 274 ++++++++++++++++++++++++++++++
1 file changed, 274 insertions(+)
diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 07c11e2a446d..6754b5d11c52 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -117,6 +117,7 @@ struct cci_master {
};
struct cci_data {
+ bool read_params_from_dt;
unsigned int num_masters;
struct i2c_adapter_quirks quirks;
u16 queue_size[NUM_QUEUES];
@@ -520,11 +521,20 @@ static const struct dev_pm_ops qcom_cci_pm = {
SET_RUNTIME_PM_OPS(cci_suspend_runtime, cci_resume_runtime, NULL)
};
+static struct cci_data cci_dt_data = {
+ .read_params_from_dt = true,
+ .quirks = {},
+ .params[I2C_MODE_STANDARD] = {},
+ .params[I2C_MODE_FAST] = {},
+ .params[I2C_MODE_FAST_PLUS] = {},
+};
+
static int cci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
unsigned long cci_clk_rate = 0;
struct device_node *child;
+ struct cci_data *dt_data;
struct resource *r;
struct cci *cci;
int ret, i;
@@ -540,6 +550,267 @@ static int cci_probe(struct platform_device *pdev)
if (!cci->data)
return -ENOENT;
+ if (cci->data->read_params_from_dt) {
+ dt_data = &cci_dt_data;
+
+ /* CCI params */
+ ret = of_property_read_u32(dev->of_node, "num-masters", &val);
+ if (ret) {
+ dev_err(dev, "Error reading num-masters from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->num_masters = val;
+
+ ret = of_property_read_u16_array(dev->of_node, "queue-size", dt_data->queue_size,
+ (size_t)&dt_data->num_masters);
+ if (ret) {
+ dev_err(dev, "Error reading queue-size from DT, ret = %d", ret);
+ return ret;
+ }
+
+ if (ARRAY_SIZE(dt_data->queue_size) != dt_data->num_masters) {
+ dev_err(dev, "num-masters doesn't match the number of queue-size elements!");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "max-write-len", &val);
+ if (ret) {
+ dev_err(dev, "Error reading max-write-len from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->quirks.max_write_len = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "max-read-len", &val);
+ if (ret) {
+ dev_err(dev, "Error reading max-read-len from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->quirks.max_read_len = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "cci-clk-rate", &val);
+ if (ret) {
+ dev_err(dev, "Error reading cci-clk-rate from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->cci_clk_rate = (unsigned long)val;
+
+ /* STANDARD mode params */
+ ret = of_property_read_u32(dev->of_node, "thigh-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thigh-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].thigh = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tlow-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tlow-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].tlow = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sto-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sto-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].tsu_sto = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sta-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sta-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].tsu_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-dat-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-dat-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].thd_dat = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-sta-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-sta-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].thd_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tbuf-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tbuf-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].tbuf = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "scl-stretch-en-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading scl-stretch-en-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].scl_stretch_en = (u8)val;
+
+ ret = of_property_read_u32(dev->of_node, "trdhld-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading trdhld-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].trdhld = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsp-standard", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsp-standard from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_STANDARD].tsp = (u16)val;
+
+ /* FAST mode params */
+ ret = of_property_read_u32(dev->of_node, "thigh-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thigh-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].thigh = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tlow-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tlow-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].tlow = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sto-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sto-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].tsu_sto = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sta-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sta-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].tsu_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-dat-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-dat-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].thd_dat = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-sta-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-sta-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].thd_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tbuf-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tbuf-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].tbuf = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "scl-stretch-en-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading scl-stretch-en-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].scl_stretch_en = (u8)val;
+
+ ret = of_property_read_u32(dev->of_node, "trdhld-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading trdhld-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].trdhld = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsp-fast", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsp-fast from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST].tsp = (u16)val;
+
+ /* FAST_PLUS mode params */
+ ret = of_property_read_u32(dev->of_node, "thigh-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thigh-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].thigh = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tlow-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tlow-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].tlow = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sto-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sto-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].tsu_sto = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsu-sta-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsu-sta-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].tsu_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-dat-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-dat-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].thd_dat = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "thd-sta-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading thd-sta-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].thd_sta = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tbuf-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tbuf-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].tbuf = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "scl-stretch-en-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading scl-stretch-en-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].scl_stretch_en = (u8)val;
+
+ ret = of_property_read_u32(dev->of_node, "trdhld-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading trdhld-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].trdhld = (u16)val;
+
+ ret = of_property_read_u32(dev->of_node, "tsp-fast-plus", &val);
+ if (ret) {
+ dev_err(dev, "Error reading tsp-fast-plus from DT, ret = %d", ret);
+ return ret;
+ }
+ dt_data->params[I2C_MODE_FAST_PLUS].tsp = (u16)val;
+
+ /* Let's ship it! */
+ cci->data = dt_data;
+ }
+
for_each_available_child_of_node(dev->of_node, child) {
u32 idx;
@@ -818,6 +1089,9 @@ static const struct cci_data cci_msm8994_data = {
};
static const struct of_device_id cci_dt_match[] = {
+ { .compatible = "qcom,cci", .data = &cci_dt_data },
+
+ /* Legacy compatibles for older DTs */
{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
{ .compatible = "qcom,msm8994-cci", .data = &cci_msm8994_data},
{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
--
2.35.1