Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for the Cirrus EP93xx lcd backlight
0004  *
0005  * Copyright (c) 2010 H Hartley Sweeten <hsweeten@visionengravers.com>
0006  *
0007  * This driver controls the pulse width modulated brightness control output,
0008  * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/io.h>
0014 #include <linux/fb.h>
0015 #include <linux/backlight.h>
0016 
0017 #define EP93XX_MAX_COUNT        255
0018 #define EP93XX_MAX_BRIGHT       255
0019 #define EP93XX_DEF_BRIGHT       128
0020 
0021 struct ep93xxbl {
0022     void __iomem *mmio;
0023     int brightness;
0024 };
0025 
0026 static int ep93xxbl_set(struct backlight_device *bl, int brightness)
0027 {
0028     struct ep93xxbl *ep93xxbl = bl_get_data(bl);
0029 
0030     writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
0031 
0032     ep93xxbl->brightness = brightness;
0033 
0034     return 0;
0035 }
0036 
0037 static int ep93xxbl_update_status(struct backlight_device *bl)
0038 {
0039     return ep93xxbl_set(bl, backlight_get_brightness(bl));
0040 }
0041 
0042 static int ep93xxbl_get_brightness(struct backlight_device *bl)
0043 {
0044     struct ep93xxbl *ep93xxbl = bl_get_data(bl);
0045 
0046     return ep93xxbl->brightness;
0047 }
0048 
0049 static const struct backlight_ops ep93xxbl_ops = {
0050     .update_status  = ep93xxbl_update_status,
0051     .get_brightness = ep93xxbl_get_brightness,
0052 };
0053 
0054 static int ep93xxbl_probe(struct platform_device *dev)
0055 {
0056     struct ep93xxbl *ep93xxbl;
0057     struct backlight_device *bl;
0058     struct backlight_properties props;
0059     struct resource *res;
0060 
0061     ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL);
0062     if (!ep93xxbl)
0063         return -ENOMEM;
0064 
0065     res = platform_get_resource(dev, IORESOURCE_MEM, 0);
0066     if (!res)
0067         return -ENXIO;
0068 
0069     /*
0070      * FIXME - We don't do a request_mem_region here because we are
0071      * sharing the register space with the framebuffer driver (see
0072      * drivers/video/ep93xx-fb.c) and doing so will cause the second
0073      * loaded driver to return -EBUSY.
0074      *
0075      * NOTE: No locking is required; the framebuffer does not touch
0076      * this register.
0077      */
0078     ep93xxbl->mmio = devm_ioremap(&dev->dev, res->start,
0079                       resource_size(res));
0080     if (!ep93xxbl->mmio)
0081         return -ENXIO;
0082 
0083     memset(&props, 0, sizeof(struct backlight_properties));
0084     props.type = BACKLIGHT_RAW;
0085     props.max_brightness = EP93XX_MAX_BRIGHT;
0086     bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev,
0087                     ep93xxbl, &ep93xxbl_ops, &props);
0088     if (IS_ERR(bl))
0089         return PTR_ERR(bl);
0090 
0091     bl->props.brightness = EP93XX_DEF_BRIGHT;
0092 
0093     platform_set_drvdata(dev, bl);
0094 
0095     ep93xxbl_update_status(bl);
0096 
0097     return 0;
0098 }
0099 
0100 #ifdef CONFIG_PM_SLEEP
0101 static int ep93xxbl_suspend(struct device *dev)
0102 {
0103     struct backlight_device *bl = dev_get_drvdata(dev);
0104 
0105     return ep93xxbl_set(bl, 0);
0106 }
0107 
0108 static int ep93xxbl_resume(struct device *dev)
0109 {
0110     struct backlight_device *bl = dev_get_drvdata(dev);
0111 
0112     backlight_update_status(bl);
0113     return 0;
0114 }
0115 #endif
0116 
0117 static SIMPLE_DEV_PM_OPS(ep93xxbl_pm_ops, ep93xxbl_suspend, ep93xxbl_resume);
0118 
0119 static struct platform_driver ep93xxbl_driver = {
0120     .driver     = {
0121         .name   = "ep93xx-bl",
0122         .pm = &ep93xxbl_pm_ops,
0123     },
0124     .probe      = ep93xxbl_probe,
0125 };
0126 
0127 module_platform_driver(ep93xxbl_driver);
0128 
0129 MODULE_DESCRIPTION("EP93xx Backlight Driver");
0130 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
0131 MODULE_LICENSE("GPL");
0132 MODULE_ALIAS("platform:ep93xx-bl");