1/* 2 * linux/drivers/video/backlight/adx.c 3 * 4 * Copyright (C) 2009 Avionic Design GmbH 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 * Written by Thierry Reding <thierry.reding@avionic-design.de> 11 */ 12 13#include <linux/backlight.h> 14#include <linux/fb.h> 15#include <linux/gfp.h> 16#include <linux/io.h> 17#include <linux/module.h> 18#include <linux/platform_device.h> 19 20/* register definitions */ 21#define ADX_BACKLIGHT_CONTROL 0x00 22#define ADX_BACKLIGHT_CONTROL_ENABLE (1 << 0) 23#define ADX_BACKLIGHT_BRIGHTNESS 0x08 24#define ADX_BACKLIGHT_STATUS 0x10 25#define ADX_BACKLIGHT_ERROR 0x18 26 27struct adxbl { 28 void __iomem *base; 29}; 30 31static int adx_backlight_update_status(struct backlight_device *bldev) 32{ 33 struct adxbl *bl = bl_get_data(bldev); 34 u32 value; 35 36 value = bldev->props.brightness; 37 writel(value, bl->base + ADX_BACKLIGHT_BRIGHTNESS); 38 39 value = readl(bl->base + ADX_BACKLIGHT_CONTROL); 40 41 if (bldev->props.state & BL_CORE_FBBLANK) 42 value &= ~ADX_BACKLIGHT_CONTROL_ENABLE; 43 else 44 value |= ADX_BACKLIGHT_CONTROL_ENABLE; 45 46 writel(value, bl->base + ADX_BACKLIGHT_CONTROL); 47 48 return 0; 49} 50 51static int adx_backlight_get_brightness(struct backlight_device *bldev) 52{ 53 struct adxbl *bl = bl_get_data(bldev); 54 u32 brightness; 55 56 brightness = readl(bl->base + ADX_BACKLIGHT_BRIGHTNESS); 57 return brightness & 0xff; 58} 59 60static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb) 61{ 62 return 1; 63} 64 65static const struct backlight_ops adx_backlight_ops = { 66 .options = 0, 67 .update_status = adx_backlight_update_status, 68 .get_brightness = adx_backlight_get_brightness, 69 .check_fb = adx_backlight_check_fb, 70}; 71 72static int __devinit adx_backlight_probe(struct platform_device *pdev) 73{ 74 struct backlight_properties props; 75 struct backlight_device *bldev; 76 struct resource *res; 77 struct adxbl *bl; 78 int ret = 0; 79 80 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 81 if (!res) { 82 ret = -ENXIO; 83 goto out; 84 } 85 86 res = devm_request_mem_region(&pdev->dev, res->start, 87 resource_size(res), res->name); 88 if (!res) { 89 ret = -ENXIO; 90 goto out; 91 } 92 93 bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); 94 if (!bl) { 95 ret = -ENOMEM; 96 goto out; 97 } 98 99 bl->base = devm_ioremap_nocache(&pdev->dev, res->start, 100 resource_size(res)); 101 if (!bl->base) { 102 ret = -ENXIO; 103 goto out; 104 } 105 106 memset(&props, 0, sizeof(struct backlight_properties)); 107 props.max_brightness = 0xff; 108 bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, 109 bl, &adx_backlight_ops, &props); 110 if (IS_ERR(bldev)) { 111 ret = PTR_ERR(bldev); 112 goto out; 113 } 114 115 bldev->props.brightness = 0xff; 116 bldev->props.power = FB_BLANK_UNBLANK; 117 118 platform_set_drvdata(pdev, bldev); 119 120out: 121 return ret; 122} 123 124static int __devexit adx_backlight_remove(struct platform_device *pdev) 125{ 126 struct backlight_device *bldev; 127 int ret = 0; 128 129 bldev = platform_get_drvdata(pdev); 130 bldev->props.power = FB_BLANK_UNBLANK; 131 bldev->props.brightness = 0xff; 132 backlight_update_status(bldev); 133 backlight_device_unregister(bldev); 134 platform_set_drvdata(pdev, NULL); 135 136 return ret; 137} 138 139#ifdef CONFIG_PM 140static int adx_backlight_suspend(struct platform_device *pdev, 141 pm_message_t state) 142{ 143 return 0; 144} 145 146static int adx_backlight_resume(struct platform_device *pdev) 147{ 148 return 0; 149} 150#else 151#define adx_backlight_suspend NULL 152#define adx_backlight_resume NULL 153#endif 154 155static struct platform_driver adx_backlight_driver = { 156 .probe = adx_backlight_probe, 157 .remove = __devexit_p(adx_backlight_remove), 158 .suspend = adx_backlight_suspend, 159 .resume = adx_backlight_resume, 160 .driver = { 161 .name = "adx-backlight", 162 .owner = THIS_MODULE, 163 }, 164}; 165 166static int __init adx_backlight_init(void) 167{ 168 return platform_driver_register(&adx_backlight_driver); 169} 170 171static void __exit adx_backlight_exit(void) 172{ 173 platform_driver_unregister(&adx_backlight_driver); 174} 175 176module_init(adx_backlight_init); 177module_exit(adx_backlight_exit); 178 179MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); 180MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver"); 181MODULE_LICENSE("GPL v2"); 182