1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Backlight driver for OMAP based boards. 4 * 5 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org> 6 */ 7 8 #include <linux/module.h> 9 #include <linux/kernel.h> 10 #include <linux/init.h> 11 #include <linux/platform_device.h> 12 #include <linux/backlight.h> 13 #include <linux/slab.h> 14 #include <linux/platform_data/omap1_bl.h> 15 16 #include <linux/soc/ti/omap1-io.h> 17 #include <linux/soc/ti/omap1-mux.h> 18 19 #define OMAPBL_MAX_INTENSITY 0xff 20 21 struct omap_backlight { 22 bool enabled; 23 int current_intensity; 24 25 struct device *dev; 26 struct omap_backlight_config *pdata; 27 }; 28 29 static inline void omapbl_send_intensity(int intensity) 30 { 31 omap_writeb(intensity, OMAP_PWL_ENABLE); 32 } 33 34 static inline void omapbl_send_enable(int enable) 35 { 36 omap_writeb(enable, OMAP_PWL_CLK_ENABLE); 37 } 38 39 static void omapbl_enable(struct omap_backlight *bl, bool enable) 40 { 41 if (enable) { 42 omapbl_send_intensity(bl->current_intensity); 43 omapbl_send_enable(1); 44 } else { 45 omapbl_send_intensity(0); 46 omapbl_send_enable(0); 47 } 48 } 49 50 #ifdef CONFIG_PM_SLEEP 51 static int omapbl_suspend(struct device *dev) 52 { 53 struct backlight_device *bl_dev = dev_get_drvdata(dev); 54 struct omap_backlight *bl = bl_get_data(bl_dev); 55 56 omapbl_enable(bl, false); 57 return 0; 58 } 59 60 static int omapbl_resume(struct device *dev) 61 { 62 struct backlight_device *bl_dev = dev_get_drvdata(dev); 63 struct omap_backlight *bl = bl_get_data(bl_dev); 64 65 omapbl_enable(bl, bl->enabled); 66 return 0; 67 } 68 #endif 69 70 static void omapbl_set_enabled(struct backlight_device *dev, bool enable) 71 { 72 struct omap_backlight *bl = bl_get_data(dev); 73 74 omapbl_enable(bl, enable); 75 bl->enabled = enable; 76 } 77 78 static int omapbl_update_status(struct backlight_device *dev) 79 { 80 struct omap_backlight *bl = bl_get_data(dev); 81 bool enable; 82 83 if (bl->current_intensity != dev->props.brightness) { 84 if (bl->enabled) 85 omapbl_send_intensity(dev->props.brightness); 86 bl->current_intensity = dev->props.brightness; 87 } 88 89 enable = !backlight_is_blank(dev); 90 91 if (enable != bl->enabled) 92 omapbl_set_enabled(dev, enable); 93 94 return 0; 95 } 96 97 static int omapbl_get_intensity(struct backlight_device *dev) 98 { 99 struct omap_backlight *bl = bl_get_data(dev); 100 101 return bl->current_intensity; 102 } 103 104 static const struct backlight_ops omapbl_ops = { 105 .get_brightness = omapbl_get_intensity, 106 .update_status = omapbl_update_status, 107 }; 108 109 static int omapbl_probe(struct platform_device *pdev) 110 { 111 struct backlight_properties props; 112 struct backlight_device *dev; 113 struct omap_backlight *bl; 114 struct omap_backlight_config *pdata = dev_get_platdata(&pdev->dev); 115 116 if (!pdata) 117 return -ENXIO; 118 119 bl = devm_kzalloc(&pdev->dev, sizeof(struct omap_backlight), 120 GFP_KERNEL); 121 if (unlikely(!bl)) 122 return -ENOMEM; 123 124 memset(&props, 0, sizeof(struct backlight_properties)); 125 props.type = BACKLIGHT_RAW; 126 props.max_brightness = OMAPBL_MAX_INTENSITY; 127 dev = devm_backlight_device_register(&pdev->dev, "omap-bl", &pdev->dev, 128 bl, &omapbl_ops, &props); 129 if (IS_ERR(dev)) 130 return PTR_ERR(dev); 131 132 bl->enabled = false; 133 bl->current_intensity = 0; 134 135 bl->pdata = pdata; 136 bl->dev = &pdev->dev; 137 138 platform_set_drvdata(pdev, dev); 139 140 omap_cfg_reg(PWL); /* Conflicts with UART3 */ 141 142 dev->props.brightness = pdata->default_intensity; 143 omapbl_update_status(dev); 144 145 dev_info(&pdev->dev, "OMAP LCD backlight initialised\n"); 146 147 return 0; 148 } 149 150 static SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume); 151 152 static struct platform_driver omapbl_driver = { 153 .probe = omapbl_probe, 154 .driver = { 155 .name = "omap-bl", 156 .pm = &omapbl_pm_ops, 157 }, 158 }; 159 160 module_platform_driver(omapbl_driver); 161 162 MODULE_AUTHOR("Andrzej Zaborowski <balrog@zabor.org>"); 163 MODULE_DESCRIPTION("OMAP LCD Backlight driver"); 164 MODULE_LICENSE("GPL"); 165