Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight: backlight: Convert corgi backlight driver into a more generic driver backlight: Add Samsung LTV350QV LCD driver backlight: Fix cr_bllcd allocations and error paths backlight/leds: Make two structs static
This commit is contained in:
commit
6f35308c3f
@ -20,6 +20,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/backlight.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/memory.h>
|
||||
@ -142,15 +143,28 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
|
||||
/*
|
||||
* Corgi Backlight Device
|
||||
*/
|
||||
static struct corgibl_machinfo corgi_bl_machinfo = {
|
||||
static void corgi_bl_kick_battery(void)
|
||||
{
|
||||
void (*kick_batt)(void);
|
||||
|
||||
kick_batt = symbol_get(sharpsl_battery_kick);
|
||||
if (kick_batt) {
|
||||
kick_batt();
|
||||
symbol_put(sharpsl_battery_kick);
|
||||
}
|
||||
}
|
||||
|
||||
static struct generic_bl_info corgi_bl_machinfo = {
|
||||
.name = "corgi-bl",
|
||||
.max_intensity = 0x2f,
|
||||
.default_intensity = 0x1f,
|
||||
.limit_mask = 0x0b,
|
||||
.set_bl_intensity = corgi_bl_set_intensity,
|
||||
.kick_battery = corgi_bl_kick_battery,
|
||||
};
|
||||
|
||||
static struct platform_device corgibl_device = {
|
||||
.name = "corgi-bl",
|
||||
.name = "generic-bl",
|
||||
.dev = {
|
||||
.parent = &corgifb_device.dev,
|
||||
.platform_data = &corgi_bl_machinfo,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/backlight.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/memory.h>
|
||||
@ -222,14 +223,27 @@ struct corgissp_machinfo spitz_ssp_machinfo = {
|
||||
/*
|
||||
* Spitz Backlight Device
|
||||
*/
|
||||
static struct corgibl_machinfo spitz_bl_machinfo = {
|
||||
static void spitz_bl_kick_battery(void)
|
||||
{
|
||||
void (*kick_batt)(void);
|
||||
|
||||
kick_batt = symbol_get(sharpsl_battery_kick);
|
||||
if (kick_batt) {
|
||||
kick_batt();
|
||||
symbol_put(sharpsl_battery_kick);
|
||||
}
|
||||
}
|
||||
|
||||
static struct generic_bl_info spitz_bl_machinfo = {
|
||||
.name = "corgi-bl",
|
||||
.default_intensity = 0x1f,
|
||||
.limit_mask = 0x0b,
|
||||
.max_intensity = 0x2f,
|
||||
.kick_battery = spitz_bl_kick_battery,
|
||||
};
|
||||
|
||||
static struct platform_device spitzbl_device = {
|
||||
.name = "corgi-bl",
|
||||
.name = "generic-bl",
|
||||
.dev = {
|
||||
.platform_data = &spitz_bl_machinfo,
|
||||
},
|
||||
|
@ -24,6 +24,18 @@ config LCD_CLASS_DEVICE
|
||||
To have support for your specific LCD panel you will have to
|
||||
select the proper drivers which depend on this option.
|
||||
|
||||
config LCD_LTV350QV
|
||||
tristate "Samsung LTV350QV LCD Panel"
|
||||
depends on LCD_CLASS_DEVICE && SPI_MASTER
|
||||
default n
|
||||
help
|
||||
If you have a Samsung LTV350QV LCD panel, say y to include a
|
||||
power control driver for it. The panel starts up in power
|
||||
off state, so you need this driver in order to see any
|
||||
output.
|
||||
|
||||
The LTV350QV panel is present on all ATSTK1000 boards.
|
||||
|
||||
#
|
||||
# Backlight
|
||||
#
|
||||
@ -39,12 +51,13 @@ config BACKLIGHT_CLASS_DEVICE
|
||||
select the proper drivers which depend on this option.
|
||||
|
||||
config BACKLIGHT_CORGI
|
||||
tristate "Sharp Corgi Backlight Driver (SL Series)"
|
||||
depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL
|
||||
default y
|
||||
tristate "Generic (aka Sharp Corgi) Backlight Driver"
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
default n
|
||||
help
|
||||
If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
|
||||
backlight driver.
|
||||
Say y to enable the generic platform backlight driver previously
|
||||
known as the Corgi backlight driver. If you have a Sharp Zaurus
|
||||
SL-C7xx, SL-Cxx00 or SL-6000x say y. Most users can say n.
|
||||
|
||||
config BACKLIGHT_LOCOMO
|
||||
tristate "Sharp LOCOMO LCD/Backlight Driver"
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Backlight & LCD drivers
|
||||
|
||||
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
|
||||
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
|
||||
|
||||
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
|
||||
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
|
||||
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
|
||||
|
@ -164,7 +164,7 @@ static ssize_t backlight_show_actual_brightness(struct device *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct class *backlight_class;
|
||||
static struct class *backlight_class;
|
||||
|
||||
static void bl_device_release(struct device *dev)
|
||||
{
|
||||
|
@ -18,13 +18,11 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <asm/arch/sharpsl.h>
|
||||
#include <asm/hardware/sharpsl_pm.h>
|
||||
|
||||
static int corgibl_intensity;
|
||||
static struct backlight_properties corgibl_data;
|
||||
static struct backlight_device *corgi_backlight_device;
|
||||
static struct corgibl_machinfo *bl_machinfo;
|
||||
static struct generic_bl_info *bl_machinfo;
|
||||
|
||||
static unsigned long corgibl_flags;
|
||||
#define CORGIBL_SUSPENDED 0x01
|
||||
@ -32,7 +30,6 @@ static unsigned long corgibl_flags;
|
||||
|
||||
static int corgibl_send_intensity(struct backlight_device *bd)
|
||||
{
|
||||
void (*corgi_kick_batt)(void);
|
||||
int intensity = bd->props.brightness;
|
||||
|
||||
if (bd->props.power != FB_BLANK_UNBLANK)
|
||||
@ -48,11 +45,8 @@ static int corgibl_send_intensity(struct backlight_device *bd)
|
||||
|
||||
corgibl_intensity = intensity;
|
||||
|
||||
corgi_kick_batt = symbol_get(sharpsl_battery_kick);
|
||||
if (corgi_kick_batt) {
|
||||
corgi_kick_batt();
|
||||
symbol_put(sharpsl_battery_kick);
|
||||
}
|
||||
if (bl_machinfo->kick_battery)
|
||||
bl_machinfo->kick_battery();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -107,13 +101,17 @@ static struct backlight_ops corgibl_ops = {
|
||||
|
||||
static int corgibl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
|
||||
struct generic_bl_info *machinfo = pdev->dev.platform_data;
|
||||
const char *name = "generic-bl";
|
||||
|
||||
bl_machinfo = machinfo;
|
||||
if (!machinfo->limit_mask)
|
||||
machinfo->limit_mask = -1;
|
||||
|
||||
corgi_backlight_device = backlight_device_register ("corgi-bl",
|
||||
if (machinfo->name)
|
||||
name = machinfo->name;
|
||||
|
||||
corgi_backlight_device = backlight_device_register (name,
|
||||
&pdev->dev, NULL, &corgibl_ops);
|
||||
if (IS_ERR (corgi_backlight_device))
|
||||
return PTR_ERR (corgi_backlight_device);
|
||||
@ -149,7 +147,7 @@ static struct platform_driver corgibl_driver = {
|
||||
.suspend = corgibl_suspend,
|
||||
.resume = corgibl_resume,
|
||||
.driver = {
|
||||
.name = "corgi-bl",
|
||||
.name = "generic-bl",
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -171,13 +171,11 @@ static struct lcd_ops cr_lcd_ops = {
|
||||
|
||||
static int cr_backlight_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct backlight_device *bdp;
|
||||
struct lcd_device *ldp;
|
||||
struct cr_panel *crp;
|
||||
u8 dev_en;
|
||||
|
||||
crp = kzalloc(sizeof(*crp), GFP_KERNEL);
|
||||
if (crp == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
CRVML_DEVICE_LPC, NULL);
|
||||
if (!lpc_dev) {
|
||||
@ -193,27 +191,34 @@ static int cr_backlight_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
crp->cr_backlight_device = backlight_device_register("cr-backlight",
|
||||
&pdev->dev, NULL,
|
||||
&cr_backlight_ops);
|
||||
if (IS_ERR(crp->cr_backlight_device)) {
|
||||
bdp = backlight_device_register("cr-backlight",
|
||||
&pdev->dev, NULL, &cr_backlight_ops);
|
||||
if (IS_ERR(bdp)) {
|
||||
pci_dev_put(lpc_dev);
|
||||
return PTR_ERR(crp->cr_backlight_device);
|
||||
return PTR_ERR(bdp);
|
||||
}
|
||||
|
||||
crp->cr_lcd_device = lcd_device_register("cr-lcd",
|
||||
&pdev->dev, NULL,
|
||||
&cr_lcd_ops);
|
||||
|
||||
if (IS_ERR(crp->cr_lcd_device)) {
|
||||
ldp = lcd_device_register("cr-lcd", &pdev->dev, NULL, &cr_lcd_ops);
|
||||
if (IS_ERR(ldp)) {
|
||||
backlight_device_unregister(bdp);
|
||||
pci_dev_put(lpc_dev);
|
||||
return PTR_ERR(crp->cr_backlight_device);
|
||||
return PTR_ERR(bdp);
|
||||
}
|
||||
|
||||
pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
|
||||
&gpio_bar);
|
||||
gpio_bar &= ~0x3F;
|
||||
|
||||
crp = kzalloc(sizeof(*crp), GFP_KERNEL);
|
||||
if (!crp) {
|
||||
lcd_device_unregister(ldp);
|
||||
backlight_device_unregister(bdp);
|
||||
pci_dev_put(lpc_dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
crp->cr_backlight_device = bdp;
|
||||
crp->cr_lcd_device = ldp;
|
||||
crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
|
||||
crp->cr_backlight_device->props.brightness = 0;
|
||||
crp->cr_backlight_device->props.max_brightness = 0;
|
||||
|
@ -149,7 +149,7 @@ static ssize_t lcd_show_max_contrast(struct device *dev,
|
||||
return sprintf(buf, "%d\n", ld->props.max_contrast);
|
||||
}
|
||||
|
||||
struct class *lcd_class;
|
||||
static struct class *lcd_class;
|
||||
|
||||
static void lcd_device_release(struct device *dev)
|
||||
{
|
||||
|
330
drivers/video/backlight/ltv350qv.c
Normal file
330
drivers/video/backlight/ltv350qv.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Power control for Samsung LTV350QV Quarter VGA LCD Panel
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/lcd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "ltv350qv.h"
|
||||
|
||||
#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
|
||||
|
||||
struct ltv350qv {
|
||||
struct spi_device *spi;
|
||||
u8 *buffer;
|
||||
int power;
|
||||
struct lcd_device *ld;
|
||||
};
|
||||
|
||||
/*
|
||||
* The power-on and power-off sequences are taken from the
|
||||
* LTV350QV-F04 data sheet from Samsung. The register definitions are
|
||||
* taken from the S6F2002 command list also from Samsung. Both
|
||||
* documents are distributed with the AVR32 Linux BSP CD from Atmel.
|
||||
*
|
||||
* There's still some voodoo going on here, but it's a lot better than
|
||||
* in the first incarnation of the driver where all we had was the raw
|
||||
* numbers from the initialization sequence.
|
||||
*/
|
||||
static int ltv350qv_write_reg(struct ltv350qv *lcd, u8 reg, u16 val)
|
||||
{
|
||||
struct spi_message msg;
|
||||
struct spi_transfer index_xfer = {
|
||||
.len = 3,
|
||||
.cs_change = 1,
|
||||
};
|
||||
struct spi_transfer value_xfer = {
|
||||
.len = 3,
|
||||
};
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
/* register index */
|
||||
lcd->buffer[0] = LTV_OPC_INDEX;
|
||||
lcd->buffer[1] = 0x00;
|
||||
lcd->buffer[2] = reg & 0x7f;
|
||||
index_xfer.tx_buf = lcd->buffer;
|
||||
spi_message_add_tail(&index_xfer, &msg);
|
||||
|
||||
/* register value */
|
||||
lcd->buffer[4] = LTV_OPC_DATA;
|
||||
lcd->buffer[5] = val >> 8;
|
||||
lcd->buffer[6] = val;
|
||||
value_xfer.tx_buf = lcd->buffer + 4;
|
||||
spi_message_add_tail(&value_xfer, &msg);
|
||||
|
||||
return spi_sync(lcd->spi, &msg);
|
||||
}
|
||||
|
||||
/* The comments are taken straight from the data sheet */
|
||||
static int ltv350qv_power_on(struct ltv350qv *lcd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Power On Reset Display off State */
|
||||
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000))
|
||||
goto err;
|
||||
msleep(15);
|
||||
|
||||
/* Power Setting Function 1 */
|
||||
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE))
|
||||
goto err;
|
||||
if (ltv350qv_write_reg(lcd, LTV_PWRCTL2, LTV_VCOML_ENABLE))
|
||||
goto err_power1;
|
||||
|
||||
/* Power Setting Function 2 */
|
||||
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1,
|
||||
LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
|
||||
| LTV_SUPPLY_CURRENT(5)))
|
||||
goto err_power2;
|
||||
|
||||
msleep(55);
|
||||
|
||||
/* Instruction Setting */
|
||||
ret = ltv350qv_write_reg(lcd, LTV_IFCTL,
|
||||
LTV_NMD | LTV_REV | LTV_NL(0x1d));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_DATACTL,
|
||||
LTV_DS_SAME | LTV_CHS_480
|
||||
| LTV_DF_RGB | LTV_RGB_BGR);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_ENTRY_MODE,
|
||||
LTV_VSPL_ACTIVE_LOW
|
||||
| LTV_HSPL_ACTIVE_LOW
|
||||
| LTV_DPL_SAMPLE_RISING
|
||||
| LTV_EPL_ACTIVE_LOW
|
||||
| LTV_SS_RIGHT_TO_LEFT);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL1, LTV_CLW(3));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
|
||||
LTV_NW_INV_1LINE | LTV_FWI(3));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_VBP, 0x000a);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_HBP, 0x0021);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_SOTCTL, LTV_SDT(3) | LTV_EQ(0));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(0), 0x0103);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(1), 0x0301);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(2), 0x1f0f);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(3), 0x1f0f);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(4), 0x0707);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(5), 0x0307);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(6), 0x0707);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(7), 0x0000);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(8), 0x0004);
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(9), 0x0000);
|
||||
if (ret)
|
||||
goto err_settings;
|
||||
|
||||
/* Wait more than 2 frames */
|
||||
msleep(20);
|
||||
|
||||
/* Display On Sequence */
|
||||
ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
|
||||
LTV_VCOM_DISABLE | LTV_VCOMOUT_ENABLE
|
||||
| LTV_POWER_ON | LTV_DRIVE_CURRENT(5)
|
||||
| LTV_SUPPLY_CURRENT(5));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
|
||||
LTV_NW_INV_1LINE | LTV_DSC | LTV_FWI(3));
|
||||
if (ret)
|
||||
goto err_disp_on;
|
||||
|
||||
/* Display should now be ON. Phew. */
|
||||
return 0;
|
||||
|
||||
err_disp_on:
|
||||
/*
|
||||
* Try to recover. Error handling probably isn't very useful
|
||||
* at this point, just make a best effort to switch the panel
|
||||
* off.
|
||||
*/
|
||||
ltv350qv_write_reg(lcd, LTV_PWRCTL1,
|
||||
LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
|
||||
| LTV_SUPPLY_CURRENT(5));
|
||||
ltv350qv_write_reg(lcd, LTV_GATECTL2,
|
||||
LTV_NW_INV_1LINE | LTV_FWI(3));
|
||||
err_settings:
|
||||
err_power2:
|
||||
err_power1:
|
||||
ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
|
||||
msleep(1);
|
||||
err:
|
||||
ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int ltv350qv_power_off(struct ltv350qv *lcd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Display Off Sequence */
|
||||
ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
|
||||
LTV_VCOM_DISABLE
|
||||
| LTV_DRIVE_CURRENT(5)
|
||||
| LTV_SUPPLY_CURRENT(5));
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
|
||||
LTV_NW_INV_1LINE | LTV_FWI(3));
|
||||
|
||||
/* Power down setting 1 */
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
|
||||
|
||||
/* Wait at least 1 ms */
|
||||
msleep(1);
|
||||
|
||||
/* Power down setting 2 */
|
||||
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
|
||||
|
||||
/*
|
||||
* No point in trying to recover here. If we can't switch the
|
||||
* panel off, what are we supposed to do other than inform the
|
||||
* user about the failure?
|
||||
*/
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
/* Display power should now be OFF */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ltv350qv_power(struct ltv350qv *lcd, int power)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
|
||||
ret = ltv350qv_power_on(lcd);
|
||||
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
|
||||
ret = ltv350qv_power_off(lcd);
|
||||
|
||||
if (!ret)
|
||||
lcd->power = power;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ltv350qv_set_power(struct lcd_device *ld, int power)
|
||||
{
|
||||
struct ltv350qv *lcd = lcd_get_data(ld);
|
||||
|
||||
return ltv350qv_power(lcd, power);
|
||||
}
|
||||
|
||||
static int ltv350qv_get_power(struct lcd_device *ld)
|
||||
{
|
||||
struct ltv350qv *lcd = lcd_get_data(ld);
|
||||
|
||||
return lcd->power;
|
||||
}
|
||||
|
||||
static struct lcd_ops ltv_ops = {
|
||||
.get_power = ltv350qv_get_power,
|
||||
.set_power = ltv350qv_set_power,
|
||||
};
|
||||
|
||||
static int __devinit ltv350qv_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ltv350qv *lcd;
|
||||
struct lcd_device *ld;
|
||||
int ret;
|
||||
|
||||
lcd = kzalloc(sizeof(struct ltv350qv), GFP_KERNEL);
|
||||
if (!lcd)
|
||||
return -ENOMEM;
|
||||
|
||||
lcd->spi = spi;
|
||||
lcd->power = FB_BLANK_POWERDOWN;
|
||||
lcd->buffer = kzalloc(8, GFP_KERNEL);
|
||||
|
||||
ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops);
|
||||
if (IS_ERR(ld)) {
|
||||
ret = PTR_ERR(ld);
|
||||
goto out_free_lcd;
|
||||
}
|
||||
lcd->ld = ld;
|
||||
|
||||
ret = ltv350qv_power(lcd, FB_BLANK_UNBLANK);
|
||||
if (ret)
|
||||
goto out_unregister;
|
||||
|
||||
dev_set_drvdata(&spi->dev, lcd);
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
lcd_device_unregister(ld);
|
||||
out_free_lcd:
|
||||
kfree(lcd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ltv350qv_remove(struct spi_device *spi)
|
||||
{
|
||||
struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
|
||||
lcd_device_unregister(lcd->ld);
|
||||
kfree(lcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ltv350qv_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
|
||||
}
|
||||
|
||||
static int ltv350qv_resume(struct spi_device *spi)
|
||||
{
|
||||
struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
|
||||
}
|
||||
#else
|
||||
#define ltv350qv_suspend NULL
|
||||
#define ltv350qv_resume NULL
|
||||
#endif
|
||||
|
||||
/* Power down all displays on reboot, poweroff or halt */
|
||||
static void ltv350qv_shutdown(struct spi_device *spi)
|
||||
{
|
||||
struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
|
||||
}
|
||||
|
||||
static struct spi_driver ltv350qv_driver = {
|
||||
.driver = {
|
||||
.name = "ltv350qv",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = ltv350qv_probe,
|
||||
.remove = __devexit_p(ltv350qv_remove),
|
||||
.shutdown = ltv350qv_shutdown,
|
||||
.suspend = ltv350qv_suspend,
|
||||
.resume = ltv350qv_resume,
|
||||
};
|
||||
|
||||
static int __init ltv350qv_init(void)
|
||||
{
|
||||
return spi_register_driver(<v350qv_driver);
|
||||
}
|
||||
|
||||
static void __exit ltv350qv_exit(void)
|
||||
{
|
||||
spi_unregister_driver(<v350qv_driver);
|
||||
}
|
||||
module_init(ltv350qv_init);
|
||||
module_exit(ltv350qv_exit);
|
||||
|
||||
MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
|
||||
MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
|
||||
MODULE_LICENSE("GPL");
|
95
drivers/video/backlight/ltv350qv.h
Normal file
95
drivers/video/backlight/ltv350qv.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Register definitions for Samsung LTV350QV Quarter VGA LCD Panel
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __LTV350QV_H
|
||||
#define __LTV350QV_H
|
||||
|
||||
#define LTV_OPC_INDEX 0x74
|
||||
#define LTV_OPC_DATA 0x76
|
||||
|
||||
#define LTV_ID 0x00 /* ID Read */
|
||||
#define LTV_IFCTL 0x01 /* Display Interface Control */
|
||||
#define LTV_DATACTL 0x02 /* Display Data Control */
|
||||
#define LTV_ENTRY_MODE 0x03 /* Entry Mode */
|
||||
#define LTV_GATECTL1 0x04 /* Gate Control 1 */
|
||||
#define LTV_GATECTL2 0x05 /* Gate Control 2 */
|
||||
#define LTV_VBP 0x06 /* Vertical Back Porch */
|
||||
#define LTV_HBP 0x07 /* Horizontal Back Porch */
|
||||
#define LTV_SOTCTL 0x08 /* Source Output Timing Control */
|
||||
#define LTV_PWRCTL1 0x09 /* Power Control 1 */
|
||||
#define LTV_PWRCTL2 0x0a /* Power Control 2 */
|
||||
#define LTV_GAMMA(x) (0x10 + (x)) /* Gamma control */
|
||||
|
||||
/* Bit definitions for LTV_IFCTL */
|
||||
#define LTV_IM (1 << 15)
|
||||
#define LTV_NMD (1 << 14)
|
||||
#define LTV_SSMD (1 << 13)
|
||||
#define LTV_REV (1 << 7)
|
||||
#define LTV_NL(x) (((x) & 0x001f) << 0)
|
||||
|
||||
/* Bit definitions for LTV_DATACTL */
|
||||
#define LTV_DS_SAME (0 << 12)
|
||||
#define LTV_DS_D_TO_S (1 << 12)
|
||||
#define LTV_DS_S_TO_D (2 << 12)
|
||||
#define LTV_CHS_384 (0 << 9)
|
||||
#define LTV_CHS_480 (1 << 9)
|
||||
#define LTV_CHS_492 (2 << 9)
|
||||
#define LTV_DF_RGB (0 << 6)
|
||||
#define LTV_DF_RGBX (1 << 6)
|
||||
#define LTV_DF_XRGB (2 << 6)
|
||||
#define LTV_RGB_RGB (0 << 2)
|
||||
#define LTV_RGB_BGR (1 << 2)
|
||||
#define LTV_RGB_GRB (2 << 2)
|
||||
#define LTV_RGB_RBG (3 << 2)
|
||||
|
||||
/* Bit definitions for LTV_ENTRY_MODE */
|
||||
#define LTV_VSPL_ACTIVE_LOW (0 << 15)
|
||||
#define LTV_VSPL_ACTIVE_HIGH (1 << 15)
|
||||
#define LTV_HSPL_ACTIVE_LOW (0 << 14)
|
||||
#define LTV_HSPL_ACTIVE_HIGH (1 << 14)
|
||||
#define LTV_DPL_SAMPLE_RISING (0 << 13)
|
||||
#define LTV_DPL_SAMPLE_FALLING (1 << 13)
|
||||
#define LTV_EPL_ACTIVE_LOW (0 << 12)
|
||||
#define LTV_EPL_ACTIVE_HIGH (1 << 12)
|
||||
#define LTV_SS_LEFT_TO_RIGHT (0 << 8)
|
||||
#define LTV_SS_RIGHT_TO_LEFT (1 << 8)
|
||||
#define LTV_STB (1 << 1)
|
||||
|
||||
/* Bit definitions for LTV_GATECTL1 */
|
||||
#define LTV_CLW(x) (((x) & 0x0007) << 12)
|
||||
#define LTV_GAON (1 << 5)
|
||||
#define LTV_SDR (1 << 3)
|
||||
|
||||
/* Bit definitions for LTV_GATECTL2 */
|
||||
#define LTV_NW_INV_FRAME (0 << 14)
|
||||
#define LTV_NW_INV_1LINE (1 << 14)
|
||||
#define LTV_NW_INV_2LINE (2 << 14)
|
||||
#define LTV_DSC (1 << 12)
|
||||
#define LTV_GIF (1 << 8)
|
||||
#define LTV_FHN (1 << 7)
|
||||
#define LTV_FTI(x) (((x) & 0x0003) << 4)
|
||||
#define LTV_FWI(x) (((x) & 0x0003) << 0)
|
||||
|
||||
/* Bit definitions for LTV_SOTCTL */
|
||||
#define LTV_SDT(x) (((x) & 0x0007) << 10)
|
||||
#define LTV_EQ(x) (((x) & 0x0007) << 2)
|
||||
|
||||
/* Bit definitions for LTV_PWRCTL1 */
|
||||
#define LTV_VCOM_DISABLE (1 << 14)
|
||||
#define LTV_VCOMOUT_ENABLE (1 << 11)
|
||||
#define LTV_POWER_ON (1 << 9)
|
||||
#define LTV_DRIVE_CURRENT(x) (((x) & 0x0007) << 4) /* 0=off, 5=max */
|
||||
#define LTV_SUPPLY_CURRENT(x) (((x) & 0x0007) << 0) /* 0=off, 5=max */
|
||||
|
||||
/* Bit definitions for LTV_PWRCTL2 */
|
||||
#define LTV_VCOML_ENABLE (1 << 13)
|
||||
#define LTV_VCOML_VOLTAGE(x) (((x) & 0x001f) << 8) /* 0=1V, 31=-1V */
|
||||
#define LTV_VCOMH_VOLTAGE(x) (((x) & 0x001f) << 0) /* 0=3V, 31=4.5V */
|
||||
|
||||
#endif /* __LTV350QV_H */
|
@ -25,12 +25,6 @@ struct corgits_machinfo {
|
||||
/*
|
||||
* SharpSL Backlight
|
||||
*/
|
||||
struct corgibl_machinfo {
|
||||
int max_intensity;
|
||||
int default_intensity;
|
||||
int limit_mask;
|
||||
void (*set_bl_intensity)(int intensity);
|
||||
};
|
||||
extern void corgibl_limit_intensity(int limit);
|
||||
|
||||
|
||||
|
@ -92,4 +92,13 @@ static inline void * bl_get_data(struct backlight_device *bl_dev)
|
||||
return dev_get_drvdata(&bl_dev->dev);
|
||||
}
|
||||
|
||||
struct generic_bl_info {
|
||||
const char *name;
|
||||
int max_intensity;
|
||||
int default_intensity;
|
||||
int limit_mask;
|
||||
void (*set_bl_intensity)(int intensity);
|
||||
void (*kick_battery)(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user