rk29: remove newton board support

This commit is contained in:
黄涛
2012-08-23 10:39:29 +08:00
parent 4d93acfd39
commit 4bb8de2238
18 changed files with 0 additions and 6415 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -56,12 +56,6 @@ config MACH_RK29_PHONEPADSDK
help
Support for the ROCKCHIP Board For Rk29 Phone Pad Sdk.
config MACH_RK29_newton
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For project newton"
help
Support for the ROCKCHIP Board For project newton.
config MACH_RK29_PHONE_Z5
depends on ARCH_RK29
bool "ROCKCHIP Board Rk29 For Z5"
@@ -70,12 +64,6 @@ config MACH_RK29_PHONE_Z5
endchoice
config RK29_NEWTON_CLOCK
depends on MACH_RK29_newton
bool "enable newton 1.2G cpu clock support"
help
support for newton 1.2G cpu clock.
config RK29_MEM_SIZE_M
int "DDR Memory size (in MB)"
default 512

View File

@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_RK29FIH) += board-rk29-fih.o board-rk29-fih-key.o board-rk29sd
obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-a22-rfkill.o
obj-$(CONFIG_MACH_RK29_TD8801_V2) += board-rk29-td8801_v2.o board-rk29-td8801_v2-key.o board-rk29-td8801_v2-rfkill.o
obj-$(CONFIG_MACH_RK29_PHONEPADSDK) += board-rk29phonepadsdk.o board-rk29phonepadsdk-key.o board-rk29phonepadsdk-rfkill.o board-rk29phonepadsdk-power.o
obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-newton-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_RK29_CHARGE_EARLYSUSPEND) += rk29_charge_lowpower.o
obj-$(CONFIG_MACH_RK29_K97) += board-rk29-k97.o board-rk29k97-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_MACH_RK29_PHONE_Z5) += board-rk29-z5.o board-rk29-z5-key.o board-rk29-z5-rfkill.o

View File

@@ -1,296 +0,0 @@
/*
* 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);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʱֵ<CAB1><D6B5>
}
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)); //<2F><>ϵͳ˯<CDB3><CBAF>
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(200);
gpio_set_value(BT_GPIO_RESET, GPIO_HIGH); /* bt reset deactive*/
mdelay(200);
#if BT_WAKE_HOST_SUPPORT
btWakeupHostLock();
#endif
pr_info("bt turn on power\n");
}
else {
#if BT_WAKE_HOST_SUPPORT
btWakeupHostUnlock();
#endif
// cwz 0: close for bt uart2 larkage.
#if 0
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");
}
#endif
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 __devinit 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));//ɾ<><C9BE><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
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");

View File

@@ -1,60 +0,0 @@
#include <mach/key.h>
#include <mach/gpio.h>
#include <mach/board.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_PA3, // PA0--> PA3: home -> menu
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "vol+",
.code = KEY_VOLUMEUP,
.gpio = RK29_PIN6_PA2,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "vol-",
.code = KEY_VOLUMEDOWN,
.gpio = RK29_PIN6_PA1,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "home",
.code = KEY_HOME,
.gpio = RK29_PIN6_PA5, //PA3 --> PA5
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "esc",
.code = KEY_BACK,
.gpio = RK29_PIN6_PA0, //PA5-->PA0: menu-> esc
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "play",
.code = KEY_POWER,
.gpio = RK29_PIN6_PA7,
.active_low = PRESS_LEV_LOW,
.wakeup = 1,
},
};
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
};

File diff suppressed because it is too large Load Diff

View File

@@ -19,12 +19,6 @@ config KEYS_RK29
help
rk29 keyboard drivers(gpio and adc)
config KEYS_RK29_NEWTON
tristate "rk29 newton keyboard"
depends on ARCH_RK29
help
rk29 newton keyboard drivers(gpio and adc)
config SYNAPTICS_SO340010
tristate "Synaptics So340010 TouchPad KEY"
depends on I2C

View File

@@ -5,7 +5,6 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYS_RK29) += rk29_keys.o
obj-$(CONFIG_KEYS_RK29_NEWTON) += rk29_newton_keys.o
obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
obj-$(CONFIG_KEYBOARD_ADP5589) += adp5589-keys.o

View File

@@ -1,411 +0,0 @@
/*
* Driver for keys on GPIO lines capable of generating interrupts.
*
* Copyright 2005 Phil Blundell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/adc.h>
#include <linux/earlysuspend.h>
#include <asm/gpio.h>
#include <mach/key.h>
#include <mach/board.h>
#define EMPTY_ADVALUE 950
#define DRIFT_ADVALUE 70
#define INVALID_ADVALUE 10
#if 0
#define key_dbg(bdata, format, arg...) \
dev_printk(KERN_INFO , &bdata->input->dev , format , ## arg)
#else
#define key_dbg(bdata, format, arg...)
#endif
struct rk29_button_data {
int state;
int long_press_count;
struct rk29_keys_button *button;
struct input_dev *input;
struct timer_list timer;
};
struct rk29_keys_drvdata {
int nbuttons;
int result;
struct input_dev *input;
struct adc_client *client;
struct timer_list timer;
struct rk29_button_data data[0];
};
static struct input_dev *input_dev;
static struct early_suspend newton_key_power;
static int suspend = 0;
void rk29_send_power_key(int state)
{
if (!input_dev)
return;
if(state)
{
input_report_key(input_dev, KEY_POWER, 1);
input_sync(input_dev);
}
else
{
input_report_key(input_dev, KEY_POWER, 0);
input_sync(input_dev);
}
}
void rk28_send_wakeup_key(void)
{
if (!input_dev)
return;
input_report_key(input_dev, KEY_WAKEUP, 1);
input_sync(input_dev);
input_report_key(input_dev, KEY_WAKEUP, 0);
input_sync(input_dev);
}
static void keys_long_press_timer(unsigned long _data)
{
int state;
struct rk29_button_data *bdata = (struct rk29_button_data *)_data;
struct rk29_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = EV_KEY;
if(button->gpio != INVALID_GPIO )
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low);
else
state = !!button->adc_state;
if(state) {
if(bdata->long_press_count != 0) {
if(bdata->long_press_count % (LONG_PRESS_COUNT+ONE_SEC_COUNT) == 0){
key_dbg(bdata, "%skey[%s]: report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 0);
input_sync(input);
}
else if(bdata->long_press_count%LONG_PRESS_COUNT == 0) {
key_dbg(bdata, "%skey[%s]: report ev[%d] state[1]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 1);
input_sync(input);
}
}
bdata->long_press_count++;
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
}
else {
if(bdata->long_press_count <= LONG_PRESS_COUNT) {
bdata->long_press_count = 0;
key_dbg(bdata, "%skey[%s]: report ev[%d] state[1], report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code, button->code);
input_event(input, type, button->code, 1);
input_sync(input);
input_event(input, type, button->code, 0);
input_sync(input);
}
else if(bdata->state != state) {
key_dbg(bdata, "%skey[%s]: report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 0);
input_sync(input);
}
}
bdata->state = state;
}
static void keys_timer(unsigned long _data)
{
int state;
struct rk29_button_data *bdata = (struct rk29_button_data *)_data;
struct rk29_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = EV_KEY;
if((suspend)&&(!button->wakeup))
return;
if(button->gpio != INVALID_GPIO)
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low);
else
state = !!button->adc_state;
if(bdata->state != state) {
bdata->state = state;
key_dbg(bdata, "%skey[%s]: report ev[%d] state[%d]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code, bdata->state);
input_event(input, type, button->code, bdata->state);
input_sync(input);
}
if(state)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
}
static irqreturn_t keys_isr(int irq, void *dev_id)
{
struct rk29_button_data *bdata = dev_id;
struct rk29_keys_button *button = bdata->button;
BUG_ON(irq != gpio_to_irq(button->gpio));
bdata->long_press_count = 0;
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
return IRQ_HANDLED;
}
static void newton_key_early_suspend(struct early_suspend *h);
static void newton_key_last_resume(struct early_suspend *h);
static int __devinit keys_probe(struct platform_device *pdev)
{
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
struct rk29_keys_drvdata *ddata;
struct input_dev *input;
int i, error = 0;
int wakeup = 0;
if(!pdata)
return -EINVAL;
ddata = kzalloc(sizeof(struct rk29_keys_drvdata) +
pdata->nbuttons * sizeof(struct rk29_button_data),
GFP_KERNEL);
input = input_allocate_device();
if (!ddata || !input) {
error = -ENOMEM;
goto fail0;
}
platform_set_drvdata(pdev, ddata);
input->name = pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
/* Enable auto repeat feature of Linux input subsystem */
if (pdata->rep)
__set_bit(EV_REP, input->evbit);
ddata->nbuttons = pdata->nbuttons;
ddata->input = input;
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
struct rk29_button_data *bdata = &ddata->data[i];
int irq;
unsigned int type = EV_KEY;
bdata->input = input;
bdata->button = button;
if(button->code_long_press)
setup_timer(&bdata->timer,
keys_long_press_timer, (unsigned long)bdata);
else if(button->code)
setup_timer(&bdata->timer,
keys_timer, (unsigned long)bdata);
if(button->gpio != INVALID_GPIO) {
error = gpio_request(button->gpio, button->desc ?: "keys");
if (error < 0) {
pr_err("gpio-keys: failed to request GPIO %d,"
" error %d\n", button->gpio, error);
goto fail2;
}
error = gpio_direction_input(button->gpio);
if (error < 0) {
pr_err("gpio-keys: failed to configure input"
" direction for GPIO %d, error %d\n",
button->gpio, error);
gpio_free(button->gpio);
goto fail2;
}
irq = gpio_to_irq(button->gpio);
if (irq < 0) {
error = irq;
pr_err("gpio-keys: Unable to get irq number"
" for GPIO %d, error %d\n",
button->gpio, error);
gpio_free(button->gpio);
goto fail2;
}
error = request_irq(irq, keys_isr,
(button->active_low)?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING,
button->desc ? button->desc : "keys",
bdata);
if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
gpio_free(button->gpio);
goto fail2;
}
}
if (button->wakeup)
wakeup = 1;
input_set_capability(input, type, button->code);
}
input_set_capability(input, EV_KEY, KEY_WAKEUP);
error = input_register_device(input);
if (error) {
pr_err("gpio-keys: Unable to register input device, "
"error: %d\n", error);
goto fail2;
}
device_init_wakeup(&pdev->dev, wakeup);
input_dev = input;
newton_key_power.suspend = newton_key_early_suspend;
newton_key_power.resume = newton_key_last_resume;
newton_key_power.level = 0x2;
register_early_suspend(&newton_key_power);
return error;
fail2:
while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
}
platform_set_drvdata(pdev, NULL);
fail0:
input_free_device(input);
kfree(ddata);
return error;
}
static int __devexit keys_remove(struct platform_device *pdev)
{
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
struct rk29_keys_drvdata *ddata = platform_get_drvdata(pdev);
struct input_dev *input = ddata->input;
int i;
input_dev = NULL;
device_init_wakeup(&pdev->dev, 0);
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, &ddata->data[i]);
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
}
if(pdata->chn >= 0 && ddata->client);
adc_unregister(ddata->client);
input_unregister_device(input);
return 0;
}
#ifdef CONFIG_PM
static int keys_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = gpio_to_irq(button->gpio);
enable_irq_wake(irq);
}
}
}
return 0;
}
static int keys_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = gpio_to_irq(button->gpio);
disable_irq_wake(irq);
}
}
}
return 0;
}
static void newton_key_early_suspend(struct early_suspend *h)
{
suspend = 1;
}
static void newton_key_last_resume(struct early_suspend *h)
{
suspend = 0;
}
static const struct dev_pm_ops keys_pm_ops = {
.suspend = keys_suspend,
.resume = keys_resume,
};
#endif
static struct platform_driver keys_device_driver = {
.probe = keys_probe,
.remove = __devexit_p(keys_remove),
.driver = {
.name = "rk29-keypad",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &keys_pm_ops,
#endif
}
};
static int __init keys_init(void)
{
return platform_driver_register(&keys_device_driver);
}
static void __exit keys_exit(void)
{
platform_driver_unregister(&keys_device_driver);
}
module_init(keys_init);
module_exit(keys_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
MODULE_ALIAS("platform:gpio-keys");

View File

@@ -199,14 +199,6 @@ config LEDS_GPIO_OF
of_platform devices. For instance, LEDs which are listed in a "dts"
file.
config LEDS_NEWTON_PWM
bool "LED Support for newton pwm"
depends on LEDS_CLASS&&ARCH_RK29
default n
help
Let the leds-gpio driver drive LEDs which have been defined as
platform devices. If you don't know what this means, say yes.
config LEDS_LP3944
tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
depends on LEDS_CLASS

View File

@@ -35,7 +35,6 @@ 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
obj-$(CONFIG_LEDS_NEWTON_PWM) += leds-newton-pwm.o
obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o

View File

@@ -1,304 +0,0 @@
/*
* linux/drivers/leds-newton-pwm.c
*
* simple PWM based LED control
*
* Copyright 2009 LMC @ rock-chips (lmc@rock-chips.com)
*
* based on leds-gpio.c by Raphael Assenat <raph@8d.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.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <mach/iomux.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/regulator/rk29-pwm-regulator.h>
#include <linux/ctype.h>
#include <mach/board.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
#define LED_PWM_DIV PWM_DIV1024 /*for led the pwm per div 1024 on the register*/
#define LED_PER_DIV 1000
#define LED_PWM_FULL 255
static struct clk *pwm_clk;
struct led_newton_pwm_data {
struct led_classdev cdev;
unsigned int pwm_id;
unsigned pwm_gpio;
char* pwm_iomux_name;
unsigned int pwm_iomux_pwm;
unsigned int pwm_iomux_gpio;
unsigned int freq;/**/
unsigned int period;/*1-100*/
};
static void led_newton_pwm_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct led_newton_pwm_data *led_dat =
container_of(led_cdev, struct led_newton_pwm_data, cdev);
unsigned int period = led_dat->period;
DBG("Enter %s, brightness = %d,period =%d,freq =%d\n",__FUNCTION__,brightness,period, led_dat->freq);
if (brightness == 0||period == 0) {
// iomux pwm to gpio
rk29_mux_api_set(led_dat->pwm_iomux_name, led_dat->pwm_iomux_gpio);
// set gpio to low level
gpio_set_value(led_dat->pwm_gpio,GPIO_LOW);
}else if(period == LED_PWM_FULL){
// iomux pwm to gpio
rk29_mux_api_set(led_dat->pwm_iomux_name, led_dat->pwm_iomux_gpio);
// set gpio to high level
gpio_set_value(led_dat->pwm_gpio,GPIO_HIGH);
} else {
u32 divh,divTotal;
int id = led_dat->pwm_id;
unsigned long clkrate;
clkrate = clk_get_rate(pwm_clk);
// iomux pwm
rk29_mux_api_set(led_dat->pwm_iomux_name, led_dat->pwm_iomux_pwm);
pwm_write_reg(id,PWM_REG_CTRL, LED_PWM_DIV|PWM_RESET);
divh = clkrate >> (1+(LED_PWM_DIV>>9));/*the register pre div*/
divh = divh* led_dat->freq/LED_PER_DIV;
pwm_write_reg(id,PWM_REG_LRC,(divh == 0)?1:divh);
divTotal =pwm_read_reg(id,PWM_REG_LRC);
divh = divTotal*period/LED_PWM_FULL;
pwm_write_reg(id, PWM_REG_HRC, divh?divh:1);
pwm_write_reg(id,PWM_REG_CNTR,0);
pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|LED_PWM_DIV|PWM_ENABLE|PWM_TimeEN);
}
}
static ssize_t led_newton_freq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_newton_pwm_data *led_dat =
container_of(led_cdev, struct led_newton_pwm_data, cdev);
return sprintf(buf, "%u\n", led_dat->freq);
}
static ssize_t led_newton_freq_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_newton_pwm_data *led_dat =
container_of(led_cdev, struct led_newton_pwm_data, cdev);
ssize_t ret = -EINVAL;
char *after;
unsigned long state = simple_strtoul(buf, &after, 10);
size_t count = after - buf;
if (*after && isspace(*after))
count++;
if (count == size) {
ret = count;
if(state)
led_dat->freq = state;
led_newton_pwm_set( led_cdev, led_cdev->brightness);
}
return ret;
}
static ssize_t led_newton_period_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_newton_pwm_data *led_dat =
container_of(led_cdev, struct led_newton_pwm_data, cdev);
return sprintf(buf, "%u\n", led_dat->period);
}
static ssize_t led_newton_period_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_newton_pwm_data *led_dat =
container_of(led_cdev, struct led_newton_pwm_data, cdev);
ssize_t ret = -EINVAL;
char *after;
unsigned long state = simple_strtoul(buf, &after, 10);
size_t count = after - buf;
if (*after && isspace(*after))
count++;
if (count == size) {
ret = count;
led_dat->period = state;
led_newton_pwm_set( led_cdev, led_cdev->brightness);
}
return ret;
}
static DEVICE_ATTR(freq, 0644, led_newton_freq_show, led_newton_freq_store);
static DEVICE_ATTR(period, 0644, led_newton_period_show, led_newton_period_store);
static int led_newton_pwm_probe(struct platform_device *pdev)
{
struct led_newton_pwm_platform_data *pdata = pdev->dev.platform_data;
struct led_newton_pwm *cur_led;
struct led_newton_pwm_data *leds_data, *led_dat;
int i, ret = 0;
if (!pdata)
return -EBUSY;
leds_data = kzalloc(sizeof(struct led_newton_pwm_data) * pdata->num_leds,
GFP_KERNEL);
if (!leds_data)
return -ENOMEM;
for (i = 0; i < pdata->num_leds; i++) {
cur_led = &pdata->leds[i];
led_dat = &leds_data[i];
ret = gpio_request(cur_led->pwm_gpio,"pwm");
if (ret) {
dev_err(&pdev->dev,"failed to request pwm gpio\n");
goto err;
}
if (cur_led->pwm_id >2) {
dev_err(&pdev->dev, "unable to request PWM %d\n",
cur_led->pwm_id);
goto err;
}
led_dat->cdev.name = cur_led->name;
led_dat->pwm_id = cur_led->pwm_id;
led_dat->pwm_gpio = cur_led->pwm_gpio;
led_dat->pwm_iomux_name = cur_led->pwm_iomux_name;
led_dat->pwm_iomux_pwm = cur_led->pwm_iomux_pwm;
led_dat->pwm_iomux_gpio = cur_led->pwm_iomux_gpio;
if(cur_led->freq)
led_dat->freq = cur_led->freq;
else
led_dat->freq = 1;
led_dat->period = cur_led->period;
led_dat->cdev.brightness_set = led_newton_pwm_set;
led_dat->cdev.brightness = LED_FULL;
led_dat->cdev.flags = 0;
ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
if (ret < 0) {
goto err;
}
ret = device_create_file(led_dat->cdev.dev, &dev_attr_freq);
if (ret)
goto err;
ret = device_create_file(led_dat->cdev.dev, &dev_attr_period);
if(ret)
{
device_remove_file(led_dat->cdev.dev, &dev_attr_freq);
goto err;
}
}
pwm_clk = clk_get(NULL, "pwm");
clk_enable(pwm_clk);
platform_set_drvdata(pdev, leds_data);
return 0;
err:
if (i > 0) {
for (i = i - 1; i >= 0; i--) {
led_classdev_unregister(&leds_data[i].cdev);
gpio_free(leds_data[i].pwm_gpio);
}
}
kfree(leds_data);
return ret;
}
static int __devexit led_newton_pwm_remove(struct platform_device *pdev)
{
int i;
struct led_newton_pwm_platform_data *pdata = pdev->dev.platform_data;
struct led_newton_pwm_data *leds_data;
leds_data = platform_get_drvdata(pdev);
for (i = 0; i < pdata->num_leds; i++) {
led_classdev_unregister(&leds_data[i].cdev);
gpio_free(leds_data[i].pwm_gpio);
}
kfree(leds_data);
return 0;
}
int led_newton_pwm_suspend(struct platform_device *pdev, pm_message_t state)
{
return 1;
}
int led_newton_pwm_resume(struct platform_device *pdev)
{
return 1;
}
static struct platform_driver led_newton_pwm_driver = {
.probe = led_newton_pwm_probe,
.remove = __devexit_p(led_newton_pwm_remove),
.driver = {
.name = "leds_newton_pwm",
.owner = THIS_MODULE,
},
};
static int __init led_newton_pwm_init(void)
{
return platform_driver_register(&led_newton_pwm_driver);
}
static void __exit led_newton_pwm_exit(void)
{
platform_driver_unregister(&led_newton_pwm_driver);
}
module_init(led_newton_pwm_init);
module_exit(led_newton_pwm_exit);
MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
MODULE_DESCRIPTION("PWM LED driver for PXA");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:leds-pwm");

View File

@@ -532,10 +532,6 @@ config MTK23D
config FM580X
bool "FM rda580x driver"
config RK29_NEWTON
bool "RK29_NEWTON misc driver"
config RK29_SC8800
bool "SC8800 misc driver"
default n

View File

@@ -56,6 +56,5 @@ obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/
obj-$(CONFIG_3G_MODULE) += 3g_module/
obj-$(CONFIG_GPS_GNS7560) += gps/
obj-y += inv_mpu/
obj-$(CONFIG_RK29_NEWTON) += newton.o
obj-$(CONFIG_TDSC8800) += tdsc8800.o
obj-$(CONFIG_RK29_SC8800) += sc8800.o

View File

@@ -1,283 +0,0 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <asm/types.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <linux/wait.h>
#include <mach/board.h>
#define NEWTON_DEV "newton:"
#if 1
#define DBG(x...) printk(KERN_INFO NEWTON_DEV x)
#else
#define DBG(x...)
#endif
#define NEWTON_GPIO_R RK29_PIN4_PB0
#define NEWTON_GPIO_G RK29_PIN4_PB1
#define NEWTON_GPIO_B RK29_PIN4_PB2
#define NEWTON_GPIO_AC_DETEC RK29_PIN4_PA1
#define NEWTON_GPIO_GPS_PWR RK29_PIN6_PB2
#define NEWTON_IDBDATA_SIZE 512
#define NEWTON_GET_IDBDATA 0x600F
#define NEWTON_GET_UID 0x6001
#define NEWTON_AC_DETEC 0x6002
#define NEWTON_GPS_CTRL 0x6003
typedef struct{
uint16_t SN_Size; //0-1
char SN[30]; //2-31
char Reserved[419]; //32-450
char IMEI_Size; //451
char IMEI_Data[15]; //452-466
char UID_Size; //467
char UID_Data[30]; //468-497
char BT_Size; //498
char BlueTooth[6]; //499-504
char Mac_Size; //505
char Mac_Data[6]; //506-511
}IdbSector3;
int gps_power = 0;
char GetSNSectorInfo(char * pbuf);
int newton_print_buf(char *buf,int size)
{
int i,j,mo=size%16,line = size/16;
char *pbuf = buf;
if(line>0)
{
for(i=0;i<line;i++)
{
for(j=0;j<16;j++)
{
printk("0x%02x ",*pbuf);
pbuf++;
}
printk("\n");
}
}
for(j=0;j<mo;j++)
{
printk("0x%02x ",*pbuf);
pbuf++;
}
return 0;
}
int rk29_newton_get_ac_status()
{
int ac_status = 0;
gpio_direction_input(NEWTON_GPIO_AC_DETEC);
ac_status = gpio_get_value(NEWTON_GPIO_AC_DETEC);
DBG("%s:NEWTON_GPIO_AC_DETEC = %d\n",__FUNCTION__,ac_status);
return ac_status;
}
int rk29_newton_set_gps_power(int value)
{
DBG("%s:value = %d\n",__FUNCTION__,value);
gpio_direction_output(NEWTON_GPIO_GPS_PWR, 0);
gpio_set_value(NEWTON_GPIO_GPS_PWR,value);
return 0;
}
int rk29_newton_open(struct inode *inode, struct file *filp)
{
DBG("%s\n",__FUNCTION__);
return 0;
}
ssize_t rk29_newton_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos)
{
DBG("%s\n",__FUNCTION__);
return sizeof(int);
}
ssize_t rk29_newton_write(struct file *filp, char __user *ptr, size_t size, loff_t *pos)
{
DBG("%s\n",__FUNCTION__);
return sizeof(int);
}
int rk29_newton_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
//DBG("%s\n",__FUNCTION__);
switch(cmd)
{
case NEWTON_GET_UID:
{
IdbSector3 sn;
DBG("%s:NEWTON_GET_UID\n",__FUNCTION__);
memset(&sn,0,sizeof(IdbSector3));
GetSNSectorInfo((char*)&sn);
//newton_print_buf(&sn.UID_Data, sizeof(sn.UID_Data));
if(copy_to_user(argp, &sn.UID_Data, sizeof(sn.UID_Data))) return -EFAULT;
}
break;
case NEWTON_GET_IDBDATA:
{
char data[NEWTON_IDBDATA_SIZE];
memset(data, 0, NEWTON_IDBDATA_SIZE);
GetSNSectorInfo(data);
if(copy_to_user(argp, data, NEWTON_IDBDATA_SIZE))
return -EFAULT;
}
break;
/*
case NEWTON_AC_DETEC:
{
int ac_status = rk29_newton_get_ac_status();
if(copy_to_user(argp, &ac_status, 4)) return -EFAULT;
}
break;
*/
case NEWTON_GPS_CTRL:
{
int value = 0;
if(copy_from_user(&value, (void*)arg, 4)){
DBG("%s:NEWTON_GPS_CTRL,copy_from_user error\n",__FUNCTION__);
return -EFAULT;
}
if((value != 0) && (value != 1)){
DBG("%s:NEWTON_GPS_CTRL,parameter error,value = %d\n",__FUNCTION__,value);
return -EFAULT;
}
gps_power = value;
rk29_newton_set_gps_power(value);
}
break;
default:
break;
}
return 0;
}
int rk29_newton_release(struct inode *inode, struct file *filp)
{
DBG("%s\n",__FUNCTION__);
return 0;
}
static struct file_operations rk29_newton_fops = {
.owner = THIS_MODULE,
.open = rk29_newton_open,
//.read = rk29_newton_read,
//.write = rk29_newton_write,
.ioctl = rk29_newton_ioctl,
//.release = rk29_newton_release,
};
static struct miscdevice rk29_newton_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "newton",
.fops = &rk29_newton_fops,
};
static int rk29_newton_probe(struct platform_device *pdev)
{
int ret = 0;
struct rk29_newton_data *pdata = pdev->dev.platform_data;
if(!pdata)
return -1;
DBG("%s",__FUNCTION__);
ret = misc_register(&rk29_newton_dev);
if (ret < 0){
printk("rk29 newton register err!\n");
return ret;
}
if(gpio_request(NEWTON_GPIO_GPS_PWR,NULL) != 0){
gpio_free(NEWTON_GPIO_GPS_PWR);
printk("gpio_request NEWTON_GPIO_GPS_PWR error\n");
return -EIO;
}
/*
if(gpio_request(NEWTON_GPIO_AC_DETEC,NULL) != 0){
gpio_free(NEWTON_GPIO_AC_DETEC);
printk("gpio_request NEWTON_GPIO_AC_DETEC error\n");
return -EIO;
}
*/
rk29_newton_set_gps_power(GPIO_LOW);
DBG("%s:rk29 newton initialized\n",__FUNCTION__);
return ret;
}
static int rk29_newton_remove(struct platform_device *pdev)
{
misc_deregister(&rk29_newton_dev);
return 0;
}
int rk29_newton_suspend(struct platform_device *pdev, pm_message_t state)
{
if(gps_power==GPIO_HIGH)
rk29_newton_set_gps_power(GPIO_LOW);
return 0;
}
int rk29_newton_resume(struct platform_device *pdev)
{
if(gps_power==GPIO_HIGH)
rk29_newton_set_gps_power(gps_power);
return 0;
}
static struct platform_driver rk29_newton_driver = {
.probe = rk29_newton_probe,
.remove = rk29_newton_remove,
.suspend = rk29_newton_suspend,
.resume = rk29_newton_resume,
.driver = {
.name = "rk29_newton",
.owner = THIS_MODULE,
},
};
static int __init rk29_newton_init(void)
{
return platform_driver_register(&rk29_newton_driver);
}
static void __exit rk29_newton_exit(void)
{
platform_driver_unregister(&rk29_newton_driver);
}
module_init(rk29_newton_init);
module_exit(rk29_newton_exit);
MODULE_DESCRIPTION ("rk29 newton misc driver");
MODULE_LICENSE("GPL");

View File

@@ -304,12 +304,6 @@ config BACKLIGHT_RK29_BL
help
rk29 backlight support.
config BACKLIGHT_RK29_NEWTON_BL
bool "rk29 newton backlight driver"
depends on BACKLIGHT_CLASS_DEVICE && ARCH_RK29
help
rk29 newton backlight support.
config FIH_TOUCHKEY_LED
bool "fih touch key led driver"
depends on BACKLIGHT_CLASS_DEVICE && ARCH_RK29

View File

@@ -34,7 +34,6 @@ obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
obj-$(CONFIG_BACKLIGHT_RK29_BL) += rk29_backlight.o
obj-$(CONFIG_BACKLIGHT_RK29_NEWTON_BL) += rk29_newton_backlight.o
obj-$(CONFIG_BACKLIGHT_AW9364) += aw9364_bl.o
obj-$(CONFIG_FIH_TOUCHKEY_LED) += fih_touchkey_led.o
obj-$(CONFIG_BUTTON_LIGHT) += rk29_buttonlight.o

View File

@@ -1,276 +0,0 @@
/* drivers/video/backlight/rk29_backlight.c
*
* Copyright (C) 2009-2011 Rockchip Corporation.
*
* 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/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/backlight.h>
#include <linux/fb.h>
#include <linux/clk.h>
#include <linux/earlysuspend.h>
#include <asm/io.h>
#include <mach/rk29_iomap.h>
#include <mach/board.h>
#include "rk2818_backlight.h"
/*
* Debug
*/
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define write_pwm_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))
#define read_pwm_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
static struct clk *pwm_clk;
static struct backlight_device *rk29_bl;
static int suspend_flag = 0;
static int rk29_bl_update_status(struct backlight_device *bl)
{
u32 divh,div_total;
struct rk29_bl_info *rk29_bl_info = bl_get_data(bl);
u32 id = rk29_bl_info->pwm_id;
u32 ref = rk29_bl_info->bl_ref;
if (suspend_flag)
return 0;
if (bl->props.brightness < rk29_bl_info->min_brightness) /*avoid can't view screen when close backlight*/
bl->props.brightness = rk29_bl_info->min_brightness;
div_total = read_pwm_reg(id, PWM_REG_LRC);
if (ref) {
divh = div_total*(bl->props.brightness)/BL_STEP;
} else {
divh = div_total*(BL_STEP-bl->props.brightness)/BL_STEP;
}
write_pwm_reg(id, PWM_REG_HRC, divh);
DBG(">>>%s-->%d brightness = %d, div_total = %d, divh = %d\n",__FUNCTION__,__LINE__,bl->props.brightness, div_total, divh);
return 0;
}
static int rk29_bl_get_brightness(struct backlight_device *bl)
{
u32 divh,div_total;
struct rk29_bl_info *rk29_bl_info = bl_get_data(bl);
u32 id = rk29_bl_info->pwm_id;
u32 ref = rk29_bl_info->bl_ref;
div_total = read_pwm_reg(id, PWM_REG_LRC);
divh = read_pwm_reg(id, PWM_REG_HRC);
if (!div_total)
return 0;
if (ref) {
return BL_STEP*divh/div_total;
} else {
return BL_STEP-(BL_STEP*divh/div_total);
}
}
static struct backlight_ops rk29_bl_ops = {
.update_status = rk29_bl_update_status,
.get_brightness = rk29_bl_get_brightness,
};
static void rk29_backlight_work_func(struct work_struct *work)
{
suspend_flag = 0;
rk29_bl_update_status(rk29_bl);
}
static DECLARE_DELAYED_WORK(rk29_backlight_work, rk29_backlight_work_func);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void rk29_bl_suspend(struct early_suspend *h)
{
struct rk29_bl_info *rk29_bl_info = bl_get_data(rk29_bl);
int brightness = rk29_bl->props.brightness;
cancel_delayed_work_sync(&rk29_backlight_work);
if (rk29_bl->props.brightness) {
rk29_bl->props.brightness = 0;
rk29_bl_update_status(rk29_bl);
rk29_bl->props.brightness = brightness;
}
if (!suspend_flag) {
clk_disable(pwm_clk);
if (rk29_bl_info->pwm_suspend)
rk29_bl_info->pwm_suspend();
}
suspend_flag = 1;
}
static void rk29_bl_resume(struct early_suspend *h)
{
struct rk29_bl_info *rk29_bl_info = bl_get_data(rk29_bl);
DBG("%s : %s\n", __FILE__, __FUNCTION__);
if (rk29_bl_info->pwm_resume)
rk29_bl_info->pwm_resume();
clk_enable(pwm_clk);
schedule_delayed_work(&rk29_backlight_work, msecs_to_jiffies(rk29_bl_info->delay_ms));
}
static struct early_suspend bl_early_suspend = {
.suspend = rk29_bl_suspend,
.resume = rk29_bl_resume,
.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1,
};
#endif
static int rk29_backlight_probe(struct platform_device *pdev)
{
int ret = 0;
struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data;
u32 id = rk29_bl_info->pwm_id;
u32 divh, div_total;
unsigned long pwm_clk_rate;
if (rk29_bl) {
DBG(KERN_CRIT "%s: backlight device register has existed \n",
__func__);
return -EEXIST;
}
if (!rk29_bl_info->delay_ms)
rk29_bl_info->delay_ms = 100;
if (rk29_bl_info->min_brightness < 0 || rk29_bl_info->min_brightness > BL_STEP)
rk29_bl_info->min_brightness = 52;
if (rk29_bl_info && rk29_bl_info->io_init) {
rk29_bl_info->io_init();
}
rk29_bl = backlight_device_register("rk28_bl", &pdev->dev, rk29_bl_info, &rk29_bl_ops);
if (!rk29_bl) {
DBG(KERN_CRIT "%s: backlight device register error\n",
__func__);
return -ENODEV;
}
pwm_clk = clk_get(NULL, "pwm");
if (IS_ERR(pwm_clk)) {
printk(KERN_ERR "failed to get pwm clock source\n");
return -ENODEV;
}
pwm_clk_rate = clk_get_rate(pwm_clk);
div_total = pwm_clk_rate / PWM_APB_PRE_DIV;
div_total >>= (1 + (PWM_DIV >> 9));
div_total = (div_total) ? div_total : 1;
if(rk29_bl_info->bl_ref) {
divh = 0;
} else {
divh = div_total;
}
clk_enable(pwm_clk);
write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_RESET);
write_pwm_reg(id, PWM_REG_LRC, div_total);
write_pwm_reg(id, PWM_REG_HRC, divh);
write_pwm_reg(id, PWM_REG_CNTR, 0x0);
write_pwm_reg(id, PWM_REG_CTRL, PWM_DIV|PWM_ENABLE|PWM_TIME_EN);
rk29_bl->props.power = FB_BLANK_UNBLANK;
rk29_bl->props.fb_blank = FB_BLANK_UNBLANK;
rk29_bl->props.max_brightness = BL_STEP;
rk29_bl->props.brightness = BL_STEP / 2;
if (rk29_bl_info && rk29_bl_info->pwm_resume) {
rk29_bl_info->pwm_resume();
}
schedule_delayed_work(&rk29_backlight_work, msecs_to_jiffies(rk29_bl_info->delay_ms));
register_early_suspend(&bl_early_suspend);
printk("RK29 Backlight Driver Initialized.\n");
return ret;
}
static int rk29_backlight_remove(struct platform_device *pdev)
{
struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data;
if (rk29_bl) {
backlight_device_unregister(rk29_bl);
unregister_early_suspend(&bl_early_suspend);
clk_disable(pwm_clk);
clk_put(pwm_clk);
if (rk29_bl_info && rk29_bl_info->io_deinit) {
rk29_bl_info->io_deinit();
}
return 0;
} else {
DBG(KERN_CRIT "%s: no backlight device has registered\n",
__func__);
return -ENODEV;
}
}
static void rk29_backlight_shutdown(struct platform_device *pdev)
{
struct rk29_bl_info *rk29_bl_info = pdev->dev.platform_data;
rk29_bl->props.brightness >>= 1;
rk29_bl_update_status(rk29_bl);
mdelay(100);
rk29_bl->props.brightness >>= 1;
rk29_bl_update_status(rk29_bl);
mdelay(100);
rk29_bl->props.brightness = 0;
rk29_bl_update_status(rk29_bl);
if (rk29_bl_info && rk29_bl_info->io_deinit)
rk29_bl_info->io_deinit();
}
static struct platform_driver rk29_backlight_driver = {
.probe = rk29_backlight_probe,
.remove = rk29_backlight_remove,
.driver = {
.name = "rk29_backlight",
.owner = THIS_MODULE,
},
.shutdown = rk29_backlight_shutdown,
};
static int __init rk29_backlight_init(void)
{
platform_driver_register(&rk29_backlight_driver);
return 0;
}
fs_initcall_sync(rk29_backlight_init);