Commit 96f970fe authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'backlight-next-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight

Pull backlight updates from Lee Jones:
 "Core Framework:
   - Trivial: Code refactoring
   - New API backlight_is_blank()
   - New API backlight_get_brightness()
   - Additional/reworked documentation
   - Remove 'extern' labels from prototypes
   - Drop backlight_put()
   - Staticify of_find_backlight()

  Driver Removal:
   - Removal of unused OT200 driver
   - Removal of unused Generic Backlight driver

  Fix-ups
   - Bunch of W=1 warning fixes
   - Convert to GPIO descriptors; sky81452
   - Move platform data handling into driver; sky81452
   - Remove superfluous code; lms501kf03
   - Many instances of using new APIs"

* tag 'backlight-next-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight: (34 commits)
  video: backlight: cr_bllcd: Remove unused variable 'intensity'
  backlight: backlight: Make of_find_backlight static
  backlight: backlight: Drop backlight_put()
  backlight: Use backlight_get_brightness() throughout
  backlight: jornada720_bl: Introduce backlight_is_blank()
  backlight: gpio_backlight: Simplify update_status()
  backlight: cr_bllcd: Introduce gpio-backlight semantics
  backlight: as3711_bl: Simplify update_status
  backlight: backlight: Introduce backlight_get_brightness()
  doc-rst: Wire-up Backlight kernel-doc documentation
  backlight: backlight: Add overview and update existing doc
  backlight: backlight: Drop extern from prototypes
  backlight: generic_bl: Remove this driver as it is unused
  backlight: backlight: Document enums in backlight.h
  backlight: backlight: Document inline functions in backlight.h
  backlight: backlight: Improve backlight_device documentation
  backlight: backlight: Improve backlight_properties documentation
  backlight: backlight: Improve backlight_ops documentation
  backlight: backlight: Add backlight_is_blank()
  backlight: backlight: Refactor fb_notifier_callback()
  ...
parents c636eef2 7eb99a39
=================
Backlight support
=================
.. kernel-doc:: drivers/video/backlight/backlight.c
:doc: overview
.. kernel-doc:: include/linux/backlight.h
:internal:
.. kernel-doc:: drivers/video/backlight/backlight.c
:export:
...@@ -12,6 +12,7 @@ Linux GPU Driver Developer's Guide ...@@ -12,6 +12,7 @@ Linux GPU Driver Developer's Guide
drm-uapi drm-uapi
drm-client drm-client
drivers drivers
backlight
vga-switcheroo vga-switcheroo
vgaarbiter vgaarbiter
todo todo
......
...@@ -47,8 +47,6 @@ static int sky81452_probe(struct i2c_client *client, ...@@ -47,8 +47,6 @@ static int sky81452_probe(struct i2c_client *client,
memset(cells, 0, sizeof(cells)); memset(cells, 0, sizeof(cells));
cells[0].name = "sky81452-backlight"; cells[0].name = "sky81452-backlight";
cells[0].of_compatible = "skyworks,sky81452-backlight"; cells[0].of_compatible = "skyworks,sky81452-backlight";
cells[0].platform_data = pdata->bl_pdata;
cells[0].pdata_size = sizeof(*pdata->bl_pdata);
cells[1].name = "sky81452-regulator"; cells[1].name = "sky81452-regulator";
cells[1].platform_data = pdata->regulator_init_data; cells[1].platform_data = pdata->regulator_init_data;
cells[1].pdata_size = sizeof(*pdata->regulator_init_data); cells[1].pdata_size = sizeof(*pdata->regulator_init_data);
......
...@@ -121,18 +121,7 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness) ...@@ -121,18 +121,7 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
static int pm860x_backlight_update_status(struct backlight_device *bl) static int pm860x_backlight_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return pm860x_backlight_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
return pm860x_backlight_set(bl, brightness);
} }
static int pm860x_backlight_get_brightness(struct backlight_device *bl) static int pm860x_backlight_get_brightness(struct backlight_device *bl)
......
...@@ -173,14 +173,6 @@ config BACKLIGHT_EP93XX ...@@ -173,14 +173,6 @@ config BACKLIGHT_EP93XX
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called ep93xx_bl. be called ep93xx_bl.
config BACKLIGHT_GENERIC
tristate "Generic (aka Sharp Corgi) Backlight Driver"
default y
help
Say y to enable the generic platform backlight driver previously
known as the Corgi backlight driver. If you have a Sharp Zaurus
SL-C7xx, SL-Cxx00 or SL-6000x say y.
config BACKLIGHT_IPAQ_MICRO config BACKLIGHT_IPAQ_MICRO
tristate "iPAQ microcontroller backlight driver" tristate "iPAQ microcontroller backlight driver"
depends on MFD_IPAQ_MICRO depends on MFD_IPAQ_MICRO
...@@ -386,13 +378,6 @@ config BACKLIGHT_LP8788 ...@@ -386,13 +378,6 @@ config BACKLIGHT_LP8788
help help
This supports TI LP8788 backlight driver. This supports TI LP8788 backlight driver.
config BACKLIGHT_OT200
tristate "Backlight driver for ot200 visualisation device"
depends on CS5535_MFGPT && GPIO_CS5535
help
To compile this driver as a module, choose M here: the module will be
called ot200_bl.
config BACKLIGHT_PANDORA config BACKLIGHT_PANDORA
tristate "Backlight driver for Pandora console" tristate "Backlight driver for Pandora console"
depends on TWL4030_CORE depends on TWL4030_CORE
......
...@@ -31,7 +31,6 @@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o ...@@ -31,7 +31,6 @@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o
obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
...@@ -45,7 +44,6 @@ obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o ...@@ -45,7 +44,6 @@ obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o
obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
......
...@@ -65,15 +65,7 @@ static int adp5520_bl_set(struct backlight_device *bl, int brightness) ...@@ -65,15 +65,7 @@ static int adp5520_bl_set(struct backlight_device *bl, int brightness)
static int adp5520_bl_update_status(struct backlight_device *bl) static int adp5520_bl_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return adp5520_bl_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
return adp5520_bl_set(bl, brightness);
} }
static int adp5520_bl_get_brightness(struct backlight_device *bl) static int adp5520_bl_get_brightness(struct backlight_device *bl)
......
...@@ -361,15 +361,7 @@ static int adp8860_bl_set(struct backlight_device *bl, int brightness) ...@@ -361,15 +361,7 @@ static int adp8860_bl_set(struct backlight_device *bl, int brightness)
static int adp8860_bl_update_status(struct backlight_device *bl) static int adp8860_bl_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return adp8860_bl_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
return adp8860_bl_set(bl, brightness);
} }
static int adp8860_bl_get_brightness(struct backlight_device *bl) static int adp8860_bl_get_brightness(struct backlight_device *bl)
......
...@@ -399,15 +399,7 @@ static int adp8870_bl_set(struct backlight_device *bl, int brightness) ...@@ -399,15 +399,7 @@ static int adp8870_bl_set(struct backlight_device *bl, int brightness)
static int adp8870_bl_update_status(struct backlight_device *bl) static int adp8870_bl_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return adp8870_bl_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
return adp8870_bl_set(bl, brightness);
} }
static int adp8870_bl_get_brightness(struct backlight_device *bl) static int adp8870_bl_get_brightness(struct backlight_device *bl)
......
...@@ -104,17 +104,10 @@ static int as3711_bl_update_status(struct backlight_device *bl) ...@@ -104,17 +104,10 @@ static int as3711_bl_update_status(struct backlight_device *bl)
struct as3711_bl_data *data = bl_get_data(bl); struct as3711_bl_data *data = bl_get_data(bl);
struct as3711_bl_supply *supply = to_supply(data); struct as3711_bl_supply *supply = to_supply(data);
struct as3711 *as3711 = supply->as3711; struct as3711 *as3711 = supply->as3711;
int brightness = bl->props.brightness; int brightness;
int ret = 0; int ret = 0;
dev_dbg(&bl->dev, "%s(): brightness %u, pwr %x, blank %x, state %x\n", brightness = backlight_get_brightness(bl);
__func__, bl->props.brightness, bl->props.power,
bl->props.fb_blank, bl->props.state);
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
if (data->type == AS3711_BL_SU1) { if (data->type == AS3711_BL_SU1) {
ret = as3711_set_brightness_v(as3711, brightness, ret = as3711_set_brightness_v(as3711, brightness,
......
...@@ -22,6 +22,47 @@ ...@@ -22,6 +22,47 @@
#include <asm/backlight.h> #include <asm/backlight.h>
#endif #endif
/**
* DOC: overview
*
* The backlight core supports implementing backlight drivers.
*
* A backlight driver registers a driver using
* devm_backlight_device_register(). The properties of the backlight
* driver such as type and max_brightness must be specified.
* When the core detect changes in for example brightness or power state
* the update_status() operation is called. The backlight driver shall
* implement this operation and use it to adjust backlight.
*
* Several sysfs attributes are provided by the backlight core::
*
* - brightness R/W, set the requested brightness level
* - actual_brightness RO, the brightness level used by the HW
* - max_brightness RO, the maximum brightness level supported
*
* See Documentation/ABI/stable/sysfs-class-backlight for the full list.
*
* The backlight can be adjusted using the sysfs interface, and
* the backlight driver may also support adjusting backlight using
* a hot-key or some other platform or firmware specific way.
*
* The driver must implement the get_brightness() operation if
* the HW do not support all the levels that can be specified in
* brightness, thus providing user-space access to the actual level
* via the actual_brightness attribute.
*
* When the backlight changes this is reported to user-space using
* an uevent connected to the actual_brightness attribute.
* When brightness is set by platform specific means, for example
* a hot-key to adjust backlight, the driver must notify the backlight
* core that brightness has changed using backlight_force_update().
*
* The backlight driver core receives notifications from fbdev and
* if the event is FB_EVENT_BLANK and if the value of blank, from the
* FBIOBLANK ioctrl, results in a change in the backlight state the
* update_status() operation is called.
*/
static struct list_head backlight_dev_list; static struct list_head backlight_dev_list;
static struct mutex backlight_dev_list_mutex; static struct mutex backlight_dev_list_mutex;
static struct blocking_notifier_head backlight_notifier; static struct blocking_notifier_head backlight_notifier;
...@@ -40,9 +81,17 @@ static const char *const backlight_scale_types[] = { ...@@ -40,9 +81,17 @@ static const char *const backlight_scale_types[] = {
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
/* This callback gets called when something important happens inside a /*
* framebuffer driver. We're looking if that important event is blanking, * fb_notifier_callback
* and if it is and necessary, we're switching backlight power as well ... *
* This callback gets called when something important happens inside a
* framebuffer driver. The backlight core only cares about FB_BLANK_UNBLANK
* which is reported to the driver using backlight_update_status()
* as a state change.
*
* There may be several fbdev's connected to the backlight device,
* in which case they are kept track of. A state change is only reported
* if there is a change in backlight for the specified fbdev.
*/ */
static int fb_notifier_callback(struct notifier_block *self, static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data) unsigned long event, void *data)
...@@ -58,28 +107,29 @@ static int fb_notifier_callback(struct notifier_block *self, ...@@ -58,28 +107,29 @@ static int fb_notifier_callback(struct notifier_block *self,
bd = container_of(self, struct backlight_device, fb_notif); bd = container_of(self, struct backlight_device, fb_notif);
mutex_lock(&bd->ops_lock); mutex_lock(&bd->ops_lock);
if (bd->ops)
if (!bd->ops->check_fb || if (!bd->ops)
bd->ops->check_fb(bd, evdata->info)) { goto out;
fb_blank = *(int *)evdata->data; if (bd->ops->check_fb && !bd->ops->check_fb(bd, evdata->info))
if (fb_blank == FB_BLANK_UNBLANK && goto out;
!bd->fb_bl_on[node]) {
bd->fb_bl_on[node] = true; fb_blank = *(int *)evdata->data;
if (!bd->use_count++) { if (fb_blank == FB_BLANK_UNBLANK && !bd->fb_bl_on[node]) {
bd->props.state &= ~BL_CORE_FBBLANK; bd->fb_bl_on[node] = true;
bd->props.fb_blank = FB_BLANK_UNBLANK; if (!bd->use_count++) {
backlight_update_status(bd); bd->props.state &= ~BL_CORE_FBBLANK;
} bd->props.fb_blank = FB_BLANK_UNBLANK;
} else if (fb_blank != FB_BLANK_UNBLANK && backlight_update_status(bd);
bd->fb_bl_on[node]) {
bd->fb_bl_on[node] = false;
if (!(--bd->use_count)) {
bd->props.state |= BL_CORE_FBBLANK;
bd->props.fb_blank = fb_blank;
backlight_update_status(bd);
}
}
} }
} else if (fb_blank != FB_BLANK_UNBLANK && bd->fb_bl_on[node]) {
bd->fb_bl_on[node] = false;
if (!(--bd->use_count)) {
bd->props.state |= BL_CORE_FBBLANK;
bd->props.fb_blank = fb_blank;
backlight_update_status(bd);
}
}
out:
mutex_unlock(&bd->ops_lock); mutex_unlock(&bd->ops_lock);
return 0; return 0;
} }
...@@ -320,9 +370,13 @@ ATTRIBUTE_GROUPS(bl_device); ...@@ -320,9 +370,13 @@ ATTRIBUTE_GROUPS(bl_device);
* backlight_force_update - tell the backlight subsystem that hardware state * backlight_force_update - tell the backlight subsystem that hardware state
* has changed * has changed
* @bd: the backlight device to update * @bd: the backlight device to update
* @reason: reason for update
* *
* Updates the internal state of the backlight in response to a hardware event, * Updates the internal state of the backlight in response to a hardware event,
* and generate a uevent to notify userspace * and generates an uevent to notify userspace. A backlight driver shall call
* backlight_force_update() when the backlight is changed using, for example,
* a hot-key. The updated brightness is read using get_brightness() and the
* brightness value is reported using an uevent.
*/ */
void backlight_force_update(struct backlight_device *bd, void backlight_force_update(struct backlight_device *bd,
enum backlight_update_reason reason) enum backlight_update_reason reason)
...@@ -335,19 +389,7 @@ void backlight_force_update(struct backlight_device *bd, ...@@ -335,19 +389,7 @@ void backlight_force_update(struct backlight_device *bd,
} }
EXPORT_SYMBOL(backlight_force_update); EXPORT_SYMBOL(backlight_force_update);
/** /* deprecated - use devm_backlight_device_register() */
* backlight_device_register - create and register a new object of
* backlight_device class.
* @name: the name of the new object(must be the same as the name of the
* respective framebuffer device).
* @parent: a pointer to the parent device
* @devdata: an optional pointer to be stored for private driver use. The
* methods may retrieve it by using bl_get_data(bd).
* @ops: the backlight operations structure.
*
* Creates and registers new backlight device. Returns either an
* ERR_PTR() or a pointer to the newly allocated device.
*/
struct backlight_device *backlight_device_register(const char *name, struct backlight_device *backlight_device_register(const char *name,
struct device *parent, void *devdata, const struct backlight_ops *ops, struct device *parent, void *devdata, const struct backlight_ops *ops,
const struct backlight_properties *props) const struct backlight_properties *props)
...@@ -414,6 +456,15 @@ struct backlight_device *backlight_device_register(const char *name, ...@@ -414,6 +456,15 @@ struct backlight_device *backlight_device_register(const char *name,
} }
EXPORT_SYMBOL(backlight_device_register); EXPORT_SYMBOL(backlight_device_register);
/** backlight_device_get_by_type - find first backlight device of a type
* @type: the type of backlight device
*
* Look up the first backlight device of the specified type
*
* RETURNS:
*
* Pointer to backlight device if any was found. Otherwise NULL.
*/
struct backlight_device *backlight_device_get_by_type(enum backlight_type type) struct backlight_device *backlight_device_get_by_type(enum backlight_type type)
{ {
bool found = false; bool found = false;
...@@ -453,12 +504,7 @@ struct backlight_device *backlight_device_get_by_name(const char *name) ...@@ -453,12 +504,7 @@ struct backlight_device *backlight_device_get_by_name(const char *name)
} }
EXPORT_SYMBOL(backlight_device_get_by_name); EXPORT_SYMBOL(backlight_device_get_by_name);
/** /* deprecated - use devm_backlight_device_unregister() */
* backlight_device_unregister - unregisters a backlight device object.
* @bd: the backlight device object to be unregistered and freed.
*
* Unregisters a previously registered via backlight_device_register object.
*/
void backlight_device_unregister(struct backlight_device *bd) void backlight_device_unregister(struct backlight_device *bd)
{ {
if (!bd) if (!bd)
...@@ -506,10 +552,12 @@ static int devm_backlight_device_match(struct device *dev, void *res, ...@@ -506,10 +552,12 @@ static int devm_backlight_device_match(struct device *dev, void *res,
* backlight_register_notifier - get notified of backlight (un)registration * backlight_register_notifier - get notified of backlight (un)registration
* @nb: notifier block with the notifier to call on backlight (un)registration * @nb: notifier block with the notifier to call on backlight (un)registration
* *
* @return 0 on success, otherwise a negative error code
*
* Register a notifier to get notified when backlight devices get registered * Register a notifier to get notified when backlight devices get registered
* or unregistered. * or unregistered.
*
* RETURNS:
*
* 0 on success, otherwise a negative error code
*/ */
int backlight_register_notifier(struct notifier_block *nb) int backlight_register_notifier(struct notifier_block *nb)
{ {
...@@ -521,10 +569,12 @@ EXPORT_SYMBOL(backlight_register_notifier); ...@@ -521,10 +569,12 @@ EXPORT_SYMBOL(backlight_register_notifier);
* backlight_unregister_notifier - unregister a backlight notifier * backlight_unregister_notifier - unregister a backlight notifier
* @nb: notifier block to unregister * @nb: notifier block to unregister
* *
* @return 0 on success, otherwise a negative error code
*
* Register a notifier to get notified when backlight devices get registered * Register a notifier to get notified when backlight devices get registered
* or unregistered. * or unregistered.
*
* RETURNS:
*
* 0 on success, otherwise a negative error code
*/ */
int backlight_unregister_notifier(struct notifier_block *nb) int backlight_unregister_notifier(struct notifier_block *nb)
{ {
...@@ -533,19 +583,21 @@ int backlight_unregister_notifier(struct notifier_block *nb) ...@@ -533,19 +583,21 @@ int backlight_unregister_notifier(struct notifier_block *nb)
EXPORT_SYMBOL(backlight_unregister_notifier); EXPORT_SYMBOL(backlight_unregister_notifier);
/** /**
* devm_backlight_device_register - resource managed backlight_device_register() * devm_backlight_device_register - register a new backlight device
* @dev: the device to register * @dev: the device to register
* @name: the name of the device * @name: the name of the device
* @parent: a pointer to the parent device * @parent: a pointer to the parent device (often the same as @dev)
* @devdata: an optional pointer to be stored for private driver use * @devdata: an optional pointer to be stored for private driver use
* @ops: the backlight operations structure * @ops: the backlight operations structure
* @props: the backlight properties * @props: the backlight properties
* *
* @return a struct backlight on success, or an ERR_PTR on error * Creates and registers new backlight device. When a backlight device
* is registered the configuration must be specified in the @props
* parameter. See description of &backlight_properties.
*
* RETURNS:
* *
* Managed backlight_device_register(). The backlight_device returned * struct backlight on success, or an ERR_PTR on error
* from this function are automatically freed on driver detach.
* See backlight_device_register() for more information.
*/ */
struct backlight_device *devm_backlight_device_register(struct device *dev, struct backlight_device *devm_backlight_device_register(struct device *dev,
const char *name, struct device *parent, void *devdata, const char *name, struct device *parent, void *devdata,
...@@ -573,13 +625,13 @@ struct backlight_device *devm_backlight_device_register(struct device *dev, ...@@ -573,13 +625,13 @@ struct backlight_device *devm_backlight_device_register(struct device *dev,
EXPORT_SYMBOL(devm_backlight_device_register); EXPORT_SYMBOL(devm_backlight_device_register);
/** /**
* devm_backlight_device_unregister - resource managed backlight_device_unregister() * devm_backlight_device_unregister - unregister backlight device
* @dev: the device to unregister * @dev: the device to unregister
* @bd: the backlight device to unregister * @bd: the backlight device to unregister
* *
* Deallocated a backlight allocated with devm_backlight_device_register(). * Deallocates a backlight allocated with devm_backlight_device_register().
* Normally this function will not need to be called and the resource management * Normally this function will not need to be called and the resource management
* code will ensure that the resource is freed. * code will ensure that the resources are freed.
*/ */
void devm_backlight_device_unregister(struct device *dev, void devm_backlight_device_unregister(struct device *dev,
struct backlight_device *bd) struct backlight_device *bd)
...@@ -621,22 +673,7 @@ struct backlight_device *of_find_backlight_by_node(struct device_node *node) ...@@ -621,22 +673,7 @@ struct backlight_device *of_find_backlight_by_node(struct device_node *node)
EXPORT_SYMBOL(of_find_backlight_by_node); EXPORT_SYMBOL(of_find_backlight_by_node);
#endif #endif
/** static struct backlight_device *of_find_backlight(struct device *dev)
* of_find_backlight - Get backlight device
* @dev: Device
*
* This function looks for a property named 'backlight' on the DT node
* connected to @dev and looks up the backlight device.
*
* Call backlight_put() to drop the reference on the backlight device.
*
* Returns:
* A pointer to the backlight device if found.
* Error pointer -EPROBE_DEFER if the DT property is set, but no backlight
* device is found.
* NULL if there's no backlight property.
*/
struct backlight_device *of_find_backlight(struct device *dev)
{ {
struct backlight_device *bd = NULL; struct backlight_device *bd = NULL;
struct device_node *np; struct device_node *np;
...@@ -662,20 +699,29 @@ struct backlight_device *of_find_backlight(struct device *dev) ...@@ -662,20 +699,29 @@ struct backlight_device *of_find_backlight(struct device *dev)
return bd; return bd;
} }
EXPORT_SYMBOL(of_find_backlight);
static void devm_backlight_release(void *data) static void devm_backlight_release(void *data)
{ {
backlight_put(data); struct backlight_device *bd = data;
if (bd)
put_device(&bd->dev);
} }
/** /**
* devm_of_find_backlight - Resource-managed of_find_backlight() * devm_of_find_backlight - find backlight for a device
* @dev: Device * @dev: the device
* *
* Device managed version of of_find_backlight(). * This function looks for a property named 'backlight' on the DT node
* The reference on the backlight device is automatically * connected to @dev and looks up the backlight device. The lookup is
* device managed so the reference to the backlight device is automatically
* dropped on driver detach. * dropped on driver detach.
*
* RETURNS:
*
* A pointer to the backlight device if found.
* Error pointer -EPROBE_DEFER if the DT property is set, but no backlight
* device is found. NULL if there's no backlight property.
*/ */
struct backlight_device *devm_of_find_backlight(struct device *dev) struct backlight_device *devm_of_find_backlight(struct device *dev)
{ {
...@@ -687,7 +733,7 @@ struct backlight_device *devm_of_find_backlight(struct device *dev) ...@@ -687,7 +733,7 @@ struct backlight_device *devm_of_find_backlight(struct device *dev)
return bd; return bd;
ret = devm_add_action(dev, devm_backlight_release, bd); ret = devm_add_action(dev, devm_backlight_release, bd);
if (ret) { if (ret) {
backlight_put(bd); put_device(&bd->dev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
return bd; return bd;
......
...@@ -82,12 +82,7 @@ static int bd6107_write(struct bd6107 *bd, u8 reg, u8 data) ...@@ -82,12 +82,7 @@ static int bd6107_write(struct bd6107 *bd, u8 reg, u8 data)
static int bd6107_backlight_update_status(struct backlight_device *backlight) static int bd6107_backlight_update_status(struct backlight_device *backlight)
{ {
struct bd6107 *bd = bl_get_data(backlight); struct bd6107 *bd = bl_get_data(backlight);
int brightness = backlight->props.brightness; int brightness = backlight_get_brightness(backlight);
if (backlight->props.power != FB_BLANK_UNBLANK ||
backlight->props.fb_blank != FB_BLANK_UNBLANK ||
backlight->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
if (brightness) { if (brightness) {
bd6107_write(bd, BD6107_PORTSEL, BD6107_PORTSEL_LEDM(2) | bd6107_write(bd, BD6107_PORTSEL, BD6107_PORTSEL_LEDM(2) |
......
...@@ -420,13 +420,7 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) ...@@ -420,13 +420,7 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
static int corgi_bl_update_status(struct backlight_device *bd) static int corgi_bl_update_status(struct backlight_device *bd)
{ {
struct corgi_lcd *lcd = bl_get_data(bd); struct corgi_lcd *lcd = bl_get_data(bd);
int intensity = bd->props.brightness; int intensity = backlight_get_brightness(bd);
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
if (corgibl_flags & CORGIBL_SUSPENDED) if (corgibl_flags & CORGIBL_SUSPENDED)
intensity = 0; intensity = 0;
......
...@@ -59,26 +59,18 @@ struct cr_panel { ...@@ -59,26 +59,18 @@ struct cr_panel {
static int cr_backlight_set_intensity(struct backlight_device *bd) static int cr_backlight_set_intensity(struct backlight_device *bd)
{ {
int intensity = bd->props.brightness;
u32 addr = gpio_bar + CRVML_PANEL_PORT; u32 addr = gpio_bar + CRVML_PANEL_PORT;
u32 cur = inl(addr); u32 cur = inl(addr);
if (bd->props.power == FB_BLANK_UNBLANK) if (backlight_get_brightness(bd) == 0) {
intensity = FB_BLANK_UNBLANK; /* OFF */
if (bd->props.fb_blank == FB_BLANK_UNBLANK)
intensity = FB_BLANK_UNBLANK;
if (bd->props.power == FB_BLANK_POWERDOWN)
intensity = FB_BLANK_POWERDOWN;
if (bd->props.fb_blank == FB_BLANK_POWERDOWN)
intensity = FB_BLANK_POWERDOWN;
if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */
cur &= ~CRVML_BACKLIGHT_OFF;
outl(cur, addr);
} else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */
cur |= CRVML_BACKLIGHT_OFF; cur |= CRVML_BACKLIGHT_OFF;
outl(cur, addr); outl(cur, addr);
} /* anything else, don't bother */ } else {
/* FULL ON */
cur &= ~CRVML_BACKLIGHT_OFF;
outl(cur, addr);
}
return 0; return 0;
} }
...@@ -90,9 +82,9 @@ static int cr_backlight_get_intensity(struct backlight_device *bd) ...@@ -90,9 +82,9 @@ static int cr_backlight_get_intensity(struct backlight_device *bd)
u8 intensity; u8 intensity;
if (cur & CRVML_BACKLIGHT_OFF) if (cur & CRVML_BACKLIGHT_OFF)
intensity = FB_BLANK_POWERDOWN; intensity = 0;
else else
intensity = FB_BLANK_UNBLANK; intensity = 1;
return intensity; return intensity;
} }
......
...@@ -77,18 +77,7 @@ static int da903x_backlight_set(struct backlight_device *bl, int brightness) ...@@ -77,18 +77,7 @@ static int da903x_backlight_set(struct backlight_device *bl, int brightness)
static int da903x_backlight_update_status(struct backlight_device *bl) static int da903x_backlight_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return da903x_backlight_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
return da903x_backlight_set(bl, brightness);
} }
static int da903x_backlight_get_brightness(struct backlight_device *bl) static int da903x_backlight_get_brightness(struct backlight_device *bl)
......
...@@ -36,13 +36,7 @@ static int ep93xxbl_set(struct backlight_device *bl, int brightness) ...@@ -36,13 +36,7 @@ static int ep93xxbl_set(struct backlight_device *bl, int brightness)
static int ep93xxbl_update_status(struct backlight_device *bl) static int ep93xxbl_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return ep93xxbl_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
return ep93xxbl_set(bl, brightness);
} }
static int ep93xxbl_get_brightness(struct backlight_device *bl) static int ep93xxbl_get_brightness(struct backlight_device *bl)
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Generic Backlight Driver
*
* Copyright (c) 2004-2008 Richard Purdie
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/fb.h>
#include <linux/backlight.h>
static int genericbl_intensity;
static struct backlight_device *generic_backlight_device;
static struct generic_bl_info *bl_machinfo;
static int genericbl_send_intensity(struct backlight_device *bd)
{
int intensity = bd->props.brightness;
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.state & BL_CORE_FBBLANK)
intensity = 0;
if (bd->props.state & BL_CORE_SUSPENDED)
intensity = 0;
bl_machinfo->set_bl_intensity(intensity);
genericbl_intensity = intensity;
if (bl_machinfo->kick_battery)
bl_machinfo->kick_battery();
return 0;
}
static int genericbl_get_intensity(struct backlight_device *bd)
{
return genericbl_intensity;
}
static const struct backlight_ops genericbl_ops = {
.options = BL_CORE_SUSPENDRESUME,
.get_brightness = genericbl_get_intensity,
.update_status = genericbl_send_intensity,
};
static int genericbl_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct generic_bl_info *machinfo = dev_get_platdata(&pdev->dev);
const char *name = "generic-bl";
struct backlight_device *bd;
bl_machinfo = machinfo;
if (!machinfo->limit_mask)
machinfo->limit_mask = -1;
if (machinfo->name)
name = machinfo->name;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = machinfo->max_intensity;
bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev,
NULL, &genericbl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
platform_set_drvdata(pdev, bd);
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = machinfo->default_intensity;
backlight_update_status(bd);
generic_backlight_device = bd;
dev_info(&pdev->dev, "Generic Backlight Driver Initialized.\n");
return 0;
}
static int genericbl_remove(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
bd->props.power = 0;
bd->props.brightness = 0;
backlight_update_status(bd);
dev_info(&pdev->dev, "Generic Backlight Driver Unloaded\n");
return 0;
}
static struct platform_driver genericbl_driver = {
.probe = genericbl_probe,
.remove = genericbl_remove,
.driver = {
.name = "generic-bl",
},
};
module_platform_driver(genericbl_driver);
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
MODULE_DESCRIPTION("Generic Backlight Driver");
MODULE_LICENSE("GPL");
...@@ -21,24 +21,11 @@ struct gpio_backlight { ...@@ -21,24 +21,11 @@ struct gpio_backlight {
struct gpio_desc *gpiod; struct gpio_desc *gpiod;
}; };
static int gpio_backlight_get_next_brightness(struct backlight_device *bl)
{
int brightness = bl->props.brightness;
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
return brightness;
}
static int gpio_backlight_update_status(struct backlight_device *bl) static int gpio_backlight_update_status(struct backlight_device *bl)
{ {
struct gpio_backlight *gbl = bl_get_data(bl); struct gpio_backlight *gbl = bl_get_data(bl);
int brightness = gpio_backlight_get_next_brightness(bl);
gpiod_set_value_cansleep(gbl->gpiod, brightness); gpiod_set_value_cansleep(gbl->gpiod, backlight_get_brightness(bl));
return 0; return 0;
} }
...@@ -108,7 +95,7 @@ static int gpio_backlight_probe(struct platform_device *pdev) ...@@ -108,7 +95,7 @@ static int gpio_backlight_probe(struct platform_device *pdev)
bl->props.brightness = 1; bl->props.brightness = 1;
init_brightness = gpio_backlight_get_next_brightness(bl); init_brightness = backlight_get_brightness(bl);
ret = gpiod_direction_output(gbl->gpiod, init_brightness); ret = gpiod_direction_output(gbl->gpiod, init_brightness);
if (ret) { if (ret) {
dev_err(dev, "failed to set initial brightness\n"); dev_err(dev, "failed to set initial brightness\n");
......
...@@ -33,12 +33,8 @@ static void hp680bl_send_intensity(struct backlight_device *bd) ...@@ -33,12 +33,8 @@ static void hp680bl_send_intensity(struct backlight_device *bd)
{ {
unsigned long flags; unsigned long flags;
u16 v; u16 v;
int intensity = bd->props.brightness; int intensity = backlight_get_brightness(bd);
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
if (hp680bl_suspended) if (hp680bl_suspended)
intensity = 0; intensity = 0;
......
...@@ -107,6 +107,8 @@ ...@@ -107,6 +107,8 @@
* lower frequency when the registers are read/written. * lower frequency when the registers are read/written.
* The macro sets the frequency in the spi_transfer structure if * The macro sets the frequency in the spi_transfer structure if
* the frequency exceeds the maximum value. * the frequency exceeds the maximum value.
* @s: pointer to an SPI device
* @x: pointer to the read/write buffer pair
*/ */
#define CHECK_FREQ_REG(s, x) \ #define CHECK_FREQ_REG(s, x) \
do { \ do { \
...@@ -121,7 +123,7 @@ ...@@ -121,7 +123,7 @@
#define set_tx_byte(b) (tx_invert ? ~(b) : b) #define set_tx_byte(b) (tx_invert ? ~(b) : b)
/** /*
* ili922x_id - id as set by manufacturer * ili922x_id - id as set by manufacturer
*/ */
static int ili922x_id = 1; static int ili922x_id = 1;
...@@ -130,7 +132,7 @@ module_param(ili922x_id, int, 0); ...@@ -130,7 +132,7 @@ module_param(ili922x_id, int, 0);
static int tx_invert; static int tx_invert;
module_param(tx_invert, int, 0); module_param(tx_invert, int, 0);
/** /*
* driver's private structure * driver's private structure
*/ */
struct ili922x { struct ili922x {
...@@ -293,6 +295,8 @@ static int ili922x_write(struct spi_device *spi, u8 reg, u16 value) ...@@ -293,6 +295,8 @@ static int ili922x_write(struct spi_device *spi, u8 reg, u16 value)
#ifdef DEBUG #ifdef DEBUG
/** /**
* ili922x_reg_dump - dump all registers * ili922x_reg_dump - dump all registers
*
* @spi: pointer to an SPI device
*/ */
static void ili922x_reg_dump(struct spi_device *spi) static void ili922x_reg_dump(struct spi_device *spi)
{ {
......
...@@ -54,7 +54,7 @@ static int jornada_bl_update_status(struct backlight_device *bd) ...@@ -54,7 +54,7 @@ static int jornada_bl_update_status(struct backlight_device *bd)
jornada_ssp_start(); jornada_ssp_start();
/* If backlight is off then really turn it off */ /* If backlight is off then really turn it off */
if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) { if (backlight_is_blank(bd)) {
ret = jornada_ssp_byte(BRIGHTNESSOFF); ret = jornada_ssp_byte(BRIGHTNESSOFF);
if (ret != TXDUMMY) { if (ret != TXDUMMY) {
dev_info(&bd->dev, "brightness off timeout\n"); dev_info(&bd->dev, "brightness off timeout\n");
......
...@@ -87,12 +87,8 @@ static const struct dmi_system_id kb3886bl_device_table[] __initconst = { ...@@ -87,12 +87,8 @@ static const struct dmi_system_id kb3886bl_device_table[] __initconst = {
static int kb3886bl_send_intensity(struct backlight_device *bd) static int kb3886bl_send_intensity(struct backlight_device *bd)
{ {
int intensity = bd->props.brightness; int intensity = backlight_get_brightness(bd);
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
if (kb3886bl_flags & KB3886BL_SUSPENDED) if (kb3886bl_flags & KB3886BL_SUSPENDED)
intensity = 0; intensity = 0;
......
...@@ -179,6 +179,7 @@ ATTRIBUTE_GROUPS(lcd_device); ...@@ -179,6 +179,7 @@ ATTRIBUTE_GROUPS(lcd_device);
* lcd_device_register - register a new object of lcd_device class. * lcd_device_register - register a new object of lcd_device class.
* @name: the name of the new object(must be the same as the name of the * @name: the name of the new object(must be the same as the name of the
* respective framebuffer device). * respective framebuffer device).
* @parent: pointer to the parent's struct device .
* @devdata: an optional pointer to be stored in the device. The * @devdata: an optional pointer to be stored in the device. The
* methods may retrieve it by using lcd_get_data(ld). * methods may retrieve it by using lcd_get_data(ld).
* @ops: the lcd operations structure. * @ops: the lcd operations structure.
......
...@@ -54,12 +54,7 @@ static void led_bl_power_off(struct led_bl_data *priv) ...@@ -54,12 +54,7 @@ static void led_bl_power_off(struct led_bl_data *priv)
static int led_bl_update_status(struct backlight_device *bl) static int led_bl_update_status(struct backlight_device *bl)
{ {
struct led_bl_data *priv = bl_get_data(bl); struct led_bl_data *priv = bl_get_data(bl);
int brightness = bl->props.brightness; int brightness = backlight_get_brightness(bl);
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
if (brightness > 0) if (brightness > 0)
led_bl_set_brightness(priv, brightness); led_bl_set_brightness(priv, brightness);
......
...@@ -39,14 +39,8 @@ static inline int lm3533_bl_get_ctrlbank_id(struct lm3533_bl *bl) ...@@ -39,14 +39,8 @@ static inline int lm3533_bl_get_ctrlbank_id(struct lm3533_bl *bl)
static int lm3533_bl_update_status(struct backlight_device *bd) static int lm3533_bl_update_status(struct backlight_device *bd)
{ {
struct lm3533_bl *bl = bl_get_data(bd); struct lm3533_bl *bl = bl_get_data(bd);
int brightness = bd->props.brightness;
if (bd->props.power != FB_BLANK_UNBLANK) return lm3533_ctrlbank_set_brightness(&bl->cb, backlight_get_brightness(bd));
brightness = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
return lm3533_ctrlbank_set_brightness(&bl->cb, (u8)brightness);
} }
static int lm3533_bl_get_brightness(struct backlight_device *bd) static int lm3533_bl_get_brightness(struct backlight_device *bd)
...@@ -235,7 +229,7 @@ static struct attribute *lm3533_bl_attributes[] = { ...@@ -235,7 +229,7 @@ static struct attribute *lm3533_bl_attributes[] = {
static umode_t lm3533_bl_attr_is_visible(struct kobject *kobj, static umode_t lm3533_bl_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n) struct attribute *attr, int n)
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = kobj_to_dev(kobj);
struct lm3533_bl *bl = dev_get_drvdata(dev); struct lm3533_bl *bl = dev_get_drvdata(dev);
umode_t mode = attr->mode; umode_t mode = attr->mode;
......
...@@ -391,7 +391,7 @@ static int lm3630a_parse_led_sources(struct fwnode_handle *node, ...@@ -391,7 +391,7 @@ static int lm3630a_parse_led_sources(struct fwnode_handle *node,
return ret; return ret;
for (i = 0; i < num_sources; i++) { for (i = 0; i < num_sources; i++) {
if (sources[i] < LM3630A_SINK_0 || sources[i] > LM3630A_SINK_1) if (sources[i] != LM3630A_SINK_0 && sources[i] != LM3630A_SINK_1)
return -EINVAL; return -EINVAL;
ret |= BIT(sources[i]); ret |= BIT(sources[i]);
...@@ -412,7 +412,7 @@ static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata, ...@@ -412,7 +412,7 @@ static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata,
if (ret) if (ret)
return ret; return ret;
if (bank < LM3630A_BANK_0 || bank > LM3630A_BANK_1) if (bank != LM3630A_BANK_0 && bank != LM3630A_BANK_1)
return -EINVAL; return -EINVAL;
led_sources = lm3630a_parse_led_sources(node, BIT(bank)); led_sources = lm3630a_parse_led_sources(node, BIT(bank));
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/lcd.h> #include <linux/lcd.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -89,14 +88,6 @@ static const unsigned char seq_rgb_gamma[] = { ...@@ -89,14 +88,6 @@ static const unsigned char seq_rgb_gamma[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
static const unsigned char seq_up_dn[] = {
0x36, 0x10,
};
static const unsigned char seq_sleep_in[] = {
0x10,
};
static const unsigned char seq_sleep_out[] = { static const unsigned char seq_sleep_out[] = {
0x11, 0x11,
}; };
......
...@@ -111,12 +111,8 @@ static int current_intensity; ...@@ -111,12 +111,8 @@ static int current_intensity;
static int locomolcd_set_intensity(struct backlight_device *bd) static int locomolcd_set_intensity(struct backlight_device *bd)
{ {
int intensity = bd->props.brightness; int intensity = backlight_get_brightness(bd);
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
if (locomolcd_flags & LOCOMOLCD_SUSPENDED) if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
intensity = 0; intensity = 0;
......
...@@ -46,12 +46,7 @@ static int lv5207lp_write(struct lv5207lp *lv, u8 reg, u8 data) ...@@ -46,12 +46,7 @@ static int lv5207lp_write(struct lv5207lp *lv, u8 reg, u8 data)
static int lv5207lp_backlight_update_status(struct backlight_device *backlight) static int lv5207lp_backlight_update_status(struct backlight_device *backlight)
{ {
struct lv5207lp *lv = bl_get_data(backlight); struct lv5207lp *lv = bl_get_data(backlight);
int brightness = backlight->props.brightness; int brightness = backlight_get_brightness(backlight);
if (backlight->props.power != FB_BLANK_UNBLANK ||
backlight->props.fb_blank != FB_BLANK_UNBLANK ||
backlight->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
if (brightness) { if (brightness) {
lv5207lp_write(lv, LV5207LP_CTRL1, lv5207lp_write(lv, LV5207LP_CTRL1,
......
...@@ -64,18 +64,7 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness) ...@@ -64,18 +64,7 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness)
static int max8925_backlight_update_status(struct backlight_device *bl) static int max8925_backlight_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return max8925_backlight_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
return max8925_backlight_set(bl, brightness);
} }
static int max8925_backlight_get_brightness(struct backlight_device *bl) static int max8925_backlight_get_brightness(struct backlight_device *bl)
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2012 Bachmann electronic GmbH
* Christian Gmeiner <christian.gmeiner@gmail.com>
*
* Backlight driver for ot200 visualisation device from
* Bachmann electronic GmbH.
*/
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/cs5535.h>
static struct cs5535_mfgpt_timer *pwm_timer;
/* this array defines the mapping of brightness in % to pwm frequency */
static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28,
30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50,
53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88,
93, 97, 103, 108, 114, 120, 126, 133, 140,
147, 155, 163};
struct ot200_backlight_data {
int current_brightness;
};
#define GPIO_DIMM 27
#define SCALE 1
#define CMP1MODE 0x2 /* compare on GE; output high on compare
* greater than or equal */
#define PWM_SETUP (SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN)
#define MAX_COMP2 163
static int ot200_backlight_update_status(struct backlight_device *bl)
{
struct ot200_backlight_data *data = bl_get_data(bl);
int brightness = bl->props.brightness;
if (bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
/* enable or disable PWM timer */
if (brightness == 0)
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0);
else if (data->current_brightness == 0) {
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP,
MFGPT_SETUP_CNTEN);
}
/* apply new brightness value */
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
MAX_COMP2 - dim_table[brightness]);
data->current_brightness = brightness;
return 0;
}
static int ot200_backlight_get_brightness(struct backlight_device *bl)
{
struct ot200_backlight_data *data = bl_get_data(bl);
return data->current_brightness;
}
static const struct backlight_ops ot200_backlight_ops = {
.update_status = ot200_backlight_update_status,
.get_brightness = ot200_backlight_get_brightness,
};
static int ot200_backlight_probe(struct platform_device *pdev)
{
struct backlight_device *bl;
struct ot200_backlight_data *data;
struct backlight_properties props;
int retval = 0;
/* request gpio */
if (devm_gpio_request(&pdev->dev, GPIO_DIMM,
"ot200 backlight dimmer") < 0) {
dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM);
return -ENODEV;
}
/* request timer */
pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY);
if (!pwm_timer) {
dev_err(&pdev->dev, "MFGPT 7 not available\n");
return -ENODEV;
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
retval = -ENOMEM;
goto error_devm_kzalloc;
}
/* setup gpio */
cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE);
cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1);
/* setup timer */
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP);
data->current_brightness = 100;
props.max_brightness = 100;
props.brightness = 100;
props.type = BACKLIGHT_RAW;
bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
&pdev->dev, data, &ot200_backlight_ops,
&props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
retval = PTR_ERR(bl);
goto error_devm_kzalloc;
}
platform_set_drvdata(pdev, bl);
return 0;
error_devm_kzalloc:
cs5535_mfgpt_free_timer(pwm_timer);
return retval;
}
static int ot200_backlight_remove(struct platform_device *pdev)
{
/* on module unload set brightness to 100% */
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
MAX_COMP2 - dim_table[100]);
cs5535_mfgpt_free_timer(pwm_timer);
return 0;
}
static struct platform_driver ot200_backlight_driver = {
.driver = {
.name = "ot200-backlight",
},
.probe = ot200_backlight_probe,
.remove = ot200_backlight_remove,
};
module_platform_driver(ot200_backlight_driver);
MODULE_DESCRIPTION("backlight driver for ot200 visualisation device");
MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ot200-backlight");
...@@ -108,14 +108,9 @@ static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) ...@@ -108,14 +108,9 @@ static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
static int pwm_backlight_update_status(struct backlight_device *bl) static int pwm_backlight_update_status(struct backlight_device *bl)
{ {
struct pwm_bl_data *pb = bl_get_data(bl); struct pwm_bl_data *pb = bl_get_data(bl);
int brightness = bl->props.brightness; int brightness = backlight_get_brightness(bl);
struct pwm_state state; struct pwm_state state;
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
if (pb->notify) if (pb->notify)
brightness = pb->notify(pb->dev, brightness); brightness = pb->notify(pb->dev, brightness);
......
...@@ -433,14 +433,9 @@ static int wled5_ovp_delay(struct wled *wled) ...@@ -433,14 +433,9 @@ static int wled5_ovp_delay(struct wled *wled)
static int wled_update_status(struct backlight_device *bl) static int wled_update_status(struct backlight_device *bl)
{ {
struct wled *wled = bl_get_data(bl); struct wled *wled = bl_get_data(bl);
u16 brightness = bl->props.brightness; u16 brightness = backlight_get_brightness(bl);
int rc = 0; int rc = 0;
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
bl->props.state & BL_CORE_FBBLANK)
brightness = 0;
mutex_lock(&wled->lock); mutex_lock(&wled->lock);
if (brightness) { if (brightness) {
rc = wled->wled_set_brightness(wled, brightness); rc = wled->wled_set_brightness(wled, brightness);
...@@ -1287,14 +1282,6 @@ static const struct wled_var_cfg wled4_string_i_limit_cfg = { ...@@ -1287,14 +1282,6 @@ static const struct wled_var_cfg wled4_string_i_limit_cfg = {
.size = ARRAY_SIZE(wled4_string_i_limit_values), .size = ARRAY_SIZE(wled4_string_i_limit_values),
}; };
static const struct wled_var_cfg wled3_string_cfg = {
.size = 8,
};
static const struct wled_var_cfg wled4_string_cfg = {
.size = 16,
};
static const struct wled_var_cfg wled5_mod_sel_cfg = { static const struct wled_var_cfg wled5_mod_sel_cfg = {
.size = 2, .size = 2,
}; };
......
...@@ -8,15 +8,13 @@ ...@@ -8,15 +8,13 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/platform_data/sky81452-backlight.h>
#include <linux/slab.h> #include <linux/slab.h>
/* registers */ /* registers */
...@@ -42,6 +40,29 @@ ...@@ -42,6 +40,29 @@
#define SKY81452_DEFAULT_NAME "lcd-backlight" #define SKY81452_DEFAULT_NAME "lcd-backlight"
#define SKY81452_MAX_BRIGHTNESS (SKY81452_CS + 1) #define SKY81452_MAX_BRIGHTNESS (SKY81452_CS + 1)
/**
* struct sky81452_platform_data
* @name: backlight driver name.
* If it is not defined, default name is lcd-backlight.
* @gpiod_enable:GPIO descriptor which control EN pin
* @enable: Enable mask for current sink channel 1, 2, 3, 4, 5 and 6.
* @ignore_pwm: true if DPWMI should be ignored.
* @dpwm_mode: true is DPWM dimming mode, otherwise Analog dimming mode.
* @phase_shift:true is phase shift mode.
* @short_detection_threshold: It should be one of 4, 5, 6 and 7V.
* @boost_current_limit: It should be one of 2300, 2750mA.
*/
struct sky81452_bl_platform_data {
const char *name;
struct gpio_desc *gpiod_enable;
unsigned int enable;
bool ignore_pwm;
bool dpwm_mode;
bool phase_shift;
unsigned int short_detection_threshold;
unsigned int boost_current_limit;
};
#define CTZ(b) __builtin_ctz(b) #define CTZ(b) __builtin_ctz(b)
static int sky81452_bl_update_status(struct backlight_device *bd) static int sky81452_bl_update_status(struct backlight_device *bd)
...@@ -182,7 +203,7 @@ static struct sky81452_bl_platform_data *sky81452_bl_parse_dt( ...@@ -182,7 +203,7 @@ static struct sky81452_bl_platform_data *sky81452_bl_parse_dt(
pdata->ignore_pwm = of_property_read_bool(np, "skyworks,ignore-pwm"); pdata->ignore_pwm = of_property_read_bool(np, "skyworks,ignore-pwm");
pdata->dpwm_mode = of_property_read_bool(np, "skyworks,dpwm-mode"); pdata->dpwm_mode = of_property_read_bool(np, "skyworks,dpwm-mode");
pdata->phase_shift = of_property_read_bool(np, "skyworks,phase-shift"); pdata->phase_shift = of_property_read_bool(np, "skyworks,phase-shift");
pdata->gpio_enable = of_get_gpio(np, 0); pdata->gpiod_enable = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
ret = of_property_count_u32_elems(np, "led-sources"); ret = of_property_count_u32_elems(np, "led-sources");
if (ret < 0) { if (ret < 0) {
...@@ -252,26 +273,15 @@ static int sky81452_bl_probe(struct platform_device *pdev) ...@@ -252,26 +273,15 @@ static int sky81452_bl_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct regmap *regmap = dev_get_drvdata(dev->parent); struct regmap *regmap = dev_get_drvdata(dev->parent);
struct sky81452_bl_platform_data *pdata = dev_get_platdata(dev); struct sky81452_bl_platform_data *pdata;
struct backlight_device *bd; struct backlight_device *bd;
struct backlight_properties props; struct backlight_properties props;
const char *name; const char *name;
int ret; int ret;
if (!pdata) { pdata = sky81452_bl_parse_dt(dev);
pdata = sky81452_bl_parse_dt(dev); if (IS_ERR(pdata))
if (IS_ERR(pdata)) return PTR_ERR(pdata);
return PTR_ERR(pdata);
}
if (gpio_is_valid(pdata->gpio_enable)) {
ret = devm_gpio_request_one(dev, pdata->gpio_enable,
GPIOF_OUT_INIT_HIGH, "sky81452-en");
if (ret < 0) {
dev_err(dev, "failed to request GPIO. err=%d\n", ret);
return ret;
}
}
ret = sky81452_bl_init_device(regmap, pdata); ret = sky81452_bl_init_device(regmap, pdata);
if (ret < 0) { if (ret < 0) {
...@@ -312,8 +322,8 @@ static int sky81452_bl_remove(struct platform_device *pdev) ...@@ -312,8 +322,8 @@ static int sky81452_bl_remove(struct platform_device *pdev)
bd->props.brightness = 0; bd->props.brightness = 0;
backlight_update_status(bd); backlight_update_status(bd);
if (gpio_is_valid(pdata->gpio_enable)) if (pdata->gpiod_enable)
gpio_set_value_cansleep(pdata->gpio_enable, 0); gpiod_set_value_cansleep(pdata->gpiod_enable, 0);
return 0; return 0;
} }
......
...@@ -77,15 +77,7 @@ static int tps65217_bl_update_status(struct backlight_device *bl) ...@@ -77,15 +77,7 @@ static int tps65217_bl_update_status(struct backlight_device *bl)
{ {
struct tps65217_bl *tps65217_bl = bl_get_data(bl); struct tps65217_bl *tps65217_bl = bl_get_data(bl);
int rc; int rc;
int brightness = bl->props.brightness; int brightness = backlight_get_brightness(bl);
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
if ((bl->props.power != FB_BLANK_UNBLANK) ||
(bl->props.fb_blank != FB_BLANK_UNBLANK))
/* framebuffer in low power mode or blanking active */
brightness = 0;
if (brightness > 0) { if (brightness > 0) {
rc = tps65217_reg_write(tps65217_bl->tps, rc = tps65217_reg_write(tps65217_bl->tps,
......
...@@ -91,18 +91,7 @@ static int wm831x_backlight_set(struct backlight_device *bl, int brightness) ...@@ -91,18 +91,7 @@ static int wm831x_backlight_set(struct backlight_device *bl, int brightness)
static int wm831x_backlight_update_status(struct backlight_device *bl) static int wm831x_backlight_update_status(struct backlight_device *bl)
{ {
int brightness = bl->props.brightness; return wm831x_backlight_set(bl, backlight_get_brightness(bl));
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.state & BL_CORE_SUSPENDED)
brightness = 0;
return wm831x_backlight_set(bl, brightness);
} }
static int wm831x_backlight_get_brightness(struct backlight_device *bl) static int wm831x_backlight_get_brightness(struct backlight_device *bl)
......
...@@ -14,113 +14,336 @@ ...@@ -14,113 +14,336 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/notifier.h> #include <linux/notifier.h>
/* Notes on locking: /**
* * enum backlight_update_reason - what method was used to update backlight
* backlight_device->ops_lock is an internal backlight lock protecting the
* ops pointer and no code outside the core should need to touch it.
*
* Access to update_status() is serialised by the update_lock mutex since
* most drivers seem to need this and historically get it wrong.
*
* Most drivers don't need locking on their get_brightness() method.
* If yours does, you need to implement it in the driver. You can use the
* update_lock mutex if appropriate.
* *
* Any other use of the locks below is probably wrong. * A driver indicates the method (reason) used for updating the backlight
* when calling backlight_force_update().
*/ */
enum backlight_update_reason { enum backlight_update_reason {
/**
* @BACKLIGHT_UPDATE_HOTKEY: The backlight was updated using a hot-key.
*/
BACKLIGHT_UPDATE_HOTKEY, BACKLIGHT_UPDATE_HOTKEY,
/**
* @BACKLIGHT_UPDATE_SYSFS: The backlight was updated using sysfs.
*/
BACKLIGHT_UPDATE_SYSFS, BACKLIGHT_UPDATE_SYSFS,
}; };
/**
* enum backlight_type - the type of backlight control
*
* The type of interface used to control the backlight.
*/
enum backlight_type { enum backlight_type {
/**
* @BACKLIGHT_RAW:
*
* The backlight is controlled using hardware registers.
*/
BACKLIGHT_RAW = 1, BACKLIGHT_RAW = 1,
/**
* @BACKLIGHT_PLATFORM:
*
* The backlight is controlled using a platform-specific interface.
*/
BACKLIGHT_PLATFORM, BACKLIGHT_PLATFORM,
/**
* @BACKLIGHT_FIRMWARE:
*
* The backlight is controlled using a standard firmware interface.
*/
BACKLIGHT_FIRMWARE, BACKLIGHT_FIRMWARE,
/**
* @BACKLIGHT_TYPE_MAX: Number of entries.
*/
BACKLIGHT_TYPE_MAX, BACKLIGHT_TYPE_MAX,
}; };
/**
* enum backlight_notification - the type of notification
*
* The notifications that is used for notification sent to the receiver
* that registered notifications using backlight_register_notifier().
*/
enum backlight_notification { enum backlight_notification {
/**
* @BACKLIGHT_REGISTERED: The backlight device is registered.
*/
BACKLIGHT_REGISTERED, BACKLIGHT_REGISTERED,
/**
* @BACKLIGHT_UNREGISTERED: The backlight revice is unregistered.
*/
BACKLIGHT_UNREGISTERED, BACKLIGHT_UNREGISTERED,
}; };
/** enum backlight_scale - the type of scale used for brightness values
*
* The type of scale used for brightness values.
*/
enum backlight_scale { enum backlight_scale {
/**
* @BACKLIGHT_SCALE_UNKNOWN: The scale is unknown.
*/
BACKLIGHT_SCALE_UNKNOWN = 0, BACKLIGHT_SCALE_UNKNOWN = 0,
/**
* @BACKLIGHT_SCALE_LINEAR: The scale is linear.
*
* The linear scale will increase brightness the same for each step.
*/
BACKLIGHT_SCALE_LINEAR, BACKLIGHT_SCALE_LINEAR,
/**
* @BACKLIGHT_SCALE_NON_LINEAR: The scale is not linear.
*
* This is often used when the brightness values tries to adjust to
* the relative perception of the eye demanding a non-linear scale.
*/
BACKLIGHT_SCALE_NON_LINEAR, BACKLIGHT_SCALE_NON_LINEAR,
}; };
struct backlight_device; struct backlight_device;
struct fb_info; struct fb_info;
/**
* struct backlight_ops - backlight operations
*
* The backlight operations are specified when the backlight device is registered.
*/
struct backlight_ops { struct backlight_ops {
/**
* @options: Configure how operations are called from the core.
*
* The options parameter is used to adjust the behaviour of the core.
* Set BL_CORE_SUSPENDRESUME to get the update_status() operation called
* upon suspend and resume.
*/
unsigned int options; unsigned int options;
#define BL_CORE_SUSPENDRESUME (1 << 0) #define BL_CORE_SUSPENDRESUME (1 << 0)
/* Notify the backlight driver some property has changed */ /**
* @update_status: Operation called when properties have changed.
*
* Notify the backlight driver some property has changed.
* The update_status operation is protected by the update_lock.
*
* The backlight driver is expected to use backlight_is_blank()
* to check if the display is blanked and set brightness accordingly.
* update_status() is called when any of the properties has changed.
*
* RETURNS:
*
* 0 on success, negative error code if any failure occurred.
*/
int (*update_status)(struct backlight_device *); int (*update_status)(struct backlight_device *);
/* Return the current backlight brightness (accounting for power,
fb_blank etc.) */ /**
* @get_brightness: Return the current backlight brightness.
*
* The driver may implement this as a readback from the HW.
* This operation is optional and if not present then the current
* brightness property value is used.
*
* RETURNS:
*
* A brightness value which is 0 or a positive number.
* On failure a negative error code is returned.
*/
int (*get_brightness)(struct backlight_device *); int (*get_brightness)(struct backlight_device *);
/* Check if given framebuffer device is the one bound to this backlight;
return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ /**
int (*check_fb)(struct backlight_device *, struct fb_info *); * @check_fb: Check the framebuffer device.
*
* Check if given framebuffer device is the one bound to this backlight.
* This operation is optional and if not implemented it is assumed that the
* fbdev is always the one bound to the backlight.
*
* RETURNS:
*
* If info is NULL or the info matches the fbdev bound to the backlight return true.
* If info does not match the fbdev bound to the backlight return false.
*/
int (*check_fb)(struct backlight_device *bd, struct fb_info *info);
}; };
/* This structure defines all the properties of a backlight */ /**
* struct backlight_properties - backlight properties
*
* This structure defines all the properties of a backlight.
*/
struct backlight_properties { struct backlight_properties {
/* Current User requested brightness (0 - max_brightness) */ /**
* @brightness: The current brightness requested by the user.
*
* The backlight core makes sure the range is (0 to max_brightness)
* when the brightness is set via the sysfs attribute:
* /sys/class/backlight/<backlight>/brightness.
*
* This value can be set in the backlight_properties passed
* to devm_backlight_device_register() to set a default brightness
* value.
*/
int brightness; int brightness;
/* Maximal value for brightness (read-only) */
/**
* @max_brightness: The maximum brightness value.
*
* This value must be set in the backlight_properties passed to
* devm_backlight_device_register() and shall not be modified by the
* driver after registration.
*/
int max_brightness; int max_brightness;
/* Current FB Power mode (0: full on, 1..3: power saving
modes; 4: full off), see FB_BLANK_XXX */ /**
* @power: The current power mode.
*
* User space can configure the power mode using the sysfs
* attribute: /sys/class/backlight/<backlight>/bl_power
* When the power property is updated update_status() is called.
*
* The possible values are: (0: full on, 1 to 3: power saving
* modes; 4: full off), see FB_BLANK_XXX.
*
* When the backlight device is enabled @power is set
* to FB_BLANK_UNBLANK. When the backlight device is disabled
* @power is set to FB_BLANK_POWERDOWN.
*/
int power; int power;
/* FB Blanking active? (values as for power) */
/* Due to be removed, please use (state & BL_CORE_FBBLANK) */ /**
* @fb_blank: The power state from the FBIOBLANK ioctl.
*
* When the FBIOBLANK ioctl is called @fb_blank is set to the
* blank parameter and the update_status() operation is called.
*
* When the backlight device is enabled @fb_blank is set
* to FB_BLANK_UNBLANK. When the backlight device is disabled
* @fb_blank is set to FB_BLANK_POWERDOWN.
*
* Backlight drivers should avoid using this property. It has been
* replaced by state & BL_CORE_FBLANK (although most drivers should
* use backlight_is_blank() as the preferred means to get the blank
* state).
*
* fb_blank is deprecated and will be removed.
*/
int fb_blank; int fb_blank;
/* Backlight type */
/**
* @type: The type of backlight supported.
*
* The backlight type allows userspace to make appropriate
* policy decisions based on the backlight type.
*
* This value must be set in the backlight_properties
* passed to devm_backlight_device_register().
*/
enum backlight_type type; enum backlight_type type;
/* Flags used to signal drivers of state changes */
/**
* @state: The state of the backlight core.
*
* The state is a bitmask. BL_CORE_FBBLANK is set when the display
* is expected to be blank. BL_CORE_SUSPENDED is set when the
* driver is suspended.
*
* backlight drivers are expected to use backlight_is_blank()
* in their update_status() operation rather than reading the
* state property.
*
* The state is maintained by the core and drivers may not modify it.
*/
unsigned int state; unsigned int state;
/* Type of the brightness scale (linear, non-linear, ...) */
enum backlight_scale scale;
#define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */ #define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */
#define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */ #define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */
/**
* @scale: The type of the brightness scale.
*/
enum backlight_scale scale;
}; };
/**
* struct backlight_device - backlight device data
*
* This structure holds all data required by a backlight device.
*/
struct backlight_device { struct backlight_device {
/* Backlight properties */ /**
* @props: Backlight properties
*/
struct backlight_properties props; struct backlight_properties props;
/* Serialise access to update_status method */ /**
* @update_lock: The lock used when calling the update_status() operation.
*
* update_lock is an internal backlight lock that serialise access
* to the update_status() operation. The backlight core holds the update_lock
* when calling the update_status() operation. The update_lock shall not
* be used by backlight drivers.
*/
struct mutex update_lock; struct mutex update_lock;
/* This protects the 'ops' field. If 'ops' is NULL, the driver that /**
registered this device has been unloaded, and if class_get_devdata() * @ops_lock: The lock used around everything related to backlight_ops.
points to something in the body of that driver, it is also invalid. */ *
* ops_lock is an internal backlight lock that protects the ops pointer
* and is used around all accesses to ops and when the operations are
* invoked. The ops_lock shall not be used by backlight drivers.
*/
struct mutex ops_lock; struct mutex ops_lock;
/**
* @ops: Pointer to the backlight operations.
*
* If ops is NULL, the driver that registered this device has been unloaded,
* and if class_get_devdata() points to something in the body of that driver,
* it is also invalid.
*/
const struct backlight_ops *ops; const struct backlight_ops *ops;
/* The framebuffer notifier block */ /**
* @fb_notif: The framebuffer notifier block
*/
struct notifier_block fb_notif; struct notifier_block fb_notif;
/* list entry of all registered backlight devices */ /**
* @entry: List entry of all registered backlight devices
*/
struct list_head entry; struct list_head entry;
/**
* @dev: Parent device.
*/
struct device dev; struct device dev;
/* Multiple framebuffers may share one backlight device */ /**
* @fb_bl_on: The state of individual fbdev's.
*
* Multiple fbdev's may share one backlight device. The fb_bl_on
* records the state of the individual fbdev.
*/
bool fb_bl_on[FB_MAX]; bool fb_bl_on[FB_MAX];
/**
* @use_count: The number of uses of fb_bl_on.
*/
int use_count; int use_count;
}; };
/**
* backlight_update_status - force an update of the backlight device status
* @bd: the backlight device
*/
static inline int backlight_update_status(struct backlight_device *bd) static inline int backlight_update_status(struct backlight_device *bd)
{ {
int ret = -ENOENT; int ret = -ENOENT;
...@@ -166,49 +389,83 @@ static inline int backlight_disable(struct backlight_device *bd) ...@@ -166,49 +389,83 @@ static inline int backlight_disable(struct backlight_device *bd)
} }
/** /**
* backlight_put - Drop backlight reference * backlight_is_blank - Return true if display is expected to be blank
* @bd: the backlight device to put * @bd: the backlight device
*
* Display is expected to be blank if any of these is true::
*
* 1) if power in not UNBLANK
* 2) if fb_blank is not UNBLANK
* 3) if state indicate BLANK or SUSPENDED
*
* Returns true if display is expected to be blank, false otherwise.
*/ */
static inline void backlight_put(struct backlight_device *bd) static inline bool backlight_is_blank(const struct backlight_device *bd)
{ {
if (bd) return bd->props.power != FB_BLANK_UNBLANK ||
put_device(&bd->dev); bd->props.fb_blank != FB_BLANK_UNBLANK ||
bd->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK);
} }
extern struct backlight_device *backlight_device_register(const char *name, /**
struct device *dev, void *devdata, const struct backlight_ops *ops, * backlight_get_brightness - Returns the current brightness value
const struct backlight_properties *props); * @bd: the backlight device
extern struct backlight_device *devm_backlight_device_register( *
struct device *dev, const char *name, struct device *parent, * Returns the current brightness value, taking in consideration the current
void *devdata, const struct backlight_ops *ops, * state. If backlight_is_blank() returns true then return 0 as brightness
const struct backlight_properties *props); * otherwise return the current brightness property value.
extern void backlight_device_unregister(struct backlight_device *bd); *
extern void devm_backlight_device_unregister(struct device *dev, * Backlight drivers are expected to use this function in their update_status()
struct backlight_device *bd); * operation to get the brightness value.
extern void backlight_force_update(struct backlight_device *bd, */
enum backlight_update_reason reason); static inline int backlight_get_brightness(const struct backlight_device *bd)
extern int backlight_register_notifier(struct notifier_block *nb); {
extern int backlight_unregister_notifier(struct notifier_block *nb); if (backlight_is_blank(bd))
extern struct backlight_device *backlight_device_get_by_type(enum backlight_type type); return 0;
else
return bd->props.brightness;
}
struct backlight_device *
backlight_device_register(const char *name, struct device *dev, void *devdata,
const struct backlight_ops *ops,
const struct backlight_properties *props);
struct backlight_device *
devm_backlight_device_register(struct device *dev, const char *name,
struct device *parent, void *devdata,
const struct backlight_ops *ops,
const struct backlight_properties *props);
void backlight_device_unregister(struct backlight_device *bd);
void devm_backlight_device_unregister(struct device *dev,
struct backlight_device *bd);
void backlight_force_update(struct backlight_device *bd,
enum backlight_update_reason reason);
int backlight_register_notifier(struct notifier_block *nb);
int backlight_unregister_notifier(struct notifier_block *nb);
struct backlight_device *backlight_device_get_by_name(const char *name); struct backlight_device *backlight_device_get_by_name(const char *name);
extern int backlight_device_set_brightness(struct backlight_device *bd, unsigned long brightness); struct backlight_device *backlight_device_get_by_type(enum backlight_type type);
int backlight_device_set_brightness(struct backlight_device *bd,
unsigned long brightness);
#define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev)
/**
* bl_get_data - access devdata
* @bl_dev: pointer to backlight device
*
* When a backlight device is registered the driver has the possibility
* to supply a void * devdata. bl_get_data() return a pointer to the
* devdata.
*
* RETURNS:
*
* pointer to devdata stored while registering the backlight device.
*/
static inline void * bl_get_data(struct backlight_device *bl_dev) static inline void * bl_get_data(struct backlight_device *bl_dev)
{ {
return dev_get_drvdata(&bl_dev->dev); return dev_get_drvdata(&bl_dev->dev);
} }
struct generic_bl_info {
const char *name;
int max_intensity;
int default_intensity;
int limit_mask;
void (*set_bl_intensity)(int intensity);
void (*kick_battery)(void);
};
#ifdef CONFIG_OF #ifdef CONFIG_OF
struct backlight_device *of_find_backlight_by_node(struct device_node *node); struct backlight_device *of_find_backlight_by_node(struct device_node *node);
#else #else
...@@ -220,14 +477,8 @@ of_find_backlight_by_node(struct device_node *node) ...@@ -220,14 +477,8 @@ of_find_backlight_by_node(struct device_node *node)
#endif #endif
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
struct backlight_device *of_find_backlight(struct device *dev);
struct backlight_device *devm_of_find_backlight(struct device *dev); struct backlight_device *devm_of_find_backlight(struct device *dev);
#else #else
static inline struct backlight_device *of_find_backlight(struct device *dev)
{
return NULL;
}
static inline struct backlight_device * static inline struct backlight_device *
devm_of_find_backlight(struct device *dev) devm_of_find_backlight(struct device *dev)
{ {
......
...@@ -9,11 +9,9 @@ ...@@ -9,11 +9,9 @@
#ifndef _SKY81452_H #ifndef _SKY81452_H
#define _SKY81452_H #define _SKY81452_H
#include <linux/platform_data/sky81452-backlight.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
struct sky81452_platform_data { struct sky81452_platform_data {
struct sky81452_bl_platform_data *bl_pdata;
struct regulator_init_data *regulator_init_data; struct regulator_init_data *regulator_init_data;
}; };
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* sky81452.h SKY81452 backlight driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.com>
*/
#ifndef _SKY81452_BACKLIGHT_H
#define _SKY81452_BACKLIGHT_H
/**
* struct sky81452_platform_data
* @name: backlight driver name.
If it is not defined, default name is lcd-backlight.
* @gpio_enable:GPIO number which control EN pin
* @enable: Enable mask for current sink channel 1, 2, 3, 4, 5 and 6.
* @ignore_pwm: true if DPWMI should be ignored.
* @dpwm_mode: true is DPWM dimming mode, otherwise Analog dimming mode.
* @phase_shift:true is phase shift mode.
* @short_detecion_threshold: It should be one of 4, 5, 6 and 7V.
* @boost_current_limit: It should be one of 2300, 2750mA.
*/
struct sky81452_bl_platform_data {
const char *name;
int gpio_enable;
unsigned int enable;
bool ignore_pwm;
bool dpwm_mode;
bool phase_shift;
unsigned int short_detection_threshold;
unsigned int boost_current_limit;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment