This is a driver for the Truly G240400RTSW LCD panel using the Jz4740 SLCD framebuffer functions to communicate with the driver chip (Renesas R61509). It currently supports initializing at boot and suspending, but it fails to come back up after resume and it doesn't support any gamma or image control. Tested on an Onda VX747 (Ingenic Jz4740 device). Signed-off-by: Maurus Cuelenaere <mcuelenaere@xxxxxxxxx> --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/truly_g240400rtsw.c | 464 +++++++++++++++++++++++++++ include/video/truly_g240400rtsw.h | 35 ++ 4 files changed, 507 insertions(+), 0 deletions(-) create mode 100644 drivers/video/backlight/truly_g240400rtsw.c create mode 100644 include/video/truly_g240400rtsw.h diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index e54a337..afa96c2 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -109,6 +109,13 @@ config LCD_S6E63M0 If you have an S6E63M0 LCD Panel, say Y to enable its LCD control driver. +config LCD_G240400 + tristate "Truly G240400RTSW LCD Driver" + depends on MACH_JZ4740 + help + If you have a Truly G2400400RTSW LCD panel, say Y to enable its LCD + control driver. + endif # LCD_CLASS_DEVICE # diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 44c0f81..1e338ce 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o obj-$(CONFIG_LCD_TDO24M) += tdo24m.o obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o +obj-$(CONFIG_LCD_G240400) += truly_g240400rtsw.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o diff --git a/drivers/video/backlight/truly_g240400rtsw.c b/drivers/video/backlight/truly_g240400rtsw.c new file mode 100644 index 0000000..437980b --- /dev/null +++ b/drivers/video/backlight/truly_g240400rtsw.c @@ -0,0 +1,464 @@ +/* + * drivers/video/backlight/truly_g240400rtsw.c + * + * Truly G240400RTSW LCD panel driver + * + * Copyright (c) 2011, Maurus Cuelenaere <mcuelenaere@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include <linux/backlight.h> +#include <linux/device.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/lcd.h> + +#include <asm/mach-jz4740/jz4740_fb.h> + +#include <video/truly_g240400rtsw.h> + +/* This LCD panel contains a Renesas R61509 driver chip */ +/* Register list */ +#define REG_DEVICE_CODE 0x000 +#define REG_DRIVER_OUTPUT 0x001 +#define REG_LCD_DR_WAVE_CTRL 0x002 +#define REG_ENTRY_MODE 0x003 +#define REG_OUTL_SHARP_CTRL 0x006 +#define REG_DISP_CTRL1 0x007 +#define REG_DISP_CTRL2 0x008 +#define REG_DISP_CTRL3 0x009 +#define REG_LPCTRL 0x00B +#define REG_EXT_DISP_CTRL1 0x00C +#define REG_EXT_DISP_CTRL2 0x00F +#define REG_PAN_INTF_CTRL1 0x010 +#define REG_PAN_INTF_CTRL2 0x011 +#define REG_PAN_INTF_CTRL3 0x012 +#define REG_PAN_INTF_CTRL4 0x020 +#define REG_PAN_INTF_CTRL5 0x021 +#define REG_PAN_INTF_CTRL6 0x022 +#define REG_FRM_MRKR_CTRL 0x090 + +#define REG_PWR_CTRL1 0x100 +#define REG_PWR_CTRL2 0x101 +#define REG_PWR_CTRL3 0x102 +#define REG_PWR_CTRL4 0x103 +#define REG_PWR_CTRL5 0x107 +#define REG_PWR_CTRL6 0x110 +#define REG_PWR_CTRL7 0x112 + +#define REG_RAM_HADDR_SET 0x200 +#define REG_RAM_VADDR_SET 0x201 +#define REG_RW_GRAM 0x202 +#define REG_RAM_HADDR_START 0x210 +#define REG_RAM_HADDR_END 0x211 +#define REG_RAM_VADDR_START 0x212 +#define REG_RAM_VADDR_END 0x213 +#define REG_RW_NVM 0x280 +#define REG_VCOM_HVOLTAGE1 0x281 +#define REG_VCOM_HVOLTAGE2 0x282 + +#define REG_GAMMA_CTRL1 0x300 +#define REG_GAMMA_CTRL2 0x301 +#define REG_GAMMA_CTRL3 0x302 +#define REG_GAMMA_CTRL4 0x303 +#define REG_GAMMA_CTRL5 0x304 +#define REG_GAMMA_CTRL6 0x305 +#define REG_GAMMA_CTRL7 0x306 +#define REG_GAMMA_CTRL8 0x307 +#define REG_GAMMA_CTRL9 0x308 +#define REG_GAMMA_CTRL10 0x309 +#define REG_GAMMA_CTRL11 0x30A +#define REG_GAMMA_CTRL12 0x30B +#define REG_GAMMA_CTRL13 0x30C +#define REG_GAMMA_CTRL14 0x30D + +#define REG_BIMG_NR_LINE 0x400 +#define REG_BIMG_DISP_CTRL 0x401 +#define REG_BIMG_VSCROLL_CTRL 0x404 + +#define REG_PARTIMG1_POS 0x500 +#define REG_PARTIMG1_RAM_START 0x501 +#define REG_PARTIMG1_RAM_END 0x502 +#define REG_PARTIMG2_POS 0x503 +#define REG_PARTIMG2_RAM_START 0x504 +#define REG_PARTIMG2_RAM_END 0x505 + +#define REG_SOFT_RESET 0x600 +#define REG_ENDIAN_CTRL 0x606 +#define REG_NVM_ACCESS_CTRL 0x6F0 + +/* Bits */ +#define DRIVER_OUTPUT_SS_BIT (1 << 8) +#define DRIVER_OUTPUT_SM_BIT (1 << 10) + +#define ENTRY_MODE_TRI (1 << 15) +#define ENTRY_MODE_DFM (1 << 14) +#define ENTRY_MODE_BGR (1 << 12) +#define ENTRY_MODE_HWM (1 << 9) +#define ENTRY_MODE_ORG (1 << 7) +#define ENTRY_MODE_VID (1 << 5) +#define ENTRY_MODE_HID (1 << 4) +#define ENTRY_MODE_AM (1 << 3) +#define ENTRY_MODE_EPF(n) (n & 3) + +#define OUTL_SHARP_CTRL_EGMODE (1 << 15) +#define OUTL_SHARP_CTRL_AVST(n) ((n & 7) << 7) +#define OUTL_SHARP_CTRL_ADST(n) ((n & 7) << 4) +#define OUTL_SHARP_CTRL_DTHU(n) ((n & 3) << 2) +#define OUTL_SHARP_CTRL_DTHL(n) (n & 3) + +#define DISP_CTRL1_PTDE(n) ((n & 4) << 12) +#define DISP_CTRL1_BASEE (1 << 8) +#define DISP_CTRL1_VON (1 << 6) +#define DISP_CTRL1_GON (1 << 5) +#define DISP_CTRL1_DTE (1 << 4) +#define DISP_CTRL1_D(n) (n & 3) + +#define EXT_DISP_CTRL1_ENC(n) ((n & 7) << 12) +#define EXT_DISP_CTRL1_RM(n) ((n & 1) << 8) +#define EXT_DISP_CTRL1_DM(n) ((n & 3) << 4) +#define EXT_DISP_CTRL1_RIM(n) (n & 3) + +#define PWR_CTRL1_SAP(n) ((n & 3) << 13) +#define PWR_CTRL1_SAPE (1 << 12) +#define PWR_CTRL1_BT(n) ((n & 7) << 8) +#define PWR_CTRL1_APE (1 << 7) +#define PWR_CTRL1_AP(n) ((n & 7) << 4) +#define PWR_CTRL1_DSTB (1 << 2) +#define PWR_CTRL1_SLP (1 << 1) + +#define SOFT_RESET(n) (n << 0) + +struct g240400 { + struct device *dev; + struct lcd_device *lcd; + + struct g240400_pdata pdata; + + int power; +}; + +#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) + +static void g240400_reset(struct g240400 *lcm) +{ + struct platform_device *jzfb = lcm->pdata.jz4740_fb; + + if (gpio_is_valid(lcm->pdata.gpio_reset)) { + gpio_direction_output(lcm->pdata.gpio_reset, 0); + mdelay(1); + gpio_direction_output(lcm->pdata.gpio_reset, 1); + } + + jz4740_fb_slcd_disable_transfer(jzfb); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_SOFT_RESET, SOFT_RESET(1)); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_SOFT_RESET, SOFT_RESET(0)); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_ENDIAN_CTRL, 0); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DRIVER_OUTPUT, 0x100); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_LCD_DR_WAVE_CTRL, 0x100); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_HWM | ENTRY_MODE_DFM | ENTRY_MODE_VID | ENTRY_MODE_HID)); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL2, 0x503); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL3, 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_LPCTRL, 0x10); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_EXT_DISP_CTRL1, EXT_DISP_CTRL1_RIM(1)); /* 16-bit RGB interface */ + jz4740_fb_slcd_send_cmd_data(jzfb, REG_EXT_DISP_CTRL2, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, DISP_CTRL1_D(1)); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL1, 0x12); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL2, 0x202); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL3, 0x300); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL4, 0x21e); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL5, 0x202); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PAN_INTF_CTRL6, 0x100); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_FRM_MRKR_CTRL, 0x8000); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL1, (PWR_CTRL1_SAPE | PWR_CTRL1_BT(6) | PWR_CTRL1_APE | PWR_CTRL1_AP(3))); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL2, 0x147); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL3, 0x1bd); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL4, 0x2f00); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL5, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL6, 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RW_NVM, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_VCOM_HVOLTAGE1, 6); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_VCOM_HVOLTAGE2, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL1, 0x101); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL2, 0xb27); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL3, 0x132a); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL4, 0x2a13); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL5, 0x270b); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL6, 0x101); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL7, 0x1205); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL8, 0x512); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL9, 5); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL10, 3); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL11, 0xf04); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL12, 0xf00); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL13, 0xf); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_GAMMA_CTRL14, 0x40f); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x30e, 0x300); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x30f, 0x500); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_BIMG_NR_LINE, 0x3100); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_BIMG_DISP_CTRL, 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_BIMG_VSCROLL_CTRL, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG1_POS, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG1_RAM_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG1_RAM_END, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG2_POS, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG2_RAM_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PARTIMG2_RAM_END, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_ENDIAN_CTRL, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_NVM_ACCESS_CTRL, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x7f0, 0x5420); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x7f3, 0x288a); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x7f4, 0x22); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x7f5, 1); + jz4740_fb_slcd_send_cmd_data(jzfb, 0x7f0, 0); + + /* LCD ON */ + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, (DISP_CTRL1_GON | + DISP_CTRL1_D(1))); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, (DISP_CTRL1_VON | + DISP_CTRL1_GON | DISP_CTRL1_D(1))); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, (DISP_CTRL1_BASEE | + DISP_CTRL1_VON | DISP_CTRL1_GON | + DISP_CTRL1_DTE | DISP_CTRL1_D(3))); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_END, lcm->pdata.default_mode->xres - 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_END, lcm->pdata.default_mode->yres - 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_SET, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_SET, 0); + jz4740_fb_slcd_send_cmd(jzfb, REG_RW_GRAM); /* write data to GRAM */ + + jz4740_fb_slcd_enable_transfer(jzfb); +} + +static void g240400_powerdown(struct g240400 *lcm) +{ + struct platform_device *jzfb = lcm->pdata.jz4740_fb; + + jz4740_fb_slcd_disable_transfer(jzfb); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, (DISP_CTRL1_VON | + DISP_CTRL1_GON | DISP_CTRL1_DTE | + DISP_CTRL1_D(2))); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, DISP_CTRL1_D(1)); + mdelay(1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_DISP_CTRL1, DISP_CTRL1_D(0)); + + jz4740_fb_slcd_enable_transfer(jzfb); +} + +static void g240400_standby(struct g240400 *lcm) +{ + struct platform_device *jzfb = lcm->pdata.jz4740_fb; + + jz4740_fb_slcd_disable_transfer(jzfb); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL1, PWR_CTRL1_SLP); + + jz4740_fb_slcd_enable_transfer(jzfb); +} + +static void g240400_poweron(struct g240400 *lcm) +{ + struct platform_device *jzfb = lcm->pdata.jz4740_fb; + + jz4740_fb_slcd_disable_transfer(jzfb); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_PWR_CTRL1, (PWR_CTRL1_SAPE | PWR_CTRL1_BT(6) | PWR_CTRL1_APE | PWR_CTRL1_AP(3))); + + jz4740_fb_slcd_enable_transfer(jzfb); +} + +static int g240400_get_power(struct lcd_device *lcd) +{ + struct g240400 *lcm = lcd_get_data(lcd); + + return lcm->power; +} + +static int g240400_set_power(struct lcd_device *lcd, int power) +{ + struct g240400 *lcm = lcd_get_data(lcd); + + if (power == lcm->power) + return 0; + + if (POWER_IS_ON(power)) + g240400_poweron(lcm); + else + g240400_standby(lcm); + + lcm->power = power; + + return 0; +} + +static int g240400_set_mode(struct lcd_device *lcd, struct fb_videomode *mode) +{ + struct g240400 *lcm = lcd_get_data(lcd); + struct platform_device *jzfb = lcm->pdata.jz4740_fb; + + jz4740_fb_slcd_disable_transfer(jzfb); + + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_END, mode->xres - 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_START, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_END, mode->yres - 1); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_HADDR_SET, 0); + jz4740_fb_slcd_send_cmd_data(jzfb, REG_RAM_VADDR_SET, 0); + jz4740_fb_slcd_send_cmd(jzfb, REG_RW_GRAM); /* write data to GRAM */ + + jz4740_fb_slcd_enable_transfer(jzfb); + + lcm->pdata.default_mode = mode; + + return 0; +} + +static struct lcd_ops g240400_lcd_ops = { + .get_power = g240400_get_power, + .set_power = g240400_set_power, + .set_mode = g240400_set_mode, +}; + +static int __devinit g240400_probe(struct platform_device *pdev) +{ + int ret; + struct g240400 *lcm; + struct lcd_device *lcd; + struct g240400_pdata *pdata = pdev->dev.platform_data; + + if (!pdata) { + dev_err(&pdev->dev, "Platform data wasn't provided!"); + return -EINVAL; + } + + lcm = kzalloc(sizeof(struct g240400), GFP_KERNEL); + if (!lcm) + return -ENOMEM; + + lcm->dev = &pdev->dev; + memcpy(&lcm->pdata, pdata, sizeof(struct g240400_pdata)); + + lcd = lcd_device_register("truly_g240400", &pdev->dev, lcm, + &g240400_lcd_ops); + if (IS_ERR(lcd)) { + ret = PTR_ERR(lcd); + goto out_free_device; + } + + if (gpio_is_valid(lcm->pdata.gpio_reset)) { + ret = gpio_request(lcm->pdata.gpio_reset, "lcd reset"); + if (ret) + goto out_unregister_lcd; + } + + if (gpio_is_valid(lcm->pdata.gpio_cs)) { + ret = gpio_request(lcm->pdata.gpio_cs, "lcd chip select"); + if (ret) + goto out_free_pin_cs; + } + + dev_set_drvdata(&pdev->dev, lcm); + + /* Always select LCD chip */ + if (gpio_is_valid(lcm->pdata.gpio_cs)) + gpio_direction_output(lcm->pdata.gpio_cs, 0); + + g240400_reset(lcm); + + return 0; + +out_free_pin_cs: + if (gpio_is_valid(lcm->pdata.gpio_cs)) + gpio_free(lcm->pdata.gpio_cs); +out_unregister_lcd: + lcd_device_unregister(lcd); +out_free_device: + kfree(lcm); + + return ret; +} + +static int __devexit g240400_remove(struct platform_device *pdev) +{ + struct g240400 *lcm = dev_get_drvdata(&pdev->dev); + + if (gpio_is_valid(lcm->pdata.gpio_reset)) + gpio_free(lcm->pdata.gpio_reset); + if (gpio_is_valid(lcm->pdata.gpio_cs)) + gpio_free(lcm->pdata.gpio_cs); + lcd_device_unregister(lcm->lcd); + kfree(lcm); + + return 0; +} + +#ifdef CONFIG_PM +static int g240400_suspend(struct device *dev) +{ + struct g240400 *lcm = dev_get_drvdata(dev); + + g240400_powerdown(lcm); + gpio_direction_output(lcm->pdata.gpio_cs, 1); + + return 0; +} + +static int g240400_resume(struct device *dev) +{ + struct g240400 *lcm = dev_get_drvdata(dev); + + gpio_direction_output(lcm->pdata.gpio_cs, 0); + g240400_reset(lcm); + + return 0; +} + +static const struct dev_pm_ops g240400_ops = { + .suspend = g240400_suspend, + .resume = g240400_resume, +}; +#endif + +static struct platform_driver g240400_driver = { + .driver = { + .name = "truly_g240400rtsw", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &g240400_ops, +#endif + }, + .probe = g240400_probe, + .remove = __devexit_p(g240400_remove), +}; + +static int __init g240400_init(void) +{ + return platform_driver_register(&g240400_driver); +} +late_initcall(g240400_init); /* Ensure this gets loaded *after* the FB */ + +static void __exit g240400_exit(void) +{ + platform_driver_unregister(&g240400_driver); +} +module_exit(g240400_exit); diff --git a/include/video/truly_g240400rtsw.h b/include/video/truly_g240400rtsw.h new file mode 100644 index 0000000..e4147b2 --- /dev/null +++ b/include/video/truly_g240400rtsw.h @@ -0,0 +1,35 @@ +/* + * include/video/truly_g240400rtsw.h + * + * Truly G240400RTSW LCD panel driver + * + * Copyright (c) 2011, Maurus Cuelenaere <mcuelenaere@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __VIDEO_TRULY_G240400RTSW_H__ +#define __VIDEO_TRULY_G240400RTSW_H__ + +struct platform_device; +struct fb_videomode; + +/** + * @jz4740_fb: pointer to the platform_device corresponding with the Ingenic + * Jz4740 framebuffer driver, required + * @default_mode: initial video mode when LCD panel gets powered on, required + * @gpio_reset: GPIO reset pin, set to -1 for unused + * @gpio_cs: GPIO chip select pin, set to -1 for unused + */ +struct g240400_pdata { + struct platform_device *jz4740_fb; + struct fb_videomode *default_mode; + int gpio_reset; + int gpio_cs; +}; + +#endif /* __VIDEO_TRULY_G240400RTSW_H__ */ -- 1.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html