@@ -2167,11 +2167,122 @@ static u32 i3c_master_i2c_funcs(struct i2c_adapter *adapter)
2167
2167
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C ;
2168
2168
}
2169
2169
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
+
2170
2243
static const struct i2c_algorithm i3c_master_i2c_algo = {
2171
2244
.master_xfer = i3c_master_i2c_adapter_xfer ,
2172
2245
.functionality = i3c_master_i2c_funcs ,
2173
2246
};
2174
2247
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
+
2175
2286
static int i3c_master_i2c_adapter_init (struct i3c_master_controller * master )
2176
2287
{
2177
2288
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)
2699
2810
2700
2811
static int __init i3c_init (void )
2701
2812
{
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 ;
2703
2828
}
2704
2829
subsys_initcall (i3c_init );
2705
2830
2706
2831
static void __exit i3c_exit (void )
2707
2832
{
2833
+ bus_unregister_notifier (& i2c_bus_type , & i2cdev_notifier );
2708
2834
idr_destroy (& i3c_bus_idr );
2709
2835
bus_unregister (& i3c_bus_type );
2710
2836
}
0 commit comments