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 | #endif | ||||||
| 
 | 
 | ||||||
|  | /* This is superseded by led_post_bind()/led_post_probe() below. */ | ||||||
| int led_default_state(void) | int led_default_state(void) | ||||||
| { | { | ||||||
| 	struct udevice *dev; | 	return 0; | ||||||
| 	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; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int led_post_bind(struct udevice *dev) | static int led_post_bind(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); | 	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); | ||||||
|  | 	const char *default_state; | ||||||
| 
 | 
 | ||||||
| 	uc_plat->label = dev_read_string(dev, "label"); | 	uc_plat->label = dev_read_string(dev, "label"); | ||||||
| 	if (!uc_plat->label) | 	if (!uc_plat->label) | ||||||
| 		uc_plat->label = ofnode_get_name(dev_ofnode(dev)); | 		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; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -111,4 +117,5 @@ UCLASS_DRIVER(led) = { | ||||||
| 	.name		= "led", | 	.name		= "led", | ||||||
| 	.per_device_plat_auto	= sizeof(struct led_uc_plat), | 	.per_device_plat_auto	= sizeof(struct led_uc_plat), | ||||||
| 	.post_bind	= led_post_bind, | 	.post_bind	= led_post_bind, | ||||||
|  | 	.post_probe	= led_post_probe, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -9,24 +9,6 @@ | ||||||
| 
 | 
 | ||||||
| struct udevice; | 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 { | enum led_state_t { | ||||||
| 	LEDST_OFF = 0, | 	LEDST_OFF = 0, | ||||||
| 	LEDST_ON = 1, | 	LEDST_ON = 1, | ||||||
|  | @ -38,6 +20,26 @@ enum led_state_t { | ||||||
| 	LEDST_COUNT, | 	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 { | struct led_ops { | ||||||
| 	/**
 | 	/**
 | ||||||
| 	 * set_state() - set the state of an LED | 	 * 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. */ | 	/* Test that 'pinmux status <pinname>' displays the selected pin. */ | ||||||
| 	console_record_reset(); | 	console_record_reset(); | ||||||
| 	run_command("pinmux status a5", 0); | 	run_command("pinmux status a5", 0); | ||||||
| 	ut_assert_nextlinen("a5        : gpio input ."); | 	ut_assert_nextlinen("a5        : gpio output ."); | ||||||
| 	ut_assert_console_end(); | 	ut_assert_console_end(); | ||||||
| 
 | 
 | ||||||
| 	console_record_reset(); | 	console_record_reset(); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue