0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/mfd/ipaq-micro.h>
0012 #include <linux/leds.h>
0013
0014 #define LED_YELLOW 0x00
0015 #define LED_GREEN 0x01
0016
0017 #define LED_EN (1 << 4)
0018 #define LED_AUTOSTOP (1 << 5)
0019 #define LED_ALWAYS (1 << 6)
0020
0021 static int micro_leds_brightness_set(struct led_classdev *led_cdev,
0022 enum led_brightness value)
0023 {
0024 struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 struct ipaq_micro_msg msg = {
0038 .id = MSG_NOTIFY_LED,
0039 .tx_len = 4,
0040 };
0041
0042 msg.tx_data[0] = LED_GREEN;
0043 msg.tx_data[1] = 0;
0044 if (value) {
0045 msg.tx_data[2] = 0;
0046 msg.tx_data[3] = 1;
0047 } else {
0048 msg.tx_data[2] = 1;
0049 msg.tx_data[3] = 0;
0050 }
0051 return ipaq_micro_tx_msg_sync(micro, &msg);
0052 }
0053
0054
0055 #define IPAQ_LED_MAX_DUTY 25600
0056
0057 static int micro_leds_blink_set(struct led_classdev *led_cdev,
0058 unsigned long *delay_on,
0059 unsigned long *delay_off)
0060 {
0061 struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 struct ipaq_micro_msg msg = {
0075 .id = MSG_NOTIFY_LED,
0076 .tx_len = 4,
0077 };
0078
0079 msg.tx_data[0] = LED_GREEN;
0080 if (*delay_on > IPAQ_LED_MAX_DUTY ||
0081 *delay_off > IPAQ_LED_MAX_DUTY)
0082 return -EINVAL;
0083
0084 if (*delay_on == 0 && *delay_off == 0) {
0085 *delay_on = 100;
0086 *delay_off = 100;
0087 }
0088
0089 msg.tx_data[1] = 0;
0090 if (*delay_on >= IPAQ_LED_MAX_DUTY)
0091 msg.tx_data[2] = 0;
0092 else
0093 msg.tx_data[2] = (u8) DIV_ROUND_CLOSEST(*delay_on, 100);
0094 if (*delay_off >= IPAQ_LED_MAX_DUTY)
0095 msg.tx_data[3] = 0;
0096 else
0097 msg.tx_data[3] = (u8) DIV_ROUND_CLOSEST(*delay_off, 100);
0098 return ipaq_micro_tx_msg_sync(micro, &msg);
0099 }
0100
0101 static struct led_classdev micro_led = {
0102 .name = "led-ipaq-micro",
0103 .brightness_set_blocking = micro_leds_brightness_set,
0104 .blink_set = micro_leds_blink_set,
0105 .flags = LED_CORE_SUSPENDRESUME,
0106 };
0107
0108 static int micro_leds_probe(struct platform_device *pdev)
0109 {
0110 int ret;
0111
0112 ret = devm_led_classdev_register(&pdev->dev, µ_led);
0113 if (ret) {
0114 dev_err(&pdev->dev, "registering led failed: %d\n", ret);
0115 return ret;
0116 }
0117 dev_info(&pdev->dev, "iPAQ micro notification LED driver\n");
0118
0119 return 0;
0120 }
0121
0122 static struct platform_driver micro_leds_device_driver = {
0123 .driver = {
0124 .name = "ipaq-micro-leds",
0125 },
0126 .probe = micro_leds_probe,
0127 };
0128 module_platform_driver(micro_leds_device_driver);
0129
0130 MODULE_LICENSE("GPL");
0131 MODULE_DESCRIPTION("driver for iPAQ Atmel micro leds");
0132 MODULE_ALIAS("platform:ipaq-micro-leds");