12fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli/*
22fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli * Copyright 2006 - Florian Fainelli <florian@openwrt.org>
32fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli *
42fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli * Control the Cobalt Qube/RaQ front LED
52fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli */
64276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#include <linux/init.h>
74276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#include <linux/io.h>
84276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#include <linux/ioport.h>
94276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#include <linux/leds.h>
102fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli#include <linux/module.h>
114276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#include <linux/platform_device.h>
122fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli#include <linux/types.h>
132fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli
144276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#define LED_FRONT_LEFT	0x01
154276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa#define LED_FRONT_RIGHT	0x02
164276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
174276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic void __iomem *led_port;
184276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic u8 led_value;
194276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
204276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic void qube_front_led_set(struct led_classdev *led_cdev,
214d404fd5c51772720e9c72aa3185bd5119bc6e69Németh Márton			       enum led_brightness brightness)
222fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli{
232fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli	if (brightness)
244276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
252fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli	else
264276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		led_value = ~(LED_FRONT_LEFT | LED_FRONT_RIGHT);
274276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	writeb(led_value, led_port);
284276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa}
294276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
304276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic struct led_classdev qube_front_led = {
31db3f520738a8c5bf593e13d4ac71f8da9ffcb964Olaf Hering	.name			= "qube::front",
324276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	.brightness		= LED_FULL,
334276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	.brightness_set		= qube_front_led_set,
3451de036ba388a1bda08755f7c0d3d1ae27c81e66Florian Fainelli	.default_trigger	= "default-on",
354276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa};
364276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
374276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic int __devinit cobalt_qube_led_probe(struct platform_device *pdev)
384276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa{
394276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	struct resource *res;
404276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	int retval;
414276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
424276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
434276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	if (!res)
444276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		return -EBUSY;
454276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
463c0f6e1eddeddd95ed04d4a7f0e55ab0aa99adf9H Hartley Sweeten	led_port = ioremap(res->start, resource_size(res));
474276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	if (!led_port)
484276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		return -ENOMEM;
494276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
504276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	led_value = LED_FRONT_LEFT | LED_FRONT_RIGHT;
514276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	writeb(led_value, led_port);
524276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
534276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	retval = led_classdev_register(&pdev->dev, &qube_front_led);
544276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	if (retval)
554276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		goto err_iounmap;
564276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
574276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	return 0;
584276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
594276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasaerr_iounmap:
604276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	iounmap(led_port);
614276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	led_port = NULL;
624276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
634276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	return retval;
644276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa}
654276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
664276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
674276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa{
684276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	led_classdev_unregister(&qube_front_led);
694276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
704276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	if (led_port) {
714276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		iounmap(led_port);
724276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		led_port = NULL;
734276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	}
744276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa
754276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	return 0;
762fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli}
772fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli
784276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasastatic struct platform_driver cobalt_qube_led_driver = {
794276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	.probe	= cobalt_qube_led_probe,
804276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	.remove	= __devexit_p(cobalt_qube_led_remove),
814276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	.driver	= {
824276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		.name	= "cobalt-qube-leds",
834276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa		.owner	= THIS_MODULE,
844276fd7349bfd4f557d9777100fdcf1140771b4eYoichi Yuasa	},
852fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli};
862fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli
87892a8843fbef07a7f2ab62d5f7ff5c16ea0903b0Axel Linmodule_platform_driver(cobalt_qube_led_driver);
882fea6f35c388c5add15d1492c7f4f3dac401717bFlorian Fainelli
892fea6f35c388c5add15d1492c7f4f3dac401717bFlorian FainelliMODULE_LICENSE("GPL");
902fea6f35c388c5add15d1492c7f4f3dac401717bFlorian FainelliMODULE_DESCRIPTION("Front LED support for Cobalt Server");
912fea6f35c388c5add15d1492c7f4f3dac401717bFlorian FainelliMODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
92892a8843fbef07a7f2ab62d5f7ff5c16ea0903b0Axel LinMODULE_ALIAS("platform:cobalt-qube-leds");
93