aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i3c/master.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index b9d2b88928e1..54026be03998 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -91,6 +91,12 @@ void i3c_bus_normaluse_unlock(struct i3c_bus *bus)
91 up_read(&bus->lock); 91 up_read(&bus->lock);
92} 92}
93 93
94static struct i3c_master_controller *
95i3c_bus_to_i3c_master(struct i3c_bus *i3cbus)
96{
97 return container_of(i3cbus, struct i3c_master_controller, bus);
98}
99
94static struct i3c_master_controller *dev_to_i3cmaster(struct device *dev) 100static struct i3c_master_controller *dev_to_i3cmaster(struct device *dev)
95{ 101{
96 return container_of(dev, struct i3c_master_controller, dev); 102 return container_of(dev, struct i3c_master_controller, dev);
@@ -565,20 +571,38 @@ static const struct device_type i3c_masterdev_type = {
565 .groups = i3c_masterdev_groups, 571 .groups = i3c_masterdev_groups,
566}; 572};
567 573
568int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode) 574int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
575 unsigned long max_i2c_scl_rate)
569{ 576{
570 i3cbus->mode = mode; 577 struct i3c_master_controller *master = i3c_bus_to_i3c_master(i3cbus);
571 578
572 if (!i3cbus->scl_rate.i3c) 579 i3cbus->mode = mode;
573 i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
574 580
575 if (!i3cbus->scl_rate.i2c) { 581 switch (i3cbus->mode) {
576 if (i3cbus->mode == I3C_BUS_MODE_MIXED_SLOW) 582 case I3C_BUS_MODE_PURE:
577 i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE; 583 if (!i3cbus->scl_rate.i3c)
578 else 584 i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
579 i3cbus->scl_rate.i2c = I3C_BUS_I2C_FM_PLUS_SCL_RATE; 585 break;
586 case I3C_BUS_MODE_MIXED_FAST:
587 if (!i3cbus->scl_rate.i3c)
588 i3cbus->scl_rate.i3c = I3C_BUS_TYP_I3C_SCL_RATE;
589 if (!i3cbus->scl_rate.i2c)
590 i3cbus->scl_rate.i2c = max_i2c_scl_rate;
591 break;
592 case I3C_BUS_MODE_MIXED_SLOW:
593 if (!i3cbus->scl_rate.i2c)
594 i3cbus->scl_rate.i2c = max_i2c_scl_rate;
595 if (!i3cbus->scl_rate.i3c ||
596 i3cbus->scl_rate.i3c > i3cbus->scl_rate.i2c)
597 i3cbus->scl_rate.i3c = i3cbus->scl_rate.i2c;
598 break;
599 default:
600 return -EINVAL;
580 } 601 }
581 602
603 dev_dbg(&master->dev, "i2c-scl = %ld Hz i3c-scl = %ld Hz\n",
604 i3cbus->scl_rate.i2c, i3cbus->scl_rate.i3c);
605
582 /* 606 /*
583 * I3C/I2C frequency may have been overridden, check that user-provided 607 * I3C/I2C frequency may have been overridden, check that user-provided
584 * values are not exceeding max possible frequency. 608 * values are not exceeding max possible frequency.
@@ -1976,9 +2000,6 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
1976 /* LVR is encoded in reg[2]. */ 2000 /* LVR is encoded in reg[2]. */
1977 boardinfo->lvr = reg[2]; 2001 boardinfo->lvr = reg[2];
1978 2002
1979 if (boardinfo->lvr & I3C_LVR_I2C_FM_MODE)
1980 master->bus.scl_rate.i2c = I3C_BUS_I2C_FM_SCL_RATE;
1981
1982 list_add_tail(&boardinfo->node, &master->boardinfo.i2c); 2003 list_add_tail(&boardinfo->node, &master->boardinfo.i2c);
1983 of_node_get(node); 2004 of_node_get(node);
1984 2005
@@ -2424,6 +2445,7 @@ int i3c_master_register(struct i3c_master_controller *master,
2424 const struct i3c_master_controller_ops *ops, 2445 const struct i3c_master_controller_ops *ops,
2425 bool secondary) 2446 bool secondary)
2426{ 2447{
2448 unsigned long i2c_scl_rate = I3C_BUS_I2C_FM_PLUS_SCL_RATE;
2427 struct i3c_bus *i3cbus = i3c_master_get_bus(master); 2449 struct i3c_bus *i3cbus = i3c_master_get_bus(master);
2428 enum i3c_bus_mode mode = I3C_BUS_MODE_PURE; 2450 enum i3c_bus_mode mode = I3C_BUS_MODE_PURE;
2429 struct i2c_dev_boardinfo *i2cbi; 2451 struct i2c_dev_boardinfo *i2cbi;
@@ -2473,9 +2495,12 @@ int i3c_master_register(struct i3c_master_controller *master,
2473 ret = -EINVAL; 2495 ret = -EINVAL;
2474 goto err_put_dev; 2496 goto err_put_dev;
2475 } 2497 }
2498
2499 if (i2cbi->lvr & I3C_LVR_I2C_FM_MODE)
2500 i2c_scl_rate = I3C_BUS_I2C_FM_SCL_RATE;
2476 } 2501 }
2477 2502
2478 ret = i3c_bus_set_mode(i3cbus, mode); 2503 ret = i3c_bus_set_mode(i3cbus, mode, i2c_scl_rate);
2479 if (ret) 2504 if (ret)
2480 goto err_put_dev; 2505 goto err_put_dev;
2481 2506