2 * EASY98000 CPLD LED driver
4 * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
12 #include <linux/kernel.h>
13 #include <linux/version.h>
14 #include <linux/types.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/errno.h>
18 #include <linux/leds.h>
19 #include <linux/slab.h>
21 #include "dev-leds-easy98000-cpld.h"
23 const char *led_name
[8] = {
34 #define cpld_base7 ((u16 *)(KSEG1 | 0x17c0000c))
35 #define cpld_base8 ((u16 *)(KSEG1 | 0x17c00012))
37 #define ltq_r16(reg) __raw_readw(reg)
38 #define ltq_w16(val, reg) __raw_writew(val, reg)
41 struct led_classdev cdev
;
46 struct cpld_led_drvdata
{
47 struct cpld_led_dev
*led_devs
;
51 void led_set(u8 mask
, u16
*base
)
53 ltq_w16(ltq_r16(base
) | mask
, base
);
56 void led_clear(u8 mask
, u16
*base
)
58 ltq_w16(ltq_r16(base
) & (~mask
), base
);
61 void led_blink_clear(u8 mask
, u16
*base
)
63 led_clear(mask
, base
);
66 static void led_brightness(struct led_classdev
*led_cdev
,
67 enum led_brightness value
)
69 struct cpld_led_dev
*led_dev
=
70 container_of(led_cdev
, struct cpld_led_dev
, cdev
);
73 led_set(led_dev
->mask
, led_dev
->base
);
75 led_clear(led_dev
->mask
, led_dev
->base
);
78 static int led_probe(struct platform_device
*pdev
)
82 struct cpld_led_drvdata
*drvdata
;
85 drvdata
= kzalloc(sizeof(struct cpld_led_drvdata
) +
86 sizeof(struct cpld_led_dev
) * MAX_LED
,
91 drvdata
->led_devs
= (struct cpld_led_dev
*) &drvdata
[1];
93 for (i
= 0; i
< MAX_LED
; i
++) {
94 struct cpld_led_dev
*led_dev
= &drvdata
->led_devs
[i
];
95 led_dev
->cdev
.brightness_set
= led_brightness
;
96 led_dev
->cdev
.default_trigger
= NULL
;
97 led_dev
->mask
= 1 << (i
% 8);
99 sprintf(name
, "easy98000-cpld:%s", led_name
[i
]);
100 led_dev
->base
= cpld_base8
;
102 sprintf(name
, "easy98000-cpld:red:%d", i
-8);
103 led_dev
->base
= cpld_base7
;
105 led_dev
->cdev
.name
= name
;
106 ret
= led_classdev_register(&pdev
->dev
, &led_dev
->cdev
);
110 platform_set_drvdata(pdev
, drvdata
);
114 printk("led_probe: 3\n");
115 for (i
= i
- 1; i
>= 0; i
--)
116 led_classdev_unregister(&drvdata
->led_devs
[i
].cdev
);
122 static int led_remove(struct platform_device
*pdev
)
125 struct cpld_led_drvdata
*drvdata
= platform_get_drvdata(pdev
);
126 for (i
= 0; i
< MAX_LED
; i
++)
127 led_classdev_unregister(&drvdata
->led_devs
[i
].cdev
);
132 static struct platform_driver led_driver
= {
134 .remove
= __devexit_p(led_remove
),
137 .owner
= THIS_MODULE
,
141 int __init
easy98000_cpld_led_init(void)
143 pr_info(LED_DESC
", Version " LED_VERSION
144 " (c) Copyright 2011, Lantiq Deutschland GmbH\n");
145 return platform_driver_register(&led_driver
);
148 void __exit
easy98000_cpld_led_exit(void)
150 platform_driver_unregister(&led_driver
);
153 module_init(easy98000_cpld_led_init
);
154 module_exit(easy98000_cpld_led_exit
);
156 MODULE_DESCRIPTION(LED_NAME
);
157 MODULE_DESCRIPTION(LED_DESC
);
158 MODULE_AUTHOR("Ralph Hempel <ralph.hempel@lantiq.com>");
159 MODULE_LICENSE("GPL v2");