Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /*
*
* LCD driver for HP Jornada 700 series (710/720/728)
* Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 or any later version as published by the Free Software Foundation.
*
*/
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <linux/lcd.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <mach/jornada720.h>
#include <mach/hardware.h>
#include <video/s1d13xxxfb.h>
#define LCD_MAX_CONTRAST 0xff
#define LCD_DEF_CONTRAST 0x80
static int jornada_lcd_get_power(struct lcd_device *dev)
{
/* LDD2 in PPC = LCD POWER */
if (PPSR & PPC_LDD2)
return FB_BLANK_UNBLANK; /* PW ON */
else
return FB_BLANK_POWERDOWN; /* PW OFF */
}
static int jornada_lcd_get_contrast(struct lcd_device *dev)
{
int ret;
if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK)
return 0;
jornada_ssp_start();
if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) {
printk(KERN_ERR "lcd: get contrast failed\n");
jornada_ssp_end();
return -ETIMEDOUT;
} else {
ret = jornada_ssp_byte(TXDUMMY);
jornada_ssp_end();
return ret;
}
}
static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
{
int ret;
jornada_ssp_start();
/* start by sending our set contrast cmd to mcu */
ret = jornada_ssp_byte(SETCONTRAST);
/* push the new value */
if (jornada_ssp_byte(value) != TXDUMMY) {
printk(KERN_ERR "lcd : set contrast failed\n");
jornada_ssp_end();
return -ETIMEDOUT;
}
/* if we get here we can assume everything went well */
jornada_ssp_end();
return 0;
}
static int jornada_lcd_set_power(struct lcd_device *dev, int power)
{
if (power != FB_BLANK_UNBLANK) {
PPSR &= ~PPC_LDD2;
PPDR |= PPC_LDD2;
} else
PPSR |= PPC_LDD2;
return 0;
}
static struct lcd_ops jornada_lcd_props = {
.get_contrast = jornada_lcd_get_contrast,
.set_contrast = jornada_lcd_set_contrast,
.get_power = jornada_lcd_get_power,
.set_power = jornada_lcd_set_power,
};
static int jornada_lcd_probe(struct platform_device *pdev)
{
struct lcd_device *lcd_device;
int ret;
lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props);
if (IS_ERR(lcd_device)) {
ret = PTR_ERR(lcd_device);
printk(KERN_ERR "lcd : failed to register device\n");
return ret;
}
platform_set_drvdata(pdev, lcd_device);
/* lets set our default values */
jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST);
jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
/* give it some time to startup */
msleep(100);
return 0;
}
static int jornada_lcd_remove(struct platform_device *pdev)
{
struct lcd_device *lcd_device = platform_get_drvdata(pdev);
lcd_device_unregister(lcd_device);
return 0;
}
static struct platform_driver jornada_lcd_driver = {
.probe = jornada_lcd_probe,
.remove = jornada_lcd_remove,
.driver = {
.name = "jornada_lcd",
},
};
module_platform_driver(jornada_lcd_driver);
MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
MODULE_LICENSE("GPL");
|