xref: /linux/include/linux/lcd.h (revision e9ef810dfee7a2227da9d423aecb0ced35faddbe)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * LCD Lowlevel Control Abstraction
4  *
5  * Copyright (C) 2003,2004 Hewlett-Packard Company
6  *
7  */
8 
9 #ifndef _LINUX_LCD_H
10 #define _LINUX_LCD_H
11 
12 #include <linux/device.h>
13 #include <linux/mutex.h>
14 
15 #define LCD_POWER_ON			(0)
16 #define LCD_POWER_REDUCED		(1) // deprecated; don't use in new code
17 #define LCD_POWER_REDUCED_VSYNC_SUSPEND	(2) // deprecated; don't use in new code
18 #define LCD_POWER_OFF			(4)
19 
20 /* Notes on locking:
21  *
22  * lcd_device->ops_lock is an internal backlight lock protecting the ops
23  * field and no code outside the core should need to touch it.
24  *
25  * Access to set_power() is serialised by the update_lock mutex since
26  * most drivers seem to need this and historically get it wrong.
27  *
28  * Most drivers don't need locking on their get_power() method.
29  * If yours does, you need to implement it in the driver. You can use the
30  * update_lock mutex if appropriate.
31  *
32  * Any other use of the locks below is probably wrong.
33  */
34 
35 struct lcd_device;
36 
37 struct lcd_properties {
38 	/* The maximum value for contrast (read-only) */
39 	int max_contrast;
40 };
41 
42 struct lcd_ops {
43 	/* Get the LCD panel power status (0: full on, 1..3: controller
44 	   power on, flat panel power off, 4: full off), see FB_BLANK_XXX */
45 	int (*get_power)(struct lcd_device *);
46 	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
47 	int (*set_power)(struct lcd_device *, int power);
48 	/* Get the current contrast setting (0-max_contrast) */
49 	int (*get_contrast)(struct lcd_device *);
50 	/* Set LCD panel contrast */
51         int (*set_contrast)(struct lcd_device *, int contrast);
52 
53 	/*
54 	 * Set LCD panel mode (resolutions ...)
55 	 */
56 	int (*set_mode)(struct lcd_device *lcd, u32 xres, u32 yres);
57 
58 	/*
59 	 * Check if the LCD controls the given display device. This
60 	 * operation is optional and if not implemented it is assumed that
61 	 * the display is always the one controlled by the LCD.
62 	 *
63 	 * RETURNS:
64 	 *
65 	 * If display_dev is NULL or display_dev matches the device controlled by
66 	 * the LCD, return true. Otherwise return false.
67 	 */
68 	bool (*controls_device)(struct lcd_device *lcd, struct device *display_device);
69 };
70 
71 struct lcd_device {
72 	struct lcd_properties props;
73 	/* This protects the 'ops' field. If 'ops' is NULL, the driver that
74 	   registered this device has been unloaded, and if class_get_devdata()
75 	   points to something in the body of that driver, it is also invalid. */
76 	struct mutex ops_lock;
77 	/* If this is NULL, the backing module is unloaded */
78 	const struct lcd_ops *ops;
79 	/* Serialise access to set_power method */
80 	struct mutex update_lock;
81 
82 	/**
83 	 * @entry: List entry of all registered lcd devices
84 	 */
85 	struct list_head entry;
86 
87 	struct device dev;
88 };
89 
90 struct lcd_platform_data {
91 	/* reset lcd panel device. */
92 	int (*reset)(struct lcd_device *ld);
93 	/* on or off to lcd panel. if 'enable' is 0 then
94 	   lcd power off and 1, lcd power on. */
95 	int (*power_on)(struct lcd_device *ld, int enable);
96 
97 	/* it indicates whether lcd panel was enabled
98 	   from bootloader or not. */
99 	int lcd_enabled;
100 	/* it means delay for stable time when it becomes low to high
101 	   or high to low that is dependent on whether reset gpio is
102 	   low active or high active. */
103 	unsigned int reset_delay;
104 	/* stable time needing to become lcd power on. */
105 	unsigned int power_on_delay;
106 	/* stable time needing to become lcd power off. */
107 	unsigned int power_off_delay;
108 
109 	/* it could be used for any purpose. */
110 	void *pdata;
111 };
112 
lcd_set_power(struct lcd_device * ld,int power)113 static inline void lcd_set_power(struct lcd_device *ld, int power)
114 {
115 	mutex_lock(&ld->update_lock);
116 	if (ld->ops && ld->ops->set_power)
117 		ld->ops->set_power(ld, power);
118 	mutex_unlock(&ld->update_lock);
119 }
120 
121 extern struct lcd_device *lcd_device_register(const char *name,
122 	struct device *parent, void *devdata, const struct lcd_ops *ops);
123 extern struct lcd_device *devm_lcd_device_register(struct device *dev,
124 	const char *name, struct device *parent,
125 	void *devdata, const struct lcd_ops *ops);
126 extern void lcd_device_unregister(struct lcd_device *ld);
127 extern void devm_lcd_device_unregister(struct device *dev,
128 	struct lcd_device *ld);
129 
130 #if IS_REACHABLE(CONFIG_LCD_CLASS_DEVICE)
131 void lcd_notify_blank_all(struct device *display_dev, int power);
132 void lcd_notify_mode_change_all(struct device *display_dev,
133 				unsigned int width, unsigned int height);
134 #else
lcd_notify_blank_all(struct device * display_dev,int power)135 static inline void lcd_notify_blank_all(struct device *display_dev, int power)
136 {}
137 
lcd_notify_mode_change_all(struct device * display_dev,unsigned int width,unsigned int height)138 static inline void lcd_notify_mode_change_all(struct device *display_dev,
139 					      unsigned int width, unsigned int height)
140 {}
141 #endif
142 
143 #define to_lcd_device(obj) container_of(obj, struct lcd_device, dev)
144 
lcd_get_data(struct lcd_device * ld_dev)145 static inline void * lcd_get_data(struct lcd_device *ld_dev)
146 {
147 	return dev_get_drvdata(&ld_dev->dev);
148 }
149 
150 
151 #endif
152