1*16216333SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
297da7aafSYoichi Yuasa /*
397da7aafSYoichi Yuasa * LEDs driver for the Cobalt Raq series.
497da7aafSYoichi Yuasa *
5ada8e951SYoichi Yuasa * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
697da7aafSYoichi Yuasa */
797da7aafSYoichi Yuasa #include <linux/init.h>
897da7aafSYoichi Yuasa #include <linux/io.h>
997da7aafSYoichi Yuasa #include <linux/ioport.h>
1097da7aafSYoichi Yuasa #include <linux/leds.h>
1197da7aafSYoichi Yuasa #include <linux/platform_device.h>
1297da7aafSYoichi Yuasa #include <linux/spinlock.h>
1397da7aafSYoichi Yuasa #include <linux/types.h>
14d131c496SPaul Gortmaker #include <linux/export.h>
1597da7aafSYoichi Yuasa
1697da7aafSYoichi Yuasa #define LED_WEB 0x04
1797da7aafSYoichi Yuasa #define LED_POWER_OFF 0x08
1897da7aafSYoichi Yuasa
1997da7aafSYoichi Yuasa static void __iomem *led_port;
2097da7aafSYoichi Yuasa static u8 led_value;
2197da7aafSYoichi Yuasa static DEFINE_SPINLOCK(led_value_lock);
2297da7aafSYoichi Yuasa
raq_web_led_set(struct led_classdev * led_cdev,enum led_brightness brightness)2397da7aafSYoichi Yuasa static void raq_web_led_set(struct led_classdev *led_cdev,
2497da7aafSYoichi Yuasa enum led_brightness brightness)
2597da7aafSYoichi Yuasa {
2697da7aafSYoichi Yuasa unsigned long flags;
2797da7aafSYoichi Yuasa
2897da7aafSYoichi Yuasa spin_lock_irqsave(&led_value_lock, flags);
2997da7aafSYoichi Yuasa
3097da7aafSYoichi Yuasa if (brightness)
3197da7aafSYoichi Yuasa led_value |= LED_WEB;
3297da7aafSYoichi Yuasa else
3397da7aafSYoichi Yuasa led_value &= ~LED_WEB;
3497da7aafSYoichi Yuasa writeb(led_value, led_port);
3597da7aafSYoichi Yuasa
3697da7aafSYoichi Yuasa spin_unlock_irqrestore(&led_value_lock, flags);
3797da7aafSYoichi Yuasa }
3897da7aafSYoichi Yuasa
3997da7aafSYoichi Yuasa static struct led_classdev raq_web_led = {
40db3f5207SOlaf Hering .name = "raq::web",
4197da7aafSYoichi Yuasa .brightness_set = raq_web_led_set,
4297da7aafSYoichi Yuasa };
4397da7aafSYoichi Yuasa
raq_power_off_led_set(struct led_classdev * led_cdev,enum led_brightness brightness)4497da7aafSYoichi Yuasa static void raq_power_off_led_set(struct led_classdev *led_cdev,
4597da7aafSYoichi Yuasa enum led_brightness brightness)
4697da7aafSYoichi Yuasa {
4797da7aafSYoichi Yuasa unsigned long flags;
4897da7aafSYoichi Yuasa
4997da7aafSYoichi Yuasa spin_lock_irqsave(&led_value_lock, flags);
5097da7aafSYoichi Yuasa
5197da7aafSYoichi Yuasa if (brightness)
5297da7aafSYoichi Yuasa led_value |= LED_POWER_OFF;
5397da7aafSYoichi Yuasa else
5497da7aafSYoichi Yuasa led_value &= ~LED_POWER_OFF;
5597da7aafSYoichi Yuasa writeb(led_value, led_port);
5697da7aafSYoichi Yuasa
5797da7aafSYoichi Yuasa spin_unlock_irqrestore(&led_value_lock, flags);
5897da7aafSYoichi Yuasa }
5997da7aafSYoichi Yuasa
6097da7aafSYoichi Yuasa static struct led_classdev raq_power_off_led = {
61db3f5207SOlaf Hering .name = "raq::power-off",
6297da7aafSYoichi Yuasa .brightness_set = raq_power_off_led_set,
6397da7aafSYoichi Yuasa .default_trigger = "power-off",
6497da7aafSYoichi Yuasa };
6597da7aafSYoichi Yuasa
cobalt_raq_led_probe(struct platform_device * pdev)6698ea1ea2SBill Pemberton static int cobalt_raq_led_probe(struct platform_device *pdev)
6797da7aafSYoichi Yuasa {
6897da7aafSYoichi Yuasa struct resource *res;
6997da7aafSYoichi Yuasa int retval;
7097da7aafSYoichi Yuasa
7197da7aafSYoichi Yuasa res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
7297da7aafSYoichi Yuasa if (!res)
7397da7aafSYoichi Yuasa return -EBUSY;
7497da7aafSYoichi Yuasa
7550e51943SJingoo Han led_port = devm_ioremap(&pdev->dev, res->start, resource_size(res));
7697da7aafSYoichi Yuasa if (!led_port)
7797da7aafSYoichi Yuasa return -ENOMEM;
7897da7aafSYoichi Yuasa
7997da7aafSYoichi Yuasa retval = led_classdev_register(&pdev->dev, &raq_power_off_led);
8097da7aafSYoichi Yuasa if (retval)
8150e51943SJingoo Han goto err_null;
8297da7aafSYoichi Yuasa
8397da7aafSYoichi Yuasa retval = led_classdev_register(&pdev->dev, &raq_web_led);
8497da7aafSYoichi Yuasa if (retval)
8597da7aafSYoichi Yuasa goto err_unregister;
8697da7aafSYoichi Yuasa
8797da7aafSYoichi Yuasa return 0;
8897da7aafSYoichi Yuasa
8997da7aafSYoichi Yuasa err_unregister:
9097da7aafSYoichi Yuasa led_classdev_unregister(&raq_power_off_led);
9197da7aafSYoichi Yuasa
9250e51943SJingoo Han err_null:
9397da7aafSYoichi Yuasa led_port = NULL;
9497da7aafSYoichi Yuasa
9597da7aafSYoichi Yuasa return retval;
9697da7aafSYoichi Yuasa }
9797da7aafSYoichi Yuasa
9897da7aafSYoichi Yuasa static struct platform_driver cobalt_raq_led_driver = {
9997da7aafSYoichi Yuasa .probe = cobalt_raq_led_probe,
10097da7aafSYoichi Yuasa .driver = {
10197da7aafSYoichi Yuasa .name = "cobalt-raq-leds",
10297da7aafSYoichi Yuasa },
10397da7aafSYoichi Yuasa };
10497da7aafSYoichi Yuasa
105cee0122dSGeliang Tang builtin_platform_driver(cobalt_raq_led_driver);
106