led: Configure LED default-state on boot
In case the DT LED subnode contains "default-state" property set to either "on" or "off", probe the LED driver and configure the LED state automatically. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Alex Nemirovsky <alex.nemirovsky@cortina-access.com> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com> Cc: Philippe Reynes <philippe.reynes@softathome.com> Cc: Sean Anderson <seanga2@gmail.com> Cc: Simon Glass <sjg@chromium.org> Cc: Steven Lawrance <steven.lawrance@softathome.com> [trini: Update the relevant test now that we have support] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
		
							parent
							
								
									2d1deaf88e
								
							
						
					
					
						commit
						72675b063b
					
				|  | @ -66,43 +66,49 @@ int led_set_period(struct udevice *dev, int period_ms) | |||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* This is superseded by led_post_bind()/led_post_probe() below. */ | ||||
| int led_default_state(void) | ||||
| { | ||||
| 	struct udevice *dev; | ||||
| 	struct uclass *uc; | ||||
| 	const char *default_state; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = uclass_get(UCLASS_LED, &uc); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	for (uclass_find_first_device(UCLASS_LED, &dev); | ||||
| 	     dev; | ||||
| 	     uclass_find_next_device(&dev)) { | ||||
| 		default_state = dev_read_string(dev, "default-state"); | ||||
| 		if (!default_state) | ||||
| 			continue; | ||||
| 		ret = device_probe(dev); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 		if (!strncmp(default_state, "on", 2)) | ||||
| 			led_set_state(dev, LEDST_ON); | ||||
| 		else if (!strncmp(default_state, "off", 3)) | ||||
| 			led_set_state(dev, LEDST_OFF); | ||||
| 		/* default-state = "keep" : device is only probed */ | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int led_post_bind(struct udevice *dev) | ||||
| { | ||||
| 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); | ||||
| 	const char *default_state; | ||||
| 
 | ||||
| 	uc_plat->label = dev_read_string(dev, "label"); | ||||
| 	if (!uc_plat->label) | ||||
| 		uc_plat->label = ofnode_get_name(dev_ofnode(dev)); | ||||
| 
 | ||||
| 	uc_plat->default_state = LEDST_COUNT; | ||||
| 
 | ||||
| 	default_state = dev_read_string(dev, "default-state"); | ||||
| 	if (!default_state) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (!strncmp(default_state, "on", 2)) | ||||
| 		uc_plat->default_state = LEDST_ON; | ||||
| 	else if (!strncmp(default_state, "off", 3)) | ||||
| 		uc_plat->default_state = LEDST_OFF; | ||||
| 	else | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * In case the LED has default-state DT property, trigger | ||||
| 	 * probe() to configure its default state during startup. | ||||
| 	 */ | ||||
| 	return device_probe(dev); | ||||
| } | ||||
| 
 | ||||
| static int led_post_probe(struct udevice *dev) | ||||
| { | ||||
| 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); | ||||
| 
 | ||||
| 	if (uc_plat->default_state == LEDST_ON || | ||||
| 	    uc_plat->default_state == LEDST_OFF) | ||||
| 		led_set_state(dev, uc_plat->default_state); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -111,4 +117,5 @@ UCLASS_DRIVER(led) = { | |||
| 	.name		= "led", | ||||
| 	.per_device_plat_auto	= sizeof(struct led_uc_plat), | ||||
| 	.post_bind	= led_post_bind, | ||||
| 	.post_probe	= led_post_probe, | ||||
| }; | ||||
|  |  | |||
|  | @ -9,24 +9,6 @@ | |||
| 
 | ||||
| struct udevice; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct led_uc_plat - Platform data the uclass stores about each device | ||||
|  * | ||||
|  * @label:	LED label | ||||
|  */ | ||||
| struct led_uc_plat { | ||||
| 	const char *label; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct led_uc_priv - Private data the uclass stores about each device | ||||
|  * | ||||
|  * @period_ms:	Flash period in milliseconds | ||||
|  */ | ||||
| struct led_uc_priv { | ||||
| 	int period_ms; | ||||
| }; | ||||
| 
 | ||||
| enum led_state_t { | ||||
| 	LEDST_OFF = 0, | ||||
| 	LEDST_ON = 1, | ||||
|  | @ -38,6 +20,26 @@ enum led_state_t { | |||
| 	LEDST_COUNT, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct led_uc_plat - Platform data the uclass stores about each device | ||||
|  * | ||||
|  * @label:	LED label | ||||
|  * @default_state:	LED default state | ||||
|  */ | ||||
| struct led_uc_plat { | ||||
| 	const char *label; | ||||
| 	enum led_state_t default_state; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct led_uc_priv - Private data the uclass stores about each device | ||||
|  * | ||||
|  * @period_ms:	Flash period in milliseconds | ||||
|  */ | ||||
| struct led_uc_priv { | ||||
| 	int period_ms; | ||||
| }; | ||||
| 
 | ||||
| struct led_ops { | ||||
| 	/**
 | ||||
| 	 * set_state() - set the state of an LED | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ static int dm_test_cmd_pinmux_status_pinname(struct unit_test_state *uts) | |||
| 	/* Test that 'pinmux status <pinname>' displays the selected pin. */ | ||||
| 	console_record_reset(); | ||||
| 	run_command("pinmux status a5", 0); | ||||
| 	ut_assert_nextlinen("a5        : gpio input ."); | ||||
| 	ut_assert_nextlinen("a5        : gpio output ."); | ||||
| 	ut_assert_console_end(); | ||||
| 
 | ||||
| 	console_record_reset(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue