Merge remote branch 'origin/develop' into develop

This commit is contained in:
陈真 2011-03-23 17:05:12 +08:00
commit c479a969c5
55 changed files with 10259 additions and 1598 deletions

File diff suppressed because it is too large Load Diff

View File

@ -119,9 +119,9 @@ struct rk2818_bl_info{
};
struct rk2818_gpio_expander_info {
unsigned int gpio_num;// 初始化的pin 脚宏定义 如:RK2818_PIN_PI0
unsigned int pin_type;//初始化的pin 为输入pin还是输出pin 如:GPIO_IN
unsigned int pin_value;//如果为 output pin 设置电平,如:GPIO_HIGH
unsigned int gpio_num;// RK2818_PIN_PI0
unsigned int pin_type;//GPIO_IN or GPIO_OUT
unsigned int pin_value;//GPIO_HIGH or GPIO_LOW
};
@ -132,8 +132,8 @@ struct pca9554_platform_data {
/* the first gpio irq number in all of irq source */
unsigned int gpio_irq_start;
unsigned int irq_pin_num; //中断的个数
unsigned int pca9954_irq_pin; //扩展IO的中断挂在哪个gpio
unsigned int irq_pin_num; //number of intterupt
unsigned int pca9954_irq_pin; //rk28 gpio
/* initial polarity inversion setting */
uint16_t invert;
struct rk2818_gpio_expander_info *settinginfo;
@ -152,8 +152,8 @@ struct tca6424_platform_data {
/* the first gpio irq number in all of irq source */
unsigned int gpio_irq_start;
unsigned int irq_pin_num; //中断的个数
unsigned int tca6424_irq_pin; //扩展IO的中断挂在哪个gpio
unsigned int irq_pin_num; //number of interrupt
unsigned int tca6424_irq_pin; //rk28 gpio
unsigned int expand_port_group;
unsigned int expand_port_pinnum;
unsigned int rk_irq_mode;

View File

@ -42,6 +42,12 @@ config MACH_RK29_PHONESDK
help
Support for the ROCKCHIP Board For Rk29 Phone Sdk.
config MACH_RK29_A22
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For A22"
help
Support for the ROCKCHIP Board For A22.
endchoice
config RK29_MEM_SIZE_M

View File

@ -12,3 +12,5 @@ obj-$(CONFIG_MACH_RK29_AIGO) += board-rk29-aigo.o board-rk29aigo-key.o board-rk2
obj-$(CONFIG_MACH_RK29_MALATA) += board-malata.o board-rk29malata-key.o board-rk29sdk-rfkill.o
obj-$(CONFIG_MACH_RK29_PHONESDK) += board-rk29-phonesdk.o board-rk29-phonesdk-key.o board-rk29-phonesdk-rfkill.o
obj-$(CONFIG_MACH_RK29FIH) += board-rk29-fih.o board-rk29sdk-key.o board-rk29sdk-rfkill.o
obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-a22-rfkill.o

View File

@ -0,0 +1,106 @@
#include <mach/key.h>
#include <mach/gpio.h>
#define EV_ENCALL KEY_F4
#define EV_MENU KEY_F1
#define PRESS_LEV_LOW 1
#define PRESS_LEV_HIGH 0
static struct rk29_keys_button key_button[] = {
{
.desc = "menu",
.code = EV_MENU,
.gpio = RK29_PIN6_PA0,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol+",
.code = KEY_VOLUMEUP,
.gpio = RK29_PIN6_PA1,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEDOWN,
.gpio = RK29_PIN6_PA2,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.gpio = RK29_PIN6_PA3,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "search",
.code = KEY_SEARCH,
.gpio = RK29_PIN6_PA4,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_BACK,
.gpio = RK29_PIN6_PA5,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "sensor",
.code = KEY_CAMERA,
.gpio = RK29_PIN6_PA6,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "play",
.code = KEY_POWER,
.gpio = RK29_PIN6_PA7,
.active_low = PRESS_LEV_LOW,
.wakeup = 1,
},
#if 0
{
.desc = "vol+",
.code = KEY_VOLUMEDOWN,
.adc_value = 95,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEUP,
.adc_value = 249,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "menu",
.code = EV_MENU,
.adc_value = 406,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.code_long_press = KEY_F4,
.adc_value = 561,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_ESC,
.adc_value = 726,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "adkey6",
.code = KEY_BACK,
.code_long_press = EV_ENCALL,
.adc_value = 899,
.active_low = PRESS_LEV_LOW,
},
#endif
};
struct rk29_keys_platform_data rk29_keys_pdata = {
.buttons = key_button,
.nbuttons = ARRAY_SIZE(key_button),
.chn = -1, //chn: 0-7, if do not use ADC,set 'chn' -1
};

View File

@ -0,0 +1,294 @@
/*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Author: roger_chen <cz@rock-chips.com>
*
* This program is the bluetooth device bcm4329's driver,
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/rfkill.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>
#include <asm/irq.h>
#include <mach/iomux.h>
#include <linux/wakelock.h>
#include <linux/timer.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define BT_WAKE_HOST_SUPPORT 0
struct bt_ctrl
{
struct rfkill *bt_rfk;
#if BT_WAKE_HOST_SUPPORT
struct timer_list tl;
bool b_HostWake;
struct wake_lock bt_wakelock;
#endif
};
#define BT_GPIO_POWER RK29_PIN5_PD6
#define IOMUX_BT_GPIO_POWER rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
#define BT_GPIO_RESET RK29_PIN6_PC4
#define BT_GPIO_WAKE_UP RK29_PIN6_PC5
#define BT_GPIO_WAKE_UP_HOST //RK2818_PIN_PA7
#define IOMUX_BT_GPIO_WAKE_UP_HOST() //rk2818_mux_api_set(GPIOA7_FLASHCS3_SEL_NAME,0);
#define BT_WAKE_LOCK_TIMEOUT 10 //s
static const char bt_name[] = "bcm4329";
extern int rk29sdk_bt_power_state;
extern int rk29sdk_wifi_power_state;
struct bt_ctrl gBtCtrl;
#if BT_WAKE_HOST_SUPPORT
void resetBtHostSleepTimer(void)
{
mod_timer(&(gBtCtrl.tl),jiffies + BT_WAKE_LOCK_TIMEOUT*HZ);//再重新设置超时值。
}
void btWakeupHostLock(void)
{
if(gBtCtrl.b_HostWake == false){
DBG("*************************Lock\n");
wake_lock(&(gBtCtrl.bt_wakelock));
gBtCtrl.b_HostWake = true;
}
}
void btWakeupHostUnlock(void)
{
if(gBtCtrl.b_HostWake == true){
DBG("*************************UnLock\n");
wake_unlock(&(gBtCtrl.bt_wakelock)); //让系统睡眠
gBtCtrl.b_HostWake = false;
}
}
static void timer_hostSleep(unsigned long arg)
{
DBG("%s---b_HostWake=%d\n",__FUNCTION__,gBtCtrl.b_HostWake);
btWakeupHostUnlock();
}
#ifdef CONFIG_PM
static int bcm4329_rfkill_suspend(struct platform_device *pdev, pm_message_t state)
{
DBG("%s\n",__FUNCTION__);
return 0;
}
static int bcm4329_rfkill_resume(struct platform_device *pdev)
{
DBG("%s\n",__FUNCTION__);
btWakeupHostLock();
resetBtHostSleepTimer();
return 0;
}
#else
#define bcm4329_rfkill_suspend NULL
#define bcm4329_rfkill_resume NULL
#endif
static irqreturn_t bcm4329_wake_host_irq(int irq, void *dev)
{
btWakeupHostLock();
resetBtHostSleepTimer();
return IRQ_HANDLED;
}
#endif
#ifdef CONFIG_BT_HCIBCM4325
int bcm4325_sleep(int bSleep)
{
// printk("*************bt enter sleep***************\n");
if (bSleep)
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_LOW); //low represent bt device may enter sleep
else
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_HIGH); //high represent bt device must be awake
//printk("sleep=%d\n",bSleep);
}
#endif
static int bcm4329_set_block(void *data, bool blocked)
{
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
IOMUX_BT_GPIO_POWER;
if (false == blocked) {
gpio_set_value(BT_GPIO_POWER, GPIO_HIGH); /* bt power on */
gpio_set_value(BT_GPIO_RESET, GPIO_LOW);
mdelay(20);
gpio_set_value(BT_GPIO_RESET, GPIO_HIGH); /* bt reset deactive*/
mdelay(20);
#if BT_WAKE_HOST_SUPPORT
btWakeupHostLock();
#endif
pr_info("bt turn on power\n");
}
else {
#if BT_WAKE_HOST_SUPPORT
btWakeupHostUnlock();
#endif
if (!rk29sdk_wifi_power_state) {
gpio_set_value(BT_GPIO_POWER, GPIO_LOW); /* bt power off */
mdelay(20);
pr_info("bt shut off power\n");
}else {
pr_info("bt shouldn't shut off power, wifi is using it!\n");
}
gpio_set_value(BT_GPIO_RESET, GPIO_LOW); /* bt reset active*/
mdelay(20);
}
rk29sdk_bt_power_state = !blocked;
return 0;
}
static const struct rfkill_ops bcm4329_rfk_ops = {
.set_block = bcm4329_set_block,
};
static int __init bcm4329_rfkill_probe(struct platform_device *pdev)
{
int rc = 0;
bool default_state = true;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
/* default to bluetooth off */
bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
gBtCtrl.bt_rfk = rfkill_alloc(bt_name,
NULL,
RFKILL_TYPE_BLUETOOTH,
&bcm4329_rfk_ops,
NULL);
if (!gBtCtrl.bt_rfk)
{
printk("fail to rfkill_allocate************\n");
return -ENOMEM;
}
rfkill_set_states(gBtCtrl.bt_rfk, default_state, false);
rc = rfkill_register(gBtCtrl.bt_rfk);
if (rc)
{
printk("failed to rfkill_register,rc=0x%x\n",rc);
rfkill_destroy(gBtCtrl.bt_rfk);
}
gpio_request(BT_GPIO_POWER, NULL);
gpio_request(BT_GPIO_RESET, NULL);
gpio_request(BT_GPIO_WAKE_UP, NULL);
#if BT_WAKE_HOST_SUPPORT
init_timer(&(gBtCtrl.tl));
gBtCtrl.tl.expires = jiffies + BT_WAKE_LOCK_TIMEOUT*HZ;
gBtCtrl.tl.function = timer_hostSleep;
add_timer(&(gBtCtrl.tl));
gBtCtrl.b_HostWake = false;
wake_lock_init(&(gBtCtrl.bt_wakelock), WAKE_LOCK_SUSPEND, "bt_wake");
rc = gpio_request(BT_GPIO_WAKE_UP_HOST, "bt_wake");
if (rc) {
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST\n",__FUNCTION__);
}
IOMUX_BT_GPIO_WAKE_UP_HOST();
gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
rc = request_irq(gpio_to_irq(BT_GPIO_WAKE_UP_HOST),bcm4329_wake_host_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
if(rc)
{
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST irq\n",__FUNCTION__);
gpio_free(BT_GPIO_WAKE_UP_HOST);
}
enable_irq_wake(gpio_to_irq(BT_GPIO_WAKE_UP_HOST)); // so RAHO_BT_WAKE_UP_HOST can wake up system
printk(KERN_INFO "bcm4329 module has been initialized,rc=0x%x\n",rc);
#endif
return rc;
}
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
{
if (gBtCtrl.bt_rfk)
rfkill_unregister(gBtCtrl.bt_rfk);
gBtCtrl.bt_rfk = NULL;
#if BT_WAKE_HOST_SUPPORT
del_timer(&(gBtCtrl.tl));//删掉定时器
btWakeupHostUnlock();
wake_lock_destroy(&(gBtCtrl.bt_wakelock));
#endif
platform_set_drvdata(pdev, NULL);
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
return 0;
}
static struct platform_driver bcm4329_rfkill_driver = {
.probe = bcm4329_rfkill_probe,
.remove = __devexit_p(bcm4329_rfkill_remove),
.driver = {
.name = "rk29sdk_rfkill",
.owner = THIS_MODULE,
},
#if BT_WAKE_HOST_SUPPORT
.suspend = bcm4329_rfkill_suspend,
.resume = bcm4329_rfkill_resume,
#endif
};
/*
* Module initialization
*/
static int __init bcm4329_mod_init(void)
{
int ret;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
ret = platform_driver_register(&bcm4329_rfkill_driver);
printk("ret=0x%x\n", ret);
return ret;
}
static void __exit bcm4329_mod_exit(void)
{
platform_driver_unregister(&bcm4329_rfkill_driver);
}
module_init(bcm4329_mod_init);
module_exit(bcm4329_mod_exit);
MODULE_DESCRIPTION("bcm4329 Bluetooth driver");
MODULE_AUTHOR("roger_chen cz@rock-chips.com");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,7 @@
#include <mach/rk29_nand.h>
#include <mach/rk29_camera.h> /* ddl@rock-chips.com : camera support */
#include <media/soc_camera.h> /* ddl@rock-chips.com : camera support */
#include <linux/leds-att1272.h> /* ddl@rock-chips.com: camera flash led support */
#include <mach/vpu_mem.h>
#include <mach/sram.h>
@ -67,7 +68,7 @@
#define PMEM_VPU_SIZE SZ_64M
#define PMEM_CAM_SIZE 0x01300000
#ifdef CONFIG_VIDEO_RK29_WORK_IPP
#define MEM_CAMIPP_SIZE SZ_4M
#define MEM_CAMIPP_SIZE SZ_8M
#else
#define MEM_CAMIPP_SIZE 0
#endif
@ -805,7 +806,14 @@ struct tps65910_platform_data rk29_tps65910_data = {
};
#endif /* CONFIG_TPS65910_CORE */
/* ddl@rock-chips.com: camera flash led support */
#if CONFIG_LEDS_ATT1272
struct att1272_led_platform_data rk29_att1272_led_data = {
.name = "camera_flash_led",
.en_gpio = RK29_PIN1_PB0,
.flen_gpio = RK29_PIN1_PB1,
};
#endif
/*****************************************************************************************
* i2c devices
* author: kfx@rock-chips.com
@ -983,6 +991,15 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
//.platform_data = &p1003_info,
},
#endif
#if defined (CONFIG_LEDS_ATT1272)
{
.type = "att1272",
.addr = 0x37,
.flags = 0,
.platform_data = &rk29_att1272_led_data,
},
#endif
};
#endif
@ -1029,7 +1046,7 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
*****************************************************************************************/
#ifdef CONFIG_VIDEO_RK29
#define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_MT9P111 /* back camera sensor */
#define SENSOR_IIC_ADDR_0 0x00
#define SENSOR_IIC_ADDR_0 0x78
#define SENSOR_IIC_ADAPTER_ID_0 1
#define SENSOR_POWER_PIN_0 RK29_PIN5_PD7
#define SENSOR_RESET_PIN_0 INVALID_GPIO
@ -1041,7 +1058,7 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
#define SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L
#define SENSOR_NAME_1 RK29_CAM_SENSOR_NAME_S5K6AA /* front camera sensor */
#define SENSOR_IIC_ADDR_1 0x78
#define SENSOR_IIC_ADDR_1 0x00
#define SENSOR_IIC_ADAPTER_ID_1 1
#define SENSOR_POWER_PIN_1 INVALID_GPIO
#define SENSOR_RESET_PIN_1 RK29_PIN1_PB3

View File

@ -322,7 +322,7 @@ static struct platform_device rk29_v4l2_output_devce = {
.name = "rk29_vout",
};
/*HANNSTAR_P1003 touch*/
/* HANNSTAR_P1003 touch I2C */
#if defined (CONFIG_HANNSTAR_P1003)
#define TOUCH_RESET_PIN RK29_PIN6_PC3
#define TOUCH_INT_PIN RK29_PIN4_PD5
@ -357,6 +357,30 @@ struct p1003_platform_data p1003_info = {
};
#endif
#if defined(CONFIG_TOUCHSCREEN_GT801_IIC)
#include "../../../drivers/input/touchscreen/gt801_ts.h"
#define GT801_GPIO_INT RK29_PIN4_PD5
#define GT801_GPIO_RESET RK29_PIN6_PC3
static struct gt801_platform_data gt801_info = {
.model = 801,
.swap_xy = 0,
.x_min = 0,
.x_max = 480,
.y_min = 0,
.y_max = 800,
.gpio_reset = GT801_GPIO_RESET,
.gpio_reset_active_low = 1,
.gpio_pendown = GT801_GPIO_INT,
.pendown_iomux_name = GPIO4D5_CPUTRACECTL_NAME,
.resetpin_iomux_name = NULL,
.pendown_iomux_mode = GPIO4H_GPIO4D5,
.resetpin_iomux_mode = 0,
};
#endif
/* EETI_EGALAX touch I2C */
#if defined (CONFIG_EETI_EGALAX)
#define TOUCH_RESET_PIN RK29_PIN6_PC3
#define TOUCH_INT_PIN RK29_PIN4_PD5
@ -391,6 +415,31 @@ static struct eeti_egalax_platform_data eeti_egalax_info = {
};
#endif
/* GT801 touch I2C */
#if defined (CONFIG_GT801)
#include <drivers/input/touchscreen/gt801.h>
#define TOUCH_RESET_PIN RK29_PIN6_PC3
#define TOUCH_INT_PIN RK29_PIN4_PD5
static struct gt801_platform_data gt801_info = {
.model = 801,
.swap_xy = 0,
.x_min = 0,
.x_max = 480,
.y_min = 0,
.y_max = 800,
.gpio_reset = TOUCH_RESET_PIN,
.gpio_reset_active_low = 1,
.gpio_pendown = TOUCH_INT_PIN,
.pendown_iomux_name = GPIO4D5_CPUTRACECTL_NAME,
.resetpin_iomux_name = "FFF",
.pendown_iomux_mode = GPIO4H_GPIO4D5,
.resetpin_iomux_mode = 0,
.get_pendown_state = NULL,
};
#endif
/*MMA8452 gsensor*/
#if defined (CONFIG_GS_MMA8452)
#define MMA8452_INT_PIN RK29_PIN6_PC4
@ -1403,6 +1452,24 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
#ifdef CONFIG_I2C2_RK29
static struct i2c_board_info __initdata board_i2c2_devices[] = {
#if defined (CONFIG_TOUCHSCREEN_GT801_IIC)
{
.type = "gt801_ts",
.addr = 0x55,
.flags = 0,
.irq = RK29_PIN4_PD5,
.platform_data = &gt801_info,
},
#endif
#if defined (CONFIG_GT801)
{
.type = "gt801_touch",
.addr = 0x55,
.flags = 0,
.irq = RK29_PIN4_PD5,
.platform_data = &gt801_info,
},
#endif
#if defined (CONFIG_MFD_WM831X_I2C)
{
.type = "wm8310",

View File

@ -37,6 +37,7 @@
/* bit 0 is free */
#define RATE_FIXED (1 << 1) /* Fixed clock rate */
#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
#define IS_PD (1 << 2) /* Power Domain */
#define cru_readl(offset) readl(RK29_CRU_BASE + offset)
#define cru_writel(v, offset) writel(v, RK29_CRU_BASE + offset)
@ -201,7 +202,7 @@ static int gate_mode(struct clk *clk, int on)
v = cru_readl(reg);
if (on)
v &= ~(1 << idx); // clear bit
v &= ~(1 << idx); // clear bit
else
v |= (1 << idx); // set bit
@ -1600,12 +1601,16 @@ static struct clk aclk_gpu = {
};
static struct clk vip_clkin = {
.name = "vip_clkin",
};
static struct clk *clk_vip_parents[4] = { &xin24m, &xin27m, &dclk_ebook };
static struct clk clk_vip = {
.name = "vip",
static struct clk clk_vip_out = {
.name = "vip_out",
.mode = gate_mode,
.gate_idx = CLK_GATE_VIP,
.gate_idx = CLK_GATE_VIP_OUT,
.clksel_con = CRU_CLKSEL1_CON,
.clksel_parent_mask = 3,
.clksel_parent_shift = 7,
@ -1673,7 +1678,7 @@ GATE_CLK(wdt, pclk_periph, WDT);
GATE_CLK(pwm, pclk_periph, PWM);
GATE_CLK(vip_bus, aclk_cpu, VIP_BUS);
GATE_CLK(vip_matrix, clk_vip_bus, VIP_MATRIX);
GATE_CLK(vip_input, hclk_cpu, VIP_INPUT);
GATE_CLK(vip_input, vip_clkin, VIP_INPUT);
GATE_CLK(jtag, aclk_cpu, JTAG);
GATE_CLK(aclk_ddr_lcdc, aclk_lcdc, ACLK_DDR_LCDC);
@ -1693,6 +1698,101 @@ GATE_CLK(hclk_mmc0, hclk_periph, HCLK_MMC0);
GATE_CLK(hclk_mmc1, hclk_periph, HCLK_MMC1);
GATE_CLK(hclk_emmc, hclk_periph, HCLK_EMMC);
static int pd_vcodec_mode(struct clk *clk, int on)
{
if (on) {
u32 gate;
gate = cru_clkgate3_con_mirror;
gate |= (1 << CLK_GATE_ACLK_DDR_VEPU % 32);
gate &= ~((1 << CLK_GATE_ACLK_VEPU % 32)
| (1 << CLK_GATE_HCLK_VEPU % 32)
| (1 << CLK_GATE_HCLK_CPU_VCODEC % 32));
cru_writel(gate, CRU_CLKGATE3_CON);
pmu_set_power_domain(PD_VCODEC, true);
udelay(10);
cru_writel(cru_clkgate3_con_mirror, CRU_CLKGATE3_CON);
} else {
pmu_set_power_domain(PD_VCODEC, false);
}
return 0;
}
static struct clk pd_vcodec = {
.name = "pd_vcodec",
.flags = IS_PD,
.mode = pd_vcodec_mode,
};
static int pd_display_mode(struct clk *clk, int on)
{
if (on) {
u32 gate, gate2;
gate = cru_clkgate3_con_mirror;
gate |= (1 << CLK_GATE_ACLK_DDR_LCDC % 32);
gate &= ~((1 << CLK_GATE_HCLK_CPU_DISPLAY % 32)
| (1 << CLK_GATE_HCLK_DISP_MATRIX % 32)
| (1 << CLK_GATE_ACLK_DISP_MATRIX % 32)
| (1 << CLK_GATE_DCLK_EBOOK % 32)
| (1 << CLK_GATE_HCLK_EBOOK % 32)
| (1 << CLK_GATE_HCLK_IPP % 32)
| (1 << CLK_GATE_ACLK_IPP % 32)
| (1 << CLK_GATE_DCLK_LCDC % 32)
| (1 << CLK_GATE_HCLK_LCDC % 32)
| (1 << CLK_GATE_ACLK_LCDC % 32));
cru_writel(gate, CRU_CLKGATE3_CON);
gate2 = cru_readl(CRU_CLKGATE2_CON);
gate = gate2;
gate &= ~((1 << CLK_GATE_VIP_OUT % 32)
| (1 << CLK_GATE_VIP_SLAVE % 32)
| (1 << CLK_GATE_VIP_MATRIX % 32)
| (1 << CLK_GATE_VIP_BUS % 32));
cru_writel(gate, CRU_CLKGATE2_CON);
pmu_set_power_domain(PD_DISPLAY, true);
udelay(10);
cru_writel(gate2, CRU_CLKGATE2_CON);
cru_writel(cru_clkgate3_con_mirror, CRU_CLKGATE3_CON);
} else {
pmu_set_power_domain(PD_DISPLAY, false);
}
return 0;
}
static struct clk pd_display = {
.name = "pd_display",
.flags = IS_PD,
.mode = pd_display_mode,
};
static int pd_gpu_mode(struct clk *clk, int on)
{
if (on) {
pmu_set_power_domain(PD_GPU, true);
} else {
pmu_set_power_domain(PD_GPU, false);
}
return 0;
}
static struct clk pd_gpu = {
.name = "pd_gpu",
.flags = IS_PD,
.mode = pd_gpu_mode,
};
#define CLK(dev, con, ck) \
{ \
.dev_id = dev, \
@ -1713,6 +1813,7 @@ static struct clk_lookup clks[] = {
CLK(NULL, "otgphy0_clkin", &otgphy0_clkin),
CLK(NULL, "otgphy1_clkin", &otgphy1_clkin),
CLK(NULL, "gpsclk", &gpsclk),
CLK(NULL, "vip_clkin", &vip_clkin),
CLK1(12m),
CLK(NULL, "arm_pll", &arm_pll_clk),
@ -1729,7 +1830,7 @@ static struct clk_lookup clks[] = {
CLK(NULL, "hclk_periph", &hclk_periph),
CLK(NULL, "pclk_periph", &pclk_periph),
CLK1(vip),
CLK1(vip_out),
CLK1(otgphy0),
CLK1(otgphy1),
CLK1(uhost),
@ -1869,6 +1970,10 @@ static struct clk_lookup clks[] = {
CLK1(hclk_gpu),
CLK1(hclk_cpu_vcodec),
CLK1(hclk_cpu_display),
CLK(NULL, "pd_vcodec", &pd_vcodec),
CLK(NULL, "pd_display", &pd_display),
CLK(NULL, "pd_gpu", &pd_gpu),
};
static LIST_HEAD(clocks);
@ -2190,7 +2295,7 @@ static int clk_register(struct clk *clk)
return 0;
}
static unsigned int __initdata armclk = 600 * MHZ;
static unsigned int __initdata armclk = 300 * MHZ;
/*
* You can override arm_clk rate with armclk= cmdline option.
@ -2278,7 +2383,7 @@ static int __init clk_disable_unused(void)
struct clk *ck;
list_for_each_entry(ck, &clocks, node) {
if (ck->usecount > 0 || ck->mode == NULL)
if (ck->usecount > 0 || ck->mode == NULL || (ck->flags & IS_PD))
continue;
LOCK();
@ -2353,7 +2458,7 @@ static void dump_clock(struct seq_file *s, struct clk *clk, int deep)
v = cru_clkgate3_con_mirror & (1 << idx);
else
v = cru_readl(reg) & (1 << idx);
seq_printf(s, "%s ", v ? "off" : "on ");
}

View File

@ -194,7 +194,6 @@ struct it7260_platform_data {
void (*exit_platform_hw)(void);
};
struct akm8975_platform_data {
char layouts[3][3];
char project_name[64];
@ -202,9 +201,9 @@ struct akm8975_platform_data {
};
struct rk29_gpio_expander_info {
unsigned int gpio_num;// 初始化的pin 脚宏定义 如rk29_PIN_PI0
unsigned int pin_type;//初始化的pin 为输入pin还是输出pin 如:GPIO_IN
unsigned int pin_value;//如果为 output pin 设置电平,如:GPIO_HIGH
unsigned int gpio_num;
unsigned int pin_type;//GPIO_IN or GPIO_OUT
unsigned int pin_value;//GPIO_HIGH or GPIO_LOW
};
struct tca6424_platform_data {
@ -214,8 +213,8 @@ struct tca6424_platform_data {
/* the first gpio irq number in all of irq source */
unsigned int gpio_irq_start;
unsigned int irq_pin_num; //中断的个数
unsigned int tca6424_irq_pin; //扩展IO的中断挂在哪个gpio
unsigned int irq_pin_num; //number of interrupt
unsigned int tca6424_irq_pin; //rk29 gpio
unsigned int expand_port_group;
unsigned int expand_port_pinnum;
unsigned int rk_irq_mode;

View File

@ -106,7 +106,7 @@ enum cru_clk_gate
CLK_GATE_PWM,
CLK_GATE_VIP_BUS,
CLK_GATE_VIP_MATRIX,
CLK_GATE_VIP,
CLK_GATE_VIP_OUT,
CLK_GATE_VIP_INPUT,
CLK_GATE_JTAG,

View File

@ -0,0 +1,27 @@
/* arch/arm/mach-rk29/include/mach/ddr.h
*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_RK29_DDR_H
#define __ARCH_ARM_MACH_RK29_DDR_H
#include <linux/types.h>
#include <mach/sram.h>
void __sramfunc ddr_suspend(void);
void __sramfunc ddr_resume(void);
void __sramlocalfunc delayus(uint32_t us);
void __sramfunc ddr_change_freq(uint32_t nMHz);
#endif

View File

@ -7,6 +7,8 @@
* Author: Rickard Andersson <rickard.andersson@stericsson.com>
*/
#ifndef __ARCH_ARM_MACH_RK29_SRAM_H
#define __ARCH_ARM_MACH_RK29_SRAM_H
#ifdef CONFIG_ARCH_RK29
/* Tag variables with this */
@ -34,4 +36,5 @@ static inline unsigned long ddr_save_sp(unsigned long new_sp)
#define DDR_RESTORE_SP(save_sp) do { ddr_save_sp(save_sp); } while (0)
#endif
#endif

View File

@ -24,6 +24,7 @@
#include <mach/system.h>
#include <mach/sram.h>
#include <mach/gpio.h>
#include <mach/ddr.h>
#define cru_readl(offset) readl(RK29_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel(v, RK29_CRU_BASE + offset); readl(RK29_CRU_BASE + offset); } while (0)
@ -44,11 +45,6 @@ static inline void delay_300us(void)
LOOP(300 * LOOPS_PER_USEC);
}
extern void ddr_suspend(void);
extern void ddr_resume(void);
extern void delayus(uint32_t us);
extern void ddr_change_freq(uint32_t nMHz);
#ifdef DEBUG
static void/* inline*/ __sramfunc printch(char byte)
{

View File

@ -70,7 +70,8 @@ static void pwm2gpiodefault(void)
*pGRF_GPIO2L_IOMUX &= ~(0x3<<6);
// set gpio to input
*pGPIO2_DIR &= ~(0x1<<3);
// testflag =1;
memset(RK29_PWM_BASE, 0, 0x40);
}
@ -93,24 +94,22 @@ void rk29_arch_reset(int mode, const char *cmd)
{
u32 reg;
local_irq_disable();
local_fiq_disable();
cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);
delay_500ns();
/* from panic? */
if (system_state != SYSTEM_RESTART)
machine_power_off();
local_irq_disable();
local_fiq_disable();
pwm2gpiodefault();
cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);
delay_500ns();
cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | CRU_GENERAL_MODE_SLOW, CRU_MODE_CON);
delay_500ns();
cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | CRU_CODEC_MODE_SLOW, CRU_MODE_CON);
delay_500ns();
cru_writel(0, CRU_CLKGATE0_CON);

View File

@ -95,9 +95,12 @@ static void rk29_timer_set_mode(enum clock_event_mode mode, struct clock_event_d
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
RK_TIMER_DISABLE(TIMER_CLKEVT);
RK_TIMER_SETCOUNT(TIMER_CLKEVT, 24000000/HZ - 1);
RK_TIMER_ENABLE(TIMER_CLKEVT);
do {
RK_TIMER_DISABLE(TIMER_CLKEVT);
RK_TIMER_SETCOUNT(TIMER_CLKEVT, 24000000/HZ - 1);
RK_TIMER_ENABLE(TIMER_CLKEVT);
} while (RK_TIMER_READVALUE(TIMER_CLKEVT) > (24000000/HZ - 1));
break;
case CLOCK_EVT_MODE_RESUME:
case CLOCK_EVT_MODE_ONESHOT:
break;

View File

@ -125,7 +125,7 @@ adc_sync_read_callback(struct adc_client *client, void *param, int result)
int adc_sync_read(struct adc_client *client)
{
struct adc_request *req = NULL;
int err, tmo;
int err, tmo, tail;
if(client == NULL) {
printk(KERN_ERR "client point is NULL");
@ -144,6 +144,7 @@ int adc_sync_read(struct adc_client *client)
req->callback = adc_sync_read_callback;
req->callback_param = req;
req->client = client;
req->status = SYNC_READ;
init_completion(&req->completion);
err = adc_enqueue_request(client->adc, req);
@ -154,8 +155,14 @@ int adc_sync_read(struct adc_client *client)
return err;
}
tmo = wait_for_completion_timeout(&req->completion,msecs_to_jiffies(100));
if(tmo == 0)
kfree(req);
req = NULL;
if(tmo == 0) {
tail = (client->adc->queue_tail - 1) & (MAX_ADC_FIFO_DEPTH - 1);
client->adc->queue[tail] = NULL;
client->adc->queue_tail = tail;
return -ETIMEDOUT;
}
return client->result;
}
EXPORT_SYMBOL(adc_sync_read);
@ -181,6 +188,7 @@ int adc_async_read(struct adc_client *client)
req->callback = client->callback;
req->callback_param = client->callback_param;
req->client = client;
req->status = ASYNC_READ;
return adc_enqueue_request(client->adc, req);
}
@ -206,7 +214,10 @@ void adc_core_irq_handle(struct adc_host *adc)
trigger_next_adc_job_if_any(adc);
req->callback(adc->cur, req->callback_param, res);
kfree(req);
if(req->status == ASYNC_READ) {
kfree(req);
req = NULL;
}
}
EXPORT_SYMBOL(adc_core_irq_handle);

View File

@ -66,31 +66,50 @@ static const struct adc_ops rk29_adc_ops = {
.read = rk29_adc_read,
};
#ifdef ADC_TEST
struct adc_test_data {
struct adc_client *client;
struct timer_list timer;
struct work_struct timer_work;
};
static void callback(struct adc_client *client, void *param, int result)
{
dev_info(client->adc->dev, "[chn%d] async_read = %d\n", client->chn, result);
return;
}
static void adc_timer(unsigned long data)
{
//int sync_read = 0;
struct adc_test_data *test=(struct adc_test_data *)data;
//sync_read = adc_sync_read(test->client);
//dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);
schedule_work(&test->timer_work);
add_timer(&test->timer);
}
static void adc_timer_work(struct work_struct *work)
{
int sync_read = 0;
struct adc_test_data *test = container_of(work, struct adc_test_data,
timer_work);
adc_async_read(test->client);
sync_read = adc_sync_read(test->client);
dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);
}
static int rk29_adc_test(void)
{
int sync_read = 0, i, j = 10;
struct adc_client *client =NULL;
struct adc_test_data *test = NULL;
while(j--)
{
client = adc_register(i, callback, NULL);
adc_async_read(client);
mdelay(1000);
sync_read = adc_sync_read(client);
dev_info(client->adc->dev, "[chn%d] sync_read = %d\n", client->chn, sync_read);
adc_unregister(client);
mdelay(1000);
i++;
if(i >= 4)
i = 0;
}
adc_unregister(client);
test = kzalloc(sizeof(struct adc_test_data), GFP_KERNEL);
test->client = adc_register(0, callback, NULL);
INIT_WORK(&test->timer_work, adc_timer_work);
setup_timer(&test->timer, adc_timer, (unsigned long)test);
test->timer.expires = jiffies + 100;
add_timer(&test->timer);
return 0;
}
#endif
@ -157,9 +176,6 @@ static int rk29_adc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, dev);
dev_info(&pdev->dev, "rk29 adc: driver initialized\n");
#ifdef ADC_TEST
rk29_adc_test();
#endif
return 0;
// err_iomap:
// iounmap(dev->regs);
@ -243,4 +259,12 @@ module_exit(rk29_adc_exit);
MODULE_DESCRIPTION("Driver for ADC");
MODULE_AUTHOR("kfx, kfx@rock-chips.com");
MODULE_LICENSE("GPL");
static int __init adc_test_init(void)
{
#ifdef ADC_TEST
rk29_adc_test();
#endif
return 0;
}
module_init(adc_test_init);

View File

@ -48,24 +48,19 @@ static int vflash_ioctl(struct inode *inode, struct file *file,
case READ_BDADDR_FROM_FLASH:
{
char *tempBuf = (char *)kmalloc(512, GFP_KERNEL);
char bd_addr[6] = {0};
int i;
#if 0
GetSNSectorInfo(tempBuf);
#else
tempBuf[498] = 0x00;
tempBuf[499] = 0x11;
tempBuf[500] = 0x22;
tempBuf[501] = 0x33;
tempBuf[502] = 0x44;
tempBuf[503] = 0x55;
tempBuf[504] = 0x66;
#endif
for(i=498; i<=504; i++)
{
DBG("tempBuf[%d]=%x\n", i, tempBuf[i]);
bd_addr[504-i] = tempBuf[i];
}
if(copy_to_user(argp, &(tempBuf[499]), 6))
if(copy_to_user(argp, bd_addr, 6))
{
printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
kfree(tempBuf);

View File

@ -184,6 +184,7 @@ static void rk29_i2c_clockrate(struct rk29_i2c_data *i2c)
rk29_i2c_calcdivisor(i2c->i2c_rate, scl_rate, &real_rate, &rem, &exp);
tmp = readl(i2c->regs + I2C_OPR);
tmp &= ~0x3f;
tmp |= exp;
tmp |= rem<<I2CCDVR_EXP_BITS;
writel(tmp, i2c->regs + I2C_OPR);

View File

@ -13,7 +13,7 @@ if INPUT_TOUCHSCREEN
config TOUCHSCREEN_XPT2046_SPI
tristate "XPT2046 based touchscreens:SPI Interface"
depends on SPIM_RK29
depends on SPIM_RK2818 || SPIM_RK29
config TOUCHSCREEN_XPT2046_NORMAL_SPI
tristate "normal mode"
@ -63,31 +63,6 @@ config TOUCHSCREEN_XPT2046_SPI
tristate "320X480 resolution"
depends on TOUCHSCREEN_XPT2046_CBN_SPI
#choice
# prompt "XPT2046 based touchscreens: SPI Interface"
# default TOUCHSCREEN_XPT2046_CBN_SPI
# config TOUCHSCREEN_XPT2046_SPI_NOCHOOSE
# bool "DO NOT CHOOSE TOUCHSCREEN_XPT2046"
# config TOUCHSCREEN_XPT2046_SPI
# bool "800X480 TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_CBN_SPI
# bool "800X480 CALIBRATION TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_320X480_SPI
# bool "320X480 TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
# config TOUCHSCREEN_XPT2046_320X480_CBN_SPI
# bool "320X480 CALIBRATION TOUCHSCREEN"
# depends on SPIM_RK2818 || SPIM_RK29
#endchoice
config TOUCHSCREEN_ADS7846
tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
depends on SPI_MASTER
@ -119,8 +94,6 @@ config TOUCHSCREEN_AD7877
To compile this driver as a module, choose M here: the
module will be called ad7877.
config RK28_I2C_TS_NTP070
tristate "NTP070 based touchscreens: NTP070 Interface"
depends on I2C_RK2818
@ -742,4 +715,8 @@ config TOUCHSCREEN_IT7260
If unsure, say N (but it's safe to say "Y").
config TOUCHSCREEN_GT801_IIC
tristate "GT801_IIC based touchscreens"
depends on I2C2_RK29
endif

View File

@ -53,3 +53,5 @@ obj-$(CONFIG_TOUCHSCREEN_IT7260) += it7260_ts.o
obj-$(CONFIG_SINTEK_3FA16) += sintek_3FA16.o
obj-$(CONFIG_EETI_EGALAX) += eeti_egalax_i2c.o
obj-$(CONFIG_ATMEL_MXT224) += atmel_mxt224.o
obj-$(CONFIG_TOUCHSCREEN_GT801_IIC) += gt801_ts.o

View File

@ -0,0 +1,644 @@
/*
* drivers/input/touchscreen/gt801_ts.c
*
* Copyright (C) 2010 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include "gt801_ts.h"
#define GT801_DEBUG 0
#if GT801_DEBUG
#define gt801printk(msg...) printk(msg);
#else
#define gt801printk(msg...)
#endif
#define SINGLTOUCH_MODE 0
#define GT801_REGS_NUM 53
#if SINGLTOUCH_MODE
#define TOUCH_NUMBER 1
#else
#define TOUCH_NUMBER 2
#endif
#define TOUCH_REG_NUM 5 //每组坐标需要的寄存器数目
const unsigned char GT801_RegData[GT801_REGS_NUM]={
0x19,0x05,0x06,0x28,0x02,0x14,0x14,0x10,0x40,0xB0,0x01,0xE0,0x03,0x4C,0x78,0x9A,0xBC,0xDE,0x65,0x43,0x20,0x11,0x00,0x00,0x00,0x00,0x05,0xCF,0x20,0x0B,0x0D,0x8D,0x32,0x3C,0x1E,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
};
struct gt801_ts_data {
u16 model; /* 801. */
bool swap_xy; /* swap x and y axes */
u16 x_min, x_max;
u16 y_min, y_max;
uint16_t addr;
int use_irq;
int gpio_pendown;
int gpio_reset;
int gpio_reset_active_low;
int pendown_iomux_mode;
int resetpin_iomux_mode;
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
char phys[32];
char name[32];
struct i2c_client *client;
struct input_dev *input_dev;
struct hrtimer timer;
struct work_struct work;
struct early_suspend early_suspend;
};
/*tochscreen private data*/
static int touch_state[TOUCH_NUMBER] = {TOUCH_UP,TOUCH_UP};
static struct workqueue_struct *gt801_wq;
#ifdef CONFIG_HAS_EARLYSUSPEND
static void gt801_ts_early_suspend(struct early_suspend *h);
static void gt801_ts_late_resume(struct early_suspend *h);
#endif
static int verify_coord(struct gt801_ts_data *ts,unsigned short *x,unsigned short *y)
{
gt801printk("%s:(%d/%d)\n",__FUNCTION__,*x, *y);
if((*x< ts->x_min) || (*x > ts->x_max))
return -1;
if((*y< ts->y_min) || (*y > ts->y_max))
return -1;
// *x = ts->x_max - *x;
//if(*y <780)
*y = ts->y_max -*y;
return 0;
}
/*read the gt801 register ,used i2c bus*/
static int gt801_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
{
int ret;
ret =i2c_master_reg8_recv(client, reg, buf, len, 200*1000);
if(ret < 0)
printk("gt801_ts_work_func:i2c_transfer fail =%d\n",ret);
return ret;
}
/* set the gt801 registe,used i2c bus*/
static int gt801_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
{
int ret;
ret = i2c_master_reg8_send(client,reg, buf, len, 200*1000);
if (ret < 0) {
printk("gt801_ts_work_func:i2c_transfer fail =%d\n",ret);
}
return ret;
}
static int gt801_init_panel(struct gt801_ts_data *ts)
{
return 0;
}
static void gt801_ts_work_func(struct work_struct *work)
{
#if SINGLTOUCH_MODE
#else
int touch_state_index = 0;
#endif
unsigned char start_reg = 0x02;
unsigned char buf[TOUCH_NUMBER*TOUCH_REG_NUM];
unsigned short x;
unsigned short y;
int i,ret;
int syn_flag = 0;
int bufLen = TOUCH_NUMBER*TOUCH_REG_NUM;
struct gt801_ts_data *ts = container_of(work, struct gt801_ts_data, work);
gt801printk("%s\n",__FUNCTION__);
ret=gt801_read_regs(ts->client, start_reg, buf,bufLen);
if (ret < 0) {
printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,ret);
if (ts->use_irq)
enable_irq(ts->client->irq);
return;
}
#if SINGLTOUCH_MODE
i = 0;
if(buf[i+ptpressure] == 0)
{
gt801printk(" realse ts_dev->point.x=%d ,ts_dev->point.y=%d \n",ts->point.x,ts->point.y);
if (touch_state[i] == TOUCH_DOWN)
{
input_report_key(ts->input_dev,BTN_TOUCH,0);
syn_flag = 1;
touch_state[i] = TOUCH_UP;
gt801printk("SINGLTOUCH_MODE up\n");
}
}
else
{
x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]);
y= (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]);
if (ts->swap_xy)
swap(x, y);
if (verify_coord(ts,&x,&y))
goto out;
if (touch_state[i] == TOUCH_UP)
{
gt801printk("SINGLTOUCH_MODE down\n");
input_report_key(ts->input_dev,BTN_TOUCH,1);
touch_state[i] = TOUCH_DOWN;
}
gt801printk("input_report_abs(%d/%d)\n",x,y);
input_report_abs(ts->input_dev,ABS_X,x );
input_report_abs(ts->input_dev,ABS_Y,y );
syn_flag = 1;
}
#else
for(i=0; i<bufLen; i+=TOUCH_REG_NUM)
{
if(buf[i+ptpressure] == 0){
gt801printk("%s:buf=%d touch up\n",__FUNCTION__,buf[i+ptpressure]);
if (touch_state[touch_state_index] == TOUCH_DOWN)
{
gt801printk("%s:%d touch up\n",__FUNCTION__,i);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size
input_mt_sync(ts->input_dev);
syn_flag =1;
touch_state[touch_state_index] = TOUCH_UP;
}
}
else{
x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]);
y= (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]);
if (ts->swap_xy)
swap(x, y);
if (verify_coord(ts,&x,&y))
;//goto out;
gt801printk("input_report_abs--%d-%d-(%d/%d)\n", i,touch_state_index, x, y);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size
input_mt_sync(ts->input_dev);
syn_flag = 1;
touch_state[touch_state_index] = TOUCH_DOWN;
}
touch_state_index++;
}
#endif
if(syn_flag)
input_sync(ts->input_dev);
out:
if (ts->use_irq)
enable_irq(ts->client->irq);
return;
}
static enum hrtimer_restart gt801_ts_timer_func(struct hrtimer *timer)
{
struct gt801_ts_data *ts = container_of(timer, struct gt801_ts_data, timer);
gt801printk("%s\n",__FUNCTION__);
queue_work(gt801_wq, &ts->work);
hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
static irqreturn_t gt801_ts_irq_handler(int irq, void *dev_id)
{
struct gt801_ts_data *ts = dev_id;
gt801printk("%s=%d,%d\n",__FUNCTION__,ts->client->irq,ts->use_irq);
//if (ts->use_irq)
disable_irq_nosync(ts->client->irq);
queue_work(gt801_wq, &ts->work);
return IRQ_HANDLED;
}
static int __devinit setup_resetPin(struct i2c_client *client, struct gt801_ts_data *ts)
{
struct gt801_platform_data *pdata = client->dev.platform_data;
int err;
ts->gpio_reset = pdata->gpio_reset;
ts->gpio_reset_active_low = pdata->gpio_reset_active_low;
ts->resetpin_iomux_mode = pdata->resetpin_iomux_mode;
if(pdata->resetpin_iomux_name != NULL)
strcpy(ts->resetpin_iomux_name,pdata->resetpin_iomux_name);
gt801printk("%s=%d,%s,%d,%d\n",__FUNCTION__,ts->gpio_reset,ts->resetpin_iomux_name,ts->resetpin_iomux_mode,ts->gpio_reset_active_low);
if (!gpio_is_valid(ts->gpio_reset)) {
dev_err(&client->dev, "no gpio_reset?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->resetpin_iomux_name,ts->resetpin_iomux_mode);
err = gpio_request(ts->gpio_reset, "gt801_resetPin");
if (err) {
dev_err(&client->dev, "failed to request resetPin GPIO%d\n",
ts->gpio_reset);
return err;
}
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
err = gpio_direction_output(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
if (err) {
dev_err(&client->dev, "failed to pulldown resetPin GPIO%d,err%d\n",
ts->gpio_reset,err);
gpio_free(ts->gpio_reset);
return err;
}
mdelay(100);
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
mdelay(100);
return 0;
}
static int __devinit setup_pendown(struct i2c_client *client, struct gt801_ts_data *ts)
{
int err;
struct gt801_platform_data *pdata = client->dev.platform_data;
if (!client->irq) {
dev_dbg(&client->dev, "no IRQ?\n");
return -ENODEV;
}
if (!gpio_is_valid(pdata->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
ts->gpio_pendown = pdata->gpio_pendown;
strcpy(ts->pendown_iomux_name,pdata->pendown_iomux_name);
ts->pendown_iomux_mode = pdata->pendown_iomux_mode;
gt801printk("%s=%d,%s,%d\n",__FUNCTION__,ts->gpio_pendown,ts->pendown_iomux_name,ts->pendown_iomux_mode);
if (!gpio_is_valid(ts->gpio_pendown)) {
dev_err(&client->dev, "no gpio_pendown?\n");
return -EINVAL;
}
rk29_mux_api_set(ts->pendown_iomux_name,ts->pendown_iomux_mode);
err = gpio_request(ts->gpio_pendown, "gt801_pendown");
if (err) {
dev_err(&client->dev, "failed to request pendown GPIO%d\n",
ts->gpio_pendown);
return err;
}
err = gpio_pull_updown(ts->gpio_pendown, GPIOPullUp);
if (err) {
dev_err(&client->dev, "failed to pullup pendown GPIO%d\n",
ts->gpio_pendown);
gpio_free(ts->gpio_pendown);
return err;
}
return 0;
}
static int gt801_chip_Init(struct i2c_client *client)
{
u8 i,j;
int ret=0;
u8 start_reg=0x30;
u8 buf[GT801_REGS_NUM];
gt801printk("enter gt801_chip_Init!!!!\n");
for(j=0;j<2;j++)
{
ret=gt801_write_regs(client,start_reg, GT801_RegData,GT801_REGS_NUM);
if(ret<0)
{
printk("\n--%s--Set Register values error !!!\n",__FUNCTION__);
}
ret=gt801_read_regs(client, start_reg, buf,GT801_REGS_NUM);
if(ret<0)
{
printk("\n--%s--Read Register values error !!!\n",__FUNCTION__);
}
for(i=0;i<GT801_REGS_NUM-1;i++)
{
if(buf[i]!=GT801_RegData[i])
{
printk("!!!!!!!!gt801_chip_Init err may be i2c errorat adress=%x var=%x i=%x\n",0x30+i, buf[i],i);
break;
}
}
if(i==GT801_REGS_NUM-1)
break;
else if(j==1)
return -1;
mdelay(500);
}
mdelay(100);
return ret;
}
static int gt801_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct gt801_ts_data *ts;
struct gt801_platform_data *pdata = client->dev.platform_data;
int ret = 0;
gt801printk("%s \n",__FUNCTION__);
if (!pdata) {
dev_err(&client->dev, "empty platform_data\n");
goto err_check_functionality_failed;
}
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk(KERN_ERR "gt801_ts_probe: need I2C_FUNC_I2C\n");
ret = -ENODEV;
goto err_check_functionality_failed;
}
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
if (ts == NULL) {
ret = -ENOMEM;
goto err_alloc_data_failed;
}
INIT_WORK(&ts->work, gt801_ts_work_func);
ts->client = client;
i2c_set_clientdata(client, ts);
ret = setup_resetPin(client,ts);
if(ret)
{
printk("%s:setup_resetPin fail\n",__FUNCTION__);
goto err_input_dev_alloc_failed;
}
ret=gt801_chip_Init(ts->client);
if(ret<0)
{
printk("%s:chips init failed\n",__FUNCTION__);
goto err_resetpin_failed;
}
/* allocate input device */
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
ret = -ENOMEM;
printk(KERN_ERR "%s: Failed to allocate input device\n",__FUNCTION__);
goto err_input_dev_alloc_failed;
}
ts->model = pdata->model ? : 801;
ts->swap_xy = pdata->swap_xy;
ts->x_min = pdata->x_min;
ts->x_max = pdata->x_max;
ts->y_min = pdata->y_min;
ts->y_max = pdata->y_max;
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev));
snprintf(ts->name, sizeof(ts->name), "gt%d-touchscreen", ts->model);
ts->input_dev->phys = ts->phys;
ts->input_dev->name = ts->name;
ts->input_dev->dev.parent = &client->dev;
#if SINGLTOUCH_MODE
ts->input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY);
ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(ts->input_dev,ABS_X,
ts->x_min ? : 0,
ts->x_max ? : 480,
0, 0);
input_set_abs_params(ts->input_dev,ABS_Y,
ts->y_min ? : 0,
ts->y_max ? : 800,
0, 0);
#else
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS);
// ts->input_dev->absbit[0] =
// BIT(ABS_MT_POSITION_X) | BIT(ABS_MT_POSITION_Y) |
// BIT(ABS_MT_TOUCH_MAJOR) | BIT(ABS_MT_WIDTH_MAJOR); // for android
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
ts->x_min ? : 0,
ts->x_max ? : 480,
0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
ts->y_min ? : 0,
ts->y_max ? : 800,
0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0); //Finger Size
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 10, 0, 0); //Touch Size
#endif
ret = input_register_device(ts->input_dev);
if (ret) {
printk(KERN_ERR "%s: Unable to register %s input device\n", __FUNCTION__,ts->input_dev->name);
goto err_input_register_device_failed;
}
client->irq = gpio_to_irq(client->irq);
if (client->irq) {
ret = setup_pendown(client,ts);
if(ret)
{
printk("%s:setup_pendown fail\n",__FUNCTION__);
goto err_input_register_device_failed;
}
ret = request_irq(client->irq, gt801_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW, client->name, ts);
if (ret == 0) {
gt801printk("%s:register ISR (irq=%d)\n", __FUNCTION__,client->irq);
ts->use_irq = 1;
}
else
dev_err(&client->dev, "request_irq failed\n");
}
if (!ts->use_irq) {
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ts->timer.function = gt801_ts_timer_func;
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
}
#ifdef CONFIG_HAS_EARLYSUSPEND
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ts->early_suspend.suspend = gt801_ts_early_suspend;
ts->early_suspend.resume = gt801_ts_late_resume;
register_early_suspend(&ts->early_suspend);
#endif
printk(KERN_INFO "%s: Start touchscreen %s in %s mode\n", __FUNCTION__,ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
return 0;
err_input_register_device_failed:
input_free_device(ts->input_dev);
err_resetpin_failed:
gpio_free(ts->gpio_reset);
err_input_dev_alloc_failed:
kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
return ret;
}
static int gt801_ts_remove(struct i2c_client *client)
{
struct gt801_ts_data *ts = i2c_get_clientdata(client);
unregister_early_suspend(&ts->early_suspend);
if (ts->use_irq)
free_irq(client->irq, ts);
else
hrtimer_cancel(&ts->timer);
input_unregister_device(ts->input_dev);
gpio_free(ts->gpio_pendown);
gpio_free(ts->gpio_reset);
kfree(ts);
return 0;
}
static int gt801_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
int ret;
struct gt801_ts_data *ts = i2c_get_clientdata(client);
printk("gt801 TS Suspend\n");
if (ts->use_irq)
disable_irq(client->irq);
else
hrtimer_cancel(&ts->timer);
ret = cancel_work_sync(&ts->work);
if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
enable_irq(client->irq);
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_LOW:GPIO_HIGH);
return 0;
}
static int gt801_ts_resume(struct i2c_client *client)
{
struct gt801_ts_data *ts = i2c_get_clientdata(client);
gt801_init_panel(ts);
printk("gt801 TS Resume\n");
gpio_set_value(ts->gpio_reset, ts->gpio_reset_active_low? GPIO_HIGH:GPIO_LOW);
if (ts->use_irq) {
printk("enabling IRQ %d\n", client->irq);
enable_irq(client->irq);
}
else
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void gt801_ts_early_suspend(struct early_suspend *h)
{
struct gt801_ts_data *ts;
ts = container_of(h, struct gt801_ts_data, early_suspend);
gt801_ts_suspend(ts->client, PMSG_SUSPEND);
}
static void gt801_ts_late_resume(struct early_suspend *h)
{
struct gt801_ts_data *ts;
ts = container_of(h, struct gt801_ts_data, early_suspend);
gt801_ts_resume(ts->client);
}
#endif
#define gt801_TS_NAME "gt801_ts"
static const struct i2c_device_id gt801_ts_id[] = {
{ gt801_TS_NAME, 0 },
{ }
};
static struct i2c_driver gt801_ts_driver = {
.probe = gt801_ts_probe,
.remove = gt801_ts_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = gt801_ts_suspend,
.resume = gt801_ts_resume,
#endif
.id_table = gt801_ts_id,
.driver = {
.name = gt801_TS_NAME,
},
};
static int __devinit gt801_ts_init(void)
{
printk("%s\n",__FUNCTION__);
gt801_wq = create_singlethread_workqueue("gt801_wq");
if (!gt801_wq)
return -ENOMEM;
return i2c_add_driver(&gt801_ts_driver);
}
static void __exit gt801_ts_exit(void)
{
printk("%s\n",__FUNCTION__);
i2c_del_driver(&gt801_ts_driver);
if (gt801_wq)
destroy_workqueue(gt801_wq);
}
module_init(gt801_ts_init);
module_exit(gt801_ts_exit);
MODULE_DESCRIPTION("gt801 Touchscreen Driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,45 @@
/*
* drivers/input/touchscreen/gt801_ts.h
*
* Copyright (C) 2010 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DRIVERS_TOUCHSCREEN_GT801_TS_H
#define __DRIVERS_TOUCHSCREEN_GT801_TS_H
#define IOMUX_NAME_SIZE 48
enum regadd {
ptxh = 0, ptxl = 1, ptyh = 2, ptyl = 3, ptpressure = 4,
};
enum touchstate {
TOUCH_UP = 0, TOUCH_DOWN = 1,
};
struct gt801_platform_data {
u16 model; /* 801. */
bool swap_xy; /* swap x and y axes */
u16 x_min, x_max;
u16 y_min, y_max;
int gpio_reset;
int gpio_reset_active_low;
int gpio_pendown; /* the GPIO used to decide the pendown */
char pendown_iomux_name[IOMUX_NAME_SIZE];
char resetpin_iomux_name[IOMUX_NAME_SIZE];
int pendown_iomux_mode;
int resetpin_iomux_mode;
int (*get_pendown_state)(void);
};
#endif

7
drivers/leds/Kconfig Normal file → Executable file
View File

@ -236,6 +236,13 @@ config LEDS_BD2802
This option enables support for BD2802GU RGB LED driver chips
accessed via the I2C bus.
config LEDS_ATT1272
tristate "LED driver for ATT1272 LED"
depends on LEDS_CLASS && I2C
help
This option enables support for ATT1272 LED driver chips
accessed via the I2C bus.
comment "LED Triggers"
config LEDS_TRIGGERS

1
drivers/leds/Makefile Normal file → Executable file
View File

@ -29,6 +29,7 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
obj-$(CONFIG_LEDS_ATT1272) += leds-att1272.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o

346
drivers/leds/leds-att1272.c Executable file
View File

@ -0,0 +1,346 @@
/*
* leds-att1272.c - LED Driver
*
* Copyright (C) 2011 Rockchips
* deng dalong <ddl@rock-chips.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 as
* published by the Free Software Foundation.
*
* Datasheet: http://www.rohm.com/products/databook/driver/pdf/att1272gu-e.pdf
*
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/leds-att1272.h>
static int debug;
module_param(debug, int, S_IRUGO|S_IWUSR);
#define dprintk(level, fmt, arg...) do { \
if (debug >= level) \
printk(KERN_WARNING"leds-att1272: " fmt , ## arg); } while (0)
#define LEDS_ATT1272_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
#define LEDS_ATT1272_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
struct att1272_led {
struct att1272_led_platform_data *pdata;
struct i2c_client *client;
struct rw_semaphore rwsem;
struct work_struct work;
/*
* Making led_classdev as array is not recommended, because array
* members prevent using 'container_of' macro. So repetitive works
* are needed.
*/
struct led_classdev cdev_led;
/* General attributes of LEDs */
int flash_safety_timeout;
int flash_safety_timeout_offset;
int movie_mode_current;
int movie_mode_current_offset;
int flash_to_movie_mode_ratio;
int flash_to_movie_mode_ratio_offset;
int flout_config;
int flout_config_offset;
};
static int att1272_write_byte(struct i2c_client *client, u8 reg, u8 val)
{
int err,cnt;
struct att1272_led *led = i2c_get_clientdata(client);
u8 buf[2];
struct i2c_msg msg[1];
gpio_set_value(led->pdata->en_gpio, 0);
buf[0] = reg & 0xFF;
buf[1] = val;
msg->addr = client->addr;
msg->flags = client->flags;
msg->buf = buf;
msg->len = sizeof(buf);
msg->scl_rate = 100000; /* ddl@rock-chips.com : 100kHz */
msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
cnt = 1;
err = -EAGAIN;
gpio_set_value(led->pdata->en_gpio, 1);
while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */
err = i2c_transfer(client->adapter, msg, 1);
if (err >= 0) {
err = 0;
goto att1272_write_byte_end;
} else {
LEDS_ATT1272_TR("\n write reg(0x%x, val:0x%x) failed, try to write again!\n",reg, val);
udelay(10);
}
}
att1272_write_byte_end:
gpio_set_value(led->pdata->en_gpio, 0);
return err;
}
#define att1272_CONTROL_ATTR(attr_name, name_str,reg_addr, attr_together) \
static ssize_t att1272_show_##attr_name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct att1272_led *led = i2c_get_clientdata(to_i2c_client(dev));\
ssize_t ret; \
LEDS_ATT1272_DG("%s enter\n",__FUNCTION__); \
down_read(&led->rwsem); \
ret = sprintf(buf, "0x%02x\n", led->attr_name); \
up_read(&led->rwsem); \
return ret; \
} \
static ssize_t att1272_store_##attr_name(struct device *dev, \
struct device_attribute *attr, const char *buf, size_t count) \
{ \
struct att1272_led *led = i2c_get_clientdata(to_i2c_client(dev));\
unsigned long val,val_w; \
int ret; \
if (!count) \
return -EINVAL; \
ret = strict_strtoul(buf, 16, &val); \
if (ret) \
return ret; \
down_write(&led->rwsem); \
val_w = (val<<led->attr_name##_offset); \
val_w |= (led->attr_together<<led->attr_together##_offset);\
LEDS_ATT1272_DG("%s enter, val:0x%x\n",__FUNCTION__,val_w); \
if (att1272_write_byte(led->client, reg_addr, (u8) val) == 0) { \
led->attr_name = val; \
} \
up_write(&led->rwsem); \
return count; \
} \
static struct device_attribute att1272_##attr_name##_attr = { \
.attr = { \
.name = name_str, \
.mode = 0644, \
.owner = THIS_MODULE \
}, \
.show = att1272_show_##attr_name, \
.store = att1272_store_##attr_name, \
};
att1272_CONTROL_ATTR(flash_safety_timeout, "flash_safety_timeout",0x00,movie_mode_current);
att1272_CONTROL_ATTR(flash_to_movie_mode_ratio, "flash_to_movie_mode_ratio",0x01,flout_config);
att1272_CONTROL_ATTR(flout_config, "flout_config",0x01,flash_to_movie_mode_ratio);
static struct device_attribute *att1272_attributes[] = {
&att1272_flash_safety_timeout_attr,
&att1272_flash_to_movie_mode_ratio_attr,
&att1272_flout_config_attr,
};
static void att1272_led_work(struct work_struct *work)
{
struct att1272_led *led = container_of(work, struct att1272_led, work);
att1272_write_byte(led->client, 0x00, (u8)(led->movie_mode_current<<led->movie_mode_current_offset));
LEDS_ATT1272_DG();
}
static void att1272_set_led_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct att1272_led *led =
container_of(led_cdev, struct att1272_led, cdev_led);
led->movie_mode_current = led->cdev_led.max_brightness - (value>led->cdev_led.max_brightness)?led->cdev_led.max_brightness:value;
schedule_work(&led->work);
}
static int att1272_set_led_blink(struct led_classdev *led_cdev,
unsigned long *delay_on, unsigned long *delay_off)
{
struct att1272_led *led =
container_of(led_cdev, struct att1272_led, cdev_led);
if (*delay_on == 0 || *delay_off == 0)
return -EINVAL;
schedule_work(&led->work);
return 0;
}
static int att1272_register_led_classdev(struct att1272_led *led)
{
int ret;
struct att1272_led_platform_data *pdata = led->client->dev.platform_data;
INIT_WORK(&led->work, att1272_led_work);
led->cdev_led.name = pdata->name;
led->cdev_led.brightness = LED_OFF;
led->cdev_led.max_brightness = 15;
led->cdev_led.brightness_set = att1272_set_led_brightness;
led->cdev_led.blink_set = att1272_set_led_blink;
ret = led_classdev_register(&led->client->dev, &led->cdev_led);
if (ret < 0) {
LEDS_ATT1272_TR("couldn't register LED %s\n",
led->cdev_led.name);
goto failed_unregister_led;
}
return 0;
failed_unregister_led:
return ret;
}
static void att1272_unregister_led_classdev(struct att1272_led *led)
{
cancel_work_sync(&led->work);
led_classdev_unregister(&led->cdev_led);
}
static int __devinit att1272_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct att1272_led *led;
struct att1272_led_platform_data *pdata;
int ret, i;
LEDS_ATT1272_DG("%s enter: client->addr:0x%x\n",__FUNCTION__,client->addr);
led = kzalloc(sizeof(struct att1272_led), GFP_KERNEL);
if (!led) {
LEDS_ATT1272_TR("failed to allocate driver data\n");
return -ENOMEM;
}
led->client = client;
pdata = led->pdata = client->dev.platform_data;
i2c_set_clientdata(client, led);
/* Configure EN GPIO */
if (gpio_request(pdata->en_gpio, "ATT1272_EN") < 0) {
LEDS_ATT1272_TR("request en_gpio(%d) is failed!\n",pdata->en_gpio);
goto failed_free;
}
gpio_direction_output(pdata->en_gpio, 0);
/* Detect att1272 */
printk("att1272 i2c write.....\n");
ret = att1272_write_byte(client, 0x01, 0x30);
ret |= att1272_write_byte(client, 0x00, 0x00);
if (ret < 0) {
LEDS_ATT1272_TR("failed to detect device\n");
goto failed_free;
}
/* Default attributes */
led->flash_safety_timeout = 0x00;
led->flash_safety_timeout_offset = 0x00;
led->movie_mode_current = 0x00;
led->movie_mode_current_offset = 0x04;
led->flash_to_movie_mode_ratio = 0x03;
led->flash_to_movie_mode_ratio_offset = 0x03;
led->flout_config = 0x00;
led->flout_config_offset = 0x04;
init_rwsem(&led->rwsem);
for (i = 0; i < ARRAY_SIZE(att1272_attributes); i++) {
ret = device_create_file(&led->client->dev,
att1272_attributes[i]);
if (ret) {
LEDS_ATT1272_TR("failed: sysfs file %s\n",
att1272_attributes[i]->attr.name);
goto failed_unregister_dev_file;
}
}
ret = att1272_register_led_classdev(led);
if (ret < 0)
goto failed_unregister_dev_file;
return 0;
failed_unregister_dev_file:
for (i--; i >= 0; i--)
device_remove_file(&led->client->dev, att1272_attributes[i]);
failed_free:
i2c_set_clientdata(client, NULL);
kfree(led);
return ret;
}
static int __exit att1272_remove(struct i2c_client *client)
{
struct att1272_led *led = i2c_get_clientdata(client);
int i;
gpio_set_value(led->pdata->en_gpio, 0);
att1272_unregister_led_classdev(led);
for (i = 0; i < ARRAY_SIZE(att1272_attributes); i++)
device_remove_file(&led->client->dev, att1272_attributes[i]);
i2c_set_clientdata(client, NULL);
kfree(led);
return 0;
}
static int att1272_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct att1272_led *led = i2c_get_clientdata(client);
return 0;
}
static int att1272_resume(struct i2c_client *client)
{
struct att1272_led *led = i2c_get_clientdata(client);
return 0;
}
static const struct i2c_device_id att1272_id[] = {
{ "att1272", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, att1272_id);
static struct i2c_driver att1272_i2c_driver = {
.driver = {
.name = "att1272",
},
.probe = att1272_probe,
.remove = __exit_p(att1272_remove),
.suspend = att1272_suspend,
.resume = att1272_resume,
.id_table = att1272_id,
};
static int __init att1272_init(void)
{
return i2c_add_driver(&att1272_i2c_driver);
}
module_init(att1272_init);
static void __exit att1272_exit(void)
{
i2c_del_driver(&att1272_i2c_driver);
}
module_exit(att1272_exit);
MODULE_AUTHOR("deng dalong <ddl@rock-chips.com>");
MODULE_DESCRIPTION("att1272 LED driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,13 @@ struct reginfo
{
u16 reg;
u16 val;
u16 reg_len;
u16 rev;
};
#define WORD_LEN 0x04
#define BYTE_LEN 0x02
#define SEQUENCE_INIT 0x00
#define SEQUENCE_NORMAL 0x01
#define SEQUENCE_CAPTURE 0x02

View File

@ -2810,11 +2810,9 @@ static int sensor_video_probe(struct soc_camera_device *icd,
icd->formats = sensor_colour_formats;
icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return 0;
sensor_video_probe_err:
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return ret;
}
static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)

View File

@ -2628,11 +2628,11 @@ static int sensor_video_probe(struct soc_camera_device *icd,
icd->formats = sensor_colour_formats;
icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return 0;
sensor_video_probe_err:
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return ret;
}

View File

@ -5387,11 +5387,11 @@ static int sensor_video_probe(struct soc_camera_device *icd,
icd->formats = sensor_colour_formats;
icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return 0;
sensor_video_probe_err:
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return ret;
}
static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)

View File

@ -207,7 +207,7 @@ struct rk29_camera_dev
struct clk *hclk_cpu_display;
struct clk *vip_slave;
struct clk *vip;
struct clk *vip_out;
struct clk *vip_input;
struct clk *vip_bus;
@ -263,8 +263,13 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
/* planar capture requires Y, U and V buffers to be page aligned */
#if 0
*size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel); /* Y pages UV pages, yuv422*/
pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel);
#else
*size = PAGE_ALIGN((icd->user_width* icd->user_height * icd->current_fmt->depth + 7)>>3); /* Y pages UV pages, yuv422*/
pcdev->vipmem_bsize = PAGE_ALIGN((pcdev->host_width * pcdev->host_height * icd->current_fmt->depth + 7)>>3);
#endif
if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) {
@ -612,9 +617,9 @@ static int rk29_camera_activate(struct rk29_camera_dev *pcdev, struct soc_camera
RK29CAMERA_DG("%s..%d.. \n",__FUNCTION__,__LINE__);
if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix || !pcdev->hclk_cpu_display ||
!pcdev->vip_slave || !pcdev->vip || !pcdev->vip_input || !pcdev->vip_bus ||
!pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus ||
IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) || IS_ERR(pcdev->hclk_cpu_display) ||
IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) {
IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) {
RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
goto RK29_CAMERA_ACTIVE_ERR;
@ -658,9 +663,9 @@ static int rk29_camera_activate(struct rk29_camera_dev *pcdev, struct soc_camera
goto RK29_CAMERA_ACTIVE_ERR;
}
clk_set_parent(pcdev->vip, parent);
clk_set_parent(pcdev->vip_out, parent);
clk_enable(pcdev->vip);
clk_enable(pcdev->vip_out);
rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_VIP_CLKOUT);
ndelay(10);
@ -693,7 +698,7 @@ static void rk29_camera_deactivate(struct rk29_camera_dev *pcdev)
read_vip_reg(RK29_VIP_INT_STS); //clear vip interrupte single
rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_GPIO1B4);
clk_disable(pcdev->vip);
clk_disable(pcdev->vip_out);
clk_disable(pcdev->vip_input);
clk_disable(pcdev->vip_bus);
@ -1133,7 +1138,26 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
RK29CAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
return ret;
}
static bool rk29_camera_fmt_capturechk(struct v4l2_format *f)
{
bool ret = false;
if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
ret = true;
} else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
ret = true;
} else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
ret = true;
} else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
ret = true;
} else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
ret = true;
}
if (ret == true)
RK29CAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
return ret;
}
static int rk29_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@ -1145,7 +1169,8 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
__u32 pixfmt = pix->pixelformat;
enum v4l2_field field;
int ret,usr_w,usr_h;
int bytes_per_pixel;
bool is_capture = rk29_camera_fmt_capturechk(f);
bool vipmem_is_overflow = false;
usr_w = pix->width;
usr_h = pix->height;
@ -1171,10 +1196,14 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
ret = v4l2_subdev_call(sd, video, try_fmt, f);
pix->pixelformat = pixfmt;
#ifdef CONFIG_VIDEO_RK29_WORK_IPP
bytes_per_pixel = (xlate->cam_fmt->depth + 7) >> 3;
if ((pix->width > usr_w) && (pix->height > usr_h)) {
/* Assume preview buffer minimum is 4 */
if (PAGE_ALIGN(bytes_per_pixel*pix->width*pix->height)*4 <= pcdev->vipmem_size) {
if (is_capture) {
vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size);
} else {
/* Assume preview buffer minimum is 4 */
vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size);
}
if (vipmem_is_overflow == false) {
pix->width = usr_w;
pix->height = usr_h;
} else {
@ -1182,14 +1211,19 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
}
} else if ((pix->width < usr_w) && (pix->height < usr_h)) {
if (((usr_w>>1) < pix->width) && ((usr_h>>1) < pix->height)) {
if (PAGE_ALIGN(bytes_per_pixel*pix->width*pix->height)*4 <= pcdev->vipmem_size) {
if (is_capture) {
vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) <= pcdev->vipmem_size);
} else {
vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 <= pcdev->vipmem_size);
}
if (vipmem_is_overflow == false) {
pix->width = usr_w;
pix->height = usr_h;
} else {
RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",pix->width,pix->height,usr_w,usr_h);
}
} else {
RK29CAMERA_TR("The aspect ratio(%dx%d//%dx%d) is bigger than 2 !\n",pix->width,pix->height,usr_w,usr_h);
RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",pix->width,pix->height,usr_w,usr_h);
}
}
#endif
@ -1443,7 +1477,7 @@ static int rk29_camera_probe(struct platform_device *pdev)
pcdev->hclk_cpu_display = clk_get(&pdev->dev, "hclk_cpu_display");
pcdev->vip_slave = clk_get(&pdev->dev, "vip_slave");
pcdev->vip = clk_get(&pdev->dev,"vip");
pcdev->vip_out = clk_get(&pdev->dev,"vip_out");
pcdev->vip_input = clk_get(&pdev->dev,"vip_input");
pcdev->vip_bus = clk_get(&pdev->dev, "vip_bus");
@ -1451,9 +1485,9 @@ static int rk29_camera_probe(struct platform_device *pdev)
pcdev->vip_matrix = clk_get(&pdev->dev,"vip_matrix");
if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix || !pcdev->hclk_cpu_display ||
!pcdev->vip_slave || !pcdev->vip || !pcdev->vip_input || !pcdev->vip_bus ||
!pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus ||
IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) || IS_ERR(pcdev->hclk_cpu_display) ||
IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) {
IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) {
RK29CAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n");
err = -ENOENT;
@ -1565,9 +1599,9 @@ static int rk29_camera_probe(struct platform_device *pdev)
clk_put(pcdev->vip_slave);
pcdev->vip_slave = NULL;
}
if (pcdev->vip) {
clk_put(pcdev->vip);
pcdev->vip = NULL;
if (pcdev->vip_out) {
clk_put(pcdev->vip_out);
pcdev->vip_out = NULL;
}
if (pcdev->vip_input) {
clk_put(pcdev->vip_input);

View File

@ -1223,7 +1223,7 @@ static int rk29_camera_probe(struct platform_device *pdev)
rk29_camdev_info_ptr = pcdev;
/*config output clk*/
pcdev->clk = clk_get(&pdev->dev, "vip");
pcdev->clk = clk_get(&pdev->dev, "vip_out");
if (!pcdev->clk || IS_ERR(pcdev->clk)) {
RK29CAMERA_TR(KERN_ERR "failed to get vip_clk source\n");
err = -ENOENT;

View File

@ -3394,7 +3394,7 @@ static int sensor_deactivate(struct i2c_client *client)
/* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
sensor_task_lock(client, 1);
sensor_ioctrl(icd, Sensor_PowerDown, 1);
/* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
icd->user_width = SENSOR_INIT_WIDTH;
icd->user_height = SENSOR_INIT_HEIGHT;
@ -4463,11 +4463,11 @@ static int sensor_video_probe(struct soc_camera_device *icd,
icd->formats = sensor_colour_formats;
icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return 0;
sensor_video_probe_err:
sensor_ioctrl(icd, Sensor_PowerDown, 1);
return ret;
}
static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)

View File

@ -262,6 +262,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
}
card->type = MMC_TYPE_SDIO;
/*
* Call the optional HC's init_card function to handle quirks.
*/
if (host->ops->init_card)
host->ops->init_card(host, card);
/*
* For native busses: set card RCA and quit open drain mode.

View File

@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
{
unsigned mval = min(func->card->host->max_seg_size,
func->card->host->max_blk_size);
mval = min(mval, func->max_blksize);
if (mmc_blksz_for_byte_mode(func->card))
mval = min(mval, func->cur_blksize);
else
mval = min(mval, func->max_blksize);
return min(mval, 512u); /* maximum size for byte mode */
}

View File

@ -31,6 +31,7 @@
#include <linux/irq.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/card.h>
#include <mach/board.h>
#include <mach/rk29_iomap.h>
@ -704,6 +705,11 @@ static void rk29_sdmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
spin_unlock_irqrestore(&host->lock, flags);
}
static void rk29_sdmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
{
card->quirks = MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
}
static const struct mmc_host_ops rk29_sdmmc_ops[] = {
{
.request = rk29_sdmmc_request,
@ -715,6 +721,7 @@ static const struct mmc_host_ops rk29_sdmmc_ops[] = {
.request = rk29_sdmmc_request,
.set_ios = rk29_sdmmc_set_ios,
.enable_sdio_irq = rk29_sdmmc_enable_sdio_irq,
.init_card = rk29_sdmmc_init_card,
},
};

8
drivers/staging/rk29/ipp/rk29-ipp.c Normal file → Executable file
View File

@ -135,6 +135,12 @@ int ipp_do_blit(struct rk29_ipp_req *req)
uint32_t post_scale_target_w, post_scale_target_h;
uint32_t dst0_YrgbMst=0,dst0_CbrMst=0;
uint32_t ret = 0;
if (drvdata == NULL) { /* ddl@rock-chips.com : check driver is normal or not */
printk(KERN_ERR, "%s drvdata is NULL, IPP driver probe is fail!!\n", __FUNCTION__);
return -EPERM;
}
rotate = req->flag;
switch (rotate) {
case IPP_ROT_90:
@ -928,7 +934,7 @@ static void __exit rk29_ipp_exit(void)
platform_driver_unregister(&rk29_ipp_driver);
}
module_init_sync(rk29_ipp_init);
device_initcall_sync(rk29_ipp_init);
module_exit(rk29_ipp_exit);
/* Module information */

View File

@ -396,4 +396,4 @@ static int __init rk29_backlight_init(void)
platform_driver_register(&rk29_backlight_driver);
return 0;
}
postcore_initcall_sync(rk29_backlight_init);
fs_initcall_sync(rk29_backlight_init);

View File

@ -3526,7 +3526,7 @@ static int __init fb_console_init(void)
return 0;
}
module_init(fb_console_init);
subsys_initcall(fb_console_init);
#ifdef MODULE

View File

@ -13,10 +13,16 @@ config LCD_HL070VM4AU
bool "RGB_HL070VM4AU"
config LCD_HSD070IDW1
bool "RGB Hannstar800x480"
config LCD_RGB_TFT480800_25_E
bool "RGB TFT480800_25_E"
config LCD_HSD100PXN
bool "RGB Hannstar HSD100PXN(1024X768)"
config LCD_B101AW06
bool "RGB Hannstar B101AW06(1024X600)"
config LCD_RGB_TFT480800_25_E
bool "RGB TFT480800_25_E(480X800)"
config LCD_LS035Y8DX02A
bool "RGB LS035Y8DX02A(480X800)"
config LCD_A060SE02
bool "MCU A060SE02"
config LCD_S1D13521
@ -25,6 +31,16 @@ config LCD_NT35582
bool "MCU NT35582"
config LCD_NT35580
bool "MCU NT35580"
config LCD_IPS1P5680_V1_E
bool "MCU IPS1P5680_V1_E"
config LCD_MCU_TFT480800_25_E
bool "MCU TFT480800_25_E"
config LCD_ILI9803_CPT4_3
bool "RGB lcd_ILI9803_CPT4_3"
config LCD_IPS1P5680_V1_E
bool "MCU IPS1P5680_V1_E"
config LCD_MCU_TFT480800_25_E
bool "MCU TFT480800_25_E"
config LCD_ANX7150_720P
bool "anx7150 720p for default panel"
---help---

View File

@ -3,6 +3,7 @@ obj-$(CONFIG_TV_NULL) += tv_null.o
obj-$(CONFIG_HDMI_NULL) += hdmi_null.o
obj-$(CONFIG_LCD_TD043MGEA1) += lcd_td043mgea1.o
obj-$(CONFIG_LCD_HSD070IDW1) += lcd_hsd800x480.o
obj-$(CONFIG_LCD_HL070VM4AU) += lcd_hl070vm4.o
@ -13,6 +14,10 @@ obj-$(CONFIG_LCD_A060SE02) += lcd_a060se02.o
obj-$(CONFIG_LCD_S1D13521) += lcd_s1d13521.o
obj-$(CONFIG_LCD_NT35582) += lcd_nt35582.o
obj-$(CONFIG_LCD_NT35580) += lcd_nt35580.o
obj-$(CONFIG_LCD_IPS1P5680_V1_E) += lcd_ips1p5680_v1_e.o
obj-$(CONFIG_LCD_RGB_TFT480800_25_E) += lcd_rgb_tft480800_25_e.o
obj-$(CONFIG_LCD_MCU_TFT480800_25_E) += lcd_mcu_tft480800_25_e.o
obj-$(CONFIG_LCD_LS035Y8DX02A) += lcd_ls035y8dx02a.o
obj-$(CONFIG_HDMI_ANX7150) += hdmi_anx7150.o
@ -20,4 +25,8 @@ obj-$(CONFIG_LCD_HX8357) += lcd_hx8357.o
obj-$(CONFIG_LCD_HSD100PXN) += lcd_hsd100pxn.o
obj-$(CONFIG_LCD_B101AW06) += lcd_B101AW06.o
obj-$(CONFIG_LCD_ANX7150_720P) += lcd_anx7150_720p.o
obj-$(CONFIG_LCD_ILI9803_CPT4_3) += lcd_ili9803_cpt4_3.o
obj-$(CONFIG_LCD_RGB_TFT480800_25_E) += lcd_rgb_tft480800_25_e.o
obj-$(CONFIG_LCD_LS035Y8DX02A) += lcd_ls035y8dx02a.o
obj-$(CONFIG_LCD_IPS1P5680_V1_E) += lcd_ips1p5680_v1_e.o
obj-$(CONFIG_LCD_MCU_TFT480800_25_E) += lcd_mcu_tft480800_25_e.o

View File

@ -0,0 +1,332 @@
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_RGB
#define OUT_FACE OUT_P888
#define OUT_CLK 26 //***27
/* Timing */
#define H_PW 16 //8ǰÏûÓ°
#define H_BP 24//6
#define H_VD 480//320 //***800
#define H_FP 16//60
#define V_PW 2//12
#define V_BP 2// 4
#define V_VD 800//480 //***480
#define V_FP 4//40
/* Other */
#define DCLK_POL 1//0
#define SWAP_RB 0
static struct rk29lcd_info *gLcd_info = NULL;
int init(void);
int standby(u8 enable);
#define TXD_PORT gLcd_info->txd_pin
#define CLK_PORT gLcd_info->clk_pin
#define CS_PORT gLcd_info->cs_pin
#define CS_OUT() gpio_direction_output(CS_PORT, 1)
#define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
#define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
#define CLK_OUT() gpio_direction_output(CLK_PORT, 0)
#define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
#define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
#define TXD_OUT() gpio_direction_output(TXD_PORT, 1)
#define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
#define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
#define DRVDelayUs(i) udelay(i*4)
void spi_screenreg_cmd(u8 Addr)
{
u32 i;
u32 control_bit;
TXD_OUT();
CLK_OUT();
CS_OUT();
DRVDelayUs(2);
DRVDelayUs(2);
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(30);
CS_CLR();
control_bit = 0x0000;
Addr = (control_bit | Addr);//spi_screenreg_set(0x36, 0x0000, 0xffff);
//printk("addr is 0x%x \n", Addr);
for(i = 0; i < 9; i++) //reg
{
if(Addr &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(10);
}
void spi_screenreg_param(u8 Param)
{
u32 i;
u32 control_bit;
CS_CLR();
control_bit = 0x0100;
Param = (control_bit | Param);
//printk("data0 is 0x%x \n", Data);
for(i = 0; i < 9; i++) //data
{
if(Param &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
CLK_CLR();
TXD_CLR();
DRVDelayUs(10);
}
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
{
//printk("lcd_hx8357 set_lcd_info \n");
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
/* Timing */
screen->pixclock = OUT_CLK;
screen->left_margin = H_BP; /*>2*/
screen->right_margin = H_FP; /*>2*/
screen->hsync_len = H_PW; /*>2*/ //***all > 326, 4<PW+BP<15,
screen->upper_margin = V_BP; /*>2*/
screen->lower_margin = V_FP; /*>2*/
screen->vsync_len = V_PW; /*>6*/
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = init;
screen->standby = standby;
if(lcd_info)
gLcd_info = lcd_info;
}
int init(void)
{
volatile u32 data;
if(gLcd_info)
gLcd_info->io_init();
printk("lcd init...\n");
spi_screenreg_cmd(0xB1);
spi_screenreg_param(0x00);
spi_screenreg_cmd(0xB2);
spi_screenreg_param(0x10);
spi_screenreg_param(0xC7);
spi_screenreg_cmd(0xB3);
spi_screenreg_param(0x00);
spi_screenreg_cmd(0xB4);
spi_screenreg_param(0x00);
spi_screenreg_cmd(0xB9);
spi_screenreg_param(0x00);
spi_screenreg_cmd(0xC3);
spi_screenreg_param(0x07);
spi_screenreg_cmd(0xB2);
spi_screenreg_param(0x04);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x00);
spi_screenreg_param(0x07);
spi_screenreg_param(0x04);
spi_screenreg_cmd(0xC5);
spi_screenreg_param(0x6E);
spi_screenreg_cmd(0xC2);
spi_screenreg_param(0x20);
spi_screenreg_param(0x00);
spi_screenreg_param(0x10);
mdelay(20);//20ms
spi_screenreg_cmd(0xC8);
spi_screenreg_param(0xA3);
spi_screenreg_cmd(0xC9);
spi_screenreg_param(0x32);
spi_screenreg_param(0x06);
spi_screenreg_cmd(0xD7);
spi_screenreg_param(0x03);
spi_screenreg_param(0x00);
spi_screenreg_param(0x0F);
spi_screenreg_param(0x0F);
spi_screenreg_cmd(0xCF);
spi_screenreg_param(0x00);
spi_screenreg_param(0x08);
spi_screenreg_cmd(0xB6);
spi_screenreg_param(0x20);
spi_screenreg_param(0xC2);
spi_screenreg_param(0xFF);
spi_screenreg_param(0x04);
spi_screenreg_cmd(0xEA);
spi_screenreg_param(0x00);
spi_screenreg_cmd(0x2A);
spi_screenreg_param(0x00);
spi_screenreg_param(0x00);
spi_screenreg_param(0x01);
spi_screenreg_param(0xDF);
spi_screenreg_cmd(0x2B);
spi_screenreg_param(0x00);
spi_screenreg_param(0x00);
spi_screenreg_param(0x03);
spi_screenreg_param(0xEF);
spi_screenreg_cmd(0xB0);
spi_screenreg_param(0x01);
spi_screenreg_cmd(0x0C);
spi_screenreg_param(0x50);
spi_screenreg_cmd(0x36);
spi_screenreg_param(0x48);
spi_screenreg_cmd(0x3A);
spi_screenreg_param(0x66);
spi_screenreg_cmd(0xE0);
spi_screenreg_param(0x05);
spi_screenreg_param(0x07);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x14);
spi_screenreg_param(0x11);
spi_screenreg_param(0x14);
spi_screenreg_param(0x0A);
spi_screenreg_param(0x07);
spi_screenreg_param(0x04);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x02);
spi_screenreg_param(0x00);
spi_screenreg_param(0x04);
spi_screenreg_param(0x33);
spi_screenreg_param(0x36);
spi_screenreg_param(0x1F);
spi_screenreg_cmd(0xE1);
spi_screenreg_param(0x1F);
spi_screenreg_param(0x36);
spi_screenreg_param(0x33);
spi_screenreg_param(0x04);
spi_screenreg_param(0x00);
spi_screenreg_param(0x02);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x04);
spi_screenreg_param(0x07);
spi_screenreg_param(0x0A);
spi_screenreg_param(0x14);
spi_screenreg_param(0x11);
spi_screenreg_param(0x14);
spi_screenreg_param(0x0B);
spi_screenreg_param(0x07);
spi_screenreg_param(0x05);
spi_screenreg_cmd(0x11);
mdelay(70);
spi_screenreg_cmd(0x29);
mdelay(10);
spi_screenreg_cmd(0x2C);
if(gLcd_info)
gLcd_info->io_deinit();
return 0;
}
int standby(u8 enable) //***enable =1 means suspend, 0 means resume
{
int i;
#if 1
if(gLcd_info)
gLcd_info->io_init();
if(enable) {
spi_screenreg_cmd(0xB7);
spi_screenreg_param(0x0f);
} else {
CS_OUT() ;
for(i=0; i<6; i++)
{
CS_SET();
DRVDelayUs(1);
CS_CLR();
DRVDelayUs(1);
CS_SET();
mdelay(2);
}
}
if(gLcd_info)
gLcd_info->io_deinit();
#endif
return 0;
}
void set_backlight(int brightness)
{
#if 1
if(gLcd_info)
gLcd_info->io_init();
printk("lcd_ili9803:set_backlight = %d\r\n", brightness);
if (brightness < 0)
{
brightness = 0;
}
if (brightness > 4)
{
brightness = 4;
}
spi_screenreg_cmd(0x51);
spi_screenreg_param(brightness<<5);
if(gLcd_info)
gLcd_info->io_deinit();
#endif
}

View File

@ -0,0 +1,239 @@
/*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* author: hhb@rock-chips.com
* creat date: 2011-03-07
* route:drivers/video/display/screen/lcd_ips1p5680_v1_e.c - driver for rk29 phone sdk
* station:haven't been tested in any hardware platform
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_MCU
#define OUT_FACE OUT_P565
/* Timing */
#define H_PW 1
#define H_BP 1
#define H_VD 320
#define H_FP 5
#define V_PW 1
#define V_BP 1
#define V_VD 480
#define V_FP 1
#define LCD_WIDTH 320 //need modify
#define LCD_HEIGHT 480
#define LCDC_ACLK 150000000 //29 lcdc axi DMA ƵÂÊ
#define P_WR 27
#define USE_FMARK 0 //2 ÊÇ·ñʹÓÃFMK (0:²»Ö§³Ö 1:ºáÆÁÖ§³Ö 2:ºáÊúÆÁ¶ŒÖ§³Ö)
#define FRMRATE 60 //MCUÆÁµÄË¢ÐÂÂÊ (FMKÓÐЧʱÓÃ)
/* Other */
#define DCLK_POL 0
#define SWAP_RB 0
/* define lcd command */
#define ENTER_SLEEP_MODE 0x10
#define EXIT_SLEEP_MODE 0x11
#define SET_COLUMN_ADDRESS 0x2a
#define SET_PAGE_ADDRESS 0x2b
#define WRITE_MEMORY_START 0x2c
#define SET_DISPLAY_ON 0x29
#define SET_DISPLAY_OFF 0x28
#define SET_ADDRESS_MODE 0x36
#define SET_PIXEL_FORMAT 0x3a
/* initialize the lcd registers to make it function noamally*/
int lcd_init(void)
{
int i =0;
mcu_ioctl(MCU_SETBYPASS, 1);
msleep(5);
mcu_ioctl(MCU_WRCMD, SET_ADDRESS_MODE); //set address normal mode
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRCMD, SET_PIXEL_FORMAT); //set 16 bits per pixel
mcu_ioctl(MCU_WRDATA, 0x55);
mcu_ioctl(MCU_WRCMD, EXIT_SLEEP_MODE); //set lcd exit sleep mode,because the lcd is in sleep mode when power on
msleep(1000*6 / FRMRATE + 10); //wait for about 6 frames' time
mcu_ioctl(MCU_WRCMD, SET_DISPLAY_ON); //set display on
msleep(1000/FRMRATE);
/*init lcd internal ram,so lcd won't display randomly*/
mcu_ioctl(MCU_WRCMD, SET_COLUMN_ADDRESS);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_WIDTH >> 8) & 0x0003);
mcu_ioctl(MCU_WRDATA, LCD_WIDTH & 0x00ff);
msleep(10);
mcu_ioctl(MCU_WRCMD, SET_PAGE_ADDRESS);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_HEIGHT >> 8) & 0x0003);
mcu_ioctl(MCU_WRDATA, LCD_HEIGHT & 0x00ff);
msleep(10);
mcu_ioctl(MCU_WRCMD, WRITE_MEMORY_START);
for(i = 0; i < LCD_WIDTH*LCD_HEIGHT; i++)
{
mcu_ioctl(MCU_WRDATA, 0x00000000);
}
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* set lcd to sleep mode or not */
int lcd_standby(u32 enable)
{
mcu_ioctl(MCU_SETBYPASS, 1);
if(enable) {
mcu_ioctl(MCU_WRCMD, ENTER_SLEEP_MODE);
} else {
mcu_ioctl(MCU_WRCMD, EXIT_SLEEP_MODE);
}
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* set lcd to write memory mode, so the lcdc of RK29xx can send the fb content to the lcd internal ram in hold mode*/
int lcd_refresh(u32 arg)
{
mcu_ioctl(MCU_SETBYPASS, 1);
switch(arg)
{
case REFRESH_PRE: //start to write the image data to lcd ram
mcu_ioctl(MCU_WRCMD, SET_COLUMN_ADDRESS); //set
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_WIDTH >> 8) & 0x0003);
mcu_ioctl(MCU_WRDATA, LCD_WIDTH & 0x00ff);
msleep(10);
mcu_ioctl(MCU_WRCMD, SET_PAGE_ADDRESS);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_HEIGHT >> 8) & 0x0003);
mcu_ioctl(MCU_WRDATA, LCD_HEIGHT & 0x00ff);
msleep(10);
mcu_ioctl(MCU_WRCMD, WRITE_MEMORY_START);
break;
case REFRESH_END: //set display on
mcu_ioctl(MCU_WRCMD, SET_DISPLAY_ON);
break;
default:
break;
}
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* not used */
int lcd_scandir(u32 dir)
{
mcu_ioctl(MCU_SETBYPASS, 1);
// mcu_ioctl(MCU_WRCMD, SET_DISPLAY_OFF);
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* not used */
int lcd_disparea(u32 area)
{
mcu_ioctl(MCU_SETBYPASS, 1);
mcu_ioctl(MCU_SETBYPASS, 0);
return (0);
}
/* set real information about lcd which we use in this harware platform */
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info)
{
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
screen->width = LCD_WIDTH;
screen->height = LCD_HEIGHT;
/* Timing */
screen->lcdc_aclk = LCDC_ACLK;
screen->left_margin = H_BP;
screen->right_margin = H_FP;
screen->hsync_len = H_PW;
screen->upper_margin = V_BP;
screen->lower_margin = V_FP;
screen->vsync_len = V_PW;
screen->mcu_wrperiod = P_WR;
screen->mcu_usefmk = USE_FMARK;
screen->mcu_frmrate = FRMRATE;
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = lcd_init;
screen->standby = lcd_standby;
screen->scandir = lcd_scandir;
screen->refresh = lcd_refresh;
screen->disparea = lcd_disparea;
}

View File

@ -0,0 +1,344 @@
/*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* author: hhb@rock-chips.com
* creat date: 2011-03-22
* route:drivers/video/display/screen/lcd_ls035y8dx02a.c - driver for rk29 phone sdk
* station:haven't been tested in any hardware platform
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_RGB
#define OUT_FACE OUT_P888
#define OUT_CLK 26 //***27
#define LCDC_ACLK 150000000 //29 lcdc axi DMA Ƶ<><C6B5> //rk29
/* Timing */
#define H_PW 16 //8
#define H_BP 24//6
#define H_VD 480//320 //***800
#define H_FP 16//60
#define V_PW 2//12
#define V_BP 2// 4
#define V_VD 800//480 //***480
#define V_FP 4//40
#define LCD_WIDTH 800 //need modify //rk29
#define LCD_HEIGHT 480
/* Other */
#define DCLK_POL 1 //0
#define SWAP_RB 0
static struct rk29lcd_info *gLcd_info = NULL;
int lcd_init(void);
int lcd_standby(u32 enable);
/*
#define RXD_PORT RK2818_PIN_PB7
#define TXD_PORT RK2818_PIN_PB6 //gLcd_info->txd_pin
#define CLK_PORT RK2818_PIN_PB5 //gLcd_info->clk_pin
#define CS_PORT RK2818_PIN_PB4 // gLcd_info->cs_pin
*/
#define RXD_PORT 1
#define TXD_PORT gLcd_info->txd_pin
#define CLK_PORT gLcd_info->clk_pin
#define CS_PORT gLcd_info->cs_pin
#define CS_OUT() gpio_direction_output(CS_PORT, 1)
#define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
#define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
#define CLK_OUT() gpio_direction_output(CLK_PORT, 0)
#define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
#define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
#define TXD_OUT() gpio_direction_output(TXD_PORT, 1)
#define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
#define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
#define RXD_IN() gpio_direction_input(RXD_PORT)
#define RXD_GET() gpio_get_value(RXD_PORT)
#define DRVDelayUs(i) udelay(i*4)
u32 spi_screenreg_get(u32 Addr)
{
u32 i, data = 0;
u32 control_bit;
TXD_OUT();
CLK_OUT();
CS_OUT();
DRVDelayUs(2);
DRVDelayUs(2);
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(30);
CS_CLR();
control_bit = 0x0000;
Addr = (control_bit | Addr);
printk("addr is 0x%x \n", Addr);
for(i = 0; i < 9; i++) //reg
{
if(Addr &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(10);
CS_CLR();
for(i = 0; i < 9; i++)
{
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
if(RXD_GET())
{
data |= 1<<(8-i);
}
else
{
data &= ~(1<<(8-i));
}
DRVDelayUs(2);
}
CS_SET();
CLK_CLR();
TXD_CLR();
DRVDelayUs(30);
return data;
}
void spi_screenreg_set(u32 Addr, u32 Data0, u32 Data1)
{
u32 i;
u32 control_bit;
TXD_OUT();
CLK_OUT();
CS_OUT();
DRVDelayUs(2);
DRVDelayUs(2);
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(30);
CS_CLR();
control_bit = 0x0000;
Addr = (control_bit | Addr);
//printk("addr is 0x%x \n", Addr);
for(i = 0; i < 9; i++) //reg
{
if(Addr &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
TXD_SET();
CLK_CLR();
DRVDelayUs(10);
if(0xffff == Data0)
return;
CS_CLR();
control_bit = 0x0100;
Data0 = (control_bit | Data0);
//printk("data0 is 0x%x \n", Data);
for(i = 0; i < 9; i++) //data
{
if(Data0 &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
CLK_CLR();
TXD_CLR();
DRVDelayUs(10);
if(0xffff == Data1)
return;
CS_CLR();
control_bit = 0x0100;
Data1 = (control_bit | Data1);
//printk("data1 is 0x%x \n", Data);
for(i = 0; i < 9; i++) //data
{
if(Data1 &(1<<(8-i)))
TXD_SET();
else
TXD_CLR();
// \u6a21\u62dfCLK
CLK_SET();
DRVDelayUs(2);
CLK_CLR();
DRVDelayUs(2);
}
CS_SET();
CLK_CLR();
TXD_CLR();
DRVDelayUs(30);
}
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
{
//printk("lcd_hx8357 set_lcd_info \n");
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
screen->width = LCD_WIDTH; //rk29
screen->height = LCD_HEIGHT; //rk29
/* Timing */
screen->lcdc_aclk = LCDC_ACLK; //rk29
screen->pixclock = OUT_CLK;
screen->left_margin = H_BP; /*>2*/
screen->right_margin = H_FP; /*>2*/
screen->hsync_len = H_PW; /*>2*/ //***all > 326, 4<PW+BP<15,
screen->upper_margin = V_BP; /*>2*/
screen->lower_margin = V_FP; /*>2*/
screen->vsync_len = V_PW; /*>6*/
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = lcd_init;
screen->standby = lcd_standby;
if(lcd_info)
gLcd_info = lcd_info;
}
int lcd_init(void)
{
volatile u32 data;
// rk2818_mux_api_set(GPIOB_SPI0_MMC0_NAME,IOMUXA_GPIO0_B567);
// rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,IOMUXA_GPIO0_B4);
//gpio_pull_updown(RK2818_PIN_PB7, GPIOPullUp);
if(gLcd_info)
{printk("lcd init11111111111111111111111111...\n");
gLcd_info->io_init();}
printk("lcd init22222222222222222222222222...\n");
printk("lcd init...\n");
spi_screenreg_set(0x29, 0xffff, 0xffff);
spi_screenreg_set(0x11, 0xffff, 0xffff);
mdelay(150);
spi_screenreg_set(0x36, 0x0000, 0xffff);
//while(1)
{
data = spi_screenreg_get(0x0a);
printk("------------liuylcd init reg 0x0a=0x%x \n", spi_screenreg_get(0x0a));
data = spi_screenreg_get(0x0b);
printk("------------liuylcd init reg 0x0b=0x%x \n", spi_screenreg_get(0x0b));
data = spi_screenreg_get(0x0c);
printk("------------liuylcd init reg 0x0c=0x%x \n", spi_screenreg_get(0x0c));
data = spi_screenreg_get(0x0d);
printk("------------liuylcd init reg 0x0d=0x%x \n", spi_screenreg_get(0x0d));
data = spi_screenreg_get(0x0f);
printk("------------liuylcd init reg 0x0f=0x%x \n", spi_screenreg_get(0x0f));
}
spi_screenreg_set(0x3a, 0x0070, 0xffff);
spi_screenreg_set(0xb0, 0x0000, 0xffff);
spi_screenreg_set(0xb8, 0x0001, 0xffff);
spi_screenreg_set(0xb9, 0x0001, 0x00ff);
spi_screenreg_set(0xb0, 0x0003, 0xffff);
if(gLcd_info)
gLcd_info->io_deinit();
return 0;
}
int lcd_standby(u32 enable) //***enable =1 means suspend, 0 means resume
{
if(gLcd_info)
gLcd_info->io_init();
printk("lcd standby\n");
if(enable) {
printk("lcd standby...enable =1 means suspend\n");
spi_screenreg_set(0x10, 0xffff, 0xffff);
mdelay(120);
spi_screenreg_set(0x28, 0xffff, 0xffff);
} else {
printk("lcd standby...0 means resume\n");
spi_screenreg_set(0x29, 0xffff, 0xffff);
spi_screenreg_set(0x11, 0xffff, 0xffff);
//mdelay(150);
}
if(gLcd_info)
gLcd_info->io_deinit();
return 0;
}

View File

@ -0,0 +1,556 @@
/*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* author: hhb@rock-chips.com
* creat date: 2011-03-11
* route:drivers/video/display/screen/lcd_mcu_tft480800_25_e.c - driver for rk29 phone sdk
* station:haven't been tested in any hardware platform
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_MCU
#define OUT_FACE OUT_P888
/* Timing */
#define H_PW 1
#define H_BP 1
#define H_VD 480
#define H_FP 5
#define V_PW 1
#define V_BP 1
#define V_VD 800
#define V_FP 1
#define LCD_WIDTH 480 //need modify
#define LCD_HEIGHT 800
#define LCDC_ACLK 150000000 //29 lcdc axi DMA ƵÂÊ
#define P_WR 27
#define USE_FMARK 0 //2 ÊÇ·ñʹÓÃFMK (0:²»Ö§³Ö 1:ºáÆÁÖ§³Ö 2:ºáÊúÆÁ¶ŒÖ§³Ö)
#define FRMRATE 60 //MCUÆÁµÄË¢ÐÂÂÊ (FMKÓÐЧʱÓÃ)
/* Other */
#define DCLK_POL 0
#define SWAP_RB 0
/* define lcd command */
#define ENTER_SLEEP_MODE 0x10
#define EXIT_SLEEP_MODE 0x11
#define SET_COLUMN_ADDRESS 0x2a
#define SET_PAGE_ADDRESS 0x2b
#define WRITE_MEMORY_START 0x2c
#define SET_DISPLAY_ON 0x29
#define SET_DISPLAY_OFF 0x28
#define SET_ADDRESS_MODE 0x36
#define SET_PIXEL_FORMAT 0x3a
#define WMLCDCOM(command) mcu_ioctl(MCU_WRCMD,command)
#define WMLCDDATA(data) mcu_ioctl(MCU_WRDATA,data)
/* initialize the lcd registers to make it function noamally*/
int lcd_init(void)
{
int k = 0;
mcu_ioctl(MCU_SETBYPASS, 1);
#if 1 //HX8369-A
WMLCDCOM(0xB9); // SET password
WMLCDDATA(0xFF);
WMLCDDATA(0x83);
WMLCDDATA(0x69);
WMLCDCOM(0xB0); //Enable internal oscillator
WMLCDDATA(0x01);
WMLCDDATA(0x0B);
WMLCDCOM(0xB1); //Set Power
WMLCDDATA(0x85);
WMLCDDATA(0x00);
WMLCDDATA(0x34);
WMLCDDATA(0x0A);
WMLCDDATA(0x00);
WMLCDDATA(0x0F);
WMLCDDATA(0x0F);
WMLCDDATA(0x2A);
WMLCDDATA(0x32);
WMLCDDATA(0x3F);
WMLCDDATA(0x3F);
WMLCDDATA(0x01); //update VBIAS
WMLCDDATA(0x23);
WMLCDDATA(0x01);
WMLCDDATA(0xE6);
WMLCDDATA(0xE6);
WMLCDDATA(0xE6);
WMLCDDATA(0xE6);
WMLCDDATA(0xE6);
WMLCDCOM(0xB2); // SET Display 480x800
WMLCDDATA(0x00);
WMLCDDATA(0x20);
WMLCDDATA(0x05);
WMLCDDATA(0x05);
WMLCDDATA(0x70); //70
WMLCDDATA(0x00); //00
WMLCDDATA(0xFF); //FF
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x00); //1
WMLCDDATA(0x03);
WMLCDDATA(0x03);
WMLCDDATA(0x00);
WMLCDDATA(0x01);
WMLCDCOM(0xB4); // SET Display 480x800
WMLCDDATA(0x00); //00
WMLCDDATA(0x18); //18
WMLCDDATA(0x80); //80
WMLCDDATA(0x06);
WMLCDDATA(0x02);
WMLCDCOM(0xB6); // SET VCOM
WMLCDDATA(0x3A); // Update VCOM
WMLCDDATA(0x3A);
/************CABC test ***************/
WMLCDCOM(0X51);//Write Display Brightness
WMLCDDATA(0Xff);//DBV[7:0]=0XE4
msleep(20);
/*
WMLCDCOM(0XC9);//SETCABC
WMLCDDATA(0X5F);//PWM_DIV="110" PWM_CLK 64·ÖƵ INVPULS="1"
WMLCDDATA(0X7F);//WMLCDDATA(0X7F);
WMLCDDATA(0X20);//PWM_EPERIOD
WMLCDDATA(0X00);//SAVEPOWER[6:0]
WMLCDDATA(0X20);//DIM_FRAM[6:0]
WMLCDDATA(0X00);//
WMLCDDATA(0X03);//CABC_FLM
WMLCDDATA(0X20);//
msleep(20);
*/
WMLCDCOM(0X53);//WRITE CTRL DISPLAY
WMLCDDATA(0X24);//WMLCDDATA(0X26) BCTRL="1" BL="1" DD="1"/"0"
msleep(20);
WMLCDCOM(0X55);
WMLCDDATA(0X02);//STILL PICTURE
msleep(20);
//WMLCDCOM(0X5E);//Write CABC minimum brightness (5Eh)
//WMLCDDATA(0X00);//CMB[7:0=0X00
//msleep(20);
/***************************************/
WMLCDCOM(0x2A); //set window
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x0);
WMLCDDATA(0xF0);
WMLCDCOM(0x2B);
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x01);
WMLCDDATA(0x40);
WMLCDCOM(0xD5); //Set GIP
WMLCDDATA(0x00);
WMLCDDATA(0x04);
WMLCDDATA(0x03);
WMLCDDATA(0x00);
WMLCDDATA(0x01);
WMLCDDATA(0x05);
WMLCDDATA(0x28);
WMLCDDATA(0x70);
WMLCDDATA(0x01);
WMLCDDATA(0x03);
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x40);
WMLCDDATA(0x06);
WMLCDDATA(0x51);
WMLCDDATA(0x07);
WMLCDDATA(0x00);
WMLCDDATA(0x00);
WMLCDDATA(0x41);
WMLCDDATA(0x06);
WMLCDDATA(0x50);
WMLCDDATA(0x07);
WMLCDDATA(0x07);
WMLCDDATA(0x0F);
WMLCDDATA(0x04);
WMLCDDATA(0x00);
//Gamma2.2
WMLCDCOM(0xE0);
WMLCDDATA(0x00);
WMLCDDATA(0x13);
WMLCDDATA(0x19);
WMLCDDATA(0x38);
WMLCDDATA(0x3D);
WMLCDDATA(0x3F);
WMLCDDATA(0x28);
WMLCDDATA(0x46);
WMLCDDATA(0x07);
WMLCDDATA(0x0D);
WMLCDDATA(0x0E);
WMLCDDATA(0x12);
WMLCDDATA(0x15);
WMLCDDATA(0x12);
WMLCDDATA(0x14);
WMLCDDATA(0x0F);
WMLCDDATA(0x17);
WMLCDDATA(0x00);
WMLCDDATA(0x13);
WMLCDDATA(0x19);
WMLCDDATA(0x38);
WMLCDDATA(0x3D);
WMLCDDATA(0x3F);
WMLCDDATA(0x28);
WMLCDDATA(0x46);
WMLCDDATA(0x07);
WMLCDDATA(0x0D);
WMLCDDATA(0x0E);
WMLCDDATA(0x12);
WMLCDDATA(0x15);
WMLCDDATA(0x12);
WMLCDDATA(0x14);
WMLCDDATA(0x0F);
WMLCDDATA(0x17);
msleep(10);
//DGC Setting
WMLCDCOM(0xC1);
WMLCDDATA(0x01);
//R
WMLCDDATA(0x00);
WMLCDDATA(0x04);
WMLCDDATA(0x11);
WMLCDDATA(0x19);
WMLCDDATA(0x20);
WMLCDDATA(0x29);
WMLCDDATA(0x30);
WMLCDDATA(0x37);
WMLCDDATA(0x40);
WMLCDDATA(0x4A);
WMLCDDATA(0x52);
WMLCDDATA(0x59);
WMLCDDATA(0x60);
WMLCDDATA(0x68);
WMLCDDATA(0x70);
WMLCDDATA(0x79);
WMLCDDATA(0x81);
WMLCDDATA(0x89);
WMLCDDATA(0x91);
WMLCDDATA(0x99);
WMLCDDATA(0xA1);
WMLCDDATA(0xA8);
WMLCDDATA(0xB0);
WMLCDDATA(0xB8);
WMLCDDATA(0xC1);
WMLCDDATA(0xC9);
WMLCDDATA(0xD0);
WMLCDDATA(0xD8);
WMLCDDATA(0xE1);
WMLCDDATA(0xE8);
WMLCDDATA(0xF1);
WMLCDDATA(0xF8);
WMLCDDATA(0xFF);
WMLCDDATA(0x31);
WMLCDDATA(0x9C);
WMLCDDATA(0x57);
WMLCDDATA(0xED);
WMLCDDATA(0x57);
WMLCDDATA(0x7F);
WMLCDDATA(0x61);
WMLCDDATA(0xAD);
WMLCDDATA(0xC0);
//G
WMLCDDATA(0x00);
WMLCDDATA(0x04);
WMLCDDATA(0x11);
WMLCDDATA(0x19);
WMLCDDATA(0x20);
WMLCDDATA(0x29);
WMLCDDATA(0x30);
WMLCDDATA(0x37);
WMLCDDATA(0x40);
WMLCDDATA(0x4A);
WMLCDDATA(0x52);
WMLCDDATA(0x59);
WMLCDDATA(0x60);
WMLCDDATA(0x68);
WMLCDDATA(0x70);
WMLCDDATA(0x79);
WMLCDDATA(0x81);
WMLCDDATA(0x89);
WMLCDDATA(0x91);
WMLCDDATA(0x99);
WMLCDDATA(0xA1);
WMLCDDATA(0xA8);
WMLCDDATA(0xB0);
WMLCDDATA(0xB8);
WMLCDDATA(0xC1);
WMLCDDATA(0xC9);
WMLCDDATA(0xD0);
WMLCDDATA(0xD8);
WMLCDDATA(0xE1);
WMLCDDATA(0xE8);
WMLCDDATA(0xF1);
WMLCDDATA(0xF8);
WMLCDDATA(0xFF);
WMLCDDATA(0x31);
WMLCDDATA(0x9C);
WMLCDDATA(0x57);
WMLCDDATA(0xED);
WMLCDDATA(0x57);
WMLCDDATA(0x7F);
WMLCDDATA(0x61);
WMLCDDATA(0xAD);
WMLCDDATA(0xC0);
//B
WMLCDDATA(0x00);
WMLCDDATA(0x04);
WMLCDDATA(0x11);
WMLCDDATA(0x19);
WMLCDDATA(0x20);
WMLCDDATA(0x29);
WMLCDDATA(0x30);
WMLCDDATA(0x37);
WMLCDDATA(0x40);
WMLCDDATA(0x4A);
WMLCDDATA(0x52);
WMLCDDATA(0x59);
WMLCDDATA(0x60);
WMLCDDATA(0x68);
WMLCDDATA(0x70);
WMLCDDATA(0x79);
WMLCDDATA(0x81);
WMLCDDATA(0x89);
WMLCDDATA(0x91);
WMLCDDATA(0x99);
WMLCDDATA(0xA1);
WMLCDDATA(0xA8);
WMLCDDATA(0xB0);
WMLCDDATA(0xB8);
WMLCDDATA(0xC1);
WMLCDDATA(0xC9);
WMLCDDATA(0xD0);
WMLCDDATA(0xD8);
WMLCDDATA(0xE1);
WMLCDDATA(0xE8);
WMLCDDATA(0xF1);
WMLCDDATA(0xF8);
WMLCDDATA(0xFF);
WMLCDDATA(0x31);
WMLCDDATA(0x9C);
WMLCDDATA(0x57);
WMLCDDATA(0xED);
WMLCDDATA(0x57);
WMLCDDATA(0x7F);
WMLCDDATA(0x61);
WMLCDDATA(0xAD);
WMLCDDATA(0xC0);
WMLCDCOM(0x2D);//Look up table
for(k = 0; k < 64; k++) //RED
{
WMLCDDATA(8*k);
}
for(k = 0; k < 64; k++) //GREEN
{
WMLCDDATA(4*k);
}
for(k = 0; k < 64; k++) //BLUE
{
WMLCDDATA(8*k);
}
msleep(10);
WMLCDCOM(SET_PIXEL_FORMAT); //pixel format setting
WMLCDDATA(0x77);
WMLCDCOM(EXIT_SLEEP_MODE);
msleep(120);
WMLCDCOM(SET_DISPLAY_ON); //Display on
WMLCDCOM(WRITE_MEMORY_START);
#endif
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* set lcd to sleep mode or not */
int lcd_standby(u32 enable)
{
mcu_ioctl(MCU_SETBYPASS, 1);
if(enable) {
mcu_ioctl(MCU_WRCMD, ENTER_SLEEP_MODE);
msleep(10);
} else {
mcu_ioctl(MCU_WRCMD, EXIT_SLEEP_MODE);
msleep(20);
}
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* set lcd to write memory mode, so the lcdc of RK29xx can send the fb content to the lcd internal ram in hold mode*/
int lcd_refresh(u32 arg)
{
mcu_ioctl(MCU_SETBYPASS, 1);
switch(arg)
{
case REFRESH_PRE: //start to write the image data to lcd ram
mcu_ioctl(MCU_WRCMD, SET_COLUMN_ADDRESS); //set
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_WIDTH >> 8) & 0x00ff);
mcu_ioctl(MCU_WRDATA, LCD_WIDTH & 0x00ff);
msleep(1);
mcu_ioctl(MCU_WRCMD, SET_PAGE_ADDRESS);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, 0);
mcu_ioctl(MCU_WRDATA, (LCD_HEIGHT >> 8) & 0x00ff);
mcu_ioctl(MCU_WRDATA, LCD_HEIGHT & 0x00ff);
msleep(1);
mcu_ioctl(MCU_WRCMD, WRITE_MEMORY_START);
break;
case REFRESH_END: //set display on
mcu_ioctl(MCU_WRCMD, SET_DISPLAY_ON);
break;
default:
break;
}
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* not used */
int lcd_scandir(u32 dir)
{
mcu_ioctl(MCU_SETBYPASS, 1);
// mcu_ioctl(MCU_WRCMD, SET_DISPLAY_OFF);
mcu_ioctl(MCU_SETBYPASS, 0);
return 0;
}
/* not used */
int lcd_disparea(u32 area)
{
mcu_ioctl(MCU_SETBYPASS, 1);
mcu_ioctl(MCU_SETBYPASS, 0);
return (0);
}
/* set real information about lcd which we use in this harware platform */
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info)
{
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
screen->width = LCD_WIDTH;
screen->height = LCD_HEIGHT;
/* Timing */
screen->lcdc_aclk = LCDC_ACLK;
screen->left_margin = H_BP;
screen->right_margin = H_FP;
screen->hsync_len = H_PW;
screen->upper_margin = V_BP;
screen->lower_margin = V_FP;
screen->vsync_len = V_PW;
screen->mcu_wrperiod = P_WR;
screen->mcu_usefmk = USE_FMARK;
screen->mcu_frmrate = FRMRATE;
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = lcd_init;
screen->standby = lcd_standby;
screen->scandir = lcd_scandir;
screen->refresh = lcd_refresh;
screen->disparea = lcd_disparea;
}

View File

@ -0,0 +1,548 @@
/*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* author: hhb@rock-chips.com
* creat date: 2011-03-11
* route:drivers/video/display/screen/lcd_rgb_tft480800_25_e.c - driver for rk29 phone sdk
* station:haven't been tested in any hardware platform
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/fb.h>
#include <linux/delay.h>
#include "../../rk29_fb.h"
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include "screen.h"
/* Base */
#define OUT_TYPE SCREEN_RGB
#define OUT_FACE OUT_P888
#define OUT_CLK 23000000
#define LCDC_ACLK 150000000 //29 lcdc axi DMA Ƶ<><C6B5>
/* Timing */
#define H_PW 1
#define H_BP 120
#define H_VD 800
#define H_FP 20
#define V_PW 1
#define V_BP 20
#define V_VD 480
#define V_FP 4
#define LCD_WIDTH 800 //need modify
#define LCD_HEIGHT 480
/* Other */
#define DCLK_POL 1
#define SWAP_RB 0
/* define spi write command and data interface function */
#define SIMULATION_SPI 1
#ifdef SIMULATION_SPI
#define TXD_PORT gLcd_info->txd_pin
#define CLK_PORT gLcd_info->clk_pin
#define CS_PORT gLcd_info->cs_pin
#define LCD_RST_PORT 1
#define CS_OUT() gpio_direction_output(CS_PORT, 0)
#define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
#define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
#define CLK_OUT() gpio_direction_output(CLK_PORT, 0)
#define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
#define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
#define TXD_OUT() gpio_direction_output(TXD_PORT, 0)
#define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
#define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
#define LCD_RST_OUT() gpio_direction_output(LCD_RST_PORT, 0)
#define LCD_RST(i) gpio_set_value(LCD_RST_PORT, i)
#define bits_9 1
#ifdef bits_9 //9bits
#define LCDSPI_InitCMD(cmd) spi_write_9bit(0, cmd)
#define LCDSPI_InitDAT(dat) spi_write_9bit(1, dat)
#else //16bits
#define LCDSPI_InitCMD(cmd)
#define LCDSPI_InitDAT(dat)
#endif
#define Lcd_EnvidOnOff(i)
#else
#define bits_9 1
#ifdef bits_9 //9bits
#define LCDSPI_InitCMD(cmd)
#define LCDSPI_InitDAT(dat)
#else //16bits
#define LCDSPI_InitCMD(cmd)
#define LCDSPI_InitDAT(dat)
#endif
#endif
/* define lcd command */
#define ENTER_SLEEP_MODE 0x10
#define EXIT_SLEEP_MODE 0x11
#define SET_COLUMN_ADDRESS 0x2a
#define SET_PAGE_ADDRESS 0x2b
#define WRITE_MEMORY_START 0x2c
#define SET_DISPLAY_ON 0x29
#define SET_DISPLAY_OFF 0x28
#define SET_ADDRESS_MODE 0x36
#define SET_PIXEL_FORMAT 0x3a
#define DRVDelayUs(i) udelay(i*2)
static struct rk29lcd_info *gLcd_info = NULL;
int lcd_init(void);
int lcd_standby(u32 enable);
/* spi write a data frame,type mean command or data */
int spi_write_9bit(u32 type, u32 value)
{
u32 i = 0;
if(type != 0 && type != 1)
{
return -1;
}
/*make a data frame of 9 bits,the 8th bit 0:mean command,1:mean data*/
value &= 0xff;
value &= (type << 8);
TXD_OUT();
CLK_OUT();
CS_OUT();
DRVDelayUs(2);
DRVDelayUs(2);
CS_SET();
TXD_SET();
CLK_SET();
DRVDelayUs(2);
CS_CLR();
for(i = 0; i < 9; i++) //reg
{
if(value & (1 << (8-i)))
{
TXD_SET();
}
else
{
TXD_CLR();
}
CLK_CLR();
DRVDelayUs(2);
CLK_SET();
DRVDelayUs(2);
}
CS_SET();
CLK_CLR();
TXD_CLR();
DRVDelayUs(2);
return 0;
}
int lcd_init(void)
{
if(gLcd_info)
gLcd_info->io_init();
#if 1
TXD_OUT();
CLK_OUT();
CS_OUT();
CS_SET();
TXD_SET();
CLK_SET();
LCD_RST_OUT();
LCD_RST(1);
msleep(10);
LCD_RST(0);
msleep(100);
LCD_RST(1);
msleep(100);
#endif
#if 1
LCDSPI_InitCMD(0xB9); // SET password
LCDSPI_InitDAT(0xFF);
LCDSPI_InitDAT(0x83);
LCDSPI_InitDAT(0x69);
LCDSPI_InitCMD(0xB1); //Set Power
LCDSPI_InitDAT(0x85);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x34);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x0F);
LCDSPI_InitDAT(0x0F);
LCDSPI_InitDAT(0x2A);
LCDSPI_InitDAT(0x32);
LCDSPI_InitDAT(0x3F);
LCDSPI_InitDAT(0x3F);
LCDSPI_InitDAT(0x01); //update VBIAS
LCDSPI_InitDAT(0x3A);
LCDSPI_InitDAT(0x01);
LCDSPI_InitDAT(0xE6);
LCDSPI_InitDAT(0xE6);
LCDSPI_InitDAT(0xE6);
LCDSPI_InitDAT(0xE6);
LCDSPI_InitDAT(0xE6);
LCDSPI_InitCMD(0xB2); // SET Display 480x800
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x28); //23
LCDSPI_InitDAT(0x05); //03
LCDSPI_InitDAT(0x05); //03
LCDSPI_InitDAT(0x70);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0xFF);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x03);
LCDSPI_InitDAT(0x03);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x01);
LCDSPI_InitCMD(0xB4); // SET Display 480x800
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x18);
LCDSPI_InitDAT(0x80);
LCDSPI_InitDAT(0x06);
LCDSPI_InitDAT(0x02);
LCDSPI_InitCMD(0xB6); // SET VCOM
LCDSPI_InitDAT(0x42); // Update VCOM
LCDSPI_InitDAT(0x42);
LCDSPI_InitCMD(0xD5);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x04);
LCDSPI_InitDAT(0x03);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x01);
LCDSPI_InitDAT(0x05);
LCDSPI_InitDAT(0x28);
LCDSPI_InitDAT(0x70);
LCDSPI_InitDAT(0x01);
LCDSPI_InitDAT(0x03);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x40);
LCDSPI_InitDAT(0x06);
LCDSPI_InitDAT(0x51);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x41);
LCDSPI_InitDAT(0x06);
LCDSPI_InitDAT(0x50);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x0F);
LCDSPI_InitDAT(0x04);
LCDSPI_InitDAT(0x00);
///Gamma2.2
LCDSPI_InitCMD(0xE0);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x13);
LCDSPI_InitDAT(0x19);
LCDSPI_InitDAT(0x38);
LCDSPI_InitDAT(0x3D);
LCDSPI_InitDAT(0x3F);
LCDSPI_InitDAT(0x28);
LCDSPI_InitDAT(0x46);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x0D);
LCDSPI_InitDAT(0x0E);
LCDSPI_InitDAT(0x12);
LCDSPI_InitDAT(0x15);
LCDSPI_InitDAT(0x12);
LCDSPI_InitDAT(0x14);
LCDSPI_InitDAT(0x0F);
LCDSPI_InitDAT(0x17);
LCDSPI_InitDAT(0x00);
LCDSPI_InitDAT(0x13);
LCDSPI_InitDAT(0x19);
LCDSPI_InitDAT(0x38);
LCDSPI_InitDAT(0x3D);
LCDSPI_InitDAT(0x3F);
LCDSPI_InitDAT(0x28);
LCDSPI_InitDAT(0x46);
LCDSPI_InitDAT(0x07);
LCDSPI_InitDAT(0x0D);
LCDSPI_InitDAT(0x0E);
LCDSPI_InitDAT(0x12);
LCDSPI_InitDAT(0x15);
LCDSPI_InitDAT(0x12);
LCDSPI_InitDAT(0x14);
LCDSPI_InitDAT(0x0F);
LCDSPI_InitDAT(0x17);
msleep(10);
///DGC Setting
LCDSPI_InitCMD(0xC1);
LCDSPI_InitDAT(0x01);
//R
LCDSPI_InitDAT(0x04);
LCDSPI_InitDAT(0x13);
LCDSPI_InitDAT(0x1a);
LCDSPI_InitDAT(0x20);
LCDSPI_InitDAT(0x27);
LCDSPI_InitDAT(0x2c);
LCDSPI_InitDAT(0x32);
LCDSPI_InitDAT(0x36);
LCDSPI_InitDAT(0x3f);
LCDSPI_InitDAT(0x47);
LCDSPI_InitDAT(0x50);
LCDSPI_InitDAT(0x59);
LCDSPI_InitDAT(0x60);
LCDSPI_InitDAT(0x68);
LCDSPI_InitDAT(0x71);
LCDSPI_InitDAT(0x7B);
LCDSPI_InitDAT(0x82);
LCDSPI_InitDAT(0x89);
LCDSPI_InitDAT(0x91);
LCDSPI_InitDAT(0x98);
LCDSPI_InitDAT(0xA0);
LCDSPI_InitDAT(0xA8);
LCDSPI_InitDAT(0xB0);
LCDSPI_InitDAT(0xB8);
LCDSPI_InitDAT(0xC1);
LCDSPI_InitDAT(0xC9);
LCDSPI_InitDAT(0xD0);
LCDSPI_InitDAT(0xD7);
LCDSPI_InitDAT(0xE0);
LCDSPI_InitDAT(0xE7);
LCDSPI_InitDAT(0xEF);
LCDSPI_InitDAT(0xF7);
LCDSPI_InitDAT(0xFE);
LCDSPI_InitDAT(0xCF);
LCDSPI_InitDAT(0x52);
LCDSPI_InitDAT(0x34);
LCDSPI_InitDAT(0xF8);
LCDSPI_InitDAT(0x51);
LCDSPI_InitDAT(0xF5);
LCDSPI_InitDAT(0x9D);
LCDSPI_InitDAT(0x75);
LCDSPI_InitDAT(0x00);
//G
LCDSPI_InitDAT(0x04);
LCDSPI_InitDAT(0x13);
LCDSPI_InitDAT(0x1a);
LCDSPI_InitDAT(0x20);
LCDSPI_InitDAT(0x27);
LCDSPI_InitDAT(0x2c);
LCDSPI_InitDAT(0x32);
LCDSPI_InitDAT(0x36);
LCDSPI_InitDAT(0x3f);
LCDSPI_InitDAT(0x47);
LCDSPI_InitDAT(0x50);
LCDSPI_InitDAT(0x59);
LCDSPI_InitDAT(0x60);
LCDSPI_InitDAT(0x68);
LCDSPI_InitDAT(0x71);
LCDSPI_InitDAT(0x7B);
LCDSPI_InitDAT(0x82);
LCDSPI_InitDAT(0x89);
LCDSPI_InitDAT(0x91);
LCDSPI_InitDAT(0x98);
LCDSPI_InitDAT(0xA0);
LCDSPI_InitDAT(0xA8);
LCDSPI_InitDAT(0xB0);
LCDSPI_InitDAT(0xB8);
LCDSPI_InitDAT(0xC1);
LCDSPI_InitDAT(0xC9);
LCDSPI_InitDAT(0xD0);
LCDSPI_InitDAT(0xD7);
LCDSPI_InitDAT(0xE0);
LCDSPI_InitDAT(0xE7);
LCDSPI_InitDAT(0xEF);
LCDSPI_InitDAT(0xF7);
LCDSPI_InitDAT(0xFE);
LCDSPI_InitDAT(0xCF);
LCDSPI_InitDAT(0x52);
LCDSPI_InitDAT(0x34);
LCDSPI_InitDAT(0xF8);
LCDSPI_InitDAT(0x51);
LCDSPI_InitDAT(0xF5);
LCDSPI_InitDAT(0x9D);
LCDSPI_InitDAT(0x75);
LCDSPI_InitDAT(0x00);
//B
LCDSPI_InitDAT(0x04);
LCDSPI_InitDAT(0x13);
LCDSPI_InitDAT(0x1a);
LCDSPI_InitDAT(0x20);
LCDSPI_InitDAT(0x27);
LCDSPI_InitDAT(0x2c);
LCDSPI_InitDAT(0x32);
LCDSPI_InitDAT(0x36);
LCDSPI_InitDAT(0x3f);
LCDSPI_InitDAT(0x47);
LCDSPI_InitDAT(0x50);
LCDSPI_InitDAT(0x59);
LCDSPI_InitDAT(0x60);
LCDSPI_InitDAT(0x68);
LCDSPI_InitDAT(0x71);
LCDSPI_InitDAT(0x7B);
LCDSPI_InitDAT(0x82);
LCDSPI_InitDAT(0x89);
LCDSPI_InitDAT(0x91);
LCDSPI_InitDAT(0x98);
LCDSPI_InitDAT(0xA0);
LCDSPI_InitDAT(0xA8);
LCDSPI_InitDAT(0xB0);
LCDSPI_InitDAT(0xB8);
LCDSPI_InitDAT(0xC1);
LCDSPI_InitDAT(0xC9);
LCDSPI_InitDAT(0xD0);
LCDSPI_InitDAT(0xD7);
LCDSPI_InitDAT(0xE0);
LCDSPI_InitDAT(0xE7);
LCDSPI_InitDAT(0xEF);
LCDSPI_InitDAT(0xF7);
LCDSPI_InitDAT(0xFE);
LCDSPI_InitDAT(0xCF);
LCDSPI_InitDAT(0x52);
LCDSPI_InitDAT(0x34);
LCDSPI_InitDAT(0xF8);
LCDSPI_InitDAT(0x51);
LCDSPI_InitDAT(0xF5);
LCDSPI_InitDAT(0x9D);
LCDSPI_InitDAT(0x75);
LCDSPI_InitDAT(0x00);
msleep(10);
//LCDSPI_InitCMD(0x36);
//LCDSPI_InitDAT(0x80); //µ÷Õû36HÖеIJÎÊý¿ÉÒÔʵÏÖGATEºÍSOURCEµÄ·­×ª
LCDSPI_InitCMD(SET_PIXEL_FORMAT);
LCDSPI_InitDAT(0x77);
LCDSPI_InitCMD(EXIT_SLEEP_MODE);
msleep(120);
LCDSPI_InitCMD(SET_DISPLAY_ON);
LCDSPI_InitCMD(WRITE_MEMORY_START);
#endif
if(gLcd_info)
gLcd_info->io_deinit();
return 0;
}
int lcd_standby(u32 enable)
{
if(gLcd_info)
gLcd_info->io_init();
if(enable) {
Lcd_EnvidOnOff(0); //RGB TIMENG OFF
LCDSPI_InitCMD(ENTER_SLEEP_MODE);
Lcd_EnvidOnOff(1); //RGB TIMENG ON
msleep(200);
Lcd_EnvidOnOff(0); //RGB TIMENG OFF
msleep(100);
} else {
//LCD_RESET();
LCDSPI_InitCMD(EXIT_SLEEP_MODE);
msleep(200);
Lcd_EnvidOnOff(1); //RGB TIMENG ON
msleep(200);
}
if(gLcd_info)
gLcd_info->io_deinit();
return 0;
}
void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info )
{
/* screen type & face */
screen->type = OUT_TYPE;
screen->face = OUT_FACE;
/* Screen size */
screen->x_res = H_VD;
screen->y_res = V_VD;
screen->width = LCD_WIDTH;
screen->height = LCD_HEIGHT;
/* Timing */
screen->lcdc_aclk = LCDC_ACLK;
screen->pixclock = OUT_CLK;
screen->left_margin = H_BP;
screen->right_margin = H_FP;
screen->hsync_len = H_PW;
screen->upper_margin = V_BP;
screen->lower_margin = V_FP;
screen->vsync_len = V_PW;
/* Pin polarity */
screen->pin_hsync = 0;
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = DCLK_POL;
/* Swap rule */
screen->swap_rb = SWAP_RB;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = lcd_init;
screen->standby = lcd_standby;
if(lcd_info)
gLcd_info = lcd_info;
}

View File

@ -34,7 +34,7 @@ typedef enum _MCU_STATUS {
} MCU_STATUS;
/* Sceen description */
/* Screen description */
struct rk29fb_screen {
/* screen type & out face */
u16 type;
@ -77,10 +77,10 @@ struct rk29fb_screen {
/* Operation function*/
int (*init)(void);
int (*standby)(u8 enable);
int (*refresh)(u8 arg);
int (*scandir)(u16 dir);
int (*disparea)(u8 area);
int (*standby)(u32 enable);
int (*refresh)(u32 arg);
int (*scandir)(u32 dir);
int (*disparea)(u32 area);
};

View File

@ -195,6 +195,7 @@ struct rk29fb_inf {
struct clk *aclk_ddr_lcdc; //DDR LCDC AXI clock disable.
struct clk *aclk_disp_matrix; //DISPLAY matrix AXI clock disable.
struct clk *hclk_cpu_display; //CPU DISPLAY AHB bus clock disable.
struct clk *pd_display; // display power domain
unsigned long dclk_rate;
/* lcdc reg base address and backup reg */
@ -455,7 +456,12 @@ int init_lcdc(struct fb_info *info)
inf->aclk_ddr_lcdc = clk_get(NULL, "aclk_ddr_lcdc");
inf->aclk_disp_matrix = clk_get(NULL, "aclk_disp_matrix");
inf->hclk_cpu_display = clk_get(NULL, "hclk_cpu_display");
if ((IS_ERR(inf->clk)) || (IS_ERR(inf->aclk_ddr_lcdc)) || (IS_ERR(inf->aclk_disp_matrix)) ||(IS_ERR(inf->hclk_cpu_display)))
inf->pd_display = clk_get(NULL, "pd_display");
if ((IS_ERR(inf->clk)) ||
(IS_ERR(inf->aclk_ddr_lcdc)) ||
(IS_ERR(inf->aclk_disp_matrix)) ||
(IS_ERR(inf->hclk_cpu_display)) ||
(IS_ERR(inf->pd_display)))
{
printk(KERN_ERR "failed to get lcdc_hclk source\n");
return PTR_ERR(inf->clk);
@ -463,7 +469,8 @@ int init_lcdc(struct fb_info *info)
clk_enable(inf->aclk_disp_matrix);
clk_enable(inf->hclk_cpu_display);
clk_enable(inf->clk);
pmu_set_power_domain(PD_DISPLAY, 1);
clk_enable(inf->pd_display);
//pmu_set_power_domain(PD_DISPLAY, 1);
clk_enable(inf->aclk_ddr_lcdc);
// set AHB access rule and disable all windows
@ -2175,7 +2182,8 @@ static int rk29fb_suspend(struct platform_device *pdev, pm_message_t mesg)
if(inf->clk){
clk_disable(inf->aclk);
}
pmu_set_power_domain(PD_DISPLAY, 0);
clk_disable(inf->pd_display);
//pmu_set_power_domain(PD_DISPLAY, 0);
inf->in_suspend = 1;
}
return 0;
@ -2200,7 +2208,8 @@ static int rk29fb_resume(struct platform_device *pdev)
clk_enable(inf->aclk_disp_matrix);
clk_enable(inf->hclk_cpu_display);
clk_enable(inf->clk);
pmu_set_power_domain(PD_DISPLAY, 1);
clk_enable(inf->pd_display);
//pmu_set_power_domain(PD_DISPLAY, 1);
clk_enable(inf->aclk_ddr_lcdc);
if (inf->dclk){
@ -2662,7 +2671,8 @@ static void rk29fb_shutdown(struct platform_device *pdev)
if(inf->clk){
clk_disable(inf->aclk);
}
pmu_set_power_domain(PD_DISPLAY, 0);
clk_disable(inf->pd_display);
//pmu_set_power_domain(PD_DISPLAY, 0);
inf->in_suspend = 1;
}
@ -2693,9 +2703,7 @@ static void __exit rk29fb_exit(void)
platform_driver_unregister(&rk29fb_driver);
}
//subsys_initcall(rk29fb_init);
module_init(rk29fb_init);
fs_initcall(rk29fb_init);
module_exit(rk29fb_exit);

View File

@ -31,6 +31,9 @@ struct adc_request {
struct adc_client *client;
/* Used in case of sync requests */
struct completion completion;
#define ASYNC_READ 0
#define SYNC_READ 1
int status;
};
struct adc_host;
struct adc_ops {

23
include/linux/leds-att1272.h Executable file
View File

@ -0,0 +1,23 @@
/*
* leds-att1272.c - LED Driver
*
* Copyright (C) 2011 Rockchips
* deng dalong <ddl@rock-chips.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 as
* published by the Free Software Foundation.
*
* Datasheet: http://www.rohm.com/products/databook/driver/pdf/att1272gu-e.pdf
*
*/
#ifndef _LEDS_ATT1272_H_
#define _LEDS_ATT1272_H_
struct att1272_led_platform_data {
const char *name;
int en_gpio;
int flen_gpio;
};
#endif /* _LEDS_ATT1272_H_ */

View File

@ -99,6 +99,7 @@ struct mmc_card {
#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
@ -139,6 +140,11 @@ static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
return c->quirks & MMC_QUIRK_LENIENT_FN0;
}
static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
{
return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
}
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev))

View File

@ -107,6 +107,9 @@ struct mmc_host_ops {
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
/* optional callback for HC quirks */
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
};
struct mmc_card;