xref: /aosp_15_r20/external/libwebsockets/lib/drivers/led/led-gpio.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * Generic GPIO led
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
25*1c60b9acSAndroid Build Coastguard Worker #include "drivers/led/private-lib-drivers-led.h"
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_TIMER_CB)
LWS_PLAT_TIMER_CB(lws_led_timer_cb,th)28*1c60b9acSAndroid Build Coastguard Worker static LWS_PLAT_TIMER_CB(lws_led_timer_cb, th)
29*1c60b9acSAndroid Build Coastguard Worker {
30*1c60b9acSAndroid Build Coastguard Worker 	lws_led_state_t *lcs = LWS_PLAT_TIMER_CB_GET_OPAQUE(th);
31*1c60b9acSAndroid Build Coastguard Worker 
32*1c60b9acSAndroid Build Coastguard Worker 	lws_seq_timer_handle(lcs);
33*1c60b9acSAndroid Build Coastguard Worker }
34*1c60b9acSAndroid Build Coastguard Worker #endif
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker struct lws_led_state *
lws_led_gpio_create(const lws_led_ops_t * led_ops)37*1c60b9acSAndroid Build Coastguard Worker lws_led_gpio_create(const lws_led_ops_t *led_ops)
38*1c60b9acSAndroid Build Coastguard Worker {
39*1c60b9acSAndroid Build Coastguard Worker 	lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)led_ops;
40*1c60b9acSAndroid Build Coastguard Worker 	/*
41*1c60b9acSAndroid Build Coastguard Worker 	 * We allocate the main state object, and a 3 x seq dynamic footprint
42*1c60b9acSAndroid Build Coastguard Worker 	 * for each led, since it may be sequencing the transition between two
43*1c60b9acSAndroid Build Coastguard Worker 	 * other sequences.
44*1c60b9acSAndroid Build Coastguard Worker 	 */
45*1c60b9acSAndroid Build Coastguard Worker 
46*1c60b9acSAndroid Build Coastguard Worker 	lws_led_state_t *lcs = lws_zalloc(sizeof(lws_led_state_t) +
47*1c60b9acSAndroid Build Coastguard Worker 				(lgc->count_leds * sizeof(lws_led_state_chs_t)),
48*1c60b9acSAndroid Build Coastguard Worker 				__func__);
49*1c60b9acSAndroid Build Coastguard Worker 	int n;
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	if (!lcs)
52*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker 	lcs->controller = lgc;
55*1c60b9acSAndroid Build Coastguard Worker 
56*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_TIMER_CREATE)
57*1c60b9acSAndroid Build Coastguard Worker 	lcs->timer = LWS_PLAT_TIMER_CREATE("leds",
58*1c60b9acSAndroid Build Coastguard Worker 			LWS_LED_SEQUENCER_UPDATE_INTERVAL_MS, 1, lcs,
59*1c60b9acSAndroid Build Coastguard Worker 				  (TimerCallbackFunction_t)lws_led_timer_cb);
60*1c60b9acSAndroid Build Coastguard Worker 	if (!lcs->timer)
61*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
62*1c60b9acSAndroid Build Coastguard Worker #endif
63*1c60b9acSAndroid Build Coastguard Worker 
64*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < lgc->count_leds; n++) {
65*1c60b9acSAndroid Build Coastguard Worker 		const lws_led_gpio_map_t *map = &lgc->led_map[n];
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker 		if (map->pwm_ops) {
68*1c60b9acSAndroid Build Coastguard Worker 			lgc->gpio_ops->mode(map->gpio, LWSGGPIO_FL_READ);
69*1c60b9acSAndroid Build Coastguard Worker 			lgc->gpio_ops->set(map->gpio, 0);
70*1c60b9acSAndroid Build Coastguard Worker 		} else {
71*1c60b9acSAndroid Build Coastguard Worker 			lgc->gpio_ops->mode(map->gpio, LWSGGPIO_FL_WRITE);
72*1c60b9acSAndroid Build Coastguard Worker 			lgc->gpio_ops->set(map->gpio,
73*1c60b9acSAndroid Build Coastguard Worker 					   !lgc->led_map[n].active_level);
74*1c60b9acSAndroid Build Coastguard Worker 		}
75*1c60b9acSAndroid Build Coastguard Worker 	}
76*1c60b9acSAndroid Build Coastguard Worker 
77*1c60b9acSAndroid Build Coastguard Worker 	return lcs;
78*1c60b9acSAndroid Build Coastguard Worker }
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker void
lws_led_gpio_destroy(struct lws_led_state * lcs)81*1c60b9acSAndroid Build Coastguard Worker lws_led_gpio_destroy(struct lws_led_state *lcs)
82*1c60b9acSAndroid Build Coastguard Worker {
83*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_PLAT_TIMER_DELETE)
84*1c60b9acSAndroid Build Coastguard Worker 	LWS_PLAT_TIMER_DELETE(&lcs->timer);
85*1c60b9acSAndroid Build Coastguard Worker #endif
86*1c60b9acSAndroid Build Coastguard Worker 	lws_free(lcs);
87*1c60b9acSAndroid Build Coastguard Worker }
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker int
lws_led_gpio_lookup(const struct lws_led_ops * lo,const char * name)90*1c60b9acSAndroid Build Coastguard Worker lws_led_gpio_lookup(const struct lws_led_ops *lo, const char *name)
91*1c60b9acSAndroid Build Coastguard Worker {
92*1c60b9acSAndroid Build Coastguard Worker 	const lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)lo;
93*1c60b9acSAndroid Build Coastguard Worker 	int n;
94*1c60b9acSAndroid Build Coastguard Worker 
95*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < lgc->count_leds; n++)
96*1c60b9acSAndroid Build Coastguard Worker 		if (!strcmp(name, lgc->led_map[n].name))
97*1c60b9acSAndroid Build Coastguard Worker 			return n;
98*1c60b9acSAndroid Build Coastguard Worker 
99*1c60b9acSAndroid Build Coastguard Worker 	return -1;
100*1c60b9acSAndroid Build Coastguard Worker }
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker void
lws_led_gpio_intensity(const struct lws_led_ops * lo,const char * name,lws_led_intensity_t inten)103*1c60b9acSAndroid Build Coastguard Worker lws_led_gpio_intensity(const struct lws_led_ops *lo, const char *name,
104*1c60b9acSAndroid Build Coastguard Worker 		       lws_led_intensity_t inten)
105*1c60b9acSAndroid Build Coastguard Worker {
106*1c60b9acSAndroid Build Coastguard Worker 	const lws_led_gpio_controller_t *lgc = (lws_led_gpio_controller_t *)lo;
107*1c60b9acSAndroid Build Coastguard Worker 	int idx = lws_led_gpio_lookup(lo, name);
108*1c60b9acSAndroid Build Coastguard Worker 	const lws_led_gpio_map_t *map;
109*1c60b9acSAndroid Build Coastguard Worker 
110*1c60b9acSAndroid Build Coastguard Worker 	if (idx < 0)
111*1c60b9acSAndroid Build Coastguard Worker 		return;
112*1c60b9acSAndroid Build Coastguard Worker 
113*1c60b9acSAndroid Build Coastguard Worker 	map = &lgc->led_map[idx];
114*1c60b9acSAndroid Build Coastguard Worker 
115*1c60b9acSAndroid Build Coastguard Worker 	if (map->pwm_ops)
116*1c60b9acSAndroid Build Coastguard Worker 		map->pwm_ops->intensity(map->pwm_ops, map->gpio, inten);
117*1c60b9acSAndroid Build Coastguard Worker 	else
118*1c60b9acSAndroid Build Coastguard Worker 		lgc->gpio_ops->set(map->gpio,
119*1c60b9acSAndroid Build Coastguard Worker 				(!!map->active_level) ^ !(inten & 0x8000));
120*1c60b9acSAndroid Build Coastguard Worker }
121