diff options
Diffstat (limited to 'drivers/video/backlight/jornada720_bl.c')
-rw-r--r-- | drivers/video/backlight/jornada720_bl.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c new file mode 100644 index 000000000..066d0dc98 --- /dev/null +++ b/drivers/video/backlight/jornada720_bl.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * + * Backlight driver for HP Jornada 700 series (710/720/728) + * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> + */ + +#include <linux/backlight.h> +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <mach/jornada720.h> +#include <mach/hardware.h> + +#include <video/s1d13xxxfb.h> + +#define BL_MAX_BRIGHT 255 +#define BL_DEF_BRIGHT 25 + +static int jornada_bl_get_brightness(struct backlight_device *bd) +{ + int ret; + + /* check if backlight is on */ + if (!(PPSR & PPC_LDD1)) + return 0; + + jornada_ssp_start(); + + /* cmd should return txdummy */ + ret = jornada_ssp_byte(GETBRIGHTNESS); + + if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) { + dev_err(&bd->dev, "get brightness timeout\n"); + jornada_ssp_end(); + return -ETIMEDOUT; + } + + /* exchange txdummy for value */ + ret = jornada_ssp_byte(TXDUMMY); + + jornada_ssp_end(); + + return BL_MAX_BRIGHT - ret; +} + +static int jornada_bl_update_status(struct backlight_device *bd) +{ + int ret = 0; + + jornada_ssp_start(); + + /* If backlight is off then really turn it off */ + if (backlight_is_blank(bd)) { + ret = jornada_ssp_byte(BRIGHTNESSOFF); + if (ret != TXDUMMY) { + dev_info(&bd->dev, "brightness off timeout\n"); + /* turn off backlight */ + PPSR &= ~PPC_LDD1; + PPDR |= PPC_LDD1; + ret = -ETIMEDOUT; + } + } else /* turn on backlight */ + PPSR |= PPC_LDD1; + + /* send command to our mcu */ + if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { + dev_info(&bd->dev, "failed to set brightness\n"); + ret = -ETIMEDOUT; + goto out; + } + + /* + * at this point we expect that the mcu has accepted + * our command and is waiting for our new value + * please note that maximum brightness is 255, + * but due to physical layout it is equal to 0, so we simply + * invert the value (MAX VALUE - NEW VALUE). + */ + if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) + != TXDUMMY) { + dev_err(&bd->dev, "set brightness failed\n"); + ret = -ETIMEDOUT; + } + + /* + * If infact we get an TXDUMMY as output we are happy and dont + * make any further comments about it + */ +out: + jornada_ssp_end(); + + return ret; +} + +static const struct backlight_ops jornada_bl_ops = { + .get_brightness = jornada_bl_get_brightness, + .update_status = jornada_bl_update_status, + .options = BL_CORE_SUSPENDRESUME, +}; + +static int jornada_bl_probe(struct platform_device *pdev) +{ + struct backlight_properties props; + int ret; + struct backlight_device *bd; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_RAW; + props.max_brightness = BL_MAX_BRIGHT; + + bd = devm_backlight_device_register(&pdev->dev, S1D_DEVICENAME, + &pdev->dev, NULL, &jornada_bl_ops, + &props); + if (IS_ERR(bd)) { + ret = PTR_ERR(bd); + dev_err(&pdev->dev, "failed to register device, err=%x\n", ret); + return ret; + } + + bd->props.power = FB_BLANK_UNBLANK; + bd->props.brightness = BL_DEF_BRIGHT; + /* + * note. make sure max brightness is set otherwise + * you will get seemingly non-related errors when + * trying to change brightness + */ + jornada_bl_update_status(bd); + + platform_set_drvdata(pdev, bd); + dev_info(&pdev->dev, "HP Jornada 700 series backlight driver\n"); + + return 0; +} + +static struct platform_driver jornada_bl_driver = { + .probe = jornada_bl_probe, + .driver = { + .name = "jornada_bl", + }, +}; + +module_platform_driver(jornada_bl_driver); + +MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>"); +MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver"); +MODULE_LICENSE("GPL"); |