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