Lines Matching +full:gpio +full:- +full:leds

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs
15 #include <linux/gpio/consumer.h>
16 #include <linux/leds.h>
58 struct netxbig_led *leds; member
63 * GPIO extension bus.
72 for (pin = 0; pin < gpio_ext->num_addr; pin++) in gpio_ext_set_addr()
73 gpiod_set_value(gpio_ext->addr[pin], (addr >> pin) & 1); in gpio_ext_set_addr()
80 for (pin = 0; pin < gpio_ext->num_data; pin++) in gpio_ext_set_data()
81 gpiod_set_value(gpio_ext->data[pin], (data >> pin) & 1); in gpio_ext_set_data()
87 gpiod_set_value(gpio_ext->enable, 0); in gpio_ext_enable_select()
88 gpiod_set_value(gpio_ext->enable, 1); in gpio_ext_enable_select()
135 return -EINVAL; in netxbig_led_get_timer_mode()
150 led_dat->timer, led_dat->num_timer); in netxbig_led_blink_set()
154 mode_val = led_dat->mode_val[mode]; in netxbig_led_blink_set()
156 return -EINVAL; in netxbig_led_blink_set()
158 spin_lock_irq(&led_dat->lock); in netxbig_led_blink_set()
160 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); in netxbig_led_blink_set()
161 led_dat->mode = mode; in netxbig_led_blink_set()
163 spin_unlock_irq(&led_dat->lock); in netxbig_led_blink_set()
178 spin_lock_irqsave(&led_dat->lock, flags); in netxbig_led_set()
184 if (led_dat->sata) in netxbig_led_set()
186 else if (led_dat->mode == NETXBIG_LED_OFF) in netxbig_led_set()
189 mode = led_dat->mode; in netxbig_led_set()
191 mode_val = led_dat->mode_val[mode]; in netxbig_led_set()
193 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); in netxbig_led_set()
194 led_dat->mode = mode; in netxbig_led_set()
197 * SATA LEDs. So, change the brightness setting for a single in netxbig_led_set()
201 gpio_ext_set_value(led_dat->gpio_ext, in netxbig_led_set()
202 led_dat->bright_addr, value); in netxbig_led_set()
204 spin_unlock_irqrestore(&led_dat->lock, flags); in netxbig_led_set()
225 spin_lock_irq(&led_dat->lock); in sata_store()
227 if (led_dat->sata == enable) { in sata_store()
232 if (led_dat->mode != NETXBIG_LED_ON && in sata_store()
233 led_dat->mode != NETXBIG_LED_SATA) in sata_store()
234 mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */ in sata_store()
240 mode_val = led_dat->mode_val[mode]; in sata_store()
242 ret = -EINVAL; in sata_store()
246 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); in sata_store()
247 led_dat->mode = mode; in sata_store()
248 led_dat->sata = enable; in sata_store()
253 spin_unlock_irq(&led_dat->lock); in sata_store()
265 return sprintf(buf, "%d\n", led_dat->sata); in sata_show()
281 spin_lock_init(&led_dat->lock); in create_netxbig_led()
282 led_dat->gpio_ext = pdata->gpio_ext; in create_netxbig_led()
283 led_dat->cdev.name = template->name; in create_netxbig_led()
284 led_dat->cdev.default_trigger = template->default_trigger; in create_netxbig_led()
285 led_dat->cdev.blink_set = netxbig_led_blink_set; in create_netxbig_led()
286 led_dat->cdev.brightness_set = netxbig_led_set; in create_netxbig_led()
288 * Because the GPIO extension bus don't allow to read registers in create_netxbig_led()
297 led_dat->sata = 0; in create_netxbig_led()
298 led_dat->cdev.brightness = LED_OFF; in create_netxbig_led()
299 led_dat->cdev.max_brightness = template->bright_max; in create_netxbig_led()
300 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; in create_netxbig_led()
301 led_dat->mode_addr = template->mode_addr; in create_netxbig_led()
302 led_dat->mode_val = template->mode_val; in create_netxbig_led()
303 led_dat->bright_addr = template->bright_addr; in create_netxbig_led()
304 led_dat->timer = pdata->timer; in create_netxbig_led()
305 led_dat->num_timer = pdata->num_timer; in create_netxbig_led()
310 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) in create_netxbig_led()
311 led_dat->cdev.groups = netxbig_led_groups; in create_netxbig_led()
313 return devm_led_classdev_register(&pdev->dev, &led_dat->cdev); in create_netxbig_led()
317 * netxbig_gpio_ext_remove() - Clean up GPIO extension data
320 * Since we pick GPIO descriptors from another device than the device our
329 for (i = 0; i < gpio_ext->num_addr; i++) in netxbig_gpio_ext_remove()
330 gpiod_put(gpio_ext->addr[i]); in netxbig_gpio_ext_remove()
331 for (i = 0; i < gpio_ext->num_data; i++) in netxbig_gpio_ext_remove()
332 gpiod_put(gpio_ext->data[i]); in netxbig_gpio_ext_remove()
333 gpiod_put(gpio_ext->enable); in netxbig_gpio_ext_remove()
337 * netxbig_gpio_ext_get() - Obtain GPIO extension device data
339 * @gpio_ext_dev: the GPIO extension device
340 * @gpio_ext: the data structure holding the GPIO extension data
342 * This function walks the subdevice that only contain GPIO line
343 * handles in the device tree and obtains the GPIO descriptors from that
359 "Failed to count GPIOs in DT property addr-gpios\n"); in netxbig_gpio_ext_get()
365 return -ENOMEM; in netxbig_gpio_ext_get()
368 * We cannot use devm_ managed resources with these GPIO descriptors in netxbig_gpio_ext_get()
369 * since they are associated with the "GPIO extension device" which in netxbig_gpio_ext_get()
372 * GPIO descriptors from the device. in netxbig_gpio_ext_get()
379 gpiod_set_consumer_name(gpiod, "GPIO extension addr"); in netxbig_gpio_ext_get()
382 gpio_ext->addr = addr; in netxbig_gpio_ext_get()
383 gpio_ext->num_addr = num_addr; in netxbig_gpio_ext_get()
388 "Failed to count GPIOs in DT property data-gpios\n"); in netxbig_gpio_ext_get()
394 return -ENOMEM; in netxbig_gpio_ext_get()
401 gpiod_set_consumer_name(gpiod, "GPIO extension data"); in netxbig_gpio_ext_get()
404 gpio_ext->data = data; in netxbig_gpio_ext_get()
405 gpio_ext->num_data = num_data; in netxbig_gpio_ext_get()
410 "Failed to get GPIO from DT property enable-gpio\n"); in netxbig_gpio_ext_get()
413 gpiod_set_consumer_name(gpiod, "GPIO extension enable"); in netxbig_gpio_ext_get()
414 gpio_ext->enable = gpiod; in netxbig_gpio_ext_get()
428 struct netxbig_led *leds, *led; in netxbig_leds_get_of_pdata() local
434 /* GPIO extension */ in netxbig_leds_get_of_pdata()
435 gpio_ext_np = of_parse_phandle(np, "gpio-ext", 0); in netxbig_leds_get_of_pdata()
437 dev_err(dev, "Failed to get DT handle gpio-ext\n"); in netxbig_leds_get_of_pdata()
438 return -EINVAL; in netxbig_leds_get_of_pdata()
442 dev_err(dev, "Failed to find platform device for gpio-ext\n"); in netxbig_leds_get_of_pdata()
443 return -ENODEV; in netxbig_leds_get_of_pdata()
445 gpio_ext_dev = &gpio_ext_pdev->dev; in netxbig_leds_get_of_pdata()
450 ret = -ENOMEM; in netxbig_leds_get_of_pdata()
457 pdata->gpio_ext = gpio_ext; in netxbig_leds_get_of_pdata()
463 ret = -EINVAL; in netxbig_leds_get_of_pdata()
471 ret = -ENOMEM; in netxbig_leds_get_of_pdata()
480 ret = -EINVAL; in netxbig_leds_get_of_pdata()
490 pdata->timer = timers; in netxbig_leds_get_of_pdata()
491 pdata->num_timer = num_timers; in netxbig_leds_get_of_pdata()
494 /* LEDs */ in netxbig_leds_get_of_pdata()
498 ret = -ENODEV; in netxbig_leds_get_of_pdata()
502 leds = devm_kcalloc(dev, num_leds, sizeof(*leds), GFP_KERNEL); in netxbig_leds_get_of_pdata()
503 if (!leds) { in netxbig_leds_get_of_pdata()
504 ret = -ENOMEM; in netxbig_leds_get_of_pdata()
508 led = leds; in netxbig_leds_get_of_pdata()
514 ret = of_property_read_u32(child, "mode-addr", in netxbig_leds_get_of_pdata()
515 &led->mode_addr); in netxbig_leds_get_of_pdata()
519 ret = of_property_read_u32(child, "bright-addr", in netxbig_leds_get_of_pdata()
520 &led->bright_addr); in netxbig_leds_get_of_pdata()
524 ret = of_property_read_u32(child, "max-brightness", in netxbig_leds_get_of_pdata()
525 &led->bright_max); in netxbig_leds_get_of_pdata()
534 ret = -ENOMEM; in netxbig_leds_get_of_pdata()
541 ret = of_property_count_u32_elems(child, "mode-val"); in netxbig_leds_get_of_pdata()
543 ret = -EINVAL; in netxbig_leds_get_of_pdata()
548 ret = -EINVAL; in netxbig_leds_get_of_pdata()
557 "mode-val", 2 * i, &mode); in netxbig_leds_get_of_pdata()
559 "mode-val", 2 * i + 1, &val); in netxbig_leds_get_of_pdata()
561 ret = -EINVAL; in netxbig_leds_get_of_pdata()
566 led->mode_val = mode_val; in netxbig_leds_get_of_pdata()
569 led->name = string; in netxbig_leds_get_of_pdata()
571 led->name = child->name; in netxbig_leds_get_of_pdata()
574 "linux,default-trigger", &string)) in netxbig_leds_get_of_pdata()
575 led->default_trigger = string; in netxbig_leds_get_of_pdata()
580 pdata->leds = leds; in netxbig_leds_get_of_pdata()
581 pdata->num_leds = num_leds; in netxbig_leds_get_of_pdata()
591 { .compatible = "lacie,netxbig-leds", },
603 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); in netxbig_led_probe()
605 return -ENOMEM; in netxbig_led_probe()
606 ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata); in netxbig_led_probe()
610 leds_data = devm_kcalloc(&pdev->dev, in netxbig_led_probe()
611 pdata->num_leds, sizeof(*leds_data), in netxbig_led_probe()
614 return -ENOMEM; in netxbig_led_probe()
616 for (i = 0; i < pdata->num_leds; i++) { in netxbig_led_probe()
618 &leds_data[i], &pdata->leds[i]); in netxbig_led_probe()
629 .name = "leds-netxbig",
639 MODULE_ALIAS("platform:leds-netxbig");