0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/fb.h>
0010 #include <linux/kernel.h>
0011 #include <linux/lcd.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/delay.h>
0015
0016 #include <mach/jornada720.h>
0017 #include <mach/hardware.h>
0018
0019 #include <video/s1d13xxxfb.h>
0020
0021 #define LCD_MAX_CONTRAST 0xff
0022 #define LCD_DEF_CONTRAST 0x80
0023
0024 static int jornada_lcd_get_power(struct lcd_device *ld)
0025 {
0026 return PPSR & PPC_LDD2 ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
0027 }
0028
0029 static int jornada_lcd_get_contrast(struct lcd_device *ld)
0030 {
0031 int ret;
0032
0033 if (jornada_lcd_get_power(ld) != FB_BLANK_UNBLANK)
0034 return 0;
0035
0036 jornada_ssp_start();
0037
0038 if (jornada_ssp_byte(GETCONTRAST) == TXDUMMY) {
0039 ret = jornada_ssp_byte(TXDUMMY);
0040 goto success;
0041 }
0042
0043 dev_err(&ld->dev, "failed to set contrast\n");
0044 ret = -ETIMEDOUT;
0045
0046 success:
0047 jornada_ssp_end();
0048 return ret;
0049 }
0050
0051 static int jornada_lcd_set_contrast(struct lcd_device *ld, int value)
0052 {
0053 int ret = 0;
0054
0055 jornada_ssp_start();
0056
0057
0058 if (jornada_ssp_byte(SETCONTRAST) == TXDUMMY) {
0059
0060 if (jornada_ssp_byte(value) == TXDUMMY)
0061 goto success;
0062 }
0063
0064 dev_err(&ld->dev, "failed to set contrast\n");
0065 ret = -ETIMEDOUT;
0066
0067 success:
0068 jornada_ssp_end();
0069 return ret;
0070 }
0071
0072 static int jornada_lcd_set_power(struct lcd_device *ld, int power)
0073 {
0074 if (power != FB_BLANK_UNBLANK) {
0075 PPSR &= ~PPC_LDD2;
0076 PPDR |= PPC_LDD2;
0077 } else {
0078 PPSR |= PPC_LDD2;
0079 }
0080
0081 return 0;
0082 }
0083
0084 static struct lcd_ops jornada_lcd_props = {
0085 .get_contrast = jornada_lcd_get_contrast,
0086 .set_contrast = jornada_lcd_set_contrast,
0087 .get_power = jornada_lcd_get_power,
0088 .set_power = jornada_lcd_set_power,
0089 };
0090
0091 static int jornada_lcd_probe(struct platform_device *pdev)
0092 {
0093 struct lcd_device *lcd_device;
0094 int ret;
0095
0096 lcd_device = devm_lcd_device_register(&pdev->dev, S1D_DEVICENAME,
0097 &pdev->dev, NULL, &jornada_lcd_props);
0098
0099 if (IS_ERR(lcd_device)) {
0100 ret = PTR_ERR(lcd_device);
0101 dev_err(&pdev->dev, "failed to register device\n");
0102 return ret;
0103 }
0104
0105 platform_set_drvdata(pdev, lcd_device);
0106
0107
0108 jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST);
0109 jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
0110
0111 msleep(100);
0112
0113 return 0;
0114 }
0115
0116 static struct platform_driver jornada_lcd_driver = {
0117 .probe = jornada_lcd_probe,
0118 .driver = {
0119 .name = "jornada_lcd",
0120 },
0121 };
0122
0123 module_platform_driver(jornada_lcd_driver);
0124
0125 MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
0126 MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
0127 MODULE_LICENSE("GPL");