10
10
#include <linux/device.h>
11
11
#include <linux/dev_printk.h>
12
12
#include <linux/err.h>
13
+ #include <linux/gpio/consumer.h>
13
14
#include <linux/i2c.h>
14
15
#include <linux/i2c-of-prober.h>
15
16
#include <linux/module.h>
31
32
* address responds.
32
33
*
33
34
* TODO:
34
- * - Support handling common GPIOs.
35
35
* - Support I2C muxes
36
36
*/
37
37
@@ -246,14 +246,74 @@ static void i2c_of_probe_simple_disable_regulator(struct device *dev, struct i2c
246
246
regulator_disable (ctx -> supply );
247
247
}
248
248
249
+ static int i2c_of_probe_simple_get_gpiod (struct device * dev , struct device_node * node ,
250
+ struct i2c_of_probe_simple_ctx * ctx )
251
+ {
252
+ struct fwnode_handle * fwnode = of_fwnode_handle (node );
253
+ struct gpio_desc * gpiod ;
254
+ const char * con_id ;
255
+
256
+ /* NULL signals no GPIO needed */
257
+ if (!ctx -> opts -> gpio_name )
258
+ return 0 ;
259
+
260
+ /* An empty string signals an unnamed GPIO */
261
+ if (!ctx -> opts -> gpio_name [0 ])
262
+ con_id = NULL ;
263
+ else
264
+ con_id = ctx -> opts -> gpio_name ;
265
+
266
+ gpiod = fwnode_gpiod_get_index (fwnode , con_id , 0 , GPIOD_ASIS , "i2c-of-prober" );
267
+ if (IS_ERR (gpiod ))
268
+ return PTR_ERR (gpiod );
269
+
270
+ ctx -> gpiod = gpiod ;
271
+
272
+ return 0 ;
273
+ }
274
+
275
+ static void i2c_of_probe_simple_put_gpiod (struct i2c_of_probe_simple_ctx * ctx )
276
+ {
277
+ gpiod_put (ctx -> gpiod );
278
+ ctx -> gpiod = NULL ;
279
+ }
280
+
281
+ static int i2c_of_probe_simple_set_gpio (struct device * dev , struct i2c_of_probe_simple_ctx * ctx )
282
+ {
283
+ int ret ;
284
+
285
+ if (!ctx -> gpiod )
286
+ return 0 ;
287
+
288
+ dev_dbg (dev , "Configuring GPIO\n" );
289
+
290
+ ret = gpiod_direction_output (ctx -> gpiod , ctx -> opts -> gpio_assert_to_enable );
291
+ if (ret )
292
+ return ret ;
293
+
294
+ if (ctx -> opts -> post_gpio_config_delay_ms )
295
+ msleep (ctx -> opts -> post_gpio_config_delay_ms );
296
+
297
+ return 0 ;
298
+ }
299
+
300
+ static void i2c_of_probe_simple_disable_gpio (struct device * dev , struct i2c_of_probe_simple_ctx * ctx )
301
+ {
302
+ gpiod_set_value (ctx -> gpiod , !ctx -> opts -> gpio_assert_to_enable );
303
+ }
304
+
249
305
/**
250
306
* i2c_of_probe_simple_enable - Simple helper for I2C OF prober to get and enable resources
251
307
* @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages
252
308
* @bus_node: Pointer to the &struct device_node of the I2C adapter.
253
309
* @data: Pointer to &struct i2c_of_probe_simple_ctx helper context.
254
310
*
255
311
* If &i2c_of_probe_simple_opts->supply_name is given, request the named regulator supply.
312
+ * If &i2c_of_probe_simple_opts->gpio_name is given, request the named GPIO. Or if it is
313
+ * the empty string, request the unnamed GPIO.
256
314
* If a regulator supply was found, enable that regulator.
315
+ * If a GPIO line was found, configure the GPIO line to output and set value
316
+ * according to given options.
257
317
*
258
318
* Return: %0 on success or no-op, or a negative error number on failure.
259
319
*/
@@ -282,12 +342,24 @@ int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node,
282
342
if (ret )
283
343
goto out_put_node ;
284
344
285
- ret = i2c_of_probe_simple_enable_regulator (dev , ctx );
345
+ ret = i2c_of_probe_simple_get_gpiod (dev , node , ctx );
286
346
if (ret )
287
347
goto out_put_supply ;
288
348
349
+ ret = i2c_of_probe_simple_enable_regulator (dev , ctx );
350
+ if (ret )
351
+ goto out_put_gpiod ;
352
+
353
+ ret = i2c_of_probe_simple_set_gpio (dev , ctx );
354
+ if (ret )
355
+ goto out_disable_regulator ;
356
+
289
357
return 0 ;
290
358
359
+ out_disable_regulator :
360
+ i2c_of_probe_simple_disable_regulator (dev , ctx );
361
+ out_put_gpiod :
362
+ i2c_of_probe_simple_put_gpiod (ctx );
291
363
out_put_supply :
292
364
i2c_of_probe_simple_put_supply (ctx );
293
365
out_put_node :
@@ -296,24 +368,48 @@ int i2c_of_probe_simple_enable(struct device *dev, struct device_node *bus_node,
296
368
}
297
369
EXPORT_SYMBOL_NS_GPL (i2c_of_probe_simple_enable , I2C_OF_PROBER );
298
370
371
+ /**
372
+ * i2c_of_probe_simple_cleanup_early - \
373
+ * Simple helper for I2C OF prober to release GPIOs before component is enabled
374
+ * @dev: Pointer to the &struct device of the caller; unused.
375
+ * @data: Pointer to &struct i2c_of_probe_simple_ctx helper context.
376
+ *
377
+ * GPIO descriptors are exclusive and have to be released before the
378
+ * actual driver probes so that the latter can acquire them.
379
+ */
380
+ void i2c_of_probe_simple_cleanup_early (struct device * dev , void * data )
381
+ {
382
+ struct i2c_of_probe_simple_ctx * ctx = data ;
383
+
384
+ i2c_of_probe_simple_put_gpiod (ctx );
385
+ }
386
+ EXPORT_SYMBOL_NS_GPL (i2c_of_probe_simple_cleanup_early , I2C_OF_PROBER );
387
+
299
388
/**
300
389
* i2c_of_probe_simple_cleanup - Clean up and release resources for I2C OF prober simple helpers
301
390
* @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages
302
391
* @data: Pointer to &struct i2c_of_probe_simple_ctx helper context.
303
392
*
393
+ * * If a GPIO line was found and not yet released, set its value to the opposite of that
394
+ * set in i2c_of_probe_simple_enable() and release it.
304
395
* * If a regulator supply was found, disable that regulator and release it.
305
396
*/
306
397
void i2c_of_probe_simple_cleanup (struct device * dev , void * data )
307
398
{
308
399
struct i2c_of_probe_simple_ctx * ctx = data ;
309
400
401
+ /* GPIO operations here are no-ops if i2c_of_probe_simple_cleanup_early was called. */
402
+ i2c_of_probe_simple_disable_gpio (dev , ctx );
403
+ i2c_of_probe_simple_put_gpiod (ctx );
404
+
310
405
i2c_of_probe_simple_disable_regulator (dev , ctx );
311
406
i2c_of_probe_simple_put_supply (ctx );
312
407
}
313
408
EXPORT_SYMBOL_NS_GPL (i2c_of_probe_simple_cleanup , I2C_OF_PROBER );
314
409
315
410
struct i2c_of_probe_ops i2c_of_probe_simple_ops = {
316
411
.enable = i2c_of_probe_simple_enable ,
412
+ .cleanup_early = i2c_of_probe_simple_cleanup_early ,
317
413
.cleanup = i2c_of_probe_simple_cleanup ,
318
414
};
319
415
EXPORT_SYMBOL_NS_GPL (i2c_of_probe_simple_ops , I2C_OF_PROBER );
0 commit comments