150 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *4 * Backlight driver for HP Jornada 700 series (710/720/728)5 * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>6 */7 8#include <linux/backlight.h>9#include <linux/device.h>10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/platform_device.h>13 14#include <mach/jornada720.h>15#include <mach/hardware.h>16 17#include <video/s1d13xxxfb.h>18 19#define BL_MAX_BRIGHT 25520#define BL_DEF_BRIGHT 2521 22static int jornada_bl_get_brightness(struct backlight_device *bd)23{24 int ret;25 26 /* check if backlight is on */27 if (!(PPSR & PPC_LDD1))28 return 0;29 30 jornada_ssp_start();31 32 /* cmd should return txdummy */33 ret = jornada_ssp_byte(GETBRIGHTNESS);34 35 if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {36 dev_err(&bd->dev, "get brightness timeout\n");37 jornada_ssp_end();38 return -ETIMEDOUT;39 }40 41 /* exchange txdummy for value */42 ret = jornada_ssp_byte(TXDUMMY);43 44 jornada_ssp_end();45 46 return BL_MAX_BRIGHT - ret;47}48 49static int jornada_bl_update_status(struct backlight_device *bd)50{51 int ret = 0;52 53 jornada_ssp_start();54 55 /* If backlight is off then really turn it off */56 if (backlight_is_blank(bd)) {57 ret = jornada_ssp_byte(BRIGHTNESSOFF);58 if (ret != TXDUMMY) {59 dev_info(&bd->dev, "brightness off timeout\n");60 /* turn off backlight */61 PPSR &= ~PPC_LDD1;62 PPDR |= PPC_LDD1;63 ret = -ETIMEDOUT;64 }65 } else /* turn on backlight */66 PPSR |= PPC_LDD1;67 68 /* send command to our mcu */69 if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {70 dev_info(&bd->dev, "failed to set brightness\n");71 ret = -ETIMEDOUT;72 goto out;73 }74 75 /*76 * at this point we expect that the mcu has accepted77 * our command and is waiting for our new value78 * please note that maximum brightness is 255,79 * but due to physical layout it is equal to 0, so we simply80 * invert the value (MAX VALUE - NEW VALUE).81 */82 if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness)83 != TXDUMMY) {84 dev_err(&bd->dev, "set brightness failed\n");85 ret = -ETIMEDOUT;86 }87 88 /*89 * If infact we get an TXDUMMY as output we are happy and dont90 * make any further comments about it91 */92out:93 jornada_ssp_end();94 95 return ret;96}97 98static const struct backlight_ops jornada_bl_ops = {99 .get_brightness = jornada_bl_get_brightness,100 .update_status = jornada_bl_update_status,101 .options = BL_CORE_SUSPENDRESUME,102};103 104static int jornada_bl_probe(struct platform_device *pdev)105{106 struct backlight_properties props;107 int ret;108 struct backlight_device *bd;109 110 memset(&props, 0, sizeof(struct backlight_properties));111 props.type = BACKLIGHT_RAW;112 props.max_brightness = BL_MAX_BRIGHT;113 114 bd = devm_backlight_device_register(&pdev->dev, S1D_DEVICENAME,115 &pdev->dev, NULL, &jornada_bl_ops,116 &props);117 if (IS_ERR(bd)) {118 ret = PTR_ERR(bd);119 dev_err(&pdev->dev, "failed to register device, err=%x\n", ret);120 return ret;121 }122 123 bd->props.power = BACKLIGHT_POWER_ON;124 bd->props.brightness = BL_DEF_BRIGHT;125 /*126 * note. make sure max brightness is set otherwise127 * you will get seemingly non-related errors when128 * trying to change brightness129 */130 jornada_bl_update_status(bd);131 132 platform_set_drvdata(pdev, bd);133 dev_info(&pdev->dev, "HP Jornada 700 series backlight driver\n");134 135 return 0;136}137 138static struct platform_driver jornada_bl_driver = {139 .probe = jornada_bl_probe,140 .driver = {141 .name = "jornada_bl",142 },143};144 145module_platform_driver(jornada_bl_driver);146 147MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");148MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");149MODULE_LICENSE("GPL");150