@@ -2167,11 +2167,122 @@ static u32 i3c_master_i2c_funcs(struct i2c_adapter *adapter)
21672167 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C ;
21682168}
21692169
2170+ static u8 i3c_master_i2c_get_lvr (struct i2c_client * client )
2171+ {
2172+ /* Fall back to no spike filters and FM bus mode. */
2173+ u8 lvr = I3C_LVR_I2C_INDEX (2 ) | I3C_LVR_I2C_FM_MODE ;
2174+
2175+ if (client -> dev .of_node ) {
2176+ u32 reg [3 ];
2177+
2178+ if (!of_property_read_u32_array (client -> dev .of_node , "reg" ,
2179+ reg , ARRAY_SIZE (reg )))
2180+ lvr = reg [2 ];
2181+ }
2182+
2183+ return lvr ;
2184+ }
2185+
2186+ static int i3c_master_i2c_attach (struct i2c_adapter * adap , struct i2c_client * client )
2187+ {
2188+ struct i3c_master_controller * master = i2c_adapter_to_i3c_master (adap );
2189+ enum i3c_addr_slot_status status ;
2190+ struct i2c_dev_desc * i2cdev ;
2191+ int ret ;
2192+
2193+ /* Already added by board info? */
2194+ if (i3c_master_find_i2c_dev_by_addr (master , client -> addr ))
2195+ return 0 ;
2196+
2197+ status = i3c_bus_get_addr_slot_status (& master -> bus , client -> addr );
2198+ if (status != I3C_ADDR_SLOT_FREE )
2199+ return - EBUSY ;
2200+
2201+ i3c_bus_set_addr_slot_status (& master -> bus , client -> addr ,
2202+ I3C_ADDR_SLOT_I2C_DEV );
2203+
2204+ i2cdev = i3c_master_alloc_i2c_dev (master , client -> addr ,
2205+ i3c_master_i2c_get_lvr (client ));
2206+ if (IS_ERR (i2cdev )) {
2207+ ret = PTR_ERR (i2cdev );
2208+ goto out_clear_status ;
2209+ }
2210+
2211+ ret = i3c_master_attach_i2c_dev (master , i2cdev );
2212+ if (ret )
2213+ goto out_free_dev ;
2214+
2215+ return 0 ;
2216+
2217+ out_free_dev :
2218+ i3c_master_free_i2c_dev (i2cdev );
2219+ out_clear_status :
2220+ i3c_bus_set_addr_slot_status (& master -> bus , client -> addr ,
2221+ I3C_ADDR_SLOT_FREE );
2222+
2223+ return ret ;
2224+ }
2225+
2226+ static int i3c_master_i2c_detach (struct i2c_adapter * adap , struct i2c_client * client )
2227+ {
2228+ struct i3c_master_controller * master = i2c_adapter_to_i3c_master (adap );
2229+ struct i2c_dev_desc * dev ;
2230+
2231+ dev = i3c_master_find_i2c_dev_by_addr (master , client -> addr );
2232+ if (!dev )
2233+ return - ENODEV ;
2234+
2235+ i3c_master_detach_i2c_dev (dev );
2236+ i3c_bus_set_addr_slot_status (& master -> bus , dev -> addr ,
2237+ I3C_ADDR_SLOT_FREE );
2238+ i3c_master_free_i2c_dev (dev );
2239+
2240+ return 0 ;
2241+ }
2242+
21702243static const struct i2c_algorithm i3c_master_i2c_algo = {
21712244 .master_xfer = i3c_master_i2c_adapter_xfer ,
21722245 .functionality = i3c_master_i2c_funcs ,
21732246};
21742247
2248+ static int i3c_i2c_notifier_call (struct notifier_block * nb , unsigned long action ,
2249+ void * data )
2250+ {
2251+ struct i2c_adapter * adap ;
2252+ struct i2c_client * client ;
2253+ struct device * dev = data ;
2254+ struct i3c_master_controller * master ;
2255+ int ret ;
2256+
2257+ if (dev -> type != & i2c_client_type )
2258+ return 0 ;
2259+
2260+ client = to_i2c_client (dev );
2261+ adap = client -> adapter ;
2262+
2263+ if (adap -> algo != & i3c_master_i2c_algo )
2264+ return 0 ;
2265+
2266+ master = i2c_adapter_to_i3c_master (adap );
2267+
2268+ i3c_bus_maintenance_lock (& master -> bus );
2269+ switch (action ) {
2270+ case BUS_NOTIFY_ADD_DEVICE :
2271+ ret = i3c_master_i2c_attach (adap , client );
2272+ break ;
2273+ case BUS_NOTIFY_DEL_DEVICE :
2274+ ret = i3c_master_i2c_detach (adap , client );
2275+ break ;
2276+ }
2277+ i3c_bus_maintenance_unlock (& master -> bus );
2278+
2279+ return ret ;
2280+ }
2281+
2282+ static struct notifier_block i2cdev_notifier = {
2283+ .notifier_call = i3c_i2c_notifier_call ,
2284+ };
2285+
21752286static int i3c_master_i2c_adapter_init (struct i3c_master_controller * master )
21762287{
21772288 struct i2c_adapter * adap = i3c_master_to_i2c_adapter (master );
@@ -2699,12 +2810,27 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)
26992810
27002811static int __init i3c_init (void )
27012812{
2702- return bus_register (& i3c_bus_type );
2813+ int res = bus_register_notifier (& i2c_bus_type , & i2cdev_notifier );
2814+
2815+ if (res )
2816+ return res ;
2817+
2818+ res = bus_register (& i3c_bus_type );
2819+ if (res )
2820+ goto out_unreg_notifier ;
2821+
2822+ return 0 ;
2823+
2824+ out_unreg_notifier :
2825+ bus_unregister_notifier (& i2c_bus_type , & i2cdev_notifier );
2826+
2827+ return res ;
27032828}
27042829subsys_initcall (i3c_init );
27052830
27062831static void __exit i3c_exit (void )
27072832{
2833+ bus_unregister_notifier (& i2c_bus_type , & i2cdev_notifier );
27082834 idr_destroy (& i3c_bus_idr );
27092835 bus_unregister (& i3c_bus_type );
27102836}
0 commit comments