diff options
| author | H Hartley Sweeten <hartleys@visionengravers.com> | 2010-05-05 13:13:23 -0400 |
|---|---|---|
| committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-05-26 08:08:32 -0400 |
| commit | 08b3924b24cdb1942393dc3009335a2153bd2eac (patch) | |
| tree | ff74825a5a5f50948125c014565690eb540d1172 | |
| parent | 47306fc35ec39a5d0715e0a79344d02dffeaeeb2 (diff) | |
backlight: Add Cirrus EP93xx backlight driver
The EP9307, EP9312, and EP9315 processors include a framebuffer
peripheral. This peripheral has a dedicated pwm output called
BRIGHT that can be used to control the backlight on an LCD.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
| -rw-r--r-- | drivers/video/backlight/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/video/backlight/Makefile | 1 | ||||
| -rw-r--r-- | drivers/video/backlight/ep93xx_bl.c | 160 |
3 files changed, 171 insertions, 0 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 0f7e795f27f8..2d8052182960 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
| @@ -142,6 +142,16 @@ config BACKLIGHT_ATMEL_PWM | |||
| 142 | To compile this driver as a module, choose M here: the module will be | 142 | To compile this driver as a module, choose M here: the module will be |
| 143 | called atmel-pwm-bl. | 143 | called atmel-pwm-bl. |
| 144 | 144 | ||
| 145 | config BACKLIGHT_EP93XX | ||
| 146 | tristate "Cirrus EP93xx Backlight Driver" | ||
| 147 | depends on FB_EP93XX | ||
| 148 | help | ||
| 149 | If you have a LCD backlight connected to the BRIGHT output of | ||
| 150 | the EP93xx, say Y here to enable this driver. | ||
| 151 | |||
| 152 | To compile this driver as a module, choose M here: the module will | ||
| 153 | be called ep93xx_bl. | ||
| 154 | |||
| 145 | config BACKLIGHT_GENERIC | 155 | config BACKLIGHT_GENERIC |
| 146 | tristate "Generic (aka Sharp Corgi) Backlight Driver" | 156 | tristate "Generic (aka Sharp Corgi) Backlight Driver" |
| 147 | default y | 157 | default y |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 3cbaacae8f9c..ef610b15fdc6 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
| @@ -14,6 +14,7 @@ obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o | |||
| 14 | 14 | ||
| 15 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 15 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
| 16 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o | 16 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o |
| 17 | obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o | ||
| 17 | obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o | 18 | obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o |
| 18 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o | 19 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o |
| 19 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 20 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c new file mode 100644 index 000000000000..b0cc49184803 --- /dev/null +++ b/drivers/video/backlight/ep93xx_bl.c | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the Cirrus EP93xx lcd backlight | ||
| 3 | * | ||
| 4 | * Copyright (c) 2010 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This driver controls the pulse width modulated brightness control output, | ||
| 11 | * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors. | ||
| 12 | */ | ||
| 13 | |||
| 14 | |||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/fb.h> | ||
| 18 | #include <linux/backlight.h> | ||
| 19 | |||
| 20 | #include <mach/hardware.h> | ||
| 21 | |||
| 22 | #define EP93XX_RASTER_REG(x) (EP93XX_RASTER_BASE + (x)) | ||
| 23 | #define EP93XX_RASTER_BRIGHTNESS EP93XX_RASTER_REG(0x20) | ||
| 24 | |||
| 25 | #define EP93XX_MAX_COUNT 255 | ||
| 26 | #define EP93XX_MAX_BRIGHT 255 | ||
| 27 | #define EP93XX_DEF_BRIGHT 128 | ||
| 28 | |||
| 29 | struct ep93xxbl { | ||
| 30 | void __iomem *mmio; | ||
| 31 | int brightness; | ||
| 32 | }; | ||
| 33 | |||
| 34 | static int ep93xxbl_set(struct backlight_device *bl, int brightness) | ||
| 35 | { | ||
| 36 | struct ep93xxbl *ep93xxbl = bl_get_data(bl); | ||
| 37 | |||
| 38 | __raw_writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio); | ||
| 39 | |||
| 40 | ep93xxbl->brightness = brightness; | ||
| 41 | |||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int ep93xxbl_update_status(struct backlight_device *bl) | ||
| 46 | { | ||
| 47 | int brightness = bl->props.brightness; | ||
| 48 | |||
| 49 | if (bl->props.power != FB_BLANK_UNBLANK || | ||
| 50 | bl->props.fb_blank != FB_BLANK_UNBLANK) | ||
| 51 | brightness = 0; | ||
| 52 | |||
| 53 | return ep93xxbl_set(bl, brightness); | ||
| 54 | } | ||
| 55 | |||
| 56 | static int ep93xxbl_get_brightness(struct backlight_device *bl) | ||
| 57 | { | ||
| 58 | struct ep93xxbl *ep93xxbl = bl_get_data(bl); | ||
| 59 | |||
| 60 | return ep93xxbl->brightness; | ||
| 61 | } | ||
| 62 | |||
| 63 | static const struct backlight_ops ep93xxbl_ops = { | ||
| 64 | .update_status = ep93xxbl_update_status, | ||
| 65 | .get_brightness = ep93xxbl_get_brightness, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static int __init ep93xxbl_probe(struct platform_device *dev) | ||
| 69 | { | ||
| 70 | struct ep93xxbl *ep93xxbl; | ||
| 71 | struct backlight_device *bl; | ||
| 72 | struct backlight_properties props; | ||
| 73 | |||
| 74 | ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL); | ||
| 75 | if (!ep93xxbl) | ||
| 76 | return -ENOMEM; | ||
| 77 | |||
| 78 | /* | ||
| 79 | * This register is located in the range already ioremap'ed by | ||
| 80 | * the framebuffer driver. A MFD driver seems a bit of overkill | ||
| 81 | * to handle this so use the static I/O mapping; this address | ||
| 82 | * is already virtual. | ||
| 83 | * | ||
| 84 | * NOTE: No locking is required; the framebuffer does not touch | ||
| 85 | * this register. | ||
| 86 | */ | ||
| 87 | ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS; | ||
| 88 | |||
| 89 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
| 90 | props.max_brightness = EP93XX_MAX_BRIGHT; | ||
| 91 | bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl, | ||
| 92 | &ep93xxbl_ops, &props); | ||
| 93 | if (IS_ERR(bl)) | ||
| 94 | return PTR_ERR(bl); | ||
| 95 | |||
| 96 | bl->props.brightness = EP93XX_DEF_BRIGHT; | ||
| 97 | |||
| 98 | platform_set_drvdata(dev, bl); | ||
| 99 | |||
| 100 | ep93xxbl_update_status(bl); | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int ep93xxbl_remove(struct platform_device *dev) | ||
| 106 | { | ||
| 107 | struct backlight_device *bl = platform_get_drvdata(dev); | ||
| 108 | |||
| 109 | backlight_device_unregister(bl); | ||
| 110 | platform_set_drvdata(dev, NULL); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | #ifdef CONFIG_PM | ||
| 115 | static int ep93xxbl_suspend(struct platform_device *dev, pm_message_t state) | ||
| 116 | { | ||
| 117 | struct backlight_device *bl = platform_get_drvdata(dev); | ||
| 118 | |||
| 119 | return ep93xxbl_set(bl, 0); | ||
| 120 | } | ||
| 121 | |||
| 122 | static int ep93xxbl_resume(struct platform_device *dev) | ||
| 123 | { | ||
| 124 | struct backlight_device *bl = platform_get_drvdata(dev); | ||
| 125 | |||
| 126 | backlight_update_status(bl); | ||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | #else | ||
| 130 | #define ep93xxbl_suspend NULL | ||
| 131 | #define ep93xxbl_resume NULL | ||
| 132 | #endif | ||
| 133 | |||
| 134 | static struct platform_driver ep93xxbl_driver = { | ||
| 135 | .driver = { | ||
| 136 | .name = "ep93xx-bl", | ||
| 137 | .owner = THIS_MODULE, | ||
| 138 | }, | ||
| 139 | .probe = ep93xxbl_probe, | ||
| 140 | .remove = __devexit_p(ep93xxbl_remove), | ||
| 141 | .suspend = ep93xxbl_suspend, | ||
| 142 | .resume = ep93xxbl_resume, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static int __init ep93xxbl_init(void) | ||
| 146 | { | ||
| 147 | return platform_driver_register(&ep93xxbl_driver); | ||
| 148 | } | ||
| 149 | module_init(ep93xxbl_init); | ||
| 150 | |||
| 151 | static void __exit ep93xxbl_exit(void) | ||
| 152 | { | ||
| 153 | platform_driver_unregister(&ep93xxbl_driver); | ||
| 154 | } | ||
| 155 | module_exit(ep93xxbl_exit); | ||
| 156 | |||
| 157 | MODULE_DESCRIPTION("EP93xx Backlight Driver"); | ||
| 158 | MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
| 159 | MODULE_LICENSE("GPL"); | ||
| 160 | MODULE_ALIAS("platform:ep93xx-bl"); | ||
