1 // SPDX-License-Identifier: GPL-2.0-only
2 /* drivers/video/backlight/platform_lcd.c
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
7 * Generic platform-device LCD power control interface.
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
13 #include <linux/backlight.h>
14 #include <linux/lcd.h>
16 #include <linux/slab.h>
18 #include <video/platform_lcd.h>
22 struct lcd_device
*lcd
;
23 struct plat_lcd_data
*pdata
;
26 unsigned int suspended
:1;
29 static inline struct platform_lcd
*to_our_lcd(struct lcd_device
*lcd
)
31 return lcd_get_data(lcd
);
34 static int platform_lcd_get_power(struct lcd_device
*lcd
)
36 struct platform_lcd
*plcd
= to_our_lcd(lcd
);
41 static int platform_lcd_set_power(struct lcd_device
*lcd
, int power
)
43 struct platform_lcd
*plcd
= to_our_lcd(lcd
);
46 if (power
== FB_BLANK_POWERDOWN
|| plcd
->suspended
)
49 plcd
->pdata
->set_power(plcd
->pdata
, lcd_power
);
55 static int platform_lcd_match(struct lcd_device
*lcd
, struct fb_info
*info
)
57 struct platform_lcd
*plcd
= to_our_lcd(lcd
);
58 struct plat_lcd_data
*pdata
= plcd
->pdata
;
61 return pdata
->match_fb(pdata
, info
);
63 return plcd
->us
->parent
== info
->device
;
66 static struct lcd_ops platform_lcd_ops
= {
67 .get_power
= platform_lcd_get_power
,
68 .set_power
= platform_lcd_set_power
,
69 .check_fb
= platform_lcd_match
,
72 static int platform_lcd_probe(struct platform_device
*pdev
)
74 struct plat_lcd_data
*pdata
;
75 struct platform_lcd
*plcd
;
76 struct device
*dev
= &pdev
->dev
;
79 pdata
= dev_get_platdata(&pdev
->dev
);
81 dev_err(dev
, "no platform data supplied\n");
86 err
= pdata
->probe(pdata
);
91 plcd
= devm_kzalloc(&pdev
->dev
, sizeof(struct platform_lcd
),
98 plcd
->lcd
= devm_lcd_device_register(&pdev
->dev
, dev_name(dev
), dev
,
99 plcd
, &platform_lcd_ops
);
100 if (IS_ERR(plcd
->lcd
)) {
101 dev_err(dev
, "cannot register lcd device\n");
102 return PTR_ERR(plcd
->lcd
);
105 platform_set_drvdata(pdev
, plcd
);
106 platform_lcd_set_power(plcd
->lcd
, FB_BLANK_NORMAL
);
111 #ifdef CONFIG_PM_SLEEP
112 static int platform_lcd_suspend(struct device
*dev
)
114 struct platform_lcd
*plcd
= dev_get_drvdata(dev
);
117 platform_lcd_set_power(plcd
->lcd
, plcd
->power
);
122 static int platform_lcd_resume(struct device
*dev
)
124 struct platform_lcd
*plcd
= dev_get_drvdata(dev
);
127 platform_lcd_set_power(plcd
->lcd
, plcd
->power
);
133 static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops
, platform_lcd_suspend
,
134 platform_lcd_resume
);
137 static const struct of_device_id platform_lcd_of_match
[] = {
138 { .compatible
= "platform-lcd" },
141 MODULE_DEVICE_TABLE(of
, platform_lcd_of_match
);
144 static struct platform_driver platform_lcd_driver
= {
146 .name
= "platform-lcd",
147 .pm
= &platform_lcd_pm_ops
,
148 .of_match_table
= of_match_ptr(platform_lcd_of_match
),
150 .probe
= platform_lcd_probe
,
153 module_platform_driver(platform_lcd_driver
);
155 MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
156 MODULE_LICENSE("GPL v2");
157 MODULE_ALIAS("platform:platform-lcd");