xref: /openbmc/linux/include/linux/lcd.h (revision e7642f35)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * LCD Lowlevel Control Abstraction
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Copyright (C) 2003,2004 Hewlett-Packard Company
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #ifndef _LINUX_LCD_H
101da177e4SLinus Torvalds #define _LINUX_LCD_H
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/device.h>
1328ee086dSRichard Purdie #include <linux/mutex.h>
141da177e4SLinus Torvalds #include <linux/notifier.h>
15faa312daSEric Miao #include <linux/fb.h>
161da177e4SLinus Torvalds 
1728ee086dSRichard Purdie /* Notes on locking:
1828ee086dSRichard Purdie  *
19599a52d1SRichard Purdie  * lcd_device->ops_lock is an internal backlight lock protecting the ops
2028ee086dSRichard Purdie  * field and no code outside the core should need to touch it.
2128ee086dSRichard Purdie  *
2228ee086dSRichard Purdie  * Access to set_power() is serialised by the update_lock mutex since
2328ee086dSRichard Purdie  * most drivers seem to need this and historically get it wrong.
2428ee086dSRichard Purdie  *
2528ee086dSRichard Purdie  * Most drivers don't need locking on their get_power() method.
2628ee086dSRichard Purdie  * If yours does, you need to implement it in the driver. You can use the
2728ee086dSRichard Purdie  * update_lock mutex if appropriate.
2828ee086dSRichard Purdie  *
2928ee086dSRichard Purdie  * Any other use of the locks below is probably wrong.
3028ee086dSRichard Purdie  */
3128ee086dSRichard Purdie 
321da177e4SLinus Torvalds struct lcd_device;
331da177e4SLinus Torvalds struct fb_info;
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds struct lcd_properties {
36599a52d1SRichard Purdie 	/* The maximum value for contrast (read-only) */
37599a52d1SRichard Purdie 	int max_contrast;
38599a52d1SRichard Purdie };
39599a52d1SRichard Purdie 
40599a52d1SRichard Purdie struct lcd_ops {
411da177e4SLinus Torvalds 	/* Get the LCD panel power status (0: full on, 1..3: controller
421da177e4SLinus Torvalds 	   power on, flat panel power off, 4: full off), see FB_BLANK_XXX */
431da177e4SLinus Torvalds 	int (*get_power)(struct lcd_device *);
441da177e4SLinus Torvalds 	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
451da177e4SLinus Torvalds 	int (*set_power)(struct lcd_device *, int power);
461da177e4SLinus Torvalds 	/* Get the current contrast setting (0-max_contrast) */
471da177e4SLinus Torvalds 	int (*get_contrast)(struct lcd_device *);
481da177e4SLinus Torvalds 	/* Set LCD panel contrast */
491da177e4SLinus Torvalds         int (*set_contrast)(struct lcd_device *, int contrast);
50faa312daSEric Miao 	/* Set LCD panel mode (resolutions ...) */
51faa312daSEric Miao 	int (*set_mode)(struct lcd_device *, struct fb_videomode *);
521da177e4SLinus Torvalds 	/* Check if given framebuffer device is the one LCD is bound to;
531da177e4SLinus Torvalds 	   return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */
540c531360SBen Dooks 	int (*check_fb)(struct lcd_device *, struct fb_info *);
551da177e4SLinus Torvalds };
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds struct lcd_device {
58599a52d1SRichard Purdie 	struct lcd_properties props;
59599a52d1SRichard Purdie 	/* This protects the 'ops' field. If 'ops' is NULL, the driver that
601da177e4SLinus Torvalds 	   registered this device has been unloaded, and if class_get_devdata()
611da177e4SLinus Torvalds 	   points to something in the body of that driver, it is also invalid. */
62599a52d1SRichard Purdie 	struct mutex ops_lock;
631da177e4SLinus Torvalds 	/* If this is NULL, the backing module is unloaded */
64599a52d1SRichard Purdie 	struct lcd_ops *ops;
6528ee086dSRichard Purdie 	/* Serialise access to set_power method */
6628ee086dSRichard Purdie 	struct mutex update_lock;
671da177e4SLinus Torvalds 	/* The framebuffer notifier block */
681da177e4SLinus Torvalds 	struct notifier_block fb_notif;
69655bfd7aSRichard Purdie 
70655bfd7aSRichard Purdie 	struct device dev;
711da177e4SLinus Torvalds };
721da177e4SLinus Torvalds 
73ee378a5cSInKi Dae struct lcd_platform_data {
74ee378a5cSInKi Dae 	/* reset lcd panel device. */
75ee378a5cSInKi Dae 	int (*reset)(struct lcd_device *ld);
76ee378a5cSInKi Dae 	/* on or off to lcd panel. if 'enable' is 0 then
77ee378a5cSInKi Dae 	   lcd power off and 1, lcd power on. */
78ee378a5cSInKi Dae 	int (*power_on)(struct lcd_device *ld, int enable);
79ee378a5cSInKi Dae 
80ee378a5cSInKi Dae 	/* it indicates whether lcd panel was enabled
81ee378a5cSInKi Dae 	   from bootloader or not. */
82ee378a5cSInKi Dae 	int lcd_enabled;
83ee378a5cSInKi Dae 	/* it means delay for stable time when it becomes low to high
84ee378a5cSInKi Dae 	   or high to low that is dependent on whether reset gpio is
85ee378a5cSInKi Dae 	   low active or high active. */
86ee378a5cSInKi Dae 	unsigned int reset_delay;
87ee378a5cSInKi Dae 	/* stable time needing to become lcd power on. */
88ee378a5cSInKi Dae 	unsigned int power_on_delay;
89ee378a5cSInKi Dae 	/* stable time needing to become lcd power off. */
90ee378a5cSInKi Dae 	unsigned int power_off_delay;
91ee378a5cSInKi Dae 
92ee378a5cSInKi Dae 	/* it could be used for any purpose. */
93ee378a5cSInKi Dae 	void *pdata;
94ee378a5cSInKi Dae };
95ee378a5cSInKi Dae 
lcd_set_power(struct lcd_device * ld,int power)9628ee086dSRichard Purdie static inline void lcd_set_power(struct lcd_device *ld, int power)
9728ee086dSRichard Purdie {
9828ee086dSRichard Purdie 	mutex_lock(&ld->update_lock);
99599a52d1SRichard Purdie 	if (ld->ops && ld->ops->set_power)
100599a52d1SRichard Purdie 		ld->ops->set_power(ld, power);
10128ee086dSRichard Purdie 	mutex_unlock(&ld->update_lock);
10228ee086dSRichard Purdie }
10328ee086dSRichard Purdie 
1041da177e4SLinus Torvalds extern struct lcd_device *lcd_device_register(const char *name,
105655bfd7aSRichard Purdie 	struct device *parent, void *devdata, struct lcd_ops *ops);
1061d0c48e6SJingoo Han extern struct lcd_device *devm_lcd_device_register(struct device *dev,
1071d0c48e6SJingoo Han 	const char *name, struct device *parent,
1081d0c48e6SJingoo Han 	void *devdata, struct lcd_ops *ops);
1091da177e4SLinus Torvalds extern void lcd_device_unregister(struct lcd_device *ld);
1101d0c48e6SJingoo Han extern void devm_lcd_device_unregister(struct device *dev,
1111d0c48e6SJingoo Han 	struct lcd_device *ld);
1121da177e4SLinus Torvalds 
113655bfd7aSRichard Purdie #define to_lcd_device(obj) container_of(obj, struct lcd_device, dev)
114655bfd7aSRichard Purdie 
lcd_get_data(struct lcd_device * ld_dev)115655bfd7aSRichard Purdie static inline void * lcd_get_data(struct lcd_device *ld_dev)
116655bfd7aSRichard Purdie {
117655bfd7aSRichard Purdie 	return dev_get_drvdata(&ld_dev->dev);
118655bfd7aSRichard Purdie }
119655bfd7aSRichard Purdie 
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds #endif
122