mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 22:52:35 +02:00
rk2818: remove all rk2818 stuff, prepare for 2.6.36
This commit is contained in:
parent
54d1431f25
commit
b9556fd539
|
|
@ -707,20 +707,6 @@ config ARCH_BCMRING
|
|||
help
|
||||
Support for Broadcom's BCMRing platform.
|
||||
|
||||
config ARCH_RK2818
|
||||
bool "Rockchip soc rk2818"
|
||||
select CPU_ARM926T
|
||||
select CPU_CP15_MMU
|
||||
select HAVE_TCM
|
||||
select HAVE_CLK
|
||||
select COMMON_CLKDEV
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Support for Rockchip RK2818 soc.
|
||||
|
||||
config ARCH_RK29
|
||||
bool "Rockchip Soc Rk29"
|
||||
select CPU_V7
|
||||
|
|
@ -840,8 +826,6 @@ source "arch/arm/mach-w90x900/Kconfig"
|
|||
|
||||
source "arch/arm/mach-bcmring/Kconfig"
|
||||
|
||||
source "arch/arm/mach-rk2818/Kconfig"
|
||||
|
||||
source "arch/arm/mach-rk29/Kconfig"
|
||||
|
||||
# Definitions to make life easier
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
|||
machine-$(CONFIG_ARCH_W90X900) := w90x900
|
||||
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
||||
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
|
||||
machine-$(CONFIG_ARCH_RK2818) := rk2818
|
||||
machine-$(CONFIG_ARCH_RK29) := rk29
|
||||
|
||||
# Platform directory name. This list is sorted alphanumerically
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,74 +0,0 @@
|
|||
if ARCH_RK2818
|
||||
|
||||
comment "ROCKCHIP rk2818 Board Type"
|
||||
depends on ARCH_RK2818
|
||||
|
||||
config MACH_RK2818MID
|
||||
depends on ARCH_RK2818
|
||||
default y
|
||||
bool "ROCKCHIP Board For Mid"
|
||||
help
|
||||
Support for the ROCKCHIP Board For Rk2818 Mid.
|
||||
|
||||
config MACH_RK2818PHONE
|
||||
depends on ARCH_RK2818
|
||||
default y
|
||||
bool "ROCKCHIP Board For PHONE"
|
||||
help
|
||||
Support for the ROCKCHIP Board For Rk2818 Phone.
|
||||
|
||||
config MACH_RAHO
|
||||
depends on ARCH_RK2818
|
||||
default n
|
||||
bool "ROCKCHIP Board For raho"
|
||||
help
|
||||
Support for the ROCKCHIP Board For raho Phone.
|
||||
|
||||
config MACH_RAHOSDK
|
||||
depends on ARCH_RK2818
|
||||
default n
|
||||
bool "ROCKCHIP Board For raho sdk"
|
||||
help
|
||||
Support for the ROCKCHIP Board For raho sdk Phone.
|
||||
|
||||
config MACH_RK2818INFO
|
||||
depends on ARCH_RK2818
|
||||
default n
|
||||
bool "ROCKCHIP Board For Info"
|
||||
help
|
||||
Support for the ROCKCHIP Board For Info Telephone.
|
||||
|
||||
config MACH_RK2818INFO_IT50
|
||||
depends on ARCH_RK2818
|
||||
default n
|
||||
bool "ROCKCHIP Board For Info It50"
|
||||
help
|
||||
Support for the ROCKCHIP Board For Info IT50 Telephone.
|
||||
|
||||
config RK28_GPIO_IRQ
|
||||
int
|
||||
default 16 if ARCH_RK2818
|
||||
default 0
|
||||
config RK28_ADC
|
||||
tristate "RK28 ADC Driver"
|
||||
depends on ARCH_RK2818
|
||||
default y
|
||||
---help---
|
||||
RK28 ADC Driver
|
||||
|
||||
config RK28_USB_WAKE
|
||||
bool "Enable wake-up events for USB ports"
|
||||
depends on ARCH_RK2818 && PM
|
||||
default y
|
||||
help
|
||||
Select this option if you want to have your system wake up from USB.
|
||||
This will poll usb every second while suspend, so consumes more power.
|
||||
|
||||
config WIFI_CONTROL_FUNC
|
||||
bool "Enable WiFi control function abstraction"
|
||||
help
|
||||
Enables Power/Reset/Carddetect function abstraction
|
||||
config RK2818_SOC_PM
|
||||
bool "Enable soc power manager function"
|
||||
default n
|
||||
endif
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
obj-y += irq.o timer.o iomux.o gpio.o
|
||||
obj-y += devices.o
|
||||
obj-y += clock.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-y += ddr.o
|
||||
obj-y += dma.o
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
obj-$(CONFIG_RK28_ADC) += adc.o
|
||||
obj-$(CONFIG_MACH_RK2818MID) += board-midsdk.o
|
||||
obj-$(CONFIG_MACH_RK2818PHONE) += board-phonesdk.o
|
||||
obj-$(CONFIG_MACH_RAHO) += board-raho.o board-raho-rfkill.o
|
||||
obj-$(CONFIG_MACH_RAHOSDK) += board-rahosdk.o board-rahosdk-rfkill.o
|
||||
obj-$(CONFIG_MACH_RK2818INFO) += board-infosdk.o board-infosdk-rfkill.o
|
||||
obj-$(CONFIG_MACH_RK2818INFO_IT50) += board-infoit50.o board-infoit50-rfkill.o
|
||||
obj-$(CONFIG_RK2818_SOC_PM) += rk2818-socpm.o
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
zreladdr-y := 0x60408000
|
||||
params_phys-y := 0x600f8000
|
||||
initrd_phys-y := 0x60800000
|
||||
|
|
@ -1,527 +0,0 @@
|
|||
/* arm/arch/mach-rk2818/adc.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/adc.h>
|
||||
|
||||
/* This driver is designed to control the usage of the ADC block between
|
||||
* the keyboard and any other drivers that may need to use it.
|
||||
*
|
||||
* Priority will be given to the touchscreen driver, but as this itself is
|
||||
* rate limited it should not starve other requests which are processed in
|
||||
* order that they are received.
|
||||
*
|
||||
* Each user registers to get a client block which uniquely identifies it
|
||||
* and stores information such as the necessary functions to callback when
|
||||
* action is required.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
struct rk28_adc_client {
|
||||
struct platform_device *pdev;
|
||||
struct list_head pend;
|
||||
wait_queue_head_t *wait;
|
||||
unsigned int nr_samples;
|
||||
int result;
|
||||
unsigned char is_ts;
|
||||
unsigned char channel;
|
||||
|
||||
void (*select_cb)(struct rk28_adc_client *c, unsigned selected);
|
||||
void (*convert_cb)(struct rk28_adc_client *c,
|
||||
unsigned val1, unsigned val2,
|
||||
unsigned *samples_left);
|
||||
};
|
||||
|
||||
struct adc_device {
|
||||
struct semaphore lock;
|
||||
struct platform_device *pdev;
|
||||
struct platform_device *owner;
|
||||
struct clk *clk;
|
||||
struct rk28_adc_client *client;
|
||||
struct rk28_adc_client *cur;
|
||||
struct rk28_adc_client *ts_pend;
|
||||
struct workqueue_struct *timer_workqueue;
|
||||
struct work_struct timer_work;
|
||||
void __iomem *regs;
|
||||
struct timer_list timer;
|
||||
unsigned int pre_con;
|
||||
int irq;
|
||||
};
|
||||
|
||||
static struct adc_device *pAdcDev;
|
||||
volatile int gAdcChanel = 0;
|
||||
volatile int gAdcValue[4]={0, 0, 0, 0}; //0->ch0 1->ch1 2->ch2 3->ch3
|
||||
|
||||
static LIST_HEAD(adc_pending);
|
||||
|
||||
#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
|
||||
|
||||
static inline void rk28_adc_int_enable(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con |= RK28_ADC_INT_ENABLE;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_int_disable(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con &= RK28_ADC_INT_DISABLE;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_int_clear(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con &= RK28_ADC_INT_CLEAR;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_power_up(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con |= RK28_ADC_POWER_UP;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_power_down(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con &= RK28_ADC_POWER_DOWN;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_convert(struct adc_device *adc)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
con |= RK28_ADC_POWER_UP | RK28_ADC_CONV_START | RK28_ADC_INT_ENABLE;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static inline void rk28_adc_select(struct adc_device *adc,
|
||||
struct rk28_adc_client *client)
|
||||
{
|
||||
unsigned con = readl(adc->regs + RK28_ADCCON);
|
||||
|
||||
client->select_cb(client, 1);
|
||||
|
||||
con &= RK28_ADC_MASK_CH;
|
||||
con &= RK28_ADC_CONV_STOP;
|
||||
|
||||
if (!client->is_ts)
|
||||
con |= RK28_ADC_SEL_CH(client->channel);
|
||||
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
}
|
||||
|
||||
static void rk28_adc_dbgshow(struct adc_device *adc)
|
||||
{
|
||||
adc_dbg(adc, "CON=0x%x, STAS=0x%x, DATA=0x%x\n",
|
||||
readl(adc->regs + RK28_ADCCON),
|
||||
readl(adc->regs + RK28_ADCSTAS),
|
||||
readl(adc->regs + RK28_ADCDAT));
|
||||
}
|
||||
|
||||
static void rk28_adc_try(struct adc_device *adc)
|
||||
{
|
||||
struct rk28_adc_client *next = adc->ts_pend;
|
||||
|
||||
if (!next && !list_empty(&adc_pending)) {
|
||||
next = list_first_entry(&adc_pending,
|
||||
struct rk28_adc_client, pend);
|
||||
list_del(&next->pend);
|
||||
} else
|
||||
adc->ts_pend = NULL;
|
||||
|
||||
if (next) {
|
||||
adc_dbg(adc, "new client is %p\n", next);
|
||||
adc->cur = next;
|
||||
rk28_adc_select(adc, next);
|
||||
rk28_adc_convert(adc);
|
||||
rk28_adc_dbgshow(adc);
|
||||
}
|
||||
}
|
||||
|
||||
int rk28_adc_start(struct rk28_adc_client *client,
|
||||
unsigned int channel, unsigned int nr_samples)
|
||||
{
|
||||
struct adc_device *adc = pAdcDev;
|
||||
unsigned long flags;
|
||||
|
||||
if (!adc) {
|
||||
printk(KERN_ERR "%s: failed to find adc\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (client->is_ts && adc->ts_pend)
|
||||
return -EAGAIN;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
client->channel = channel;
|
||||
client->nr_samples = nr_samples;
|
||||
|
||||
if (client->is_ts)
|
||||
adc->ts_pend = client;
|
||||
else
|
||||
list_add_tail(&client->pend, &adc_pending);
|
||||
|
||||
if (!adc->cur)
|
||||
rk28_adc_try(adc);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk28_adc_start);
|
||||
|
||||
static void rk28_convert_done(struct rk28_adc_client *client,
|
||||
unsigned v, unsigned u, unsigned *left)
|
||||
{
|
||||
client->result = v;
|
||||
wake_up(client->wait);
|
||||
}
|
||||
|
||||
int rk28_adc_read(struct rk28_adc_client *client, unsigned int ch)
|
||||
{
|
||||
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
||||
int ret;
|
||||
|
||||
client->convert_cb = rk28_convert_done;
|
||||
client->wait = &wake;
|
||||
client->result = -1;
|
||||
|
||||
ret = rk28_adc_start(client, ch, 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
|
||||
if (client->result < 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
client->convert_cb = NULL;
|
||||
return client->result;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk28_adc_read);
|
||||
|
||||
static void rk28_adc_default_select(struct rk28_adc_client *client,
|
||||
unsigned select)
|
||||
{
|
||||
}
|
||||
|
||||
struct rk28_adc_client *rk28_adc_register(struct platform_device *pdev,
|
||||
void (*select)(struct rk28_adc_client *client,
|
||||
unsigned int selected),
|
||||
void (*conv)(struct rk28_adc_client *client,
|
||||
unsigned d0, unsigned d1,
|
||||
unsigned *samples_left),
|
||||
unsigned int is_ts)
|
||||
{
|
||||
struct rk28_adc_client *client;
|
||||
|
||||
WARN_ON(!pdev);
|
||||
|
||||
if (!select)
|
||||
select = rk28_adc_default_select;
|
||||
|
||||
if (!pdev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
client = kzalloc(sizeof(struct rk28_adc_client), GFP_KERNEL);
|
||||
if (!client) {
|
||||
dev_err(&pdev->dev, "no memory for adc client\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
client->pdev = pdev;
|
||||
client->is_ts = is_ts;
|
||||
client->select_cb = select;
|
||||
client->convert_cb = conv;
|
||||
|
||||
return client;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk28_adc_register);
|
||||
|
||||
void rk28_adc_release(struct rk28_adc_client *client)
|
||||
{
|
||||
/* We should really check that nothing is in progress. */
|
||||
if (pAdcDev->cur == client)
|
||||
pAdcDev->cur = NULL;
|
||||
if (pAdcDev->ts_pend == client)
|
||||
pAdcDev->ts_pend = NULL;
|
||||
else {
|
||||
struct list_head *p, *n;
|
||||
struct rk28_adc_client *tmp;
|
||||
|
||||
list_for_each_safe(p, n, &adc_pending) {
|
||||
tmp = list_entry(p, struct rk28_adc_client, pend);
|
||||
if (tmp == client)
|
||||
list_del(&tmp->pend);
|
||||
}
|
||||
}
|
||||
|
||||
if (pAdcDev->cur == NULL)
|
||||
rk28_adc_try(pAdcDev);
|
||||
kfree(client);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk28_adc_release);
|
||||
|
||||
|
||||
//read four ADC chanel
|
||||
static int rk28_read_adc(struct adc_device *adc)
|
||||
{
|
||||
int ret = 0,i;
|
||||
|
||||
ret = down_interruptible(&adc->lock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
gAdcValue[i] = rk28_adc_read(adc->client, i);
|
||||
DBG("gAdcValue[%d]=%d\n",i,gAdcValue[i]);
|
||||
}
|
||||
|
||||
up(&adc->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void adc_timer_work(struct work_struct *work)
|
||||
{
|
||||
rk28_read_adc(pAdcDev);
|
||||
}
|
||||
|
||||
|
||||
static void rk28_adcscan_timer(unsigned long data)
|
||||
{
|
||||
pAdcDev->timer.expires = jiffies + msecs_to_jiffies(30);
|
||||
add_timer(&pAdcDev->timer);
|
||||
//schedule_work(&pAdcDev->timer_work);
|
||||
queue_work(pAdcDev->timer_workqueue, &pAdcDev->timer_work);
|
||||
}
|
||||
|
||||
static irqreturn_t rk28_adc_irq(int irq, void *pw)
|
||||
{
|
||||
struct adc_device *adc = pw;
|
||||
struct rk28_adc_client *client = adc->cur;
|
||||
unsigned long flags;
|
||||
unsigned data0, data1 = 0;
|
||||
rk28_adc_int_disable(adc);
|
||||
rk28_adc_int_clear(adc);
|
||||
|
||||
if (!client) {
|
||||
dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
data0 = readl(adc->regs + RK28_ADCDAT);
|
||||
|
||||
adc_dbg(adc, "read %d: 0x%x\n", client->nr_samples, data0);
|
||||
|
||||
client->nr_samples--;
|
||||
|
||||
if (client->convert_cb)
|
||||
(client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
|
||||
&client->nr_samples);
|
||||
|
||||
if (client->nr_samples > 0) {
|
||||
/* fire another conversion for this */
|
||||
|
||||
client->select_cb(client, 1);
|
||||
rk28_adc_convert(adc);
|
||||
} else {
|
||||
local_irq_save(flags);
|
||||
(client->select_cb)(client, 0);
|
||||
adc->cur = NULL;
|
||||
|
||||
rk28_adc_try(adc);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk28_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct adc_device *adc;
|
||||
struct resource *regs;
|
||||
int ret;
|
||||
|
||||
adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
|
||||
if (adc == NULL) {
|
||||
dev_err(dev, "failed to allocate adc_device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
adc->pdev = pdev;
|
||||
|
||||
adc->irq = platform_get_irq(pdev, 0);
|
||||
if (adc->irq <= 0) {
|
||||
dev_err(dev, "failed to get adc irq\n");
|
||||
ret = -ENOENT;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
ret = request_irq(adc->irq, rk28_adc_irq, 0, dev_name(dev), adc);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach adc irq\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
adc->clk = clk_get(dev, "lsadc");
|
||||
if (IS_ERR(adc->clk)) {
|
||||
dev_err(dev, "failed to get adc clock\n");
|
||||
ret = PTR_ERR(adc->clk);
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!regs) {
|
||||
dev_err(dev, "failed to find registers\n");
|
||||
ret = -ENXIO;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
adc->regs = ioremap(regs->start, resource_size(regs));
|
||||
if (!adc->regs) {
|
||||
dev_err(dev, "failed to map registers\n");
|
||||
ret = -ENXIO;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
clk_enable(adc->clk);
|
||||
|
||||
dev_info(dev, "attached adc driver\n");
|
||||
|
||||
platform_set_drvdata(pdev, adc);
|
||||
|
||||
init_MUTEX(&adc->lock);
|
||||
adc->timer_workqueue = create_freezeable_workqueue("adc timer work");
|
||||
if (!adc->timer_workqueue) {
|
||||
printk("%s:cannot create workqueue\n",__FUNCTION__);
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&adc->timer_work, adc_timer_work);
|
||||
/* Register with the core ADC driver. */
|
||||
adc->client = rk28_adc_register(pdev, NULL, NULL, 0);
|
||||
if (IS_ERR(adc->client)) {
|
||||
dev_err(dev, "cannot register adc\n");
|
||||
ret = PTR_ERR(adc->client);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
rk28_adc_int_disable(adc);
|
||||
pAdcDev = adc;
|
||||
|
||||
setup_timer(&adc->timer, rk28_adcscan_timer, (unsigned long)adc);
|
||||
adc->timer.expires = jiffies + 50;
|
||||
add_timer(&adc->timer);
|
||||
printk(KERN_INFO "rk2818 adc: driver initialized\n");
|
||||
return 0;
|
||||
|
||||
err_clk:
|
||||
clk_put(adc->clk);
|
||||
|
||||
err_irq:
|
||||
free_irq(adc->irq, adc);
|
||||
|
||||
err_alloc:
|
||||
kfree(adc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk28_adc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct adc_device *adc = platform_get_drvdata(pdev);
|
||||
rk28_adc_power_down(adc);
|
||||
rk28_adc_release(adc->client);
|
||||
iounmap(adc->regs);
|
||||
free_irq(adc->irq, adc);
|
||||
clk_disable(adc->clk);
|
||||
clk_put(adc->clk);
|
||||
kfree(adc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rk28_adc_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct adc_device *adc = platform_get_drvdata(pdev);
|
||||
u32 con;
|
||||
|
||||
con = readl(adc->regs + RK28_ADCCON);
|
||||
adc->pre_con = con;
|
||||
con &= RK28_ADC_POWER_DOWN;
|
||||
writel(con, adc->regs + RK28_ADCCON);
|
||||
|
||||
clk_disable(adc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk28_adc_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct adc_device *adc = platform_get_drvdata(pdev);
|
||||
|
||||
clk_enable(adc->clk);
|
||||
|
||||
writel(adc->pre_con, adc->regs + RK28_ADCCON);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define rk28_adc_suspend NULL
|
||||
#define rk28_adc_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver rk28_adc_driver = {
|
||||
.driver = {
|
||||
.name = "rk2818-adc",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rk28_adc_probe,
|
||||
.remove = __devexit_p(rk28_adc_remove),
|
||||
.suspend = rk28_adc_suspend,
|
||||
.resume = rk28_adc_resume,
|
||||
};
|
||||
|
||||
static int __init adc_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&rk28_adc_driver);
|
||||
if (ret)
|
||||
printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
module_init(adc_init);
|
||||
MODULE_DESCRIPTION("rk28xx adc driver");
|
||||
MODULE_AUTHOR("luowei lw@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/board-infoit50-rfkill.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/rfkill.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#define INFOIT50_BT_GPIO_POWER_N TCA6424_P01
|
||||
#define INFOIT50_BT_GPIO_RESET_N TCA6424_P14
|
||||
|
||||
static struct rfkill *bt_rfk;
|
||||
static const char bt_name[] = "bcm4329";
|
||||
|
||||
static int bcm4329_set_block(void *data, bool blocked)
|
||||
{
|
||||
pr_info("%s---blocked :%d\n", __func__, blocked);
|
||||
|
||||
if (false == blocked) {
|
||||
gpio_direction_output(INFOIT50_BT_GPIO_POWER_N, GPIO_HIGH); /* bt power on */
|
||||
gpio_direction_output(INFOIT50_BT_GPIO_RESET_N, GPIO_HIGH); /* bt reset deactive */
|
||||
mdelay(20);
|
||||
pr_info("bt turn on power\n");
|
||||
}else{
|
||||
gpio_direction_output(INFOIT50_BT_GPIO_POWER_N, GPIO_LOW); /* bt power off */
|
||||
gpio_direction_output(INFOIT50_BT_GPIO_RESET_N, GPIO_LOW); /* bt reset active */
|
||||
mdelay(20);
|
||||
pr_info("bt shut off power\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct rfkill_ops bcm4329_rfk_ops = {
|
||||
.set_block = bcm4329_set_block,
|
||||
};
|
||||
|
||||
static int bcm4329_rfkill_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
bool default_state = true;
|
||||
|
||||
pr_info("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
rc = gpio_request(INFOIT50_BT_GPIO_POWER_N, "bt_shutdown");
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = gpio_request(INFOIT50_BT_GPIO_RESET_N, "bt_reset");
|
||||
if (rc){
|
||||
gpio_free(INFOIT50_BT_GPIO_POWER_N);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* default to bluetooth off */
|
||||
bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
|
||||
|
||||
bt_rfk = rfkill_alloc(bt_name,
|
||||
NULL,
|
||||
RFKILL_TYPE_BLUETOOTH,
|
||||
&bcm4329_rfk_ops,
|
||||
NULL);
|
||||
|
||||
if (!bt_rfk)
|
||||
{
|
||||
printk("fail to rfkill_allocate************\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfkill_set_states(bt_rfk, default_state, false);
|
||||
|
||||
rc = rfkill_register(bt_rfk);
|
||||
if (rc)
|
||||
rfkill_destroy(bt_rfk);
|
||||
|
||||
printk("rc=0x%x\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int bcm4329_rfkill_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (bt_rfk)
|
||||
rfkill_unregister(bt_rfk);
|
||||
rfkill_destroy(bt_rfk);
|
||||
bt_rfk = NULL;
|
||||
gpio_free(INFOIT50_BT_GPIO_POWER_N);
|
||||
gpio_free(INFOIT50_BT_GPIO_RESET_N);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
pr_info("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bcm4329_rfkill_driver = {
|
||||
.probe = bcm4329_rfkill_probe,
|
||||
.remove = bcm4329_rfkill_remove,
|
||||
.driver = {
|
||||
.name = "infoit50_rfkill",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Module initialization
|
||||
*/
|
||||
static int __init bcm4329_mod_init(void)
|
||||
{
|
||||
int ret;
|
||||
pr_info("Enter::%s,line=%d\n",__func__,__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
|
|
@ -1,152 +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 <asm/gpio.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
//#include <asm/arch/iomux.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_RK2818INFO_IT50
|
||||
#define INFO_BT_GPIO_POWER_N TCA6424_P01
|
||||
#define INFO_BT_GPIO_RESET_N TCA6424_P14
|
||||
#else
|
||||
#define INFO_BT_GPIO_POWER_N TCA6424_P25
|
||||
#define INFO_BT_GPIO_RESET_N TCA6424_P22
|
||||
#endif
|
||||
static struct rfkill *bt_rfk;
|
||||
static const char bt_name[] = "bcm4329";
|
||||
extern int info_bt_power_state;
|
||||
extern int info_wifi_power_state;
|
||||
|
||||
static int bcm4329_set_block(void *data, bool blocked)
|
||||
{
|
||||
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
|
||||
|
||||
if (false == blocked) {
|
||||
gpio_set_value(INFO_BT_GPIO_POWER_N, GPIO_HIGH); /* bt power on */
|
||||
gpio_set_value(INFO_BT_GPIO_RESET_N, GPIO_HIGH); /* bt reset deactive*/
|
||||
mdelay(20);
|
||||
pr_info("bt turn on power\n");
|
||||
}
|
||||
else {
|
||||
if (!info_wifi_power_state) {
|
||||
gpio_set_value(INFO_BT_GPIO_POWER_N, 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(INFO_BT_GPIO_RESET_N, GPIO_LOW); /* bt reset active*/
|
||||
mdelay(20);
|
||||
}
|
||||
|
||||
info_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;
|
||||
|
||||
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/* default to bluetooth off */
|
||||
// rfkill_switch_all(RFKILL_TYPE_BLUETOOTH, true);
|
||||
|
||||
bt_rfk = rfkill_alloc(bt_name,
|
||||
NULL,
|
||||
RFKILL_TYPE_BLUETOOTH,
|
||||
&bcm4329_rfk_ops,
|
||||
NULL);
|
||||
|
||||
if (!bt_rfk)
|
||||
{
|
||||
printk("fail to rfkill_allocate************\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = rfkill_register(bt_rfk);
|
||||
if (rc)
|
||||
rfkill_destroy(bt_rfk);
|
||||
|
||||
printk("rc=0x%x\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (bt_rfk)
|
||||
rfkill_unregister(bt_rfk);
|
||||
bt_rfk = NULL;
|
||||
|
||||
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 = "info_rfkill",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
|
@ -1,755 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/board-midsdk.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/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* 声明了rk2818_gpioBank数组,并定义了GPIO寄存器组ID和寄存器基地址。
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
static struct rk2818_gpio_bank rk2818_gpioBank[] = {
|
||||
{
|
||||
.id = RK2818_ID_PIOA,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOB,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOC,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOD,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOE,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOF,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOG,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOH,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
//IO映射方式描述 ,每个为一段线性连续映射
|
||||
static struct map_desc rk2818_io_desc[] __initdata = {
|
||||
|
||||
{
|
||||
.virtual = RK2818_MCDMA_BASE, //虚拟地址
|
||||
.pfn = __phys_to_pfn(RK2818_MCDMA_PHYS), //物理地址,须与页表对齐
|
||||
.length = RK2818_MCDMA_SIZE, //长度
|
||||
.type = MT_DEVICE //映射方式
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_DWDMA_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_DWDMA_PHYS),
|
||||
.length = RK2818_DWDMA_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_INTC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_INTC_PHYS),
|
||||
.length = RK2818_INTC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_NANDC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_NANDC_PHYS),
|
||||
.length = RK2818_NANDC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_SDRAMC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_SDRAMC_PHYS),
|
||||
.length = RK2818_SDRAMC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_ARMDARBITER_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_ARMDARBITER_PHYS),
|
||||
.length = RK2818_ARMDARBITER_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_APB_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_APB_PHYS),
|
||||
.length = 0xa0000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_WDT_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_WDT_PHYS),
|
||||
.length = 0xa0000, ///apb bus i2s i2c spi no map in this
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
/*****************************************************************************************
|
||||
* SDMMC devices
|
||||
*author: kfx
|
||||
*****************************************************************************************/
|
||||
void rk2818_sdmmc0_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOF3_APWM1_MMC0DETN_NAME, IOMUXA_SDMMC1_DETECT_N);
|
||||
rk2818_mux_api_set(GPIOH_MMC0D_SEL_NAME, IOMUXA_SDMMC0_DATA123);
|
||||
rk2818_mux_api_set(GPIOH_MMC0_SEL_NAME, IOMUXA_SDMMC0_CMD_DATA0_CLKOUT);
|
||||
}
|
||||
|
||||
void rk2818_sdmmc1_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOG_MMC1_SEL_NAME, IOMUXA_SDMMC1_CMD_DATA0_CLKOUT);
|
||||
rk2818_mux_api_set(GPIOG_MMC1D_SEL_NAME, IOMUXA_SDMMC1_DATA123);
|
||||
#if 0
|
||||
/* wifi power up (gpio control) */
|
||||
rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);
|
||||
rk2818_mux_api_set(GPIOF5_APWM3_DPWM3_NAME,IOMUXB_GPIO1_B5);
|
||||
gpio_request(RK2818_PIN_PH7, "sdio");
|
||||
gpio_direction_output(RK2818_PIN_PH7,GPIO_HIGH);
|
||||
#endif
|
||||
|
||||
}
|
||||
#define CONFIG_SDMMC0_USE_DMA
|
||||
#define CONFIG_SDMMC1_USE_DMA
|
||||
struct rk2818_sdmmc_platform_data default_sdmmc0_data = {
|
||||
.host_ocr_avail = (MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
|
||||
MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33|
|
||||
MMC_VDD_33_34|MMC_VDD_34_35| MMC_VDD_35_36),
|
||||
.host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
|
||||
.cfg_gpio = rk2818_sdmmc0_cfg_gpio,
|
||||
.no_detect = 0,
|
||||
.dma_name = "sd_mmc",
|
||||
#ifdef CONFIG_SDMMC0_USE_DMA
|
||||
.use_dma = 1,
|
||||
#else
|
||||
.use_dma = 0,
|
||||
#endif
|
||||
};
|
||||
struct rk2818_sdmmc_platform_data default_sdmmc1_data = {
|
||||
.host_ocr_avail = (MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|
|
||||
MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32|
|
||||
MMC_VDD_32_33|MMC_VDD_33_34),
|
||||
.host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_SDIO_IRQ|
|
||||
MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
|
||||
.cfg_gpio = rk2818_sdmmc1_cfg_gpio,
|
||||
.no_detect = 1,
|
||||
.dma_name = "sdio",
|
||||
#ifdef CONFIG_SDMMC1_USE_DMA
|
||||
.use_dma = 1,
|
||||
#else
|
||||
.use_dma = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* extern gpio devices
|
||||
*author: xxx
|
||||
*****************************************************************************************/
|
||||
#if defined (CONFIG_GPIO_PCA9554)
|
||||
struct rk2818_gpio_expander_info extern_gpio_settinginfo[] = {
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI0,
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI4,// tp3
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI5,//tp4
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI6,//tp2
|
||||
.pin_type = GPIO_OUT,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI7,//tp1
|
||||
.pin_type = GPIO_OUT,
|
||||
.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct pca9554_platform_data rk2818_pca9554_data={
|
||||
.gpio_base=GPIO_EXPANDER_BASE,
|
||||
.gpio_pin_num=CONFIG_EXPANDED_GPIO_NUM,
|
||||
.gpio_irq_start=NR_AIC_IRQS + 2*NUM_GROUP,
|
||||
.irq_pin_num=CONFIG_EXPANDED_GPIO_IRQ_NUM,
|
||||
.pca9954_irq_pin=RK2818_PIN_PE2,
|
||||
.settinginfo=extern_gpio_settinginfo,
|
||||
.settinginfolen=ARRAY_SIZE(extern_gpio_settinginfo),
|
||||
};
|
||||
#endif
|
||||
|
||||
/*****************************************************************************************
|
||||
* I2C devices
|
||||
*author: kfx
|
||||
*****************************************************************************************/
|
||||
void rk2818_i2c0_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, IOMUXA_I2C0);
|
||||
}
|
||||
|
||||
void rk2818_i2c1_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, IOMUXA_I2C1);
|
||||
}
|
||||
struct rk2818_i2c_platform_data default_i2c0_data = {
|
||||
.bus_num = 0,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
.mode = I2C_MODE_IRQ, //I2C_MODE_POLL
|
||||
.cfg_gpio = rk2818_i2c0_cfg_gpio,
|
||||
};
|
||||
struct rk2818_i2c_platform_data default_i2c1_data = {
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
.bus_num = 1,
|
||||
#else
|
||||
.bus_num = 0,
|
||||
#endif
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
.mode = I2C_MODE_IRQ, //I2C_MODE_POLL
|
||||
.cfg_gpio = rk2818_i2c1_cfg_gpio,
|
||||
};
|
||||
|
||||
struct rk2818_i2c_spi_data default_i2c2_data = {
|
||||
.bus_num = 2,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
struct rk2818_i2c_spi_data default_i2c3_data = {
|
||||
|
||||
.bus_num = 3,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c0_devices[] = {
|
||||
#if defined (CONFIG_RK1000_CONTROL)
|
||||
{
|
||||
.type = "rk1000_control",
|
||||
.addr = 0x40,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_RK1000_TVOUT)
|
||||
{
|
||||
.type = "rk1000_tvout",
|
||||
.addr = 0x42,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_RK1000)
|
||||
{
|
||||
.type = "rk1000_i2c_codec",
|
||||
.addr = 0x60,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_WM8988)
|
||||
{
|
||||
.type = "wm8988",
|
||||
.addr = 0x1a,
|
||||
.flags = 0,
|
||||
}
|
||||
#endif
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c1_devices[] = {
|
||||
#if defined (CONFIG_RTC_HYM8563)
|
||||
{
|
||||
.type = "rtc_hym8563",
|
||||
.addr = 0x51,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_FM_QN8006)
|
||||
{
|
||||
.type = "fm_qn8006",
|
||||
.addr = 0x2b,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_GPIO_PCA9554)
|
||||
{
|
||||
.type = "extend_gpio_pca9554",
|
||||
.addr = 0x3c,
|
||||
.flags = 0,
|
||||
.platform_data=&rk2818_pca9554_data.gpio_base,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_PMIC_LP8725)
|
||||
{
|
||||
.type = "lp8725",
|
||||
.addr = 0x79,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
{},
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata board_i2c2_devices[] = {
|
||||
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c3_devices[] = {
|
||||
#if defined (CONFIG_SND_SOC_WM8994)
|
||||
{
|
||||
.type = "wm8994",
|
||||
.addr = 0x1a,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* SPI devices
|
||||
*author: lhh
|
||||
*****************************************************************************************/
|
||||
static struct spi_board_info board_spi_devices[] = {
|
||||
#if defined(CONFIG_SPI_FPGA)
|
||||
{ /* fpga ice65l08xx */
|
||||
.modalias = "spi_fpga",
|
||||
.chip_select = 1,
|
||||
.max_speed_hz = 8 * 1000 * 1000,
|
||||
.bus_num = 0,
|
||||
.mode = SPI_MODE_0,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_ENC28J60)
|
||||
{ /* net chip */
|
||||
.modalias = "enc28j60",
|
||||
.chip_select = 1,
|
||||
.max_speed_hz = 12 * 1000 * 1000,
|
||||
.bus_num = 0,
|
||||
.mode = SPI_MODE_0,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_XPT2046_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI)
|
||||
{
|
||||
.modalias = "xpt2046_ts",
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 125 * 1000 * 26,/* (max sample rate @ 3V) * (cmd + data + overhead) */
|
||||
.bus_num = 0,
|
||||
.irq = RK2818_PIN_PE3,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*rk2818_fb gpio information*/
|
||||
static struct rk2818_fb_gpio rk2818_fb_gpio_info = {
|
||||
.display_on = (GPIO_LOW<<16)|RK2818_PIN_PA2,
|
||||
.lcd_standby = 0,
|
||||
.mcu_fmk_pin = 0,
|
||||
};
|
||||
|
||||
/*rk2818_fb iomux information*/
|
||||
static struct rk2818_fb_iomux rk2818_fb_iomux_info = {
|
||||
.data16 = GPIOC_LCDC16BIT_SEL_NAME,
|
||||
.data18 = GPIOC_LCDC18BIT_SEL_NAME,
|
||||
.data24 = GPIOC_LCDC24BIT_SEL_NAME,
|
||||
.den = CXGPIO_LCDDEN_SEL_NAME,
|
||||
.vsync = CXGPIO_LCDVSYNC_SEL_NAME,
|
||||
.mcu_fmk = 0,
|
||||
};
|
||||
/*rk2818_fb*/
|
||||
struct rk2818_fb_mach_info rk2818_fb_mach_info = {
|
||||
.gpio = &rk2818_fb_gpio_info,
|
||||
.iomux = &rk2818_fb_iomux_info,
|
||||
};
|
||||
|
||||
struct rk2818bl_info rk2818_bl_info = {
|
||||
.pwm_id = 0,
|
||||
.pw_pin = GPIO_HIGH | (RK2818_PIN_PA3<< 8) ,
|
||||
.bl_ref = 0,
|
||||
.pw_iomux = GPIOA23_UART2_SEL_NAME,
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* dm9000 net work devices
|
||||
* author:lyx
|
||||
********************************************************/
|
||||
#ifdef CONFIG_DM9000
|
||||
/*
|
||||
GPIOA5_FLASHCS1_SEL_NAME IOMUXB_FLASH_CS1
|
||||
GPIOA6_FLASHCS2_SEL_NAME IOMUXB_FLASH_CS2
|
||||
GPIOA7_FLASHCS3_SEL_NAME IOMUXB_FLASH_CS3
|
||||
GPIOE_SPI1_FLASH_SEL1_NAME IOMUXA_FLASH_CS45
|
||||
GPIOE_SPI1_FLASH_SEL_NAME IOMUXA_FLASH_CS67
|
||||
*/
|
||||
#define DM9000_USE_NAND_CS 1 //cs can be 1,2,3,4,5,6 or 7
|
||||
#define DM9000_CS_IOMUX_NAME GPIOA5_FLASHCS1_SEL_NAME
|
||||
#define DM9000_CS_IOMUX_MODE IOMUXB_FLASH_CS1
|
||||
#define DM9000_NET_INT_PIN RK2818_PIN_PE2
|
||||
#define DM9000_INT_IOMUX_NAME GPIOE_SPI1_FLASH_SEL1_NAME
|
||||
#define DM9000_INT_IOMUX_MODE IOMUXA_GPIO1_A12
|
||||
#define DM9000_INT_INIT_VALUE GPIOPullDown
|
||||
#define DM9000_IRQ IRQF_TRIGGER_HIGH
|
||||
#define DM9000_IO_ADDR (RK2818_NANDC_PHYS + 0x800 + DM9000_USE_NAND_CS*0x100 + 0x8)
|
||||
#define DM9000_DATA_ADDR (RK2818_NANDC_PHYS + 0x800 + DM9000_USE_NAND_CS*0x100 + 0x4)
|
||||
|
||||
int dm9k_gpio_set(void)
|
||||
{
|
||||
//cs
|
||||
rk2818_mux_api_set(DM9000_CS_IOMUX_NAME, DM9000_CS_IOMUX_MODE);
|
||||
|
||||
//int
|
||||
rk2818_mux_api_set(DM9000_INT_IOMUX_NAME, DM9000_INT_IOMUX_MODE);
|
||||
|
||||
if (gpio_request(DM9000_NET_INT_PIN, "dm9000 interrupt")) {
|
||||
gpio_free(DM9000_NET_INT_PIN);
|
||||
rk2818_mux_api_mode_resume(DM9000_INT_IOMUX_NAME);
|
||||
rk2818_mux_api_mode_resume(DM9000_CS_IOMUX_NAME);
|
||||
printk("[fun:%s line:%d], request gpio for net interrupt fail\n", __func__,__LINE__);
|
||||
|
||||
return -1;
|
||||
}
|
||||
gpio_pull_updown(DM9000_NET_INT_PIN, DM9000_INT_INIT_VALUE);
|
||||
gpio_direction_input(DM9000_NET_INT_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int dm9k_gpio_free(void)
|
||||
{
|
||||
gpio_free(DM9000_NET_INT_PIN);
|
||||
rk2818_mux_api_mode_resume(DM9000_INT_IOMUX_NAME);
|
||||
rk2818_mux_api_mode_resume(DM9000_CS_IOMUX_NAME);
|
||||
return 0;
|
||||
}
|
||||
int dm9k_get_gpio_irq(void)
|
||||
{
|
||||
return gpio_to_irq(DM9000_NET_INT_PIN);
|
||||
}
|
||||
|
||||
static struct resource dm9k_resource[] = {
|
||||
[0] = {
|
||||
.start = DM9000_IO_ADDR,
|
||||
.end = DM9000_IO_ADDR + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = DM9000_DATA_ADDR,
|
||||
.end = DM9000_DATA_ADDR + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = DM9000_NET_INT_PIN,
|
||||
.end = DM9000_NET_INT_PIN,
|
||||
.flags = IORESOURCE_IRQ | DM9000_IRQ,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* for the moment we limit ourselves to 8bit IO until some
|
||||
* better IO routines can be written and tested
|
||||
*/
|
||||
struct dm9000_plat_data dm9k_platdata = {
|
||||
.flags = DM9000_PLATF_8BITONLY,
|
||||
.io_init = dm9k_gpio_set,
|
||||
.io_deinit = dm9k_gpio_free,
|
||||
.get_irq_num = dm9k_get_gpio_irq,
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_dm9k = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(dm9k_resource),
|
||||
.resource = dm9k_resource,
|
||||
.dev = {
|
||||
.platform_data = &dm9k_platdata,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
#ifdef CONFIG_UART1_RK2818
|
||||
&rk2818_device_uart1,
|
||||
#endif
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
&rk2818_device_i2c0,
|
||||
#endif
|
||||
#ifdef CONFIG_I2C1_RK2818
|
||||
&rk2818_device_i2c1,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC0_RK2818
|
||||
&rk2818_device_sdmmc0,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC1_RK2818
|
||||
&rk2818_device_sdmmc1,
|
||||
#endif
|
||||
&rk2818_device_spim,
|
||||
&rk2818_device_i2s,
|
||||
#if defined(CONFIG_ANDROID_PMEM)
|
||||
&rk2818_device_pmem,
|
||||
&rk2818_device_pmem_dsp,
|
||||
#endif
|
||||
&rk2818_device_adc,
|
||||
&rk2818_device_adckey,
|
||||
&rk2818_device_battery,
|
||||
&rk2818_device_fb,
|
||||
&rk2818_device_backlight,
|
||||
&rk2818_device_dsp,
|
||||
#ifdef CONFIG_MTD_NAND_RK2818
|
||||
&rk2818_nand_device,
|
||||
#endif
|
||||
#ifdef CONFIG_DM9000
|
||||
&rk2818_device_dm9k,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DWC_OTG
|
||||
&rk2818_device_dwc_otg,
|
||||
#endif
|
||||
#ifdef CONFIG_RK2818_HOST11
|
||||
&rk2818_device_host11,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_ANDROID
|
||||
&android_usb_device,
|
||||
&usb_mass_storage_device,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern struct sys_timer rk2818_timer;
|
||||
#define POWER_PIN RK2818_PIN_PA3
|
||||
static void rk2818_power_on(void)
|
||||
{
|
||||
int ret;
|
||||
ret = gpio_request(POWER_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("failed to request power_off gpio\n");
|
||||
goto err_free_gpio;
|
||||
}
|
||||
|
||||
gpio_pull_updown(POWER_PIN, GPIOPullUp);
|
||||
ret = gpio_direction_output(POWER_PIN, GPIO_HIGH);
|
||||
if (ret) {
|
||||
printk("failed to set power_off gpio output\n");
|
||||
goto err_free_gpio;
|
||||
}
|
||||
|
||||
gpio_set_value(POWER_PIN, 1);/*power on*/
|
||||
|
||||
err_free_gpio:
|
||||
gpio_free(POWER_PIN);
|
||||
}
|
||||
|
||||
static void rk2818_power_off(void)
|
||||
{
|
||||
printk("shut down system now ...\n");
|
||||
gpio_set_value(POWER_PIN, 0);/*power down*/
|
||||
}
|
||||
|
||||
void lcd_set_iomux(u8 enable)
|
||||
{
|
||||
int ret=-1;
|
||||
|
||||
if(enable)
|
||||
{
|
||||
rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 0);
|
||||
ret = gpio_request(RK2818_PIN_PA4, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PA4);
|
||||
printk(">>>>>> lcd cs gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
|
||||
rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, 0);
|
||||
|
||||
ret = gpio_request(RK2818_PIN_PE7, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PE7);
|
||||
printk(">>>>>> lcd clk gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
|
||||
ret = gpio_request(RK2818_PIN_PE6, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PE6);
|
||||
printk(">>>>>> lcd txd gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_free(RK2818_PIN_PA4);
|
||||
//rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 1);
|
||||
rk2818_mux_api_mode_resume(CXGPIO_HSADC_SEL_NAME);
|
||||
|
||||
gpio_free(RK2818_PIN_PE7);
|
||||
gpio_free(RK2818_PIN_PE6);
|
||||
//rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, 2);
|
||||
rk2818_mux_api_mode_resume(GPIOE_U1IR_I2C1_NAME);
|
||||
}
|
||||
return ;
|
||||
pin_err:
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
struct lcd_td043mgea1_data lcd_td043mgea1 = {
|
||||
.pin_txd = RK2818_PIN_PE6,
|
||||
.pin_clk = RK2818_PIN_PE7,
|
||||
.pin_cs = RK2818_PIN_PA4,
|
||||
.screen_set_iomux = lcd_set_iomux,
|
||||
};
|
||||
|
||||
// adc ---> key
|
||||
static ADC_keyst gAdcValueTab[] =
|
||||
{
|
||||
{95, AD2KEY1},///VOLUME_DOWN
|
||||
{192, AD2KEY2},///VOLUME_UP
|
||||
{280, AD2KEY3},///MENU
|
||||
{376, AD2KEY4},///HOME
|
||||
{467, AD2KEY5},///BACK
|
||||
{560, AD2KEY6},///CALL
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static unsigned char gInitKeyCode[] =
|
||||
{
|
||||
AD2KEY1,AD2KEY2,AD2KEY3,AD2KEY4,AD2KEY5,AD2KEY6,
|
||||
ENDCALL,KEYSTART,KEY_WAKEUP,
|
||||
};
|
||||
|
||||
struct adc_key_data rk2818_adc_key = {
|
||||
.pin_playon = RK2818_PIN_PA3,
|
||||
.playon_level = 1,
|
||||
.adc_empty = 900,
|
||||
.adc_invalid = 20,
|
||||
.adc_drift = 50,
|
||||
.adc_chn = 1,
|
||||
.adc_key_table = gAdcValueTab,
|
||||
.initKeyCode = gInitKeyCode,
|
||||
.adc_key_cnt = 9,
|
||||
};
|
||||
|
||||
static void __init machine_rk2818_init_irq(void)
|
||||
{
|
||||
rk2818_init_irq();
|
||||
rk2818_gpio_init(rk2818_gpioBank, 8);
|
||||
rk2818_gpio_irq_setup();
|
||||
}
|
||||
|
||||
static void __init machine_rk2818_board_init(void)
|
||||
{
|
||||
rk2818_power_on();
|
||||
pm_power_off = rk2818_power_off;
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
i2c_register_board_info(default_i2c0_data.bus_num, board_i2c0_devices,
|
||||
ARRAY_SIZE(board_i2c0_devices));
|
||||
#endif
|
||||
#ifdef CONFIG_I2C1_RK2818
|
||||
i2c_register_board_info(default_i2c1_data.bus_num, board_i2c1_devices,
|
||||
ARRAY_SIZE(board_i2c1_devices));
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_FPGA_I2C
|
||||
i2c_register_board_info(default_i2c2_data.bus_num, board_i2c2_devices,
|
||||
ARRAY_SIZE(board_i2c2_devices));
|
||||
i2c_register_board_info(default_i2c3_data.bus_num, board_i2c3_devices,
|
||||
ARRAY_SIZE(board_i2c3_devices));
|
||||
#endif
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices));
|
||||
rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,IOMUXA_GPIO0_B4); //IOMUXA_SPI0_CSN0);//use for gpio SPI CS0
|
||||
rk2818_mux_api_set(GPIOB0_SPI0CSN1_MMC1PCA_NAME,IOMUXA_GPIO0_B0); //IOMUXA_SPI0_CSN1);//use for gpio SPI CS1
|
||||
rk2818_mux_api_set(GPIOB_SPI0_MMC0_NAME,IOMUXA_SPI0);//use for SPI CLK SDI SDO
|
||||
}
|
||||
|
||||
static void __init machine_rk2818_mapio(void)
|
||||
{
|
||||
iotable_init(rk2818_io_desc, ARRAY_SIZE(rk2818_io_desc));
|
||||
rk2818_clock_init();
|
||||
rk2818_iomux_init();
|
||||
}
|
||||
|
||||
MACHINE_START(RK2818, "RK28board")
|
||||
|
||||
/* UART for LL DEBUG */
|
||||
.phys_io = 0x18002000,
|
||||
.io_pg_offst = ((0xFF100000) >> 18) & 0xfffc,
|
||||
.boot_params = RK2818_SDRAM_PHYS + 0xf8000,
|
||||
.map_io = machine_rk2818_mapio,
|
||||
.init_irq = machine_rk2818_init_irq,
|
||||
.init_machine = machine_rk2818_board_init,
|
||||
.timer = &rk2818_timer,
|
||||
MACHINE_END
|
||||
|
|
@ -1,762 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/board-phonesdk.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/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* 声明了rk2818_gpioBank数组,并定义了GPIO寄存器组ID和寄存器基地址。
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
static struct rk2818_gpio_bank rk2818_gpioBank[] = {
|
||||
{
|
||||
.id = RK2818_ID_PIOA,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOB,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOC,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOD,
|
||||
.offset = RK2818_GPIO0_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOE,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOF,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOG,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
},
|
||||
{
|
||||
.id = RK2818_ID_PIOH,
|
||||
.offset = RK2818_GPIO1_BASE,
|
||||
.clock = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
//IO映射方式描述 ,每个为一段线性连续映射
|
||||
static struct map_desc rk2818_io_desc[] __initdata = {
|
||||
|
||||
{
|
||||
.virtual = RK2818_MCDMA_BASE, //虚拟地址
|
||||
.pfn = __phys_to_pfn(RK2818_MCDMA_PHYS), //物理地址,须与页表对齐
|
||||
.length = RK2818_MCDMA_SIZE, //长度
|
||||
.type = MT_DEVICE //映射方式
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_DWDMA_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_DWDMA_PHYS),
|
||||
.length = RK2818_DWDMA_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_INTC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_INTC_PHYS),
|
||||
.length = RK2818_INTC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_NANDC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_NANDC_PHYS),
|
||||
.length = RK2818_NANDC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_SDRAMC_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_SDRAMC_PHYS),
|
||||
.length = RK2818_SDRAMC_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_ARMDARBITER_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_ARMDARBITER_PHYS),
|
||||
.length = RK2818_ARMDARBITER_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_APB_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_APB_PHYS),
|
||||
.length = 0xa0000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
{
|
||||
.virtual = RK2818_WDT_BASE,
|
||||
.pfn = __phys_to_pfn(RK2818_WDT_PHYS),
|
||||
.length = 0xa0000, ///apb bus i2s i2c spi no map in this
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
/*****************************************************************************************
|
||||
* SDMMC devices
|
||||
*author: kfx
|
||||
*****************************************************************************************/
|
||||
void rk2818_sdmmc0_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOF3_APWM1_MMC0DETN_NAME, IOMUXA_SDMMC1_DETECT_N);
|
||||
rk2818_mux_api_set(GPIOH_MMC0D_SEL_NAME, IOMUXA_SDMMC0_DATA123);
|
||||
rk2818_mux_api_set(GPIOH_MMC0_SEL_NAME, IOMUXA_SDMMC0_CMD_DATA0_CLKOUT);
|
||||
}
|
||||
|
||||
void rk2818_sdmmc1_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOG_MMC1_SEL_NAME, IOMUXA_SDMMC1_CMD_DATA0_CLKOUT);
|
||||
rk2818_mux_api_set(GPIOG_MMC1D_SEL_NAME, IOMUXA_SDMMC1_DATA123);
|
||||
#if 0
|
||||
/* wifi power up (gpio control) */
|
||||
rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);
|
||||
rk2818_mux_api_set(GPIOF5_APWM3_DPWM3_NAME,IOMUXB_GPIO1_B5);
|
||||
gpio_request(RK2818_PIN_PH7, "sdio");
|
||||
gpio_direction_output(RK2818_PIN_PH7,GPIO_HIGH);
|
||||
#endif
|
||||
|
||||
}
|
||||
#define CONFIG_SDMMC0_USE_DMA
|
||||
#define CONFIG_SDMMC1_USE_DMA
|
||||
struct rk2818_sdmmc_platform_data default_sdmmc0_data = {
|
||||
.host_ocr_avail = (MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
|
||||
MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33|
|
||||
MMC_VDD_33_34|MMC_VDD_34_35| MMC_VDD_35_36),
|
||||
.host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
|
||||
.cfg_gpio = rk2818_sdmmc0_cfg_gpio,
|
||||
.no_detect = 0,
|
||||
.dma_name = "sd_mmc",
|
||||
#ifdef CONFIG_SDMMC0_USE_DMA
|
||||
.use_dma = 1,
|
||||
#else
|
||||
.use_dma = 0,
|
||||
#endif
|
||||
};
|
||||
struct rk2818_sdmmc_platform_data default_sdmmc1_data = {
|
||||
.host_ocr_avail = (MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|
|
||||
MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32|
|
||||
MMC_VDD_32_33|MMC_VDD_33_34),
|
||||
.host_caps = (MMC_CAP_4_BIT_DATA|MMC_CAP_SDIO_IRQ|
|
||||
MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
|
||||
.cfg_gpio = rk2818_sdmmc1_cfg_gpio,
|
||||
.no_detect = 1,
|
||||
.dma_name = "sdio",
|
||||
#ifdef CONFIG_SDMMC1_USE_DMA
|
||||
.use_dma = 1,
|
||||
#else
|
||||
.use_dma = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* extern gpio devices
|
||||
*author: xxx
|
||||
*****************************************************************************************/
|
||||
#if defined (CONFIG_GPIO_PCA9554)
|
||||
struct rk2818_gpio_expander_info extern_gpio_settinginfo[] = {
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI0,
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI4,// tp3
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI5,//tp4
|
||||
.pin_type = GPIO_IN,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI6,//tp2
|
||||
.pin_type = GPIO_OUT,
|
||||
//.pin_value =GPIO_HIGH,
|
||||
},
|
||||
{
|
||||
.gpio_num =RK2818_PIN_PI7,//tp1
|
||||
.pin_type = GPIO_OUT,
|
||||
.pin_value =GPIO_HIGH,
|
||||
},
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct pca9554_platform_data rk2818_pca9554_data={
|
||||
.gpio_base=GPIO_EXPANDER_BASE,
|
||||
.gpio_pin_num=CONFIG_EXPANDED_GPIO_NUM,
|
||||
.gpio_irq_start=NR_AIC_IRQS + 2*NUM_GROUP,
|
||||
.irq_pin_num=CONFIG_EXPANDED_GPIO_IRQ_NUM,
|
||||
.pca9954_irq_pin=RK2818_PIN_PE2,
|
||||
.settinginfo=extern_gpio_settinginfo,
|
||||
.settinginfolen=ARRAY_SIZE(extern_gpio_settinginfo),
|
||||
};
|
||||
#endif
|
||||
|
||||
/*****************************************************************************************
|
||||
* I2C devices
|
||||
*author: kfx
|
||||
*****************************************************************************************/
|
||||
void rk2818_i2c0_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOE_I2C0_SEL_NAME, IOMUXA_I2C0);
|
||||
}
|
||||
|
||||
void rk2818_i2c1_cfg_gpio(struct platform_device *dev)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, IOMUXA_I2C1);
|
||||
}
|
||||
struct rk2818_i2c_platform_data default_i2c0_data = {
|
||||
.bus_num = 0,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
.cfg_gpio = rk2818_i2c0_cfg_gpio,
|
||||
};
|
||||
struct rk2818_i2c_platform_data default_i2c1_data = {
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
.bus_num = 1,
|
||||
#else
|
||||
.bus_num = 0,
|
||||
#endif
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
.cfg_gpio = rk2818_i2c1_cfg_gpio,
|
||||
};
|
||||
|
||||
struct rk2818_i2c_spi_data default_i2c2_data = {
|
||||
.bus_num = 2,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
struct rk2818_i2c_spi_data default_i2c3_data = {
|
||||
|
||||
.bus_num = 3,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c0_devices[] = {
|
||||
#if defined (CONFIG_RK1000_CONTROL)
|
||||
{
|
||||
.type = "rk1000_control",
|
||||
.addr = 0x40,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_RK1000_TVOUT)
|
||||
{
|
||||
.type = "rk1000_tvout",
|
||||
.addr = 0x42,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_RK1000)
|
||||
{
|
||||
.type = "rk1000_i2c_codec",
|
||||
.addr = 0x60,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_SND_SOC_WM8988)
|
||||
{
|
||||
.type = "wm8988",
|
||||
.addr = 0x1a,
|
||||
.flags = 0,
|
||||
}
|
||||
#endif
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c1_devices[] = {
|
||||
#if defined (CONFIG_RTC_HYM8563)
|
||||
{
|
||||
.type = "rtc_hym8563",
|
||||
.addr = 0x51,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_FM_QN8006)
|
||||
{
|
||||
.type = "fm_qn8006",
|
||||
.addr = 0x2b,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_GPIO_PCA9554)
|
||||
{
|
||||
.type = "extend_gpio_pca9554",
|
||||
.addr = 0x3c,
|
||||
.flags = 0,
|
||||
.platform_data=&rk2818_pca9554_data.gpio_base,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_PMIC_LP8725)
|
||||
{
|
||||
.type = "lp8725",
|
||||
.addr = 0x79,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_GS_MMA7660)
|
||||
{
|
||||
.type = "gs_mma7660",
|
||||
.addr = 0x4c,
|
||||
.flags = 0,
|
||||
.irq = RK2818_PIN_PE3,
|
||||
},
|
||||
#endif
|
||||
{},
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata board_i2c2_devices[] = {
|
||||
|
||||
};
|
||||
static struct i2c_board_info __initdata board_i2c3_devices[] = {
|
||||
#if defined (CONFIG_SND_SOC_WM8994)
|
||||
{
|
||||
.type = "wm8994",
|
||||
.addr = 0x1a,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************************
|
||||
* SPI devices
|
||||
*author: lhh
|
||||
*****************************************************************************************/
|
||||
static struct spi_board_info board_spi_devices[] = {
|
||||
#if defined(CONFIG_SPI_FPGA)
|
||||
{ /* fpga ice65l08xx */
|
||||
.modalias = "spi_fpga",
|
||||
.chip_select = 1,
|
||||
.max_speed_hz = 8 * 1000 * 1000,
|
||||
.bus_num = 0,
|
||||
.mode = SPI_MODE_0,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_ENC28J60)
|
||||
{ /* net chip */
|
||||
.modalias = "enc28j60",
|
||||
.chip_select = 1,
|
||||
.max_speed_hz = 12 * 1000 * 1000,
|
||||
.bus_num = 0,
|
||||
.mode = SPI_MODE_0,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_XPT2046_SPI) || defined(CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI)
|
||||
{
|
||||
.modalias = "xpt2046_ts",
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 125 * 1000 * 26,/* (max sample rate @ 3V) * (cmd + data + overhead) */
|
||||
.bus_num = 0,
|
||||
.irq = RK2818_PIN_PE3,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*rk2818_fb gpio information*/
|
||||
static struct rk2818_fb_gpio rk2818_fb_gpio_info = {
|
||||
.display_on = (GPIO_LOW<<16)|RK2818_PIN_PA2,
|
||||
.lcd_standby = 0,
|
||||
.mcu_fmk_pin = 0,
|
||||
};
|
||||
|
||||
/*rk2818_fb iomux information*/
|
||||
static struct rk2818_fb_iomux rk2818_fb_iomux_info = {
|
||||
.data16 = GPIOC_LCDC16BIT_SEL_NAME,
|
||||
.data18 = GPIOC_LCDC18BIT_SEL_NAME,
|
||||
.data24 = GPIOC_LCDC24BIT_SEL_NAME,
|
||||
.den = CXGPIO_LCDDEN_SEL_NAME,
|
||||
.vsync = CXGPIO_LCDVSYNC_SEL_NAME,
|
||||
.mcu_fmk = 0,
|
||||
};
|
||||
/*rk2818_fb*/
|
||||
struct rk2818_fb_mach_info rk2818_fb_mach_info = {
|
||||
.gpio = &rk2818_fb_gpio_info,
|
||||
.iomux = &rk2818_fb_iomux_info,
|
||||
};
|
||||
|
||||
struct rk2818bl_info rk2818_bl_info = {
|
||||
.pwm_id = 0,
|
||||
.pw_pin = GPIO_HIGH | (RK2818_PIN_PF4<< 8) ,
|
||||
.bl_ref = 0,
|
||||
.pw_iomux = GPIOF34_UART3_SEL_NAME,
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* dm9000 net work devices
|
||||
* author:lyx
|
||||
********************************************************/
|
||||
#ifdef CONFIG_DM9000
|
||||
/*
|
||||
GPIOA5_FLASHCS1_SEL_NAME IOMUXB_FLASH_CS1
|
||||
GPIOA6_FLASHCS2_SEL_NAME IOMUXB_FLASH_CS2
|
||||
GPIOA7_FLASHCS3_SEL_NAME IOMUXB_FLASH_CS3
|
||||
GPIOE_SPI1_FLASH_SEL1_NAME IOMUXA_FLASH_CS45
|
||||
GPIOE_SPI1_FLASH_SEL_NAME IOMUXA_FLASH_CS67
|
||||
*/
|
||||
#define DM9000_USE_NAND_CS 1 //cs can be 1,2,3,4,5,6 or 7
|
||||
#define DM9000_CS_IOMUX_NAME GPIOA5_FLASHCS1_SEL_NAME
|
||||
#define DM9000_CS_IOMUX_MODE IOMUXB_FLASH_CS1
|
||||
#define DM9000_NET_INT_PIN RK2818_PIN_PA1
|
||||
#define DM9000_INT_IOMUX_NAME GPIOA1_HOSTDATA17_SEL_NAME
|
||||
#define DM9000_INT_IOMUX_MODE IOMUXB_GPIO0_A1
|
||||
#define DM9000_INT_INIT_VALUE GPIOPullDown
|
||||
#define DM9000_IRQ IRQF_TRIGGER_HIGH
|
||||
#define DM9000_IO_ADDR (RK2818_NANDC_PHYS + 0x800 + DM9000_USE_NAND_CS*0x100 + 0x8)
|
||||
#define DM9000_DATA_ADDR (RK2818_NANDC_PHYS + 0x800 + DM9000_USE_NAND_CS*0x100 + 0x4)
|
||||
|
||||
int dm9k_gpio_set(void)
|
||||
{
|
||||
//cs
|
||||
rk2818_mux_api_set(DM9000_CS_IOMUX_NAME, DM9000_CS_IOMUX_MODE);
|
||||
|
||||
//int
|
||||
rk2818_mux_api_set(DM9000_INT_IOMUX_NAME, DM9000_INT_IOMUX_MODE);
|
||||
|
||||
if (gpio_request(DM9000_NET_INT_PIN, "dm9000 interrupt")) {
|
||||
gpio_free(DM9000_NET_INT_PIN);
|
||||
rk2818_mux_api_mode_resume(DM9000_INT_IOMUX_NAME);
|
||||
rk2818_mux_api_mode_resume(DM9000_CS_IOMUX_NAME);
|
||||
printk("[fun:%s line:%d], request gpio for net interrupt fail\n", __func__,__LINE__);
|
||||
|
||||
return -1;
|
||||
}
|
||||
gpio_pull_updown(DM9000_NET_INT_PIN, DM9000_INT_INIT_VALUE);
|
||||
gpio_direction_input(DM9000_NET_INT_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int dm9k_gpio_free(void)
|
||||
{
|
||||
gpio_free(DM9000_NET_INT_PIN);
|
||||
rk2818_mux_api_mode_resume(DM9000_INT_IOMUX_NAME);
|
||||
rk2818_mux_api_mode_resume(DM9000_CS_IOMUX_NAME);
|
||||
return 0;
|
||||
}
|
||||
int dm9k_get_gpio_irq(void)
|
||||
{
|
||||
return gpio_to_irq(DM9000_NET_INT_PIN);
|
||||
}
|
||||
|
||||
static struct resource dm9k_resource[] = {
|
||||
[0] = {
|
||||
.start = DM9000_IO_ADDR,
|
||||
.end = DM9000_IO_ADDR + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = DM9000_DATA_ADDR,
|
||||
.end = DM9000_DATA_ADDR + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = DM9000_NET_INT_PIN,
|
||||
.end = DM9000_NET_INT_PIN,
|
||||
.flags = IORESOURCE_IRQ | DM9000_IRQ,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* for the moment we limit ourselves to 8bit IO until some
|
||||
* better IO routines can be written and tested
|
||||
*/
|
||||
struct dm9000_plat_data dm9k_platdata = {
|
||||
.flags = DM9000_PLATF_8BITONLY,
|
||||
.io_init = dm9k_gpio_set,
|
||||
.io_deinit = dm9k_gpio_free,
|
||||
.get_irq_num = dm9k_get_gpio_irq,
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_dm9k = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(dm9k_resource),
|
||||
.resource = dm9k_resource,
|
||||
.dev = {
|
||||
.platform_data = &dm9k_platdata,
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
#ifdef CONFIG_UART1_RK2818
|
||||
&rk2818_device_uart1,
|
||||
#endif
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
&rk2818_device_i2c0,
|
||||
#endif
|
||||
#ifdef CONFIG_I2C1_RK2818
|
||||
&rk2818_device_i2c1,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC0_RK2818
|
||||
&rk2818_device_sdmmc0,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC1_RK2818
|
||||
&rk2818_device_sdmmc1,
|
||||
#endif
|
||||
&rk2818_device_spim,
|
||||
&rk2818_device_i2s,
|
||||
#if defined(CONFIG_ANDROID_PMEM)
|
||||
&rk2818_device_pmem,
|
||||
&rk2818_device_pmem_dsp,
|
||||
#endif
|
||||
&rk2818_device_adc,
|
||||
&rk2818_device_adckey,
|
||||
&rk2818_device_battery,
|
||||
&rk2818_device_fb,
|
||||
&rk2818_device_backlight,
|
||||
&rk2818_device_dsp,
|
||||
#ifdef CONFIG_MTD_NAND_RK2818
|
||||
&rk2818_nand_device,
|
||||
#endif
|
||||
#ifdef CONFIG_DM9000
|
||||
&rk2818_device_dm9k,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DWC_OTG
|
||||
&rk2818_device_dwc_otg,
|
||||
#endif
|
||||
#ifdef CONFIG_RK2818_HOST11
|
||||
&rk2818_device_host11,
|
||||
#endif
|
||||
#ifdef CONFIG_USB_ANDROID
|
||||
&android_usb_device,
|
||||
&usb_mass_storage_device,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern struct sys_timer rk2818_timer;
|
||||
#define POWER_PIN RK2818_PIN_PB1
|
||||
static void rk2818_power_on(void)
|
||||
{
|
||||
int ret;
|
||||
ret = gpio_request(POWER_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("failed to request power_off gpio\n");
|
||||
goto err_free_gpio;
|
||||
}
|
||||
|
||||
gpio_pull_updown(POWER_PIN, GPIOPullUp);
|
||||
ret = gpio_direction_output(POWER_PIN, GPIO_HIGH);
|
||||
if (ret) {
|
||||
printk("failed to set power_off gpio output\n");
|
||||
goto err_free_gpio;
|
||||
}
|
||||
|
||||
gpio_set_value(POWER_PIN, 1);/*power on*/
|
||||
|
||||
err_free_gpio:
|
||||
gpio_free(POWER_PIN);
|
||||
}
|
||||
|
||||
static void rk2818_power_off(void)
|
||||
{
|
||||
printk("shut down system now ...\n");
|
||||
gpio_set_value(POWER_PIN, 0);/*power down*/
|
||||
}
|
||||
|
||||
void lcd_set_iomux(u8 enable)
|
||||
{
|
||||
int ret=-1;
|
||||
|
||||
if(enable)
|
||||
{
|
||||
rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 0);
|
||||
ret = gpio_request(RK2818_PIN_PA4, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PA4);
|
||||
printk(">>>>>> lcd cs gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
|
||||
rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, 0);
|
||||
|
||||
ret = gpio_request(RK2818_PIN_PE7, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PE7);
|
||||
printk(">>>>>> lcd clk gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
|
||||
ret = gpio_request(RK2818_PIN_PE6, NULL);
|
||||
if(0)//(ret != 0)
|
||||
{
|
||||
gpio_free(RK2818_PIN_PE6);
|
||||
printk(">>>>>> lcd txd gpio_request err \n ");
|
||||
goto pin_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_free(RK2818_PIN_PA4);
|
||||
//rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 1);
|
||||
rk2818_mux_api_mode_resume(CXGPIO_HSADC_SEL_NAME);
|
||||
|
||||
gpio_free(RK2818_PIN_PE7);
|
||||
gpio_free(RK2818_PIN_PE6);
|
||||
//rk2818_mux_api_set(GPIOE_U1IR_I2C1_NAME, 2);
|
||||
rk2818_mux_api_mode_resume(GPIOE_U1IR_I2C1_NAME);
|
||||
}
|
||||
return ;
|
||||
pin_err:
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
struct lcd_td043mgea1_data lcd_td043mgea1 = {
|
||||
.pin_txd = RK2818_PIN_PE6,
|
||||
.pin_clk = RK2818_PIN_PE7,
|
||||
.pin_cs = RK2818_PIN_PA4,
|
||||
.screen_set_iomux = lcd_set_iomux,
|
||||
};
|
||||
|
||||
// adc ---> key
|
||||
static ADC_keyst gAdcValueTab[] =
|
||||
{
|
||||
{95, AD2KEY1},///VOLUME_DOWN
|
||||
{192, AD2KEY2},///VOLUME_UP
|
||||
{280, AD2KEY3},///MENU
|
||||
{376, AD2KEY4},///HOME
|
||||
{467, AD2KEY5},///BACK
|
||||
{560, AD2KEY6},///CALL
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static unsigned char gInitKeyCode[] =
|
||||
{
|
||||
AD2KEY1,AD2KEY2,AD2KEY3,AD2KEY4,AD2KEY5,AD2KEY6,
|
||||
ENDCALL,KEYSTART,KEY_WAKEUP,
|
||||
};
|
||||
|
||||
struct adc_key_data rk2818_adc_key = {
|
||||
.pin_playon = RK2818_PIN_PA3,
|
||||
.playon_level = 1,
|
||||
.adc_empty = 900,
|
||||
.adc_invalid = 20,
|
||||
.adc_drift = 50,
|
||||
.adc_chn = 1,
|
||||
.adc_key_table = gAdcValueTab,
|
||||
.initKeyCode = gInitKeyCode,
|
||||
.adc_key_cnt = 9,
|
||||
};
|
||||
|
||||
static void __init machine_rk2818_init_irq(void)
|
||||
{
|
||||
rk2818_init_irq();
|
||||
rk2818_gpio_init(rk2818_gpioBank, 8);
|
||||
rk2818_gpio_irq_setup();
|
||||
}
|
||||
|
||||
static void __init machine_rk2818_board_init(void)
|
||||
{
|
||||
rk2818_power_on();
|
||||
pm_power_off = rk2818_power_off;
|
||||
#ifdef CONFIG_I2C0_RK2818
|
||||
i2c_register_board_info(default_i2c0_data.bus_num, board_i2c0_devices,
|
||||
ARRAY_SIZE(board_i2c0_devices));
|
||||
#endif
|
||||
#ifdef CONFIG_I2C1_RK2818
|
||||
i2c_register_board_info(default_i2c1_data.bus_num, board_i2c1_devices,
|
||||
ARRAY_SIZE(board_i2c1_devices));
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_FPGA_I2C
|
||||
i2c_register_board_info(default_i2c2_data.bus_num, board_i2c2_devices,
|
||||
ARRAY_SIZE(board_i2c2_devices));
|
||||
i2c_register_board_info(default_i2c3_data.bus_num, board_i2c3_devices,
|
||||
ARRAY_SIZE(board_i2c3_devices));
|
||||
#endif
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices));
|
||||
rk2818_mux_api_set(GPIOB4_SPI0CS0_MMC0D4_NAME,IOMUXA_GPIO0_B4); //IOMUXA_SPI0_CSN0);//use for gpio SPI CS0
|
||||
rk2818_mux_api_set(GPIOB0_SPI0CSN1_MMC1PCA_NAME,IOMUXA_GPIO0_B0); //IOMUXA_SPI0_CSN1);//use for gpio SPI CS1
|
||||
rk2818_mux_api_set(GPIOB_SPI0_MMC0_NAME,IOMUXA_SPI0);//use for SPI CLK SDI SDO
|
||||
}
|
||||
|
||||
static void __init machine_rk2818_mapio(void)
|
||||
{
|
||||
iotable_init(rk2818_io_desc, ARRAY_SIZE(rk2818_io_desc));
|
||||
rk2818_clock_init();
|
||||
rk2818_iomux_init();
|
||||
}
|
||||
|
||||
MACHINE_START(RK2818, "RK28board")
|
||||
|
||||
/* UART for LL DEBUG */
|
||||
.phys_io = 0x18002000,
|
||||
.io_pg_offst = ((0xFF100000) >> 18) & 0xfffc,
|
||||
.boot_params = RK2818_SDRAM_PHYS + 0xf8000,
|
||||
.map_io = machine_rk2818_mapio,
|
||||
.init_irq = machine_rk2818_init_irq,
|
||||
.init_machine = machine_rk2818_board_init,
|
||||
.timer = &rk2818_timer,
|
||||
MACHINE_END
|
||||
|
||||
|
|
@ -1,162 +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 <asm/gpio.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
//#include <asm/arch/iomux.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#if 1
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define RAHO_BT_GPIO_POWER_N FPGA_PIO1_06
|
||||
#define RAHO_BT_GPIO_RESET_N FPGA_PIO1_07
|
||||
#define RAHO_BT_GPIO_WAKE_UP_N RK2818_PIN_PC6
|
||||
|
||||
static struct rfkill *bt_rfk;
|
||||
static const char bt_name[] = "bcm4329";
|
||||
extern int raho_bt_power_state;
|
||||
extern int raho_wifi_power_state;
|
||||
#ifdef CONFIG_BT_HCIBCM4325
|
||||
int bcm4325_sleep(int bSleep)
|
||||
{
|
||||
// printk("*************bt enter sleep***************\n");
|
||||
if (bSleep)
|
||||
gpio_set_value(RAHO_BT_GPIO_WAKE_UP_N, GPIO_LOW); //low represent bt device may enter sleep
|
||||
else
|
||||
gpio_set_value(RAHO_BT_GPIO_WAKE_UP_N, GPIO_HIGH); //high represent bt device must be awake
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bcm4329_set_block(void *data, bool blocked)
|
||||
{
|
||||
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
|
||||
|
||||
if (false == blocked) {
|
||||
gpio_set_value(RAHO_BT_GPIO_POWER_N, GPIO_HIGH); /* bt power on */
|
||||
gpio_set_value(RAHO_BT_GPIO_RESET_N, GPIO_HIGH); /* bt reset deactive*/
|
||||
mdelay(20);
|
||||
pr_info("bt turn on power\n");
|
||||
}
|
||||
else {
|
||||
if (!raho_wifi_power_state) {
|
||||
gpio_set_value(RAHO_BT_GPIO_POWER_N, 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(RAHO_BT_GPIO_RESET_N, GPIO_LOW); /* bt reset active*/
|
||||
mdelay(20);
|
||||
}
|
||||
|
||||
raho_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 */
|
||||
|
||||
bt_rfk = rfkill_alloc(bt_name,
|
||||
NULL,
|
||||
RFKILL_TYPE_BLUETOOTH,
|
||||
&bcm4329_rfk_ops,
|
||||
NULL);
|
||||
|
||||
if (!bt_rfk)
|
||||
{
|
||||
printk("fail to rfkill_allocate************\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfkill_set_states(bt_rfk, default_state, false);
|
||||
|
||||
rc = rfkill_register(bt_rfk);
|
||||
if (rc)
|
||||
rfkill_destroy(bt_rfk);
|
||||
|
||||
printk("rc=0x%x\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (bt_rfk)
|
||||
rfkill_unregister(bt_rfk);
|
||||
bt_rfk = NULL;
|
||||
|
||||
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 = "raho_rfkill",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
|
@ -1,151 +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 <asm/gpio.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
//#include <asm/arch/iomux.h>
|
||||
//#include <asm/arch/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#if 1
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define RAHO_BT_GPIO_POWER_N FPGA_PIO1_06
|
||||
#define RAHO_BT_GPIO_RESET_N FPGA_PIO1_07
|
||||
|
||||
static struct rfkill *bt_rfk;
|
||||
static const char bt_name[] = "bcm4329";
|
||||
extern int raho_bt_power_state;
|
||||
extern int raho_wifi_power_state;
|
||||
|
||||
static int bcm4329_set_block(void *data, bool blocked)
|
||||
{
|
||||
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
|
||||
|
||||
if (false == blocked) {
|
||||
gpio_set_value(RAHO_BT_GPIO_POWER_N, GPIO_HIGH); /* bt power on */
|
||||
gpio_set_value(RAHO_BT_GPIO_RESET_N, GPIO_HIGH); /* bt reset deactive*/
|
||||
mdelay(20);
|
||||
pr_info("bt turn on power\n");
|
||||
}
|
||||
else {
|
||||
if (!raho_wifi_power_state) {
|
||||
gpio_set_value(RAHO_BT_GPIO_POWER_N, 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(RAHO_BT_GPIO_RESET_N, GPIO_LOW); /* bt reset active*/
|
||||
mdelay(20);
|
||||
}
|
||||
|
||||
raho_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 */
|
||||
|
||||
bt_rfk = rfkill_alloc(bt_name,
|
||||
NULL,
|
||||
RFKILL_TYPE_BLUETOOTH,
|
||||
&bcm4329_rfk_ops,
|
||||
NULL);
|
||||
|
||||
if (!bt_rfk)
|
||||
{
|
||||
printk("fail to rfkill_allocate************\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfkill_set_states(bt_rfk, default_state, false);
|
||||
|
||||
rc = rfkill_register(bt_rfk);
|
||||
if (rc)
|
||||
rfkill_destroy(bt_rfk);
|
||||
|
||||
printk("rc=0x%x\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (bt_rfk)
|
||||
rfkill_unregister(bt_rfk);
|
||||
bt_rfk = NULL;
|
||||
|
||||
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 = "raho_rfkill",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
File diff suppressed because it is too large
Load Diff
|
|
@ -1,107 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/cpufreq.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/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
static struct cpufreq_frequency_table freq_table[] = {
|
||||
{ .frequency = 192000 },
|
||||
{ .frequency = 576000 },
|
||||
{ .frequency = CPUFREQ_TABLE_END },
|
||||
};
|
||||
static struct clk *arm_clk;
|
||||
|
||||
static int rk2818_cpufreq_verify(struct cpufreq_policy *policy)
|
||||
{
|
||||
return cpufreq_frequency_table_verify(policy, freq_table);
|
||||
}
|
||||
|
||||
static int rk2818_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)
|
||||
{
|
||||
int index;
|
||||
struct cpufreq_freqs freqs;
|
||||
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
if (cpufreq_frequency_table_target(policy, freq_table, target_freq, relation, &index)) {
|
||||
pr_err("cpufreq: invalid target_freq: %d\n", target_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (policy->cur == freq_table[index].frequency)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||
printk(KERN_DEBUG "%s %d r %d (%d-%d) selected %d\n", __func__, target_freq, relation, policy->min, policy->max, freq_table[index].frequency);
|
||||
#endif
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = freq_table[index].frequency;
|
||||
freqs.cpu = 0;
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
clk_set_rate(arm_clk, freqs.new * 1000);
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
|
||||
static int __init rk2818_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
arm_clk = clk_get(NULL, "arm");
|
||||
if (IS_ERR(arm_clk))
|
||||
return PTR_ERR(arm_clk);
|
||||
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(cpufreq_frequency_table_cpuinfo(policy, freq_table));
|
||||
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||
policy->cur = clk_get_rate(arm_clk) / 1000;
|
||||
policy->cpuinfo.transition_latency = 300 * NSEC_PER_USEC; // FIXME: 0.3ms?
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk2818_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
clk_put(arm_clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct freq_attr *rk2818_cpufreq_attr[] = {
|
||||
&cpufreq_freq_attr_scaling_available_freqs,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct cpufreq_driver rk2818_cpufreq_driver = {
|
||||
.flags = CPUFREQ_STICKY,
|
||||
.init = rk2818_cpufreq_init,
|
||||
.exit = rk2818_cpufreq_exit,
|
||||
.verify = rk2818_cpufreq_verify,
|
||||
.target = rk2818_cpufreq_target,
|
||||
.name = "rk2818",
|
||||
.attr = rk2818_cpufreq_attr,
|
||||
};
|
||||
|
||||
static int __init rk2818_cpufreq_register(void)
|
||||
{
|
||||
return cpufreq_register_driver(&rk2818_cpufreq_driver);
|
||||
}
|
||||
|
||||
device_initcall(rk2818_cpufreq_register);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,654 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/devices.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/fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include <linux/usb/android_composite.h>
|
||||
#include <linux/delay.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include "devices.h"
|
||||
|
||||
#include <asm/mach/flash.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/rk29_nand.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/rk2818_camera.h> /* ddl@rock-chips.com : camera support */
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
#include <media/soc_camera.h>
|
||||
#include "../../../drivers/staging/android/timed_gpio.h"
|
||||
static struct resource resources_sdmmc0[] = {
|
||||
{
|
||||
.start = IRQ_NR_SDMMC0,
|
||||
.end = IRQ_NR_SDMMC0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_SDMMC0_PHYS,
|
||||
.end = RK2818_SDMMC0_PHYS + SZ_8K -1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
static struct resource resources_sdmmc1[] = {
|
||||
{
|
||||
.start = IRQ_NR_SDMMC1,
|
||||
.end = IRQ_NR_SDMMC1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_SDMMC1_PHYS,
|
||||
.end = RK2818_SDMMC1_PHYS + SZ_8K -1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static struct resource resources_i2c0[] = {
|
||||
{
|
||||
.start = IRQ_NR_I2C0,
|
||||
.end = IRQ_NR_I2C0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_I2C0_PHYS,
|
||||
.end = RK2818_I2C0_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
static struct resource resources_i2c1[] = {
|
||||
{
|
||||
.start = IRQ_NR_I2C1,
|
||||
.end = IRQ_NR_I2C1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_I2C1_PHYS,
|
||||
.end = RK2818_I2C1_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
/*
|
||||
* rk2818 4 uarts device
|
||||
*/
|
||||
#ifdef CONFIG_UART0_RK2818
|
||||
static struct resource resources_uart0[] = {
|
||||
{
|
||||
.start = IRQ_NR_UART0,
|
||||
.end = IRQ_NR_UART0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_UART0_PHYS,
|
||||
.end = RK2818_UART0_PHYS + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART1_RK2818
|
||||
static struct resource resources_uart1[] = {
|
||||
{
|
||||
.start = IRQ_NR_UART1,
|
||||
.end = IRQ_NR_UART1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_UART1_PHYS,
|
||||
.end = RK2818_UART1_PHYS + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART2_RK2818
|
||||
static struct resource resources_uart2[] = {
|
||||
{
|
||||
.start = IRQ_NR_UART2,
|
||||
.end = IRQ_NR_UART2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_UART2_PHYS,
|
||||
.end = RK2818_UART2_PHYS + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART3_RK2818
|
||||
static struct resource resources_uart3[] = {
|
||||
{
|
||||
.start = IRQ_NR_UART3,
|
||||
.end = IRQ_NR_UART3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_UART3_PHYS,
|
||||
.end = RK2818_UART3_PHYS + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
/* sdmmc */
|
||||
struct platform_device rk2818_device_sdmmc0 = {
|
||||
.name = "rk2818_sdmmc",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_sdmmc0),
|
||||
.resource = resources_sdmmc0,
|
||||
.dev = {
|
||||
.platform_data = &default_sdmmc0_data,
|
||||
},
|
||||
};
|
||||
struct platform_device rk2818_device_sdmmc1 = {
|
||||
.name = "rk2818_sdmmc",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(resources_sdmmc1),
|
||||
.resource = resources_sdmmc1,
|
||||
.dev = {
|
||||
.platform_data = &default_sdmmc1_data,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_i2c0 = {
|
||||
.name = "rk2818_i2c",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_i2c0),
|
||||
.resource = resources_i2c0,
|
||||
.dev = {
|
||||
.platform_data = &default_i2c0_data,
|
||||
},
|
||||
};
|
||||
struct platform_device rk2818_device_i2c1 = {
|
||||
.name = "rk2818_i2c",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(resources_i2c1),
|
||||
.resource = resources_i2c1,
|
||||
.dev = {
|
||||
.platform_data = &default_i2c1_data,
|
||||
},
|
||||
};
|
||||
#ifdef CONFIG_SPI_FPGA_I2C
|
||||
struct platform_device rk2818_device_i2c2 = {
|
||||
.name = "fpga_i2c",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.platform_data = &default_i2c2_data,
|
||||
},
|
||||
};
|
||||
struct platform_device rk2818_device_i2c3 = {
|
||||
.name = "fpga_i2c",
|
||||
.id = 3,
|
||||
.dev = {
|
||||
.platform_data = &default_i2c3_data,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART0_RK2818
|
||||
struct platform_device rk2818_device_uart0 = {
|
||||
.name = "rk2818_serial",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_uart0),
|
||||
.resource = resources_uart0,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_serial0_platdata,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART1_RK2818
|
||||
struct platform_device rk2818_device_uart1 = {
|
||||
.name = "rk2818_serial",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(resources_uart1),
|
||||
.resource = resources_uart1,
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART2_RK2818
|
||||
struct platform_device rk2818_device_uart2 = {
|
||||
.name = "rk2818_serial",
|
||||
.id = 2,
|
||||
.num_resources = ARRAY_SIZE(resources_uart2),
|
||||
.resource = resources_uart2,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_serial2_platdata,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#ifdef CONFIG_UART3_RK2818
|
||||
struct platform_device rk2818_device_uart3 = {
|
||||
.name = "rk2818_serial",
|
||||
.id = 3,
|
||||
.num_resources = ARRAY_SIZE(resources_uart3),
|
||||
.resource = resources_uart3,
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* rk2818 spi master device
|
||||
*/
|
||||
static struct resource resources_spim[] = {
|
||||
{
|
||||
.start = IRQ_NR_SPIM,
|
||||
.end = IRQ_NR_SPIM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_SPIMASTER_PHYS,
|
||||
.end = RK2818_SPIMASTER_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
struct platform_device rk2818_device_spim = {
|
||||
.name = "rk2818_spim",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_spim),
|
||||
.resource = resources_spim,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_spi_platdata,
|
||||
},
|
||||
};
|
||||
|
||||
/* rk2818 fb resource */
|
||||
static struct resource rk2818_fb_resource[] = {
|
||||
[0] = {
|
||||
.start = RK2818_LCDC_PHYS,
|
||||
.end = RK2818_LCDC_PHYS + RK2818_LCDC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_NR_LCDC,
|
||||
.end = IRQ_NR_LCDC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
/*platform_device*/
|
||||
extern struct rk2818fb_info rk2818_fb_info;
|
||||
|
||||
struct platform_device rk2818_device_fb = {
|
||||
.name = "rk2818-fb",
|
||||
.id = 4,
|
||||
.num_resources = ARRAY_SIZE(rk2818_fb_resource),
|
||||
.resource = rk2818_fb_resource,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_fb_info,
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
* backlight
|
||||
* author :nzy zhongyw
|
||||
* data:2010-05-18
|
||||
***************************************************************/
|
||||
struct platform_device rk2818_device_backlight = {
|
||||
.name = "rk2818_backlight",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_bl_info,
|
||||
}
|
||||
};
|
||||
|
||||
/* RK2818 Camera : ddl@rock-chips.com */
|
||||
#ifdef CONFIG_VIDEO_RK2818
|
||||
|
||||
static struct resource rk2818_camera_resource[] = {
|
||||
[0] = {
|
||||
.start = RK2818_VIP_PHYS,
|
||||
.end = RK2818_VIP_PHYS + RK2818_VIP_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_NR_VIP,
|
||||
.end = IRQ_NR_VIP,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static u64 rockchip_device_camera_dmamask = 0xffffffffUL;
|
||||
|
||||
/*platform_device : */
|
||||
struct platform_device rk2818_device_camera = {
|
||||
.name = RK28_CAM_DRV_NAME,
|
||||
.id = RK28_CAM_PLATFORM_DEV_ID, /* This is used to put cameras on this interface */
|
||||
.num_resources = ARRAY_SIZE(rk2818_camera_resource),
|
||||
.resource = rk2818_camera_resource,
|
||||
.dev = {
|
||||
.dma_mask = &rockchip_device_camera_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL,
|
||||
.platform_data = &rk28_camera_platform_data,
|
||||
}
|
||||
};
|
||||
extern struct platform_device rk2818_soc_camera_pdrv;
|
||||
#endif
|
||||
|
||||
/*ADC*/
|
||||
static struct resource rk2818_adc_resource[] = {
|
||||
{
|
||||
.start = IRQ_NR_ADC,
|
||||
.end = IRQ_NR_ADC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_ADC_PHYS,
|
||||
.end = RK2818_ADC_PHYS + RK2818_ADC_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_adc = {
|
||||
.name = "rk2818-adc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rk2818_adc_resource),
|
||||
.resource = rk2818_adc_resource,
|
||||
};
|
||||
|
||||
|
||||
struct platform_device rk2818_device_adckey = {
|
||||
.name = "rk2818-adckey",
|
||||
.id = -1,
|
||||
.dev.parent = &rk2818_device_adc.dev,
|
||||
.dev.platform_data = &rk2818_adckey_platdata,
|
||||
};
|
||||
|
||||
/*
|
||||
*rk2818 i2s
|
||||
*/
|
||||
static struct resource resources_i2s[] = {
|
||||
{
|
||||
.start = IRQ_NR_I2S,
|
||||
.end = IRQ_NR_I2S,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_I2S_PHYS,
|
||||
.end = RK2818_I2S_PHYS + SZ_8K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
struct platform_device rk2818_device_i2s = {
|
||||
.name = "rk2818_i2s",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_i2s),
|
||||
.resource = resources_i2s,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_i2s_platdata,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_battery = {
|
||||
.name = "rk2818-battery",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_battery_platdata,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* rk2818 dsp device
|
||||
*/
|
||||
static struct resource resources_dsp[] = {
|
||||
[0] = {
|
||||
.start = RK2818_DSP_PHYS,
|
||||
.end = RK2818_DSP_PHYS + 0x5fffff,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_NR_PIUCMD,
|
||||
.end = IRQ_NR_PIUCMD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_NR_DSPSWI,
|
||||
.end = IRQ_NR_DSPSWI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
static u64 rk2818_device_dsp_dmamask = 0xffffffffUL;
|
||||
struct platform_device rk2818_device_dsp = {
|
||||
.name = "rk28-dsp",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(resources_dsp),
|
||||
.resource = resources_dsp,
|
||||
.dev = {
|
||||
.dma_mask = &rk2818_device_dsp_dmamask,
|
||||
.coherent_dma_mask = 0xffffffffUL
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ANDROID_PMEM)
|
||||
|
||||
static struct android_pmem_platform_data pmem_pdata = {
|
||||
.name = "pmem",
|
||||
.no_allocator = 1,
|
||||
.cached = 0,
|
||||
.start = 0x6f000000,
|
||||
.size = 0x1000000,
|
||||
};
|
||||
|
||||
static struct android_pmem_platform_data pmem_pdata_dsp = {
|
||||
.name = "pmem-dsp",
|
||||
.no_allocator = 0,
|
||||
.cached = 0,
|
||||
.start = 0x6db00000,
|
||||
.size = 0x1500000,
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_pmem = {
|
||||
.name = "android_pmem",
|
||||
.id = 0,
|
||||
.dev = { .platform_data = &pmem_pdata },
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_pmem_dsp = {
|
||||
.name = "android_pmem",
|
||||
.id = 1,
|
||||
.dev = { .platform_data = &pmem_pdata_dsp },
|
||||
};
|
||||
|
||||
#endif
|
||||
#if defined(CONFIG_MTD_NAND_RK2818)
|
||||
static struct resource nand_resources[] = {
|
||||
{
|
||||
.start = RK2818_NANDC_PHYS,
|
||||
.end = RK2818_NANDC_PHYS+RK2818_NANDC_SIZE -1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
struct platform_device rk2818_nand_device = {
|
||||
.name = "rk2818-nand",
|
||||
.id = -1,
|
||||
.resource = nand_resources,
|
||||
.num_resources= ARRAY_SIZE(nand_resources),
|
||||
.dev = {
|
||||
.platform_data= &rk2818_nand_data,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_INPUT_JOGBALL)
|
||||
struct platform_device rk2818_jogball_device = {
|
||||
.name = "rk2818_jogball",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk2818_jogball_platdata,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
/*DWC_OTG*/
|
||||
static struct resource dwc_otg_resource[] = {
|
||||
{
|
||||
.start = IRQ_NR_OTG,
|
||||
.end = IRQ_NR_OTG,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_USBOTG_PHYS,
|
||||
.end = RK2818_USBOTG_PHYS + RK2818_USBOTG_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_dwc_otg = {
|
||||
.name = "dwc_otg",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(dwc_otg_resource),
|
||||
.resource = dwc_otg_resource,
|
||||
};
|
||||
#ifdef CONFIG_RK2818_HOST11
|
||||
static struct resource rk2818_host11_resource[] = {
|
||||
{
|
||||
.start = IRQ_NR_USB_HOST,
|
||||
.end = IRQ_NR_USB_HOST,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK2818_USBHOST_PHYS,
|
||||
.end = RK2818_USBHOST_PHYS + RK2818_USBHOST_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
struct platform_device rk2818_device_host11 = {
|
||||
.name = "rk2818_host11",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rk2818_host11_resource),
|
||||
.resource = rk2818_host11_resource,
|
||||
};
|
||||
#endif
|
||||
static char *usb_functions_rockchip[] = {
|
||||
"usb_mass_storage",
|
||||
};
|
||||
|
||||
static char *usb_functions_rockchip_adb[] = {
|
||||
"usb_mass_storage",
|
||||
"adb",
|
||||
};
|
||||
|
||||
static char *usb_functions_rndis_rockchip[] = {
|
||||
"rndis",
|
||||
"usb_mass_storage",
|
||||
};
|
||||
|
||||
static char *usb_functions_rndis_rockchip_adb[] = {
|
||||
"rndis",
|
||||
"usb_mass_storage",
|
||||
"adb",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_ANDROID_DIAG
|
||||
static char *usb_functions_adb_diag[] = {
|
||||
"usb_mass_storage",
|
||||
"adb",
|
||||
"diag",
|
||||
};
|
||||
#endif
|
||||
|
||||
static char *usb_functions_all[] = {
|
||||
#ifdef CONFIG_USB_ANDROID_RNDIS
|
||||
"rndis",
|
||||
#endif
|
||||
"usb_mass_storage",
|
||||
#ifdef CONFIG_USB_ANDROID_ADB
|
||||
"adb",
|
||||
#endif
|
||||
#ifdef CONFIG_USB_ANDROID_ACM
|
||||
"acm",
|
||||
#endif
|
||||
#ifdef CONFIG_USB_ANDROID_DIAG
|
||||
"diag",
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct android_usb_product usb_products[] = {
|
||||
{
|
||||
.product_id = 0x2810,//0x0c02,//0x4e11,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_rockchip),
|
||||
.functions = usb_functions_rockchip,
|
||||
},
|
||||
{
|
||||
.product_id = 0x4e12,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_rockchip_adb),
|
||||
.functions = usb_functions_rockchip_adb,
|
||||
},
|
||||
{
|
||||
.product_id = 0x4e13,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_rndis_rockchip),
|
||||
.functions = usb_functions_rndis_rockchip,
|
||||
},
|
||||
{
|
||||
.product_id = 0x4e14,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_rndis_rockchip_adb),
|
||||
.functions = usb_functions_rndis_rockchip_adb,
|
||||
},
|
||||
#ifdef CONFIG_USB_ANDROID_DIAG
|
||||
{
|
||||
.product_id = 0x4e17,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_adb_diag),
|
||||
.functions = usb_functions_adb_diag,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct android_usb_platform_data android_usb_pdata = {
|
||||
.vendor_id = 0x2207,//0x0bb4,//0x18d1,
|
||||
.product_id = 0x2810,//0x4e11,
|
||||
.version = 0x0100,
|
||||
.product_name = "rk2818 sdk",
|
||||
.manufacturer_name = "RockChip",
|
||||
.num_products = ARRAY_SIZE(usb_products),
|
||||
.products = usb_products,
|
||||
.num_functions = ARRAY_SIZE(usb_functions_all),
|
||||
.functions = usb_functions_all,
|
||||
};
|
||||
|
||||
//static
|
||||
struct platform_device android_usb_device = {
|
||||
.name = "android_usb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &android_usb_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
//static
|
||||
struct platform_device usb_mass_storage_device = {
|
||||
.name = "usb_mass_storage",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &mass_storage_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
#if CONFIG_ANDROID_TIMED_GPIO
|
||||
struct platform_device rk28_device_vibrator ={
|
||||
.name = "timed-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rk28_vibrator_info,
|
||||
},
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/devices.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 __ARCH_ARM_MACH_RK2818_DEVICES_H
|
||||
#define __ARCH_ARM_MACH_RK2818_DEVICES_H
|
||||
|
||||
extern struct platform_device rk2818_device_uart0;
|
||||
extern struct platform_device rk2818_device_uart1;
|
||||
extern struct platform_device rk2818_device_uart2;
|
||||
extern struct platform_device rk2818_device_uart3;
|
||||
extern struct rk2818_serial_platform_data rk2818_serial0_platdata;
|
||||
extern struct rk2818_serial_platform_data rk2818_serial2_platdata;
|
||||
extern struct platform_device rk2818_device_spim;
|
||||
extern struct rk2818_spi_platform_data rk2818_spi_platdata;
|
||||
extern struct platform_device rk2818_device_i2c0;
|
||||
extern struct platform_device rk2818_device_i2c1;
|
||||
extern struct platform_device rk2818_device_i2c2;
|
||||
extern struct platform_device rk2818_device_i2c3;
|
||||
extern struct rk2818_i2c_platform_data default_i2c0_data;
|
||||
extern struct rk2818_i2c_platform_data default_i2c1_data;
|
||||
extern struct rk2818_i2c_spi_data default_i2c2_data;
|
||||
extern struct rk2818_i2c_spi_data default_i2c3_data;
|
||||
extern struct rk2818_bl_info rk2818_bl_info;
|
||||
extern struct rk2818_nand_platform_data rk2818_nand_data;
|
||||
|
||||
extern struct soc_camera_link rk2818_iclink; /* ddl@rock-chips.com : camera support */
|
||||
extern struct rk28camera_platform_data rk28_camera_platform_data;
|
||||
|
||||
extern struct platform_device rk2818_device_sdmmc0;
|
||||
extern struct platform_device rk2818_device_sdmmc1;
|
||||
extern struct rk2818_sdmmc_platform_data default_sdmmc0_data;
|
||||
extern struct rk2818_sdmmc_platform_data default_sdmmc1_data;
|
||||
extern struct platform_device rk2818_jogball_device;
|
||||
extern struct platform_device rk2818_device_i2s;
|
||||
extern struct rk2818_i2s_platform_data rk2818_i2s_platdata;
|
||||
extern struct platform_device rk2818_device_pmem;
|
||||
extern struct platform_device rk2818_device_pmem_dsp;
|
||||
extern struct platform_device rk2818_device_fb;
|
||||
extern struct platform_device rk2818_device_adc;
|
||||
extern struct platform_device rk2818_device_adckey;
|
||||
extern struct rk2818_adckey_platform_data rk2818_adckey_platdata;
|
||||
extern struct rk2818_jogball_paltform_data rk2818_jogball_platdata;
|
||||
extern struct platform_device rk2818_device_battery;
|
||||
extern struct rk2818_battery_platform_data rk2818_battery_platdata;
|
||||
extern struct platform_device rk2818_device_backlight;
|
||||
extern struct platform_device rk2818_device_camera; /* ddl@rock-chips.com : camera support */
|
||||
extern struct platform_device rk2818_soc_camera_pdrv;
|
||||
extern struct platform_device rk2818_device_dsp;
|
||||
extern struct platform_device rk2818_device_rfkill;
|
||||
extern struct platform_device rk2818_nand_device;
|
||||
extern struct platform_device rk2818_device_dwc_otg;
|
||||
extern struct platform_device rk2818_device_host11;
|
||||
extern struct platform_device android_usb_device;
|
||||
extern struct usb_mass_storage_platform_data mass_storage_pdata;
|
||||
extern struct platform_device usb_mass_storage_device;
|
||||
extern struct platform_device rk28_device_vibrator;
|
||||
extern struct timed_gpio_platform_data rk28_vibrator_info;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,768 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/dma.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/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
|
||||
static struct rk2818_dma rk2818_dma[MAX_DMA_CHANNELS];
|
||||
|
||||
static struct tasklet_struct rk2818_dma_tasklet;
|
||||
|
||||
const static char *rk28_dma_dev_id[] = {
|
||||
"sd_mmc",
|
||||
"uart_2",
|
||||
"uart_3",
|
||||
"sdio",
|
||||
"i2s",
|
||||
"spi_m",
|
||||
"spi_s",
|
||||
"uart_0",
|
||||
"uart_1",
|
||||
#ifdef test_dma
|
||||
"mobile_sdram"
|
||||
#endif
|
||||
};
|
||||
|
||||
const static struct rk28_dma_dev rk28_dev_info[] = {
|
||||
[RK28_DMA_SD_MMC] = {
|
||||
.hd_if_r = RK28_DMA_SD_MMC0,
|
||||
.hd_if_w = RK28_DMA_SD_MMC0,
|
||||
.dev_addr_r = RK2818_SDMMC0_PHYS + 0x100,
|
||||
.dev_addr_w = RK2818_SDMMC0_PHYS + 0x100,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
[RK28_DMA_URAT2] = {
|
||||
.hd_if_r = RK28_DMA_URAT2_RXD,
|
||||
.hd_if_w = RK28_DMA_URAT2_TXD,
|
||||
.dev_addr_r = RK2818_UART2_PHYS,
|
||||
.dev_addr_w = RK2818_UART2_PHYS,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
[RK28_DMA_URAT3] = {
|
||||
.hd_if_r = RK28_DMA_URAT3_RXD,
|
||||
.hd_if_w = RK28_DMA_URAT3_TXD,
|
||||
.dev_addr_r = RK2818_UART3_PHYS,
|
||||
.dev_addr_w = RK2818_UART3_PHYS,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
[RK28_DMA_SDIO] = {
|
||||
|
||||
.hd_if_r = RK28_DMA_SD_MMC1,
|
||||
.hd_if_w = RK28_DMA_SD_MMC1,
|
||||
.dev_addr_r = RK2818_SDMMC1_PHYS + 0x100,
|
||||
.dev_addr_w = RK2818_SDMMC1_PHYS + 0x100,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
[RK28_DMA_I2S] = {
|
||||
.hd_if_r = RK28_DMA_I2S_RXD,
|
||||
.hd_if_w = RK28_DMA_I2S_TXD,
|
||||
.dev_addr_r = RK2818_I2S_PHYS + 0x04,
|
||||
.dev_addr_w = RK2818_I2S_PHYS + 0x08,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
[RK28_DMA_SPI_M] = {
|
||||
.hd_if_r = RK28_DMA_SPI_M_RXD,
|
||||
.hd_if_w = RK28_DMA_SPI_M_TXD,
|
||||
.dev_addr_r = RK2818_SPIMASTER_PHYS + 0x60,
|
||||
.dev_addr_w = RK2818_SPIMASTER_PHYS + 0x60,
|
||||
.fifo_width = 8,
|
||||
},
|
||||
[RK28_DMA_SPI_S] = {
|
||||
.hd_if_r = RK28_DMA_SPI_S_RXD,
|
||||
.hd_if_w = RK28_DMA_SPI_S_TXD,
|
||||
.dev_addr_r = RK2818_SPISLAVE_PHYS + 0x60,
|
||||
.dev_addr_w = RK2818_SPISLAVE_PHYS + 0x60,
|
||||
.fifo_width = 8,
|
||||
},
|
||||
[RK28_DMA_URAT0] = {
|
||||
.hd_if_r = RK28_DMA_URAT0_RXD,
|
||||
.hd_if_w = RK28_DMA_URAT0_TXD,
|
||||
.dev_addr_r = RK2818_UART0_PHYS,
|
||||
.dev_addr_w = RK2818_UART0_PHYS,
|
||||
.fifo_width = 8,
|
||||
},
|
||||
[RK28_DMA_URAT1] = {
|
||||
.hd_if_r = RK28_DMA_URAT1_RXD,
|
||||
.hd_if_w = RK28_DMA_URAT1_TXD,
|
||||
.dev_addr_r = RK2818_UART1_PHYS,
|
||||
.dev_addr_w = RK2818_UART1_PHYS,
|
||||
.fifo_width = 8,
|
||||
},
|
||||
#ifdef test_dma
|
||||
[RK28_DMA_SDRAM] = {
|
||||
.hd_if_r = 0,
|
||||
.hd_if_w = 0,
|
||||
.dev_addr_r = BUF_READ_ARRR,
|
||||
.dev_addr_w = BUF_WRITE_ARRR,
|
||||
.fifo_width = 32,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* rk28_dma_ctl_for_write - set dma control register for writing mode
|
||||
*
|
||||
*/
|
||||
static inline unsigned int rk28_dma_ctl_for_write(unsigned int dma_ch, const struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
{
|
||||
#ifdef test_dma
|
||||
unsigned int dev_mode = B_CTLL_MEM2MEM_DMAC;
|
||||
unsigned int inc_mode = B_CTLL_DINC_INC;
|
||||
#else
|
||||
unsigned int dev_mode = B_CTLL_MEM2PER_DMAC;
|
||||
unsigned int inc_mode = B_CTLL_DINC_UNC;
|
||||
#endif
|
||||
unsigned int llp_mode = (dma_t->sg) ? (B_CTLL_LLP_DST_EN | B_CTLL_LLP_SRC_EN) : 0;
|
||||
unsigned int int_mode = (!dma_t->sg) ? B_CTLL_INT_EN : 0;
|
||||
|
||||
unsigned int ctll = B_CTLL_SRC_TR_WIDTH_32 | B_CTLL_DST_TR_WIDTH(dev_info->fifo_width >> 4) |
|
||||
B_CTLL_SINC_INC | inc_mode |
|
||||
B_CTLL_DMS_ARMD | B_CTLL_SMS_EXP | dev_mode |
|
||||
B_CTLL_SRC_MSIZE_4 | B_CTLL_DST_MSIZE_4 |
|
||||
llp_mode | int_mode;
|
||||
|
||||
return ctll;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_ctl_for_read - set dma control register for reading mode
|
||||
*
|
||||
*/
|
||||
static inline unsigned int rk28_dma_ctl_for_read(unsigned int dma_ch, const struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
{
|
||||
#ifdef test_dma
|
||||
unsigned int dev_mode = B_CTLL_MEM2MEM_DMAC;
|
||||
unsigned int inc_mode = B_CTLL_SINC_INC;
|
||||
#else
|
||||
unsigned int dev_mode = B_CTLL_PER2MEM_DMAC;
|
||||
unsigned int inc_mode = B_CTLL_SINC_UNC;
|
||||
#endif
|
||||
unsigned int llp_mode = (dma_t->sg) ? (B_CTLL_LLP_DST_EN | B_CTLL_LLP_SRC_EN) : 0;
|
||||
unsigned int int_mode = (!dma_t->sg) ? B_CTLL_INT_EN : 0;
|
||||
|
||||
unsigned int ctll = B_CTLL_SRC_TR_WIDTH(dev_info->fifo_width>> 4) | B_CTLL_DST_TR_WIDTH_32 |
|
||||
inc_mode | B_CTLL_DINC_INC |
|
||||
B_CTLL_DMS_EXP | B_CTLL_SMS_ARMD | dev_mode |
|
||||
B_CTLL_SRC_MSIZE_4 | B_CTLL_DST_MSIZE_4 |
|
||||
llp_mode | int_mode;
|
||||
|
||||
return ctll;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_set_reg - set dma registers
|
||||
*
|
||||
*/
|
||||
static inline void rk28_dma_set_reg(unsigned int dma_ch, struct rk28_dma_llp *reg, unsigned int dma_if)
|
||||
{
|
||||
write_dma_reg(DWDMA_SAR(dma_ch), reg->sar);
|
||||
write_dma_reg(DWDMA_DAR(dma_ch), reg->dar);
|
||||
write_dma_reg(DWDMA_LLP(dma_ch), (unsigned int)(reg->llp));
|
||||
write_dma_reg(DWDMA_CTLL(dma_ch), reg->ctll);
|
||||
write_dma_reg(DWDMA_CTLH(dma_ch), reg->size);
|
||||
write_dma_reg(DWDMA_CFGL(dma_ch), B_CFGL_CH_PRIOR(7) |
|
||||
B_CFGL_H_SEL_DST | B_CFGL_H_SEL_SRC |
|
||||
B_CFGL_DST_HS_POL_H | B_CFGL_SRC_HS_POL_H);
|
||||
write_dma_reg(DWDMA_CFGH(dma_ch), B_CFGH_SRC_PER(dma_if & 0xf) |
|
||||
B_CFGH_DST_PER(dma_if & 0xf) |
|
||||
B_CFGH_PROTCTL);
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_setup_reg - set linked list content
|
||||
*
|
||||
*/
|
||||
static inline void rk28_dma_set_llp(unsigned int sar,
|
||||
unsigned int dar,
|
||||
struct rk28_dma_llp *curllp,
|
||||
struct rk28_dma_llp *nexllp,
|
||||
unsigned int ctll,
|
||||
unsigned int size)
|
||||
{
|
||||
curllp->sar = sar; //pa
|
||||
curllp->dar = dar; //pa
|
||||
curllp->ctll = ctll;
|
||||
curllp->llp = nexllp; //physical next linked list pointer
|
||||
curllp->size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_end_of_llp - set linked list end
|
||||
*
|
||||
*/
|
||||
static inline void rk28_dma_end_of_llp(struct rk28_dma_llp *curllp)
|
||||
{
|
||||
curllp->llp = 0;
|
||||
curllp->ctll &= (~B_CTLL_LLP_DST_EN) & (~B_CTLL_LLP_SRC_EN);
|
||||
curllp->ctll |= B_CTLL_INT_EN;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_setup_sg - setup rk28 DMA channel SG list to/from device transfer
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
* @dma_t: pointer to the dma struct
|
||||
*
|
||||
* The function sets up DMA channel state and registers to be ready for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is set up
|
||||
* according to the parameters.
|
||||
*
|
||||
* enbale dma should be called after setup sg
|
||||
*
|
||||
* Return value: negative if incorrect parameters
|
||||
* Zero indicates success.
|
||||
*/
|
||||
static void rk28_dma_write_to_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
unsigned int i, ctll_r, dev_addr_w;
|
||||
struct rk2818_dma *rk28dma;
|
||||
struct rk28_dma_llp * rk28llp_vir;
|
||||
struct rk28_dma_llp * rk28llp_phy;
|
||||
struct rk28_dma_llp rk28dma_reg;
|
||||
struct scatterlist *sg;
|
||||
unsigned int wid_off, bk_count, bk_res, sgcount_tmp, bk_length;
|
||||
|
||||
rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
dev_addr_w = rk28dma->dev_info->dev_addr_w;
|
||||
ctll_r = rk28_dma_ctl_for_read(dma_ch, rk28dma->dev_info, dma_t);
|
||||
wid_off = rk28dma->dev_info->fifo_width >> 4;
|
||||
|
||||
if (dma_t->sg) {
|
||||
rk28llp_vir = rk28dma->dma_llp_vir;
|
||||
rk28llp_phy = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
sg = dma_t->sg;
|
||||
#if 1
|
||||
bk_length = RK28_DMA_CH0A1_MAX_LEN << wid_off;
|
||||
|
||||
for (sgcount_tmp = 0; sgcount_tmp < dma_t->sgcount; sgcount_tmp++, sg++) {
|
||||
bk_count = (sg->length >> wid_off) / RK28_DMA_CH0A1_MAX_LEN;
|
||||
bk_res = (sg->length >> wid_off) % RK28_DMA_CH0A1_MAX_LEN;
|
||||
for (i = 0; i < bk_count; i++) {
|
||||
rk28_dma_set_llp(dev_addr_w,
|
||||
sg->dma_address + i * bk_length,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_r,
|
||||
RK28_DMA_CH0A1_MAX_LEN);
|
||||
}
|
||||
if (bk_res > 0) {
|
||||
rk28_dma_set_llp(dev_addr_w,
|
||||
sg->dma_address + bk_count * bk_length,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_r,
|
||||
bk_res);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < dma_t->sgcount; i++, sg++) {
|
||||
rk28_dma_set_llp(dev_addr_w, sg->dma_address, rk28llp_vir++, ++rk28llp_phy, ctll_r, (sg->length >> wid_off));
|
||||
}
|
||||
#endif
|
||||
rk28_dma_end_of_llp(rk28llp_vir - 1);
|
||||
rk28dma_reg.llp = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
} else { /*single transfer*/
|
||||
if (dma_t->buf.length > RK28_DMA_CH2_MAX_LEN) {
|
||||
rk28dma->length = RK28_DMA_CH2_MAX_LEN;
|
||||
rk28dma->residue = dma_t->buf.length - RK28_DMA_CH2_MAX_LEN;
|
||||
} else {
|
||||
rk28dma->length = dma_t->buf.length;
|
||||
rk28dma->residue = 0;
|
||||
}
|
||||
rk28dma_reg.llp = NULL;
|
||||
}
|
||||
rk28dma_reg.sar = dev_addr_w;
|
||||
rk28dma_reg.dar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.ctll = ctll_r;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
rk28_dma_set_reg(dma_ch, &rk28dma_reg, rk28dma->dev_info->hd_if_r);
|
||||
/*
|
||||
printk(KERN_INFO "dma_write_to_sg: ch = %d, sar = 0x%x, dar = 0x%x, ctll = 0x%x, llp = 0x%x, size = %d, \n",
|
||||
dma_ch, rk28dma_reg.sar, rk28dma_reg.dar, rk28dma_reg.ctll, rk28dma_reg.llp, rk28dma_reg.size);
|
||||
rk28llp_vir = rk28dma->dma_llp_vir;
|
||||
for (i=0; i<dma_t->sgcount; i++, rk28llp_vir++)
|
||||
printk(KERN_INFO "dma_write_to_sg: ch = %d, sar = 0x%x, dar = 0x%x, ctll = 0x%x, llp = 0x%x, size = %d, \n",
|
||||
dma_ch, rk28llp_vir->sar, rk28llp_vir->dar, rk28llp_vir->ctll, rk28llp_vir->llp, rk28llp_vir->size);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_setup_sg - setup rk28 DMA channel SG list to/from device transfer
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
* @dma_t: pointer to the dma struct
|
||||
*
|
||||
* The function sets up DMA channel state and registers to be ready for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is set up
|
||||
* according to the parameters.
|
||||
*
|
||||
* enbale dma should be called after setup sg
|
||||
*
|
||||
* Return value: negative if incorrect parameters
|
||||
* Zero indicates success.
|
||||
*/
|
||||
static void rk28_dma_read_from_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
unsigned int i, ctll_w, dev_addr_r;
|
||||
struct rk2818_dma *rk28dma;
|
||||
struct rk28_dma_llp * rk28llp_vir;
|
||||
struct rk28_dma_llp * rk28llp_phy;
|
||||
struct rk28_dma_llp rk28dma_reg;
|
||||
struct scatterlist *sg;
|
||||
unsigned int wid_off, bk_count, bk_res, sgcount_tmp, bk_length;
|
||||
|
||||
rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
/*setup linked list table end*/
|
||||
dev_addr_r = rk28dma->dev_info->dev_addr_r;
|
||||
ctll_w = rk28_dma_ctl_for_write(dma_ch, rk28dma->dev_info, dma_t);
|
||||
wid_off = rk28dma->dev_info->fifo_width >> 4;
|
||||
|
||||
if (dma_t->sg) {
|
||||
rk28llp_vir = rk28dma->dma_llp_vir;
|
||||
rk28llp_phy = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
sg = dma_t->sg;
|
||||
#if 1
|
||||
bk_length = RK28_DMA_CH0A1_MAX_LEN << wid_off;
|
||||
|
||||
for (sgcount_tmp = 0; sgcount_tmp < dma_t->sgcount; sgcount_tmp++, sg++) {
|
||||
bk_count = (sg->length >> wid_off) / RK28_DMA_CH0A1_MAX_LEN;
|
||||
bk_res = (sg->length >> wid_off) % RK28_DMA_CH0A1_MAX_LEN;
|
||||
for (i = 0; i < bk_count; i++) {
|
||||
rk28_dma_set_llp(sg->dma_address + i * bk_length,
|
||||
dev_addr_r,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_w,
|
||||
RK28_DMA_CH0A1_MAX_LEN);
|
||||
}
|
||||
if (bk_res > 0) {
|
||||
rk28_dma_set_llp(sg->dma_address + bk_count * bk_length,
|
||||
dev_addr_r,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_w,
|
||||
bk_res);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < dma_t->sgcount; i++, sg++) {
|
||||
rk28_dma_set_llp(sg->dma_address, dev_addr_r, rk28llp_vir++, ++rk28llp_phy, ctll_w, (sg->length >> wid_off));
|
||||
}
|
||||
#endif
|
||||
rk28_dma_end_of_llp(rk28llp_vir - 1);
|
||||
rk28dma_reg.llp = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
} else { /*single transfer*/
|
||||
if (dma_t->buf.length > RK28_DMA_CH2_MAX_LEN) {
|
||||
rk28dma->length = RK28_DMA_CH2_MAX_LEN;
|
||||
rk28dma->residue = dma_t->buf.length - RK28_DMA_CH2_MAX_LEN;
|
||||
} else {
|
||||
rk28dma->length = dma_t->buf.length;
|
||||
rk28dma->residue = 0;
|
||||
}
|
||||
rk28dma_reg.llp = NULL;
|
||||
}
|
||||
rk28dma_reg.sar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.dar = dev_addr_r;
|
||||
rk28dma_reg.ctll = ctll_w;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
rk28_dma_set_reg(dma_ch, &rk28dma_reg, rk28dma->dev_info->hd_if_w);
|
||||
|
||||
//printk(KERN_INFO "read_from_sg: ch = %d, sar = 0x%x, dar = 0x%x, ctll = 0x%x, llp = 0x%x, size = %d, \n",
|
||||
// dma_ch, rk28dma_reg.sar, rk28dma_reg.dar, rk28dma_reg.ctll, rk28dma_reg.llp, rk28dma_reg.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_enable - function to start rk28 DMA channel operation
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
*
|
||||
* The channel has to be allocated by driver through rk28_dma_request()
|
||||
* The transfer parameters has to be set to the channel registers through
|
||||
* call of the rk28_dma_setup_sg() function.
|
||||
|
||||
*/
|
||||
static int rk28_dma_enable(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
//printk(KERN_INFO "enter dwdma_enable\n");
|
||||
struct rk2818_dma *rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
spin_lock(&rk28dma->lock);
|
||||
|
||||
if (dma_t->sg) {
|
||||
if (dma_ch >= RK28_DMA_CH2) {
|
||||
printk(KERN_ERR "dma_enable: channel %d does not support sg transfer mode\n", dma_ch);
|
||||
goto bad_enable;
|
||||
}
|
||||
if (dma_t->sgcount > RK28_MAX_DMA_LLPS) {
|
||||
printk(KERN_ERR "dma_enable: count %d are more than supported number %d\n", dma_t->sgcount, RK28_MAX_DMA_LLPS);
|
||||
goto bad_enable;
|
||||
}
|
||||
} else { /*single transfer*/
|
||||
if ((!dma_t->addr) || (dma_t->count == 0)) {
|
||||
printk(KERN_ERR "dma_enable: channel %d does not have leagal address or count\n", dma_ch);
|
||||
goto bad_enable;
|
||||
}
|
||||
dma_t->buf.dma_address = (dma_addr_t)dma_t->addr;
|
||||
dma_t->buf.length = dma_t->count;
|
||||
}
|
||||
//printk(KERN_INFO "dma_enable: addr = 0x%x\n", (dma_addr_t)dma_t->addr);
|
||||
|
||||
if (dma_t->dma_mode == DMA_MODE_READ) {
|
||||
rk28_dma_write_to_sg(dma_ch, dma_t);
|
||||
} else {
|
||||
rk28_dma_read_from_sg(dma_ch, dma_t);
|
||||
}
|
||||
|
||||
dma_t->invalid = 0;
|
||||
|
||||
ENABLE_DWDMA(dma_ch);
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
//printk(KERN_INFO "exit dwdma_enable\n");
|
||||
|
||||
return 0;
|
||||
|
||||
bad_enable:
|
||||
dma_t->active = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_disable - stop, finish rk28 DMA channel operatin
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
*
|
||||
* dma transfer will be force into suspend state whether dma have completed current transfer
|
||||
*/
|
||||
static int rk28_dma_disable(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
struct rk2818_dma *rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
spin_lock(&rk28dma->lock);
|
||||
|
||||
DISABLE_DWDMA(dma_ch);
|
||||
while (GET_DWDMA_STATUS(dma_ch))
|
||||
cpu_relax();
|
||||
|
||||
rk28dma->tasklet_flag = 0;
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_request - request/allocate specified channel number
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
* requesting dma channel if device need dma transfer
|
||||
* but just called one time in one event, and channle should be
|
||||
* free after this event
|
||||
*/
|
||||
static int rk28_dma_request(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
int i;
|
||||
struct rk2818_dma *rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
//printk(KERN_INFO "enter dwdma request\n");
|
||||
|
||||
spin_lock(&rk28dma->lock);
|
||||
|
||||
/*compare to make sure whether device that request dma is legal*/
|
||||
for (i = 0; i < RK28_DMA_DEV_NUM_MAX; i++) {
|
||||
if (!strcmp(dma_t->device_id, rk28_dma_dev_id[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= RK28_DMA_DEV_NUM_MAX) {
|
||||
printk(KERN_ERR "dma_request: called for non-existed dev %s\n", dma_t->device_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*channel 0 and 1 support llp, but others does not*/
|
||||
if (dma_ch < RK28_DMA_CH2) {
|
||||
rk28dma->dma_llp_vir = (struct rk28_dma_llp *)dma_alloc_coherent(NULL, RK28_MAX_DMA_LLPS*sizeof(struct rk28_dma_llp), &rk28dma->dma_llp_phy, GFP_ATOMIC);
|
||||
if (!rk28dma->dma_llp_vir) {
|
||||
printk(KERN_ERR "dma_request: no dma space can be allocated for llp by virtual channel %d\n", dma_ch);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
rk28dma->dma_llp_vir = NULL;
|
||||
rk28dma->dma_llp_phy = 0;
|
||||
}
|
||||
|
||||
rk28dma->dev_info = &rk28_dev_info[i];
|
||||
|
||||
/* clear interrupt */
|
||||
CLR_DWDMA_INTR(dma_ch);
|
||||
|
||||
UN_MASK_DWDMA_TRF_INTR(dma_ch);
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
|
||||
//printk(KERN_INFO "exit dwdma request device %d\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_free - release previously acquired channel
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
*
|
||||
* request dam should be prior free dma
|
||||
*/
|
||||
static int rk28_dma_free(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
struct rk2818_dma *rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
spin_lock(&rk28dma->lock);
|
||||
|
||||
/* clear interrupt */
|
||||
CLR_DWDMA_INTR(dma_ch);
|
||||
|
||||
MASK_DWDMA_TRF_INTR(dma_ch);
|
||||
|
||||
if (dma_ch < RK28_DMA_CH2) {
|
||||
if (!rk28dma->dma_llp_vir) {
|
||||
printk(KERN_ERR "dma_free: no dma space can be free by virtual channel %d\n", dma_ch);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dma_free_coherent(NULL, RK28_MAX_DMA_LLPS*sizeof(struct rk28_dma_llp), (void *)rk28dma->dma_llp_vir, rk28dma->dma_llp_phy);
|
||||
}
|
||||
|
||||
rk28dma->dma_t.irqHandle = NULL;
|
||||
rk28dma->dma_t.data = NULL;
|
||||
rk28dma->dma_t.sg = NULL;
|
||||
rk28dma->dma_t.addr = NULL;
|
||||
rk28dma->dma_t.count = 0;
|
||||
rk28dma->dma_llp_vir = NULL;
|
||||
rk28dma->dma_llp_phy = 0;
|
||||
rk28dma->residue = 0;
|
||||
rk28dma->length = 0;
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_next - set dma regiters and start of next transfer if using channel 2
|
||||
* @dma_ch: rk28 device ID which using DMA, device id list is showed in dma.h
|
||||
*
|
||||
* just be applied to channel 2
|
||||
*/
|
||||
static int rk28_dma_next(unsigned int dma_ch)
|
||||
{
|
||||
struct rk2818_dma *rk28dma = &rk2818_dma[dma_ch];
|
||||
unsigned int nextlength;
|
||||
unsigned int nextaddr;
|
||||
unsigned int width_off = rk28dma->dev_info->fifo_width >> 4;
|
||||
unsigned int dma_if;
|
||||
struct rk28_dma_llp rk28dma_reg;
|
||||
|
||||
/*go on transfering if there are buffer of other blocks leave*/
|
||||
if (rk28dma->residue > 0) {
|
||||
nextaddr = rk28dma->dma_t.buf.dma_address + (rk28dma->length << width_off);
|
||||
if (rk28dma->residue > RK28_DMA_CH2_MAX_LEN) {
|
||||
nextlength = RK28_DMA_CH2_MAX_LEN;
|
||||
rk28dma->residue -= RK28_DMA_CH2_MAX_LEN;
|
||||
} else {
|
||||
nextlength = rk28dma->residue;
|
||||
rk28dma->residue = 0;
|
||||
}
|
||||
rk28dma->length = nextlength;
|
||||
|
||||
if (rk28dma->dma_t.dma_mode == DMA_MODE_READ) {
|
||||
rk28dma_reg.sar = rk28dma->dev_info->dev_addr_r;
|
||||
rk28dma_reg.dar = nextaddr;
|
||||
rk28dma_reg.ctll = rk28_dma_ctl_for_read(dma_ch, rk28dma->dev_info, &rk28dma->dma_t);
|
||||
dma_if = rk28dma->dev_info->hd_if_r;
|
||||
} else {
|
||||
rk28dma_reg.sar = nextaddr;
|
||||
rk28dma_reg.dar = rk28dma->dev_info->dev_addr_w;
|
||||
rk28dma_reg.ctll = rk28_dma_ctl_for_write(dma_ch, rk28dma->dev_info, &rk28dma->dma_t);
|
||||
dma_if = rk28dma->dev_info->hd_if_w;
|
||||
}
|
||||
rk28dma_reg.llp = NULL;
|
||||
rk28dma_reg.size = nextlength;
|
||||
|
||||
rk28_dma_set_reg(dma_ch, &rk28dma_reg, dma_if);
|
||||
|
||||
ENABLE_DWDMA(dma_ch);
|
||||
|
||||
return nextlength;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_tasklet - irq callback function
|
||||
*
|
||||
*/
|
||||
static void rk28_dma_tasklet(unsigned long data)
|
||||
{
|
||||
int i;
|
||||
struct rk2818_dma *rk28dma;
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
||||
rk28dma = &rk2818_dma[i];
|
||||
if ((rk28dma->tasklet_flag) && (rk28dma->dma_t.irq_mode == DMA_IRQ_DELAY_MODE)) {
|
||||
rk28dma->dma_t.active = 0;
|
||||
rk28dma->tasklet_flag = 0;
|
||||
if (rk28dma->dma_t.irqHandle)
|
||||
rk28dma->dma_t.irqHandle(i, rk28dma->dma_t.data);
|
||||
UN_MASK_DWDMA_TRF_INTR(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_irq_handler - irq callback function
|
||||
*
|
||||
*/
|
||||
static irqreturn_t rk28_dma_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
int i, raw_status;
|
||||
struct rk2818_dma *rk28dma;
|
||||
|
||||
raw_status = read_dma_reg(DWDMA_RawTfr);
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
||||
if (raw_status & (1 << i)) {
|
||||
CLR_DWDMA_INTR(i);
|
||||
|
||||
rk28dma = &rk2818_dma[i];
|
||||
|
||||
if ((!rk28dma->dma_t.sg) && (rk28_dma_next(i))) {
|
||||
//printk(KERN_WARNING "dma_irq: don't finish for channel %d\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rk28dma->dma_t.irqHandle) {
|
||||
if (rk28dma->dma_t.irq_mode != DMA_IRQ_DELAY_MODE) {
|
||||
/* already have completed transfer */
|
||||
rk28dma->dma_t.active = 0;
|
||||
rk28dma->dma_t.irqHandle(i, rk28dma->dma_t.data);
|
||||
} else {
|
||||
MASK_DWDMA_TRF_INTR(i);
|
||||
rk28dma->tasklet_flag = 1;
|
||||
tasklet_schedule(&rk2818_dma_tasklet);
|
||||
//printk(KERN_WARNING "dma_irq: no IRQ handler for DMA channel %d\n", i);
|
||||
}
|
||||
} else {
|
||||
/* already have completed transfer */
|
||||
rk28dma->dma_t.active = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//tasklet_schedule(&rk2818_dma_tasklet);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void rk28_dma_position(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
dma_t->src_pos = read_dma_reg(DWDMA_SAR(dma_ch));
|
||||
dma_t->dst_pos = read_dma_reg(DWDMA_DAR(dma_ch));
|
||||
}
|
||||
|
||||
static struct dma_ops rk2818_dma_ops = {
|
||||
.request = rk28_dma_request,
|
||||
.free = rk28_dma_free,
|
||||
.enable = rk28_dma_enable,
|
||||
.disable = rk28_dma_disable,
|
||||
.position = rk28_dma_position,
|
||||
};
|
||||
|
||||
/**
|
||||
* rk28_dma_init - dma information initialize
|
||||
*
|
||||
*/
|
||||
static int __init rk28_dma_init(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
printk(KERN_INFO "enter dwdma init\n");
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
||||
rk2818_dma[i].dma_t.irqHandle = NULL;
|
||||
rk2818_dma[i].dma_t.data = NULL;
|
||||
rk2818_dma[i].dma_t.sg = NULL;
|
||||
rk2818_dma[i].dma_t.addr = NULL;
|
||||
rk2818_dma[i].dma_t.count = 0;
|
||||
rk2818_dma[i].dma_t.d_ops = &rk2818_dma_ops;
|
||||
dma_add(i, &rk2818_dma[i].dma_t);
|
||||
|
||||
rk2818_dma[i].dma_llp_vir = NULL;
|
||||
rk2818_dma[i].dma_llp_phy = 0;
|
||||
rk2818_dma[i].residue = 0;
|
||||
rk2818_dma[i].length = 0;
|
||||
rk2818_dma[i].tasklet_flag = 0;
|
||||
spin_lock_init(&rk2818_dma[i].lock);
|
||||
}
|
||||
|
||||
/* clear all interrupts */
|
||||
write_dma_reg(DWDMA_ClearBlock, 0x3f3f);
|
||||
write_dma_reg(DWDMA_ClearTfr, 0x3f3f);
|
||||
write_dma_reg(DWDMA_ClearSrcTran, 0x3f3f);
|
||||
write_dma_reg(DWDMA_ClearDstTran, 0x3f3f);
|
||||
write_dma_reg(DWDMA_ClearErr, 0x3f3f);
|
||||
|
||||
/*mask all interrupts*/
|
||||
write_dma_reg(DWDMA_MaskBlock, 0x3f00);
|
||||
write_dma_reg(DWDMA_MaskSrcTran, 0x3f00);
|
||||
write_dma_reg(DWDMA_MaskDstTran, 0x3f00);
|
||||
write_dma_reg(DWDMA_MaskErr, 0x3f00);
|
||||
|
||||
/*unmask transfer completion interrupt*/
|
||||
//UN_MASK_DWDMA_ALL_TRF_INTR;
|
||||
MASK_DWDMA_ALL_TRF_INTR;
|
||||
|
||||
ret = request_irq(RK28_DMA_IRQ_NUM, rk28_dma_irq_handler, 0, "DMA", NULL);
|
||||
if (ret < 0) {
|
||||
printk(KERN_CRIT "Can't register IRQ for DMA\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
tasklet_init(&rk2818_dma_tasklet, rk28_dma_tasklet, 0);
|
||||
|
||||
/* enable DMA module */
|
||||
write_dma_reg(DWDMA_DmaCfgReg, 0x01);
|
||||
|
||||
printk(KERN_INFO "exit dwdma init\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(rk28_dma_init);
|
||||
|
||||
MODULE_AUTHOR("nzy@rock-chips.com");
|
||||
MODULE_DESCRIPTION("Driver for rk2818 dma device");
|
||||
MODULE_LICENSE("GPL");
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,57 +0,0 @@
|
|||
/* arch/arm/mach-rk28418/include/mach/adc.h
|
||||
*
|
||||
* Copyright (c) 2010 luowei <lw@rock-chips.com>
|
||||
*
|
||||
* This program is free software; yosu can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_ADC_H
|
||||
#define __ASM_ARCH_ADC_H
|
||||
|
||||
#define RK28_ADCREG(x) (x)
|
||||
#define RK28_ADCDAT RK28_ADCREG(0x00)
|
||||
#define RK28_ADCSTAS RK28_ADCREG(0x04)
|
||||
#define RK28_ADCCON RK28_ADCREG(0x08)
|
||||
|
||||
//ADC_DATA
|
||||
#define RK28_ADC_DATA_MASK (0x3ff)
|
||||
|
||||
//ADC_STAS
|
||||
#define RK28_ADC_STAS_STOP (0)
|
||||
|
||||
//ADC_CTRL
|
||||
#define RK28_ADC_INT_END (1<<6)
|
||||
#define RK28_ADC_INT_CLEAR (~(1<<6))
|
||||
#define RK28_ADC_INT_ENABLE (1<<5)
|
||||
#define RK28_ADC_INT_DISABLE (~(1<<5))
|
||||
#define RK28_ADC_CONV_START (1<<4)
|
||||
#define RK28_ADC_CONV_STOP (~(1<<4))
|
||||
#define RK28_ADC_POWER_UP (1<<3)
|
||||
#define RK28_ADC_POWER_DOWN (~(1<<3))
|
||||
#define RK28_ADC_SEL_CH(x) ((x)&0x03)
|
||||
#define RK28_ADC_MASK_CH (~(0x03))
|
||||
|
||||
struct rk28_adc_client;
|
||||
|
||||
extern volatile int gAdcValue[4]; //start adc in rk2818_adckey.c
|
||||
extern int rk28_adc_start(struct rk28_adc_client *client,
|
||||
unsigned int channel, unsigned int nr_samples);
|
||||
|
||||
extern int rk28_adc_read(struct rk28_adc_client *client, unsigned int ch);
|
||||
|
||||
extern struct rk28_adc_client *
|
||||
rk28_adc_register(struct platform_device *pdev,
|
||||
void (*select)(struct rk28_adc_client *client,
|
||||
unsigned selected),
|
||||
void (*conv)(struct rk28_adc_client *client,
|
||||
unsigned d0, unsigned d1,
|
||||
unsigned *samples_left),
|
||||
unsigned int is_ts);
|
||||
|
||||
extern void rk28_adc_release(struct rk28_adc_client *client);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/board.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 __ASM_ARCH_RK2818_BOARD_H
|
||||
#define __ASM_ARCH_RK2818_BOARD_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
|
||||
|
||||
#define INVALID_GPIO -1
|
||||
|
||||
|
||||
struct rk2818_io_cfg {
|
||||
int (*io_init)(void *);
|
||||
int (*io_deinit)(void *);
|
||||
};
|
||||
|
||||
/* platform device data structures */
|
||||
struct platform_device;
|
||||
struct i2c_client;
|
||||
struct rk2818_sdmmc_platform_data {
|
||||
unsigned int host_caps;
|
||||
unsigned int host_ocr_avail;
|
||||
unsigned int use_dma:1;
|
||||
unsigned int no_detect:1;
|
||||
char dma_name[8];
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
int (*status)(struct device *);
|
||||
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
|
||||
};
|
||||
|
||||
struct wifi_platform_data {
|
||||
int (*set_power)(int val);
|
||||
int (*set_reset)(int val);
|
||||
int (*set_carddetect)(int val);
|
||||
void *(*mem_prealloc)(int section, unsigned long size);
|
||||
};
|
||||
|
||||
struct wifi_power_gpio_control_data {
|
||||
unsigned int use_gpio; /* If uses GPIO to control wifi power supply. 0 - no, 1 - yes. */
|
||||
unsigned int gpio_iomux; /* If the GPIO is iomux. 0 - no, 1 - yes. */
|
||||
char *iomux_name; /* IOMUX name */
|
||||
unsigned int iomux_value; /* IOMUX value - which function is choosen. */
|
||||
unsigned int gpio_id; /* GPIO number */
|
||||
unsigned int sensi_level; /* GPIO sensitive level. */
|
||||
};
|
||||
|
||||
struct rk2818_i2c_spi_data {
|
||||
int bus_num;
|
||||
unsigned int flags;
|
||||
unsigned int slave_addr;
|
||||
unsigned long scl_rate;
|
||||
};
|
||||
struct rk2818_i2c_platform_data {
|
||||
int bus_num;
|
||||
unsigned int flags;
|
||||
unsigned int slave_addr;
|
||||
unsigned long scl_rate;
|
||||
#define I2C_MODE_IRQ 0
|
||||
#define I2C_MODE_POLL 1
|
||||
unsigned int mode:1;
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
struct rk2818lcd_info{
|
||||
u32 lcd_id;
|
||||
u32 txd_pin;
|
||||
u32 clk_pin;
|
||||
u32 cs_pin;
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
struct rk2818_fb_setting_info{
|
||||
u8 data_num;
|
||||
u8 vsync_en;
|
||||
u8 den_en;
|
||||
u8 mcu_fmk_en;
|
||||
u8 disp_on_en;
|
||||
u8 standby_en;
|
||||
};
|
||||
|
||||
struct rk2818fb_info{
|
||||
u32 fb_id;
|
||||
u32 disp_on_pin;
|
||||
u8 disp_on_value;
|
||||
u32 standby_pin;
|
||||
u8 standby_value;
|
||||
u32 mcu_fmk_pin;
|
||||
struct rk2818lcd_info *lcd_info;
|
||||
int (*io_init)(struct rk2818_fb_setting_info *fb_setting);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
struct rk2818_bl_info{
|
||||
u32 pwm_id;
|
||||
u32 bl_ref;
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
struct timer_list timer;
|
||||
struct notifier_block freq_transition;
|
||||
};
|
||||
|
||||
struct rk2818_gpio_expander_info {
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
struct pca9554_platform_data {
|
||||
/* the first extern gpio number in all of gpio groups */
|
||||
unsigned int gpio_base;
|
||||
unsigned int gpio_pin_num;
|
||||
/* the first gpio irq number in all of irq source */
|
||||
|
||||
unsigned int gpio_irq_start;
|
||||
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;
|
||||
int settinginfolen;
|
||||
void *context; /* param to setup/teardown */
|
||||
|
||||
int (*setup)(struct i2c_client *client,unsigned gpio, unsigned ngpio,void *context);
|
||||
int (*teardown)(struct i2c_client *client,unsigned gpio, unsigned ngpio,void *context);
|
||||
char **names;
|
||||
};
|
||||
|
||||
struct tca6424_platform_data {
|
||||
/* the first extern gpio number in all of gpio groups */
|
||||
unsigned int gpio_base;
|
||||
unsigned int gpio_pin_num;
|
||||
/* the first gpio irq number in all of irq source */
|
||||
|
||||
unsigned int gpio_irq_start;
|
||||
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;
|
||||
unsigned int rk_irq_gpio_pull_up_down;
|
||||
|
||||
/* initial polarity inversion setting */
|
||||
uint16_t invert;
|
||||
struct rk2818_gpio_expander_info *settinginfo;
|
||||
int settinginfolen;
|
||||
void *context; /* param to setup/teardown */
|
||||
|
||||
int (*setup)(struct i2c_client *client,unsigned gpio, unsigned ngpio,void *context);
|
||||
int (*teardown)(struct i2c_client *client,unsigned gpio, unsigned ngpio,void *context);
|
||||
char **names;
|
||||
void (*reseti2cpin)(void);
|
||||
};
|
||||
|
||||
/*battery*/
|
||||
struct rk2818_battery_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
int charge_ok_pin;
|
||||
int charge_ok_level;
|
||||
};
|
||||
|
||||
/*g_sensor*/
|
||||
struct rk2818_gs_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
int gsensor_irq_pin;
|
||||
bool swap_xy; /* swap x and y axes add swj */
|
||||
};
|
||||
|
||||
/*serial*/
|
||||
struct rk2818_serial_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
/*i2s*/
|
||||
struct rk2818_i2s_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
/*spi*/
|
||||
struct spi_cs_gpio {
|
||||
const char *name;
|
||||
unsigned int cs_gpio;
|
||||
char *cs_iomux_name;
|
||||
unsigned int cs_iomux_mode;
|
||||
};
|
||||
|
||||
struct rk2818_spi_platform_data {
|
||||
int (*io_init)(struct spi_cs_gpio*, int);
|
||||
int (*io_deinit)(struct spi_cs_gpio*, int);
|
||||
int (*io_fix_leakage_bug)(void);
|
||||
int (*io_resume_leakage_bug)(void);
|
||||
struct spi_cs_gpio *chipselect_gpios;
|
||||
u16 num_chipselect;
|
||||
};
|
||||
|
||||
/*rtc*/
|
||||
struct rk2818_rtc_platform_data {
|
||||
u8 irq_type;
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
//ROCKCHIP AD KEY CODE ,for demo board
|
||||
// key ---> EV
|
||||
#define AD2KEY1 114 ///VOLUME_DOWN
|
||||
#define AD2KEY2 115 ///VOLUME_UP
|
||||
#define AD2KEY3 59 ///MENU
|
||||
#define AD2KEY4 102 ///HOME
|
||||
#define AD2KEY5 158 ///BACK
|
||||
#define AD2KEY6 61 ///CALL
|
||||
#define AD2KEY7 127 ///SEARCH
|
||||
#define ENDCALL 62
|
||||
#define KEYSTART 232 ///DPAD_CENTER 28 //ENTER
|
||||
#define KEYMENU AD2KEY6 ///CALL
|
||||
#define KEY_PLAY_SHORT_PRESS KEYSTART //code for short press the play key
|
||||
#define KEY_PLAY_LONG_PRESS ENDCALL //code for long press the play key
|
||||
#define KEY_HEADSETHOOK 226
|
||||
|
||||
//ADC Registers
|
||||
typedef struct tagADC_keyst
|
||||
{
|
||||
unsigned int adc_value;
|
||||
unsigned int adc_keycode;
|
||||
}ADC_keyst,*pADC_keyst;
|
||||
|
||||
/*ad key*/
|
||||
struct adc_key_data{
|
||||
u32 pin_playon;
|
||||
u32 playon_level;
|
||||
u32 adc_empty;
|
||||
u32 adc_invalid;
|
||||
u32 adc_drift;
|
||||
u32 adc_chn;
|
||||
ADC_keyst * adc_key_table;
|
||||
unsigned char *initKeyCode;
|
||||
u32 adc_key_cnt;
|
||||
};
|
||||
|
||||
struct rk2818_adckey_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
struct adc_key_data *adc_key;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct jgball_data {
|
||||
u32 pin_up;
|
||||
u32 pin_down;
|
||||
u32 pin_left;
|
||||
u32 pin_right;
|
||||
};
|
||||
|
||||
struct rk2818_jogball_paltform_data {
|
||||
struct jgball_data *jogball_key;
|
||||
};
|
||||
|
||||
|
||||
/* common init routines for use by arch/arm/mach-msm/board-*.c */
|
||||
void __init rk2818_add_devices(void);
|
||||
void __init rk2818_map_common_io(void);
|
||||
void __init rk2818_init_irq(void);
|
||||
void __init rk2818_init_gpio(void);
|
||||
void __init rk2818_clock_init(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef __MACH_CLKDEV_H
|
||||
#define __MACH_CLKDEV_H
|
||||
|
||||
static inline int __clk_get(struct clk *clk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void __clk_put(struct clk *clk)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/debug-macro.S
|
||||
*
|
||||
* 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 <mach/hardware.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
.macro addruart,rx
|
||||
@ see if the MMU is enabled and select appropriate base address
|
||||
mrc p15, 0, \rx, c1, c0
|
||||
tst \rx, #1
|
||||
ldreq \rx, =RK2818_UART1_PHYS
|
||||
ldrne \rx, =RK2818_UART1_BASE
|
||||
.endm
|
||||
|
||||
.macro senduart,rd,rx
|
||||
str \rd, [\rx, #0x00]
|
||||
.endm
|
||||
|
||||
.macro waituart,rd,rx
|
||||
@ wait for TX_READY
|
||||
1: ldr \rd, [\rx, #0x7C]
|
||||
tst \rd, #0x02
|
||||
beq 1b
|
||||
.endm
|
||||
|
||||
.macro busyuart,rd,rx
|
||||
.endm
|
||||
|
|
@ -1,257 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-rk2818/include/mach/dma.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 __ASM_ARCH_RK2818_DMA_H
|
||||
#define __ASM_ARCH_RK2818_DMA_H
|
||||
|
||||
#include <asm/mach/dma.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
|
||||
|
||||
/******dam registers*******/
|
||||
//cfg low word
|
||||
#define B_CFGL_CH_PRIOR(P) ((P)<<5)//pri = 0~2
|
||||
#define B_CFGL_CH_SUSP (1<<8)
|
||||
#define B_CFGL_FIFO_EMPTY (1<<9)
|
||||
#define B_CFGL_H_SEL_DST (0<<10)
|
||||
#define B_CFGL_S_SEL_DST (1<<10)
|
||||
#define B_CFGL_H_SEL_SRC (0<<11)
|
||||
#define B_CFGL_S_SEL_SRC (1<<11)
|
||||
#define B_CFGL_LOCK_CH_L_OTF (0<<12)
|
||||
#define B_CFGL_LOCK_CH_L_OBT (1<<12)
|
||||
#define B_CFGL_LOCK_CH_L_OTN (2<<12)
|
||||
#define B_CFGL_LOCK_B_L_OTF (0<<14)
|
||||
#define B_CFGL_LOCK_B_L_OBT (1<<14)
|
||||
#define B_CFGL_LOCK_B_L_OTN (2<<14)
|
||||
#define B_CFGL_LOCK_CH_EN (0<<16)
|
||||
#define B_CFGL_LOCK_B_EN (0<<17)
|
||||
#define B_CFGL_DST_HS_POL_H (0<<18)
|
||||
#define B_CFGL_DST_HS_POL_L (1<<18)
|
||||
#define B_CFGL_SRC_HS_POL_H (0<<19)
|
||||
#define B_CFGL_SRC_HS_POL_L (1<<19)
|
||||
#define B_CFGL_RELOAD_SRC (1<<30)
|
||||
#define B_CFGL_RELOAD_DST (1<<31)
|
||||
//cfg high word
|
||||
#define B_CFGH_FCMODE (1<<0)
|
||||
#define B_CFGH_FIFO_MODE (1<<1)
|
||||
#define B_CFGH_PROTCTL (1<<2)
|
||||
#define B_CFGH_DS_UPD_EN (1<<5)
|
||||
#define B_CFGH_SS_UPD_EN (1<<6)
|
||||
#define B_CFGH_SRC_PER(HS) ((HS)<<7)
|
||||
#define B_CFGH_DST_PER(HS) ((HS)<<11)
|
||||
|
||||
//ctl low word
|
||||
#define B_CTLL_INT_EN (1<<0)
|
||||
#define B_CTLL_DST_TR_WIDTH_8 (0<<1)
|
||||
#define B_CTLL_DST_TR_WIDTH_16 (1<<1)
|
||||
#define B_CTLL_DST_TR_WIDTH_32 (2<<1)
|
||||
#define B_CTLL_DST_TR_WIDTH(W) ((W)<<1)
|
||||
#define B_CTLL_SRC_TR_WIDTH_8 (0<<4)
|
||||
#define B_CTLL_SRC_TR_WIDTH_16 (1<<4)
|
||||
#define B_CTLL_SRC_TR_WIDTH_32 (2<<4)
|
||||
#define B_CTLL_SRC_TR_WIDTH(W) ((W)<<4)
|
||||
#define B_CTLL_DINC_INC (0<<7)
|
||||
#define B_CTLL_DINC_DEC (1<<7)
|
||||
#define B_CTLL_DINC_UNC (2<<7)
|
||||
#define B_CTLL_DINC(W) ((W)<<7)
|
||||
#define B_CTLL_SINC_INC (0<<9)
|
||||
#define B_CTLL_SINC_DEC (1<<9)
|
||||
#define B_CTLL_SINC_UNC (2<<9)
|
||||
#define B_CTLL_SINC(W) ((W)<<9)
|
||||
#define B_CTLL_DST_MSIZE_1 (0<<11)
|
||||
#define B_CTLL_DST_MSIZE_4 (1<<11)
|
||||
#define B_CTLL_DST_MSIZE_8 (2<<11)
|
||||
#define B_CTLL_DST_MSIZE_16 (3<<11)
|
||||
#define B_CTLL_DST_MSIZE_32 (4<<11)
|
||||
#define B_CTLL_SRC_MSIZE_1 (0<<14)
|
||||
#define B_CTLL_SRC_MSIZE_4 (1<<14)
|
||||
#define B_CTLL_SRC_MSIZE_8 (2<<14)
|
||||
#define B_CTLL_SRC_MSIZE_16 (3<<14)
|
||||
#define B_CTLL_SRC_MSIZE_32 (4<<14)
|
||||
#define B_CTLL_SRC_GATHER (1<<17)
|
||||
#define B_CTLL_DST_SCATTER (1<<18)
|
||||
#define B_CTLL_MEM2MEM_DMAC (0<<20)
|
||||
#define B_CTLL_MEM2PER_DMAC (1<<20)
|
||||
#define B_CTLL_PER2MEM_DMAC (2<<20)
|
||||
#define B_CTLL_PER2MEM_PER (4<<20)
|
||||
#define B_CTLL_DMS_EXP (0<<23)
|
||||
#define B_CTLL_DMS_ARMD (1<<23)
|
||||
#define B_CTLL_SMS_EXP (0<<25)
|
||||
#define B_CTLL_SMS_ARMD (1<<25)
|
||||
#define B_CTLL_LLP_DST_EN (1<<27)
|
||||
#define B_CTLL_LLP_SRC_EN (1<<28)
|
||||
|
||||
#define DWDMA_SAR(chn) 0x00+0x58*(chn)
|
||||
#define DWDMA_DAR(chn) 0x08+0x58*(chn)
|
||||
#define DWDMA_LLP(chn) 0x10+0x58*(chn)
|
||||
#define DWDMA_CTLL(chn) 0x18+0x58*(chn)
|
||||
#define DWDMA_CTLH(chn) 0x1c+0x58*(chn)
|
||||
#define DWDMA_SSTAT(chn) 0x20+0x58*(chn)
|
||||
#define DWDMA_DSTAT(chn) 0x28+0x58*(chn)
|
||||
#define DWDMA_SSTATAR(chn) 0x30+0x58*(chn)
|
||||
#define DWDMA_DSTATAR(chn) 0x38+0x58*(chn)
|
||||
#define DWDMA_CFGL(chn) 0x40+0x58*(chn)
|
||||
#define DWDMA_CFGH(chn) 0x44+0x58*(chn)
|
||||
#define DWDMA_SGR(chn) 0x48+0x58*(chn)
|
||||
#define DWDMA_DSR(chn) 0x50+0x58*(chn)
|
||||
|
||||
#define DWDMA_RawTfr 0x2c0
|
||||
#define DWDMA_RawBlock 0x2c8
|
||||
#define DWDMA_RawSrcTran 0x2d0
|
||||
#define DWDMA_RawDstTran 0x2d8
|
||||
#define DWDMA_RawErr 0x2e0
|
||||
#define DWDMA_StatusTfr 0x2e8
|
||||
#define DWDMA_StatusBlock 0x2f0
|
||||
#define DWDMA_StatusSrcTran 0x2f8
|
||||
#define DWDMA_StatusDstTran 0x300
|
||||
#define DWDMA_StatusErr 0x308
|
||||
#define DWDMA_MaskTfr 0x310
|
||||
#define DWDMA_MaskBlock 0x318
|
||||
#define DWDMA_MaskSrcTran 0x320
|
||||
#define DWDMA_MaskDstTran 0x328
|
||||
#define DWDMA_MaskErr 0x330
|
||||
#define DWDMA_ClearTfr 0x338
|
||||
#define DWDMA_ClearBlock 0x340
|
||||
#define DWDMA_ClearSrcTran 0x348
|
||||
#define DWDMA_ClearDstTran 0x350
|
||||
#define DWDMA_ClearErr 0x358
|
||||
#define DWDMA_StatusInt 0x360
|
||||
#define DWDMA_ReqSrcReg 0x368
|
||||
#define DWDMA_ReqDstReg 0x370
|
||||
#define DWDMA_SglReqSrcReg 0x378
|
||||
#define DWDMA_SglReqDstReg 0x380
|
||||
#define DWDMA_LstSrcReg 0x388
|
||||
#define DWDMA_LstDstReg 0x390
|
||||
#define DWDMA_DmaCfgReg 0x398
|
||||
#define DWDMA_ChEnReg 0x3a0
|
||||
#define DWDMA_DmaIdReg 0x3a8
|
||||
#define DWDMA_DmaTestReg 0x3b0
|
||||
/**************************/
|
||||
|
||||
#define write_dma_reg(addr, val) __raw_writel(val, addr+RK2818_DWDMA_BASE)
|
||||
#define read_dma_reg(addr) __raw_readl(addr+RK2818_DWDMA_BASE)
|
||||
#define mask_dma_reg(addr, msk, val) write_dma_reg(addr, (val)|((~(msk))&read_dma_reg(addr)))
|
||||
|
||||
/* clear interrupt */
|
||||
#define CLR_DWDMA_INTR(dma_ch) write_dma_reg(DWDMA_ClearTfr, 0x101<<dma_ch)
|
||||
|
||||
/* Unmask interrupt */
|
||||
#define UN_MASK_DWDMA_ALL_TRF_INTR write_dma_reg(DWDMA_MaskTfr, 0x3f3f)//mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
#define UN_MASK_DWDMA_TRF_INTR(dma_ch) mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
|
||||
/* Mask interrupt */
|
||||
#define MASK_DWDMA_ALL_TRF_INTR write_dma_reg(DWDMA_MaskTfr, 0x3f00)//mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x100<<dma_ch)
|
||||
#define MASK_DWDMA_TRF_INTR(dma_ch) mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x100<<dma_ch)
|
||||
|
||||
/* Enable channel */
|
||||
#define ENABLE_DWDMA(dma_ch) mask_dma_reg(DWDMA_ChEnReg, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
|
||||
/* Disable channel */
|
||||
#define DISABLE_DWDMA(dma_ch) mask_dma_reg(DWDMA_ChEnReg, 0x101<<dma_ch, 0x100<<dma_ch)
|
||||
|
||||
/* Disable channel */
|
||||
#define GET_DWDMA_STATUS(dma_ch) read_dma_reg(DWDMA_ChEnReg) & (0x001<<dma_ch)
|
||||
|
||||
/**************************/
|
||||
|
||||
#define RK28_DMA_IRQ_NUM 0
|
||||
#define RK28_MAX_DMA_LLPS 64 /*max dma sg count*/
|
||||
|
||||
#define RK28_DMA_CH0A1_MAX_LEN 4095U
|
||||
#define RK28_DMA_CH2_MAX_LEN 2047U
|
||||
|
||||
|
||||
|
||||
struct rk28_dma_llp;
|
||||
typedef struct rk28_dma_llp llp_t;
|
||||
|
||||
struct rk28_dma_llp {
|
||||
unsigned int sar;
|
||||
unsigned int dar;
|
||||
llp_t *llp;
|
||||
unsigned int ctll;
|
||||
unsigned int size;
|
||||
unsigned int sstat;
|
||||
unsigned int dstat;
|
||||
};
|
||||
|
||||
struct rk28_dma_dev {
|
||||
unsigned int hd_if_r; /* hardware interface for reading */
|
||||
unsigned int hd_if_w; /* hardware interface for writing */
|
||||
unsigned int dev_addr_r; /* device basic addresss for reading */
|
||||
unsigned int dev_addr_w; /* device basic addresss for reading */
|
||||
unsigned int fifo_width; /* fifo width of device */
|
||||
};
|
||||
|
||||
struct rk2818_dma {
|
||||
dma_t dma_t;
|
||||
const struct rk28_dma_dev *dev_info;/* basic address of sg in memory */
|
||||
struct rk28_dma_llp *dma_llp_vir; /* virtual cpu addrress of linked list */
|
||||
unsigned int dma_llp_phy; /* physical bus address of linked list */
|
||||
unsigned int length; /* current transfer block */
|
||||
unsigned int residue; /* residue block of current dma transfer */
|
||||
unsigned int tasklet_flag;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
//#define test_dma
|
||||
|
||||
/*devicd id list*/
|
||||
#define RK28_DMA_SD_MMC 0
|
||||
#define RK28_DMA_URAT2 1
|
||||
#define RK28_DMA_URAT3 2
|
||||
#define RK28_DMA_SDIO 3
|
||||
#define RK28_DMA_I2S 4
|
||||
#define RK28_DMA_SPI_M 5
|
||||
#define RK28_DMA_SPI_S 6
|
||||
#define RK28_DMA_URAT0 7
|
||||
#define RK28_DMA_URAT1 8
|
||||
|
||||
#ifdef test_dma
|
||||
#define RK28_DMA_SDRAM 9
|
||||
#define RK28_DMA_DEV_NUM_MAX 10 /*max number of device that support dwdma*/
|
||||
|
||||
#define BUF_READ_ARRR 0x66000000
|
||||
#define BUF_WRITE_ARRR 0x66000000
|
||||
#else
|
||||
#define RK28_DMA_DEV_NUM_MAX 9 /*max number of device that support dwdma*/
|
||||
#endif
|
||||
|
||||
|
||||
/*device hardware interface to dwdma*/
|
||||
#define RK28_DMA_SD_MMC0 0
|
||||
#define RK28_DMA_URAT2_TXD 1
|
||||
#define RK28_DMA_URAT2_RXD 2
|
||||
#define RK28_DMA_URAT3_TXD 3
|
||||
#define RK28_DMA_URAT3_RXD 4
|
||||
#define RK28_DMA_SD_MMC1 5
|
||||
#define RK28_DMA_I2S_TXD 6
|
||||
#define RK28_DMA_I2S_RXD 7
|
||||
#define RK28_DMA_SPI_M_TXD 8
|
||||
#define RK28_DMA_SPI_M_RXD 9
|
||||
#define RK28_DMA_SPI_S_TXD 10
|
||||
#define RK28_DMA_SPI_S_RXD 11
|
||||
#define RK28_DMA_URAT0_TXD 12
|
||||
#define RK28_DMA_URAT0_RXD 13
|
||||
#define RK28_DMA_URAT1_TXD 14
|
||||
#define RK28_DMA_URAT1_RXD 15
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _ASM_ARCH_RK28_DMA_H */
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/entry-macro.S
|
||||
*
|
||||
* 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 "irqs.h"
|
||||
|
||||
.macro disable_fiq
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
ldr \base,=0xff0aa000
|
||||
.endm
|
||||
|
||||
.macro arch_ret_to_user, tmp1, tmp2
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
1001:
|
||||
ldr \irqstat, [\base, #IRQ_REG_FINALSTATUS_L]
|
||||
cmp \irqstat, #0
|
||||
beq 1002f
|
||||
|
||||
clz \irqnr, \irqstat
|
||||
rsb \irqnr, \irqnr, #31
|
||||
b 1003f
|
||||
|
||||
1002:
|
||||
ldr \irqstat, [\base, #IRQ_REG_FINALSTATUS_H]
|
||||
lsr \tmp, \irqstat, #8
|
||||
and \tmp, \tmp, #0xff
|
||||
lsl \tmp, \tmp, #8
|
||||
and \irqstat, \irqstat, #0xff
|
||||
orr \irqstat, \irqstat, \tmp
|
||||
|
||||
cmp \irqstat, #0
|
||||
beq 1003f
|
||||
|
||||
clz \irqnr, \irqstat
|
||||
rsb \irqnr, \irqnr, #31
|
||||
add \irqnr, \irqnr, #32
|
||||
1003:
|
||||
.endm
|
||||
|
|
@ -1,378 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/GPIO.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 __ARCH_ARM_MACH_RK2818_GPIO_H
|
||||
#define __ARCH_ARM_MACH_RK2818_GPIO_H
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#define PIN_BASE 0//定义RK2818内部GPIO的第一个PIN口(即GPIO0_A0)在gpio_desc数组的地址
|
||||
#define NUM_GROUP 8// 定义RK2818内部GPIO每一组最大的PIN数目,现在定为8个,即GPIOX_Y0~ GPIOX_Y7(其中X=0/1;Y=A/B/C/D)
|
||||
#define MAX_GPIO_BANKS 8//定义RK2818内部GPIO总共有几组,现在定为8组,即GPIO0_A~ GPIO0_D,GPIO1_A~ GPIO1_D。
|
||||
#define SPI_FPGA_EXPANDER_BASE (PIN_BASE+NUM_GROUP*MAX_GPIO_BANKS)
|
||||
|
||||
#if defined (CONFIG_SPI_FPGA_GPIO)
|
||||
#define GPIO_EXPANDER_BASE (PIN_BASE+NUM_GROUP*MAX_GPIO_BANKS+CONFIG_SPI_FPGA_GPIO_NUM)
|
||||
#else
|
||||
#define GPIO_EXPANDER_BASE (PIN_BASE+NUM_GROUP*MAX_GPIO_BANKS)
|
||||
#endif
|
||||
|
||||
//定义GPIO的PIN口最大数目。(NUM_GROUP*MAX_GPIO_BANKS)表示RK2818的内部GPIO的PIN口最大数目;CONFIG_ARCH_EXTEND_GPIOS表示扩展IO的最大数目,CONFIG_SPI_FPGA_GPIO_NUM表示FPGA的PIN脚数。
|
||||
#define ARCH_NR_GPIOS ((NUM_GROUP*MAX_GPIO_BANKS)+CONFIG_EXPANDED_GPIO_NUM+CONFIG_SPI_FPGA_GPIO_NUM)
|
||||
typedef enum eGPIOPinLevel
|
||||
{
|
||||
GPIO_LOW=0,
|
||||
GPIO_HIGH
|
||||
}eGPIOPinLevel_t;
|
||||
|
||||
typedef enum eGPIOPinDirection
|
||||
{
|
||||
GPIO_IN=0,
|
||||
GPIO_OUT
|
||||
}eGPIOPinDirection_t;
|
||||
typedef enum GPIOPullType {
|
||||
GPIONormal,
|
||||
GPIOPullUp,
|
||||
GPIOPullDown,
|
||||
GPIONOInit
|
||||
}eGPIOPullType_t;
|
||||
|
||||
typedef enum GPIOIntType {
|
||||
GPIOLevelLow=0,
|
||||
GPIOLevelHigh,
|
||||
GPIOEdgelFalling,
|
||||
GPIOEdgelRising
|
||||
}eGPIOIntType_t;
|
||||
//GPIO Registers
|
||||
|
||||
struct rk2818_gpio_bank {
|
||||
unsigned short id; //GPIO寄存器组的ID识别号
|
||||
unsigned long offset; //GPIO0或GPIO1的基地址
|
||||
struct clk *clock; /* associated clock */
|
||||
};
|
||||
//定义GPIO相关寄存器偏移地址
|
||||
#define GPIO_SWPORTA_DR 0x00
|
||||
#define GPIO_SWPORTA_DDR 0x04
|
||||
|
||||
#define GPIO_SWPORTB_DR 0x0c
|
||||
#define GPIO_SWPORTB_DDR 0x10
|
||||
|
||||
#define GPIO_SWPORTC_DR 0x18
|
||||
#define GPIO_SWPORTC_DDR 0x1c
|
||||
|
||||
#define GPIO_SWPORTD_DR 0x24
|
||||
#define GPIO_SWPORTD_DDR 0x28
|
||||
|
||||
#define GPIO_INTEN 0x30
|
||||
#define GPIO_INTMASK 0x34
|
||||
#define GPIO_INTTYPE_LEVEL 0x38
|
||||
#define GPIO_INT_POLARITY 0x3c
|
||||
#define GPIO_INT_STATUS 0x40
|
||||
#define GPIO_INT_RAWSTATUS 0x44
|
||||
#define GPIO_DEBOUNCE 0x48
|
||||
#define GPIO_PORTS_EOI 0x4c
|
||||
#define GPIO_EXT_PORTA 0x50
|
||||
#define GPIO_EXT_PORTB 0x54
|
||||
#define GPIO_EXT_PORTC 0x58
|
||||
#define GPIO_EXT_PORTD 0x5c
|
||||
#define GPIO_LS_SYNC 0x60
|
||||
|
||||
#define RK2818_ID_PIOA 0
|
||||
#define RK2818_ID_PIOB 1
|
||||
#define RK2818_ID_PIOC 2
|
||||
#define RK2818_ID_PIOD 3
|
||||
#define RK2818_ID_PIOE 4
|
||||
#define RK2818_ID_PIOF 5
|
||||
#define RK2818_ID_PIOG 6
|
||||
#define RK2818_ID_PIOH 7
|
||||
/* these pin numbers double as IRQ numbers, like RK2818xxx_ID_* values */
|
||||
|
||||
#define RK2818_PIN_PA0 (PIN_BASE + 0*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PA1 (PIN_BASE + 0*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PA2 (PIN_BASE + 0*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PA3 (PIN_BASE + 0*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PA4 (PIN_BASE + 0*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PA5 (PIN_BASE + 0*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PA6 (PIN_BASE + 0*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PA7 (PIN_BASE + 0*NUM_GROUP + 7)
|
||||
|
||||
|
||||
#define RK2818_PIN_PB0 (PIN_BASE + 1*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PB1 (PIN_BASE + 1*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PB2 (PIN_BASE + 1*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PB3 (PIN_BASE + 1*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PB4 (PIN_BASE + 1*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PB5 (PIN_BASE + 1*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PB6 (PIN_BASE + 1*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PB7 (PIN_BASE + 1*NUM_GROUP + 7)
|
||||
|
||||
#define RK2818_PIN_PC0 (PIN_BASE + 2*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PC1 (PIN_BASE + 2*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PC2 (PIN_BASE + 2*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PC3 (PIN_BASE + 2*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PC4 (PIN_BASE + 2*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PC5 (PIN_BASE + 2*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PC6 (PIN_BASE + 2*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PC7 (PIN_BASE + 2*NUM_GROUP + 7)
|
||||
|
||||
#define RK2818_PIN_PD0 (PIN_BASE + 3*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PD1 (PIN_BASE + 3*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PD2 (PIN_BASE + 3*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PD3 (PIN_BASE + 3*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PD4 (PIN_BASE + 3*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PD5 (PIN_BASE + 3*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PD6 (PIN_BASE + 3*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PD7 (PIN_BASE + 3*NUM_GROUP + 7)
|
||||
|
||||
#define RK2818_PIN_PE0 (PIN_BASE + 4*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PE1 (PIN_BASE + 4*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PE2 (PIN_BASE + 4*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PE3 (PIN_BASE + 4*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PE4 (PIN_BASE + 4*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PE5 (PIN_BASE + 4*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PE6 (PIN_BASE + 4*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PE7 (PIN_BASE + 4*NUM_GROUP + 7)
|
||||
|
||||
#define RK2818_PIN_PF0 (PIN_BASE + 5*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PF1 (PIN_BASE + 5*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PF2 (PIN_BASE + 5*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PF3 (PIN_BASE + 5*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PF4 (PIN_BASE + 5*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PF5 (PIN_BASE + 5*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PF6 (PIN_BASE + 5*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PF7 (PIN_BASE + 5*NUM_GROUP + 7)
|
||||
|
||||
|
||||
#define RK2818_PIN_PG0 (PIN_BASE + 6*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PG1 (PIN_BASE + 6*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PG2 (PIN_BASE + 6*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PG3 (PIN_BASE + 6*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PG4 (PIN_BASE + 6*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PG5 (PIN_BASE + 6*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PG6 (PIN_BASE + 6*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PG7 (PIN_BASE + 6*NUM_GROUP + 7)
|
||||
|
||||
#define RK2818_PIN_PH0 (PIN_BASE + 7*NUM_GROUP + 0)
|
||||
#define RK2818_PIN_PH1 (PIN_BASE + 7*NUM_GROUP + 1)
|
||||
#define RK2818_PIN_PH2 (PIN_BASE + 7*NUM_GROUP + 2)
|
||||
#define RK2818_PIN_PH3 (PIN_BASE + 7*NUM_GROUP + 3)
|
||||
#define RK2818_PIN_PH4 (PIN_BASE + 7*NUM_GROUP + 4)
|
||||
#define RK2818_PIN_PH5 (PIN_BASE + 7*NUM_GROUP + 5)
|
||||
#define RK2818_PIN_PH6 (PIN_BASE + 7*NUM_GROUP + 6)
|
||||
#define RK2818_PIN_PH7 (PIN_BASE + 7*NUM_GROUP + 7)
|
||||
/***********************define extern gpio pin num******************************/
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
#define FPGA_PIO0_00 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 0)
|
||||
#define FPGA_PIO0_01 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 1)
|
||||
#define FPGA_PIO0_02 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 2)
|
||||
#define FPGA_PIO0_03 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 3)
|
||||
#define FPGA_PIO0_04 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 4)
|
||||
#define FPGA_PIO0_05 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 5)
|
||||
#define FPGA_PIO0_06 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 6)
|
||||
#define FPGA_PIO0_07 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO0_08 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 0)
|
||||
#define FPGA_PIO0_09 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 1)
|
||||
#define FPGA_PIO0_10 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 2)
|
||||
#define FPGA_PIO0_11 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 3)
|
||||
#define FPGA_PIO0_12 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 4)
|
||||
#define FPGA_PIO0_13 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 5)
|
||||
#define FPGA_PIO0_14 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 6)
|
||||
#define FPGA_PIO0_15 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO1_00 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 0)
|
||||
#define FPGA_PIO1_01 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 1)
|
||||
#define FPGA_PIO1_02 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 2)
|
||||
#define FPGA_PIO1_03 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 3)
|
||||
#define FPGA_PIO1_04 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 4)
|
||||
#define FPGA_PIO1_05 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 5)
|
||||
#define FPGA_PIO1_06 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 6)
|
||||
#define FPGA_PIO1_07 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO1_08 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 0)
|
||||
#define FPGA_PIO1_09 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 1)
|
||||
#define FPGA_PIO1_10 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 2)
|
||||
#define FPGA_PIO1_11 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 3)
|
||||
#define FPGA_PIO1_12 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 4)
|
||||
#define FPGA_PIO1_13 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 5)
|
||||
#define FPGA_PIO1_14 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 6)
|
||||
#define FPGA_PIO1_15 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO2_00 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 0)
|
||||
#define FPGA_PIO2_01 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 1)
|
||||
#define FPGA_PIO2_02 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 2)
|
||||
#define FPGA_PIO2_03 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 3)
|
||||
#define FPGA_PIO2_04 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 4)
|
||||
#define FPGA_PIO2_05 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 5)
|
||||
#define FPGA_PIO2_06 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 6)
|
||||
#define FPGA_PIO2_07 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO2_08 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 0)
|
||||
#define FPGA_PIO2_09 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 1)
|
||||
#define FPGA_PIO2_10 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 2)
|
||||
#define FPGA_PIO2_11 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 3)
|
||||
#define FPGA_PIO2_12 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 4)
|
||||
#define FPGA_PIO2_13 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 5)
|
||||
#define FPGA_PIO2_14 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 6)
|
||||
#define FPGA_PIO2_15 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO3_00 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 0)
|
||||
#define FPGA_PIO3_01 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 1)
|
||||
#define FPGA_PIO3_02 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 2)
|
||||
#define FPGA_PIO3_03 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 3)
|
||||
#define FPGA_PIO3_04 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 4)
|
||||
#define FPGA_PIO3_05 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 5)
|
||||
#define FPGA_PIO3_06 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 6)
|
||||
#define FPGA_PIO3_07 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO3_08 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 0)
|
||||
#define FPGA_PIO3_09 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 1)
|
||||
#define FPGA_PIO3_10 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 2)
|
||||
#define FPGA_PIO3_11 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 3)
|
||||
#define FPGA_PIO3_12 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 4)
|
||||
#define FPGA_PIO3_13 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 5)
|
||||
#define FPGA_PIO3_14 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 6)
|
||||
#define FPGA_PIO3_15 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO4_00 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 0)
|
||||
#define FPGA_PIO4_01 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 1)
|
||||
#define FPGA_PIO4_02 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 2)
|
||||
#define FPGA_PIO4_03 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 3)
|
||||
#define FPGA_PIO4_04 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 4)
|
||||
#define FPGA_PIO4_05 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 5)
|
||||
#define FPGA_PIO4_06 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 6)
|
||||
#define FPGA_PIO4_07 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO4_08 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 0)
|
||||
#define FPGA_PIO4_09 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 1)
|
||||
#define FPGA_PIO4_10 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 2)
|
||||
#define FPGA_PIO4_11 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 3)
|
||||
#define FPGA_PIO4_12 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 4)
|
||||
#define FPGA_PIO4_13 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 5)
|
||||
#define FPGA_PIO4_14 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 6)
|
||||
#define FPGA_PIO4_15 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO5_00 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 0)
|
||||
#define FPGA_PIO5_01 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 1)
|
||||
#define FPGA_PIO5_02 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 2)
|
||||
#define FPGA_PIO5_03 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 3)
|
||||
#define FPGA_PIO5_04 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 4)
|
||||
#define FPGA_PIO5_05 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 5)
|
||||
#define FPGA_PIO5_06 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 6)
|
||||
#define FPGA_PIO5_07 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 7)
|
||||
|
||||
#define FPGA_PIO5_08 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 0)
|
||||
#define FPGA_PIO5_09 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 1)
|
||||
#define FPGA_PIO5_10 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 2)
|
||||
#define FPGA_PIO5_11 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 3)
|
||||
#define FPGA_PIO5_12 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 4)
|
||||
#define FPGA_PIO5_13 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 5)
|
||||
#define FPGA_PIO5_14 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 6)
|
||||
#define FPGA_PIO5_15 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 7)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IOEXTEND_TCA6424)
|
||||
#define TCA6424_P00 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 0)
|
||||
#define TCA6424_P01 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 1)
|
||||
#define TCA6424_P02 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 2)
|
||||
#define TCA6424_P03 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 3)
|
||||
#define TCA6424_P04 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 4)
|
||||
#define TCA6424_P05 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 5)
|
||||
#define TCA6424_P06 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 6)
|
||||
#define TCA6424_P07 (GPIO_EXPANDER_BASE + 0*NUM_GROUP + 7)
|
||||
|
||||
#define TCA6424_P10 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 0)
|
||||
#define TCA6424_P11 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 1)
|
||||
#define TCA6424_P12 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 2)
|
||||
#define TCA6424_P13 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 3)
|
||||
#define TCA6424_P14 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 4)
|
||||
#define TCA6424_P15 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 5)
|
||||
#define TCA6424_P16 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 6)
|
||||
#define TCA6424_P17 (GPIO_EXPANDER_BASE + 1*NUM_GROUP + 7)
|
||||
|
||||
#define TCA6424_P20 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 0)
|
||||
#define TCA6424_P21 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 1)
|
||||
#define TCA6424_P22 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 2)
|
||||
#define TCA6424_P23 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 3)
|
||||
#define TCA6424_P24 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 4)
|
||||
#define TCA6424_P25 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 5)
|
||||
#define TCA6424_P26 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 6)
|
||||
#define TCA6424_P27 (GPIO_EXPANDER_BASE + 2*NUM_GROUP + 7)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void __init rk2818_gpio_init(struct rk2818_gpio_bank *data, int nr_banks);
|
||||
extern void __init rk2818_gpio_irq_setup(void);
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* wrappers for "new style" GPIO calls. the old RK2818-specfic ones should
|
||||
* eventually be removed (along with this errno.h inclusion), and the
|
||||
* gpio request/free calls should probably be implemented.
|
||||
*/
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm-generic/gpio.h> /* cansleep wrappers */
|
||||
|
||||
#define gpio_get_value __gpio_get_value
|
||||
#define gpio_set_value __gpio_set_value
|
||||
#define gpio_cansleep __gpio_cansleep
|
||||
|
||||
static inline int gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
return __gpio_to_irq(gpio);
|
||||
}
|
||||
|
||||
static inline int irq_to_gpio(unsigned irq)
|
||||
{
|
||||
if(irq<NR_AIC_IRQS)
|
||||
return -ENXIO;
|
||||
|
||||
if((irq - __gpio_to_irq(RK2818_PIN_PA0)) < NUM_GROUP)
|
||||
{
|
||||
return (RK2818_PIN_PA0 + (irq - __gpio_to_irq(RK2818_PIN_PA0)));
|
||||
}
|
||||
else if((irq - __gpio_to_irq(RK2818_PIN_PA0)) < 2*NUM_GROUP)
|
||||
{
|
||||
return (RK2818_PIN_PE0 + (irq - __gpio_to_irq(RK2818_PIN_PE0)));
|
||||
}
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
else if((irq - __gpio_to_irq(FPGA_PIO0_00)) <2*NUM_GROUP)
|
||||
{
|
||||
return (FPGA_PIO0_00 + (irq - __gpio_to_irq(FPGA_PIO0_00)));
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_IOEXTEND_TCA6424)
|
||||
else if((irq - __gpio_to_irq(TCA6424_P00)) <3*NUM_GROUP)
|
||||
{
|
||||
return (TCA6424_P00 + (irq - __gpio_to_irq(TCA6424_P00)));
|
||||
}
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/hardware.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 __ASM_ARCH_RK2818_HARDWARE_H
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# define __REG(x) (*((volatile u32 *)IO_ADDRESS(x)))
|
||||
|
||||
# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/io.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 __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
#define __io(a) __typesafe_io(a)
|
||||
#define __mem_pci(a) (a)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-rk2818/include/mach/iomux.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 __RK2818_IOMUX_H__
|
||||
#define __RK2818_IOMUX_H__
|
||||
|
||||
//IOMUX_A_CON
|
||||
#define IOMUXA_I2C0 (0)
|
||||
#define IOMUXA_GPIO1_A45 (1)
|
||||
#define IOMUXA_GPIO1_A67 (0)
|
||||
#define IOMUXA_UART1_SIR (1)
|
||||
#define IOMUXA_I2C1 (2)
|
||||
#define IOMUXA_GPIO1_B1 (0)
|
||||
#define IOMUXA_UART1_SOUT (1)
|
||||
#define IOMUXA_CX_TIMER1_PMW (2)
|
||||
#define IOMUXA_GPIO1_B0 (0)
|
||||
#define IOMUXA_UART1_SIN (1)
|
||||
#define IOMUXA_CX_TIMER0_PWM (2)
|
||||
#define IOMUXA_GPIO1_C237 (0)
|
||||
#define IOMUXA_SDMMC1_CMD_DATA0_CLKOUT (1)
|
||||
#define IOMUXA_GPIO1_C456 (0)
|
||||
#define IOMUXA_SDMMC1_DATA123 (1)
|
||||
#define IOMUXA_GPIO1_A3B7 (0)
|
||||
#define IOMUXA_SPI1_RXD_TXD (1)
|
||||
#define IOMUXA_FLASH_CS67 (2)
|
||||
#define IOMUXA_GPIO1_A12 (0)
|
||||
#define IOMUXA_CLKIN_SSINN (1)
|
||||
#define IOMUXA_FLASH_CS45 (2)
|
||||
#define IOMUXA_GPIO0_B0 (0)
|
||||
#define IOMUXA_SPI0_CSN1 (1)
|
||||
#define IOMUXA_SDMMC1_PWR_EN (2)
|
||||
#define IOMUXA_GPIO1_C1 (0)
|
||||
#define IOMUXA_UART0_SOUT (1)
|
||||
#define IOMUXA_SDMMC1_WRITE_PRT (2)
|
||||
#define IOMUXA_GPIO1_C0 (0)
|
||||
#define IOMUXA_UART0_SIN (1)
|
||||
#define IOMUXA_SDMMC1_DETECT_N (2)
|
||||
#define IOMUXA_GPIO1_B4 (0)
|
||||
#define IOMUXA_PWM2 (1)
|
||||
#define IOMUXA_SDMMC0_WRITE_PRT (2)
|
||||
#define IOMUXA_GPIO1_B3 (0)
|
||||
#define IOMUXA_PWM1 (1)
|
||||
#define IOMUXA_SDMMC0_DETECT_N (2)
|
||||
#define IOMUXA_GPIO0_B1 (0)
|
||||
#define IOMUXA_SM_CS1_N (1)
|
||||
#define IOMUXA_SDMMC0_PWR_EN (2)
|
||||
#define IOMUXA_GPIO1_D234 (0)
|
||||
#define IOMUXA_SDMMC0_DATA123 (1)
|
||||
#define IOMUXA_GPIO1_D015 (0)
|
||||
#define IOMUXA_SDMMC0_CMD_DATA0_CLKOUT (1)
|
||||
#define IOMUXA_GPIO0_B567 (0)
|
||||
#define IOMUXA_SPI0 (1)
|
||||
#define IOMUXA_SDMMC0_DATA567 (2)
|
||||
#define IOMUXA_GPIO0_B4 (0)
|
||||
#define IOMUXA_SPI0_CSN0 (1)
|
||||
#define IOMUXA_SDMMC0_DATA4 (2)
|
||||
|
||||
///IOMUX_B_CON
|
||||
#define IOMUXB_GPIO1_B34 (0)
|
||||
#define IOMUXB_UART3_IN_OUT (1)
|
||||
#define IOMUXB_GPIO0_B01 (0)
|
||||
#define IOMUXB_UART2_IN_OUT (1)
|
||||
#define IOMUXB_GPIO0_A23 (0)
|
||||
#define IOMUXB_UART2_CTS_RTS (1)
|
||||
#define IOMUXB_GPIO2_22_23 (0)
|
||||
#define IOMUXB_HSADC_DATA_Q89 (1)
|
||||
#define IOMUXB_SM_WE_SM_OE (2)
|
||||
#define IOMUXB_GPIO2_14_TO_21 (0)
|
||||
#define IOMUXB_HSADC_DATA_Q7_TO_Q0 (1)
|
||||
#define IOMUXB_HOST_DATA15_TO_8 (2)
|
||||
#define IOMUXB_GPIO0_A1 (0)
|
||||
#define IOMUXB_HOST_DATA17 (1)
|
||||
#define IOMUXB_GPIO0_A0 (0)
|
||||
#define IOMUXB_HOST_DATA16 (1)
|
||||
#define IOMUXB_GPIO1_A0 (0)
|
||||
#define IOMUXB_VIP_DATA0 (1)
|
||||
#define IOMUXB_GPIO2_24 (0)
|
||||
#define IOMUXB_GPS_CLK (1)
|
||||
#define IOMUXB_HSADC_CLKOUT (2)
|
||||
#define IOMUXB_HSADC_DATA_I98 (0)
|
||||
#define IOMUXB_TS_FAIL_TS_VALID (1)
|
||||
#define IOMUXB_GPIO0_A7 (0)
|
||||
#define IOMUXB_FLASH_CS3 (1)
|
||||
#define IOMUXB_GPIO0_A6 (0)
|
||||
#define IOMUXB_FLASH_CS2 (1)
|
||||
#define IOMUXB_GPIO0_A5 (0)
|
||||
#define IOMUXB_FLASH_CS1 (1)
|
||||
#define IOMUXB_GPIO1_B5 (0)
|
||||
#define IOMUXB_PWM3 (1)
|
||||
#define IOMUXB_DEMOD_PWM_OUT (2)
|
||||
#define IOMUXB_GPIO0_B3 (0)
|
||||
#define IOMUXB_UART0_RTS_N (1)
|
||||
#define IOMUXB_GPIO0_B2 (0)
|
||||
#define IOMUXB_UART0_CTS_N (1)
|
||||
#define IOMUXB_GPIO1_B2 (0)
|
||||
#define IOMUXB_PWM0 (1)
|
||||
#define IOMUXB_GPIO0_D0_7 (0)
|
||||
#define IOMUXB_LCDC_DATA8_15 (1)
|
||||
#define IOMUXB_GPIO0_C2_7 (0)
|
||||
#define IOMUXB_LCDC_DATA18_23 (1)
|
||||
#define IOMUXB_GPIO0_C01 (0)
|
||||
#define IOMUXB_LCDC_DATA16_17 (1)
|
||||
#define IOMUXB_GPIO2_26 (0)
|
||||
#define IOMUXB_LCDC_DENABLE (1)
|
||||
#define IOMUXB_GPIO2_25 (0)
|
||||
#define IOMUXB_LCDC_VSYNC (1)
|
||||
#define IOMUXB_GPIO2_14_23 (0)
|
||||
#define IOMUXB_HSADC_DATA9_0 (1)
|
||||
#define IOMUXB_GPIO2_0_13 (0)
|
||||
#define IOMUXB_HOST_INTERFACE (1)
|
||||
#define IOMUXB_GPIO1_D7 (0)
|
||||
#define IOMUXB_HSADC_CLKIN (1)
|
||||
#define IOMUXB_GPIO1_D6 (0)
|
||||
#define IOMUXB_EXT_IQ_INDEX (1)
|
||||
#define IOMUXB_I2S_INTERFACE (0)
|
||||
#define IOMUXB_GPIO2_27_31 (1)
|
||||
#define IOMUXB_GPIO1_B6 (0)
|
||||
#define IOMUXB_VIP_CLKOUT (1)
|
||||
|
||||
#define DEFAULT 0
|
||||
#define INITIAL 1
|
||||
|
||||
|
||||
|
||||
#define GPIOE_I2C0_SEL_NAME "gpioe_i2c0_sel"
|
||||
#define GPIOE_U1IR_I2C1_NAME "gpioe_u1ir_i2c1"
|
||||
#define GPIOF1_UART1_CPWM1_NAME "gpiof1_uart1_cpwm1"
|
||||
#define GPIOF0_UART1_CPWM0_NAME "gpiof0_uart1_cpwm0"
|
||||
#define GPIOG_MMC1_SEL_NAME "gpiog_mmc1_sel"
|
||||
#define GPIOG_MMC1D_SEL_NAME "gpiog_mmc1d_sel"
|
||||
#define GPIOE_SPI1_FLASH_SEL_NAME "gpioe_spi1_flash2"
|
||||
#define GPIOE_SPI1_FLASH_SEL1_NAME "gpioe_spi1_flash1"
|
||||
#define GPIOB0_SPI0CSN1_MMC1PCA_NAME "gpiob0_spi0csn1_mmc1pca"
|
||||
#define GPIOG1_UART0_MMC1WPT_NAME "gpiog1_uart0_mmc1wpt"
|
||||
#define GPIOG0_UART0_MMC1DET_NAME "gpiog0_uart0_mmc1det"
|
||||
#define GPIOF4_APWM2_MMC0WPT_NAME "gpiof4_apwm2_mmc0wpt"
|
||||
#define GPIOF3_APWM1_MMC0DETN_NAME "gpiof3_apwm1_mmc0detn"
|
||||
#define GPIOB1_SMCS1_MMC0PCA_NAME "gpiob1_smcs1_mmc0pca"
|
||||
#define GPIOH_MMC0D_SEL_NAME "gpioh_mmc0d_sel"
|
||||
#define GPIOH_MMC0_SEL_NAME "gpioh_mmc0_sel"
|
||||
#define GPIOB_SPI0_MMC0_NAME "gpiob_spi0_mmc0"
|
||||
#define GPIOB4_SPI0CS0_MMC0D4_NAME "gpiob4_spi0cs0_mmc0d4"
|
||||
|
||||
#define GPIOF34_UART3_SEL_NAME "gpiof34_uart3"
|
||||
#define GPIOF01_UART2_SEL_NAME "gpiof01_uart2"
|
||||
#define GPIOA23_UART2_SEL_NAME "gpioa23_uart2"
|
||||
#define CXGPIO_HSADC_NORFLASH_SEL_NAME "cxgpio_hsadc_norflash"
|
||||
#define CXGPIO_HSADC_HIF_SEL_NAME "cxgpio_hsadc_hif"
|
||||
#define GPIOA1_HOSTDATA17_SEL_NAME "gpioa1_hostdata17"
|
||||
#define GPIOA0_HOSTDATA16_SEL_NAME "gpioa0_hostdata16"
|
||||
#define GPIOE0_VIPDATA0_SEL_NAME "gpioe0_vipdata0"
|
||||
#define CXGPIO_GPSCLK_HSADCCLKOUT_NAME "cxgpio_gpsclk_hsadcclkout"
|
||||
#define HSADCDATA_TSCON_SEL_NAME "hsadcdata_tscon_sel"
|
||||
#define GPIOA7_FLASHCS3_SEL_NAME "gpioa7_flashcs3_sel"
|
||||
#define GPIOA6_FLASHCS2_SEL_NAME "gpioa6_flashcs2_sel"
|
||||
#define GPIOA5_FLASHCS1_SEL_NAME "gpioa5_flashcs1_sel"
|
||||
#define GPIOF5_APWM3_DPWM3_NAME "gpiof5_apwm3_dpwm"
|
||||
#define GPIOB3_U0RTSN_SEL_NAME "gpiob3_u0rtsn_sel"
|
||||
#define GPIOB2_U0CTSN_SEL_NAME "gpiob2_u0ctsn_sel"
|
||||
#define GPIOF2_APWM0_SEL_NAME "gpiof2_apwm0_sel"
|
||||
#define GPIOC_LCDC16BIT_SEL_NAME "gpiod_lcdc16bit_sel"
|
||||
#define GPIOC_LCDC24BIT_SEL_NAME "gpioc_lcdc24bit_sel"
|
||||
#define GPIOC_LCDC18BIT_SEL_NAME "gpioc_lcdc18bit_sel"
|
||||
#define CXGPIO_LCDDEN_SEL_NAME "cxgpio_lcdden_sel"
|
||||
#define CXGPIO_LCDVSYNC_SEL_NAME "cxgpio_lcdvsync_sel"
|
||||
#define CXGPIO_HSADC_SEL_NAME "cxgpio_hsadc_sel"
|
||||
#define CXGPIO_HOST_SEL_NAME "cxgpio_host_sel"
|
||||
#define GPIOH7_HSADCCLK_SEL_NAME "gpioh7_hsadcclk_sel"
|
||||
#define GPIOH6_IQ_SEL_NAME "gpioh6_iq_sel"
|
||||
#define CXGPIO_I2S_SEL_NAME "cxgpio_i2s_sel"
|
||||
#define GPIOF6_VIPCLK_SEL_NAME "gpiof6_vipclk_sel"
|
||||
|
||||
#define CPU_APB_REG0 0x00
|
||||
#define CPU_APB_REG1 0x04
|
||||
#define CPU_APB_REG2 0x08
|
||||
#define CPU_APB_REG3 0x0c
|
||||
#define CPU_APB_REG4 0x10
|
||||
#define CPU_APB_REG5 0x14
|
||||
#define CPU_APB_REG6 0x18
|
||||
#define CPU_APB_REG7 0x1c
|
||||
#define IOMUX_A_CON 0x20
|
||||
#define IOMUX_B_CON 0x24
|
||||
#define GPIO0_AB_PU_CON 0x28
|
||||
#define GPIO0_CD_PU_CON 0x2c
|
||||
#define GPIO1_AB_PU_CON 0x30
|
||||
#define GPIO1_CD_PU_CON 0x34
|
||||
#define OTGPHY_CON0 0x38
|
||||
#define OTGPHY_CON1 0x3c
|
||||
|
||||
|
||||
#define MUX_CFG(desc,reg,off,interl,mux_mode,bflags) \
|
||||
{ \
|
||||
.name = desc, \
|
||||
.offset = off, \
|
||||
.interleave = interl, \
|
||||
.mux_reg = RK2818_IOMUX_##reg##_CON, \
|
||||
.mode = mux_mode, \
|
||||
.premode = mux_mode, \
|
||||
.flags = bflags, \
|
||||
},
|
||||
|
||||
struct mux_config {
|
||||
char *name;
|
||||
const unsigned int offset;
|
||||
unsigned int mode;
|
||||
unsigned int premode;
|
||||
const unsigned int mux_reg;
|
||||
const unsigned int interleave;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
extern int rk2818_iomux_init(void);
|
||||
extern void rk2818_mux_api_set(char *name, unsigned int mode);
|
||||
extern void rk2818_mux_api_mode_resume(char *name);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/irqs.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 __ARCH_ARM_MACH_RK2818_IRQS_H
|
||||
#define __ARCH_ARM_MACH_RK2818_IRQS_H
|
||||
|
||||
|
||||
|
||||
#define IRQ_REG_INTEN_L 0x00//IRQ interrupt source enable register (low)
|
||||
#define IRQ_REG_INTEN_H 0x04//IRQ interrupt source enable register (high)
|
||||
#define IRQ_REG_INTMASK_L 0x08//IRQ interrupt source mask register (low).
|
||||
#define IRQ_REG_INTMASK_H 0x0c//IRQ interrupt source mask register (high).
|
||||
#define IRQ_REG_INTFORCE_L 0x10//IRQ interrupt force register
|
||||
#define IRQ_REG_INTFORCE_H 0x14//
|
||||
#define IRQ_REG_RAWSTATUS_L 0x18//IRQ raw status register
|
||||
#define IRQ_REG_RAWSTATUS_H 0x1c//
|
||||
#define IRQ_REG_STATUS_L 0x20//IRQ status register
|
||||
#define IRQ_REG_STATUS_H 0x24//
|
||||
#define IRQ_REG_MASKSTATUS_L 0x28//IRQ interrupt mask status register
|
||||
#define IRQ_REG_MASKSTATUS_H 0x2c//
|
||||
#define IRQ_REG_FINALSTATUS_L 0x30//IRQ interrupt final status
|
||||
#define IRQ_REG_FINALSTATUS_H 0x34
|
||||
#define FIQ_REG_INTEN 0xc0//Fast interrupt enable register
|
||||
#define FIQ_REG_INTMASK 0xc4//Fast interrupt mask register
|
||||
#define FIQ_REG_INTFORCE 0xc8//Fast interrupt force register
|
||||
#define FIQ_REG_RAWSTATUS 0xcc//Fast interrupt source raw status register
|
||||
#define FIQ_REG_STATUS 0xd0//Fast interrupt status register
|
||||
#define FIQ_REG_FINALSTATUS 0xd4//Fast interrupt final status register
|
||||
#define IRQ_REG_PLEVEL 0xd8//IRQ System Priority Level Register
|
||||
|
||||
|
||||
/*定义RK2818的最大中断数目。NR_AIC_IRQS表示RK2818的中断寄存器支持的最大中断数目,
|
||||
CONFIG_RK28_GPIO_IRQ表示RK2818的GPIO复用的最大中断数目,CONFIG_EXTEND_GPIO_IRQ表示RK2818的
|
||||
扩展IO复用的最大中断数目。*/
|
||||
#define NR_AIC_IRQS 48
|
||||
#define NR_IRQS (NR_AIC_IRQS + CONFIG_RK28_GPIO_IRQ+CONFIG_EXPANDED_GPIO_IRQ_NUM+CONFIG_SPI_FPGA_GPIO_IRQ_NUM)
|
||||
|
||||
|
||||
/*irq number*/
|
||||
#define IRQ_NR_DWDMA 0 // -- low
|
||||
#define IRQ_NR_HOST 1 // -- Host Interface
|
||||
#define IRQ_NR_NANDC 2
|
||||
#define IRQ_NR_LCDC 3
|
||||
#define IRQ_NR_SDMMC0 4
|
||||
#define IRQ_NR_VIP 5
|
||||
#define IRQ_NR_GPIO0 6
|
||||
#define IRQ_NR_GPIO1 7
|
||||
#define IRQ_NR_OTG 8 // -- USB OTG
|
||||
#define IRQ_NR_ABTARMD 9 // -- Arbiter in ARMD BUS
|
||||
#define IRQ_NR_ABTEXP 10//-- Arbiter in EXP BUS
|
||||
#define IRQ_NR_I2C0 11
|
||||
#define IRQ_NR_I2C1 12
|
||||
#define IRQ_NR_I2S 13
|
||||
#define IRQ_NR_SPIM 14// -- SPI Master
|
||||
#define IRQ_NR_SPIS 15//-- SPI Slave
|
||||
#define IRQ_NR_TIMER1 16
|
||||
#define IRQ_NR_TIMER2 17
|
||||
#define IRQ_NR_TIMER3 18
|
||||
#define IRQ_NR_UART0 19
|
||||
#define IRQ_NR_UART1 20
|
||||
#define IRQ_NR_WDT 21
|
||||
#define IRQ_NR_PWM0 22
|
||||
#define IRQ_NR_PWM1 23
|
||||
#define IRQ_NR_PWM2 24
|
||||
#define IRQ_NR_PWM3 25
|
||||
#define IRQ_NR_ADC 26
|
||||
#define IRQ_NR_RTC 27
|
||||
#define IRQ_NR_PIUSEM0 28// -- PIU Semphore 0
|
||||
#define IRQ_NR_PIUSEM1 29
|
||||
#define IRQ_NR_PIUSEM3 30
|
||||
#define IRQ_NR_PIUCMD 31// -- PIU command/reply
|
||||
#define IRQ_NR_XDMA 32
|
||||
#define IRQ_NR_SDMMC1 33
|
||||
#define IRQ_NR_DSPSEI 34// -- DSP slave interface error interrupt
|
||||
#define IRQ_NR_DSPSWI 35// -- DSP interrupt by software set
|
||||
#define IRQ_NR_SCU 36
|
||||
#define IRQ_NR_SWI 37// -- Software Interrupt
|
||||
#define IRQ_NR_DSPMEI 38// -- DSP master interface error interrupt
|
||||
#define IRQ_NR_DSPSAEI 39// -- DSP system access error interrupt
|
||||
#define IRQ_NR_GPU_M55 40
|
||||
#define IRQ_NR_GPU_MMU 41
|
||||
#define IRQ_NR_DDRII_MOBILE_CTR 42
|
||||
#define IRQ_NR_MC_DMA 43
|
||||
#define IRQ_NR_NAND_FLASH_RDY 44
|
||||
#define IRQ_NR_UART2 45
|
||||
#define IRQ_NR_UART3 46
|
||||
#define IRQ_NR_USB_HOST 47
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/memory.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 __ASM_ARCH_MEMORY_H
|
||||
#define __ASM_ARCH_MEMORY_H
|
||||
|
||||
/* physical offset of RAM */
|
||||
#define PHYS_OFFSET UL(0x60000000)
|
||||
|
||||
/* bus address and physical addresses are identical */
|
||||
#define __virt_to_bus(x) __virt_to_phys(x)
|
||||
#define __bus_to_virt(x) __phys_to_virt(x)
|
||||
|
||||
/*
|
||||
* TCM memory whereabouts
|
||||
*/
|
||||
#define ITCM_OFFSET 0xff400000
|
||||
#define ITCM_END 0xff401fff
|
||||
#define DTCM_OFFSET 0xff404000
|
||||
#define DTCM_END 0xff407fff
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
/*
|
||||
* rockchip-pcm.h - ALSA PCM interface for the Rockchip rk28 SoC
|
||||
*
|
||||
* Driver for rockchip iis audio
|
||||
* Copyright (C) 2009 lhh
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ROCKCHIP_SOC_PM_H
|
||||
#define _ROCKCHIP_SOC_PM_H
|
||||
|
||||
#if defined (CONFIG_RK2818_SOC_PM)
|
||||
|
||||
#include <asm/tcm.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
|
||||
#define RK2818_PM_PRT_ORIGINAL_REG
|
||||
#define RK2818_PM_PRT_CHANGED_REG
|
||||
|
||||
#define PM_SAVE_REG_NUM 4
|
||||
|
||||
#define PM_NUM_BIT_MASK(b) ((0x1<<(b))-1)
|
||||
#define PM_BIT_OFF_MASK(off,numbit) (PM_NUM_BIT_MASK(numbit)<<(off))
|
||||
#define PM_BIT_CLEAR(off,numbit) (~(PM_BIT_OFF_MASK(off,numbit)))
|
||||
#define PM_BIT_SET(off,val,numbit) ((val&PM_NUM_BIT_MASK(numbit))<<off)
|
||||
#define PM_BIT_get(val,off,numbit) ((val&PM_NUM_BIT_MASK(numbit))>>off)
|
||||
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
|
||||
#define PM_SCU_ATTR_DBG_NUM 30
|
||||
#define PM_GENERAL_ATTR_DBG_NUM 10
|
||||
#define PM_GPIO0_ATTR_DBG_NUM 10
|
||||
#define PM_GPIO1_ATTR_DBG_NUM 10
|
||||
|
||||
|
||||
#define PM_DBG_CH_REG_INI 0
|
||||
#define PM_DBG_CH_REG_UPDATA 1
|
||||
|
||||
|
||||
|
||||
#define PM_DBG_SET_ONCE 0xEE
|
||||
#define PM_DBG_SET_ALWAY 0x99
|
||||
#define PM_DBG_NOT_SET 0
|
||||
|
||||
enum PM_DBG_USER_EN{
|
||||
|
||||
PM_DBG_USER_VALUE,
|
||||
PM_DBG_USER_REGOFF,
|
||||
PM_DBG_USER_BITS_OFF,
|
||||
PM_DBG_USER_BITS_NUM,
|
||||
PM_DBG_USER_FLAG,
|
||||
PM_DBG_USER_END,
|
||||
};
|
||||
|
||||
|
||||
#define PM_ATTR_CTR_ONCE 0xEE
|
||||
#define PM_ATTR_CTR_ALWAY 0x99
|
||||
#define PM_ATTR_NO_CTR 0x0
|
||||
|
||||
struct rk2818_pm_attr_dbg_st{
|
||||
unsigned int value;
|
||||
unsigned char regoff;
|
||||
unsigned char regbits_off;
|
||||
unsigned char bitsnum;
|
||||
unsigned char flag;
|
||||
};
|
||||
|
||||
bool rk2818_socpm_attr_store(int type,const char *buf, size_t n);
|
||||
ssize_t rk2818_socpm_attr_show(int type,char *buf);
|
||||
#endif
|
||||
|
||||
typedef void (*pm_scu_suspend)(unsigned int *tempdata,int regoff);
|
||||
typedef void (*pm_general_reg_suspend)(void);
|
||||
typedef void (*pm_suspend_ctr_pin)(void);
|
||||
typedef void (*pm_resume_ctr_pin)(void);
|
||||
|
||||
struct rk2818_pm_soc_st{
|
||||
unsigned int *reg_save;
|
||||
unsigned int *reg_base_addr;
|
||||
u16 reg_ctrbit;
|
||||
u8 reg_num;
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
unsigned int *reg_ch;
|
||||
#endif
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
u8 attr_num;
|
||||
struct rk2818_pm_attr_dbg_st *attr_dbg;
|
||||
u8 attr_flag;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rk2818_pm_callback_st{
|
||||
pm_scu_suspend scu_suspend;
|
||||
pm_general_reg_suspend general_reg_suspend;
|
||||
pm_suspend_ctr_pin set_pin;
|
||||
pm_resume_ctr_pin resume_pin;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct rk2818_pm_st{
|
||||
struct rk2818_pm_soc_st *scu;
|
||||
unsigned int *scu_tempreg;
|
||||
unsigned int scu_reg;
|
||||
struct rk2818_pm_soc_st *general;
|
||||
struct rk2818_pm_soc_st *gpio0;
|
||||
struct rk2818_pm_soc_st *gpio1;
|
||||
//struct rk2818_pm_callback_st *callback;
|
||||
unsigned int *save_reg;
|
||||
unsigned int *save_ch;
|
||||
};
|
||||
|
||||
/***********************scu SCU_CLKSEL0 reg bit************************************/
|
||||
#define PM_RESUME_BIT 0
|
||||
#define PM_DEBUG_BIT 1
|
||||
#define PM_SET_BIT(b) (1<<b)
|
||||
#define PM_GET_BIT(val,b) ((val&(1<<b))>>b)
|
||||
|
||||
/***********************scu SCU_CLKSEL0 reg bit************************************/
|
||||
|
||||
#define SCU_GATE0CLK_ALL_EN 0
|
||||
#define SCU_GATE0CLK_ALL_DIS 0XFFFFFFFF
|
||||
#define DIS_TIMER_CLK (1<<25)
|
||||
#define DIS_UART1_CLK (1<<19)
|
||||
#define DIS_UART0_CLK (1<<18)
|
||||
#define DIS_GPIO1_CLK (1<<17)
|
||||
#define DIS_GPIO0_CLK (1<<16)
|
||||
#define DIS_INTC_CLK (1<<9)
|
||||
#define DIS_ARM_CLK (1<<0)
|
||||
/***********************scu SCU_CLKSEL1_CON reg bit************************************/
|
||||
|
||||
#define SCU_GATE1CLK_ALL_EN 0
|
||||
//#define SCU_GATE1CLK_BASE_SET (0XFFFFFFFF&(~DIS_DDR_CLK)&(~DIS_DDR_HCLK)) // 注意AXI 位为1时为enable
|
||||
|
||||
#define SCU_GATE1CLK_BASE_SET (0XFFFF8001&(~EN_AXI_CLK)) // 注意AXI 位为1时为enable
|
||||
//#define SCU_GATE1CLK_BASE_SET (0XFFFFFFFF)
|
||||
#define EN_AXI_CLK (1<<27)
|
||||
#define DIS_DDR_CLK (1<<23)
|
||||
#define DIS_DDR_HCLK (1<<22)
|
||||
#define DIS_MSDRAM_CTR_HCLK (1<<17)
|
||||
#define DIS_SDRAM_CTR_HCLK (1<<16)
|
||||
#define DIS_MAndSDRAM_CMM_HCLK (1<<15)
|
||||
/***********************scu SCU_CLKSEL2_CON reg bit************************************/
|
||||
#define SCU_GATE2CLK_ALL_EN 0
|
||||
#define SCU_GATE2CLK_ALL_DIS 0X3FF
|
||||
#define SCU_GATE2CLK_BASE_SET (SCU_GATE2CLK_ALL_DIS&(~DIS_ARMIBUS_CLK)&(~DIS_ARMDBUS_CLK)&(~DIS_EXPAHBBUS_CLK)&(~DIS_APBBUS_CLK))
|
||||
|
||||
#define DIS_ITCMBUS_CLK (1<<8)
|
||||
#define DIS_DTCM0BUS_CLK (1<<7)
|
||||
#define DIS_DTCM1BUS_CLK (1<<6)
|
||||
|
||||
#define DIS_APBBUS_CLK (1<<4)
|
||||
#define DIS_EXPAHBBUS_CLK (1<<3)
|
||||
#define DIS_ARMDBUS_CLK (1<<1)
|
||||
#define DIS_ARMIBUS_CLK (1<<0)
|
||||
/***********************scu SCU_APLL_CON reg bit************************************/
|
||||
#define ARMPLL_POERDOWN (1<<22)
|
||||
#define ARMPLL_BYPASSMODE (1<<0)
|
||||
/***********************scu SCU_DPLL_CON reg bit************************************/
|
||||
|
||||
#define DSPPLL_POERDOWN (1<<22)
|
||||
|
||||
/***********************scu SCU_CPLL_CON reg bit************************************/
|
||||
#define CPLL_POERDOWN (1<<22)
|
||||
|
||||
/***********************scu PM_SCU_MODE_CON reg bit************************************/
|
||||
#define CPU_SLOW_MODE (~(3<<2))
|
||||
#define CPU_STOP_MODE (1<<4)
|
||||
|
||||
|
||||
|
||||
/***********************scu SCU_PMU_CON reg bit************************************/
|
||||
|
||||
#define LCDC_POWER_DOWN (1<<3)
|
||||
#define DSP_POWER_DOWN (1<<0)
|
||||
#define DDR_POWER_DOWN (1<<2)
|
||||
|
||||
|
||||
/***********************scu PM_SCU_CLKSEL0_CON reg bit************************************/
|
||||
#define CLKSEL0_HCLK (0)
|
||||
#define CLKSEL0_PCLK (2)
|
||||
|
||||
#define CLK_ARM1_H1 (0)
|
||||
#define CLK_ARM2_H1 (1)
|
||||
#define CLK_ARM3_H1 (2)
|
||||
#define CLK_ARM4_H1 (3)
|
||||
|
||||
#define CLK_HCLK1_P1 (0)
|
||||
#define CLK_HCLK2_P1 (1)
|
||||
#define CLK_HCLK4_P1 (2)
|
||||
|
||||
/***********************scu PM_SCU_SOFTRST_CON] reg bit************************************/
|
||||
#define RST_ALL 0xFFFFFFFF
|
||||
|
||||
#define RST_DDR_BUS (1<<31)
|
||||
#define RST_DDR_CORE_LOGIC (1<<30)
|
||||
|
||||
#define RST_ARM (1<<23)
|
||||
|
||||
enum
|
||||
{
|
||||
PM_SCU_APLL_CON,
|
||||
PM_SCU_DPLL_CON,
|
||||
PM_SCU_CPLL_CON,
|
||||
PM_SCU_MODE_CON,
|
||||
PM_SCU_PMU_CON,
|
||||
PM_SCU_CLKSEL0_CON,
|
||||
PM_SCU_CLKSEL1_CON,
|
||||
PM_SCU_CLKGATE0_CON,
|
||||
PM_SCU_CLKGATE1_CON,
|
||||
PM_SCU_CLKGATE2_CON,
|
||||
PM_SCU_SOFTRST_CON,
|
||||
PM_SCU_CHIPCFG_CON,
|
||||
PM_SCU_CPUPD,
|
||||
PM_CLKSEL2_CON,
|
||||
PM_SCU_REG_NUM
|
||||
};
|
||||
|
||||
/***********************general cpu reg bit************************************/
|
||||
#define RK2818GPIO_TOTAL (PIN_BASE+NUM_GROUP*MAX_GPIO_BANKS)
|
||||
|
||||
/***********************general cpu reg IOMUX_A bit************************************/
|
||||
|
||||
#define PM_I2C0 (30)
|
||||
#define PM_I2C1 (28)
|
||||
#define PM_UART1_OUT (26)
|
||||
#define PM_UART1_IN (24)
|
||||
#define PM_SDIO1_CMD (23)
|
||||
#define PM_SDIO1_DATA (22)
|
||||
#define PM_UART0_OUT (14)
|
||||
#define PM_UART0_IN (12)
|
||||
|
||||
#define PM_SDIO0_CMD (5)
|
||||
#define PM_SDIO0_DATA (4)
|
||||
|
||||
|
||||
|
||||
/***********************general cpu reg IOMUX_B bit************************************/
|
||||
|
||||
#define PM_UART0_RTS (13)
|
||||
#define PM_UART0_CTS (12)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************general cpu reg PU bit************************************/
|
||||
#define PM_CLEAR_IO_PU(pin) (~((3)<<pin))
|
||||
#define PM_GPIO_NRO(pin) (0<<pin)
|
||||
#define PM_GPIO_UP(pin) (1<<pin)
|
||||
#define PM_GPIO_DN(pin) (2<<pin)
|
||||
|
||||
#define GPIO0_AB_NORMAL (0X0)
|
||||
#define GPIO0_CD_NORMAL (0X0)
|
||||
#define GPIO1_AB_NORMAL (0X0)
|
||||
#define GPIO1_CD_NORMAL (0X0)
|
||||
|
||||
#define GPIO0_A0 (0)
|
||||
#define GPIO0_A3 (3*2)
|
||||
|
||||
enum
|
||||
{
|
||||
PM_CPU_APB_REG0,
|
||||
PM_CPU_APB_REG1,
|
||||
PM_CPU_APB_REG2,
|
||||
PM_CPU_APB_REG3,
|
||||
PM_CPU_APB_REG4,
|
||||
PM_CPU_APB_REG5,
|
||||
PM_CPU_APB_REG6,
|
||||
PM_CPU_APB_REG7,
|
||||
PM_IOMUX_A_CON,
|
||||
PM_IOMUX_B_CON,
|
||||
PM_GPIO0_AB_PU_CON,
|
||||
PM_GPIO0_CD_PU_CON,
|
||||
PM_GPIO1_AB_PU_CON,
|
||||
PM_GPIO1_CD_PU_CON,
|
||||
PM_OTGPHY_CON0,
|
||||
PM_OTGPHY_CON1,
|
||||
PM_GENERAL_CPU_REG
|
||||
};
|
||||
/***********************gpio cpu reg bit************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
PM_GPIO_SWPORTA_DR,
|
||||
PM_GPIO_SWPORTA_DDR,
|
||||
PM_GPIO_SWPORTA_NULL,
|
||||
PM_GPIO_SWPORTB_DR,
|
||||
PM_GPIO_SWPORTB_DDR,
|
||||
PM_GPIO_SWPORTB_NULL,
|
||||
PM_GPIO_SWPORTC_DR,
|
||||
PM_GPIO_SWPORTC_DDR,
|
||||
PM_GPIO_SWPORTC_NULL,
|
||||
PM_GPIO_SWPORTD_DR,
|
||||
PM_GPIO_SWPORTD_DDR,
|
||||
PM_SCU_GPIO_SWPORTC_NUM
|
||||
};
|
||||
|
||||
int rk2818_socpm_init(struct rk2818_pm_callback_st *call_back);
|
||||
extern struct rk2818_pm_st __tcmdata rk2818_soc_pm;
|
||||
extern int __tcmfunc rk2818_socpm_gpio_pullupdown(unsigned int gpio,eGPIOPullType_t GPIOPullUpDown);
|
||||
extern int __tcmfunc rk2818_socpm_set_gpio(unsigned int gpio,unsigned int output,unsigned int level);
|
||||
|
||||
|
||||
|
||||
void __tcmfunc rk2818_socpm_suspend_first(void);
|
||||
void __tcmfunc rk2818_socpm_suspend(void);
|
||||
|
||||
void __tcmfunc rk2818_socpm_resume_last(void);
|
||||
void __tcmfunc rk2818_socpm_resume(void);
|
||||
void rk2818_socpm_print(void);
|
||||
#else
|
||||
#define rk2818_socpm_int(a,b,c,d)
|
||||
#define rk2818_socpm_gpio_pullupdown(a,b)
|
||||
#define rk2818_socpm_set_gpio(a,b,c)
|
||||
#define rk2818_socpm_suspend_first()
|
||||
#define rk2818_socpm_suspend()
|
||||
#define rk2818_socpm_resume_last()
|
||||
#define rk2818_socpm_resume()
|
||||
#define rk2818_socpm_print()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
camera.h - PXA camera driver header file
|
||||
|
||||
Copyright (C) 2003, Intel Corporation
|
||||
Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_CAMERA_H_
|
||||
#define __ASM_ARCH_CAMERA_H_
|
||||
|
||||
|
||||
#define RK28_CAM_DRV_NAME "rk2818-camera"
|
||||
#define RK28_CAM_PLATFORM_DEV_ID 33
|
||||
|
||||
#define RK28_CAM_SENSOR_NAME_OV9650 "ov9650"
|
||||
#define RK28_CAM_SENSOR_NAME_OV2655 "ov2655"
|
||||
#define RK28_CAM_SENSOR_NAME_OV3640 "ov3640"
|
||||
|
||||
#define RK28_CAM_POWERACTIVE_BITPOS 0x00
|
||||
#define RK28_CAM_POWERACTIVE_MASK (1<<RK28_CAM_POWERACTIVE_BITPOS)
|
||||
#define RK28_CAM_POWERACTIVE_H (0x01<<RK28_CAM_POWERACTIVE_BITPOS)
|
||||
#define RK28_CAM_POWERACTIVE_L (0x00<<RK28_CAM_POWERACTIVE_BITPOS)
|
||||
|
||||
#define RK28_CAM_RESETACTIVE_BITPOS 0x01
|
||||
#define RK28_CAM_RESETACTIVE_MASK (1<<RK28_CAM_RESETACTIVE_BITPOS)
|
||||
#define RK28_CAM_RESETACTIVE_H (0x01<<RK28_CAM_RESETACTIVE_BITPOS)
|
||||
#define RK28_CAM_RESETACTIVE_L (0x00<<RK28_CAM_RESETACTIVE_BITPOS)
|
||||
|
||||
struct rk28camera_gpio_res {
|
||||
unsigned int gpio_reset;
|
||||
unsigned int gpio_power;
|
||||
unsigned int gpio_flag;
|
||||
const char *dev_name;
|
||||
};
|
||||
|
||||
struct rk28camera_platform_data {
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
struct rk28camera_gpio_res gpio_res[2];
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARCH_CAMERA_H_ */
|
||||
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/rk281x_iomap.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 __ASM_ARCH_RK2818_IOMAP_H
|
||||
#define __ASM_ARCH_RK2818_IOMAP_H
|
||||
|
||||
#include <asm/sizes.h>
|
||||
|
||||
/* defines */
|
||||
|
||||
#define SZ_22K 0x5800
|
||||
|
||||
/* Physical base address and size of peripherals.
|
||||
* Ordered by the virtual base addresses they will be mapped at.
|
||||
*
|
||||
* RK2818_VIC_BASE must be an value that can be loaded via a "mov"
|
||||
* instruction, otherwise entry-macro.S will not compile.
|
||||
*
|
||||
* If you add or remove entries here, you'll want to edit the
|
||||
* rk2818_io_desc array in arch/arm/mach-rk2818/io.c to reflect your
|
||||
* changes.
|
||||
*
|
||||
*/
|
||||
//内存物理地址
|
||||
#ifdef CONFIG_DRAM_BASE
|
||||
#define RK2818_SDRAM_BASE 0x60000000//CONFIG_DRAM_BASE
|
||||
#else
|
||||
#define RK2818_SDRAM_PHYS 0x60000000
|
||||
#define RK2818_SDRAM_SIZE (0x00100000*64)
|
||||
#endif
|
||||
|
||||
#define RK2818_AHB_PHYS 0x10000000 //AHB 总线设备基物理地址
|
||||
#define RK2818_AHB_SIZE 0x00100000 // size:1M
|
||||
|
||||
#define RK2818_APB_BASE 0xFF100000
|
||||
#define RK2818_APB_PHYS 0x18000000 // APB总线设备基物理地址
|
||||
#define RK2818_APB_SIZE 0x00100000 // size:1M
|
||||
|
||||
#define RK2818_BOOTROM_PHYS 0x10000000
|
||||
#define RK2818_BOOTROM_SIZE SZ_8K
|
||||
|
||||
#define RK2818_SRAM_PHYS 0x10002000
|
||||
#define RK2818_SRAM_SIZE SZ_8K
|
||||
|
||||
#define RK2818_USBOTG_PHYS 0x10040000
|
||||
#define RK2818_USBOTG_SIZE SZ_256K
|
||||
|
||||
#define RK2818_MCDMA_BASE 0xFF080000
|
||||
#define RK2818_MCDMA_PHYS 0x10080000
|
||||
#define RK2818_MCDMA_SIZE SZ_8K
|
||||
|
||||
#define RK2818_SHAREMEM_PHYS 0x10090000
|
||||
#define RK2818_SHAREMEM_SIZE SZ_64K
|
||||
|
||||
#define RK2818_DWDMA_BASE 0xFF0A0000
|
||||
#define RK2818_DWDMA_PHYS 0x100A0000
|
||||
#define RK2818_DWDMA_SIZE SZ_8K
|
||||
|
||||
#define RK2818_HOSTIF_PHYS 0x100A2000
|
||||
#define RK2818_HOSTIF_SIZE SZ_8K
|
||||
|
||||
#define RK2818_LCDC_PHYS 0x100A4000
|
||||
#define RK2818_LCDC_SIZE SZ_8K
|
||||
|
||||
#define RK2818_VIP_PHYS 0x100A6000
|
||||
#define RK2818_VIP_SIZE SZ_8K
|
||||
|
||||
#define RK2818_SDMMC1_PHYS 0x100A8000
|
||||
#define RK2818_SDMMC1_SIZE SZ_8K
|
||||
|
||||
#define RK2818_INTC_BASE 0xFF0AA000
|
||||
#define RK2818_INTC_PHYS 0x100AA000
|
||||
#define RK2818_INTC_SIZE SZ_8K
|
||||
|
||||
#define RK2818_SDMMC0_PHYS 0x100AC000
|
||||
#define RK2818_SDMMC0_SIZE SZ_8K
|
||||
|
||||
#define RK2818_NANDC_BASE 0xFF0AE000
|
||||
#define RK2818_NANDC_PHYS 0x100AE000
|
||||
#define RK2818_NANDC_SIZE SZ_16K
|
||||
|
||||
#define RK2818_SDRAMC_BASE 0xFF0B0000
|
||||
#define RK2818_SDRAMC_PHYS 0x100B0000
|
||||
#define RK2818_SDRAMC_SIZE SZ_8K
|
||||
|
||||
#define RK2818_ARMDARBITER_BASE 0xFF0B4000
|
||||
#define RK2818_ARMDARBITER_PHYS 0x100B4000
|
||||
#define RK2818_ARMDARBITER_SIZE SZ_8K
|
||||
|
||||
#define RK2818_VIDEOCOP_PHYS 0x100B8000
|
||||
#define RK2818_VIDEOCOP_SIZE SZ_8K
|
||||
|
||||
#define RK2818_ESRAM_PHYS 0x100BA000
|
||||
#define RK2818_ESRAM_SIZE SZ_8K
|
||||
|
||||
#define RK2818_USBHOST_PHYS 0x10100000
|
||||
#define RK2818_USBHOST_SIZE SZ_256K
|
||||
|
||||
#define RK2818_UART0_BASE 0xFF100000
|
||||
#define RK2818_UART0_PHYS 0x18000000
|
||||
#define RK2818_UART0_SIZE SZ_4K
|
||||
|
||||
#define RK2818_UART2_BASE 0xFF101000
|
||||
#define RK2818_UART2_PHYS 0x18001000
|
||||
#define RK2818_UART2_SIZE SZ_4K
|
||||
|
||||
#define RK2818_UART1_BASE 0xFF102000
|
||||
#define RK2818_UART1_PHYS 0x18002000
|
||||
#define RK2818_UART1_SIZE SZ_4K
|
||||
|
||||
#define RK2818_UART3_BASE 0xFF103000
|
||||
#define RK2818_UART3_PHYS 0x18003000
|
||||
#define RK2818_UART3_SIZE SZ_4K
|
||||
|
||||
#define RK2818_TIMER_BASE 0xFF104000
|
||||
#define RK2818_TIMER_PHYS 0x18004000
|
||||
#define RK2818_TIMER_SIZE SZ_8K
|
||||
|
||||
#define RK2818_eFUSE_BASE 0xFF106000
|
||||
#define RK2818_eFUSE_PHYS 0x18006000
|
||||
#define RK2818_eFUSE_SIZE SZ_8K
|
||||
|
||||
#define RK2818_GPIO0_BASE 0xFF108000
|
||||
#define RK2818_GPIO0_PHYS 0x18008000
|
||||
#define RK2818_GPIO0_SIZE SZ_8K
|
||||
|
||||
#define RK2818_GPIO1_BASE 0xFF109000
|
||||
#define RK2818_GPIO1_PHYS 0x18009000
|
||||
#define RK2818_GPIO1_SIZE SZ_8K
|
||||
|
||||
#define RK2818_I2S_PHYS 0x1800A000
|
||||
#define RK2818_I2S_SIZE SZ_8K
|
||||
|
||||
#define RK2818_I2C0_PHYS 0x1800C000
|
||||
#define RK2818_I2C0_SIZE SZ_4K
|
||||
|
||||
#define RK2818_I2C1_PHYS 0x1800D000
|
||||
#define RK2818_I2C1_SIZE SZ_4K
|
||||
|
||||
#define RK2818_SPIMASTER_PHYS 0x1800E000
|
||||
#define RK2818_SPIMASTER_SIZE SZ_4K
|
||||
|
||||
#define RK2818_SPISLAVE_BASE 0xFF10F000
|
||||
#define RK2818_SPISLAVE_PHYS 0x1800F000
|
||||
#define RK2818_SPISLAVE_SIZE SZ_4K
|
||||
|
||||
#define RK2818_WDT_BASE 0xFF110000
|
||||
#define RK2818_WDT_PHYS 0x18010000
|
||||
#define RK2818_WDT_SIZE SZ_8K
|
||||
|
||||
#define RK2818_PWM_BASE 0xFF112000
|
||||
#define RK2818_PWM_PHYS 0x18012000
|
||||
#define RK2818_PWM_SIZE SZ_8K
|
||||
|
||||
#define RK2818_RTC_BASE 0xFF114000
|
||||
#define RK2818_RTC_PHYS 0x18014000
|
||||
#define RK2818_RTC_SIZE SZ_8K
|
||||
|
||||
#define RK2818_ADC_BASE 0xFF116000
|
||||
#define RK2818_ADC_PHYS 0x18016000
|
||||
#define RK2818_ADC_SIZE SZ_8K
|
||||
|
||||
#define RK2818_SCU_BASE 0xFF118000
|
||||
#define RK2818_SCU_PHYS 0x18018000
|
||||
#define RK2818_SCU_SIZE SZ_4K
|
||||
|
||||
#define RK2818_REGFILE_BASE 0xFF119000
|
||||
#define RK2818_REGFILE_PHYS 0x18019000
|
||||
#define RK2818_REGFILE_SIZE SZ_4K
|
||||
|
||||
#define RK2818_DSP_PHYS 0x80000000
|
||||
#define RK2818_DSP_SIZE 0x00600000
|
||||
|
||||
#endif
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
|
||||
/*
|
||||
* arch/arm/mach-rk2818/include/mach/rk2818_nand.h
|
||||
*
|
||||
* Copyright (C) 2010 RockChip, Inc.
|
||||
* Author:
|
||||
*
|
||||
* 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 __ASM_ARCH_RK2818_NAND_H
|
||||
#define __ASM_ARCH_RK2818_NAND_H
|
||||
|
||||
|
||||
//BCHCTL寄存器
|
||||
#define BCH_WR 0x0002
|
||||
#define BCH_RST 0x0001
|
||||
//FLCTL寄存器
|
||||
#define FL_RDY (0x1<<20)
|
||||
#define FL_LBA_EN (0x1<<11)
|
||||
#define FL_COR_EN (0x1<<10)
|
||||
#define FL_INT_EN (0x1<<9)
|
||||
#define FL_INTCLR (0x1<<8)
|
||||
#define FL_STMOD (0x1<<7)
|
||||
#define FL_TRCNT (0x3<<5)
|
||||
#define FL_STADDR (0x1<<4)
|
||||
#define FL_BYPASS (0x1<<3)
|
||||
#define FL_START (0x1<<2)
|
||||
#define FL_RDN (0x1<<1)
|
||||
#define FL_RST (0x1<<0)
|
||||
//FMCTL寄存器
|
||||
#define FMC_WP (0x1<<8)
|
||||
#define FMC_FRDY (0x1<<9)
|
||||
#define FMC_FRDY_INT_EN (0x1<<10)
|
||||
#define FMC_FRDY_INT_CLR (0x1<<11)
|
||||
//FMWAIT寄存器
|
||||
#define FMW_RWCS_OFFSET 0
|
||||
#define FMW_RWPW_OFFSET 5
|
||||
#define FMW_RDY (0x1<<11)
|
||||
#define FMW_CSRW_OFFSET 12
|
||||
#define FMW_DLY_OFFSET 16
|
||||
#define FMW_DLY_DBG (0x1<<23)
|
||||
|
||||
struct rk2818_nand_timing {
|
||||
unsigned int tCH; /* Enable signal hold time */
|
||||
unsigned int tCS; /* Enable signal setup time */
|
||||
unsigned int tWH; /* ND_nWE high duration */
|
||||
unsigned int tWP; /* ND_nWE pulse time */
|
||||
unsigned int tRH; /* ND_nRE high duration */
|
||||
unsigned int tRP; /* ND_nRE pulse width */
|
||||
unsigned int tR; /* ND_nWE high to ND_nRE low for read */
|
||||
unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */
|
||||
unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
|
||||
};
|
||||
|
||||
struct rk2818_nand_cmdset {
|
||||
uint16_t read1;
|
||||
uint16_t read2;
|
||||
uint16_t program;
|
||||
uint16_t read_status;
|
||||
uint16_t read_id;
|
||||
uint16_t erase;
|
||||
uint16_t reset;
|
||||
uint16_t lock;
|
||||
uint16_t unlock;
|
||||
uint16_t lock_status;
|
||||
};
|
||||
|
||||
typedef volatile struct tagCHIP_IF
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t addr;
|
||||
uint32_t cmd;
|
||||
uint32_t RESERVED[0x3d];
|
||||
}CHIP_IF, *pCHIP_IF;
|
||||
|
||||
//NANDC Registers
|
||||
typedef volatile struct tagNANDC
|
||||
{
|
||||
volatile uint32_t FMCTL;
|
||||
volatile uint32_t FMWAIT;
|
||||
volatile uint32_t FLCTL;
|
||||
volatile uint32_t BCHCTL;
|
||||
volatile uint32_t BCHST;
|
||||
volatile uint32_t RESERVED1[(0x200-0x14)/4]; //FLR
|
||||
volatile uint32_t spare[0x200/4];
|
||||
volatile uint32_t RESERVED2[0x400/4];
|
||||
volatile CHIP_IF chip[8];
|
||||
volatile uint32_t buf[0x800/4];
|
||||
}NANDC, *pNANDC;
|
||||
|
||||
struct rk2818_nand_flash {
|
||||
const struct rk2818_nand_timing *timing; /* NAND Flash timing */
|
||||
const struct rk2818_nand_cmdset *cmdset;
|
||||
|
||||
uint32_t page_per_block; /* Pages per block (PG_PER_BLK) */
|
||||
uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
|
||||
uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
|
||||
uint32_t num_blocks; /* Number of physical blocks in Flash */
|
||||
uint32_t chip_id;
|
||||
};
|
||||
|
||||
struct rk2818_nand_platform_data {
|
||||
|
||||
int width; /* data bus width in bytes */
|
||||
int hw_ecc; /* 1:hw ecc, 0: soft ecc */
|
||||
struct mtd_partition *parts;
|
||||
unsigned int nr_parts;
|
||||
size_t num_flash;
|
||||
int (*io_init)(void);
|
||||
int (*io_deinit)(void);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ASM_ARCH_RK2818_NAND_H */
|
||||
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
* rockchip-pcm.h - ALSA PCM interface for the Rockchip rk28 SoC
|
||||
*
|
||||
* Driver for rockchip iis audio
|
||||
* Copyright (C) 2009 lhh
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _ROCKCHIP_PM_H
|
||||
#define _ROCKCHIP_PM_H
|
||||
|
||||
/***********************scu SCU_CLKSEL0 reg bit************************************/
|
||||
#define PM_RESUME_BIT 0
|
||||
#define PM_DEBUG_BIT 1
|
||||
#define PM_SET_BIT(b) (1<<b)
|
||||
#define PM_GET_BIT(val,b) ((val&(1<<b))>>b)
|
||||
|
||||
#define PM_BIT_CLEAR(off,b) (~((1<<(b))-1)<<(off))
|
||||
|
||||
|
||||
/***********************scu SCU_CLKSEL0 reg bit************************************/
|
||||
|
||||
#define SCU_GATE0CLK_ALL_EN 0
|
||||
#define SCU_GATE0CLK_ALL_DIS 0XFFFFFFFF
|
||||
#define DIS_RTC_PCLK (1<<27)
|
||||
#define DIS_WDT_PCLK (1<<26)
|
||||
#define DIS_TIMER_CLK (1<<25)
|
||||
#define DIS_PWM_CLK (1<<24)
|
||||
#define DIS_SPI1_CLK (1<<23)
|
||||
#define DIS_SPI0_CLK (1<<22)
|
||||
#define DIS_I2C1_CLK (1<<21)
|
||||
#define DIS_I2C0_CLK (1<<20)
|
||||
#define DIS_UART1_CLK (1<<19)
|
||||
#define DIS_UART0_CLK (1<<18)
|
||||
#define DIS_GPIO1_CLK (1<<17)
|
||||
#define DIS_GPIO0_CLK (1<<16)
|
||||
#define DIS_EMBEDED_ROM_CLK (1<<15)
|
||||
#define DIS_LCDC_CLK (1<<11)
|
||||
#define DIS_DEBLOCK_HCLK (1<<10)
|
||||
#define DIS_INTC_CLK (1<<9)
|
||||
#define DIS_NANDC_HCLK (1<<8)
|
||||
#define DIS_DMA_CLK (1<<2)
|
||||
#define DIS_DSP_CLK (1<<1)
|
||||
#define DIS_ARM_CLK (1<<0)
|
||||
/***********************scu SCU_CLKSEL1_CON reg bit************************************/
|
||||
|
||||
#define SCU_GATE1CLK_ALL_EN 0
|
||||
//#define SCU_GATE1CLK_BASE_SET (0XFFFFFFFF&(~DIS_DDR_CLK)&(~DIS_DDR_HCLK)) // 注意AXI 位为1时为enable
|
||||
|
||||
#define SCU_GATE1CLK_BASE_SET (0XFFFF8001&(~EN_AXI_CLK)) // 注意AXI 位为1时为enable
|
||||
//#define SCU_GATE1CLK_BASE_SET (0XFFFFFFFF)
|
||||
#define EN_AXI_CLK (1<<27)
|
||||
#define DIS_DDR_CLK (1<<23)
|
||||
#define DIS_DDR_HCLK (1<<22)
|
||||
#define DIS_LCDC_HCLK (1<<19)
|
||||
#define DIS_LCDC_SHARE_MEM_CLK (1<<18)
|
||||
#define DIS_MSDRAM_CTR_HCLK (1<<17)
|
||||
#define DIS_SDRAM_CTR_HCLK (1<<16)
|
||||
#define DIS_MAndSDRAM_CMM_HCLK (1<<15)
|
||||
/***********************scu SCU_CLKSEL2_CON reg bit************************************/
|
||||
#define SCU_GATE2CLK_ALL_EN 0
|
||||
#define SCU_GATE2CLK_ALL_DIS 0X3FF
|
||||
#define SCU_GATE2CLK_BASE_SET (SCU_GATE2CLK_ALL_DIS&(~DIS_ARMIBUS_CLK)&(~DIS_ARMDBUS_CLK)&(~DIS_EXPAHBBUS_CLK)&(~DIS_APBBUS_CLK))
|
||||
|
||||
#define DIS_ITCMBUS_CLK (1<<8)
|
||||
#define DIS_DTCM0BUS_CLK (1<<7)
|
||||
#define DIS_DTCM1BUS_CLK (1<<6)
|
||||
|
||||
#define DIS_APBBUS_CLK (1<<4)
|
||||
#define DIS_EXPAHBBUS_CLK (1<<3)
|
||||
#define DIS_ARMDBUS_CLK (1<<1)
|
||||
#define DIS_ARMIBUS_CLK (1<<0)
|
||||
/***********************scu SCU_APLL_CON reg bit************************************/
|
||||
#define ARMPLL_POERDOWN (1<<22)
|
||||
#define ARMPLL_BYPASSMODE (1<<0)
|
||||
/***********************scu SCU_DPLL_CON reg bit************************************/
|
||||
|
||||
#define DSPPLL_POERDOWN (1<<22)
|
||||
|
||||
/***********************scu SCU_CPLL_CON reg bit************************************/
|
||||
#define CPLL_POERDOWN (1<<22)
|
||||
|
||||
/***********************scu PM_SCU_MODE_CON reg bit************************************/
|
||||
#define CPU_SLOW_MODE (~(3<<2))
|
||||
|
||||
|
||||
/***********************scu SCU_PMU_CON reg bit************************************/
|
||||
|
||||
#define LCDC_POWER_DOWN (1<<3)
|
||||
#define DSP_POWER_DOWN (1<<0)
|
||||
#define DDR_POWER_DOWN (1<<2)
|
||||
|
||||
|
||||
/***********************scu PM_SCU_CLKSEL0_CON reg bit************************************/
|
||||
#define CLKSEL0_HCLK (0)
|
||||
#define CLKSEL0_PCLK (2)
|
||||
|
||||
#define CLKSEL0_HCLK21 (0x01<CLKSEL0_HCLK)
|
||||
#define CLKSEL0_PCLK21 (0x01<CLKSEL0_PCLK)
|
||||
|
||||
/***********************scu PM_SCU_SOFTRST_CON] reg bit************************************/
|
||||
#define RST_ALL 0xFFFFFFFF
|
||||
|
||||
#define RST_DDR_BUS (1<<31)
|
||||
#define RST_DDR_CORE_LOGIC (1<<30)
|
||||
|
||||
#define RST_ARM (1<<23)
|
||||
|
||||
enum
|
||||
{
|
||||
PM_SCU_APLL_CON,
|
||||
PM_SCU_DPLL_CON,
|
||||
PM_SCU_CPLL_CON,
|
||||
PM_SCU_MODE_CON,
|
||||
PM_SCU_PMU_CON,
|
||||
PM_SCU_CLKSEL0_CON,
|
||||
PM_SCU_CLKSEL1_CON,
|
||||
PM_SCU_CLKGATE0_CON,
|
||||
PM_SCU_CLKGATE1_CON,
|
||||
PM_SCU_CLKGATE2_CON,
|
||||
PM_SCU_SOFTRST_CON,
|
||||
PM_SCU_CHIPCFG_CON,
|
||||
PM_SCU_CPUPD,
|
||||
PM_CLKSEL2_CON,
|
||||
PM_SCU_REG_NUM
|
||||
};
|
||||
|
||||
/***********************general cpu reg bit************************************/
|
||||
#define RK2818GPIO_TOTAL (PIN_BASE+NUM_GROUP*MAX_GPIO_BANKS)
|
||||
|
||||
/***********************general cpu reg IOMUX_A bit************************************/
|
||||
|
||||
#define PM_I2C0 (30)
|
||||
#define PM_I2C1 (28)
|
||||
#define PM_UART1_OUT (26)
|
||||
#define PM_UART1_IN (24)
|
||||
#define PM_SDIO1_CMD (23)
|
||||
#define PM_SDIO1_DATA (22)
|
||||
#define PM_UART0_OUT (14)
|
||||
#define PM_UART0_IN (12)
|
||||
|
||||
#define PM_SDIO0_CMD (5)
|
||||
#define PM_SDIO0_DATA (4)
|
||||
|
||||
|
||||
|
||||
/***********************general cpu reg IOMUX_B bit************************************/
|
||||
|
||||
#define PM_UART0_RTS (13)
|
||||
#define PM_UART0_CTS (12)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************general cpu reg PU bit************************************/
|
||||
#define CLEAR_IO_PU(pin) (~((3)<<pin))
|
||||
#define PMGPIO_NRO(pin) (0<<pin)
|
||||
#define PMGPIO_UP(pin) (1<<pin)
|
||||
#define PMGPIO_DN(pin) (2<<pin)
|
||||
#define GPIO0_AB_NORMAL (0X0)
|
||||
|
||||
#define GPIO0_A0 (0)
|
||||
#define GPIO0_A3 (6)
|
||||
|
||||
|
||||
#define GPIO0_CD_NORMAL (0X0)
|
||||
#define GPIO1_AB_NORMAL (0X0)
|
||||
#define GPIO1_CD_NORMAL (0X0)
|
||||
|
||||
enum
|
||||
{
|
||||
PM_CPU_APB_REG0,
|
||||
PM_CPU_APB_REG1,
|
||||
PM_CPU_APB_REG2,
|
||||
PM_CPU_APB_REG3,
|
||||
PM_CPU_APB_REG4,
|
||||
PM_CPU_APB_REG5,
|
||||
PM_CPU_APB_REG6,
|
||||
PM_CPU_APB_REG7,
|
||||
PM_IOMUX_A_CON,
|
||||
PM_IOMUX_B_CON,
|
||||
PM_GPIO0_AB_PU_CON,
|
||||
PM_GPIO0_CD_PU_CON,
|
||||
PM_GPIO1_AB_PU_CON,
|
||||
PM_GPIO1_CD_PU_CON,
|
||||
PM_OTGPHY_CON0,
|
||||
PM_OTGPHY_CON1,
|
||||
PM_GENERAL_CPU_REG
|
||||
};
|
||||
/***********************gpio cpu reg bit************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
PM_GPIO_SWPORTA_DR,
|
||||
PM_GPIO_SWPORTA_DDR,
|
||||
PM_GPIO_SWPORTA_NULL,
|
||||
PM_GPIO_SWPORTB_DR,
|
||||
PM_GPIO_SWPORTB_DDR,
|
||||
PM_GPIO_SWPORTB_NULL,
|
||||
PM_GPIO_SWPORTC_DR,
|
||||
PM_GPIO_SWPORTC_DDR,
|
||||
PM_GPIO_SWPORTC_NULL,
|
||||
PM_GPIO_SWPORTD_DR,
|
||||
PM_GPIO_SWPORTD_DDR,
|
||||
PM_SCU_GPIO_SWPORTC_NUM
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/scu.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 __ASM_ARCH_RK2818_SCU_H
|
||||
|
||||
enum scu_clk_gate
|
||||
{
|
||||
/* SCU CLK GATE 0 CON */
|
||||
CLK_GATE_ARM = 0,
|
||||
CLK_GATE_DSP,
|
||||
CLK_GATE_DMA,
|
||||
CLK_GATE_SRAMARM,
|
||||
CLK_GATE_SRAMDSP,
|
||||
CLK_GATE_HIF,
|
||||
CLK_GATE_OTGBUS,
|
||||
CLK_GATE_OTGPHY,
|
||||
CLK_GATE_NANDC,
|
||||
CLK_GATE_INTC,
|
||||
CLK_GATE_DEBLK, /* 10 */
|
||||
CLK_GATE_LCDC,
|
||||
CLK_GATE_VIP, /* as sensor */
|
||||
CLK_GATE_I2S,
|
||||
CLK_GATE_SDMMC0,
|
||||
CLK_GATE_EBROM,
|
||||
CLK_GATE_GPIO0,
|
||||
CLK_GATE_GPIO1,
|
||||
CLK_GATE_UART0,
|
||||
CLK_GATE_UART1,
|
||||
CLK_GATE_I2C0, /* 20 */
|
||||
CLK_GATE_I2C1,
|
||||
CLK_GATE_SPI0,
|
||||
CLK_GATE_SPI1,
|
||||
CLK_GATE_PWM,
|
||||
CLK_GATE_TIMER,
|
||||
CLK_GATE_WDT,
|
||||
CLK_GATE_RTC,
|
||||
CLK_GATE_LSADC,
|
||||
CLK_GATE_UART2,
|
||||
CLK_GATE_UART3, /* 30 */
|
||||
CLK_GATE_SDMMC1,
|
||||
|
||||
/* SCU CLK GATE 1 CON */
|
||||
CLK_GATE_HSADC = 32,
|
||||
CLK_GATE_SDRAM_COMMON = 47,
|
||||
CLK_GATE_SDRAM_CONTROLLER,
|
||||
CLK_GATE_MOBILE_SDRAM_CONTROLLER,
|
||||
CLK_GATE_LCDC_SHARE_MEMORY, /* 50 */
|
||||
CLK_GATE_LCDC_HCLK,
|
||||
CLK_GATE_DEBLK_H264,
|
||||
CLK_GATE_GPU,
|
||||
CLK_GATE_DDR_HCLK,
|
||||
CLK_GATE_DDR,
|
||||
CLK_GATE_CUSTOMIZED_SDRAM_CONTROLLER,
|
||||
CLK_GATE_MCDMA,
|
||||
CLK_GATE_SDRAM,
|
||||
CLK_GATE_DDR_AXI,
|
||||
CLK_GATE_DSP_TIMER, /* 60 */
|
||||
CLK_GATE_DSP_SLAVE,
|
||||
CLK_GATE_DSP_MASTER,
|
||||
CLK_GATE_USB_HOST,
|
||||
|
||||
/* SCU CLK GATE 2 CON */
|
||||
CLK_GATE_ARMIBUS = 64,
|
||||
CLK_GATE_ARMDBUS,
|
||||
CLK_GATE_DSPBUS,
|
||||
CLK_GATE_EXPBUS,
|
||||
CLK_GATE_APBBUS,
|
||||
CLK_GATE_EFUSE,
|
||||
CLK_GATE_DTCM1, /* 70 */
|
||||
CLK_GATE_DTCM0,
|
||||
CLK_GATE_ITCM,
|
||||
CLK_GATE_VIDEOBUS,
|
||||
|
||||
CLK_GATE_MAX,
|
||||
};
|
||||
|
||||
/* Register definitions */
|
||||
#define SCU_APLL_CON 0x00
|
||||
#define SCU_DPLL_CON 0x04
|
||||
#define SCU_CPLL_CON 0x08
|
||||
#define SCU_MODE_CON 0x0c
|
||||
#define SCU_PMU_CON 0x10
|
||||
#define SCU_CLKSEL0_CON 0x14
|
||||
#define SCU_CLKSEL1_CON 0x18
|
||||
#define SCU_CLKGATE0_CON 0x1c
|
||||
#define SCU_CLKGATE1_CON 0x20
|
||||
#define SCU_CLKGATE2_CON 0x24
|
||||
#define SCU_SOFTRST_CON 0x28
|
||||
#define SCU_CHIPCFG_CON 0x2c
|
||||
#define SCU_CPUPD 0x30
|
||||
#define SCU_CLKSEL2_CON 0x34
|
||||
|
||||
#include <asm/tcm.h>
|
||||
|
||||
#define DDR_SAVE_SP do { save_sp = ddr_save_sp((DTCM_END&(~7))); } while (0)
|
||||
#define DDR_RESTORE_SP do { ddr_save_sp(save_sp); } while (0)
|
||||
unsigned long ddr_save_sp( unsigned long new_sp );
|
||||
extern unsigned long save_sp;
|
||||
extern int __tcmdata ddr_disabled;
|
||||
|
||||
/*
|
||||
* delay at itcm. one loops == 6 arm instruction
|
||||
* at 600M,about 6,000,0 for 1ms delay.
|
||||
*/
|
||||
extern void __tcmfunc ddr_pll_delay( int loops ) ;
|
||||
|
||||
/**
|
||||
* tcm_udelay - delay usecs microseconds in tcm
|
||||
* @usecs: in microseconds
|
||||
* @arm_freq_mhz: arm frequency in MHz
|
||||
*
|
||||
* for example when arm run at slow mode, call tcm_udelay(usecs, 24)
|
||||
*/
|
||||
extern void __tcmfunc tcm_udelay(unsigned long usecs, unsigned long arm_freq_mhz);
|
||||
void scu_set_clk_for_reboot( void );
|
||||
void ddr_change_mode( int performance );
|
||||
void change_ddr_freq(int freq_MHZ);
|
||||
extern void kernel_restart(char *cmd);
|
||||
#endif
|
||||
|
|
@ -1,570 +0,0 @@
|
|||
/*
|
||||
defines of FPGA chip ICE65L08's register
|
||||
*/
|
||||
|
||||
#ifndef SPI_UART_H
|
||||
#define SPI_UART_H
|
||||
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#define SPI_FPGA_INT_PIN RK2818_PIN_PA4
|
||||
#define SPI_DPRAM_INT_PIN RK2818_PIN_PA2
|
||||
#define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7
|
||||
#define SPI_FPGA_RST_PIN RK2818_PIN_PF4
|
||||
|
||||
#define SPI_FPGA_POLL_WAIT 0
|
||||
#define SPI_FPGA_TRANS_WORK 1
|
||||
#define SPI_FPGA_TEST_DEBUG 0
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
#define SPI_FPGA_TEST_DEBUG_PIN RK2818_PIN_PE0
|
||||
extern int spi_test_wrong_handle(void);
|
||||
#endif
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
struct uart_icount {
|
||||
__u32 cts;
|
||||
__u32 dsr;
|
||||
__u32 rng;
|
||||
__u32 dcd;
|
||||
__u32 rx;
|
||||
__u32 tx;
|
||||
__u32 frame;
|
||||
__u32 overrun;
|
||||
__u32 parity;
|
||||
__u32 brk;
|
||||
};
|
||||
|
||||
struct spi_uart
|
||||
{
|
||||
struct workqueue_struct *spi_uart_workqueue;
|
||||
struct work_struct spi_uart_work;
|
||||
struct timer_list uart_timer;
|
||||
struct tty_struct *tty;
|
||||
struct kref kref;
|
||||
struct mutex open_lock;
|
||||
struct task_struct *in_spi_uart_irq;
|
||||
struct circ_buf xmit;
|
||||
struct uart_icount icount;
|
||||
spinlock_t write_lock;
|
||||
spinlock_t irq_lock;
|
||||
unsigned int index;
|
||||
unsigned int opened;
|
||||
unsigned int regs_offset;
|
||||
unsigned int uartclk;
|
||||
unsigned int mctrl;
|
||||
unsigned int read_status_mask;
|
||||
unsigned int ignore_status_mask;
|
||||
unsigned char x_char;
|
||||
unsigned char ier;
|
||||
unsigned char lcr;
|
||||
|
||||
};
|
||||
|
||||
struct spi_gpio
|
||||
{
|
||||
struct workqueue_struct *spi_gpio_workqueue;
|
||||
struct work_struct spi_gpio_work;
|
||||
struct workqueue_struct *spi_gpio_irq_workqueue;
|
||||
struct work_struct spi_gpio_irq_work;
|
||||
struct timer_list gpio_timer;
|
||||
struct list_head msg_queue;
|
||||
|
||||
};
|
||||
struct spi_i2c_data
|
||||
{
|
||||
struct i2c_adapter adapter;
|
||||
struct i2c_client *client;
|
||||
struct spi_fpga_port *port;
|
||||
unsigned int speed;
|
||||
unsigned int mode;
|
||||
unsigned int msg_idx;
|
||||
unsigned int msg_num;
|
||||
};
|
||||
struct spi_i2c
|
||||
{
|
||||
struct workqueue_struct *spi_i2c_workqueue;
|
||||
struct work_struct spi_i2c_work;
|
||||
struct timer_list i2c_timer;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *client;
|
||||
spinlock_t i2c_lock ;
|
||||
unsigned char interrupt;
|
||||
unsigned char i2c_data_width[2];
|
||||
unsigned int speed[2];
|
||||
wait_queue_head_t wait_w,wait_r;
|
||||
};
|
||||
|
||||
struct spi_dpram
|
||||
{
|
||||
struct workqueue_struct *spi_dpram_workqueue;
|
||||
struct work_struct spi_dpram_work;
|
||||
struct workqueue_struct *spi_dpram_irq_workqueue;
|
||||
struct work_struct spi_dpram_irq_work;
|
||||
struct timer_list dpram_timer;
|
||||
unsigned char *prx;
|
||||
unsigned char *ptx;
|
||||
unsigned int rec_len;
|
||||
unsigned int send_len;
|
||||
unsigned int max_rec_len;
|
||||
unsigned int max_send_len;
|
||||
volatile int apwrite_en;
|
||||
unsigned short int dpram_addr;
|
||||
struct semaphore rec_sem;
|
||||
struct semaphore send_sem;
|
||||
struct mutex rec_lock,send_lock;
|
||||
spinlock_t spin_rec_lock,spin_send_lock;
|
||||
wait_queue_head_t recq, sendq;
|
||||
struct miscdevice miscdev;
|
||||
|
||||
int (*write_dpram)(struct spi_dpram *, unsigned short int addr, unsigned char *buf, unsigned int len);
|
||||
int (*read_dpram)(struct spi_dpram *, unsigned short int addr, unsigned char *buf, unsigned int len);
|
||||
int (*write_ptr)(struct spi_dpram *, unsigned short int addr, unsigned int size);
|
||||
int (*read_ptr)(struct spi_dpram *, unsigned short int addr);
|
||||
int (*write_irq)(struct spi_dpram *, unsigned int mailbox);
|
||||
int (*read_irq)(struct spi_dpram *);
|
||||
int (*write_ack)(struct spi_dpram *, unsigned int mailbox);
|
||||
int (*read_ack)(struct spi_dpram *);
|
||||
|
||||
};
|
||||
|
||||
struct spi_fpga_port {
|
||||
const char *name;
|
||||
struct spi_device *spi;
|
||||
spinlock_t work_lock;
|
||||
struct mutex spi_lock;
|
||||
struct workqueue_struct *fpga_irq_workqueue;
|
||||
struct work_struct fpga_irq_work;
|
||||
struct timer_list fpga_timer;
|
||||
#if SPI_FPGA_TRANS_WORK
|
||||
struct workqueue_struct *fpga_trans_workqueue;
|
||||
struct work_struct fpga_trans_work;
|
||||
int write_en;
|
||||
int read_en;
|
||||
wait_queue_head_t wait_wq, wait_rq;
|
||||
struct list_head trans_queue;
|
||||
#endif
|
||||
|
||||
#if SPI_FPGA_POLL_WAIT
|
||||
wait_queue_head_t spi_wait_q;
|
||||
#endif
|
||||
|
||||
/*spi2uart*/
|
||||
#ifdef CONFIG_SPI_FPGA_UART
|
||||
struct spi_uart uart;
|
||||
#endif
|
||||
/*spi2gpio*/
|
||||
#ifdef CONFIG_SPI_FPGA_GPIO
|
||||
struct spi_gpio gpio;
|
||||
#endif
|
||||
/*spi2i2c*/
|
||||
#ifdef CONFIG_SPI_FPGA_I2C
|
||||
struct spi_i2c i2c;
|
||||
#endif
|
||||
/*spi2dpram*/
|
||||
#ifdef CONFIG_SPI_FPGA_DPRAM
|
||||
struct spi_dpram dpram;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define ICE_CC72 0
|
||||
#define ICE_CC196 1
|
||||
#define FPGA_TYPE ICE_CC196
|
||||
#define SEL_UART 0
|
||||
#define SEL_GPIO 1
|
||||
#define SEL_I2C 2
|
||||
#define SEL_DPRAM 3
|
||||
#define READ_TOP_INT 4
|
||||
|
||||
/* CMD */
|
||||
#define ICE_SEL_UART (SEL_UART<<6)
|
||||
#define ICE_SEL_GPIO (SEL_GPIO<<6)
|
||||
#define ICE_SEL_I2C (SEL_I2C<<6)
|
||||
#define ICE_SEL_DPRAM (SEL_DPRAM<<6)
|
||||
|
||||
#define ICE_SEL_WRITE (~(1<<5))
|
||||
#define ICE_SEL_READ (1<<5)
|
||||
|
||||
#define ICE_SEL_UART_CH(ch) ((ch&0x03)<<3)
|
||||
#define ICE_SEL_READ_INT_TYPE (3<<3)
|
||||
|
||||
/*read int type*/
|
||||
#define ICE_INT_TYPE_UART0 (~(1<<0))
|
||||
#define ICE_INT_TYPE_UART1 (~(1<<1))
|
||||
#define ICE_INT_TYPE_UART2 (~(1<<2))
|
||||
#define ICE_INT_TYPE_I2C2 (~(1<<3))
|
||||
#define ICE_INT_TYPE_I2C3 (~(1<<4))
|
||||
#define ICE_INT_TYPE_GPIO (~(1<<5))
|
||||
#define ICE_INT_TYPE_DPRAM (~(1<<6))
|
||||
#define ICE_INT_TYPE_SLEEP (~(1<<7))
|
||||
|
||||
#define ICE_INT_I2C_ACK (~(1<<0))
|
||||
#define ICE_INT_I2C_READ (~(1<<1))
|
||||
#define ICE_INT_I2C_WRITE (~(1<<2))
|
||||
|
||||
/*spi to uart*/
|
||||
#define ICE_RXFIFO_FULL (1<<8)
|
||||
#define ICE_RXFIFO_NOT_FULL (~(1<<8))
|
||||
#define ICE_RXFIFO_EMPTY (1<<9)
|
||||
#define ICE_RXFIFO_NOT_EMPTY (~(1<<9))
|
||||
#define ICE_TXFIFO_FULL (1<<10)
|
||||
#define ICE_TXFIFO_NOT_FULL (~(1<<10))
|
||||
#define ICE_TXFIFO_EMPTY (1<<11)
|
||||
#define ICE_TXFIFO_NOT_EMPTY (~(1<<11))
|
||||
|
||||
|
||||
/*spi to gpio*/
|
||||
#define ICE_SEL_GPIO0 (0X00<<3) //INT/GPIO0
|
||||
#define ICE_SEL_GPIO1 (0X02<<2) //GPIO1
|
||||
#define ICE_SEL_GPIO2 (0X03<<2)
|
||||
#define ICE_SEL_GPIO3 (0X04<<2)
|
||||
#define ICE_SEL_GPIO4 (0X05<<2)
|
||||
#define ICE_SEL_GPIO5 (0X06<<2)
|
||||
|
||||
#define ICE_SEL_GPIO0_TYPE (0X00)
|
||||
#define ICE_SEL_GPIO0_DIR (0X01)
|
||||
#define ICE_SEL_GPIO0_DATA (0X02)
|
||||
#define ICE_SEL_GPIO0_INT_EN (0X03)
|
||||
#define ICE_SEL_GPIO0_INT_TRI (0X04) //0:falling edge 1:rising edge
|
||||
#define ICE_SEL_GPIO0_INT_STATE (0X05)
|
||||
#define ICE_SEL_GPIO0_INT_TYPE (0X06) //0:edge 1:level,if 1 then support falling and rising trigger
|
||||
#define ICE_SEL_GPIO0_INT_WAKE (0X07)
|
||||
|
||||
#define ICE_SEL_GPIO_DIR (0X01)
|
||||
#define ICE_SEL_GPIO_DATA (0X02)
|
||||
|
||||
#define ICE_STATUS_SLEEP 1
|
||||
#define ICE_STATUS_WAKE 0
|
||||
|
||||
/*spi to i2c*/
|
||||
|
||||
typedef enum I2C_ch
|
||||
{
|
||||
I2C_CH0,
|
||||
I2C_CH1,
|
||||
I2C_CH2,
|
||||
I2C_CH3
|
||||
}eI2C_ch_t;
|
||||
typedef enum eI2CReadMode
|
||||
{
|
||||
I2C_NORMAL,
|
||||
I2C_NO_REG,
|
||||
I2C_NO_STOP
|
||||
}eI2ReadMode_t;
|
||||
|
||||
#define ICE_SEL_I2C_START (0<<0)
|
||||
#define ICE_SEL_I2C_STOP (1<<0)
|
||||
#define ICE_SEL_I2C_RESTART (2<<0)
|
||||
#define ICE_SEL_I2C_TRANS (3<<0)
|
||||
#define ICE_SEL_I2C_SMASK (~(3<<0))
|
||||
#define ICE_SEL_I2C_CH2 (0<<2)
|
||||
#define ICE_SEL_I2C_CH3 (1<<2)
|
||||
#define ICE_SEL_I2C_DEFMODE (0<<3)
|
||||
#define ICE_SEL_I2C_FIFO (1<<3)
|
||||
#define ICE_SEL_I2C_SPEED (2<<3)
|
||||
#define ICE_SEL_I2C_INT (3<<3)
|
||||
#define ICE_SEL_I2C_MMASK (~(3<<3))
|
||||
|
||||
#define ICE_I2C_SLAVE_WRITE (0<<0)
|
||||
#define ICE_I2C_SLAVE_READ (1<<0)
|
||||
|
||||
|
||||
|
||||
#define ICE_SEL_I2C_W8BIT (0<<2)
|
||||
#define ICE_SEL_I2C_W16BIT (1<<2)
|
||||
#define ICE_SEL_I2C_DWIDTH (2<<2)
|
||||
|
||||
#define ICE_I2C_AD_ACK (~(1<<0))
|
||||
#define ICE_I2C_WRITE_ACK (~(1<<1))
|
||||
#define ICE_I2C_READ_ACK (~(1<<2))
|
||||
|
||||
#define ICE_SEL_I2C_CH2_8BIT (0<<2)
|
||||
#define ICE_SEL_I2C_CH2_16BIT (1<<2)
|
||||
#define ICE_SEL_I2C_CH2_MIX (2<<2)
|
||||
|
||||
#define ICE_SEL_I2C_CH3_8BIT (4<<2)
|
||||
#define ICE_SEL_I2C_CH3_16BIT (5<<2)
|
||||
#define ICE_SEL_I2C_CH3_MIX (6<<2)
|
||||
#define ICE_SEL_I2C_RD_A (7<<2)
|
||||
#define ICE_SEL_I2C_MASK (7<<2)
|
||||
#define ICE_SEL_I2C_ACK3 (1<<1)
|
||||
#define ICE_SEL_I2C_ACK2 (0<<1)
|
||||
|
||||
#define INT_I2C_WRITE_ACK (2)
|
||||
#define INT_I2C_WRITE_NACK (3)
|
||||
#define INT_I2C_READ_ACK (4)
|
||||
#define INT_I2C_READ_NACK (5)
|
||||
#define INT_I2C_WRITE_MASK (~(1<<1))
|
||||
#define INT_I2C_READ_MASK (~(1<<2))
|
||||
|
||||
#define ICE_SET_10K_I2C_SPEED (0x01)
|
||||
#define ICE_SET_100K_I2C_SPEED (0x02)
|
||||
#define ICE_SET_200K_I2C_SPEED (0x04)
|
||||
#define ICE_SET_300K_I2C_SPEED (0x08)
|
||||
#define ICE_SET_400K_I2C_SPEED (0x10)
|
||||
|
||||
|
||||
/*spi to dpram*/
|
||||
#define ICE_SEL_DPRAM_NOMAL (~(1<<5))
|
||||
#define ICE_SEL_DPRAM_SEM (1<<5)
|
||||
#define ICE_SEL_DPRAM_READ (~(1<<4))
|
||||
#define ICE_SEL_DPRAM_WRITE (1<<4)
|
||||
#define ICE_SEL_DPRAM_BL1 (0)
|
||||
#define ICE_SEL_DPRAM_BL32 (1)
|
||||
#define ICE_SEL_DPRAM_BL64 (2)
|
||||
#define ICE_SEL_DPRAM_BL128 (3)
|
||||
#define ICE_SEL_DPRAM_FULL (4)
|
||||
|
||||
#define ICE_SEL_SEM_WRITE (0x7F)
|
||||
#define ICE_SEL_SEM_READ (0xBF)
|
||||
#define ICE_SEL_SEM_WRRD (0x3F)
|
||||
|
||||
typedef void (*pSpiFunc)(void); //定义函数指针, 用于调用绝对地址
|
||||
typedef void (*pSpiFuncIntr)(int,void *);
|
||||
typedef struct
|
||||
{
|
||||
pSpiFuncIntr gpio_vector;
|
||||
void *gpio_devid;
|
||||
}SPI_GPIO_PDATA;
|
||||
|
||||
|
||||
typedef enum eSpiGpioTypeSel
|
||||
{
|
||||
SPI_GPIO0_IS_GPIO = 0,
|
||||
SPI_GPIO0_IS_INT,
|
||||
}eSpiGpioTypeSel_t;
|
||||
|
||||
|
||||
|
||||
typedef enum eSpiGpioPinInt
|
||||
{
|
||||
SPI_GPIO_INT_DISABLE = 0,
|
||||
SPI_GPIO_INT_ENABLE,
|
||||
}eSpiGpioPinInt_t;
|
||||
|
||||
|
||||
typedef enum eSpiGpioIntTri
|
||||
{
|
||||
SPI_GPIO_EDGE_FALLING = 0,
|
||||
SPI_GPIO_EDGE_RISING,
|
||||
}eSpiGpioIntTri_t;
|
||||
|
||||
|
||||
typedef enum eSpiGpioIntType
|
||||
{
|
||||
SPI_GPIO_EDGE = 0,
|
||||
SPI_GPIO_LEVEL,
|
||||
}eSpiGpioIntType_t;
|
||||
|
||||
typedef enum eSpiGpioPinDirection
|
||||
{
|
||||
SPI_GPIO_IN = 0,
|
||||
SPI_GPIO_OUT,
|
||||
SPI_GPIO_DIR_ERR,
|
||||
}eSpiGpioPinDirection_t;
|
||||
|
||||
|
||||
typedef enum eSpiGpioPinLevel
|
||||
{
|
||||
SPI_GPIO_LOW = 0,
|
||||
SPI_GPIO_HIGH,
|
||||
SPI_GPIO_LEVEL_ERR,
|
||||
}eSpiGpioPinLevel_t;
|
||||
|
||||
#if (FPGA_TYPE == ICE_CC72)
|
||||
typedef enum eSpiGpioPinNum
|
||||
{
|
||||
SPI_GPIO_P0_00 = 0, //GPIO0[0]
|
||||
SPI_GPIO_P0_01,
|
||||
SPI_GPIO_P0_02,
|
||||
SPI_GPIO_P0_03,
|
||||
SPI_GPIO_P0_04,
|
||||
SPI_GPIO_P0_05,
|
||||
|
||||
SPI_GPIO_P2_00,
|
||||
SPI_GPIO_P2_01,
|
||||
SPI_GPIO_P2_02,
|
||||
SPI_GPIO_P2_03,
|
||||
SPI_GPIO_P2_04,
|
||||
SPI_GPIO_P2_05,
|
||||
SPI_GPIO_P2_06,
|
||||
SPI_GPIO_P2_07,
|
||||
SPI_GPIO_P2_08,
|
||||
SPI_GPIO_P2_09 = 15, //GPIO0[15],the last interrupt/gpio pin
|
||||
|
||||
SPI_GPIO_P3_00 = 16, //GPIO1[0]
|
||||
SPI_GPIO_P3_01,
|
||||
SPI_GPIO_P3_02,
|
||||
SPI_GPIO_P3_03,
|
||||
SPI_GPIO_P3_04,
|
||||
SPI_GPIO_P3_05,
|
||||
SPI_GPIO_P3_06,
|
||||
SPI_GPIO_P3_07,
|
||||
SPI_GPIO_P3_08,
|
||||
SPI_GPIO_P3_09,
|
||||
SPI_GPIO_P0_06 = 26,
|
||||
SPI_GPIO_I2C3_SCL,
|
||||
SPI_GPIO_I2C3_SDA,
|
||||
SPI_GPIO_I2C4_SCL,
|
||||
SPI_GPIO_I2C4_SDA,
|
||||
|
||||
}eSpiGpioPinNum_t;
|
||||
|
||||
#elif (FPGA_TYPE == ICE_CC196)
|
||||
|
||||
typedef enum eSpiGpioPinNum
|
||||
{
|
||||
//GPIO0/INT
|
||||
SPI_GPIO_P6_00 = 0, //HS_DET input
|
||||
SPI_GPIO_P6_01,
|
||||
SPI_GPIO_P6_02,
|
||||
SPI_GPIO_P6_03,
|
||||
SPI_GPIO_P6_04, //CM3605_POUT_L_INT input
|
||||
SPI_GPIO_P6_05,
|
||||
SPI_GPIO_P6_06, //CHG_OK input
|
||||
SPI_GPIO_P6_07, //HP_HOOK input
|
||||
SPI_GPIO_P6_08,
|
||||
SPI_GPIO_P6_09,
|
||||
SPI_GPIO_P6_10, //DEFSEL input
|
||||
SPI_GPIO_P6_11, //FLASH_WP_INT input
|
||||
SPI_GPIO_P6_12, //LOW_BATT_INT input
|
||||
SPI_GPIO_P6_13, //DC_DET input
|
||||
SPI_GPIO_P3_08,
|
||||
SPI_GPIO_P3_09 = 15,
|
||||
|
||||
//GPIO1
|
||||
SPI_GPIO_P1_00 = 16, //LCD_ON output
|
||||
SPI_GPIO_P1_01, //LCD_PWR_CTRL output
|
||||
SPI_GPIO_P1_02, //SD_POW_ON output
|
||||
SPI_GPIO_P1_03, //WL_RST_N/WIFI_EN output
|
||||
SPI_GPIO_P1_04, //HARDO,input
|
||||
SPI_GPIO_P1_05, //SENSOR_PWDN output
|
||||
SPI_GPIO_P1_06, //BT_PWR_EN output
|
||||
SPI_GPIO_P1_07, //BT_RST output
|
||||
SPI_GPIO_P1_08, //BT_WAKE_B output
|
||||
SPI_GPIO_P1_09, //LCD_DISP_ON output
|
||||
SPI_GPIO_P1_10, //WM_PWR_EN output
|
||||
SPI_GPIO_P1_11, //HARD1,input
|
||||
SPI_GPIO_P1_12, //VIB_MOTO output
|
||||
SPI_GPIO_P1_13, //KEYLED_EN output
|
||||
SPI_GPIO_P1_14, //CAM_RST output
|
||||
SPI_GPIO_P1_15 = 31, //WL_WAKE_B output
|
||||
|
||||
//GPIO2
|
||||
SPI_GPIO_P2_00 = 32, //Y+YD input
|
||||
SPI_GPIO_P2_01, //Y-YU input
|
||||
SPI_GPIO_P2_02, //AP_TD_UNDIFED input
|
||||
SPI_GPIO_P2_03, //AP_PW_EN_TD output
|
||||
SPI_GPIO_P2_04, //AP_RESET_TD output
|
||||
SPI_GPIO_P2_05, //AP_SHUTDOWN_TD_PMU output
|
||||
SPI_GPIO_P2_06, //AP_RESET_CMMB output
|
||||
SPI_GPIO_P2_07, //AP_CHECK_TD_STATUS input
|
||||
SPI_GPIO_P2_08, //CHARGE_CURRENT_SEL output
|
||||
SPI_GPIO_P2_09, //AP_PWD_CMMB output
|
||||
SPI_GPIO_P2_10, //X-XL input
|
||||
SPI_GPIO_P2_11, //X+XR input
|
||||
SPI_GPIO_P2_12, //LCD_RESET output
|
||||
SPI_GPIO_P2_13, //USB_PWR_EN output
|
||||
SPI_GPIO_P2_14, //WL_HOST_WAKE_B output
|
||||
SPI_GPIO_P2_15 = 47, //TOUCH_SCREEN_RST output
|
||||
|
||||
//GPIO3
|
||||
SPI_GPIO_P0_00 = 48, //
|
||||
SPI_GPIO_P0_01,
|
||||
SPI_GPIO_P0_02,
|
||||
SPI_GPIO_P0_03,
|
||||
SPI_GPIO_P0_04,
|
||||
SPI_GPIO_P0_05,
|
||||
SPI_GPIO_P0_06,
|
||||
SPI_GPIO_P0_07,
|
||||
SPI_GPIO_P0_08,
|
||||
SPI_GPIO_P0_09, //FPGA小板该引脚未引出 C5
|
||||
SPI_GPIO_P0_10,
|
||||
SPI_GPIO_P0_11,
|
||||
SPI_GPIO_P0_12,
|
||||
SPI_GPIO_P0_13,
|
||||
SPI_GPIO_P0_14,
|
||||
SPI_GPIO_P0_15 = 63,
|
||||
|
||||
//GPIO4
|
||||
SPI_GPIO_P4_00 = 64,
|
||||
SPI_GPIO_P4_01,
|
||||
SPI_GPIO_P4_02,
|
||||
SPI_GPIO_P4_03,
|
||||
SPI_GPIO_P4_04,
|
||||
SPI_GPIO_P4_05,
|
||||
SPI_GPIO_P4_06, //CHARGER_INT_END input
|
||||
SPI_GPIO_P4_07, //CM3605_PWD output
|
||||
SPI_GPIO_P3_00,
|
||||
SPI_GPIO_P3_01,
|
||||
SPI_GPIO_P3_02,
|
||||
SPI_GPIO_P3_03,
|
||||
SPI_GPIO_P3_04,
|
||||
SPI_GPIO_P3_05,
|
||||
SPI_GPIO_P3_06,
|
||||
SPI_GPIO_P3_07 = 79,
|
||||
|
||||
//GPIO5
|
||||
SPI_GPIO_P4_08 = 80, //CM3605_PS_SHUTDOWN
|
||||
SPI_GPIO_P0_TXD2, //temp
|
||||
|
||||
}eSpiGpioPinNum_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum eSpiGpioPinIntIsr
|
||||
{
|
||||
SPI_GPIO_IS_INT = 0,
|
||||
SPI_GPIO_NO_INT,
|
||||
}eSpiGpioPinIntIsr_t;
|
||||
|
||||
extern struct spi_fpga_port *pFpgaPort;
|
||||
#if SPI_FPGA_TRANS_WORK
|
||||
extern int spi_write_work(struct spi_device *spi, u8 *buf, size_t len);
|
||||
#endif
|
||||
extern unsigned int spi_in(struct spi_fpga_port *port, int reg, int type);
|
||||
extern void spi_out(struct spi_fpga_port *port, int reg, int value, int type);
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_UART)
|
||||
extern void spi_uart_handle_irq(struct spi_device *spi);
|
||||
extern int spi_uart_register(struct spi_fpga_port *port);
|
||||
extern int spi_uart_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
extern int spi_gpio_int_sel(eSpiGpioPinNum_t PinNum,eSpiGpioTypeSel_t type);
|
||||
extern int spi_gpio_set_pindirection(eSpiGpioPinNum_t PinNum,eSpiGpioPinDirection_t direction);
|
||||
extern int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t PinLevel);
|
||||
extern eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum);
|
||||
extern int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum);
|
||||
extern int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum);
|
||||
extern int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntTri_t IntTri);
|
||||
extern int spi_gpio_read_iir(void);
|
||||
extern int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntTri_t IntType,void *dev_id);
|
||||
extern int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum);
|
||||
extern int spi_gpio_handle_irq(struct spi_device *spi);
|
||||
extern int spi_gpio_init(void);
|
||||
extern void spi_gpio_irq_setup(void);
|
||||
extern int spi_gpio_register(struct spi_fpga_port *port);
|
||||
extern int spi_gpio_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
extern int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel);
|
||||
extern int spi_i2c_register(struct spi_fpga_port *port,int num);
|
||||
extern int spi_i2c_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
extern int spi_dpram_handle_ack(struct spi_device *spi);
|
||||
extern int spi_dpram_register(struct spi_fpga_port *port);
|
||||
extern int spi_dpram_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_FW)
|
||||
extern int __init fpga_dl_fw(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/system.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.
|
||||
*
|
||||
*/
|
||||
|
||||
/***************
|
||||
* DEBUG
|
||||
****************/
|
||||
#define RESTART_DEBUG
|
||||
#ifdef RESTART_DEBUG
|
||||
#define restart_dbg(format, arg...) \
|
||||
printk("RESTART_DEBUG : " format "\n" , ## arg)
|
||||
#else
|
||||
#define restart_dbg(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RK2818_POWER
|
||||
extern int rk2818_restart( int mode, const char *cmd) ;
|
||||
|
||||
static inline void arch_reset(int mode, const char *cmd)
|
||||
{
|
||||
|
||||
/*
|
||||
* debug trace
|
||||
*/
|
||||
restart_dbg("%s->%s->%d->mode=%d cmd=%s",__FILE__,__FUNCTION__,__LINE__,mode,cmd);
|
||||
rk2818_restart( mode, cmd) ;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void arch_reset(int mode, const char *cmd)
|
||||
{
|
||||
|
||||
/*
|
||||
* debug trace
|
||||
*/
|
||||
restart_dbg("%s->%s->%d->mode=%c cmd=%s",__FILE__,__FUNCTION__,__LINE__,mode,cmd);
|
||||
printk("Can't reboot. Please open rk2818 power manage!!\n");
|
||||
for(;;);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void arch_idle(void)
|
||||
{
|
||||
cpu_do_idle();
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/timex.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 __ASM_ARCH_RK2818_TIMEX_H
|
||||
#define __ASM_ARCH_RK2818_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE 1000000
|
||||
|
||||
#endif
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/uncompress.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 __ASM_ARCH_RK2818_UNCOMPRESS_H
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
static void putc(int c)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void flush(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void arch_decomp_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void arch_decomp_wdog(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* arch/arm/mach-rk2818/include/mach/vmalloc.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 __ASM_ARCH_RK2818_VMALLOC_H
|
||||
#define __ASM_ARCH_RK2818_VMALLOC_H
|
||||
|
||||
#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* linux/include/asm-arm/arch-rk2818/vreg.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 __ARCH_ARM_MACH_RK2818_VREG_H
|
||||
#define __ARCH_ARM_MACH_RK2818_VREG_H
|
||||
|
||||
struct vreg;
|
||||
|
||||
struct vreg *vreg_get(struct device *dev, const char *id);
|
||||
void vreg_put(struct vreg *vreg);
|
||||
|
||||
int vreg_enable(struct vreg *vreg);
|
||||
void vreg_disable(struct vreg *vreg);
|
||||
int vreg_set_level(struct vreg *vreg, unsigned mv);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-rk2818/iomux.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/init.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
|
||||
#define RK2818_IOMUX_A_CON (RK2818_REGFILE_BASE + IOMUX_A_CON)
|
||||
#define RK2818_IOMUX_B_CON (RK2818_REGFILE_BASE + IOMUX_B_CON)
|
||||
|
||||
static struct mux_config rk2818_muxs[] = {
|
||||
/*
|
||||
* description mux mode mux mux
|
||||
* reg offset inter mode
|
||||
*/
|
||||
MUX_CFG(GPIOE_I2C0_SEL_NAME, A, 30, 2, 0, DEFAULT) /* 0: i2c0_sda/scl gpioe_u1ir_i2c1 */
|
||||
MUX_CFG(GPIOE_U1IR_I2C1_NAME, A, 28, 2, 0, DEFAULT) /* 00 : gpio_e6/e7 01 gpiof1_uart1_cpwm1_out_n 10 : i2c1_sda/scl */
|
||||
MUX_CFG(GPIOF1_UART1_CPWM1_NAME, A, 26, 2, 1, DEFAULT) /* 00 : gpio_f1 01 : uart1_sout 10 : cx_timer1_pwm */
|
||||
MUX_CFG(GPIOF0_UART1_CPWM0_NAME, A, 24, 2, 1, DEFAULT) /* 00 : gpio_f0 01 : uart1_sin 10 : cx_timer0_pwm */
|
||||
MUX_CFG(GPIOG_MMC1_SEL_NAME, A, 23, 1, 0, DEFAULT) /* 0 : gpio_g2/g3/g7 1: sdmmc1_cmd/data0/clkout */
|
||||
MUX_CFG(GPIOG_MMC1D_SEL_NAME, A, 22, 1, 0, DEFAULT) /* 0 : gpio_g4/g5/g6 1 : sdmmc1_data1/data2/data3 */
|
||||
MUX_CFG(GPIOE_SPI1_FLASH_SEL_NAME, A, 20, 2, 0, DEFAULT) /* 00 : gpio_e1/e2/e3/f7 01 : spi1_clkin/spi1_ss_in_n/spi1_rxd/spi1_txd 10 :flash_cs6 / flash_cs7*/
|
||||
MUX_CFG(GPIOE_SPI1_FLASH_SEL1_NAME, A, 18, 2, 0, DEFAULT) /*00 : gpio1_a1/a2 01 : spi1_clkin/spi1_ss_in_n 10 : flash_cs4 / flash_cs5 */
|
||||
MUX_CFG(GPIOB0_SPI0CSN1_MMC1PCA_NAME, A, 16, 2, 0, DEFAULT) /* 00 : gpio_b0 01 : spi0_csn1 10 : sdmmc1_pwr_en */
|
||||
MUX_CFG(GPIOG1_UART0_MMC1WPT_NAME, A, 14, 2, 0, DEFAULT) /* 00 : gpio_g1 01 : uart0_sout 10 : sdmmc1_write_prt */
|
||||
MUX_CFG(GPIOG0_UART0_MMC1DET_NAME, A, 12, 2, 0, DEFAULT) /* 00 : gpio_g0 01 : uart0_sin 10 : sdmmc1_detect_n */
|
||||
MUX_CFG(GPIOF4_APWM2_MMC0WPT_NAME, A, 10, 2, 0, DEFAULT) /* 00 : gpio_f4 01 : pwm2 10 : sdmmc0_write_prt */
|
||||
MUX_CFG(GPIOF3_APWM1_MMC0DETN_NAME, A, 8, 2, 0, DEFAULT) /* 00 : gpio_f3 01 : pwm1 10 : sdmmc0_detect_n */
|
||||
MUX_CFG(GPIOB1_SMCS1_MMC0PCA_NAME, A, 6, 2, 0, DEFAULT) /* 00 : gpio_b1 01 : sm_cs1_n 10 : sdmmc0_pwr_en */
|
||||
MUX_CFG(GPIOH_MMC0D_SEL_NAME, A, 5, 1, 0, DEFAULT) /* 0 : gpio_h2/h3/h4 1 : sdmm0_data1/data2/data3 */
|
||||
MUX_CFG(GPIOH_MMC0_SEL_NAME, A, 4, 1, 0, DEFAULT) /* 0 : gpio_h0/h1/h5 1 : sdmmc0_cmd/data0/clkout */
|
||||
MUX_CFG(GPIOB_SPI0_MMC0_NAME, A, 2, 2, 0, DEFAULT) /* 00 : gpio_b5/b6/b7 01 : spi0_clkout/spi0_txd/spi0_rxd 10 : sdmmc0_data5/data6/data7 */
|
||||
MUX_CFG(GPIOB4_SPI0CS0_MMC0D4_NAME, A, 0, 2, 0, DEFAULT) /* 00 : gpio_b4 01 : spi0_csn0 10 : sdmmc0_data4 */
|
||||
|
||||
MUX_CFG(GPIOF34_UART3_SEL_NAME, B, 31, 1, 0, DEFAULT) /*0 : gpio1_b3 / gpio1_b4 function is decided by gpio1b3_apwm1_mmc0detn(IOMUX_A_CON[9:8]) and gpio1b4_apwm2_mmc0wpt(IOMUX_A_CON[11:10] separately 1 : uart3_sin / uart3_sout*/
|
||||
MUX_CFG(GPIOF01_UART2_SEL_NAME, B, 30, 1, 0, DEFAULT) /*0 : gpio0_b0 / gpio0_b1 function is decided by gpio0b0_spi0csn1_mmc1pca(IOMUX_A_CON [17:16]) and gpio0b1_smcs1_mmc0pca(IOMUX_A_CON [7:6] separately 1 : uart2_sin / uart2_sout */
|
||||
MUX_CFG(GPIOA23_UART2_SEL_NAME, B, 29, 1, 0, DEFAULT) /*0 : gpio0_a2/gpio0_a3 1 : uart2_cts_n / uart2_rts_n */
|
||||
MUX_CFG(CXGPIO_HSADC_NORFLASH_SEL_NAME, B, 27, 2, 0, DEFAULT) /*00 : gpio2_22 ~ gpio2_23 01 : hsadc_data_q[9:8] 10 : sm_we_n/sm_oe_n */
|
||||
MUX_CFG(CXGPIO_HSADC_HIF_SEL_NAME, B, 25, 2, 0, DEFAULT) /*00 : gpio2_14 ~ gpio2_21 01 : hsadc_data_q[7:0] 10 : host_data[15:8]*/
|
||||
MUX_CFG(GPIOA1_HOSTDATA17_SEL_NAME, B, 24, 1, 0, DEFAULT) /*0 : gpio0_a1 1: host data 17 */
|
||||
MUX_CFG(GPIOA0_HOSTDATA16_SEL_NAME, B, 23, 1, 0, DEFAULT) /*0 : gpio0_a0 1: host data 16 */
|
||||
MUX_CFG(GPIOE0_VIPDATA0_SEL_NAME, B, 22, 1, 0, DEFAULT) /*0: gpio1_a0 1: vip_data0 */
|
||||
MUX_CFG(CXGPIO_GPSCLK_HSADCCLKOUT_NAME, B, 20, 2, 0, DEFAULT) /* 00 : gpio2_24 01 : gps clk 10 : hsadc_clkout */
|
||||
MUX_CFG(HSADCDATA_TSCON_SEL_NAME, B, 19, 1, 0, DEFAULT) /* 0: hsadc_data_i[9:8] 1: ts_fail / ts_valid */
|
||||
MUX_CFG(GPIOA7_FLASHCS3_SEL_NAME, B, 18, 1, 0, DEFAULT) /* 0 : gpio_a7 1 : flash_cs3 */
|
||||
MUX_CFG(GPIOA6_FLASHCS2_SEL_NAME, B, 17, 1, 0, DEFAULT) /* 0 : gpio_a6 1 : flash_cs2 */
|
||||
MUX_CFG(GPIOA5_FLASHCS1_SEL_NAME, B, 16, 1, 0, DEFAULT) /* 0 : gpio_a5 1 : flash_cs1 */
|
||||
MUX_CFG(GPIOF5_APWM3_DPWM3_NAME, B, 14, 2, 0, DEFAULT) /* 00 : gpio_f5 01 : pwm3 10 : demod pwm out */
|
||||
MUX_CFG(GPIOB3_U0RTSN_SEL_NAME, B, 13, 1, 0, DEFAULT) /* 0 : gpio_b3 1 : uart0_rts_n */
|
||||
MUX_CFG(GPIOB2_U0CTSN_SEL_NAME, B, 12, 1, 0, DEFAULT) /* 0 : gpio_b2 1 : uart0_cts_n */
|
||||
MUX_CFG(GPIOF2_APWM0_SEL_NAME, B, 11, 1, 0, INITIAL) /* 0 : gpio_f2 1 : pwm0 */
|
||||
MUX_CFG(GPIOC_LCDC16BIT_SEL_NAME, B, 10, 1, 1, INITIAL) /* 0 : gpio_d0 ~ gpio_d7 1 : lcdc_data8 ~ lcdc_data15 */
|
||||
#if defined(CONFIG_MACH_RAHO)||defined(CONFIG_MACH_RAHOSDK)
|
||||
MUX_CFG(GPIOC_LCDC24BIT_SEL_NAME, B, 9, 1, 0, INITIAL) /* 0 : gpio_c2 ~ gpio_c7 1 : lcdc_data18 ~ lcdc_data23 */
|
||||
#else
|
||||
MUX_CFG(GPIOC_LCDC24BIT_SEL_NAME, B, 9, 1, 1, INITIAL) /* 0 : gpio_c2 ~ gpio_c7 1 : lcdc_data18 ~ lcdc_data23 */
|
||||
#endif
|
||||
MUX_CFG(GPIOC_LCDC18BIT_SEL_NAME, B, 8, 1, 1, INITIAL) /* 0 : gpio_c0/c1 1 : lcdc_data16 ~ lcdc_data17 */
|
||||
MUX_CFG(CXGPIO_LCDDEN_SEL_NAME, B, 7, 1, 1, INITIAL) /* 0 : gpio2_26 1 : lcdc_denable */
|
||||
MUX_CFG(CXGPIO_LCDVSYNC_SEL_NAME, B, 6, 1, 1, INITIAL) /* 0 : gpio2_25 1 : lcdc_vsync */
|
||||
MUX_CFG(CXGPIO_HSADC_SEL_NAME, B, 5, 1, 0, DEFAULT) /* 0 : gpio2_14 ~ gpio2_23 1 : hsadc_data_q[9:0] */
|
||||
MUX_CFG(CXGPIO_HOST_SEL_NAME, B, 4, 1, 0, DEFAULT) /* 0 : gpio2_0 ~ gpio2_13 1 : host interface */
|
||||
MUX_CFG(GPIOH7_HSADCCLK_SEL_NAME, B, 3, 1, 0, DEFAULT) /* 0 : gpio_h7 1 : hsadc_clkin */
|
||||
MUX_CFG(GPIOH6_IQ_SEL_NAME, B, 2, 1, 0, DEFAULT) /* 0 : gpio_h6 1 : ext_iq_index */
|
||||
MUX_CFG(CXGPIO_I2S_SEL_NAME, B, 1, 1, 0, DEFAULT) /* 0 : i2s interface 1 : gpio2_27 ~ gpio2_31 */
|
||||
MUX_CFG(GPIOF6_VIPCLK_SEL_NAME, B, 0, 1, 0, DEFAULT) /* 0 : gpio_f6 1 : vip clkout */
|
||||
};
|
||||
|
||||
void rk2818_mux_set(struct mux_config *cfg)
|
||||
{
|
||||
int regValue;
|
||||
int mask;
|
||||
|
||||
mask = ((1<<(cfg->interleave))-1)<<cfg->offset;
|
||||
regValue = readl(cfg->mux_reg);
|
||||
regValue &=~mask;
|
||||
regValue |=(cfg->mode<<cfg->offset);
|
||||
#ifdef DEBUG_LHH
|
||||
printk("%s::regValue is %x,mask is %x\n",__FUNCTION__,regValue,mask);
|
||||
#endif
|
||||
writel(regValue,cfg->mux_reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int rk2818_iomux_init(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<ARRAY_SIZE(rk2818_muxs);i++)
|
||||
{
|
||||
if(rk2818_muxs[i].flags != DEFAULT)
|
||||
rk2818_mux_set(&rk2818_muxs[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rk2818_iomux_init);
|
||||
/*
|
||||
*config iomux : input iomux name and iomux flags
|
||||
*/
|
||||
void rk2818_mux_api_set(char *name, unsigned int mode)
|
||||
{
|
||||
int i;
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
for(i=0;i<ARRAY_SIZE(rk2818_muxs);i++)
|
||||
{
|
||||
if (!strcmp(rk2818_muxs[i].name, name))
|
||||
{
|
||||
rk2818_muxs[i].premode = rk2818_muxs[i].mode;
|
||||
rk2818_muxs[i].mode = mode;
|
||||
rk2818_mux_set(&rk2818_muxs[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rk2818_mux_api_set);
|
||||
|
||||
void rk2818_mux_api_mode_resume(char *name)
|
||||
{
|
||||
int i;
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
for(i=0;i<ARRAY_SIZE(rk2818_muxs);i++)
|
||||
{
|
||||
if (!strcmp(rk2818_muxs[i].name, name))
|
||||
{
|
||||
if(rk2818_muxs[i].mode != rk2818_muxs[i].premode)
|
||||
{
|
||||
rk2818_muxs[i].mode = rk2818_muxs[i].premode;
|
||||
rk2818_mux_set(&rk2818_muxs[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rk2818_mux_api_mode_resume);
|
||||
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/irq.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/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
//#include <asm/hardware.h>
|
||||
//#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
//#include <asm/setup.h>
|
||||
|
||||
//#include <asm/arch/typedef.h>
|
||||
//#include <asm/arch/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
//#include "include/mach/irqs.h"
|
||||
//#include "include/mach/rk2818_iomap.h"
|
||||
|
||||
//#include <asm/mach/arch.h>
|
||||
#include <linux/irq.h>
|
||||
//#include <asm/mach/map.h>
|
||||
//#include <asm/hw_irq.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
||||
#define which_irq_l(irq) (0x01u << (irq))
|
||||
#define which_irq_h(irq) (0x01u << ((irq) & 0x1f))
|
||||
|
||||
#define write_irq_reg(addr, val) __raw_writel(val, addr+(RK2818_INTC_BASE))
|
||||
#define read_irq_reg(addr) __raw_readl(addr+(RK2818_INTC_BASE))
|
||||
#define set_irq_reg(addr, val) write_irq_reg(addr, ((val) | read_irq_reg(addr)))
|
||||
#define clear_irq_reg(addr, val) write_irq_reg(addr, (~(val) & read_irq_reg(addr)))
|
||||
|
||||
|
||||
|
||||
u32 int_priority[NR_AIC_IRQS]={
|
||||
/* priority name number */
|
||||
0, //IRQ_DWDMA, 0 -- low
|
||||
0, //IRQ_UHI, 1 -- USB Host Interface
|
||||
0, //IRQ_NANDC, 2
|
||||
0, //IRQ_LCDC, 3
|
||||
0, //IRQ_SDMMC0, 4
|
||||
0, //IRQ_VIP, 5
|
||||
0, //IRQ_GPIO0, 6
|
||||
0, //IRQ_GPIO1, 7
|
||||
0, //IRQ_OTG, 8 -- USB OTG
|
||||
0, //IRQ_ABTARMD, 9 -- Arbiter in ARMD BUS
|
||||
0, //IRQ_ABTEXP, 10 -- Arbiter in EXP BUS
|
||||
0, //IRQ_I2C0, 11
|
||||
0, //IRQ_I2C1, 12
|
||||
0, //IRQ_I2S, 13
|
||||
0, //IRQ_SPIM, 14 -- SPI Master
|
||||
0, //IRQ_SPIS, 15 -- SPI Slave
|
||||
0, //IRQ_TIMER1, 16
|
||||
0, //IRQ_TIMER2, 17
|
||||
0, //IRQ_TIMER3, 18
|
||||
0, //IRQ_UART0, 19
|
||||
0, //IRQ_UART1, 20
|
||||
0, //IRQ_WDT, 21
|
||||
0, //IRQ_PWM0, 22
|
||||
0, //IRQ_PWM1, 23
|
||||
0, //IRQ_PWM2, 24
|
||||
0, //IRQ_PWM3, 25
|
||||
0, //IRQ_ADC, 26
|
||||
0, //IRQ_RTC, 27
|
||||
0, //IRQ_PIUSEM0, 28 -- PIU Semphore 0
|
||||
0, //IRQ_PIUSEM1, 29
|
||||
0, //IRQ_PIUSEM3, 30
|
||||
0, //IRQ_PIUCMD, 31 -- PIU command/reply
|
||||
0, //IRQ_XDMA, 32
|
||||
0, //IRQ_SDMMC1, 33
|
||||
0, //IRQ_DSPSEI, 34 -- DSP slave interface error interrupt
|
||||
0, //IRQ_DSPSWI, 35 -- DSP interrupt by software set
|
||||
0, //IRQ_SCU, 36
|
||||
0, //IRQ_SWI, 37 -- Software Interrupt
|
||||
0, //IRQ_DSPMEI, 38 -- DSP master interface error interrupt
|
||||
0, //IRQ_DSPSAEI, 39 -- DSP system access error interrupt
|
||||
0 //IRQ_MAXNUM 40 -- interrupt
|
||||
};
|
||||
|
||||
static void rk2818_irq_ack(u32 irq)
|
||||
{
|
||||
//rk28 no irq ack
|
||||
}
|
||||
|
||||
static void rk2818_irq_mask(u32 irq)
|
||||
{
|
||||
if (irq >= 32)
|
||||
{
|
||||
set_irq_reg(IRQ_REG_INTMASK_H, which_irq_h(irq));
|
||||
}
|
||||
else
|
||||
{
|
||||
set_irq_reg(IRQ_REG_INTMASK_L, which_irq_l(irq));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rk2818_irq_unmask(u32 irq)
|
||||
{
|
||||
if (irq >= 32)
|
||||
{
|
||||
clear_irq_reg(IRQ_REG_INTMASK_H, which_irq_h(irq));
|
||||
}
|
||||
else
|
||||
{
|
||||
clear_irq_reg(IRQ_REG_INTMASK_L, which_irq_l(irq));
|
||||
}
|
||||
}
|
||||
|
||||
static s32 rk2818_irq_wake(u32 irq, u32 value)
|
||||
{
|
||||
//rk28 no irq wake
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct irq_chip rk2818_irq_chip = {
|
||||
.name = "rk2818_irq",
|
||||
.ack = rk2818_irq_ack,
|
||||
.mask = rk2818_irq_mask,
|
||||
.unmask = rk2818_irq_unmask,
|
||||
.set_wake = rk2818_irq_wake,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the AIC interrupt controller.
|
||||
*/
|
||||
void __init rk2818_init_irq(u32 priority[NR_AIC_IRQS])
|
||||
{
|
||||
u32 i;
|
||||
|
||||
write_irq_reg(IRQ_REG_INTEN_L, 0xffffffff);//enable irq interrupt
|
||||
write_irq_reg(IRQ_REG_INTEN_H, 0xffffffff);
|
||||
write_irq_reg(IRQ_REG_INTMASK_L, 0xffffffff); //mask all irq interrupt
|
||||
write_irq_reg(IRQ_REG_INTMASK_H, 0xffffffff);
|
||||
write_irq_reg(IRQ_REG_INTFORCE_L, 0);
|
||||
write_irq_reg(IRQ_REG_INTFORCE_H, 0);
|
||||
write_irq_reg(FIQ_REG_INTEN, 0x03); //enable fiq interrupt
|
||||
write_irq_reg(FIQ_REG_INTMASK, 0x03); //mask fiq interrupt
|
||||
write_irq_reg(IRQ_REG_PLEVEL, 0);
|
||||
|
||||
for (i = 0; i < NR_AIC_IRQS; i++) {
|
||||
set_irq_chip(i, &rk2818_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
set_irq_flags(i, IRQF_VALID);//no probe and auto enable
|
||||
}
|
||||
}
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/tcm.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/scu.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/rk2818-socpm.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
extern void rockchip_timer_clocksource_suspend_resume(int suspend);
|
||||
extern int rockchip_timer_clocksource_irq_checkandclear(void);
|
||||
|
||||
#ifdef CONFIG_DWC_OTG_HOST_ONLY
|
||||
static int rk28_usb_suspend(int exitsuspend) { return 0; }
|
||||
static int rk28_usb_check_vbus_change(void) { return 0; }
|
||||
#else
|
||||
extern int rk28_usb_suspend(int exitsuspend);
|
||||
extern int rk28_usb_check_vbus_change(void);
|
||||
#endif
|
||||
#ifdef CONFIG_DWC_OTG_BOTH_HOST_SLAVE
|
||||
extern int rk28_usb_check_connectid_change(void);
|
||||
#else
|
||||
static int rk28_usb_check_connectid_change(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#define regfile_readl(offset) readl(RK2818_REGFILE_BASE + offset)
|
||||
|
||||
#define scu_readl(offset) readl(RK2818_SCU_BASE + offset)
|
||||
#define scu_writel(v, offset) writel(v, RK2818_SCU_BASE + offset)
|
||||
|
||||
#define msdr_readl(offset) readl(RK2818_SDRAMC_BASE + offset)
|
||||
#define msdr_writel(v, offset) writel(v, RK2818_SDRAMC_BASE + offset)
|
||||
|
||||
#define ddr_readl(offset) readl(RK2818_SDRAMC_BASE + offset)
|
||||
#define ddr_writel(v, offset) writel(v, RK2818_SDRAMC_BASE + offset)
|
||||
|
||||
#define irq_readl(offset) readl(RK2818_INTC_BASE + offset)
|
||||
#define gpio0_readl(offset) readl(RK2818_GPIO0_BASE + offset)
|
||||
#define gpio1_readl(offset) readl(RK2818_GPIO1_BASE + offset)
|
||||
|
||||
#define PLL_PD (0x01u<<22)
|
||||
|
||||
/* CPU_APB_REG0 */
|
||||
#define MEMTYPESHIFT 11
|
||||
#define MEMTYPEMASK (0x3 << MEMTYPESHIFT)
|
||||
|
||||
#define SDRAM 0
|
||||
#define MOBILE_SDRAM 1
|
||||
#define DDRII 2
|
||||
#define MOBILE_DDR 3
|
||||
|
||||
static inline u32 sdram_get_mem_type(void)
|
||||
{
|
||||
return (regfile_readl(CPU_APB_REG0) & MEMTYPEMASK) >> MEMTYPESHIFT;
|
||||
}
|
||||
|
||||
#define ASM_LOOP_INSTRUCTION_NUM 4
|
||||
|
||||
#define CLK_GATE_SDRAM_MASK ((1 << (CLK_GATE_SDRAM_COMMON & 31)) | (1 << (CLK_GATE_SDRAM_CONTROLLER & 31)))
|
||||
#define CLK_GATE_MOBILESDRAM_MASK ((1 << (CLK_GATE_SDRAM_COMMON & 31)) | (1 << (CLK_GATE_MOBILE_SDRAM_CONTROLLER & 31)))
|
||||
|
||||
/* SDRAM Control Regitster */
|
||||
#define SR_MODE (1 << 11)
|
||||
#define ENTER_SELF_REFRESH (1 << 1)
|
||||
#define MSDR_SCTLR 0x0C // SDRAM control register
|
||||
|
||||
/* CTR_REG_62 */
|
||||
#define MODE5_MASK (0xFFFF << 16)
|
||||
#define MODE5_CNT(n) (((n) & 0xFFFF) << 16)
|
||||
#define CTRL_REG_62 0xf8 // LOWPOWER_INTERNAL_CNT/LOWPOWER_EXTERNAL_CNT.
|
||||
|
||||
/****************************************************************/
|
||||
//函数匿sdram_enter_self_refresh
|
||||
//描述: SDRAM进入自刷新模帿
|
||||
//参数说明:
|
||||
//返回伿对于DDR就是CTRL_REG_62的值,供sdram_exit_self_refresh使用
|
||||
//相关全局变量:
|
||||
//注意:(1)系统完全idle后才能进入自刷新模式,进入自刷新后不能再访问SDRAM
|
||||
// (2)要进入自刷新模式,必须保证运行时这个函数所调用到的所有代码不在SDRAM
|
||||
/****************************************************************/
|
||||
u32 __tcmfunc sdram_enter_self_refresh(void)
|
||||
{
|
||||
u32 r;
|
||||
u32 mem_type = sdram_get_mem_type();
|
||||
|
||||
switch (mem_type) {
|
||||
case SDRAM:
|
||||
case MOBILE_SDRAM:
|
||||
msdr_writel(msdr_readl(MSDR_SCTLR) | ENTER_SELF_REFRESH, MSDR_SCTLR);
|
||||
|
||||
while (!(msdr_readl(MSDR_SCTLR) & SR_MODE)); //确定已经进入self-refresh
|
||||
|
||||
/* Disable Mobile SDRAM/SDRAM Common/Controller hclk clock */
|
||||
r = scu_readl(SCU_CLKGATE1_CON);
|
||||
if (SDRAM == mem_type) {
|
||||
r |= CLK_GATE_SDRAM_MASK;
|
||||
} else {
|
||||
r |= CLK_GATE_MOBILESDRAM_MASK;
|
||||
}
|
||||
scu_writel(r, SCU_CLKGATE1_CON);
|
||||
break;
|
||||
|
||||
case DDRII:
|
||||
case MOBILE_DDR:
|
||||
r = ddr_readl(CTRL_REG_62);
|
||||
ddr_writel((r & ~MODE5_MASK) | MODE5_CNT(1), CTRL_REG_62);
|
||||
// tcm_printascii("3x DDRII\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
//函数匿sdram_exit_self_refresh
|
||||
//描述: SDRAM退出自刷新模式
|
||||
//参数说明:
|
||||
//返回伿
|
||||
//相关全局变量:
|
||||
//注意:(1)SDRAM在自刷新模式后不能被访问,必须先退出自刷新模式
|
||||
// (2)必须保证运行时这个函数的代码不在SDRAM
|
||||
/****************************************************************/
|
||||
void __tcmfunc sdram_exit_self_refresh(u32 ctrl_reg_62)
|
||||
{
|
||||
u32 r;
|
||||
u32 mem_type = sdram_get_mem_type();
|
||||
|
||||
switch (mem_type) {
|
||||
case SDRAM:
|
||||
case MOBILE_SDRAM:
|
||||
/* Enable Mobile SDRAM/SDRAM Common/Controller hclk clock */
|
||||
r = scu_readl(SCU_CLKGATE1_CON);
|
||||
if (SDRAM == mem_type) {
|
||||
r &= ~CLK_GATE_SDRAM_MASK;
|
||||
} else {
|
||||
r &= ~CLK_GATE_MOBILESDRAM_MASK;
|
||||
}
|
||||
scu_writel(r, SCU_CLKGATE1_CON);
|
||||
tcm_udelay(1, 24); // DRVDelayUs(1);
|
||||
|
||||
msdr_writel(msdr_readl(MSDR_SCTLR) & ~ENTER_SELF_REFRESH, MSDR_SCTLR);
|
||||
|
||||
while (msdr_readl(MSDR_SCTLR) & SR_MODE); //确定退出进入self-refresh
|
||||
break;
|
||||
|
||||
case DDRII:
|
||||
case MOBILE_DDR:
|
||||
ddr_writel(ctrl_reg_62, CTRL_REG_62);
|
||||
break;
|
||||
}
|
||||
|
||||
tcm_udelay(100, 24); //DRVDelayUs(100); 延时一下比较安全,保证退出后稳定
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void __tcmlocalfunc noinline tcm_printch(char byte)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
timeout = 0xffffffff;
|
||||
while (!(readl(RK2818_UART1_BASE + 0x7c) & (1<<1))) {
|
||||
if (!timeout--)
|
||||
return;
|
||||
}
|
||||
writel(byte, RK2818_UART1_BASE);
|
||||
if (byte == '\n')
|
||||
tcm_printch('\r');
|
||||
}
|
||||
static void __tcmlocalfunc noinline tcm_printascii(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
tcm_printch(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static void __tcmlocalfunc noinline tcm_printhex(unsigned int hex)
|
||||
{
|
||||
int i = 8;
|
||||
tcm_printch('0');
|
||||
tcm_printch('x');
|
||||
while (i--) {
|
||||
unsigned char c = (hex & 0xF0000000) >> 28;
|
||||
tcm_printch(c < 0xa ? c + '0' : c - 0xa + 'a');
|
||||
hex <<= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __tcmfunc rk2818_tcm_idle(void)
|
||||
{
|
||||
volatile u32 unit;
|
||||
u32 ctrl_reg_62;
|
||||
|
||||
u32 scu_mode = scu_readl(SCU_MODE_CON);
|
||||
u32 scu_apll = scu_readl(SCU_APLL_CON);
|
||||
u32 scu_clksel0 = scu_readl(SCU_CLKSEL0_CON);
|
||||
|
||||
asm("b 1f; .align 5; 1:");
|
||||
asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
|
||||
|
||||
scu_writel(scu_mode & ~(3 << 2), SCU_MODE_CON); // slow
|
||||
scu_writel(scu_apll | PLL_PD, SCU_APLL_CON); // powerdown
|
||||
|
||||
//rk28_ddr_enter_self_refresh();
|
||||
tcm_udelay(5, 24); //DRVDelayUs(100);
|
||||
ctrl_reg_62=sdram_enter_self_refresh();
|
||||
tcm_udelay(200, 24); //DRVDelayUs(100);
|
||||
|
||||
rk2818_socpm_suspend_first();
|
||||
rk2818_socpm_suspend();
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
|
||||
asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */
|
||||
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
rk2818_socpm_resume();
|
||||
rk2818_socpm_resume_last();
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
sdram_exit_self_refresh(ctrl_reg_62);
|
||||
|
||||
tcm_udelay(10, 24);
|
||||
scu_writel(scu_apll, SCU_APLL_CON); // powerup
|
||||
scu_writel(scu_clksel0 & (~3), SCU_CLKSEL0_CON);
|
||||
tcm_udelay(20, 24);
|
||||
|
||||
unit = 7200; /* 24m,0.3ms , 24*300*/
|
||||
while (unit-- > 0) {
|
||||
if (regfile_readl(CPU_APB_REG0) & 0x80)
|
||||
break;
|
||||
}
|
||||
|
||||
tcm_udelay(5 << 8, 24);
|
||||
scu_writel(scu_clksel0, SCU_CLKSEL0_CON);
|
||||
tcm_udelay(5, 24);
|
||||
|
||||
scu_writel(scu_mode, SCU_MODE_CON); // normal
|
||||
return unit;
|
||||
}
|
||||
|
||||
static void rk2818_idle(void)
|
||||
{
|
||||
unsigned long old_sp;
|
||||
unsigned long tcm_sp = ITCM_END & ~7;
|
||||
|
||||
asm volatile ("mov %0, sp" : "=r" (old_sp));
|
||||
asm volatile ("mov sp, %0" :: "r" (tcm_sp));
|
||||
rk2818_tcm_idle();
|
||||
asm volatile ("mov sp, %0" :: "r" (old_sp));
|
||||
}
|
||||
|
||||
#if 1
|
||||
static void dump_register(void)
|
||||
{
|
||||
#ifdef CONFIG_PM_DEBUG
|
||||
printk(KERN_DEBUG "SCU_APLL_CON : 0x%08x\n", scu_readl(SCU_APLL_CON));
|
||||
printk(KERN_DEBUG "SCU_DPLL_CON : 0x%08x\n", scu_readl(SCU_DPLL_CON));
|
||||
printk(KERN_DEBUG "SCU_CPLL_CON : 0x%08x\n", scu_readl(SCU_CPLL_CON));
|
||||
printk(KERN_DEBUG "SCU_MODE_CON : 0x%08x\n", scu_readl(SCU_MODE_CON));
|
||||
printk(KERN_DEBUG "SCU_PMU_CON : 0x%08x\n", scu_readl(SCU_PMU_CON));
|
||||
printk(KERN_DEBUG "SCU_CLKSEL_CON : 0x%08x 0x%08x 0x%08x\n", scu_readl(SCU_CLKSEL0_CON), scu_readl(SCU_CLKSEL1_CON), scu_readl(SCU_CLKSEL2_CON));
|
||||
printk(KERN_DEBUG "SCU_CLKGATE_CON : 0x%08x 0x%08x 0x%08x\n", scu_readl(SCU_CLKGATE0_CON), scu_readl(SCU_CLKGATE1_CON), scu_readl(SCU_CLKGATE2_CON));
|
||||
printk(KERN_DEBUG "IRQ_INTEN : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTEN_L), irq_readl(IRQ_REG_INTEN_H));
|
||||
printk(KERN_DEBUG "IRQ_INTMASK : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTMASK_L), irq_readl(IRQ_REG_INTMASK_H));
|
||||
printk(KERN_DEBUG "IRQ_INTFORCE : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTFORCE_L), irq_readl(IRQ_REG_INTFORCE_H));
|
||||
printk(KERN_DEBUG "IRQ_RAWSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_RAWSTATUS_L), irq_readl(IRQ_REG_RAWSTATUS_H));
|
||||
printk(KERN_DEBUG "IRQ_STATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_STATUS_L), irq_readl(IRQ_REG_STATUS_H));
|
||||
printk(KERN_DEBUG "IRQ_MASKSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_MASKSTATUS_L), irq_readl(IRQ_REG_MASKSTATUS_H));
|
||||
printk(KERN_DEBUG "IRQ_FINALSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_FINALSTATUS_L), irq_readl(IRQ_REG_FINALSTATUS_H));
|
||||
printk(KERN_DEBUG "GPIO_INTEN : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTEN), gpio1_readl(GPIO_INTEN));
|
||||
printk(KERN_DEBUG "GPIO_INTMASK : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTMASK), gpio1_readl(GPIO_INTMASK));
|
||||
printk(KERN_DEBUG "GPIO_INTTYPE_LEVEL : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTTYPE_LEVEL), gpio1_readl(GPIO_INTTYPE_LEVEL));
|
||||
printk(KERN_DEBUG "GPIO_INT_POLARITY : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_POLARITY), gpio1_readl(GPIO_INT_POLARITY));
|
||||
printk(KERN_DEBUG "GPIO_INT_STATUS : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_STATUS), gpio1_readl(GPIO_INT_STATUS));
|
||||
printk(KERN_DEBUG "GPIO_INT_RAWSTATUS : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_RAWSTATUS), gpio1_readl(GPIO_INT_RAWSTATUS));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int rk2818_pm_enter(suspend_state_t state)
|
||||
{
|
||||
int irq_val = 0;
|
||||
struct clk *arm_clk = clk_get(NULL, "arm");
|
||||
unsigned long arm_rate = clk_get_rate(arm_clk);
|
||||
|
||||
clk_set_rate(arm_clk, 24000000);
|
||||
dump_register();
|
||||
|
||||
#ifdef CONFIG_RK28_USB_WAKE
|
||||
rockchip_timer_clocksource_suspend_resume(1);
|
||||
|
||||
while (!irq_val) {
|
||||
rk28_usb_suspend(0);
|
||||
#endif
|
||||
|
||||
rk2818_idle();
|
||||
|
||||
#ifdef CONFIG_RK28_USB_WAKE
|
||||
rk28_usb_suspend(1);
|
||||
udelay(400);
|
||||
|
||||
irq_val = rockchip_timer_clocksource_irq_checkandclear();
|
||||
irq_val |= rk28_usb_check_vbus_change();
|
||||
irq_val |= rk28_usb_check_connectid_change();
|
||||
}
|
||||
|
||||
rockchip_timer_clocksource_suspend_resume(0);
|
||||
#endif
|
||||
dump_register();
|
||||
clk_set_rate(arm_clk, arm_rate);
|
||||
//rk2818_socpm_print();
|
||||
printk(KERN_DEBUG "quit arm halt,irq_val=0x%x\n", irq_val);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_suspend_ops rk2818_pm_ops = {
|
||||
.enter = rk2818_pm_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init rk2818_pm_init(void)
|
||||
{
|
||||
suspend_set_ops(&rk2818_pm_ops);
|
||||
return 0;
|
||||
}
|
||||
__initcall(rk2818_pm_init);
|
||||
|
|
@ -1,890 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/tcm.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/scu.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/rk2818-socpm.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
|
||||
static struct rk2818_pm_attr_dbg_st __tcmdata pm_scu_attr_dbg[PM_SCU_ATTR_DBG_NUM];
|
||||
static struct rk2818_pm_attr_dbg_st __tcmdata pm_general_attr_dbg[PM_GENERAL_ATTR_DBG_NUM];
|
||||
static struct rk2818_pm_attr_dbg_st __tcmdata pm_gpio0_attr_dbg[PM_GPIO0_ATTR_DBG_NUM];
|
||||
static struct rk2818_pm_attr_dbg_st __tcmdata pm_gpio1_attr_dbg[PM_GPIO1_ATTR_DBG_NUM];
|
||||
//static void rk2818_socpm_attr_int(void);
|
||||
//static void setreg_form_socpm_attr(unsigned int *reg,int regoff,struct rk2818_pm_soc_st *soc);
|
||||
#else
|
||||
|
||||
#define setreg_form_socpm_attr(a,b,c)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
static unsigned int __tcmdata pm_scu_reg_ch[PM_SCU_REG_NUM];
|
||||
static unsigned int __tcmdata pm_general_reg_ch[PM_GENERAL_CPU_REG];
|
||||
static unsigned int __tcmdata pm_gpio0_reg_ch[PM_SCU_GPIO_SWPORTC_NUM];
|
||||
static unsigned int __tcmdata pm_gpio1_reg_ch[PM_SCU_GPIO_SWPORTC_NUM];
|
||||
#endif
|
||||
static unsigned int __tcmdata pm_scu_reg_save[PM_SCU_REG_NUM];
|
||||
static unsigned int __tcmdata pm_scu_temp_reg[PM_SCU_REG_NUM];
|
||||
|
||||
static struct rk2818_pm_soc_st __tcmdata pm_scu_ctr={
|
||||
.reg_save=&pm_scu_reg_save[0],
|
||||
.reg_base_addr=(unsigned int *)RK2818_SCU_BASE,
|
||||
.reg_ctrbit=0,
|
||||
.reg_num=PM_SCU_REG_NUM,
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
.reg_ch=&pm_scu_reg_ch[0],
|
||||
#endif
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
.attr_num=PM_SCU_ATTR_DBG_NUM,
|
||||
.attr_dbg=&pm_scu_attr_dbg[0],
|
||||
.attr_flag=0,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static unsigned int __tcmdata pm_general_reg_save[PM_GENERAL_CPU_REG];
|
||||
|
||||
static struct rk2818_pm_soc_st __tcmdata pm_general_ctr={
|
||||
.reg_save=&pm_general_reg_save[0],
|
||||
.reg_base_addr=(unsigned int *)RK2818_REGFILE_BASE,
|
||||
.reg_ctrbit=0,
|
||||
.reg_num=PM_GENERAL_CPU_REG,
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
.reg_ch=&pm_general_reg_ch[0],
|
||||
#endif
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
.attr_num=PM_GENERAL_ATTR_DBG_NUM,
|
||||
.attr_dbg=&pm_general_attr_dbg[0],
|
||||
.attr_flag=0,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static unsigned int __tcmdata pm_gpio0_reg_save[PM_SCU_GPIO_SWPORTC_NUM];
|
||||
|
||||
static struct rk2818_pm_soc_st __tcmdata pm_gpio0_ctr={
|
||||
.reg_save=&pm_gpio0_reg_save[0],
|
||||
.reg_base_addr=(unsigned int *)RK2818_GPIO0_BASE,
|
||||
.reg_ctrbit=0,
|
||||
.reg_num=PM_SCU_GPIO_SWPORTC_NUM,
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
.reg_ch=&pm_gpio0_reg_ch[0],
|
||||
#endif
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
.attr_num=PM_GPIO0_ATTR_DBG_NUM,
|
||||
.attr_dbg=&pm_gpio0_attr_dbg[0],
|
||||
.attr_flag=0,
|
||||
#endif
|
||||
};
|
||||
static unsigned int __tcmdata pm_gpio1_reg_save[PM_SCU_GPIO_SWPORTC_NUM];
|
||||
|
||||
static struct rk2818_pm_soc_st __tcmdata pm_gpio1_ctr={
|
||||
.reg_save=&pm_gpio1_reg_save[0],
|
||||
.reg_base_addr=(unsigned int *)RK2818_GPIO1_BASE,
|
||||
.reg_ctrbit=0,
|
||||
.reg_num=PM_SCU_GPIO_SWPORTC_NUM,
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
.reg_ch=&pm_gpio1_reg_ch[0],
|
||||
#endif
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
.attr_num=PM_GPIO1_ATTR_DBG_NUM,
|
||||
.attr_dbg=&pm_gpio1_attr_dbg[0],
|
||||
.attr_flag=0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static unsigned int __tcmdata pm_savereg[PM_SAVE_REG_NUM];
|
||||
static unsigned int __tcmdata savereg_ch[PM_SAVE_REG_NUM];
|
||||
|
||||
struct rk2818_pm_st __tcmdata rk2818_soc_pm={
|
||||
.scu=(struct rk2818_pm_soc_st *)&pm_scu_ctr.reg_save,
|
||||
.scu_tempreg=&pm_scu_temp_reg[0],
|
||||
.general=(struct rk2818_pm_soc_st *)&pm_general_ctr.reg_save,
|
||||
.gpio0=(struct rk2818_pm_soc_st *)&pm_gpio0_ctr.reg_save,
|
||||
.gpio1=(struct rk2818_pm_soc_st *)&pm_gpio1_ctr.reg_save,
|
||||
.save_reg=&pm_savereg[0],
|
||||
.save_ch=&savereg_ch[0],
|
||||
};
|
||||
|
||||
static struct rk2818_pm_callback_st __tcmdata *pm_ctr_callback=NULL;
|
||||
|
||||
int __tcmfunc rk2818_socpm_set_gpio(unsigned int gpio,unsigned int output,unsigned int level)
|
||||
{
|
||||
unsigned int *rk2818_gpio_reg;
|
||||
struct rk2818_pm_soc_st *gpioctr;
|
||||
unsigned int regoff;
|
||||
|
||||
if(gpio>=RK2818GPIO_TOTAL)
|
||||
return -1;
|
||||
|
||||
if(gpio<32)
|
||||
{
|
||||
gpioctr=rk2818_soc_pm.gpio0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpioctr=rk2818_soc_pm.gpio1;
|
||||
gpio-=32;
|
||||
}
|
||||
rk2818_gpio_reg=gpioctr->reg_base_addr;
|
||||
switch(gpio/8)
|
||||
{
|
||||
case 0:
|
||||
gpioctr->reg_ctrbit|=(0x1<<PM_GPIO_SWPORTA_DR)|(0x1<<PM_GPIO_SWPORTA_DDR);
|
||||
regoff=PM_GPIO_SWPORTA_DR;
|
||||
break;
|
||||
case 1:
|
||||
gpioctr->reg_ctrbit|=(0x1<<PM_GPIO_SWPORTB_DR)|(0x1<<PM_GPIO_SWPORTB_DDR);
|
||||
regoff=PM_GPIO_SWPORTB_DR;
|
||||
break;
|
||||
case 2:
|
||||
gpioctr->reg_ctrbit|=(0x1<<PM_GPIO_SWPORTC_DR)|(0x1<<PM_GPIO_SWPORTC_DDR);
|
||||
regoff=PM_GPIO_SWPORTC_DR;
|
||||
break;
|
||||
case 3:
|
||||
gpioctr->reg_ctrbit|=(0x1<<PM_GPIO_SWPORTD_DR)|(0x1<<PM_GPIO_SWPORTD_DDR);
|
||||
regoff=PM_GPIO_SWPORTD_DR;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
gpio%=8;
|
||||
|
||||
if(output)
|
||||
{
|
||||
rk2818_gpio_reg[regoff+1]|=(1<<gpio);//ddr set dir
|
||||
if(level==0)
|
||||
rk2818_gpio_reg[regoff]&=(~(1<<gpio));//ddr set value
|
||||
else
|
||||
rk2818_gpio_reg[regoff]|=(1<<gpio);
|
||||
}
|
||||
else
|
||||
rk2818_gpio_reg[regoff+1]&=(~(1<<gpio));//ddr set dir
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __tcmfunc rk2818_socpm_gpio_pullupdown(unsigned int gpio,eGPIOPullType_t GPIOPullUpDown)
|
||||
{
|
||||
unsigned int *general_reg;
|
||||
unsigned int regoff;
|
||||
int gpionum=0;
|
||||
|
||||
if(gpio>=RK2818GPIO_TOTAL)
|
||||
return -1;
|
||||
general_reg=rk2818_soc_pm.general->reg_base_addr;
|
||||
regoff=PM_GPIO0_AB_PU_CON+gpio/16;
|
||||
rk2818_soc_pm.general->reg_ctrbit|=((0x1<<regoff));
|
||||
gpionum=gpio%16;
|
||||
general_reg[regoff]&=PM_BIT_CLEAR(gpionum*2,2)|PM_BIT_SET(gpionum*2,GPIOPullUpDown,2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void __tcmlocalfunc noinline tcm_printch(char byte)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
timeout = 0xffffffff;
|
||||
while (!(readl(RK2818_UART1_BASE + 0x7c) & (1<<1))) {
|
||||
if (!timeout--)
|
||||
return;
|
||||
}
|
||||
writel(byte, RK2818_UART1_BASE);
|
||||
if (byte == '\n')
|
||||
tcm_printch('\r');
|
||||
}
|
||||
|
||||
static void __tcmlocalfunc noinline tcm_printascii(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
tcm_printch(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static void __tcmlocalfunc noinline tcm_printhex(unsigned int hex)
|
||||
{
|
||||
//int i = 8;
|
||||
tcm_printch('0');
|
||||
tcm_printch('x');
|
||||
// while (i--)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void __tcmfunc rk2818_pm_save_reg(unsigned int *save,unsigned int *source,int num)
|
||||
{
|
||||
int i;
|
||||
if(save&&source)
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
save[i]=source[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void __tcmfunc rk2818_soc_updata_scureg(unsigned int *tempdata,int regoff,int flag)
|
||||
{
|
||||
|
||||
if(pm_ctr_callback->scu_suspend&&flag)
|
||||
{
|
||||
pm_ctr_callback->scu_suspend(tempdata,regoff);
|
||||
}
|
||||
rk2818_soc_pm.scu->reg_base_addr[regoff]=*tempdata;
|
||||
rk2818_soc_pm.scu->reg_ctrbit|=(0x1<<regoff);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void __tcmfunc rk2818_soc_arm_stop(void)
|
||||
{
|
||||
unsigned int *rk2818_scu_reg=rk2818_soc_pm.scu->reg_base_addr;
|
||||
rk2818_scu_reg[PM_SCU_MODE_CON]|=CPU_STOP_MODE;
|
||||
rk2818_scu_reg[PM_SCU_CPUPD]=0xdeedbabe;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __tcmfunc rk2818_soc_scu_suspend(void)
|
||||
{
|
||||
unsigned int *rk2818_scu_reg=rk2818_soc_pm.scu->reg_base_addr;
|
||||
unsigned int *tempdata=&rk2818_soc_pm.scu_reg;
|
||||
|
||||
|
||||
*tempdata= SCU_GATE0CLK_ALL_DIS&(~DIS_ARM_CLK)&(~DIS_TIMER_CLK)
|
||||
&(~DIS_GPIO0_CLK)&(~DIS_GPIO1_CLK)&(~DIS_INTC_CLK)/*&(~DIS_UART0_CLK)&(~DIS_UART1_CLK)*/;
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_CLKGATE0_CON,1);
|
||||
tcm_udelay(1, 24);
|
||||
|
||||
*tempdata=SCU_GATE1CLK_BASE_SET/*|EN_AXI_CLK&(~DIS_DDR_CLK)&(~DIS_DDR_HCLK)*/;
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_CLKGATE1_CON,1);
|
||||
tcm_udelay(1, 24);
|
||||
|
||||
*tempdata=SCU_GATE2CLK_BASE_SET&(~DIS_ITCMBUS_CLK)&(~DIS_DTCM0BUS_CLK)&(~DIS_DTCM1BUS_CLK);
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_CLKGATE2_CON,1);
|
||||
tcm_udelay(1, 24);
|
||||
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_DPLL_CON] |DSPPLL_POERDOWN; //dsp pll power down
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_DPLL_CON,1);
|
||||
tcm_udelay(1, 24);
|
||||
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_CPLL_CON] |CPLL_POERDOWN; //dsp pll power down
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_CPLL_CON,1);
|
||||
tcm_udelay(1, 24);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_PMU_CON] |=LCDC_POWER_DOWN;
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_PMU_CON] |DSP_POWER_DOWN;
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_PMU_CON,1);
|
||||
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_MODE_CON] &CPU_SLOW_MODE; //general slow mode
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_MODE_CON,1);
|
||||
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_APLL_CON] |ARMPLL_BYPASSMODE;//enable arm pll bypass
|
||||
*tempdata=rk2818_scu_reg[PM_SCU_APLL_CON] | ARMPLL_POERDOWN; //arm pll power down
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_APLL_CON,1);
|
||||
tcm_udelay(2, 24);
|
||||
|
||||
*tempdata=(rk2818_scu_reg[PM_SCU_CLKSEL0_CON]&PM_BIT_CLEAR(CLKSEL0_HCLK,2)&PM_BIT_CLEAR(CLKSEL0_PCLK,2))
|
||||
|PM_BIT_SET(CLKSEL0_HCLK,CLK_ARM1_H1,2)|PM_BIT_SET(CLKSEL0_PCLK,CLK_HCLK1_P1,2);
|
||||
rk2818_soc_updata_scureg(tempdata,PM_SCU_CLKSEL0_CON,1);
|
||||
tcm_udelay(2, 24);
|
||||
|
||||
*tempdata=(rk2818_scu_reg[PM_CLKSEL2_CON]&(~0xf))|0xF;
|
||||
rk2818_soc_updata_scureg(tempdata,PM_CLKSEL2_CON,1);
|
||||
|
||||
tcm_udelay(2, 24);
|
||||
|
||||
//*tempdata=rk2818_scu_reg[PM_SCU_PMU_CON] |DDR_POWER_DOWN;
|
||||
//rk2818_soc_updata_scureg(tempdata,PM_SCU_PMU_CON,0);
|
||||
|
||||
//*tempdata=rk2818_scu_reg[PM_SCU_SOFTRST_CON]|(1<<RST_DDR_BUS)|(1<<RST_DDR_CORE_LOGIC);//RST_ALL&(~(1<<RST_ARM));
|
||||
//rk2818_soc_updata_scureg(tempdata,PM_SCU_SOFTRST_CON,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
static void __tcmfunc rk2818_soc_general_reg_suspend(void)
|
||||
{
|
||||
struct rk2818_pm_soc_st *general=rk2818_soc_pm.general;
|
||||
struct rk2818_pm_soc_st *gpio0=rk2818_soc_pm.gpio0;
|
||||
struct rk2818_pm_soc_st *gpio1=rk2818_soc_pm.gpio1;
|
||||
|
||||
unsigned int *rk2818_general_reg=general->reg_ch;
|
||||
unsigned int *rk2818_gpio0_reg=gpio0->reg_ch;
|
||||
unsigned int *rk2818_gpio1_reg=gpio1->reg_ch;
|
||||
|
||||
int i;
|
||||
|
||||
#if 1
|
||||
general->reg_ctrbit|=(0x1<<PM_GPIO0_AB_PU_CON);
|
||||
rk2818_general_reg[PM_GPIO0_AB_PU_CON] =GPIO0_AB_NORMAL;
|
||||
|
||||
general->reg_ctrbit|=(0x1<<PM_GPIO0_CD_PU_CON);
|
||||
rk2818_general_reg[PM_GPIO0_CD_PU_CON] = GPIO0_CD_NORMAL;
|
||||
|
||||
general->reg_ctrbit|=(0x1<<PM_GPIO1_AB_PU_CON);
|
||||
rk2818_general_reg[PM_GPIO1_AB_PU_CON] = GPIO1_AB_NORMAL;
|
||||
|
||||
general->reg_ctrbit|=(0x1<<PM_GPIO1_CD_PU_CON);
|
||||
rk2818_general_reg[PM_GPIO1_CD_PU_CON] = GPIO1_CD_NORMAL;
|
||||
#endif
|
||||
general->reg_ctrbit|=(0x1<<PM_IOMUX_A_CON);
|
||||
general->reg_ctrbit|=(0x1<<PM_IOMUX_B_CON);
|
||||
|
||||
if(rk2818_soc_pm.general_reg_callback)
|
||||
{
|
||||
rk2818_soc_pm.general_reg_callback(general->reg_ch);
|
||||
}
|
||||
|
||||
rk2818_pm_save_reg(general->reg_base_addr,general->reg_ch,general->reg_num);
|
||||
|
||||
rk2818_pm_save_reg(gpio0->reg_base_addr,gpio0->reg_ch,gpio0->reg_num);
|
||||
rk2818_pm_save_reg(gpio1->reg_base_addr,gpio1->reg_ch,gpio1->reg_num);
|
||||
|
||||
}
|
||||
#endif
|
||||
static void rk2818_pm_reg_print(unsigned int *pm_save_reg,unsigned int *pm_ch_reg,int num,char *name)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
#ifdef RK2818_PM_PRT_ORIGINAL_REG
|
||||
printk("***the follow inf is %s original reg***\n",name);
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
printk(" %d,%x",i,pm_save_reg[i]);
|
||||
}
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
printk("***the follow inf is %s changed reg***\n",name);
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
printk(" %d,%x",i,pm_ch_reg[i]);
|
||||
}
|
||||
printk("\n");
|
||||
#endif
|
||||
}
|
||||
static void __tcmfunc rk2818_soc_resume(unsigned int *pm_save_reg,unsigned int *base_add,u16 regbit,int num)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
if((regbit>>i)&0x0001)
|
||||
base_add[i]=pm_save_reg[i];
|
||||
}
|
||||
}
|
||||
void __tcmfunc rk2818_socpm_suspend(void)
|
||||
{
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
rk2818_soc_scu_suspend();
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
|
||||
if(pm_ctr_callback&&pm_ctr_callback->general_reg_suspend)
|
||||
{
|
||||
pm_ctr_callback->general_reg_suspend();
|
||||
}
|
||||
#ifdef RK2818_PM_PRT_CHANGED_REG
|
||||
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.scu->reg_ch,rk2818_soc_pm.scu->reg_base_addr,
|
||||
rk2818_soc_pm.scu->reg_num);
|
||||
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.general->reg_ch,rk2818_soc_pm.general->reg_base_addr,
|
||||
rk2818_soc_pm.general->reg_num);
|
||||
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.gpio0->reg_ch,rk2818_soc_pm.gpio0->reg_base_addr,
|
||||
rk2818_soc_pm.gpio0->reg_num);
|
||||
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.gpio1->reg_ch,rk2818_soc_pm.gpio1->reg_base_addr,
|
||||
rk2818_soc_pm.gpio1->reg_num);
|
||||
#endif
|
||||
//rk2818_soc_arm_stop();
|
||||
|
||||
}
|
||||
void __tcmfunc rk2818_socpm_resume(void)
|
||||
{
|
||||
tcm_udelay(1, 24); //DRVDelayUs(100);
|
||||
rk2818_soc_resume(rk2818_soc_pm.scu->reg_save,rk2818_soc_pm.scu->reg_base_addr,
|
||||
rk2818_soc_pm.scu->reg_ctrbit,rk2818_soc_pm.scu->reg_num);
|
||||
tcm_udelay(2, 24);
|
||||
if(pm_ctr_callback->general_reg_suspend)
|
||||
{
|
||||
|
||||
rk2818_soc_resume(rk2818_soc_pm.general->reg_save,rk2818_soc_pm.general->reg_base_addr,
|
||||
rk2818_soc_pm.general->reg_ctrbit,rk2818_soc_pm.general->reg_num);
|
||||
|
||||
rk2818_soc_resume(rk2818_soc_pm.gpio0->reg_save,rk2818_soc_pm.gpio0->reg_base_addr,
|
||||
rk2818_soc_pm.gpio0->reg_ctrbit,rk2818_soc_pm.gpio0->reg_num);
|
||||
|
||||
rk2818_soc_resume(rk2818_soc_pm.gpio1->reg_save,rk2818_soc_pm.gpio1->reg_base_addr,
|
||||
rk2818_soc_pm.gpio1->reg_ctrbit,rk2818_soc_pm.gpio1->reg_num);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void __tcmfunc rk2818_socpm_suspend_first(void)
|
||||
{
|
||||
tcm_udelay(1, 24);
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.scu->reg_save,rk2818_soc_pm.scu->reg_base_addr,rk2818_soc_pm.scu->reg_num);
|
||||
//rk2818_pm_save_reg(rk2818_soc_pm.scu_tempreg,rk2818_soc_pm.scu->reg_base_addr,rk2818_soc_pm.scu->reg_num);
|
||||
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.general->reg_save,rk2818_soc_pm.general->reg_base_addr,rk2818_soc_pm.general->reg_num);
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.gpio0->reg_save,rk2818_soc_pm.gpio0->reg_base_addr,rk2818_soc_pm.gpio0->reg_num);
|
||||
rk2818_pm_save_reg(rk2818_soc_pm.gpio1->reg_save,rk2818_soc_pm.gpio1->reg_base_addr,rk2818_soc_pm.gpio1->reg_num);
|
||||
rk2818_soc_pm.scu->reg_ctrbit=0;
|
||||
rk2818_soc_pm.general->reg_ctrbit=0;
|
||||
rk2818_soc_pm.gpio0->reg_ctrbit=0x6db;
|
||||
rk2818_soc_pm.gpio1->reg_ctrbit=0x6db;
|
||||
|
||||
//rk2818_soc_pm.save_reg[0]=rk2818_ddr_reg[82];
|
||||
//rk2818_ddr_reg[82]=rk2818_ddr_reg[82]&(~(0xffff))&(~(0xf<<20));
|
||||
|
||||
if(pm_ctr_callback&&pm_ctr_callback->set_pin)
|
||||
pm_ctr_callback->set_pin();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void __tcmfunc rk2818_socpm_resume_last(void)
|
||||
{
|
||||
//unsigned int *rk2818_ddr_reg=(unsigned int *)RK2818_SDRAMC_BASE;
|
||||
|
||||
if(pm_ctr_callback&&pm_ctr_callback->resume_pin)
|
||||
pm_ctr_callback->resume_pin();
|
||||
|
||||
}
|
||||
|
||||
void rk2818_socpm_print(void)
|
||||
{
|
||||
rk2818_pm_reg_print(rk2818_soc_pm.scu->reg_save,rk2818_soc_pm.scu->reg_ch,
|
||||
rk2818_soc_pm.scu->reg_num,"scu");
|
||||
rk2818_pm_reg_print(rk2818_soc_pm.general->reg_save,rk2818_soc_pm.general->reg_ch,
|
||||
rk2818_soc_pm.general->reg_num,"general_general");
|
||||
rk2818_pm_reg_print(rk2818_soc_pm.gpio0->reg_save,rk2818_soc_pm.gpio0->reg_ch,
|
||||
rk2818_soc_pm.gpio0->reg_num,"gpio0");
|
||||
rk2818_pm_reg_print(rk2818_soc_pm.gpio1->reg_save,rk2818_soc_pm.gpio1->reg_ch,
|
||||
rk2818_soc_pm.gpio1->reg_num,"gpio1");
|
||||
}
|
||||
|
||||
|
||||
int rk2818_socpm_init(struct rk2818_pm_callback_st *call_back)
|
||||
{
|
||||
if(call_back==NULL)
|
||||
return -1;
|
||||
pm_ctr_callback = call_back;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if defined (CONFIG_RK2818_SOC_PM_DBG)
|
||||
|
||||
static bool check_attr_dbg_value(struct rk2818_pm_attr_dbg_st *attr)
|
||||
{
|
||||
if((attr->flag!=PM_DBG_SET_ONCE)&&(attr->flag!=PM_DBG_SET_ALWAY))
|
||||
return false;
|
||||
if(attr->bitsnum==0||attr->bitsnum>32)
|
||||
return false;
|
||||
|
||||
if(attr->regbits_off>31)
|
||||
return false;
|
||||
if((attr->regbits_off+attr->bitsnum)>32)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void setreg_form_socpm_attr(unsigned int *reg,int regoff,struct rk2818_pm_soc_st *soc)
|
||||
{
|
||||
struct rk2818_pm_attr_dbg_st *attr=soc->attr_dbg;
|
||||
int i;
|
||||
for(i=0;i<soc->attr_num;i++)
|
||||
{
|
||||
|
||||
if(check_attr_dbg_value(attr))
|
||||
{
|
||||
if(attr->regoff==regoff)
|
||||
{
|
||||
|
||||
*reg=(*reg)&PM_BIT_CLEAR(attr->regbits_off,attr->bitsnum)|PM_BIT_SET(attr->regbits_off,attr->value,attr->bitsnum);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rk2818_socpm_attr_int(void)
|
||||
{
|
||||
struct rk2818_pm_soc_st *scu=rk2818_soc_pm.scu;
|
||||
struct rk2818_pm_soc_st *general=rk2818_soc_pm.general;
|
||||
struct rk2818_pm_soc_st *gpio0=rk2818_soc_pm.gpio0;
|
||||
struct rk2818_pm_soc_st *gpio1=rk2818_soc_pm.gpio1;
|
||||
|
||||
|
||||
|
||||
memset(scu->attr_dbg,0,sizeof(struct rk2818_pm_attr_dbg_st)*scu->attr_num);
|
||||
memset(general->attr_dbg,0,sizeof(struct rk2818_pm_attr_dbg_st)*general->attr_num);
|
||||
memset(gpio0->attr_dbg,0,sizeof(struct rk2818_pm_attr_dbg_st)*gpio0->attr_num);
|
||||
memset(gpio1->attr_dbg,0,sizeof(struct rk2818_pm_attr_dbg_st)*gpio1->attr_num);
|
||||
}
|
||||
|
||||
#endif
|
||||
static u32 rk2818_socpm_attr_atoh(const unsigned char *in, unsigned int len)
|
||||
{
|
||||
u32 sum = 0;
|
||||
unsigned int mult = 1;
|
||||
unsigned char c;
|
||||
|
||||
while (len) {
|
||||
c = in[len - 1];
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
sum += mult * (c - '0');
|
||||
else if ((c >= 'A') && (c <= 'F'))
|
||||
sum += mult * (c - ('A' - 10));
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
sum += mult * (c - ('a' - 10));
|
||||
mult *= 16;
|
||||
--len;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
static bool rk2818_socpm_attr_is_number(char *p)
|
||||
{
|
||||
if((*p>='0'&&*p<='9')||(*p>='a'&&*p<='f')||(*p>='A'&&*p<='F'))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool rk2818_socpm_attr_check_value(unsigned int *info)
|
||||
{
|
||||
if((info[PM_DBG_USER_FLAG]!=PM_DBG_SET_ONCE)&&(info[PM_DBG_USER_FLAG]!=PM_DBG_SET_ALWAY))
|
||||
return false;
|
||||
if(info[PM_DBG_USER_BITS_NUM]==0||info[PM_DBG_USER_BITS_NUM]>32)
|
||||
return false;
|
||||
if((info[PM_DBG_USER_BITS_NUM]+info[PM_DBG_USER_BITS_OFF])>31)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool rk2818_socpm_attr_reset_samesituation(struct rk2818_pm_attr_dbg_st *dbg,int num,unsigned int *info)
|
||||
{
|
||||
|
||||
int i;
|
||||
for (i=0;i<num;i++)
|
||||
{
|
||||
|
||||
if((dbg[i].regoff==info[PM_DBG_USER_REGOFF])&&
|
||||
((dbg[i].regbits_off==info[PM_DBG_USER_BITS_OFF])))
|
||||
{
|
||||
|
||||
dbg[i].value=info[PM_DBG_USER_VALUE];
|
||||
dbg[i].bitsnum=info[PM_DBG_USER_BITS_NUM];
|
||||
dbg[i].flag=info[PM_DBG_USER_FLAG];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool rk2818_socpm_attr_set_value(struct rk2818_pm_attr_dbg_st *attr_dbg,int num,unsigned int *info)
|
||||
{
|
||||
int i;
|
||||
if(rk2818_socpm_attr_reset_samesituation(attr_dbg,num,info))
|
||||
return true;
|
||||
for (i=0;i<num;i++)
|
||||
{
|
||||
|
||||
if(attr_dbg[i].flag==PM_DBG_NOT_SET)
|
||||
{
|
||||
attr_dbg[i].regoff=info[PM_DBG_USER_REGOFF];
|
||||
attr_dbg[i].regbits_off=info[PM_DBG_USER_BITS_OFF];
|
||||
attr_dbg[i].value=info[PM_DBG_USER_VALUE];
|
||||
attr_dbg[i].bitsnum=info[PM_DBG_USER_BITS_NUM];
|
||||
attr_dbg[i].flag=info[PM_DBG_USER_FLAG];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rk2818_socpm_attr_parse_settinginf(struct rk2818_pm_soc_st *socpm,const char *buf, size_t n)
|
||||
{
|
||||
const char *p=buf;
|
||||
char *e;
|
||||
//int len;
|
||||
int i=0;
|
||||
unsigned int info[PM_DBG_USER_END];//regoff bitsoff value bitsnum user once
|
||||
//int oneline=-1;
|
||||
|
||||
printk("3x pm dbg %s\n",p);
|
||||
|
||||
memset(&info[0],0,4*PM_DBG_USER_END);
|
||||
|
||||
|
||||
for(;p<(buf+n);p++)
|
||||
{
|
||||
if(*p=='s'||*p=='S')
|
||||
{
|
||||
if(*p!=' ')
|
||||
continue;
|
||||
|
||||
while(*p==' ')
|
||||
{
|
||||
if(p>=(buf+n))
|
||||
return true;
|
||||
p++;
|
||||
}
|
||||
for(i=0;i<PM_DBG_USER_END;)
|
||||
{
|
||||
if(rk2818_socpm_attr_is_number((char*)p))
|
||||
{
|
||||
e= memchr(p, ' ', n-(p-buf));
|
||||
if(e==NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(e>=(buf+n))
|
||||
return true;
|
||||
info[i]=rk2818_socpm_attr_atoh(p,e-p);
|
||||
i++;
|
||||
p=e;
|
||||
if(i==(PM_DBG_USER_END-1))
|
||||
{
|
||||
if(rk2818_socpm_attr_set_value(socpm->attr_dbg,socpm->attr_num,&info[0])==true)
|
||||
return true;
|
||||
|
||||
printk("value is%x, regoff is%x bitsoff is%x bitsnum is%x ctr is%x\n",
|
||||
info[PM_DBG_USER_VALUE],info[PM_DBG_USER_REGOFF],info[PM_DBG_USER_BITS_OFF],
|
||||
info[PM_DBG_USER_BITS_NUM], info[PM_DBG_USER_FLAG]);
|
||||
|
||||
memset(&info[0],0,sizeof(int)*PM_DBG_USER_END);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((*p==' '))
|
||||
{
|
||||
while(*p==' ')
|
||||
{
|
||||
if(p>=(buf+n))
|
||||
return false;
|
||||
p++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static char * rk2818_socpm_attr_show_userinfo(struct rk2818_pm_soc_st *socpm,unsigned char regoff,char *buf)
|
||||
{
|
||||
int i;
|
||||
struct rk2818_pm_attr_dbg_st *attr_dbg;
|
||||
for(i=0;i<socpm->attr_num;i++)
|
||||
{
|
||||
if((attr_dbg[i].regoff==regoff)&&(attr_dbg[i].flag!=PM_ATTR_NO_CTR)&&attr_dbg[i].bitsnum)
|
||||
buf += sprintf(buf, "value is%x, regoff is%x bitsoff is%x bitsnum is%x ctr is%x\n",
|
||||
attr_dbg[i].value,attr_dbg[i].regoff,attr_dbg[i].regbits_off, attr_dbg[i].bitsnum, attr_dbg[i].flag);
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static ssize_t rk2818_socpm_attr_show_info(struct rk2818_pm_soc_st *socpm,char *name,char *buf)
|
||||
{
|
||||
|
||||
char *s = buf;
|
||||
int i;
|
||||
s += sprintf(s, "this is the %s reg value,when system enter suspend lately\n",name);
|
||||
for(i=0;i<socpm->reg_num;i++)
|
||||
{
|
||||
s += sprintf(s, "reg[%d] is %x,user seting is in follow\n", i,socpm->reg_ch[i]);
|
||||
s=rk2818_socpm_attr_show_userinfo(socpm,s,i);
|
||||
|
||||
}
|
||||
|
||||
if (s != buf)
|
||||
/* convert the last space to a newline */
|
||||
*(s-1) = '\n';
|
||||
return (s - buf);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t rk2818_socpm_attr_show(int type,char *buf)
|
||||
{
|
||||
struct rk2818_pm_soc_st *socpm;
|
||||
char name[4][8]={"scu","general","gpio0","gpio1"};
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
socpm=rk2818_soc_pm.scu;
|
||||
break;
|
||||
case 1:
|
||||
socpm=rk2818_soc_pm.general;
|
||||
break;
|
||||
case 2:
|
||||
socpm=rk2818_soc_pm.gpio0;
|
||||
break;
|
||||
case 3:
|
||||
socpm=rk2818_soc_pm.gpio1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
return rk2818_socpm_attr_show_info(socpm,name[type],buf);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bool rk2818_socpm_attr_store(int type,const char *buf, size_t n)
|
||||
{
|
||||
struct rk2818_pm_soc_st *socpm;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
socpm=rk2818_soc_pm.scu;
|
||||
break;
|
||||
case 1:
|
||||
socpm=rk2818_soc_pm.general;
|
||||
break;
|
||||
case 2:
|
||||
socpm=rk2818_soc_pm.gpio0;
|
||||
break;
|
||||
case 3:
|
||||
socpm=rk2818_soc_pm.gpio1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
return rk2818_socpm_attr_parse_settinginf(socpm,buf,n);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void rk2818_pm_updata_scu_reg(int regoff)
|
||||
{
|
||||
if(0)//(rk2818_soc_pm.scu_suspend)
|
||||
{
|
||||
rk2818_soc_pm.scu_suspend(rk2818_soc_pm.scu_tempreg[regoff],regoff);
|
||||
}
|
||||
rk2818_soc_pm.scu->reg_base_addr[regoff]=rk2818_soc_pm.scu_tempreg[regoff];
|
||||
rk2818_soc_pm.scu->reg_ctrbit|=(0x1<<regoff);
|
||||
tcm_printascii("3x scu");
|
||||
|
||||
}
|
||||
|
||||
static void __tcmfunc rk2818_soc_scu_suspend(void)
|
||||
{
|
||||
//unsigned int *rk2818_scu_reg=scu->reg_base_addr;
|
||||
unsigned int *rk2818_scu_reg=rk2818_soc_pm.scu_tempreg;
|
||||
|
||||
|
||||
|
||||
rk2818_scu_reg[PM_SCU_CLKGATE0_CON] = SCU_GATE0CLK_ALL_DIS&(~DIS_ARM_CLK)&(~DIS_TIMER_CLK)
|
||||
&(~DIS_GPIO0_CLK)&(~DIS_GPIO1_CLK)&(~DIS_INTC_CLK)/*&(~DIS_UART0_CLK)&(~DIS_UART1_CLK)*/;
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_CLKGATE0_CON);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_CLKGATE1_CON] =SCU_GATE1CLK_BASE_SET/*|EN_AXI_CLK&(~DIS_DDR_CLK)&(~DIS_DDR_HCLK)*/;
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_CLKGATE1_CON);
|
||||
|
||||
|
||||
rk2818_scu_reg[PM_SCU_CLKGATE2_CON] =SCU_GATE2CLK_BASE_SET&(~DIS_ITCMBUS_CLK)&(~DIS_DTCM0BUS_CLK)&(~DIS_DTCM1BUS_CLK);
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_CLKGATE2_CON);
|
||||
|
||||
|
||||
|
||||
rk2818_scu_reg[PM_SCU_CLKSEL0_CON]&=PM_BIT_CLEAR(CLKSEL0_HCLK,2)&PM_BIT_CLEAR(CLKSEL0_PCLK,2)
|
||||
|PM_BIT_SET(CLKSEL0_HCLK,CLK_ARM1_H1,2)|PM_BIT_SET(CLKSEL0_PCLK,CLK_HCLK1_P1,2);
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_CLKSEL0_CON);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_DPLL_CON] |= DSPPLL_POERDOWN; //dsp pll power down
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_DPLL_CON);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_CPLL_CON] |= CPLL_POERDOWN; //dsp pll power down
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_CPLL_CON);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_PMU_CON] |=LCDC_POWER_DOWN;
|
||||
rk2818_scu_reg[PM_SCU_PMU_CON] |=DSP_POWER_DOWN;
|
||||
|
||||
|
||||
rk2818_scu_reg[PM_SCU_MODE_CON] &= CPU_SLOW_MODE; //general slow mode
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_MODE_CON);
|
||||
|
||||
rk2818_scu_reg[PM_SCU_APLL_CON] |= ARMPLL_BYPASSMODE;//enable arm pll bypass
|
||||
rk2818_scu_reg[PM_SCU_APLL_CON] |= ARMPLL_POERDOWN; //arm pll power down
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_APLL_CON);
|
||||
|
||||
rk2818_scu_reg[PM_CLKSEL2_CON] =(rk2818_scu_reg[PM_CLKSEL2_CON]&(~0xf))|0xF;
|
||||
rk2818_pm_updata_scu_reg(PM_CLKSEL2_CON);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rk2818_pm_updata_scu_reg(PM_SCU_PMU_CON);
|
||||
//rk2818_scu_reg[PM_SCU_PMU_CON] |=DDR_POWER_DOWN;
|
||||
//rk2818_pm_updata_scu_reg(PM_SCU_PMU_CON);
|
||||
|
||||
//scu->reg_ctrbit|=(0x1<<PM_SCU_SOFTRST_CON);
|
||||
//rk2818_scu_reg[PM_SCU_SOFTRST_CON]|=(1<<RST_DDR_BUS)|(1<<RST_DDR_CORE_LOGIC);//RST_ALL&(~(1<<RST_ARM));
|
||||
//rk2818_pm_updata_scu_reg(PM_SCU_SOFTRST_CON);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1,251 +0,0 @@
|
|||
/* linux/arch/arm/mach-rk2818/timer.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/init.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#define TIMER_LOAD_COUNT 0x0000
|
||||
#define TIMER_CUR_VALUE 0x0004
|
||||
#define TIMER_CONTROL_REG 0x0008
|
||||
#define TIMER_EOI 0x000C
|
||||
#define TIMER_INT_STATUS 0x0010
|
||||
|
||||
#define TIMER_DISABLE 4
|
||||
#define TIMER_ENABLE 3
|
||||
#define TIMER_ENABLE_FREE_RUNNING 1
|
||||
|
||||
#define CHECK_VBUS_MS 1000 /* ms */
|
||||
|
||||
#define RK_TIMER_ENABLE(n) writel(TIMER_ENABLE, RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
|
||||
#define RK_TIMER_ENABLE_FREE_RUNNING(n) writel(TIMER_ENABLE_FREE_RUNNING, RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
|
||||
#define RK_TIMER_DISABLE(n) writel(TIMER_DISABLE, RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
|
||||
|
||||
#define RK_TIMER_SETCOUNT(n, count) writel(count, RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_LOAD_COUNT)
|
||||
#define RK_TIMER_GETCOUNT(n) readl(RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_LOAD_COUNT)
|
||||
|
||||
#define RK_TIMER_READVALUE(n) readl(RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_CUR_VALUE)
|
||||
#define RK_TIMER_INT_CLEAR(n) readl(RK2818_TIMER_BASE + 0x14 * (n - 1) + TIMER_EOI)
|
||||
|
||||
#define TIMER_CLKEVT 2 /* timer2 */
|
||||
#define IRQ_NR_TIMER_CLKEVT IRQ_NR_TIMER2
|
||||
#define TIMER_CLKEVT_NAME "timer2"
|
||||
|
||||
#define TIMER_CLKSRC 3 /* timer3 */
|
||||
#define IRQ_NR_TIMER_CLKSRC IRQ_NR_TIMER3
|
||||
#define TIMER_CLKSRC_NAME "timer3"
|
||||
|
||||
static struct clk *timer_clk;
|
||||
static volatile unsigned long timer_mult; /* timer count = cycle * timer_mult */
|
||||
|
||||
void rk2818_timer_update_mult(void)
|
||||
{
|
||||
if (timer_clk)
|
||||
timer_mult = clk_get_rate(timer_clk) / 1000000;
|
||||
}
|
||||
|
||||
static int rk2818_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt)
|
||||
{
|
||||
RK_TIMER_DISABLE(TIMER_CLKEVT);
|
||||
RK_TIMER_SETCOUNT(TIMER_CLKEVT, cycles * timer_mult);
|
||||
RK_TIMER_ENABLE(TIMER_CLKEVT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk2818_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
RK_TIMER_DISABLE(TIMER_CLKEVT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct clock_event_device rk2818_timer_clockevent = {
|
||||
.name = TIMER_CLKEVT_NAME,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 32,
|
||||
.rating = 200,
|
||||
.set_next_event = rk2818_timer_set_next_event,
|
||||
.set_mode = rk2818_timer_set_mode,
|
||||
};
|
||||
|
||||
static irqreturn_t rk2818_timer_clockevent_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = dev_id;
|
||||
|
||||
RK_TIMER_INT_CLEAR(TIMER_CLKEVT);
|
||||
RK_TIMER_DISABLE(TIMER_CLKEVT);
|
||||
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction rk2818_timer_clockevent_irq = {
|
||||
.name = TIMER_CLKEVT_NAME,
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.handler = rk2818_timer_clockevent_interrupt,
|
||||
.irq = IRQ_NR_TIMER_CLKEVT,
|
||||
.dev_id = &rk2818_timer_clockevent,
|
||||
};
|
||||
|
||||
static int rk2818_timer_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
|
||||
{
|
||||
if (val == CPUFREQ_POSTCHANGE) {
|
||||
rk2818_timer_update_mult();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block rk2818_timer_cpufreq_notifier_block = {
|
||||
.notifier_call = rk2818_timer_cpufreq_notifier,
|
||||
.priority = 0x7ffffff,
|
||||
};
|
||||
|
||||
static __init int rk2818_timer_init_cpufreq(void)
|
||||
{
|
||||
cpufreq_register_notifier(&rk2818_timer_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall_sync(rk2818_timer_init_cpufreq);
|
||||
|
||||
static __init int rk2818_timer_init_clockevent(void)
|
||||
{
|
||||
struct clock_event_device *ce = &rk2818_timer_clockevent;
|
||||
|
||||
timer_clk = clk_get(NULL, "timer");
|
||||
rk2818_timer_update_mult();
|
||||
|
||||
RK_TIMER_DISABLE(TIMER_CLKEVT);
|
||||
|
||||
setup_irq(rk2818_timer_clockevent_irq.irq, &rk2818_timer_clockevent_irq);
|
||||
|
||||
ce->mult = div_sc(1000000, NSEC_PER_SEC, ce->shift);
|
||||
ce->max_delta_ns = clockevent_delta2ns(0xFFFFFFFFUL / 256, ce); // max pclk < 256MHz
|
||||
ce->min_delta_ns = clockevent_delta2ns(1, ce) + 1;
|
||||
|
||||
ce->cpumask = cpumask_of(0);
|
||||
|
||||
clockevents_register_device(ce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cycle_t rk2818_timer_read(struct clocksource *cs)
|
||||
{
|
||||
return ~RK_TIMER_READVALUE(TIMER_CLKSRC);
|
||||
}
|
||||
|
||||
static struct clocksource rk2818_timer_clocksource = {
|
||||
.name = TIMER_CLKSRC_NAME,
|
||||
.rating = 200,
|
||||
.read = rk2818_timer_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 26,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_RK28_USB_WAKE
|
||||
static irqreturn_t rk2818_timer_clocksource_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
RK_TIMER_INT_CLEAR(TIMER_CLKSRC);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction rk2818_timer_clocksource_irq = {
|
||||
.name = TIMER_CLKSRC_NAME,
|
||||
.handler = rk2818_timer_clocksource_interrupt,
|
||||
.irq = IRQ_NR_TIMER_CLKSRC,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init rk2818_timer_init_clocksource(void)
|
||||
{
|
||||
static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n";
|
||||
struct clocksource *cs = &rk2818_timer_clocksource;
|
||||
|
||||
RK_TIMER_DISABLE(TIMER_CLKSRC);
|
||||
RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF);
|
||||
RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC);
|
||||
|
||||
cs->mult = clocksource_hz2mult(24000000, cs->shift);
|
||||
if (clocksource_register(cs))
|
||||
printk(err, cs->name);
|
||||
|
||||
#ifdef CONFIG_RK28_USB_WAKE
|
||||
setup_irq(rk2818_timer_clocksource_irq.irq, &rk2818_timer_clocksource_irq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init rk2818_timer_init(void)
|
||||
{
|
||||
rk2818_timer_init_clocksource();
|
||||
rk2818_timer_init_clockevent();
|
||||
}
|
||||
|
||||
struct sys_timer rk2818_timer = {
|
||||
.init = rk2818_timer_init
|
||||
};
|
||||
|
||||
#ifdef CONFIG_RK28_USB_WAKE
|
||||
void rockchip_timer_clocksource_suspend_resume(int suspend)
|
||||
{
|
||||
RK_TIMER_DISABLE(TIMER_CLKSRC);
|
||||
if (suspend) {
|
||||
RK_TIMER_SETCOUNT(TIMER_CLKSRC, 24000 * CHECK_VBUS_MS);
|
||||
RK_TIMER_ENABLE(TIMER_CLKSRC);
|
||||
} else {
|
||||
RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF);
|
||||
RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC);
|
||||
}
|
||||
}
|
||||
|
||||
int rockchip_timer_clocksource_irq_checkandclear(void)
|
||||
{
|
||||
u32 l, h;
|
||||
|
||||
l = readl(RK2818_INTC_BASE + IRQ_REG_MASKSTATUS_L);
|
||||
h = readl(RK2818_INTC_BASE + IRQ_REG_MASKSTATUS_H);
|
||||
|
||||
/* clock source irq */
|
||||
if (l & (1 << IRQ_NR_TIMER_CLKSRC)) {
|
||||
RK_TIMER_INT_CLEAR(TIMER_CLKSRC);
|
||||
l &= ~(1 << IRQ_NR_TIMER_CLKSRC);
|
||||
}
|
||||
|
||||
/* 20091103,HSL@RK,all irq must be handle !*/
|
||||
l |= (h & 0xffff);
|
||||
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1608,7 +1608,6 @@ kb9263 MACH_KB9263 KB9263 1612
|
|||
mt7108 MACH_MT7108 MT7108 1613
|
||||
smtr2440 MACH_SMTR2440 SMTR2440 1614
|
||||
manao MACH_MANAO MANAO 1615
|
||||
rk2818 MACH_RK2818 RK2818 1616
|
||||
gulfstream_kp MACH_GULFSTREAM_KP GULFSTREAM_KP 1617
|
||||
lanreadyfn522 MACH_LANREADYFN522 LANREADYFN522 1618
|
||||
arma37 MACH_ARMA37 ARMA37 1619
|
||||
|
|
@ -2536,4 +2535,4 @@ c3ax03 MACH_C3AX03 C3AX03 2549
|
|||
mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
|
||||
esyx MACH_ESYX ESYX 2551
|
||||
bulldog MACH_BULLDOG BULLDOG 2553
|
||||
rk29 MACH_RK29 RK29 2929
|
||||
rk29 MACH_RK29 RK29 2929
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ source "drivers/spi/Kconfig"
|
|||
|
||||
source "drivers/adc/Kconfig"
|
||||
|
||||
source "drivers/fpga/Kconfig"
|
||||
|
||||
source "drivers/headset_observe/Kconfig"
|
||||
|
||||
source "drivers/pps/Kconfig"
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ obj-$(CONFIG_SCSI) += scsi/
|
|||
obj-$(CONFIG_ATA) += ata/
|
||||
obj-$(CONFIG_MTD) += mtd/
|
||||
obj-$(CONFIG_SPI) += spi/
|
||||
obj-$(CONFIG_SPI_FPGA) += fpga/
|
||||
obj-y += headset_observe/
|
||||
obj-y += net/
|
||||
obj-$(CONFIG_ATM) += atm/
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
#
|
||||
# FPGA driver configuration
|
||||
#
|
||||
# NOTE: This FPGA(ice65l08xx) support spi2uart,spi2gpio,spi2i2c and spi2dpram.
|
||||
#
|
||||
|
||||
menuconfig SPI_FPGA
|
||||
bool "SPI FPGA(ice65l08xx) support"
|
||||
#depends on SPI && SPIM_RK2818
|
||||
help
|
||||
This fpga(ice65l08xx) is used for spi2uart,spi2gpio,spi2i2c,spi2dpram.
|
||||
|
||||
if SPI_FPGA
|
||||
|
||||
config SPI_FPGA_INIT
|
||||
tristate "spi fpga init support"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
fpga driver for spi init.
|
||||
|
||||
if SPI_FPGA_INIT
|
||||
config SPI_FPGA_INIT_DEBUG
|
||||
boolean "Debug support for spi fpga init drivers"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say "yes" to enable debug messaging in spi fpga init drivers.
|
||||
endif
|
||||
|
||||
if SPI_FPGA_INIT
|
||||
config SPI_FPGA_UART
|
||||
tristate "spi to uart support"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
fpga driver for spi to uart.
|
||||
|
||||
if SPI_FPGA_UART
|
||||
config SPI_UART_DEBUG
|
||||
boolean "Debug support for spi to uart drivers"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say "yes" to enable debug messaging in spi to uart drivers.
|
||||
endif
|
||||
|
||||
config SPI_FPGA_GPIO
|
||||
tristate "spi to gpio support"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
fpga driver for spi to gpio.
|
||||
|
||||
if SPI_FPGA_GPIO
|
||||
config SPI_GPIO_DEBUG
|
||||
boolean "Debug support for spi to gpio drivers"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say "yes" to enable debug messaging in spi to gpio drivers.
|
||||
endif
|
||||
|
||||
config SPI_FPGA_I2C
|
||||
tristate "spi to i2c support"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
fpga driver for spi to i2c.
|
||||
|
||||
if SPI_FPGA_I2C
|
||||
config SPI_I2C_DEBUG
|
||||
boolean "Debug support for spi to i2c drivers"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say "yes" to enable debug messaging in spi to i2c drivers.
|
||||
endif
|
||||
|
||||
config SPI_FPGA_DPRAM
|
||||
tristate "spi to dpram support"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
fpga driver for spi to dpram.
|
||||
|
||||
if SPI_FPGA_DPRAM
|
||||
config SPI_DPRAM_DEBUG
|
||||
boolean "Debug support for spi to dpram drivers"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Say "yes" to enable debug messaging in spi to dpram drivers.
|
||||
endif
|
||||
|
||||
config SPI_FPGA_FW
|
||||
tristate "spi fpga firmware online"
|
||||
depends on SPI && SPIM_RK2818
|
||||
help
|
||||
load fpga firmware online.
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#
|
||||
# Makefile for fpga(ice65l08xx) drivers.
|
||||
#
|
||||
|
||||
# fpga drivers
|
||||
obj-$(CONFIG_SPI_FPGA_INIT) += spi_fpga_init.o
|
||||
obj-$(CONFIG_SPI_FPGA_UART) += spi_uart.o
|
||||
obj-$(CONFIG_SPI_FPGA_GPIO) += spi_gpio.o
|
||||
obj-$(CONFIG_SPI_FPGA_I2C) += spi_i2c.o
|
||||
obj-$(CONFIG_SPI_FPGA_DPRAM) += spi_dpram.o
|
||||
obj-$(CONFIG_SPI_FPGA_FW) += spi_fpga_fw.o
|
||||
|
|
@ -1,844 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_DPRAM_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define SPI_DPRAM_TEST 0
|
||||
|
||||
/*****RAM0 for bp write and ap read*****/
|
||||
#define SPI_DPRAM_BPWRITE_START 0
|
||||
#define SPI_DPRAM_BPWRITE_END 0x0fff
|
||||
#define SPI_DPRAM_BPWRITE_SIZE 0x1000 // 4K*16bits
|
||||
/*****RAM1 for ap write and bp read*****/
|
||||
#define SPI_DPRAM_APWRITE_START 0x1000
|
||||
#define SPI_DPRAM_APWRITE_END 0x17ff
|
||||
#define SPI_DPRAM_APWRITE_SIZE 0x0800 // 2K*16bits
|
||||
/*****RAM2 for log of bp write and ap read*****/
|
||||
#define SPI_DPRAM_LOG_BPWRITE_START 0x2000
|
||||
#define SPI_DPRAM_LOG_BPWRITE_END 0x23ff
|
||||
#define SPI_DPRAM_LOG_BPWRITE_SIZE 0x0400 // 1K*16bits
|
||||
/*****RAM3 for log of ap write and bp read*****/
|
||||
#define SPI_DPRAM_LOG_APWRITE_START 0x3000
|
||||
#define SPI_DPRAM_LOG_APWRITE_END 0x33ff
|
||||
#define SPI_DPRAM_LOG_APWRITE_SIZE 0x0400 // 1K*16bits
|
||||
|
||||
|
||||
#define SPI_DPRAM_PTR0_BPWRITE_APREAD 0X3fee
|
||||
#define SPI_DPRAM_PTR0_APWRITE_BPREAD 0X3ff0
|
||||
|
||||
#define SPI_DPRAM_PTR1_BPWRITE_APREAD 0x3ff2
|
||||
#define SPI_DPRAM_PTR1_APWRITE_BPREAD 0x3ff4
|
||||
|
||||
#define SPI_DPRAM_PTR2_BPWRITE_APREAD 0x3ff6
|
||||
#define SPI_DPRAM_PTR2_APWRITE_BPREAD 0x3ff8
|
||||
|
||||
#define SPI_DPRAM_PTR3_BPWRITE_APREAD 0x3ffa
|
||||
#define SPI_DPRAM_PTR3_APWRITE_BPREAD 0x3ffc
|
||||
|
||||
#define SPI_DPRAM_MAILBOX_BPIRQ 0x3ffe
|
||||
#define SPI_DPRAM_MAILBOX_APIRQ 0x3fff
|
||||
#define SPI_DPRAM_MAILBOX_BPACK 0x3ffb
|
||||
#define SPI_DPRAM_MAILBOX_APACK 0x3ffd
|
||||
|
||||
/*mailbox comminication's definition*/
|
||||
#define MAILBOX_BPSEND_IRQ (0<<15)
|
||||
#define MAILBOX_BPSEND_ACK (1<<15)
|
||||
#define MAILBOX_APSEND_IRQ (0<<15)
|
||||
#define MAILBOX_APSEND_ACK (1<<15)
|
||||
#define MAILBOX_RAM0 (0<<13)
|
||||
#define MAILBOX_RAM1 (1<<13)
|
||||
#define MAILBOX_RAM2 (2<<13)
|
||||
#define MAILBOX_RAM3 (3<<13)
|
||||
|
||||
#define PIN_BPSEND_ACK RK2818_PIN_PE0
|
||||
#define PIN_APSEND_ACK RK2818_PIN_PF7
|
||||
|
||||
#define MAX_SPI_LEN 512 //the bytes of spi write or read one time
|
||||
|
||||
|
||||
static int spi_dpram_write_buf(struct spi_dpram *dpram, unsigned short int addr, unsigned char *buf, unsigned int len)
|
||||
{
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL) | ICE_SEL_DPRAM_WRITE);
|
||||
unsigned char tx_buf[MAX_SPI_LEN+3];
|
||||
int i,ret,mod,num,count;
|
||||
|
||||
#if 0
|
||||
unsigned char *p = buf;
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
DBG("%s:buf[%d]=0x%x\n",__FUNCTION__,i,*p);
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
|
||||
mod = len%MAX_SPI_LEN;
|
||||
if(!mod)
|
||||
num = len/MAX_SPI_LEN;
|
||||
else
|
||||
num = len/MAX_SPI_LEN + 1;
|
||||
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
if(i == num -1)
|
||||
{
|
||||
if(!mod)
|
||||
count = MAX_SPI_LEN;
|
||||
else
|
||||
count = mod;
|
||||
memcpy(tx_buf + 3, buf+i*MAX_SPI_LEN, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = MAX_SPI_LEN;
|
||||
memcpy(tx_buf + 3, buf+i*MAX_SPI_LEN, count);
|
||||
}
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) & 0xff);
|
||||
ret = spi_write(port->spi, tx_buf, count+3);
|
||||
if(ret)
|
||||
{
|
||||
DBG("%s:spi_write err! i=%d\n",__FUNCTION__,i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_dpram_read_buf(struct spi_dpram *dpram, unsigned short int addr, unsigned char *buf, unsigned int len)
|
||||
{
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[4];
|
||||
unsigned char stat;
|
||||
int i,mod,num,count;
|
||||
|
||||
mod = len%MAX_SPI_LEN;
|
||||
if(!mod)
|
||||
num = len/MAX_SPI_LEN;
|
||||
else
|
||||
num = len/MAX_SPI_LEN + 1;
|
||||
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
if(i == num -1)
|
||||
{
|
||||
if(!mod)
|
||||
count = MAX_SPI_LEN;
|
||||
else
|
||||
count = mod;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = MAX_SPI_LEN;
|
||||
}
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) & 0xff);
|
||||
tx_buf[3] = 0;//give fpga 8 clks for reading data
|
||||
|
||||
stat = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), buf + i*MAX_SPI_LEN, count);
|
||||
if(stat)
|
||||
{
|
||||
DBG("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_write_word(struct spi_dpram *dpram, unsigned short int addr, unsigned int size)
|
||||
{
|
||||
int ret;
|
||||
//int i;
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL) | ICE_SEL_DPRAM_WRITE);
|
||||
unsigned char tx_buf[5];
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((addr << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((addr << 1) & 0xff);
|
||||
tx_buf[3] = (size>>8);
|
||||
tx_buf[4] = (size&0xff);
|
||||
|
||||
//for(i=0;i<5;i++)
|
||||
//{
|
||||
// printk("%s:tx_buf[%d]=0x%x\n",__FUNCTION__,i,tx_buf[i]);
|
||||
//}
|
||||
|
||||
ret = spi_write(port->spi, tx_buf, sizeof(tx_buf));
|
||||
if(ret)
|
||||
{
|
||||
DBG("%s:spi_write err!\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_word(struct spi_dpram *dpram, unsigned short int addr)
|
||||
{
|
||||
int ret;
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[4],rx_buf[2];
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((addr << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((addr << 1) & 0xff);
|
||||
tx_buf[3] = 0;//give fpga 8 clks for reading data
|
||||
|
||||
ret = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf));
|
||||
if(ret)
|
||||
{
|
||||
DBG("%s:spi_write_then_read err!\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = (rx_buf[0] << 8) | rx_buf[1];
|
||||
|
||||
return (ret&0xffff);
|
||||
|
||||
}
|
||||
|
||||
int spi_dpram_write_ptr(struct spi_dpram *dpram, unsigned short int addr, unsigned int size)
|
||||
{
|
||||
return spi_dpram_write_word(dpram, addr, size);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_ptr(struct spi_dpram *dpram, unsigned short int addr)
|
||||
{
|
||||
return spi_dpram_read_word(dpram, addr);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_write_irq(struct spi_dpram *dpram, unsigned int mailbox)
|
||||
{
|
||||
return spi_dpram_write_word(dpram, SPI_DPRAM_MAILBOX_APIRQ,mailbox);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_irq(struct spi_dpram *dpram)
|
||||
{
|
||||
return spi_dpram_read_word(dpram, SPI_DPRAM_MAILBOX_BPIRQ);
|
||||
}
|
||||
|
||||
int spi_dpram_write_ack(struct spi_dpram *dpram, unsigned int mailbox)
|
||||
{
|
||||
return spi_dpram_write_word(dpram, SPI_DPRAM_MAILBOX_APACK,mailbox);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_ack(struct spi_dpram *dpram)
|
||||
{
|
||||
return spi_dpram_read_word(dpram, SPI_DPRAM_MAILBOX_BPACK);
|
||||
}
|
||||
|
||||
int gNumSendInt=0,gLastNumSendInt = 0;
|
||||
int gNumSendAck=0,gLastNumSendAck = 0;
|
||||
int gNumRecInt=0,gNumLastRecInt = 0;
|
||||
int gNumCount = 0;
|
||||
unsigned char buf_dpram[SPI_DPRAM_BPWRITE_SIZE<<1];
|
||||
|
||||
int gRecCount = 0;
|
||||
|
||||
//really is spi_dpram_irq_work_handler after dpram's pin is exchanged
|
||||
static void spi_dpram_irq_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, dpram.spi_dpram_irq_work);
|
||||
|
||||
unsigned short int mbox = port->dpram.read_irq(&port->dpram);
|
||||
unsigned int ptr,len;
|
||||
int i;
|
||||
char temp,*p;
|
||||
DBG("Enter::%s,mbox=%d\n",__FUNCTION__,mbox);
|
||||
//gNumRecInt = mbox & 0x1fff;
|
||||
//if(gNumRecInt - gNumLastRecInt !=1)
|
||||
//if(++gNumLastRecInt > (1<<12))
|
||||
//gNumLastRecInt = 0;
|
||||
//printk("gNumRecInt=%d,gLastNumInt=%d\n",gNumRecInt,gNumLastRecInt);
|
||||
|
||||
if((mbox&MAILBOX_RAM3) == MAILBOX_RAM0)
|
||||
{
|
||||
//RAM0
|
||||
ptr = port->dpram.read_ptr(&port->dpram,SPI_DPRAM_PTR0_BPWRITE_APREAD);
|
||||
if(ptr%2)
|
||||
len = ptr+1;
|
||||
else
|
||||
len = ptr;
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START, port->dpram.prx, len);
|
||||
port->dpram.rec_len += ptr;
|
||||
gRecCount = port->dpram.rec_len;
|
||||
DBG("%s:ram0:ptr=%d,len=%d\n",__FUNCTION__,ptr,len);
|
||||
//send ack
|
||||
//if(++gNumSendAck > (1<<12))
|
||||
//gNumSendAck = 0;
|
||||
//port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck));
|
||||
|
||||
p = port->dpram.prx;
|
||||
for(i=0;i<(len>>1);i++)
|
||||
{
|
||||
temp = *(p+(i<<1));
|
||||
*(p+(i<<1))= *(p+(i<<1)+1);
|
||||
*(p+(i<<1)+1) = temp;
|
||||
}
|
||||
|
||||
p = port->dpram.prx;
|
||||
for(i=0;i<ptr;i++)
|
||||
printk("%s:prx[%d]=0x%x\n",__FUNCTION__,i,*p++);
|
||||
|
||||
//wake up ap to read data
|
||||
wake_up_interruptible(&port->dpram.recq);
|
||||
|
||||
mutex_lock(&port->dpram.rec_lock);
|
||||
|
||||
//allow bp write ram0 again
|
||||
port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM0));
|
||||
|
||||
//DBG("%s:r_irq=0x%x,s_ack=0x%x\n",__FUNCTION__,mbox, (MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck));
|
||||
}
|
||||
else if((mbox&MAILBOX_RAM3) == MAILBOX_RAM2)
|
||||
{
|
||||
//RAM2
|
||||
ptr = port->dpram.read_ptr(&port->dpram,SPI_DPRAM_PTR2_BPWRITE_APREAD);
|
||||
if(ptr%2)
|
||||
len = ptr+1;
|
||||
else
|
||||
len = ptr;
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START, port->dpram.prx, len);
|
||||
port->dpram.rec_len += ptr;
|
||||
DBG("%s:ram2:ptr=%d,len=%d\n",__FUNCTION__,ptr,len);
|
||||
//if(++gNumSendAck > (1<<12))
|
||||
//gNumSendAck = 0;
|
||||
//port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM2 | gNumSendAck));
|
||||
|
||||
p = port->dpram.prx;
|
||||
for(i=0;i<(len>>1);i++)
|
||||
{
|
||||
temp = *(p+(i<<1));
|
||||
*(p+(i<<1))= *(p+(i<<1)+1);
|
||||
*(p+(i<<1)+1) = temp;
|
||||
}
|
||||
|
||||
//wake up ap to read data
|
||||
wake_up_interruptible(&port->dpram.recq);
|
||||
|
||||
mutex_lock(&port->dpram.rec_lock);
|
||||
|
||||
//allow bp write ram0 again
|
||||
port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM2));
|
||||
|
||||
//DBG("%s:r_irq=0x%x,s_ack=0x%x\n",__FUNCTION__, mbox, (MAILBOX_APSEND_ACK | MAILBOX_RAM2 | gNumSendAck));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static irqreturn_t spi_dpram_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_fpga_port *port = dev_id;
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
/*
|
||||
* Can't do anything in interrupt context because we need to
|
||||
* block (spi_sync() is blocking) so fire of the interrupt
|
||||
* handling workqueue.
|
||||
* Remember that we access ICE65LXX registers through SPI bus
|
||||
* via spi_sync() call.
|
||||
*/
|
||||
|
||||
queue_work(port->dpram.spi_dpram_irq_workqueue, &port->dpram.spi_dpram_irq_work);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
#if SPI_DPRAM_TEST
|
||||
#define SEL_RAM0 0
|
||||
#define SEL_RAM1 1
|
||||
#define SEL_RAM2 2
|
||||
#define SEL_RAM3 3
|
||||
#define SEL_REG 4
|
||||
#define SEL_RAM SEL_REG
|
||||
|
||||
void spi_dpram_work_handler(struct work_struct *work)
|
||||
{
|
||||
int i;
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, dpram.spi_dpram_work);
|
||||
DBG("*************test spi_dpram now***************\n");
|
||||
|
||||
for(i=0;i<SPI_DPRAM_BPWRITE_SIZE;i++)
|
||||
{
|
||||
buf_dpram[2*i] = (0xa000+i)>>8;
|
||||
buf_dpram[2*i+1] = (0xa000+i)&0xff;
|
||||
}
|
||||
|
||||
#if(SEL_RAM == SEL_RAM0)
|
||||
//RAM0
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START, port->dpram.prx, SPI_DPRAM_BPWRITE_SIZE<<1);
|
||||
for(i=0;i<SPI_DPRAM_BPWRITE_SIZE;i++)
|
||||
{
|
||||
ret = (*(port->dpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1));
|
||||
if(ret != 0xa000+i)
|
||||
DBG("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xa000+i);
|
||||
}
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM1)
|
||||
//RAM1
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_START);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ); //send irq to bp after ap write data to dpram
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM2)
|
||||
//RAM2
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START, port->dpram.prx, SPI_DPRAM_LOG_BPWRITE_SIZE<<1);
|
||||
for(i=0;i<SPI_DPRAM_LOG_BPWRITE_SIZE;i++)
|
||||
{
|
||||
ret = (*(port->dpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1));
|
||||
if(ret != 0xc000+i)
|
||||
DBG("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xc000+i);
|
||||
}
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM3)
|
||||
//RAM3
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_LOG_APWRITE_START, buf_dpram, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR3_APWRITE_BPREAD, SPI_DPRAM_LOG_APWRITE_START);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ); //send irq to bp after ap write data to dpram
|
||||
|
||||
#elif(SEL_RAM == SEL_REG)
|
||||
#if 1
|
||||
if(gNumCount++ == 0)
|
||||
{
|
||||
if(++gNumSendAck > (1<<12))
|
||||
gNumSendAck = 0;
|
||||
port->dpram.write_ack(&port->dpram, MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck);
|
||||
printk("%s:line=%d,s_ack=0x%x\n",__FUNCTION__,__LINE__,MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck);
|
||||
|
||||
while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en = FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
printk("%s:line=%d,s_irq=0x%x\n",__FUNCTION__,__LINE__,MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
|
||||
if(gNumCount > (1<<15))
|
||||
gNumCount = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en == FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_LOG_APWRITE_START, buf_dpram, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR3_APWRITE_BPREAD, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM3 | gNumSendInt);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void spi_testdpram_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->dpram.dpram_timer.expires = jiffies + msecs_to_jiffies(500);
|
||||
add_timer(&port->dpram.dpram_timer);
|
||||
//schedule_work(&port->gpio.spi_gpio_work);
|
||||
queue_work(port->dpram.spi_dpram_workqueue, &port->dpram.spi_dpram_work);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//really is spi_dpram_handle_ack after dpram's pin is exchanged
|
||||
int spi_dpram_handle_ack(struct spi_device *spi)
|
||||
{
|
||||
struct spi_fpga_port *port = spi_get_drvdata(spi);
|
||||
printk("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//clear ack interrupt
|
||||
port->dpram.read_ack(&port->dpram);
|
||||
|
||||
//allow ap to write and wake ap to write data
|
||||
port->dpram.apwrite_en = TRUE;
|
||||
wake_up_interruptible(&port->dpram.sendq);
|
||||
#if 0
|
||||
//while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en = FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
printk("%s:r_ack=0x%x,s_irq=0x%x\n",__FUNCTION__,ack, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpr_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
filp->private_data = port;
|
||||
port->dpram.rec_len = 0;
|
||||
port->dpram.send_len = 0;
|
||||
port->dpram.apwrite_en = TRUE;
|
||||
|
||||
return nonseekable_open(inode, filp);
|
||||
}
|
||||
|
||||
|
||||
static int dpr_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
DBG("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
filp->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t dpr_read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
struct spi_fpga_port *port = filp->private_data;
|
||||
|
||||
ret = down_interruptible(&port->dpram.rec_sem);
|
||||
//DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
DBG("%s, port=0x%x , count=%d, port->dpram.rec_len=%d \n",__FUNCTION__, (int)port, count, port->dpram.rec_len);
|
||||
|
||||
//printk("%s:CURRENT_TASK=0x%x\n",__FUNCTION__,current);
|
||||
while(port->dpram.rec_len == 0)
|
||||
{
|
||||
if( filp->f_flags&O_NONBLOCK )
|
||||
return -EAGAIN;
|
||||
|
||||
if(wait_event_interruptible(port->dpram.recq, (port->dpram.rec_len != 0)))
|
||||
{
|
||||
DBG("%s:NO data in dpram!\n",__FUNCTION__);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
//gRecCount = port->dpram.rec_len;
|
||||
}
|
||||
|
||||
/*read data from buffer*/
|
||||
if(copy_to_user((char*)buffer, (char *)(port->dpram.prx + gRecCount - port->dpram.rec_len), count))
|
||||
{
|
||||
DBG("%s:copy_to_user err!\n",__FUNCTION__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#if 1
|
||||
int i,len;
|
||||
char *p = buffer;
|
||||
len = port->dpram.rec_len;
|
||||
//for(i=0;i<len;i++)
|
||||
//{
|
||||
if(count==1){
|
||||
DBG("%s:prx[%d]=0x%x, src = %x \n",__FUNCTION__,i,*p, *((char *)(port->dpram.prx + gRecCount - port->dpram.rec_len)));
|
||||
}else{
|
||||
printk("count = %d, $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n", count);
|
||||
}
|
||||
#endif
|
||||
|
||||
port->dpram.rec_len -= count;
|
||||
if(port->dpram.rec_len == 0)
|
||||
mutex_unlock(&port->dpram.rec_lock);
|
||||
|
||||
up(&port->dpram.rec_sem);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t dpr_write (struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct spi_fpga_port *port = filp->private_data;
|
||||
int mod,num;
|
||||
char i,*p,temp;
|
||||
printk("%s:line=%d,port=0x%x, count=%d \n",__FUNCTION__,__LINE__,(int)port, count);
|
||||
|
||||
while(port->dpram.apwrite_en == FALSE)
|
||||
{
|
||||
|
||||
//if(filp->f_flags & O_NONBLOCK)
|
||||
// return -EAGAIN;
|
||||
if(wait_event_interruptible(port->dpram.sendq, (port->dpram.apwrite_en == TRUE))){
|
||||
printk("port->dpram.apwrite_en == FALSE");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
printk("%s, wake up \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if(count > port->dpram.max_send_len)
|
||||
{
|
||||
count = port->dpram.max_send_len;
|
||||
printk("%s:count is large than max_send_len(%d),and only %d's bytes is valid!\n",__FUNCTION__,count,count);
|
||||
}
|
||||
|
||||
if(copy_from_user((char *)port->dpram.ptx,buffer,count))
|
||||
{
|
||||
printk("%s:copy_from_user err!\n",__FUNCTION__);
|
||||
return -EFAULT;
|
||||
}
|
||||
mod = count % 2;
|
||||
num = count;
|
||||
if(mod)
|
||||
{
|
||||
*((char *)port->dpram.ptx + count) = 0;
|
||||
num = count + 1;
|
||||
}
|
||||
|
||||
p=port->dpram.ptx;
|
||||
|
||||
/*swap data to suitable bp:p[0]<->p[1]*/
|
||||
for(i=0;i<(num>>1);i++)
|
||||
{
|
||||
temp = *(p+(i<<1));
|
||||
*(p+(i<<1))= *(p+(i<<1)+1);
|
||||
*(p+(i<<1)+1) = temp;
|
||||
}
|
||||
|
||||
#if 1
|
||||
p=port->dpram.ptx;
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
/*DBG*/printk("%s:ptx[%d]=0x%x\n",__FUNCTION__,i,*p);
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, port->dpram.ptx, num);
|
||||
port->dpram.apwrite_en = FALSE; //clear apwrite_en after wirte data to dpram
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, count);
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
|
||||
if(gpio_get_value(PIN_BPSEND_ACK)==0){
|
||||
printk("BP_READY is LOW, wake up BP \n");
|
||||
gpio_direction_output(PIN_APSEND_ACK,GPIO_LOW);
|
||||
msleep(50);
|
||||
gpio_direction_output(PIN_APSEND_ACK,GPIO_HIGH);
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
while(gpio_get_value(PIN_BPSEND_ACK)==0){
|
||||
printk("BP_READY is LOW, wait 100ms !!!!!!!!!!!!\n");
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
//send irq to bp after ap write data to dpram
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned int dpr_poll(struct file *filp, struct poll_table_struct * wait)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
struct spi_fpga_port *port;
|
||||
port = filp->private_data;
|
||||
DBG("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
#if 1
|
||||
poll_wait(filp, &port->dpram.recq, wait);
|
||||
poll_wait(filp, &port->dpram.sendq, wait);
|
||||
|
||||
if(port->dpram.rec_len >0)
|
||||
{
|
||||
mask |= POLLIN|POLLRDNORM;
|
||||
DBG("%s:exsram_poll_____1\n",__FUNCTION__);
|
||||
}
|
||||
|
||||
if(port->dpram.apwrite_en == TRUE)
|
||||
{
|
||||
mask |= POLLOUT|POLLWRNORM;
|
||||
DBG("%s:exsram_poll_____2\n",__FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
static struct file_operations dpr_fops={
|
||||
.owner= THIS_MODULE,
|
||||
.open= dpr_open,
|
||||
.release= dpr_close,
|
||||
.read= dpr_read,
|
||||
.write= dpr_write,
|
||||
.poll = dpr_poll,
|
||||
};
|
||||
|
||||
int spi_dpram_register(struct spi_fpga_port *port)
|
||||
{
|
||||
char b[28];
|
||||
int ret;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
port->dpram.prx = (char *)kzalloc(sizeof(char)*((SPI_DPRAM_BPWRITE_SIZE<<1)+6), GFP_KERNEL);
|
||||
if(port->dpram.prx == NULL)
|
||||
{
|
||||
DBG("port->dpram.prx kzalloc err!!!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
port->dpram.ptx = (char *)kzalloc(sizeof(char)*((SPI_DPRAM_APWRITE_SIZE<<1)+6), GFP_KERNEL);
|
||||
if(port->dpram.ptx == NULL)
|
||||
{
|
||||
DBG("port->dpram.ptx kzalloc err!!!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
sprintf(b, "spi_dpram_irq_workqueue");
|
||||
port->dpram.spi_dpram_irq_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->dpram.spi_dpram_irq_workqueue) {
|
||||
DBG("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&port->dpram.spi_dpram_irq_work, spi_dpram_irq_work_handler);
|
||||
|
||||
#if SPI_DPRAM_TEST
|
||||
sprintf(b, "spi_dpram_workqueue");
|
||||
port->dpram.spi_dpram_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->dpram.spi_dpram_workqueue) {
|
||||
DBG("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&port->dpram.spi_dpram_work, spi_dpram_work_handler);
|
||||
|
||||
setup_timer(&port->dpram.dpram_timer, spi_testdpram_timer, (unsigned long)port);
|
||||
port->dpram.dpram_timer.expires = jiffies+2000;//>1000ms
|
||||
add_timer(&port->dpram.dpram_timer);
|
||||
#endif
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
//init the struct spi_dpram
|
||||
init_waitqueue_head(&port->dpram.recq);
|
||||
init_waitqueue_head(&port->dpram.sendq);
|
||||
mutex_init(&port->dpram.rec_lock);
|
||||
mutex_init(&port->dpram.send_lock);
|
||||
init_MUTEX(&port->dpram.rec_sem);
|
||||
init_MUTEX(&port->dpram.send_sem);
|
||||
spin_lock_init(&port->dpram.spin_rec_lock);
|
||||
spin_lock_init(&port->dpram.spin_send_lock);
|
||||
port->dpram.rec_len = 0;
|
||||
port->dpram.send_len = 0;
|
||||
port->dpram.apwrite_en = TRUE;
|
||||
port->dpram.max_rec_len = SPI_DPRAM_BPWRITE_SIZE;
|
||||
port->dpram.max_send_len = SPI_DPRAM_APWRITE_SIZE;
|
||||
port->dpram.miscdev.minor = MISC_DYNAMIC_MINOR;
|
||||
port->dpram.miscdev.name = "spi_dpram";//spi_fpga
|
||||
port->dpram.miscdev.fops = &dpr_fops;
|
||||
|
||||
ret = misc_register(&port->dpram.miscdev);
|
||||
if(ret)
|
||||
{
|
||||
DBG("%s:misc_register err!!!\n",__FUNCTION__);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
port->dpram.write_dpram = spi_dpram_write_buf;
|
||||
port->dpram.read_dpram = spi_dpram_read_buf;
|
||||
port->dpram.write_ptr = spi_dpram_write_ptr;
|
||||
port->dpram.read_ptr = spi_dpram_read_ptr;
|
||||
port->dpram.write_irq = spi_dpram_write_irq;
|
||||
port->dpram.read_irq = spi_dpram_read_irq;
|
||||
port->dpram.write_ack = spi_dpram_write_ack;
|
||||
port->dpram.read_ack = spi_dpram_read_ack;
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
ret = gpio_request(SPI_DPRAM_INT_PIN, NULL);
|
||||
if (ret) {
|
||||
DBG("%s:failed to request dpram irq gpio\n",__FUNCTION__);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
rk2818_mux_api_set(GPIOA23_UART2_SEL_NAME,0);
|
||||
gpio_pull_updown(SPI_DPRAM_INT_PIN,GPIOPullUp);
|
||||
ret = request_irq(gpio_to_irq(SPI_DPRAM_INT_PIN),spi_dpram_irq,IRQF_TRIGGER_FALLING,NULL,port);
|
||||
if(ret)
|
||||
{
|
||||
DBG("%s:unable to request dpram irq_gpio irq\n",__FUNCTION__);
|
||||
goto err2;
|
||||
}
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
|
||||
/*disable speaker */
|
||||
gpio_request(RK2818_PIN_PF7, "DPRAM");
|
||||
rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);
|
||||
gpio_direction_output(RK2818_PIN_PF7,GPIO_LOW);
|
||||
msleep(100);
|
||||
gpio_direction_output(RK2818_PIN_PF7,GPIO_HIGH);
|
||||
msleep(100);
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
free_irq(gpio_to_irq(SPI_DPRAM_INT_PIN),NULL);
|
||||
err1:
|
||||
gpio_free(SPI_DPRAM_INT_PIN);
|
||||
err0:
|
||||
kfree(port->dpram.prx);
|
||||
kfree(port->dpram.ptx);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int spi_dpram_unregister(struct spi_fpga_port *port)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <linux/poll.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
#include "spi_fpga_fw.h"
|
||||
|
||||
#define FPGA_GPIO_TYPE 0
|
||||
|
||||
#define FPGA_PIN_CRESET_B RK2818_PIN_PC4
|
||||
#define SPI_PIN_TX RK2818_PIN_PB6
|
||||
#define SPI_PIN_CLK RK2818_PIN_PB5
|
||||
#define SPI_PIN_CS RK2818_PIN_PB0
|
||||
|
||||
#if (FPGA_GPIO_TYPE == 0)
|
||||
#define FPGA_CRESER_OUTPUT() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTC_DDR)|(0x1<<4), (RK2818_GPIO0_BASE+GPIO_SWPORTC_DDR))
|
||||
#define FPGA_CRESET_HIGH() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTC_DR)|(0x1<<4), (RK2818_GPIO0_BASE+GPIO_SWPORTC_DR))
|
||||
#define FPGA_CRESET_LOW() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTC_DR)&(~(0x1<<4)), (RK2818_GPIO0_BASE+GPIO_SWPORTC_DR))
|
||||
|
||||
#define FPGA_TX_OUTPUT() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR)|(0x1<<6), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR))
|
||||
#define FPGA_TX_HIGH() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)|(0x1<<6), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
#define FPGA_TX_LOW() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)&(~(0x1<<6)), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
|
||||
#define FPGA_CLK_OUTPUT() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR)|(0x1<<5), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR))
|
||||
#define FPGA_CLK_HIGH() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)|(0x1<<5), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
#define FPGA_CLK_LOW() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)&(~(0x1<<5)), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
|
||||
#define FPGA_CS_OUTPUT() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR)|(0x1<<0), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DDR))
|
||||
#define FPGA_CS_HIGH() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)|(0x1<<0), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
#define FPGA_CS_LOW() __raw_writel(__raw_readl(RK2818_GPIO0_BASE+GPIO_SWPORTB_DR)&(~(0x1<<0)), (RK2818_GPIO0_BASE+GPIO_SWPORTB_DR))
|
||||
#else
|
||||
#define FPGA_CRESER_OUTPUT() gpio_direction_output(FPGA_PIN_CRESET_B,GPIO_HIGH)
|
||||
#define FPGA_CRESET_HIGH() gpio_set_value(FPGA_PIN_CRESET_B,GPIO_HIGH)
|
||||
#define FPGA_CRESET_LOW() gpio_set_value(FPGA_PIN_CRESET_B,GPIO_LOW)
|
||||
|
||||
#define FPGA_TX_OUTPUT() gpio_direction_output(SPI_PIN_TX,GPIO_HIGH)
|
||||
#define FPGA_TX_HIGH() gpio_set_value(SPI_PIN_TX,GPIO_HIGH)
|
||||
#define FPGA_TX_LOW() gpio_set_value(SPI_PIN_TX,GPIO_LOW)
|
||||
|
||||
#define FPGA_CLK_OUTPUT() gpio_direction_output(SPI_PIN_CLK,GPIO_HIGH)
|
||||
#define FPGA_CLK_HIGH() gpio_set_value(SPI_PIN_CLK,GPIO_HIGH)
|
||||
#define FPGA_CLK_LOW() gpio_set_value(SPI_PIN_CLK,GPIO_LOW)
|
||||
|
||||
#define FPGA_CS_OUTPUT() gpio_direction_output(SPI_PIN_CS,GPIO_HIGH)
|
||||
#define FPGA_CS_HIGH() gpio_set_value(SPI_PIN_CS,GPIO_HIGH)
|
||||
#define FPGA_CS_LOW() gpio_set_value(SPI_PIN_CS,GPIO_LOW)
|
||||
#endif
|
||||
|
||||
static void __init spi_fpga_send_bytes(unsigned char * bytes, unsigned int len)
|
||||
{
|
||||
unsigned int i,j;
|
||||
unsigned char spibit;
|
||||
unsigned char * fw = bytes;
|
||||
|
||||
i=0;
|
||||
while (i < len)
|
||||
{
|
||||
j=0;
|
||||
spibit = *fw++;
|
||||
while (j < 8)
|
||||
{
|
||||
FPGA_CLK_LOW();
|
||||
if(spibit & 0x80)
|
||||
{
|
||||
FPGA_TX_HIGH();
|
||||
}
|
||||
else
|
||||
{
|
||||
FPGA_TX_LOW();
|
||||
}
|
||||
FPGA_CLK_HIGH();
|
||||
spibit = spibit<<1;
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init spi_fpga_wait(unsigned int num)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
while(i<(num<<1))
|
||||
{
|
||||
FPGA_CLK_LOW();
|
||||
i++;
|
||||
FPGA_CLK_HIGH();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(lock_fw);
|
||||
static void __init spi_fpga_dlfw(unsigned char * fpga_fw, unsigned int fpga_fw_len)
|
||||
{
|
||||
//int ret;
|
||||
unsigned long flags;
|
||||
unsigned char command1[6] = {0x7e, 0xaa, 0x99, 0x7e, 0x01, 0x0e};
|
||||
unsigned char command2[5] = {0x83, 0x00, 0x00, 0x26, 0x11};
|
||||
unsigned char command3[5] = {0x83, 0x00, 0x00, 0x27, 0x21};
|
||||
unsigned char command4[1] = {0x81};
|
||||
|
||||
//local_irq_save(flags);
|
||||
spin_lock_irqsave(&lock_fw, flags);
|
||||
rk2818_mux_api_set(GPIOC_LCDC24BIT_SEL_NAME, IOMUXB_GPIO0_C2_7);
|
||||
//ret = gpio_request(FPGA_PIN_CRESET_B, NULL);
|
||||
//if (ret) {
|
||||
// printk("%s:failed to request fpga download pin\n",__FUNCTION__);
|
||||
//}
|
||||
|
||||
rk2818_mux_api_set(GPIOB_SPI0_MMC0_NAME,IOMUXA_GPIO0_B567);
|
||||
//ret = gpio_request(SPI_PIN_CLK, NULL);
|
||||
//if (ret) {
|
||||
// printk("%s:failed to request fpga clk pin\n",__FUNCTION__);
|
||||
//}
|
||||
|
||||
//ret = gpio_request(SPI_PIN_TX, NULL);
|
||||
//if (ret) {
|
||||
// printk("%s:failed to request fpga tx pin\n",__FUNCTION__);
|
||||
//}
|
||||
|
||||
rk2818_mux_api_set(GPIOB0_SPI0CSN1_MMC1PCA_NAME, IOMUXA_GPIO0_B0);
|
||||
//ret = gpio_request(SPI_PIN_CS, NULL);
|
||||
//if (ret) {
|
||||
// printk("%s:failed to request fpga cs pin\n",__FUNCTION__);
|
||||
//}
|
||||
|
||||
FPGA_CS_LOW();
|
||||
FPGA_CS_OUTPUT();
|
||||
FPGA_CRESET_LOW();
|
||||
FPGA_CRESER_OUTPUT();
|
||||
FPGA_TX_LOW();
|
||||
FPGA_TX_OUTPUT();
|
||||
FPGA_CLK_LOW();
|
||||
FPGA_CLK_OUTPUT();
|
||||
|
||||
//step 1
|
||||
FPGA_CS_LOW();
|
||||
FPGA_CRESET_LOW();
|
||||
udelay(10);//delay >= 200ns
|
||||
|
||||
//step 2
|
||||
FPGA_CRESET_HIGH();
|
||||
mdelay(2); //delay >= 300us for clear internal memory
|
||||
|
||||
//step 3
|
||||
//spi_fpga_wait(8); //need ???
|
||||
|
||||
//step 4
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_wait(8);
|
||||
|
||||
//step 5
|
||||
FPGA_CS_LOW();
|
||||
spi_fpga_send_bytes(command1, 6);
|
||||
|
||||
|
||||
//step 6
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_wait(13000);
|
||||
|
||||
//step 7
|
||||
FPGA_CS_LOW();
|
||||
spi_fpga_send_bytes(command2, 5);
|
||||
|
||||
|
||||
//step 8
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_wait(8);
|
||||
|
||||
//step 9
|
||||
FPGA_CS_LOW();
|
||||
spi_fpga_send_bytes(command3, 5);
|
||||
|
||||
|
||||
//step 10
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_wait(8);
|
||||
|
||||
//step 11
|
||||
FPGA_CS_LOW();
|
||||
spi_fpga_send_bytes(command4, 1);
|
||||
|
||||
|
||||
//step 12
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_wait(8);
|
||||
|
||||
//step 13
|
||||
FPGA_CS_HIGH();
|
||||
spi_fpga_send_bytes(fpga_fw, fpga_fw_len);
|
||||
|
||||
//step 14
|
||||
spi_fpga_wait(100);
|
||||
|
||||
//step 15
|
||||
//local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&lock_fw, flags);
|
||||
|
||||
//free gpio and set to spi
|
||||
//gpio_free(FPGA_PIN_CRESET_B);
|
||||
//gpio_free(SPI_PIN_TX);
|
||||
//gpio_free(SPI_PIN_CLK);
|
||||
//gpio_free(SPI_PIN_CS);
|
||||
rk2818_mux_api_mode_resume(GPIOB_SPI0_MMC0_NAME);
|
||||
rk2818_mux_api_mode_resume(GPIOB0_SPI0CSN1_MMC1PCA_NAME);
|
||||
rk2818_mux_api_mode_resume(GPIOC_LCDC24BIT_SEL_NAME);
|
||||
}
|
||||
|
||||
int __init fpga_dl_fw(void)
|
||||
{
|
||||
printk("%s:start to load FPGA HEX.........\n",__FUNCTION__);
|
||||
|
||||
//rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0);
|
||||
//gpio_request(RK2818_PIN_PE0, NULL);
|
||||
//gpio_direction_output(RK2818_PIN_PE0,1);
|
||||
//udelay(2);
|
||||
//gpio_direction_output(RK2818_PIN_PE0,0);
|
||||
|
||||
spi_fpga_dlfw(spibyte, CONFIGURATION_SIZE);
|
||||
|
||||
//gpio_direction_output(RK2818_PIN_PE0,1);
|
||||
//udelay(2);
|
||||
//gpio_direction_output(RK2818_PIN_PE0,0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,806 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/fpga/spi_fpga_init.c - spi fpga init driver
|
||||
*
|
||||
* Copyright (C) 2010 ROCKCHIP, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: fpga ice65l08xx is used for spi2uart,spi2gpio,spi2i2c and spi2dpram.
|
||||
* this driver is the entry of all modules's drivers,should be run at first.
|
||||
* the struct for fpga is build in the driver,and it is important.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <linux/poll.h>
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_INIT_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
struct spi_fpga_port *pFpgaPort;
|
||||
|
||||
#if SPI_FPGA_TRANS_WORK
|
||||
#define ID_SPI_FPGA_WRITE 1
|
||||
#define ID_SPI_FPGA_READ 2
|
||||
struct spi_fpga_transfer
|
||||
{
|
||||
u8 *txbuf;
|
||||
unsigned n_tx;
|
||||
u8 *rxbuf;
|
||||
unsigned n_rx;
|
||||
int id;
|
||||
struct list_head queue;
|
||||
};
|
||||
|
||||
static void spi_fpga_trans_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, fpga_trans_work);
|
||||
|
||||
while (1) {
|
||||
unsigned long flags;
|
||||
struct spi_fpga_transfer *t = NULL;
|
||||
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
if (!list_empty(&port->trans_queue)) {
|
||||
t = list_first_entry(&port->trans_queue, struct spi_fpga_transfer, queue);
|
||||
list_del(&t->queue);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
|
||||
if (!t) // trans_queue empty
|
||||
break;
|
||||
|
||||
DBG("%s:id=%d,txbuf=0x%x\n",__FUNCTION__,t->id,(int)t->txbuf);
|
||||
switch (t->id) {
|
||||
case ID_SPI_FPGA_WRITE:
|
||||
spi_write(port->spi, t->txbuf, t->n_tx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
kfree(t->txbuf);
|
||||
kfree(t);
|
||||
}
|
||||
}
|
||||
|
||||
int spi_write_work(struct spi_device *spi, u8 *buf, size_t len)
|
||||
{
|
||||
struct spi_fpga_port *port = spi_get_drvdata(spi);
|
||||
struct spi_fpga_transfer *t;
|
||||
unsigned long flags;
|
||||
|
||||
t = kzalloc(sizeof(struct spi_fpga_transfer), GFP_KERNEL);
|
||||
if (!t)
|
||||
{
|
||||
printk("err:%s:ENOMEM\n",__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
t->txbuf = (char *)kmalloc(32, GFP_KERNEL);
|
||||
if(t->txbuf == NULL)
|
||||
{
|
||||
printk("%s:t->txbuf kzalloc err!!!\n",__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(t->txbuf, buf, len);
|
||||
t->n_tx = len;
|
||||
t->id = ID_SPI_FPGA_WRITE;
|
||||
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->trans_queue);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
queue_work(port->fpga_trans_workqueue, &port->fpga_trans_work);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if SPI_FPGA_POLL_WAIT
|
||||
|
||||
#define SPI_BUFSIZE 1028
|
||||
static void spi_fpga_complete(void *arg)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
msleep(5);
|
||||
wake_up_interruptible(&port->spi_wait_q);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
int spi_fpga_write(struct spi_device *spi, const u8 *buf, size_t len)
|
||||
{
|
||||
struct spi_transfer t = {
|
||||
.tx_buf = buf,
|
||||
.len = len,
|
||||
};
|
||||
struct spi_message m;
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
spi_message_init(&m);
|
||||
spi_message_add_tail(&t, &m);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
return spi_async(spi, &m);
|
||||
}
|
||||
|
||||
struct poll_table_struct wait;
|
||||
struct file filp;
|
||||
int spi_fpga_write_then_read(struct spi_device *spi,
|
||||
const u8 *txbuf, unsigned n_tx,
|
||||
u8 *rxbuf, unsigned n_rx)
|
||||
{
|
||||
struct spi_fpga_port *port = spi_get_drvdata(spi);
|
||||
int status;
|
||||
struct spi_message message;
|
||||
struct spi_transfer x[2];
|
||||
u8 *local_buf;
|
||||
printk("%s:line=%d,n_tx+n_rx=%d\n",__FUNCTION__,__LINE__,(n_tx + n_rx));
|
||||
/* Use preallocated DMA-safe buffer. We can't avoid copying here,
|
||||
* (as a pure convenience thing), but we can keep heap costs
|
||||
* out of the hot path ...
|
||||
*/
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
if ((n_tx + n_rx) > SPI_BUFSIZE)
|
||||
return -EINVAL;
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
spi_message_init(&message);
|
||||
memset(x, 0, sizeof x);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
if (n_tx) {
|
||||
x[0].len = n_tx;
|
||||
spi_message_add_tail(&x[0], &message);
|
||||
}
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
if (n_rx) {
|
||||
x[1].len = n_rx;
|
||||
spi_message_add_tail(&x[1], &message);
|
||||
}
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
/* ... unless someone else is using the pre-allocated buffer */
|
||||
|
||||
local_buf = kmalloc(SPI_BUFSIZE, GFP_KERNEL);
|
||||
if (!local_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(local_buf, txbuf, n_tx);
|
||||
x[0].tx_buf = local_buf;
|
||||
x[1].rx_buf = local_buf + n_tx;
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
message.complete = spi_fpga_complete;
|
||||
|
||||
/* do the i/o */
|
||||
status = spi_async(spi, &message);
|
||||
#if 1
|
||||
//poll_wait(&filp, &port->spi_wait_q, &wait);
|
||||
|
||||
//if (status == 0)
|
||||
memcpy(rxbuf, x[1].rx_buf, n_rx);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
kfree(local_buf);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
#define spi_write spi_fpga_write
|
||||
#define spi_write_then_read spi_fpga_write_then_read
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/
|
||||
unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
||||
{
|
||||
unsigned char index = 0;
|
||||
unsigned char tx_buf[2], rx_buf[2], n_rx=2, stat=0;
|
||||
unsigned int result=0;
|
||||
//printk("index1=%d\n",index);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_UART)
|
||||
case SEL_UART:
|
||||
index = port->uart.index;
|
||||
reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 1;//give fpga 8 clks for reading data
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
case SEL_GPIO:
|
||||
reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;//give fpga 8 clks for reading data
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
case SEL_I2C:
|
||||
reg = (((reg) | ICE_SEL_I2C) | ICE_SEL_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);
|
||||
result = rx_buf[1];
|
||||
DBG("%s,SEL_I2C reg=0x%x,result=0x%x \n",__FUNCTION__,reg&0xff,result&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
case SEL_DPRAM:
|
||||
reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;//give fpga 8 clks for reading data
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);
|
||||
break;
|
||||
#endif
|
||||
case READ_TOP_INT:
|
||||
reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ);
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_INT reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
|
||||
break;
|
||||
default:
|
||||
printk("%s err: Can not support this type!\n",__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void spi_out(struct spi_fpga_port *port, int reg, int value, int type)
|
||||
{
|
||||
unsigned char index = 0;
|
||||
unsigned char tx_buf[3];
|
||||
int reg_temp = reg;
|
||||
switch(type)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_UART)
|
||||
case SEL_UART:
|
||||
index = port->uart.index;
|
||||
reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index));
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = (value>>8) & 0xff;
|
||||
tx_buf[2] = value & 0xff;
|
||||
if(reg_temp == UART_IER)
|
||||
spi_write_work(port->spi, tx_buf, sizeof(tx_buf));
|
||||
else
|
||||
spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));
|
||||
DBG("%s,SEL_UART reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
case SEL_GPIO:
|
||||
reg = (((reg) | ICE_SEL_GPIO) & ICE_SEL_WRITE );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = (value>>8) & 0xff;
|
||||
tx_buf[2] = value & 0xff;
|
||||
spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));
|
||||
DBG("%s,SEL_GPIO reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
case SEL_I2C:
|
||||
reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_WRITE);
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = (value>>8) & 0xff;
|
||||
tx_buf[2] = value & 0xff;
|
||||
spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));
|
||||
DBG("%s,SEL_I2C reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
case SEL_DPRAM:
|
||||
reg = (((reg) | ICE_SEL_DPRAM) | ICE_SEL_DPRAM_WRITE );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = (value>>8) & 0xff;
|
||||
tx_buf[2] = value & 0xff;
|
||||
spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));
|
||||
DBG("%s,SEL_DPRAM reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
printk("%s err: Can not support this type!\n",__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
int spi_test_wrong_handle(void)
|
||||
{
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,0);
|
||||
udelay(2);
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,1);
|
||||
printk("%s:give one trailing edge!\n",__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_test_request_gpio(int set)
|
||||
{
|
||||
int ret;
|
||||
rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0);
|
||||
ret = gpio_request(SPI_FPGA_TEST_DEBUG_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request SPI_FPGA_TEST_DEBUG_PIN pin\n",__FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void spi_fpga_irq_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, fpga_irq_work);
|
||||
struct spi_device *spi = port->spi;
|
||||
int ret,uart_ch=0;
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT) & 0xff;
|
||||
if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_UART)
|
||||
DBG("%s:ICE_INT_TYPE_UART0 ret=0x%x\n",__FUNCTION__,ret);
|
||||
port->uart.index = uart_ch;
|
||||
spi_uart_handle_irq(spi);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
DBG("%s:ICE_INT_TYPE_GPIO ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_gpio_handle_irq(spi);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
DBG("%s:ICE_INT_TYPE_I2C2 ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_i2c_handle_irq(port,I2C_CH2);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
DBG("%s:ICE_INT_TYPE_I2C3 ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_i2c_handle_irq(port,I2C_CH3);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
DBG("%s:ICE_INT_TYPE_DPRAM ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_dpram_handle_ack(spi);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_SLEEP) == ICE_INT_TYPE_SLEEP)
|
||||
{
|
||||
DBG("%s:ICE_INT_TYPE_SLEEP ret=0x%x\n",__FUNCTION__,ret);
|
||||
printk("FPGA wake up system now ...\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("warning:ret=0x%x\n",ret);
|
||||
}
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t spi_fpga_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_fpga_port *port = dev_id;
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
/*
|
||||
* Can't do anything in interrupt context because we need to
|
||||
* block (spi_sync() is blocking) so fire of the interrupt
|
||||
* handling workqueue.
|
||||
* Remember that we access ICE65LXX registers through SPI bus
|
||||
* via spi_sync() call.
|
||||
*/
|
||||
|
||||
//schedule_work(&port->fpga_irq_work);
|
||||
queue_work(port->fpga_irq_workqueue, &port->fpga_irq_work);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static int spi_fpga_set_sysclk(int set)
|
||||
{
|
||||
rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);
|
||||
gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_fpga_set_status(struct spi_fpga_port *port, int stat)
|
||||
{
|
||||
if(stat == ICE_STATUS_SLEEP)
|
||||
{
|
||||
spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_INT_WAKE), ICE_STATUS_SLEEP, SEL_GPIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_INT_WAKE), ICE_STATUS_WAKE, SEL_GPIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_fpga_rst(void)
|
||||
{
|
||||
int ret;
|
||||
ret = gpio_request(SPI_FPGA_RST_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request fpga rst pin\n",__FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
rk2818_mux_api_set(GPIOH6_IQ_SEL_NAME,0);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_HIGH);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_LOW);
|
||||
mdelay(1);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_HIGH);
|
||||
|
||||
gpio_direction_input(SPI_FPGA_RST_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit spi_fpga_probe(struct spi_device * spi)
|
||||
{
|
||||
struct spi_fpga_port *port;
|
||||
int ret;
|
||||
char b[24];
|
||||
int num;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
/*
|
||||
* bits_per_word cannot be configured in platform data
|
||||
*/
|
||||
spi->bits_per_word = 8;
|
||||
|
||||
ret = spi_setup(spi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
port = kzalloc(sizeof(struct spi_fpga_port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
DBG("port=0x%x\n",(int)port);
|
||||
|
||||
mutex_init(&port->spi_lock);
|
||||
spin_lock_init(&port->work_lock);
|
||||
ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request standby pin\n",__FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
spi_fpga_set_sysclk(GPIO_HIGH);
|
||||
|
||||
#if SPI_FPGA_TRANS_WORK
|
||||
init_waitqueue_head(&port->wait_wq);
|
||||
init_waitqueue_head(&port->wait_rq);
|
||||
port->write_en = TRUE;
|
||||
port->read_en = TRUE;
|
||||
sprintf(b, "fpga_trans_workqueue");
|
||||
port->fpga_trans_workqueue = create_rt_workqueue(b);
|
||||
if (!port->fpga_trans_workqueue) {
|
||||
printk("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&port->fpga_trans_work, spi_fpga_trans_work_handler);
|
||||
INIT_LIST_HEAD(&port->trans_queue);
|
||||
#endif
|
||||
|
||||
spi_fpga_rst(); //reset fpga
|
||||
|
||||
sprintf(b, "fpga_irq_workqueue");
|
||||
port->fpga_irq_workqueue = create_rt_workqueue(b);
|
||||
if (!port->fpga_irq_workqueue) {
|
||||
printk("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&port->fpga_irq_work, spi_fpga_irq_work_handler);
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_UART)
|
||||
ret = spi_uart_register(port);
|
||||
if(ret)
|
||||
{
|
||||
spi_uart_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_uart_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
ret = spi_gpio_register(port);
|
||||
if(ret)
|
||||
{
|
||||
spi_gpio_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_gpio_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_FPGA_I2C)
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
spin_lock_init(&port->i2c.i2c_lock);
|
||||
for (num= 2;num<4;num++)
|
||||
{
|
||||
ret = spi_i2c_register(port,num);
|
||||
if(ret)
|
||||
{
|
||||
spi_i2c_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
}
|
||||
DBG("spi_i2c spi_i2c.%d: i2c-%d: spi_i2c I2C adapter\n",num,num);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
ret = spi_dpram_register(port);
|
||||
if(ret)
|
||||
{
|
||||
spi_dpram_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_dpram_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
port->spi = spi;
|
||||
spi_set_drvdata(spi, port);
|
||||
|
||||
ret = gpio_request(SPI_FPGA_INT_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request fpga intterupt gpio\n",__FUNCTION__);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME,IOMUXB_GPIO2_14_23);
|
||||
gpio_pull_updown(SPI_FPGA_INT_PIN,GPIOPullUp);
|
||||
ret = request_irq(gpio_to_irq(SPI_FPGA_INT_PIN),spi_fpga_irq,IRQF_TRIGGER_FALLING,NULL,port);
|
||||
if(ret)
|
||||
{
|
||||
printk("unable to request spi_uart irq\n");
|
||||
goto err2;
|
||||
}
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
pFpgaPort = port;
|
||||
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_GPIO)
|
||||
spi_fpga_set_status(port, ICE_STATUS_WAKE);
|
||||
spi_gpio_init();
|
||||
#endif
|
||||
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_request_gpio(GPIO_HIGH);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
free_irq(gpio_to_irq(SPI_FPGA_INT_PIN),NULL);
|
||||
err1:
|
||||
gpio_free(SPI_FPGA_INT_PIN);
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int __devexit spi_fpga_remove(struct spi_device *spi)
|
||||
{
|
||||
//struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int spi_fpga_wait_suspend(struct spi_fpga_port *port)
|
||||
{
|
||||
int i,n_tx,n_rx;
|
||||
for(i=0;i<1000;i++)
|
||||
{
|
||||
n_tx = spi_in(port, UART_LSR, READ_TOP_INT); //CONFIG_SPI_FPGA_UART = 1
|
||||
n_rx = spi_in(port, UART_LSR, SEL_UART);
|
||||
if((((n_tx >> 8) & 0x3f) == 0) && (((n_rx >> 8) & 0x3f) == 0)) //no data in tx_buf and rx_buf
|
||||
{
|
||||
printk("%s,i=%d\n",__FUNCTION__,i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void fpga_close_power_support(void)
|
||||
{
|
||||
//modem
|
||||
#if 0
|
||||
gpio_request(FPGA_PIO2_03, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_03,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_03);
|
||||
gpio_request(FPGA_PIO2_05, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_05,GPIO_HIGH);
|
||||
gpio_free(FPGA_PIO2_05);
|
||||
#endif
|
||||
|
||||
//cmmb power down
|
||||
gpio_request(FPGA_PIO4_03, NULL);
|
||||
gpio_direction_output(FPGA_PIO4_03,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO4_03);
|
||||
gpio_request(FPGA_PIO2_09, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_09,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_09);
|
||||
gpio_request(FPGA_PIO2_06, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_06,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_06);
|
||||
|
||||
//KEY LED control
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
static void fpga_open_power_support(void)
|
||||
{
|
||||
//modem
|
||||
#if 0
|
||||
gpio_request(FPGA_PIO2_03, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_03,GPIO_HIGH);
|
||||
gpio_free(FPGA_PIO2_03);
|
||||
gpio_request(FPGA_PIO2_05, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_05,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_05);
|
||||
#endif
|
||||
|
||||
//cmmb do not control here
|
||||
|
||||
//KEY LED resume
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_HIGH);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
|
||||
static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
|
||||
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
|
||||
int ret;
|
||||
fpga_close_power_support( );
|
||||
ret = spi_fpga_wait_suspend(port);
|
||||
if(!ret)
|
||||
{
|
||||
spi_fpga_set_status(port, ICE_STATUS_SLEEP); //CONFIG_SPI_FPGA_GPIO = 1
|
||||
udelay(1);
|
||||
spi_fpga_set_sysclk(GPIO_LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("fail to suspend fpga because it is sending or recieve data!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("%s\n",__FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_fpga_resume(struct spi_device *spi)
|
||||
{
|
||||
|
||||
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
|
||||
spi_fpga_set_sysclk(GPIO_HIGH);
|
||||
udelay(1);
|
||||
spi_fpga_set_status(port, ICE_STATUS_WAKE);
|
||||
fpga_open_power_support( );
|
||||
printk("%s\n",__FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define spi_fpga_suspend NULL
|
||||
#define spi_fpga_resume NULL
|
||||
#endif
|
||||
|
||||
static struct spi_driver spi_fpga_driver = {
|
||||
.driver = {
|
||||
.name = "spi_fpga",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = spi_fpga_probe,
|
||||
.remove = __devexit_p(spi_fpga_remove),
|
||||
.suspend = spi_fpga_suspend,
|
||||
.resume = spi_fpga_resume,
|
||||
};
|
||||
|
||||
static int __init spi_fpga_init(void)
|
||||
{
|
||||
return spi_register_driver(&spi_fpga_driver);
|
||||
}
|
||||
|
||||
static void __exit spi_fpga_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spi_fpga_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(spi_fpga_init);
|
||||
module_exit(spi_fpga_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Driver for spi2uart,spi2gpio,spi2i2c.");
|
||||
MODULE_AUTHOR("luowei <lw@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,529 +0,0 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_I2C_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define MAXMSGLEN 8
|
||||
#define I2C_COUNT 20
|
||||
#define DRV_NAME "spi_i2c"
|
||||
#define SPI_I2C_TEST 0
|
||||
|
||||
#if SPI_I2C_TEST
|
||||
struct i2c_adapter *adap;
|
||||
#endif
|
||||
int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel)
|
||||
{
|
||||
int reg;
|
||||
int ret;
|
||||
|
||||
if(channel == I2C_CH2)
|
||||
reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH2;
|
||||
else
|
||||
reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH3;
|
||||
|
||||
port->i2c.interrupt = 0;
|
||||
ret = spi_in(port,reg,SEL_I2C);
|
||||
DBG("Enter::%s,LINE=%d ret = [%d]\n",__FUNCTION__,__LINE__,ret);
|
||||
if(INT_I2C_READ_ACK == (ret & 0x07))
|
||||
{
|
||||
port->i2c.interrupt = INT_I2C_READ_ACK;
|
||||
wake_up(&port->i2c.wait_r);
|
||||
}
|
||||
else if(INT_I2C_READ_NACK ==(ret & 0x07))
|
||||
{
|
||||
port->i2c.interrupt = INT_I2C_READ_NACK;
|
||||
wake_up(&port->i2c.wait_r);
|
||||
printk("err:read no ack!ch=%d\n",channel);
|
||||
}
|
||||
else if(INT_I2C_WRITE_ACK == (ret & 0x07))
|
||||
{
|
||||
port->i2c.interrupt = INT_I2C_WRITE_ACK;
|
||||
wake_up(&port->i2c.wait_w);
|
||||
}
|
||||
else if(INT_I2C_WRITE_NACK == (ret & 0x07))
|
||||
{
|
||||
port->i2c.interrupt = INT_I2C_WRITE_NACK;
|
||||
wake_up(&port->i2c.wait_w);
|
||||
printk("err:write no ack!ch=%d\n",channel);
|
||||
}
|
||||
else
|
||||
printk("err:fpga's ack value error!\n");
|
||||
return port->i2c.interrupt;
|
||||
}
|
||||
|
||||
int spi_i2c_select_speed(int speed)
|
||||
{
|
||||
int result = 0;
|
||||
switch(speed)
|
||||
{
|
||||
case 10*1000:
|
||||
result = ICE_SET_10K_I2C_SPEED;
|
||||
break;
|
||||
case 100*1000:
|
||||
result = ICE_SET_100K_I2C_SPEED;
|
||||
break;
|
||||
case 200*1000:
|
||||
result = ICE_SET_200K_I2C_SPEED;
|
||||
break;
|
||||
case 300*1000:
|
||||
result = ICE_SET_300K_I2C_SPEED;
|
||||
break;
|
||||
case 400*1000:
|
||||
result = ICE_SET_400K_I2C_SPEED;
|
||||
break;
|
||||
default:
|
||||
result = ICE_SET_100K_I2C_SPEED; /* ddl@rock-chips.com : default set 100KHz */
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
|
||||
{
|
||||
|
||||
unsigned int reg ;
|
||||
unsigned int len,i,j;
|
||||
unsigned int slaveaddr;
|
||||
unsigned int speed;
|
||||
unsigned int channel = 0 ;
|
||||
unsigned int result;
|
||||
int ret = 0;
|
||||
|
||||
slaveaddr = pmsg->addr<<1;
|
||||
len = pmsg->len;
|
||||
speed = spi_i2c_select_speed(pmsg->scl_rate);
|
||||
|
||||
if(ch == I2C_CH2)
|
||||
channel = ICE_SEL_I2C_CH2;
|
||||
else if(ch == I2C_CH3)
|
||||
channel = ICE_SEL_I2C_CH3;
|
||||
else
|
||||
{
|
||||
printk("Error:try to read form error i2c channel\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBG("len = %d chan = %d read=%d\n",pmsg->len,ch,pmsg->read_type);
|
||||
|
||||
|
||||
slaveaddr = slaveaddr|ICE_I2C_SLAVE_READ;
|
||||
if(pmsg->read_type == I2C_NORMAL || pmsg->read_type == I2C_NO_STOP)
|
||||
reg = channel |ICE_SEL_I2C_RESTART;
|
||||
else if(pmsg->read_type == I2C_NO_REG )
|
||||
reg = channel |ICE_SEL_I2C_START;
|
||||
spi_out(port,reg,slaveaddr,SEL_I2C);
|
||||
//speed;
|
||||
reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,speed,SEL_I2C);
|
||||
//len;
|
||||
reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_STOP;
|
||||
spi_out(port,reg,len,SEL_I2C);
|
||||
|
||||
ret = wait_event_timeout(port->i2c.wait_r, ((port->i2c.interrupt == INT_I2C_READ_ACK) || (port->i2c.interrupt == INT_I2C_READ_NACK)), msecs_to_jiffies(60));
|
||||
if(ret == 0)
|
||||
{
|
||||
printk("%s:60ms time out!\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
for(i = 0;i<len;i++)
|
||||
{
|
||||
result = spi_in(port,channel,SEL_I2C);
|
||||
pmsg->buf[i] = 0;
|
||||
pmsg->buf[i] = result & 0xff ;
|
||||
DBG("r_buf[%d]=0x%x\n",i,pmsg->buf[i]);
|
||||
}
|
||||
spin_lock(&port->i2c.i2c_lock);
|
||||
port->i2c.interrupt &= INT_I2C_READ_MASK;
|
||||
spin_unlock(&port->i2c.i2c_lock);
|
||||
ret = pmsg->len;
|
||||
//for(i = 0;i<len;i++)
|
||||
//printk("pmsg->buf[%d] = 0x%x \n",i,pmsg->buf[i]);
|
||||
return ret>0 ? ret:-1;
|
||||
|
||||
}
|
||||
|
||||
int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
|
||||
{
|
||||
|
||||
unsigned int reg ;
|
||||
unsigned int len,i,j;
|
||||
unsigned int slaveaddr;
|
||||
unsigned int speed;
|
||||
unsigned int channel = 0;
|
||||
int ret = 0;
|
||||
|
||||
slaveaddr = pmsg->addr;
|
||||
len = pmsg->len;
|
||||
speed = spi_i2c_select_speed(pmsg->scl_rate);
|
||||
|
||||
if(ch == I2C_CH2)
|
||||
channel = ICE_SEL_I2C_CH2;
|
||||
else if(ch == I2C_CH3)
|
||||
channel = ICE_SEL_I2C_CH3;
|
||||
else
|
||||
{
|
||||
printk("Error: try to write the error i2c channel\n");
|
||||
return 0;
|
||||
}
|
||||
DBG("len = %d chan = %d read=%d\n",pmsg->len,ch,pmsg->read_type);
|
||||
|
||||
//slaveaddr ;
|
||||
slaveaddr = slaveaddr<<1;
|
||||
reg = channel |ICE_SEL_I2C_START;
|
||||
spi_out(port,reg,slaveaddr,SEL_I2C);
|
||||
//speed;
|
||||
reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,speed,SEL_I2C);
|
||||
//len;
|
||||
reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,len,SEL_I2C);
|
||||
reg = channel |ICE_SEL_I2C_TRANS;
|
||||
//data;
|
||||
for(i = 0 ;i < len;i++)
|
||||
{
|
||||
DBG("w_buf[%d]=0x%x\n",i,pmsg->buf[i]);
|
||||
if(i==len-1 && pmsg->read_type == I2C_NORMAL)
|
||||
{
|
||||
reg = channel|ICE_SEL_I2C_STOP;
|
||||
spi_out(port,reg,pmsg->buf[i],SEL_I2C);
|
||||
ret = wait_event_timeout(port->i2c.wait_w, ((port->i2c.interrupt == INT_I2C_WRITE_ACK) || (port->i2c.interrupt == INT_I2C_WRITE_NACK)), msecs_to_jiffies(60));
|
||||
if(ret == 0)
|
||||
{
|
||||
printk("%s:60ms time out!\n",__FUNCTION__);
|
||||
continue;
|
||||
}
|
||||
spin_lock(&port->i2c.i2c_lock);
|
||||
port->i2c.interrupt &= INT_I2C_WRITE_MASK;
|
||||
spin_unlock(&port->i2c.i2c_lock);
|
||||
ret = pmsg->len;
|
||||
}
|
||||
else if(i==len-1 && pmsg->read_type == I2C_NO_STOP)
|
||||
{
|
||||
spi_out(port,reg,pmsg->buf[i],SEL_I2C);
|
||||
ret = pmsg->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_out(port,reg,pmsg->buf[i],SEL_I2C);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret>0? ret:-1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int spi_xfer_msg(struct i2c_adapter *adapter,
|
||||
struct i2c_msg *msg,int stop)
|
||||
{
|
||||
int ret;
|
||||
struct spi_i2c_data *i2c = (struct spi_i2c_data *)adapter->algo_data;
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *) i2c->port;
|
||||
//printk("%s:line=%d,channel = %d port= 0x%x\n",__FUNCTION__,__LINE__,adapter->nr,port);
|
||||
|
||||
if(msg->len >MAXMSGLEN)
|
||||
return EFBIG;
|
||||
if(msg->flags & I2C_M_RD)
|
||||
ret = spi_i2c_readbuf(port,msg,adapter->nr);
|
||||
|
||||
else
|
||||
ret = spi_i2c_writebuf(port,msg,adapter->nr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
|
||||
int i;
|
||||
int ret;
|
||||
struct spi_i2c_data *i2c = (struct spi_i2c_data *)adapter->algo_data;
|
||||
|
||||
if(adapter->nr != I2C_CH2 && adapter->nr != I2C_CH3)
|
||||
return -EPERM;
|
||||
|
||||
//i2c->msg_num = num;
|
||||
|
||||
for(i = 0;i<num;i++)
|
||||
{
|
||||
//i2c->msg_idx = i;
|
||||
ret = spi_xfer_msg(adapter,&msgs[i],(i == (num - 1)));
|
||||
if(ret <= 0)
|
||||
{
|
||||
num = ret;
|
||||
printk("spi_xfer_msg error .ret = %d\n",ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int spi_i2c_func(struct i2c_adapter *adapter)
|
||||
{
|
||||
return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL);
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm spi_i2c_algorithm = {
|
||||
.master_xfer = spi_i2c_xfer,
|
||||
.functionality = spi_i2c_func,
|
||||
};
|
||||
|
||||
#if SPI_I2C_TEST
|
||||
unsigned short rda5400[][2] =
|
||||
{
|
||||
{0x3f,0x0000},//page 0
|
||||
{0x0B,0x3200},// pll_cal_eachtime
|
||||
{0x0E,0x5200},// rxfilter_op_cal_bit_dr rxfilter_sys_cal_bit_dr
|
||||
{0x13,0x016D},// fts_cap=01, for high nak rate at high temperature。
|
||||
{0x16,0x9C23},// Load8.5pf crystal,2.2pf cap
|
||||
{0x17,0xBB12},// xtal_cpuclk_en,*
|
||||
{0x19,0xEE18},// rxfilter_bp_mode rxfilter_tuning_cap_for die
|
||||
{0x1A,0x59EE},// rmx_lo_reg=1011, tmx_iqswap
|
||||
{0x1C,0x008F},//
|
||||
{0x30,0x002B},//
|
||||
{0x3B,0x33EA},// rxfilter_imgrej_lo
|
||||
{0x3E,0x0040},// tmx_lo_reg set to1
|
||||
{0x3f,0x0001},//page 1
|
||||
{0x02,0x0001},// rxfilter_sys_cal_polarity
|
||||
{0x04,0xE41E},// ldo_ictrl<5bit> set to 1
|
||||
{0x05,0xBC00},// ldo_ictrl<5bit> set to 1
|
||||
{0x06,0x262D},//
|
||||
{0x0B,0x001F},// vco_bit=111
|
||||
{0x10,0x0100},// thermo power setting
|
||||
{0x13,0x001C},// pre_sca=1100
|
||||
{0x19,0x001C},// lo_buff=1100, improve RF per formance at high temp
|
||||
{0x1a,0x1404},
|
||||
{0x1E,0x2A48},// resetn_ex_selfgen_enable=0, for 32K is no need when poweron
|
||||
{0x27,0x0070},// power table setting, maxpower
|
||||
{0x26,0x3254},// power table setting
|
||||
{0x25,0x2180},// power table settings
|
||||
{0x24,0x0000},// power table setting
|
||||
{0x23,0x0000},// power table setting
|
||||
{0x22,0x0000},// power table setting
|
||||
{0x21,0x0000},// power table setting
|
||||
{0x20,0x0000},// power table setting
|
||||
{0x37,0x0600},// padrv_cal_bypass
|
||||
{0x3A,0x06E0},// dcdc setting
|
||||
{0x3f,0x0000},//page 0
|
||||
};
|
||||
|
||||
int spi_i2c_16bit_test(struct spi_fpga_port *port)
|
||||
{
|
||||
u8 i2c_buf[8];
|
||||
int len = 2;
|
||||
int i ;
|
||||
struct i2c_adapter *adapter = adap;
|
||||
struct i2c_msg msg[1] =
|
||||
{
|
||||
{0x16,0,len+2,i2c_buf,200*1000,0,0}
|
||||
};
|
||||
|
||||
for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)
|
||||
{
|
||||
i2c_buf[0] = 0x22;
|
||||
i2c_buf[1] = rda5400[i][0];
|
||||
i2c_buf[2] = rda5400[i][1]>>8;
|
||||
i2c_buf[3] = rda5400[i][1]&0xFF;
|
||||
printk("i = %d\n",i);
|
||||
spi_i2c_writebuf(port, msg,3);
|
||||
msg[0].len = 2;
|
||||
|
||||
spi_i2c_readbuf(port, msg,3);
|
||||
if(msg->buf[0] != i2c_buf[2] ||msg->buf[1] != i2c_buf[3] )
|
||||
printk("i=%d,msg[0]=%d,msg[1]=%d\n",i,msg->buf[0],msg->buf[1]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int spi_i2c_8bit_test(struct spi_fpga_port *port)
|
||||
{
|
||||
u8 i2c_buf[8];
|
||||
int len = 2;
|
||||
int i ;
|
||||
struct i2c_adapter *adapter = adap;
|
||||
struct i2c_msg msg[1] =
|
||||
{
|
||||
{0x16,0,len+1,i2c_buf,200*1000,0,0}
|
||||
};
|
||||
struct i2c_msg msgs[2] =
|
||||
{
|
||||
{0x16,0,1,i2c_buf,200*1000,2,0},
|
||||
{0x16,1,2,i2c_buf,200*1000,2,0},
|
||||
};
|
||||
for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)
|
||||
{
|
||||
printk("i=%d\n",i);
|
||||
msg[0].len = 3;
|
||||
i2c_buf[0] = rda5400[i][0];
|
||||
i2c_buf[1] = rda5400[i][1]>>8;
|
||||
i2c_buf[2] = rda5400[i][1]&0xFF;
|
||||
//spi_i2c_writebuf(port, msg,3);
|
||||
spi_i2c_xfer(adapter,msg,1);
|
||||
|
||||
|
||||
i2c_buf[1] = 0;
|
||||
i2c_buf[2] = 0;
|
||||
spi_i2c_xfer(adapter,msgs,2);
|
||||
//spi_i2c_readbuf(port, msg,3);
|
||||
if(msg->buf[0] != (rda5400[i][1]>>8) ||msg->buf[1] != (rda5400[i][1]&0xff) )
|
||||
printk("i=%d,msg[0]=0x%x,msg[1]=0x%x\n",i,msg->buf[0],msg->buf[1]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int spi_i2c_test(void)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
spi_i2c_8bit_test(port);
|
||||
return 0;
|
||||
}
|
||||
void spi_i2c_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, i2c.spi_i2c_work);
|
||||
|
||||
printk("*************test spi_i2c now***************\n");
|
||||
spi_i2c_8bit_test(port);
|
||||
|
||||
}
|
||||
|
||||
static void spi_testi2c_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->i2c.i2c_timer.expires = jiffies + msecs_to_jiffies(2000);
|
||||
add_timer(&port->i2c.i2c_timer);
|
||||
queue_work(port->i2c.spi_i2c_workqueue, &port->i2c.spi_i2c_work);
|
||||
}
|
||||
#define BT_RST_PIN SPI_GPIO_P1_07
|
||||
#define BT_PWR_PIN SPI_GPIO_P1_06
|
||||
int spi_i2c_set_bt_power(void)
|
||||
{
|
||||
#if 0
|
||||
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
|
||||
#else
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_LOW);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
mdelay(2);
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
|
||||
mdelay(2);
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_LOW);
|
||||
spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT);
|
||||
mdelay(20);
|
||||
/*等待10ms以上,等待26M XTAL稳定,然后拉高RESETN*/
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int spi_i2c_register(struct spi_fpga_port *port,int num)
|
||||
{
|
||||
int ret;
|
||||
struct spi_i2c_data *i2c;
|
||||
//struct i2c_adapter *adapter;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
i2c = kzalloc(sizeof(struct spi_i2c_data),GFP_KERNEL);
|
||||
if(i2c == NULL)
|
||||
{
|
||||
printk("%s:no memory for state \n",__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
i2c->port = port;
|
||||
strlcpy(i2c->adapter.name,DRV_NAME,sizeof(i2c->adapter.name));
|
||||
i2c->adapter.owner = THIS_MODULE;
|
||||
i2c->adapter.algo = &spi_i2c_algorithm;
|
||||
i2c->adapter.class = I2C_CLASS_HWMON;
|
||||
//lock
|
||||
i2c->adapter.nr = num;
|
||||
i2c->adapter.algo_data = i2c;
|
||||
ret = i2c_add_numbered_adapter(&i2c->adapter);
|
||||
if(ret)
|
||||
{
|
||||
printk(KERN_INFO "SPI2I2C: Failed to add bus\n");
|
||||
kfree(i2c);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if SPI_I2C_TEST
|
||||
char b[20];
|
||||
if(num != 3)
|
||||
return 0;
|
||||
sprintf(b, "spi_i2c_workqueue");
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
adap = &i2c->adapter;
|
||||
port->i2c.spi_i2c_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->i2c.spi_i2c_workqueue) {
|
||||
printk("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
INIT_WORK(&port->i2c.spi_i2c_work, spi_i2c_work_handler);
|
||||
|
||||
setup_timer(&port->i2c.i2c_timer, spi_testi2c_timer, (unsigned long)port);
|
||||
port->i2c.i2c_timer.expires = jiffies+2000;//>1000ms
|
||||
add_timer(&port->i2c.i2c_timer);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
#endif
|
||||
|
||||
init_waitqueue_head(&port->i2c.wait_w);
|
||||
init_waitqueue_head(&port->i2c.wait_r);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int spi_i2c_unregister(struct spi_fpga_port *port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("Driver for spi2i2c.");
|
||||
MODULE_AUTHOR("swj <swj@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,15 +4,7 @@
|
|||
|
||||
menu "Headset device support"
|
||||
|
||||
config HEADSET_DET
|
||||
depends on ARCH_RK2818
|
||||
tristate "RK2818 headset detech support"
|
||||
---help---
|
||||
only use on the rk2818
|
||||
|
||||
config RK_HEADSET_DET
|
||||
depends on !ARCH_RK2818
|
||||
default n
|
||||
tristate "RK headset detech support"
|
||||
---help---
|
||||
Universal headphone driver(write begin rk29)
|
||||
|
|
|
|||
|
|
@ -1,3 +1 @@
|
|||
obj-$(CONFIG_HEADSET_DET) += rk2818_headset.o
|
||||
obj-$(CONFIG_RK_HEADSET_DET) += rk_headset.o
|
||||
|
||||
|
|
|
|||
|
|
@ -1,252 +0,0 @@
|
|||
/* arch/arm/mach-rockchip/rk28_headset.c
|
||||
*
|
||||
* Copyright (C) 2009 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/module.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/switch.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include "rk2818_headset.h"
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
/* Debug */
|
||||
#if 1
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define BIT_HEADSET (1 << 0)
|
||||
#define BIT_HEADSET_NO_MIC (1 << 1)
|
||||
|
||||
struct rk2818_headset_dev{
|
||||
struct switch_dev sdev;
|
||||
int cur_headset_status;
|
||||
int pre_headset_status;
|
||||
struct mutex mutex_lock;
|
||||
};
|
||||
|
||||
static struct rk2818_headset_dev Headset_dev;
|
||||
static struct delayed_work g_headsetobserve_work;
|
||||
static struct rk2818_headset_data *prk2818_headset_info;
|
||||
#if defined(CONFIG_MACH_BENGO_V2) || defined(CONFIG_MACH_BENGO) || defined(CONFIG_MACH_Z5) || defined(CONFIG_MACH_Z5_V2) || defined(CONFIG_MACH_A22)
|
||||
extern void detect_HSMic(void);
|
||||
#endif
|
||||
|
||||
int headset_status(void)
|
||||
{
|
||||
if(Headset_dev.cur_headset_status & BIT_HEADSET)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(headset_status);
|
||||
|
||||
static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
// DBG("---headset_interrupt---\n");
|
||||
schedule_delayed_work(&g_headsetobserve_work, msecs_to_jiffies(20));
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int headset_change_irqtype(unsigned int irq_type)
|
||||
{
|
||||
int ret = 0;
|
||||
// DBG("--------%s----------\n",__FUNCTION__);
|
||||
free_irq(prk2818_headset_info->irq,NULL);
|
||||
|
||||
ret = request_irq(prk2818_headset_info->irq, headset_interrupt, irq_type, NULL, NULL);
|
||||
if (ret)
|
||||
{
|
||||
DBG("headsetobserve: request irq failed\n");
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void headsetobserve_work(struct work_struct *work)
|
||||
{
|
||||
int i,level = 0;
|
||||
|
||||
// DBG("---headsetobserve_work---\n");
|
||||
mutex_lock(&Headset_dev.mutex_lock);
|
||||
|
||||
for(i=0; i<3; i++)
|
||||
{
|
||||
level = gpio_get_value(prk2818_headset_info->gpio);
|
||||
if(level < 0)
|
||||
{
|
||||
printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,prk2818_headset_info->gpio,i);
|
||||
msleep(1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(level < 0)
|
||||
{
|
||||
printk("%s:get pin level err!\n",__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(prk2818_headset_info->headset_in_type)
|
||||
{
|
||||
case HEADSET_IN_HIGH:
|
||||
if(level > 0)
|
||||
{//in--High level
|
||||
DBG("--- HEADSET_IN_HIGH headset in---\n");
|
||||
Headset_dev.cur_headset_status = BIT_HEADSET;
|
||||
headset_change_irqtype(IRQF_TRIGGER_FALLING);//
|
||||
}
|
||||
else if(level == 0)
|
||||
{//out--Low level
|
||||
DBG("---HEADSET_IN_HIGH headset out---\n");
|
||||
Headset_dev.cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
|
||||
headset_change_irqtype(IRQF_TRIGGER_RISING);//
|
||||
}
|
||||
break;
|
||||
case HEADSET_IN_LOW:
|
||||
if(level == 0)
|
||||
{//in--High level
|
||||
DBG("---HEADSET_IN_LOW headset in---\n");
|
||||
Headset_dev.cur_headset_status = BIT_HEADSET;
|
||||
headset_change_irqtype(IRQF_TRIGGER_RISING);//
|
||||
}
|
||||
else if(level > 0)
|
||||
{//out--High level
|
||||
DBG("---HEADSET_IN_LOW headset out---\n");
|
||||
Headset_dev.cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
|
||||
headset_change_irqtype(IRQF_TRIGGER_FALLING);//
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBG("---- ERROR: on headset headset_in_type error -----\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(Headset_dev.cur_headset_status != Headset_dev.pre_headset_status)
|
||||
{
|
||||
Headset_dev.pre_headset_status = Headset_dev.cur_headset_status;
|
||||
switch_set_state(&Headset_dev.sdev, Headset_dev.cur_headset_status);
|
||||
DBG("Headset_dev.cur_headset_status = %d\n",Headset_dev.cur_headset_status);
|
||||
#if defined(CONFIG_MACH_BENGO_V2) || defined(CONFIG_MACH_BENGO) || defined(CONFIG_MACH_Z5) || defined(CONFIG_MACH_Z5_V2) || defined(CONFIG_MACH_A22)
|
||||
detect_HSMic();
|
||||
#endif
|
||||
}
|
||||
mutex_unlock(&Headset_dev.mutex_lock);
|
||||
}
|
||||
|
||||
static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf)
|
||||
{
|
||||
return sprintf(buf, "Headset\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void headset_early_resume(struct early_suspend *h)
|
||||
{
|
||||
schedule_delayed_work(&g_headsetobserve_work, msecs_to_jiffies(10));
|
||||
//DBG(">>>>>headset_early_resume\n");
|
||||
}
|
||||
|
||||
static struct early_suspend hs_early_suspend;
|
||||
#endif
|
||||
|
||||
static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG("RockChip headset observe driver\n");
|
||||
prk2818_headset_info = pdev->dev.platform_data;
|
||||
|
||||
Headset_dev.cur_headset_status = 0;
|
||||
Headset_dev.pre_headset_status = 0;
|
||||
Headset_dev.sdev.name = "h2w";
|
||||
Headset_dev.sdev.print_name = h2w_print_name;
|
||||
mutex_init(&Headset_dev.mutex_lock);
|
||||
|
||||
ret = switch_dev_register(&Headset_dev.sdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
INIT_DELAYED_WORK(&g_headsetobserve_work, headsetobserve_work);
|
||||
|
||||
ret = gpio_request(prk2818_headset_info->gpio, "headset_det");
|
||||
if (ret)
|
||||
{
|
||||
DBG("headsetobserve: request gpio_request failed\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_pull_updown(prk2818_headset_info->gpio, GPIONormal);
|
||||
gpio_direction_input(prk2818_headset_info->gpio);
|
||||
prk2818_headset_info->irq = gpio_to_irq(prk2818_headset_info->gpio);
|
||||
|
||||
if(prk2818_headset_info->headset_in_type == HEADSET_IN_HIGH)
|
||||
prk2818_headset_info->irq_type = IRQF_TRIGGER_RISING;
|
||||
else
|
||||
prk2818_headset_info->irq_type = IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(prk2818_headset_info->irq, headset_interrupt, prk2818_headset_info->irq_type, NULL, NULL);
|
||||
if (ret)
|
||||
{
|
||||
DBG("headsetobserve: request irq failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
schedule_delayed_work(&g_headsetobserve_work, msecs_to_jiffies(500));
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
hs_early_suspend.suspend = NULL;
|
||||
hs_early_suspend.resume = headset_early_resume;
|
||||
hs_early_suspend.level = ~0x0;
|
||||
register_early_suspend(&hs_early_suspend);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rockchip_headsetobserve_driver = {
|
||||
.probe = rockchip_headsetobserve_probe,
|
||||
.driver = {
|
||||
.name = "rk2818_headsetdet",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int __init rockchip_headsetobserve_init(void)
|
||||
{
|
||||
platform_driver_register(&rockchip_headsetobserve_driver);
|
||||
return 0;
|
||||
}
|
||||
module_init(rockchip_headsetobserve_init);
|
||||
MODULE_DESCRIPTION("Rockchip Headset Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef RK2818_HEADSET_H
|
||||
#define RK2818_HEADSET_H
|
||||
|
||||
#define HEADSET_IN_HIGH 0x00000001
|
||||
#define HEADSET_IN_LOW 0x00000000
|
||||
|
||||
/* 耳机数据结构体 */
|
||||
struct rk2818_headset_data {
|
||||
unsigned int gpio;
|
||||
unsigned int irq;
|
||||
unsigned int irq_type;
|
||||
unsigned int headset_in_type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -268,29 +268,6 @@ config I2C_POWERMAC
|
|||
tristate "Powermac I2C interface"
|
||||
depends on PPC_PMAC
|
||||
|
||||
config I2C_RK2818
|
||||
tristate "RK2818 i2c interface (I2C)"
|
||||
depends on ARCH_RK2818
|
||||
default y
|
||||
help
|
||||
This supports the use of the I2C interface on rk2818 processors.
|
||||
|
||||
if I2C_RK2818
|
||||
comment "Now, there are two I2C interfaces selected by developer."
|
||||
|
||||
config I2C0_RK2818
|
||||
bool "RK2818 I2C0 interface support"
|
||||
default y
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This supports the use of the I2C0 interface on rk2818 processors.
|
||||
config I2C1_RK2818
|
||||
bool "RK2818 I2C1 interface support"
|
||||
default y
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This supports the use of the I2C1 interface on rk2818 processors.
|
||||
endif
|
||||
config I2C_RK29
|
||||
tristate "RK29 i2c interface (I2C)"
|
||||
depends on ARCH_RK29
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#
|
||||
# Makefile for the i2c bus drivers.
|
||||
#
|
||||
obj-$(CONFIG_I2C_RK2818) += i2c-rk2818.o
|
||||
obj-$(CONFIG_I2C_RK29) += i2c-rk29.o
|
||||
obj-$(CONFIG_I2C_DEV_RK29) += i2c-dev-rk29.o
|
||||
obj-y += i2c-gpio.o
|
||||
obj-$(CONFIG_I2C_DEV_RK29) += i2c-dev-rk29.o
|
||||
obj-y += i2c-gpio.o
|
||||
|
||||
ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
|
|
|
|||
|
|
@ -1,820 +0,0 @@
|
|||
/* drivers/i2c/busses/i2c_rockchip.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/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <mach/board.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "i2c-rockchip.h"
|
||||
#define DRV_NAME "rockchip_i2c"
|
||||
|
||||
#define RK2818_I2C_TIMEOUT (msecs_to_jiffies(500))
|
||||
#define RK2818_DELAY_TIME 2
|
||||
|
||||
#if 0
|
||||
#define i2c_dbg(dev, format, arg...) \
|
||||
dev_printk(KERN_INFO , dev , format , ## arg)
|
||||
#else
|
||||
#define i2c_dbg(dev, format, arg...)
|
||||
#endif
|
||||
|
||||
enum rockchip_error {
|
||||
RK2818_ERROR_NONE = 0,
|
||||
RK2818_ERROR_ARBITR_LOSE,
|
||||
RK2818_ERROR_UNKNOWN
|
||||
};
|
||||
|
||||
enum rockchip_event {
|
||||
RK2818_EVENT_NONE = 0,
|
||||
/* master has received ack(MTX mode)
|
||||
means that data has been sent to slave.
|
||||
*/
|
||||
RK2818_EVENT_MTX_RCVD_ACK,
|
||||
/* master needs to send ack to slave(MRX mode)
|
||||
means that data has been received from slave.
|
||||
*/
|
||||
RK2818_EVENT_MRX_NEED_ACK,
|
||||
RK2818_EVENT_MAX
|
||||
};
|
||||
|
||||
struct rockchip_i2c_data {
|
||||
struct device *dev;
|
||||
struct i2c_adapter adap;
|
||||
void __iomem *regs;
|
||||
struct resource *ioarea;
|
||||
|
||||
unsigned int suspended:1;
|
||||
unsigned long scl_rate;
|
||||
unsigned long i2c_rate;
|
||||
struct clk *clk;
|
||||
|
||||
unsigned int mode;
|
||||
|
||||
unsigned int irq;
|
||||
|
||||
spinlock_t cmd_lock;
|
||||
struct completion cmd_complete;
|
||||
enum rockchip_event cmd_event;
|
||||
enum rockchip_error cmd_err;
|
||||
|
||||
unsigned int msg_idx;
|
||||
unsigned int msg_num;
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
struct notifier_block freq_transition;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void rockchip_i2c_init_hw(struct rockchip_i2c_data *i2c);
|
||||
|
||||
static inline void rockchip_i2c_disable_irqs(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = readl(i2c->regs + I2C_IER);
|
||||
writel(tmp & IRQ_ALL_DISABLE, i2c->regs + I2C_IER);
|
||||
}
|
||||
static inline void rockchip_i2c_enable_irqs(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = readl(i2c->regs + I2C_IER);
|
||||
writel(tmp | IRQ_MST_ENABLE, i2c->regs + I2C_IER);
|
||||
}
|
||||
|
||||
/* scl = pclk/(5 *(rem+1) * 2^(exp+1)) */
|
||||
static void rockchip_i2c_calcdivisor(unsigned long pclk,
|
||||
unsigned long scl_rate,
|
||||
unsigned long *real_rate,
|
||||
unsigned int *rem, unsigned int *exp)
|
||||
{
|
||||
unsigned int calc_rem = 0;
|
||||
unsigned int calc_exp = 0;
|
||||
|
||||
for(calc_exp = 0; calc_exp < I2CCDVR_EXP_MAX; calc_exp++)
|
||||
{
|
||||
calc_rem = pclk / (5 * scl_rate * (1 <<(calc_exp +1)));
|
||||
if(calc_rem < I2CCDVR_REM_MAX)
|
||||
break;
|
||||
}
|
||||
if(calc_rem >= I2CCDVR_REM_MAX || calc_exp >= I2CCDVR_EXP_MAX)
|
||||
{
|
||||
calc_rem = I2CCDVR_REM_MAX - 1;
|
||||
calc_exp = I2CCDVR_EXP_MAX - 1;
|
||||
}
|
||||
*rem = calc_rem;
|
||||
*exp = calc_exp;
|
||||
*real_rate = pclk/(5 * (calc_rem + 1) * (1 <<(calc_exp +1)));
|
||||
return;
|
||||
}
|
||||
/* set i2c bus scl rate */
|
||||
static void rockchip_i2c_clockrate(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_RK2818
|
||||
struct rk2818_i2c_platform_data *pdata = i2c->dev->platform_data;
|
||||
#else
|
||||
struct rk29_i2c_platform_data *pdata = i2c->dev->platform_data;
|
||||
#endif
|
||||
unsigned int rem = 0, exp = 0;
|
||||
unsigned long scl_rate, real_rate = 0, tmp;
|
||||
|
||||
i2c->i2c_rate = clk_get_rate(i2c->clk);
|
||||
|
||||
scl_rate = (i2c->scl_rate) ? i2c->scl_rate : ((pdata->scl_rate)? pdata->scl_rate:100000);
|
||||
|
||||
rockchip_i2c_calcdivisor(i2c->i2c_rate, scl_rate, &real_rate, &rem, &exp);
|
||||
|
||||
tmp = readl(i2c->regs + I2C_OPR);
|
||||
tmp |= exp;
|
||||
tmp |= rem<<I2CCDVR_EXP_BITS;
|
||||
writel(tmp, i2c->regs + I2C_OPR);
|
||||
if(real_rate > 400000)
|
||||
dev_warn(i2c->dev, "i2c_rate[%luKhz], scl_rate[%luKhz], real_rate[%luKhz] > 400Khz\n",
|
||||
i2c->i2c_rate/1000, scl_rate/1000, real_rate/1000);
|
||||
else
|
||||
i2c_dbg(i2c->dev, "i2c_rate[%luKhz], scl_rate[%luKhz], real_rate[%luKhz]\n",
|
||||
i2c->i2c_rate/1000, scl_rate/1000, real_rate/1000);
|
||||
return;
|
||||
}
|
||||
static int rockchip_event_occurred(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long isr;
|
||||
|
||||
isr = readl(i2c->regs + I2C_ISR);
|
||||
i2c_dbg(i2c->dev,"event occurred, isr = %lx\n", isr);
|
||||
if(isr & I2C_ISR_ARBITR_LOSE)
|
||||
{
|
||||
isr &= ~I2C_ISR_ARBITR_LOSE;
|
||||
writel(isr, i2c->regs + I2C_ISR);
|
||||
i2c->cmd_err = RK2818_ERROR_ARBITR_LOSE;
|
||||
dev_err(i2c->dev, "<error>arbitration loss\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch(i2c->cmd_event)
|
||||
{
|
||||
case RK2818_EVENT_MTX_RCVD_ACK:
|
||||
if(isr & I2C_ISR_MTX_RCVD_ACK)
|
||||
{
|
||||
isr &= ~I2C_ISR_MTX_RCVD_ACK;
|
||||
writel(isr, i2c->regs + I2C_ISR);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case RK2818_EVENT_MRX_NEED_ACK:
|
||||
if(isr & I2C_ISR_MRX_NEED_ACK)
|
||||
{
|
||||
isr &= ~I2C_ISR_MRX_NEED_ACK;
|
||||
writel(isr, i2c->regs + I2C_ISR);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
i2c->cmd_err = RK2818_ERROR_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rockchip_i2c_irq(int irq, void *data)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = (struct rockchip_i2c_data *)data;
|
||||
int res;
|
||||
|
||||
rockchip_i2c_disable_irqs(i2c);
|
||||
spin_lock(&i2c->cmd_lock);
|
||||
res = rockchip_event_occurred(i2c);
|
||||
if(res)
|
||||
//if(res || i2c->cmd_err != RK2818_ERROR_NONE)
|
||||
complete(&i2c->cmd_complete);
|
||||
spin_unlock(&i2c->cmd_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static int wait_for_completion_poll_timeout(struct rockchip_i2c_data *i2c, unsigned long timeout)
|
||||
{
|
||||
unsigned int time = RK2818_DELAY_TIME;
|
||||
int res;
|
||||
|
||||
while(!time_after(jiffies, jiffies + timeout))
|
||||
{
|
||||
res = rockchip_event_occurred(i2c);
|
||||
if(res)
|
||||
//if(res || (i2c->cmd_err != RK2818_ERROR_NONE && i2c->cmd_err != RK2818_ERROR_UNKNOWN))
|
||||
return 1;
|
||||
udelay(time);
|
||||
time *= 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int rockchip_wait_event(struct rockchip_i2c_data *i2c,
|
||||
enum rockchip_event mr_event)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
{
|
||||
if(unlikely(irqs_disabled()))
|
||||
{
|
||||
dev_err(i2c->dev, "irqs are disabled on this system!\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&i2c->cmd_lock,flags);
|
||||
i2c->cmd_err = RK2818_ERROR_NONE;
|
||||
i2c->cmd_event = mr_event;
|
||||
|
||||
init_completion(&i2c->cmd_complete);
|
||||
|
||||
spin_unlock_irqrestore(&i2c->cmd_lock,flags);
|
||||
|
||||
rockchip_i2c_enable_irqs(i2c);
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
ret = wait_for_completion_interruptible_timeout(&i2c->cmd_complete,
|
||||
RK2818_I2C_TIMEOUT);
|
||||
else
|
||||
ret = wait_for_completion_poll_timeout(i2c, RK2818_I2C_TIMEOUT);
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
dev_err(i2c->dev, "i2c wait for event %04x, retrun %d \n", mr_event, ret);
|
||||
return ret;
|
||||
}
|
||||
if(ret == 0)
|
||||
{
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_wait_while_busy(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long timeout = jiffies + RK2818_I2C_TIMEOUT;
|
||||
unsigned long lsr;
|
||||
unsigned int time = RK2818_DELAY_TIME;
|
||||
|
||||
while(!time_after(jiffies, timeout))
|
||||
{
|
||||
lsr = readl(i2c->regs + I2C_LSR);
|
||||
if(!(lsr & I2C_LSR_BUSY))
|
||||
return 0;
|
||||
udelay(time);
|
||||
time *= 2;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
static int rockchip_i2c_stop(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long timeout = jiffies + RK2818_I2C_TIMEOUT;
|
||||
unsigned int time = RK2818_DELAY_TIME;
|
||||
|
||||
writel(I2C_LCMR_STOP|I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
|
||||
while(!time_after(jiffies, timeout))
|
||||
{
|
||||
if(!(readl(i2c->regs + I2C_LCMR) & I2C_LCMR_STOP))
|
||||
{
|
||||
i2c_dbg(i2c->dev, "i2c stop successfully\n");
|
||||
return 0;
|
||||
}
|
||||
udelay(time);
|
||||
time *= 2;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
|
||||
}
|
||||
static int rockchip_send_2nd_addr(struct rockchip_i2c_data *i2c,
|
||||
struct i2c_msg *msg, int start)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long addr_2nd = msg->addr & 0xff;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
|
||||
conr |= I2C_CONR_MTX_MODE;
|
||||
//conr &= I2C_CONR_ACK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
|
||||
i2c_dbg(i2c->dev, "i2c send addr_2nd: %lx\n", addr_2nd);
|
||||
writel(addr_2nd, i2c->regs + I2C_MTXR);
|
||||
writel(I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
|
||||
if((ret = rockchip_wait_event(i2c, RK2818_EVENT_MTX_RCVD_ACK)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "after sent addr_2nd, i2c wait for ACK timeout\n");
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static int rockchip_send_address(struct rockchip_i2c_data *i2c,
|
||||
struct i2c_msg *msg, int start)
|
||||
{
|
||||
unsigned long addr_1st;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
int ret = 0;
|
||||
|
||||
if(msg->flags & I2C_M_TEN)
|
||||
addr_1st = (0xf0 | (((unsigned long) msg->addr & 0x300) >> 7)) & 0xff;
|
||||
else
|
||||
addr_1st = ((msg->addr << 1) & 0xff);
|
||||
|
||||
if (msg->flags & I2C_M_RD)
|
||||
addr_1st |= 0x01;
|
||||
else
|
||||
addr_1st &= (~0x01);
|
||||
|
||||
conr |= I2C_CONR_MTX_MODE;
|
||||
//conr &= I2C_CONR_ACK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
i2c_dbg(i2c->dev, "i2c send addr_1st: %lx\n", addr_1st);
|
||||
|
||||
writel(addr_1st, i2c->regs + I2C_MTXR);
|
||||
|
||||
if (start)
|
||||
{
|
||||
if((ret = rockchip_wait_while_busy(i2c)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "i2c is busy, when send address\n");
|
||||
return ret;
|
||||
}
|
||||
writel(I2C_LCMR_START, i2c->regs + I2C_LCMR);
|
||||
}
|
||||
else
|
||||
writel(I2C_LCMR_START|I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
|
||||
|
||||
if((ret = rockchip_wait_event(i2c, RK2818_EVENT_MTX_RCVD_ACK)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "after sent addr_1st, i2c wait for ACK timeout\n");
|
||||
return ret;
|
||||
}
|
||||
if(start && (msg->flags & I2C_M_TEN))
|
||||
ret = rockchip_send_2nd_addr(i2c, msg, start);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_i2c_send_msg(struct rockchip_i2c_data *i2c, struct i2c_msg *msg)
|
||||
{
|
||||
int i, ret = 0;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr |= I2C_CONR_MTX_MODE;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
for(i = 0; i < msg->len; i++)
|
||||
{
|
||||
i2c_dbg(i2c->dev, "i2c send buf[%d]: %x\n", i, msg->buf[i]);
|
||||
writel(msg->buf[i], i2c->regs + I2C_MTXR);
|
||||
/*
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr &= I2C_CONR_ACK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
*/
|
||||
writel(I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
|
||||
|
||||
if((ret = rockchip_wait_event(i2c, RK2818_EVENT_MTX_RCVD_ACK)) != 0)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static int rockchip_i2c_recv_msg(struct rockchip_i2c_data *i2c, struct i2c_msg *msg)
|
||||
{
|
||||
int i, ret = 0;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr &= I2C_CONR_MRX_MODE;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
|
||||
for(i = 0; i < msg->len; i++)
|
||||
{
|
||||
writel(I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
|
||||
if((ret = rockchip_wait_event(i2c, RK2818_EVENT_MRX_NEED_ACK)) != 0)
|
||||
return ret;
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr &= I2C_CONR_ACK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
msg->buf[i] = (uint8_t)readl(i2c->regs + I2C_MRXR);
|
||||
i2c_dbg(i2c->dev, "i2c recv >>>>>>>>>>>> buf[%d]: %x\n", i, msg->buf[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static int rockchip_xfer_msg(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msg, int start, int stop)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = (struct rockchip_i2c_data *)adap->algo_data;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
int ret = 0;
|
||||
|
||||
#if defined (CONFIG_IOEXTEND_TCA6424)
|
||||
struct tca6424_platform_data *pdata = adap->dev.platform_data;
|
||||
#endif
|
||||
|
||||
if(msg->len == 0)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
dev_err(i2c->dev, "<error>msg->len = %d\n", msg->len);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if((ret = rockchip_send_address(i2c, msg, start))!= 0)
|
||||
{
|
||||
dev_err(i2c->dev, "<error>rockchip_send_address timeout\n");
|
||||
goto exit;
|
||||
}
|
||||
if(msg->flags & I2C_M_RD)
|
||||
{
|
||||
if((ret = rockchip_i2c_recv_msg(i2c, msg)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "<error>rockchip_i2c_recv_msg timeout\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((ret = rockchip_i2c_send_msg(i2c, msg)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "<error>rockchip_i2c_send_msg timeout\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if(stop)
|
||||
{
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr |= I2C_CONR_NAK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
if((ret = rockchip_i2c_stop(i2c)) != 0)
|
||||
{
|
||||
dev_err(i2c->dev, "<error>rockchip_i2c_stop timeout\n");
|
||||
}
|
||||
|
||||
//not I2C code,add by sxj,used for extend gpio intrrupt,set SCL and SDA pin.
|
||||
if(msg->flags & I2C_M_RD)
|
||||
{
|
||||
#if defined (CONFIG_IOEXTEND_TCA6424)
|
||||
if (pdata && pdata->reseti2cpin) {
|
||||
pdata->reseti2cpin();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int rockchip_i2c_xfer(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msgs, int num)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
struct rockchip_i2c_data *i2c = (struct rockchip_i2c_data *)adap->algo_data;
|
||||
unsigned long conr = readl(i2c->regs + I2C_CONR);
|
||||
/*
|
||||
if(i2c->suspended ==1)
|
||||
return -EIO;
|
||||
*/
|
||||
if(msgs[0].scl_rate <= 400000 && msgs[0].scl_rate > 0)
|
||||
i2c->scl_rate = msgs[0].scl_rate;
|
||||
else
|
||||
i2c->scl_rate = 400000;
|
||||
|
||||
conr |= I2C_CONR_MPORT_ENABLE;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
|
||||
rockchip_i2c_init_hw(i2c);
|
||||
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr &= I2C_CONR_ACK;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
ret = rockchip_xfer_msg(adap, &msgs[i], (i == 0), (i == (num - 1)));
|
||||
if (ret != 0)
|
||||
{
|
||||
num = ret;
|
||||
dev_err(i2c->dev, "rockchip_xfer_msg error, ret = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
conr = readl(i2c->regs + I2C_CONR);
|
||||
conr &= I2C_CONR_MPORT_DISABLE;
|
||||
writel(conr, i2c->regs + I2C_CONR);
|
||||
return num;
|
||||
}
|
||||
|
||||
static u32 rockchip_i2c_func(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm rockchip_i2c_algorithm = {
|
||||
.master_xfer = rockchip_i2c_xfer,
|
||||
.functionality = rockchip_i2c_func,
|
||||
};
|
||||
|
||||
int i2c_suspended(struct i2c_adapter *adap)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = (struct rockchip_i2c_data *)adap->algo_data;
|
||||
if(adap->nr > 1)
|
||||
return 1;
|
||||
if(i2c == NULL)
|
||||
return 1;
|
||||
return i2c->suspended;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_suspended);
|
||||
|
||||
static void rockchip_i2c_init_hw(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
unsigned long lcmr = 0x00000000;
|
||||
|
||||
unsigned long opr = readl(i2c->regs + I2C_OPR);
|
||||
opr |= I2C_OPR_RESET_STATUS;
|
||||
writel(opr, i2c->regs + I2C_OPR);
|
||||
|
||||
writel(lcmr, i2c->regs + I2C_LCMR);
|
||||
|
||||
rockchip_i2c_disable_irqs(i2c);
|
||||
|
||||
rockchip_i2c_clockrate(i2c);
|
||||
|
||||
opr = readl(i2c->regs + I2C_OPR);
|
||||
opr |= I2C_OPR_CORE_ENABLE;
|
||||
writel(opr, i2c->regs + I2C_OPR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
|
||||
#define freq_to_i2c(_n) container_of(_n, struct rockchip_i2c_data, freq_transition)
|
||||
|
||||
static int rockchip_i2c_cpufreq_transition(struct notifier_block *nb,
|
||||
unsigned long val, void *data)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = freq_to_i2c(nb);
|
||||
unsigned long flags;
|
||||
int delta_f;
|
||||
delta_f = clk_get_rate(i2c->clk) - i2c->i2c_rate;
|
||||
|
||||
if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
|
||||
(val == CPUFREQ_PRECHANGE && delta_f > 0))
|
||||
{
|
||||
spin_lock_irqsave(&i2c->cmd_lock, flags);
|
||||
rockchip_i2c_clockrate(i2c);
|
||||
spin_unlock_irqrestore(&i2c->cmd_lock, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int rockchip_i2c_register_cpufreq(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
i2c->freq_transition.notifier_call = rockchip_i2c_cpufreq_transition;
|
||||
|
||||
return cpufreq_register_notifier(&i2c->freq_transition,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
}
|
||||
|
||||
static inline void rockchip_i2c_unregister_cpufreq(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
cpufreq_unregister_notifier(&i2c->freq_transition,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int rockchip_i2c_register_cpufreq(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rockchip_i2c_unregister_cpufreq(struct rockchip_i2c_data *i2c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
static int rockchip_i2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c;
|
||||
#ifdef CONFIG_ARCH_RK2818
|
||||
struct rk2818_i2c_platform_data *pdata = NULL;
|
||||
#else
|
||||
struct rk29_i2c_platform_data *pdata = NULL;
|
||||
#endif
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if (!pdata)
|
||||
{
|
||||
dev_err(&pdev->dev, "<error>no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
i2c = kzalloc(sizeof(struct rockchip_i2c_data), GFP_KERNEL);
|
||||
if (!i2c)
|
||||
{
|
||||
dev_err(&pdev->dev, "<error>no memory for state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
i2c->mode = pdata->mode;
|
||||
i2c->scl_rate = (pdata->scl_rate) ? pdata->scl_rate : 100000;
|
||||
|
||||
strlcpy(i2c->adap.name, DRV_NAME, sizeof(i2c->adap.name));
|
||||
i2c->adap.owner = THIS_MODULE;
|
||||
i2c->adap.algo = &rockchip_i2c_algorithm;
|
||||
i2c->adap.class = I2C_CLASS_HWMON;
|
||||
spin_lock_init(&i2c->cmd_lock);
|
||||
|
||||
i2c->dev = &pdev->dev;
|
||||
|
||||
i2c->clk = clk_get(&pdev->dev, "i2c");
|
||||
if (IS_ERR(i2c->clk)) {
|
||||
dev_err(&pdev->dev, "<error>cannot get clock\n");
|
||||
ret = -ENOENT;
|
||||
goto err_noclk;
|
||||
}
|
||||
|
||||
clk_enable(i2c->clk);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "<error>cannot find IO resource\n");
|
||||
ret = -ENOENT;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
i2c->ioarea = request_mem_region(res->start, res->end - res->start + 1,
|
||||
pdev->name);
|
||||
|
||||
if (i2c->ioarea == NULL) {
|
||||
dev_err(&pdev->dev, "<error>cannot request IO\n");
|
||||
ret = -ENXIO;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
i2c->regs = ioremap(res->start, res->end - res->start + 1);
|
||||
|
||||
if (i2c->regs == NULL) {
|
||||
dev_err(&pdev->dev, "<error>annot map IO\n");
|
||||
ret = -ENXIO;
|
||||
goto err_ioarea;
|
||||
}
|
||||
i2c->adap.algo_data = i2c;
|
||||
i2c->adap.dev.parent = &pdev->dev;
|
||||
|
||||
if(pdata->io_init)
|
||||
pdata->io_init();
|
||||
|
||||
rockchip_i2c_init_hw(i2c);
|
||||
|
||||
i2c->irq = ret = platform_get_irq(pdev, 0);
|
||||
if (ret <= 0) {
|
||||
dev_err(&pdev->dev, "cannot find IRQ\n");
|
||||
goto err_iomap;
|
||||
}
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
{
|
||||
ret = request_irq(i2c->irq, rockchip_i2c_irq, IRQF_DISABLED,
|
||||
dev_name(&pdev->dev), i2c);
|
||||
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
|
||||
goto err_iomap;
|
||||
}
|
||||
}
|
||||
ret = rockchip_i2c_register_cpufreq(i2c);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
i2c->adap.nr = pdata->bus_num;
|
||||
ret = i2c_add_numbered_adapter(&i2c->adap);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
|
||||
goto err_cpufreq;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, i2c);
|
||||
|
||||
dev_info(&pdev->dev, "%s: RK2818 I2C adapter\n", dev_name(&i2c->adap.dev));
|
||||
return 0;
|
||||
|
||||
err_cpufreq:
|
||||
rockchip_i2c_unregister_cpufreq(i2c);
|
||||
|
||||
err_irq:
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
free_irq(i2c->irq, i2c);
|
||||
|
||||
err_iomap:
|
||||
iounmap(i2c->regs);
|
||||
|
||||
err_ioarea:
|
||||
release_resource(i2c->ioarea);
|
||||
kfree(i2c->ioarea);
|
||||
|
||||
err_clk:
|
||||
clk_disable(i2c->clk);
|
||||
clk_put(i2c->clk);
|
||||
|
||||
err_noclk:
|
||||
kfree(i2c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rockchip_i2c_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
rockchip_i2c_unregister_cpufreq(i2c);
|
||||
|
||||
i2c_del_adapter(&i2c->adap);
|
||||
if(i2c->mode == I2C_MODE_IRQ)
|
||||
free_irq(i2c->irq, i2c);
|
||||
|
||||
clk_disable(i2c->clk);
|
||||
clk_put(i2c->clk);
|
||||
|
||||
iounmap(i2c->regs);
|
||||
|
||||
release_resource(i2c->ioarea);
|
||||
kfree(i2c->ioarea);
|
||||
kfree(i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int rockchip_i2c_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
i2c->suspended = 1;
|
||||
return 0;
|
||||
}
|
||||
static int rockchip_i2c_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_i2c_data *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
i2c->suspended = 0;
|
||||
rockchip_i2c_init_hw(i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rockchip_i2c_suspend NULL
|
||||
#define rockchip_i2c_resume NULL
|
||||
#endif
|
||||
|
||||
|
||||
static struct platform_driver rockchip_i2c_driver = {
|
||||
.probe = rockchip_i2c_probe,
|
||||
.remove = rockchip_i2c_remove,
|
||||
.suspend = rockchip_i2c_suspend,
|
||||
.resume = rockchip_i2c_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rockchip_i2c_adap_init(void)
|
||||
{
|
||||
return platform_driver_register(&rockchip_i2c_driver);
|
||||
}
|
||||
|
||||
static void __exit rockchip_i2c_adap_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rockchip_i2c_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(rockchip_i2c_adap_init);
|
||||
module_exit(rockchip_i2c_adap_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Driver for RK2818 I2C Bus");
|
||||
MODULE_AUTHOR("kfx, kfx@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/* drivers/i2c/busses/i2c_rk2818.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 __RK2818_I2C_H
|
||||
#define __RK2818_I2C_H
|
||||
|
||||
/* master transmit */
|
||||
#define I2C_MTXR (0x0000)
|
||||
/* master receive */
|
||||
#define I2C_MRXR (0x0004)
|
||||
/* slave address */
|
||||
#define I2C_SADDR (0x0010)
|
||||
/* interrupt enable control */
|
||||
#define I2C_IER (0x0014)
|
||||
#define I2C_IER_ARBITR_LOSE (1<<7)
|
||||
#define I2C_IER_MRX_NEED_ACK (1<<1)
|
||||
#define I2C_IER_MTX_RCVD_ACK (1<<0)
|
||||
|
||||
#define IRQ_MST_ENABLE (I2C_IER_ARBITR_LOSE | \
|
||||
I2C_IER_MRX_NEED_ACK | \
|
||||
I2C_IER_MTX_RCVD_ACK)
|
||||
#define IRQ_ALL_DISABLE (0x00)
|
||||
|
||||
/* interrupt status, write 0 to clear */
|
||||
#define I2C_ISR (0x0018)
|
||||
#define I2C_ISR_ARBITR_LOSE (1<<7)
|
||||
#define I2C_ISR_MRX_NEED_ACK (1<<1)
|
||||
#define I2C_ISR_MTX_RCVD_ACK (1<<0)
|
||||
|
||||
/* stop/start/resume command, write 1 to set */
|
||||
#define I2C_LCMR (0x001c)
|
||||
#define I2C_LCMR_RESUME (1<<2)
|
||||
#define I2C_LCMR_STOP (1<<1)
|
||||
#define I2C_LCMR_START (1<<0)
|
||||
|
||||
/* i2c core status */
|
||||
#define I2C_LSR (0x0020)
|
||||
#define I2C_LSR_RCV_NAK (1<<1)
|
||||
#define I2C_LSR_RCV_ACK (~(1<<1))
|
||||
#define I2C_LSR_BUSY (1<<0)
|
||||
|
||||
/* i2c config */
|
||||
#define I2C_CONR (0x0024)
|
||||
#define I2C_CONR_NAK (1<<4)
|
||||
#define I2C_CONR_ACK (~(1<<4))
|
||||
#define I2C_CONR_MTX_MODE (1<<3)
|
||||
#define I2C_CONR_MRX_MODE (~(1<<3))
|
||||
#define I2C_CONR_MPORT_ENABLE (1<<2)
|
||||
#define I2C_CONR_MPORT_DISABLE (~(1<<2))
|
||||
|
||||
/* i2c core config */
|
||||
#define I2C_OPR (0x0028)
|
||||
#define I2C_OPR_RESET_STATUS (1<<7)
|
||||
#define I2C_OPR_CORE_ENABLE (1<<6)
|
||||
|
||||
#define I2CCDVR_REM_BITS (0x03)
|
||||
#define I2CCDVR_REM_MAX (1<<(I2CCDVR_REM_BITS))
|
||||
#define I2CCDVR_EXP_BITS (0x03)
|
||||
#define I2CCDVR_EXP_MAX (1<<(I2CCDVR_EXP_BITS))
|
||||
|
||||
#endif
|
||||
|
|
@ -449,35 +449,5 @@ config KEYBOARD_W90P910
|
|||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called w90p910_keypad.
|
||||
config KEYBOARD_RK28ADC
|
||||
tristate "RK2818 ADC Keypad support"
|
||||
depends on RK28_ADC
|
||||
default y
|
||||
help
|
||||
Say Y here to enable the adc keypad on SDK board
|
||||
based on RK2818.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called rk2818_adckey.
|
||||
|
||||
config HEADSET_KEY
|
||||
tristate "RK2818 headset Keypad support"
|
||||
depends on RK28_ADC
|
||||
default y
|
||||
help
|
||||
Say Y here to enable the headset adc keypad on SDK board
|
||||
based on RK2818.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called rk2818_hskey.
|
||||
|
||||
config KEYBOARD_RK28ADC_IT50
|
||||
tristate "RK2818 ADC Keypad it50 support"
|
||||
depends on RK28_ADC
|
||||
help
|
||||
Say Y here to enable the adc keypad on SDK board
|
||||
based on RK2818.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called rk2818_adckey.
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -39,8 +39,5 @@ obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
|
|||
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_RK28ADC) += rk2818_adckey.o
|
||||
obj-$(CONFIG_KEYBOARD_RK28ADC_IT50) += rk2818_adckey_t50.o
|
||||
obj-$(CONFIG_HEADSET_KEY) += rk2818_hskey.o
|
||||
obj-$(CONFIG_SYNAPTICS_SO340010) += synaptics_so340010.o
|
||||
|
||||
|
|
|
|||
|
|
@ -1,411 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/input/keyboard/rk28_adckey.c
|
||||
*
|
||||
* This driver program support to AD key which use for rk28 chip
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/adc.h>
|
||||
#include <mach/board.h>
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define KEY_PHYS_NAME "rk2818_adckey/input0"
|
||||
|
||||
volatile int gADSampleTimes = 0;
|
||||
volatile int gStatePlaykey = 0;
|
||||
volatile unsigned int gCodeCount = 0;
|
||||
volatile unsigned int gThisCode = 0;
|
||||
volatile unsigned int gLastCode = 0;
|
||||
volatile unsigned int gFlagShortPlay = 0;
|
||||
volatile unsigned int gFlagLongPlay = 0;
|
||||
volatile unsigned int gPlayCount = 0;
|
||||
|
||||
//key code tab
|
||||
struct rk28_adckey
|
||||
{
|
||||
struct semaphore lock;
|
||||
struct rk28_adc_client *client;
|
||||
struct input_dev *input_dev;
|
||||
struct timer_list timer;
|
||||
unsigned char * keycodes;
|
||||
void __iomem *mmio_base;
|
||||
};
|
||||
|
||||
struct rk28_adckey *pRk28AdcKey;
|
||||
|
||||
unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
|
||||
{
|
||||
while(ptab->adc_keycode != 0)
|
||||
{
|
||||
if((ptab->adc_value == 0)&&(advalue >= 0 && advalue <= 5))
|
||||
return ptab->adc_keycode;
|
||||
if((advalue > ptab->adc_value - rk2818_adckey_data->adc_drift) && (advalue < ptab->adc_value + rk2818_adckey_data->adc_drift))
|
||||
return ptab->adc_keycode;
|
||||
ptab++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(rk28_get_keycode);
|
||||
|
||||
static irqreturn_t rk28_playkey_irq(int irq, void *handle)
|
||||
{
|
||||
|
||||
//gFlagPlay = 1;
|
||||
//DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void rk28_send_wakeup_key( void )
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Wake up system\n");
|
||||
}
|
||||
|
||||
static int rk28_adckey_open(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk28_adckey_close(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
//
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rk28_adckey_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk28_adckey_resume(struct platform_device *pdev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
//struct input_dev *input_dev = adckey->input_dev;
|
||||
#if 0
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rk28_adckey_suspend NULL
|
||||
#define rk28_adckey_resume NULL
|
||||
#endif
|
||||
static void rk28_adkeyscan_timer(unsigned long data)
|
||||
{
|
||||
unsigned int adcvalue = -1, code;
|
||||
struct adc_key_data *rk2818_adckey_data = (struct adc_key_data *)data;
|
||||
|
||||
pRk28AdcKey->timer.expires = jiffies + msecs_to_jiffies(10);
|
||||
add_timer(&pRk28AdcKey->timer);
|
||||
|
||||
/*handle long press of play key*/
|
||||
if(gpio_get_value(rk2818_adckey_data->pin_playon) == rk2818_adckey_data->playon_level)
|
||||
{
|
||||
if(++gPlayCount > 20000)
|
||||
gPlayCount = 101;
|
||||
if((1 == gPlayCount) && (0 == gFlagShortPlay))
|
||||
{
|
||||
gFlagShortPlay = 1;
|
||||
}
|
||||
else if((100 == gPlayCount) && (0 == gFlagLongPlay))
|
||||
{
|
||||
gFlagLongPlay = 1;
|
||||
gFlagShortPlay = 0;
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (1 == gFlagShortPlay)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Wake up system,ENDCALL=%d\n",ENDCALL);
|
||||
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
}
|
||||
else if(1 == gFlagLongPlay)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
|
||||
}
|
||||
|
||||
gFlagShortPlay = 0;
|
||||
gFlagLongPlay = 0;
|
||||
gPlayCount = 0;
|
||||
}
|
||||
|
||||
/*handle long press of adc key*/
|
||||
if (gADSampleTimes < 4)
|
||||
{
|
||||
gADSampleTimes ++;
|
||||
return;
|
||||
}
|
||||
|
||||
gADSampleTimes = 0;
|
||||
|
||||
//rk28_read_adc(pRk28AdcKey);
|
||||
adcvalue = gAdcValue[rk2818_adckey_data->adc_chn];
|
||||
//printk("=========== adcvalue=0x%x ===========\n",adcvalue);
|
||||
|
||||
if((adcvalue > rk2818_adckey_data->adc_empty) || (adcvalue < rk2818_adckey_data->adc_invalid))
|
||||
{
|
||||
//DBG("adcvalue invalid !!!\n");
|
||||
if(gLastCode == 0) {
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gLastCode == KEYMENU)
|
||||
{
|
||||
if(gCodeCount > 31)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,ENDCALL,0\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
}
|
||||
input_report_key(pRk28AdcKey->input_dev,gLastCode,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,1\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
}
|
||||
|
||||
input_report_key(pRk28AdcKey->input_dev,gLastCode,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,0\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
gLastCode = 0;
|
||||
gCodeCount = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//DBG("adcvalue=0x%x\n",adcvalue);
|
||||
|
||||
code=rk28_get_keycode(adcvalue,rk2818_adckey_data->adc_key_table,rk2818_adckey_data);
|
||||
if(code)
|
||||
{
|
||||
if(code == KEYMENU)
|
||||
{
|
||||
gLastCode = code;
|
||||
if(++gCodeCount == 31)//40ms * 30 =1.2s
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,ENDCALL,1\n",__FUNCTION__,__LINE__,code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gLastCode = code;
|
||||
if(++gCodeCount == 2)//only one event once one touch
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,code,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,1\n",__FUNCTION__,__LINE__,code);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int __devinit rk28_adckey_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_adckey *adckey;
|
||||
struct input_dev *input_dev;
|
||||
int error,i,irq_num;
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (!(pdata->adc_key))
|
||||
return -1;
|
||||
|
||||
adckey = kzalloc(sizeof(struct rk28_adckey), GFP_KERNEL);
|
||||
if (adckey == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
//memcpy(adckey->keycodes, gInitKeyCode, sizeof(adckey->keycodes));
|
||||
adckey->keycodes = pdata->adc_key->initKeyCode;
|
||||
|
||||
/* Create and register the input driver. */
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(&pdev->dev, "failed to allocate input device\n");
|
||||
error = -ENOMEM;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
input_dev->name = pdata->name ? pdata->name : pdev->name;
|
||||
//input_dev->id.bustype = BUS_HOST;
|
||||
input_dev->open = rk28_adckey_open;
|
||||
input_dev->close = rk28_adckey_close;
|
||||
input_dev->dev.parent = &pdev->dev;
|
||||
input_dev->phys = KEY_PHYS_NAME;
|
||||
input_dev->id.vendor = 0x0001;
|
||||
input_dev->id.product = 0x0001;
|
||||
input_dev->id.version = 0x0100;
|
||||
|
||||
input_dev->keycode = adckey->keycodes;
|
||||
input_dev->keycodesize = sizeof(unsigned char);
|
||||
input_dev->keycodemax = pdata->adc_key->adc_key_cnt;
|
||||
for (i = 0; i < pdata->adc_key->adc_key_cnt; i++)
|
||||
set_bit(pdata->adc_key->initKeyCode[i], input_dev->keybit);
|
||||
clear_bit(0, input_dev->keybit);
|
||||
|
||||
adckey->input_dev = input_dev;
|
||||
input_set_drvdata(input_dev, adckey);
|
||||
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
|
||||
// rk28_adckey_build_keycode(adckey);
|
||||
platform_set_drvdata(pdev, adckey);
|
||||
|
||||
pRk28AdcKey = adckey;
|
||||
|
||||
/* Register the input device */
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register input device\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
error = gpio_request(pdata->adc_key->pin_playon, "play key gpio");
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to request play key gpio\n");
|
||||
goto free_gpio;
|
||||
}
|
||||
|
||||
irq_num = gpio_to_irq(pdata->adc_key->pin_playon);
|
||||
|
||||
if(pdata->adc_key->playon_level)
|
||||
{
|
||||
gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullDown);
|
||||
error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_RISING,NULL,NULL);
|
||||
if(error)
|
||||
{
|
||||
printk("unable to request play key irq\n");
|
||||
goto free_gpio_irq;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullUp);
|
||||
error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
|
||||
if(error)
|
||||
{
|
||||
printk("unable to request play key irq\n");
|
||||
goto free_gpio_irq;
|
||||
}
|
||||
}
|
||||
|
||||
enable_irq_wake(irq_num); // so play/wakeup key can wake up system
|
||||
|
||||
setup_timer(&adckey->timer, rk28_adkeyscan_timer, (unsigned long)(pdata->adc_key));
|
||||
adckey->timer.expires = jiffies+50;
|
||||
add_timer(&adckey->timer);
|
||||
printk(KERN_INFO "rk2818_adckey: driver initialized\n");
|
||||
return 0;
|
||||
|
||||
free_gpio_irq:
|
||||
free_irq(irq_num,NULL);
|
||||
free_gpio:
|
||||
gpio_free(pdata->adc_key->pin_playon);
|
||||
failed_free_dev:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
input_free_device(input_dev);
|
||||
failed_free:
|
||||
kfree(adckey);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit rk28_adckey_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
input_unregister_device(adckey->input_dev);
|
||||
input_free_device(adckey->input_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(adckey);
|
||||
free_irq(gpio_to_irq(pdata->adc_key->pin_playon), NULL);
|
||||
gpio_free(pdata->adc_key->pin_playon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk28_adckey_driver =
|
||||
{
|
||||
.probe = rk28_adckey_probe,
|
||||
.remove = __devexit_p(rk28_adckey_remove),
|
||||
.suspend = rk28_adckey_suspend,
|
||||
.resume = rk28_adckey_resume,
|
||||
.driver = {
|
||||
.name = "rk2818-adckey",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int __init rk28_adckey_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk28_adckey_driver);
|
||||
}
|
||||
|
||||
static void __exit rk28_adckey_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk28_adckey_driver);
|
||||
}
|
||||
|
||||
module_init(rk28_adckey_init);
|
||||
module_exit(rk28_adckey_exit);
|
||||
|
||||
MODULE_DESCRIPTION("rk2818 adc Key Controller Driver");
|
||||
MODULE_AUTHOR("luowei lw@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
@ -1,416 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/input/keyboard/rk28_adckey.c
|
||||
*
|
||||
* This driver program support to AD key which use for rk28 chip
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/adc.h>
|
||||
#include <mach/board.h>
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define KEY_PHYS_NAME "rk2818_adckey/input0"
|
||||
|
||||
volatile int gADSampleTimes = 0;
|
||||
volatile int gStatePlaykey = 0;
|
||||
volatile unsigned int gCodeCount = 0;
|
||||
volatile unsigned int gThisCode = 0;
|
||||
volatile unsigned int gLastCode = 0;
|
||||
volatile unsigned int gFlagShortPlay = 0;
|
||||
volatile unsigned int gFlagLongPlay = 0;
|
||||
volatile unsigned int gPlayCount = 0;
|
||||
|
||||
//key code tab
|
||||
struct rk28_adckey
|
||||
{
|
||||
struct semaphore lock;
|
||||
struct rk28_adc_client *client;
|
||||
struct input_dev *input_dev;
|
||||
struct timer_list timer;
|
||||
unsigned char * keycodes;
|
||||
void __iomem *mmio_base;
|
||||
};
|
||||
|
||||
struct rk28_adckey *pRk28AdcKey;
|
||||
|
||||
unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
|
||||
{
|
||||
if(advalue >= 0 && advalue <= 5)
|
||||
return ptab->adc_keycode;
|
||||
|
||||
while(ptab->adc_keycode != 0)
|
||||
{
|
||||
|
||||
if((advalue > ptab->adc_value - rk2818_adckey_data->adc_drift) && (advalue < ptab->adc_value + rk2818_adckey_data->adc_drift))
|
||||
{
|
||||
DBG("ptab->adc_keycode is :%d\n",ptab->adc_keycode);
|
||||
return ptab->adc_keycode;
|
||||
}
|
||||
ptab++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rk28_playkey_irq(int irq, void *handle)
|
||||
{
|
||||
|
||||
//gFlagPlay = 1;
|
||||
//DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void rk28_send_wakeup_key( void )
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Wake up system\n");
|
||||
}
|
||||
|
||||
static int rk28_adckey_open(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk28_adckey_close(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
//
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rk28_adckey_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk28_adckey_resume(struct platform_device *pdev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
//struct input_dev *input_dev = adckey->input_dev;
|
||||
#if 0
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rk28_adckey_suspend NULL
|
||||
#define rk28_adckey_resume NULL
|
||||
#endif
|
||||
static void rk28_adkeyscan_timer(unsigned long data)
|
||||
{
|
||||
unsigned int adcvalue = -1, code;
|
||||
struct adc_key_data *rk2818_adckey_data = (struct adc_key_data *)data;
|
||||
|
||||
pRk28AdcKey->timer.expires = jiffies + msecs_to_jiffies(10);
|
||||
add_timer(&pRk28AdcKey->timer);
|
||||
|
||||
/*handle long press of play key*/
|
||||
if(gpio_get_value(rk2818_adckey_data->pin_playon) == rk2818_adckey_data->playon_level)
|
||||
{
|
||||
if(++gPlayCount > 20000)
|
||||
gPlayCount = 101;
|
||||
if((2 == gPlayCount) && (0 == gFlagShortPlay))
|
||||
{
|
||||
gFlagShortPlay = 1;
|
||||
}
|
||||
else if((100 == gPlayCount) && (0 == gFlagLongPlay))
|
||||
{
|
||||
gFlagLongPlay = 1;
|
||||
gFlagShortPlay = 0;
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (1 == gFlagShortPlay)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Wake up system,ENDCALL=%d\n",ENDCALL);
|
||||
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS);
|
||||
}
|
||||
else if(1 == gFlagLongPlay)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_LONG_PRESS,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,KEY_PLAY_LONG_PRESS=%d,0\n",__FUNCTION__,__LINE__,KEY_PLAY_LONG_PRESS);
|
||||
}
|
||||
|
||||
gFlagShortPlay = 0;
|
||||
gFlagLongPlay = 0;
|
||||
gPlayCount = 0;
|
||||
}
|
||||
|
||||
/*handle long press of adc key*/
|
||||
if (gADSampleTimes < 4)
|
||||
{
|
||||
gADSampleTimes ++;
|
||||
return;
|
||||
}
|
||||
|
||||
gADSampleTimes = 0;
|
||||
|
||||
//rk28_read_adc(pRk28AdcKey);
|
||||
adcvalue = gAdcValue[rk2818_adckey_data->adc_chn];
|
||||
//printk("=========== adcvalue=0x%x ===========\n",adcvalue);
|
||||
|
||||
if(adcvalue > rk2818_adckey_data->adc_empty)
|
||||
{
|
||||
//DBG("adcvalue invalid !!!\n");
|
||||
if(gLastCode == 0) {
|
||||
//DBG("(gLastCode == 0\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gLastCode == KEYMENU)
|
||||
{
|
||||
if(gCodeCount > 31)
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,ENDCALL,0\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
}
|
||||
input_report_key(pRk28AdcKey->input_dev,gLastCode,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,1\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
}
|
||||
|
||||
input_report_key(pRk28AdcKey->input_dev,gLastCode,0);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter::%s,LINE=%d,code=%d,0\n",__FUNCTION__,__LINE__,gLastCode);
|
||||
gLastCode = 0;
|
||||
gCodeCount = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("adcvalue=0x%x\n",adcvalue);
|
||||
|
||||
code=rk28_get_keycode(adcvalue,rk2818_adckey_data->adc_key_table,rk2818_adckey_data);
|
||||
if(code)
|
||||
{
|
||||
if(code == KEYMENU)
|
||||
{
|
||||
gLastCode = code;
|
||||
if(++gCodeCount == 31)//40ms * 30 =1.2s
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,ENDCALL,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter menu::%s,LINE=%d,code=%d,ENDCALL,1\n",__FUNCTION__,__LINE__,code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("Enter key ::%s,LINE=%d,gCodeCount=%d,1\n",__FUNCTION__,__LINE__,gCodeCount);
|
||||
gLastCode = code;
|
||||
if(++gCodeCount == 2)//only one event once one touch
|
||||
{
|
||||
input_report_key(pRk28AdcKey->input_dev,code,1);
|
||||
input_sync(pRk28AdcKey->input_dev);
|
||||
DBG("Enter key ::%s,LINE=%d,code=%d,1\n",__FUNCTION__,__LINE__,code);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int __devinit rk28_adckey_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_adckey *adckey;
|
||||
struct input_dev *input_dev;
|
||||
int error,i,irq_num;
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (!(pdata->adc_key))
|
||||
return -1;
|
||||
|
||||
adckey = kzalloc(sizeof(struct rk28_adckey), GFP_KERNEL);
|
||||
if (adckey == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
//memcpy(adckey->keycodes, gInitKeyCode, sizeof(adckey->keycodes));
|
||||
adckey->keycodes = pdata->adc_key->initKeyCode;
|
||||
|
||||
/* Create and register the input driver. */
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(&pdev->dev, "failed to allocate input device\n");
|
||||
error = -ENOMEM;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
input_dev->name = pdev->name;
|
||||
//input_dev->id.bustype = BUS_HOST;
|
||||
input_dev->open = rk28_adckey_open;
|
||||
input_dev->close = rk28_adckey_close;
|
||||
input_dev->dev.parent = &pdev->dev;
|
||||
input_dev->phys = KEY_PHYS_NAME;
|
||||
input_dev->id.vendor = 0x0001;
|
||||
input_dev->id.product = 0x0001;
|
||||
input_dev->id.version = 0x0100;
|
||||
|
||||
input_dev->keycode = adckey->keycodes;
|
||||
input_dev->keycodesize = sizeof(unsigned char);
|
||||
input_dev->keycodemax = pdata->adc_key->adc_key_cnt;
|
||||
for (i = 0; i < pdata->adc_key->adc_key_cnt; i++)
|
||||
set_bit(pdata->adc_key->initKeyCode[i], input_dev->keybit);
|
||||
clear_bit(0, input_dev->keybit);
|
||||
|
||||
adckey->input_dev = input_dev;
|
||||
input_set_drvdata(input_dev, adckey);
|
||||
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
|
||||
// rk28_adckey_build_keycode(adckey);
|
||||
platform_set_drvdata(pdev, adckey);
|
||||
|
||||
pRk28AdcKey = adckey;
|
||||
|
||||
/* Register the input device */
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register input device\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
error = gpio_request(pdata->adc_key->pin_playon, "play key gpio");
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to request play key gpio\n");
|
||||
goto free_gpio;
|
||||
}
|
||||
|
||||
irq_num = gpio_to_irq(pdata->adc_key->pin_playon);
|
||||
|
||||
if(pdata->adc_key->playon_level)
|
||||
{
|
||||
gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullDown);
|
||||
error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_RISING,NULL,NULL);
|
||||
if(error)
|
||||
{
|
||||
printk("unable to request play key irq\n");
|
||||
goto free_gpio_irq;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_pull_updown(pdata->adc_key->pin_playon,GPIOPullUp);
|
||||
error = request_irq(irq_num,rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
|
||||
if(error)
|
||||
{
|
||||
printk("unable to request play key irq\n");
|
||||
goto free_gpio_irq;
|
||||
}
|
||||
}
|
||||
|
||||
enable_irq_wake(irq_num); // so play/wakeup key can wake up system
|
||||
|
||||
setup_timer(&adckey->timer, rk28_adkeyscan_timer, (unsigned long)(pdata->adc_key));
|
||||
adckey->timer.expires = jiffies+50;
|
||||
add_timer(&adckey->timer);
|
||||
printk(KERN_INFO "rk2818_adckey: driver initialized\n");
|
||||
return 0;
|
||||
|
||||
free_gpio_irq:
|
||||
free_irq(irq_num,NULL);
|
||||
free_gpio:
|
||||
gpio_free(pdata->adc_key->pin_playon);
|
||||
failed_free_dev:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
input_free_device(input_dev);
|
||||
failed_free:
|
||||
kfree(adckey);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit rk28_adckey_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
input_unregister_device(adckey->input_dev);
|
||||
input_free_device(adckey->input_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(adckey);
|
||||
free_irq(gpio_to_irq(pdata->adc_key->pin_playon), NULL);
|
||||
gpio_free(pdata->adc_key->pin_playon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk28_adckey_driver =
|
||||
{
|
||||
.probe = rk28_adckey_probe,
|
||||
.remove = __devexit_p(rk28_adckey_remove),
|
||||
.suspend = rk28_adckey_suspend,
|
||||
.resume = rk28_adckey_resume,
|
||||
.driver = {
|
||||
.name = "rk2818-adckey",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int __init rk28_adckey_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk28_adckey_driver);
|
||||
}
|
||||
|
||||
static void __exit rk28_adckey_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk28_adckey_driver);
|
||||
}
|
||||
|
||||
module_init(rk28_adckey_init);
|
||||
module_exit(rk28_adckey_exit);
|
||||
|
||||
MODULE_DESCRIPTION("rk2818 adc Key Controller Driver");
|
||||
MODULE_AUTHOR("luowei lw@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
@ -1,284 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/input/keyboard/rk28_adckey.c
|
||||
*
|
||||
* This driver program support to AD key which use for rk28 chip
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/adc.h>
|
||||
#include <mach/board.h>
|
||||
|
||||
#if 1
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
//#define KEY_PHYS_NAME "rk2818_adckey/input0"
|
||||
|
||||
static unsigned int gLastKeyCode = 0;
|
||||
static int gSampleTimes = 0;
|
||||
static int gADValue = 0;
|
||||
static struct rk28_hskey *phsKey;
|
||||
|
||||
//key code tab
|
||||
struct rk28_hskey
|
||||
{
|
||||
struct input_dev *input_dev;
|
||||
struct timer_list timer;
|
||||
unsigned char * keycodes;
|
||||
};
|
||||
|
||||
extern int headset_status(void);
|
||||
extern unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data);
|
||||
|
||||
#if 0
|
||||
unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab,struct adc_key_data *rk2818_adckey_data)
|
||||
{
|
||||
while(ptab->adc_keycode != 0)
|
||||
{
|
||||
if((ptab->adc_value == 0)&&(advalue >= 0 && advalue <= 5))
|
||||
return ptab->adc_keycode;
|
||||
if((advalue > ptab->adc_value - rk2818_adckey_data->adc_drift) && (advalue < ptab->adc_value + rk2818_adckey_data->adc_drift))
|
||||
return ptab->adc_keycode;
|
||||
ptab++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rk28_send_wakeup_key( void )
|
||||
{
|
||||
input_report_key(phsKey->input_dev,KEY_WAKEUP,1);
|
||||
input_sync(phsKey->input_dev);
|
||||
input_report_key(phsKey->input_dev,KEY_WAKEUP,0);
|
||||
input_sync(phsKey->input_dev);
|
||||
DBG("Wake up system\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rk28_Hskey_open(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
DBG("===========rk28_Hskey_open===========\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk28_Hskey_close(struct input_dev *dev)
|
||||
{
|
||||
DBG("===========rk28_Hskey_close===========\n");
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
//
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rk28_hskey_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk28_hskey_resume(struct platform_device *pdev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = platform_get_drvdata(pdev);
|
||||
//struct input_dev *input_dev = adckey->input_dev;
|
||||
#if 0
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
mutex_unlock(&input_dev->mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rk28_hskey_suspend NULL
|
||||
#define rk28_hskey_resume NULL
|
||||
#endif
|
||||
static void rk28_hskeyscan_timer(unsigned long data)
|
||||
{
|
||||
unsigned int adcvalue = 0x3FF,code = 0;
|
||||
struct adc_key_data *rk2818_adckey_data = (struct adc_key_data *)data;
|
||||
|
||||
phsKey->timer.expires = jiffies + msecs_to_jiffies(10);
|
||||
add_timer(&phsKey->timer);
|
||||
|
||||
if(headset_status())
|
||||
{
|
||||
if(gSampleTimes<4)
|
||||
{
|
||||
gADValue += gAdcValue[rk2818_adckey_data->adc_chn];
|
||||
gSampleTimes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gADValue = gADValue/4;
|
||||
code=rk28_get_keycode(gADValue,rk2818_adckey_data->adc_key_table,rk2818_adckey_data);
|
||||
gADValue = 0;
|
||||
gSampleTimes = 0;
|
||||
|
||||
if(code && !gLastKeyCode)
|
||||
{
|
||||
gLastKeyCode = code;
|
||||
input_report_key(phsKey->input_dev,gLastKeyCode,1);
|
||||
input_sync(phsKey->input_dev);
|
||||
DBG("===========headset key press code=%d ===========\n",code);
|
||||
}
|
||||
else if(!code && gLastKeyCode)
|
||||
{
|
||||
input_report_key(phsKey->input_dev,gLastKeyCode,0);
|
||||
input_sync(phsKey->input_dev);
|
||||
gLastKeyCode = 0;
|
||||
DBG("===========headset key release code=%d ===========\n",code);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gLastKeyCode)
|
||||
{
|
||||
input_report_key(phsKey->input_dev,code,0);
|
||||
input_sync(phsKey->input_dev);
|
||||
gLastKeyCode = 0;
|
||||
DBG("===========headset key release code=%d ===========\n",code);
|
||||
}
|
||||
gADValue = 0;
|
||||
gSampleTimes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit rk28_adckey_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_hskey *hskey;
|
||||
struct input_dev *input_dev;
|
||||
int error,i,irq_num;
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (!(pdata->adc_key))
|
||||
return -1;
|
||||
|
||||
hskey = kzalloc(sizeof(struct rk28_hskey), GFP_KERNEL);
|
||||
if (hskey == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hskey->keycodes = pdata->adc_key->initKeyCode;
|
||||
|
||||
/* Create and register the input driver. */
|
||||
input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
dev_err(&pdev->dev, "failed to allocate input device\n");
|
||||
error = -ENOMEM;
|
||||
goto failed_free;
|
||||
}
|
||||
|
||||
input_dev->name = pdev->name;
|
||||
input_dev->open = rk28_Hskey_open;
|
||||
input_dev->close = rk28_Hskey_close;
|
||||
input_dev->dev.parent = &pdev->dev;
|
||||
//input_dev->phys = KEY_PHYS_NAME;
|
||||
input_dev->id.vendor = 0x0001;
|
||||
input_dev->id.product = 0x0001;
|
||||
input_dev->id.version = 0x0100;
|
||||
|
||||
input_dev->keycode = hskey->keycodes;
|
||||
input_dev->keycodesize = sizeof(unsigned char);
|
||||
input_dev->keycodemax = pdata->adc_key->adc_key_cnt;
|
||||
for (i = 0; i < pdata->adc_key->adc_key_cnt; i++)
|
||||
set_bit(pdata->adc_key->initKeyCode[i], input_dev->keybit);
|
||||
clear_bit(0, input_dev->keybit);
|
||||
|
||||
hskey->input_dev = input_dev;
|
||||
input_set_drvdata(input_dev, hskey);
|
||||
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
|
||||
platform_set_drvdata(pdev, hskey);
|
||||
|
||||
phsKey = hskey;
|
||||
|
||||
/* Register the input device */
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register input device\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
setup_timer(&hskey->timer, rk28_hskeyscan_timer, (unsigned long)(pdata->adc_key));
|
||||
hskey->timer.expires = jiffies+50;
|
||||
add_timer(&hskey->timer);
|
||||
printk(KERN_INFO "rk2818_hskey: driver initialized\n");
|
||||
return 0;
|
||||
|
||||
free_gpio_irq:
|
||||
free_irq(irq_num,NULL);
|
||||
free_gpio:
|
||||
gpio_free(pdata->adc_key->pin_playon);
|
||||
failed_free_dev:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
input_free_device(input_dev);
|
||||
failed_free:
|
||||
kfree(hskey);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit rk28_adckey_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk28_hskey *adckey = platform_get_drvdata(pdev);
|
||||
struct rk2818_adckey_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
input_unregister_device(adckey->input_dev);
|
||||
input_free_device(adckey->input_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(adckey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk28_hskey_driver =
|
||||
{
|
||||
.probe = rk28_adckey_probe,
|
||||
.remove = __devexit_p(rk28_adckey_remove),
|
||||
.suspend = rk28_hskey_suspend,
|
||||
.resume = rk28_hskey_resume,
|
||||
.driver = {
|
||||
.name = "rk2818-hskey",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int __init rk28_hskey_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk28_hskey_driver);
|
||||
}
|
||||
|
||||
static void __exit rk28_hskey_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk28_hskey_driver);
|
||||
}
|
||||
|
||||
module_init(rk28_hskey_init);
|
||||
module_exit(rk28_hskey_exit);
|
||||
|
||||
MODULE_DESCRIPTION("rk2818 headset Key Controller Driver");
|
||||
MODULE_AUTHOR("luowei lw@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1069,14 +1069,6 @@ config VIDEO_OMAP2
|
|||
---help---
|
||||
This is a v4l2 driver for the TI OMAP2 camera capture interface
|
||||
|
||||
|
||||
config VIDEO_RK2818
|
||||
tristate "RK2818 Camera Sensor Interface driver"
|
||||
depends on VIDEO_DEV && ARCH_RK2818 && SOC_CAMERA && HAS_DMA
|
||||
select VIDEOBUF_DMA_CONTIG
|
||||
---help---
|
||||
This is a v4l2 driver for the RK2818 Camera Sensor Interface
|
||||
|
||||
config VIDEO_RK29
|
||||
tristate "RK29XX Camera Sensor Interface driver"
|
||||
depends on VIDEO_DEV && ARCH_RK29 && SOC_CAMERA && HAS_DMA
|
||||
|
|
|
|||
|
|
@ -176,7 +176,6 @@ obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
|
|||
obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
|
||||
obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
|
||||
obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
|
||||
obj-$(CONFIG_VIDEO_RK2818) += rk2818_camera.o
|
||||
obj-$(CONFIG_VIDEO_RK29_WORK_ONEFRAME) += rk29_camera_oneframe.o
|
||||
obj-$(CONFIG_VIDEO_RK29_WORK_PINGPONG) += rk29_camera_pingpong.o
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,29 +4,6 @@
|
|||
|
||||
comment "MMC/SD/SDIO Host Controller Drivers"
|
||||
|
||||
config SDMMC_RK2818
|
||||
tristate "RK2818 SDMMC controller suppport"
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This selects the RK2818 SDMMC controller.
|
||||
SDMMC0 used for sd/mmc card, and SDMMC1 used for sdio.
|
||||
if SDMMC_RK2818
|
||||
comment "Now, there are two SDMMC controllers selected, SDMMC0 and SDMMC1."
|
||||
config SDMMC0_RK2818
|
||||
tristate "RK2818 SDMMC0 controller support(sdmmc)"
|
||||
default y
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This supports the use of the SDMMC0 controller on rk2818 processors.
|
||||
|
||||
config SDMMC1_RK2818
|
||||
tristate "RK2818 SDMMC1 controller support(sdio)"
|
||||
default y
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This supports the use of the SDMMC1 controller on rk2818 processors.
|
||||
endif
|
||||
|
||||
config SDMMC_RK29
|
||||
tristate "RK29 SDMMC controller suppport"
|
||||
depends on ARCH_RK29
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ else
|
|||
obj-$(CONFIG_SDMMC_RK29) += rk29_sdmmc.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SDMMC_RK2818) += rk2818-sdmmc.o
|
||||
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
|
||||
obj-$(CONFIG_MMC_PXA) += pxamci.o
|
||||
obj-$(CONFIG_MMC_IMX) += imxmmc.o
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -360,11 +360,6 @@ config MTD_NAND_ATMEL_ECC_NONE
|
|||
|
||||
endchoice
|
||||
|
||||
config MTD_NAND_RK2818
|
||||
tristate "NAND Flash support for RK2818"
|
||||
depends on ARCH_RK2818
|
||||
help
|
||||
This enables the NAND flash controller on the RK2818 SoC
|
||||
config MTD_NAND_RK29
|
||||
tristate "NAND Flash support for RK29sdk"
|
||||
depends on ARCH_RK29
|
||||
|
|
|
|||
|
|
@ -42,6 +42,5 @@ obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
|
|||
obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
|
||||
obj-$(CONFIG_MTD_NAND_W90P910) += w90p910_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_RK2818) += rk2818_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_RK29) += rk29_nand.o
|
||||
nand-objs := nand_base.o nand_bbt.o
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -38,7 +38,6 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include "dm9000.h"
|
||||
|
||||
|
|
@ -105,12 +104,6 @@ typedef struct board_info {
|
|||
int debug_level;
|
||||
|
||||
enum dm9000_type type;
|
||||
|
||||
#ifdef CONFIG_DM9000_USE_NAND_CONTROL
|
||||
void *dev_id;
|
||||
struct work_struct dm9k_work;
|
||||
struct workqueue_struct *dm9000_wq;
|
||||
#endif
|
||||
|
||||
void (*inblk)(void __iomem *port, void *data, int length);
|
||||
void (*outblk)(void __iomem *port, void *data, int length);
|
||||
|
|
@ -147,16 +140,6 @@ typedef struct board_info {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(CONFIG_DM9000_USE_NAND_CONTROL) && defined(CONFIG_MTD_NAND_RK2818)
|
||||
extern void rk2818_nand_status_mutex_lock(void);
|
||||
extern int rk2818_nand_status_mutex_trylock(void);
|
||||
extern void rk2818_nand_status_mutex_unlock(void);
|
||||
#else
|
||||
static void rk2818_nand_status_mutex_lock(void){return;}
|
||||
static int rk2818_nand_status_mutex_trylock(void) {return 1;}
|
||||
static void rk2818_nand_status_mutex_unlock(void) {return;}
|
||||
#endif
|
||||
|
||||
static inline board_info_t *to_dm9000_board(struct net_device *dev)
|
||||
{
|
||||
return netdev_priv(dev);
|
||||
|
|
@ -323,15 +306,11 @@ dm9000_read_locked(board_info_t *db, int reg)
|
|||
{
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
ret = ior(db, reg);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -384,8 +363,6 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
|
|||
|
||||
mutex_lock(&db->addr_lock);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
iow(db, DM9000_EPAR, offset);
|
||||
|
|
@ -393,15 +370,11 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
|
|||
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
dm9000_wait_eeprom(db);
|
||||
|
||||
/* delay for at-least 150uS */
|
||||
msleep(1);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
iow(db, DM9000_EPCR, 0x0);
|
||||
|
|
@ -411,8 +384,6 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
|
|||
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
mutex_unlock(&db->addr_lock);
|
||||
}
|
||||
|
||||
|
|
@ -429,8 +400,6 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
|
|||
|
||||
mutex_lock(&db->addr_lock);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
iow(db, DM9000_EPAR, offset);
|
||||
iow(db, DM9000_EPDRH, data[1]);
|
||||
|
|
@ -438,20 +407,14 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
|
|||
iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
dm9000_wait_eeprom(db);
|
||||
|
||||
mdelay(1); /* wait at least 150uS to clear */
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
iow(db, DM9000_EPCR, 0);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
mutex_unlock(&db->addr_lock);
|
||||
}
|
||||
|
||||
|
|
@ -514,13 +477,7 @@ static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)
|
|||
|
||||
if (dm->can_csum) {
|
||||
dm->rx_csum = data;
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&dm->lock, flags);
|
||||
iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);
|
||||
spin_unlock_irqrestore(&dm->lock, flags);
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -731,8 +688,6 @@ dm9000_hash_table_unlocked(struct net_device *dev)
|
|||
|
||||
dm9000_dbg(db, 1, "entering %s\n", __func__);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
|
||||
iow(db, oft, dev->dev_addr[i]);
|
||||
|
||||
|
|
@ -773,8 +728,6 @@ dm9000_hash_table(struct net_device *dev)
|
|||
spin_lock_irqsave(&db->lock, flags);
|
||||
dm9000_hash_table_unlocked(dev);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -838,9 +791,6 @@ static void dm9000_timeout(struct net_device *dev)
|
|||
|
||||
/* Save previous register address */
|
||||
reg_save = readb(db->io_addr);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
|
@ -853,8 +803,6 @@ static void dm9000_timeout(struct net_device *dev)
|
|||
/* Restore previous register address */
|
||||
writeb(reg_save, db->io_addr);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
}
|
||||
|
||||
static void dm9000_send_packet(struct net_device *dev,
|
||||
|
|
@ -892,15 +840,9 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
dm9000_dbg(db, 3, "%s:\n", __func__);
|
||||
|
||||
if (db->tx_pkt_cnt > 1) {
|
||||
dev_dbg(db->dev, "netdev tx busy\n");
|
||||
if (db->tx_pkt_cnt > 1)
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
if (!rk2818_nand_status_mutex_trylock()) {
|
||||
dev_dbg(db->dev, "fun:%s, nand busy\n", __func__);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
/* Move data to DM9000 TX RAM */
|
||||
|
|
@ -922,8 +864,6 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
/* free this SKB */
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
|
|
@ -992,17 +932,15 @@ dm9000_rx(struct net_device *dev)
|
|||
dev_warn(db->dev, "status check fail: %d\n", rxbyte);
|
||||
#if 0
|
||||
iow(db, DM9000_RCR, 0x00); /* Stop Device */
|
||||
iow(db, DM9000_IMR, IMR_PAR); /* Stop INT request */
|
||||
iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */
|
||||
#else
|
||||
dm9000_reset(db);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(rxbyte & DM9000_PKT_RDY)) {
|
||||
//printk("packet not ready to receive\n");
|
||||
if (!(rxbyte & DM9000_PKT_RDY))
|
||||
return;
|
||||
}
|
||||
|
||||
/* A packet ready now & Get status/length */
|
||||
GoodPacket = true;
|
||||
|
|
@ -1079,81 +1017,6 @@ dm9000_rx(struct net_device *dev)
|
|||
} while (rxbyte & DM9000_PKT_RDY);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM9000_USE_NAND_CONTROL
|
||||
static void dm9000_interrupt_work(struct work_struct *work)
|
||||
{
|
||||
board_info_t *db = container_of(work, board_info_t, dm9k_work);
|
||||
struct net_device *dev = db->dev_id;
|
||||
int int_status;
|
||||
unsigned long flags;
|
||||
u8 reg_save;
|
||||
|
||||
//printk("entering %s\n", __FUNCTION__);
|
||||
|
||||
/* A real interrupt coming */
|
||||
|
||||
/* holders of db->lock must always block IRQs */
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock, flags);
|
||||
|
||||
/* Save previous register address */
|
||||
reg_save = readb(db->io_addr);
|
||||
|
||||
/* Disable all interrupts */
|
||||
iow(db, DM9000_IMR, IMR_PAR);
|
||||
|
||||
/* Got DM9000 interrupt status */
|
||||
int_status = ior(db, DM9000_ISR); /* Got ISR */
|
||||
iow(db, DM9000_ISR, int_status); /* Clear ISR status */
|
||||
|
||||
if (netif_msg_intr(db))
|
||||
dev_dbg(db->dev, "interrupt status %02x\n", int_status);
|
||||
|
||||
/* Received the coming packet */
|
||||
if (int_status & ISR_PRS)
|
||||
dm9000_rx(dev);
|
||||
|
||||
/* Trnasmit Interrupt check */
|
||||
if (int_status & ISR_PTS)
|
||||
dm9000_tx_done(dev, db);
|
||||
|
||||
if (db->type != TYPE_DM9000E) {
|
||||
if (int_status & ISR_LNKCHNG) {
|
||||
/* fire a link-change request */
|
||||
schedule_delayed_work(&db->phy_poll, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable interrupt mask */
|
||||
iow(db, DM9000_IMR, db->imr_all);
|
||||
|
||||
/* Restore previous register address */
|
||||
writeb(reg_save, db->io_addr);
|
||||
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
enable_irq(dev->irq);
|
||||
|
||||
}
|
||||
|
||||
static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = dev_id;
|
||||
board_info_t *db = netdev_priv(dev);
|
||||
|
||||
//printk("enter : %s\n", __FUNCTION__);
|
||||
|
||||
db->dev_id = dev_id;
|
||||
disable_irq_nosync(irq);
|
||||
queue_work(db->dm9000_wq, &(db->dm9k_work));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#else
|
||||
static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = dev_id;
|
||||
|
|
@ -1207,7 +1070,6 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
|
|||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
/*
|
||||
|
|
@ -1231,11 +1093,6 @@ dm9000_open(struct net_device *dev)
|
|||
board_info_t *db = netdev_priv(dev);
|
||||
unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
#ifdef CONFIG_DM9000_USE_NAND_CONTROL
|
||||
db->dm9000_wq = create_workqueue("dm9000 wq");
|
||||
INIT_WORK(&(db->dm9k_work), dm9000_interrupt_work);
|
||||
#endif
|
||||
|
||||
if (netif_msg_ifup(db))
|
||||
dev_dbg(db->dev, "enabling %s\n", dev->name);
|
||||
|
||||
|
|
@ -1290,8 +1147,6 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
|
|||
|
||||
mutex_lock(&db->addr_lock);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock,flags);
|
||||
|
||||
/* Save previous register address */
|
||||
|
|
@ -1304,15 +1159,10 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
|
|||
|
||||
writeb(reg_save, db->io_addr);
|
||||
spin_unlock_irqrestore(&db->lock,flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
dm9000_msleep(db, 1); /* Wait read complete */
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock,flags);
|
||||
|
||||
reg_save = readb(db->io_addr);
|
||||
|
||||
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
|
||||
|
|
@ -1323,8 +1173,6 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
|
|||
/* restore the previous address */
|
||||
writeb(reg_save, db->io_addr);
|
||||
spin_unlock_irqrestore(&db->lock,flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
mutex_unlock(&db->addr_lock);
|
||||
|
||||
|
|
@ -1346,8 +1194,6 @@ dm9000_phy_write(struct net_device *dev,
|
|||
dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
|
||||
mutex_lock(&db->addr_lock);
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock,flags);
|
||||
|
||||
/* Save previous register address */
|
||||
|
|
@ -1364,15 +1210,10 @@ dm9000_phy_write(struct net_device *dev,
|
|||
|
||||
writeb(reg_save, db->io_addr);
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
|
||||
dm9000_msleep(db, 1); /* Wait write complete */
|
||||
|
||||
rk2818_nand_status_mutex_lock();
|
||||
|
||||
spin_lock_irqsave(&db->lock,flags);
|
||||
|
||||
spin_lock_irqsave(&db->lock,flags);
|
||||
reg_save = readb(db->io_addr);
|
||||
|
||||
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
|
||||
|
|
@ -1381,8 +1222,6 @@ dm9000_phy_write(struct net_device *dev,
|
|||
writeb(reg_save, db->io_addr);
|
||||
|
||||
spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
rk2818_nand_status_mutex_unlock();
|
||||
mutex_unlock(&db->addr_lock);
|
||||
}
|
||||
|
||||
|
|
@ -1420,10 +1259,6 @@ dm9000_stop(struct net_device *ndev)
|
|||
|
||||
dm9000_shutdown(ndev);
|
||||
|
||||
#ifdef CONFIG_DM9000_USE_NAND_CONTROL
|
||||
destroy_workqueue(db->dm9000_wq);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ config BATTERY_BQ3060
|
|||
depends on I2C && ARCH_RK29
|
||||
help
|
||||
Say Y here to enable support for batteries with BQ3060(I2C) chip.
|
||||
|
||||
config CHECK_BATT_CAPACITY
|
||||
tristate "check the capacity in BQ27510 battery if 1000mah write capacity for BATT_CAPACITY_MAH"
|
||||
depends on BATTERY_BQ27510 || BATTERY_BQ3060
|
||||
|
|
@ -157,17 +158,12 @@ config BATT_CAPACITY_MAH
|
|||
depends on CHECK_BATT_CAPACITY
|
||||
int "battery capacity (in mah)"
|
||||
default 2200
|
||||
|
||||
|
||||
config NO_BATTERY_IC
|
||||
tristate "no BQ27510 battery ic in board"
|
||||
depends on BATTERY_BQ27510 || BATTERY_BQ3060
|
||||
default n
|
||||
help
|
||||
Say no BQ27510(I2C) chip in board .
|
||||
|
||||
config BATTERY_RK2818
|
||||
tristate "RK2818 battery"
|
||||
depends on RK28_ADC
|
||||
help
|
||||
Say Y to enable support for the battery on the RK2818.
|
||||
|
||||
endif # POWER_SUPPLY
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
|
|||
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
|
||||
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
|
||||
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
|
||||
obj-$(CONFIG_BATTERY_RK2818) += rk2818_battery.o
|
||||
obj-$(CONFIG_BATTERY_STC3100) += stc3100_battery.o
|
||||
obj-$(CONFIG_BATTERY_BQ27510) += bq27510_battery.o
|
||||
obj-$(CONFIG_BATTERY_BQ3060) += bq3060_battery.o
|
||||
obj-$(CONFIG_BATTERY_BQ3060) += bq3060_battery.o
|
||||
|
|
|
|||
|
|
@ -1,737 +0,0 @@
|
|||
/* drivers/power/rk2818_battery.c
|
||||
*
|
||||
* battery detect driver for the rk2818
|
||||
*
|
||||
* 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/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/adc.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/board.h>
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
/*******************以下参数可以修改******************************/
|
||||
#define TIMER_MS_COUNTS 50 //定时器的长度ms
|
||||
#define SLOPE_SECOND_COUNTS 120 //统计电压斜率的时间间隔s
|
||||
#define TIME_UPDATE_STATUS 5000 //更新电池状态的时间间隔ms
|
||||
#define BATT_MAX_VOL_VALUE 4180 //满电时的电池电压 FOR A7
|
||||
#define BATT_ZERO_VOL_VALUE 3500 //关机时的电池电压
|
||||
#define BATT_NOMAL_VOL_VALUE 3800
|
||||
#define THRESHOLD_VOLTAGE_LEVEL0 4050
|
||||
#define THRESHOLD_VOLTAGE_LEVEL1 3950
|
||||
#define THRESHOLD_VOLTAGE_LEVEL2 3850
|
||||
#define THRESHOLD_VOLTAGE_LEVEL3 BATT_ZERO_VOL_VALUE
|
||||
#define THRESHOLD_SLOPE_HIGH 10 //斜率值 = 电压降低的速度
|
||||
#define THRESHOLD_SLOPE_MID 5 //< THRESHOLD_SLOPE_HIGH
|
||||
#define THRESHOLD_SLOPE_LOW 0 //< THRESHOLD_SLOPE_MID
|
||||
|
||||
/*************************************************************/
|
||||
#define CHN_BAT_ADC 0
|
||||
#define CHN_USB_ADC 2
|
||||
#define BATT_LEVEL_EMPTY 0
|
||||
#define BATT_PRESENT_TRUE 1
|
||||
#define BATT_PRESENT_FALSE 0
|
||||
#define BAT_1V2_VALUE 1270
|
||||
|
||||
#define BAT_LOADER_STATUS 0 //用电状态
|
||||
#define BAT_CHANGE_STATUS 1 //波动状态
|
||||
#define BAT_CHARGE_STATUS 2 //充电状态
|
||||
#define BAT_RELEASE_STATUS 3 //电池耗尽状态
|
||||
|
||||
#define SLOPE_HIGH_LEVEL 0 //电压变化斜率等级
|
||||
#define SLOPE_MID_LEVEL 1
|
||||
#define SLOPE_LOW_LEVEL 2
|
||||
|
||||
#define VOLTAGE_HIGH_LEVEL 0 //电压高低等级
|
||||
#define VOLTAGE_MID_LEVEL 1
|
||||
#define VOLTAGE_LOW_LEVEL 2
|
||||
#define VOLTAGE_RELEASE_LEVEL 3
|
||||
|
||||
#define NUM_VOLTAGE_SAMPLE ((1000*SLOPE_SECOND_COUNTS) / TIMER_MS_COUNTS) //存储的采样点个数
|
||||
|
||||
static int gBatFullFlag = 0;
|
||||
|
||||
static int gBatLastStatus = 0;
|
||||
static int gBatStatus = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
static int gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
|
||||
static int gBatLastPresent = 0;
|
||||
static int gBatPresent = BATT_PRESENT_TRUE;
|
||||
static int gBatLastVoltage = 0;
|
||||
static int gBatVoltage = BATT_NOMAL_VOL_VALUE;
|
||||
static int gBatLastCapacity = 0;
|
||||
static int gBatCapacity = ((BATT_NOMAL_VOL_VALUE-BATT_ZERO_VOL_VALUE)*100/(BATT_MAX_VOL_VALUE-BATT_ZERO_VOL_VALUE));
|
||||
|
||||
static int gBatVoltageSamples[NUM_VOLTAGE_SAMPLE+2]; //add 2 to handle one bug
|
||||
static int gBatSlopeValue = 0;
|
||||
static int gBatVoltageValue[2]={0,0};
|
||||
static int *pSamples = &gBatVoltageSamples[0]; //采样点指针
|
||||
static int gFlagLoop = 0; //采样足够标志
|
||||
static int gNumSamples = 0;
|
||||
static int gNumCharge = 0;
|
||||
static int gMaxCharge = 0;
|
||||
static int gNumLoader = 0;
|
||||
static int gMaxLoader = 0;
|
||||
|
||||
static int gBatSlopeLevel = SLOPE_LOW_LEVEL;
|
||||
static int gBatVoltageLevel = VOLTAGE_MID_LEVEL;
|
||||
static int gBatUseStatus = BAT_LOADER_STATUS;
|
||||
|
||||
static struct regulator *pChargeregulator;
|
||||
static int gVbuscharge = 0;
|
||||
|
||||
extern int dwc_vbus_status(void);
|
||||
extern int get_msc_connect_flag(void);
|
||||
|
||||
struct rk2818_battery_data {
|
||||
int irq;
|
||||
spinlock_t lock;
|
||||
struct work_struct timer_work;
|
||||
struct timer_list timer;
|
||||
struct power_supply battery;
|
||||
struct power_supply usb;
|
||||
struct power_supply ac;
|
||||
|
||||
int charge_ok_pin;
|
||||
int charge_ok_level;
|
||||
|
||||
int adc_bat_divider;
|
||||
int bat_max;
|
||||
int bat_min;
|
||||
};
|
||||
|
||||
|
||||
/* temporary variable used between rk2818_battery_probe() and rk2818_battery_open() */
|
||||
static struct rk2818_battery_data *gBatteryData;
|
||||
|
||||
enum {
|
||||
BATTERY_STATUS = 0,
|
||||
BATTERY_HEALTH = 1,
|
||||
BATTERY_PRESENT = 2,
|
||||
BATTERY_CAPACITY = 3,
|
||||
BATTERY_AC_ONLINE = 4,
|
||||
BATTERY_STATUS_CHANGED = 5,
|
||||
AC_STATUS_CHANGED = 6,
|
||||
BATTERY_INT_STATUS = 7,
|
||||
BATTERY_INT_ENABLE = 8,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CHARGER_BATTERY = 0,
|
||||
CHARGER_USB,
|
||||
CHARGER_AC
|
||||
} charger_type_t;
|
||||
|
||||
static int rk2818_get_charge_status(void)
|
||||
{
|
||||
struct regulator * rdev = pChargeregulator;
|
||||
//DBG("gAdcValue[CHN_USB_ADC]=%d\n",gAdcValue[CHN_USB_ADC]);
|
||||
/*if(gAdcValue[CHN_USB_ADC] > 250)
|
||||
{ //about 0.5V
|
||||
return 1;
|
||||
}
|
||||
else */
|
||||
if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag()))
|
||||
{
|
||||
DBG("CHARGE!\n");
|
||||
if(gVbuscharge !=1) {
|
||||
if(!IS_ERR(rdev))
|
||||
regulator_set_current_limit(rdev,0,1200000);
|
||||
}
|
||||
gVbuscharge = 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("NOT CHARGING!\n");
|
||||
if(gVbuscharge !=0 ) {
|
||||
if(!IS_ERR(rdev))
|
||||
regulator_set_current_limit(rdev,0,475000);
|
||||
}
|
||||
gVbuscharge = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rk2818_get_bat_status(struct rk2818_battery_data *bat)
|
||||
{
|
||||
if(rk2818_get_charge_status() == 1)
|
||||
{
|
||||
//local_irq_disable();
|
||||
if (gBatFullFlag == 0) {
|
||||
gBatStatus = POWER_SUPPLY_STATUS_CHARGING;
|
||||
} else {
|
||||
gBatStatus = POWER_SUPPLY_STATUS_FULL;
|
||||
}
|
||||
//local_irq_enable();
|
||||
DBG("Battery is Charging!\n");
|
||||
}
|
||||
else {
|
||||
gBatFullFlag = 0;
|
||||
gBatStatus = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
DBG("Battery is Not Charging!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void rk2818_get_bat_health(struct rk2818_battery_data *bat)
|
||||
{
|
||||
gBatHealth = POWER_SUPPLY_HEALTH_GOOD;
|
||||
}
|
||||
|
||||
static void rk2818_get_bat_present(struct rk2818_battery_data *bat)
|
||||
{
|
||||
if(gBatVoltage < bat->bat_min)
|
||||
gBatPresent = 0;
|
||||
else
|
||||
gBatPresent = 1;
|
||||
}
|
||||
|
||||
static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat)
|
||||
{
|
||||
unsigned long value;
|
||||
int i,*pSamp,*pStart = &gBatVoltageSamples[0],num = 0;
|
||||
int temp[2] = {0,0};
|
||||
value = gAdcValue[CHN_BAT_ADC];
|
||||
if(0 != gAdcValue[3])
|
||||
#if defined(CONFIG_MACH_RAHO)||defined(CONFIG_MACH_RAHOSDK)
|
||||
gBatVoltage = (value * BAT_1V2_VALUE * 3)/(gAdcValue[3]*2);
|
||||
#else
|
||||
gBatVoltage = (value * BAT_1V2_VALUE * 2)/gAdcValue[3]; // channel 3 is about 1.42v,need modified
|
||||
#endif
|
||||
|
||||
/*消除毛刺电压*/
|
||||
if(gBatVoltage >= BATT_MAX_VOL_VALUE + 10)
|
||||
gBatVoltage = BATT_MAX_VOL_VALUE + 10;
|
||||
else if(gBatVoltage <= BATT_ZERO_VOL_VALUE - 10)
|
||||
gBatVoltage = BATT_ZERO_VOL_VALUE - 10;
|
||||
|
||||
*pSamples = gBatVoltage;
|
||||
num = ++pSamples - pStart;
|
||||
if(num > NUM_VOLTAGE_SAMPLE)
|
||||
{
|
||||
pSamples = pStart;
|
||||
gFlagLoop = 1;
|
||||
}
|
||||
|
||||
if(gFlagLoop != 1) //未采集到 NUM_VOLTAGE_SAMPLE个电压值
|
||||
{
|
||||
for(i=(num>>1); i<num; i++)
|
||||
{
|
||||
temp[0] += gBatVoltageSamples[i];
|
||||
}
|
||||
|
||||
if(num != 0)
|
||||
{
|
||||
gBatVoltage = temp[0] / ((num+1)>>1);
|
||||
gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
|
||||
if(gBatCapacity >= 100)
|
||||
gBatCapacity = 100;
|
||||
else if(gBatCapacity < 0)
|
||||
gBatCapacity = 0;
|
||||
}
|
||||
//DBG("gBatVoltage=%d,gBatCapacity=%d,num=%d\n",gBatVoltage,gBatCapacity,num);
|
||||
}
|
||||
else
|
||||
{
|
||||
//compute the average voltage after samples-count is larger than NUM_VOLTAGE_SAMPLE
|
||||
pSamp = pSamples;
|
||||
for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
|
||||
{
|
||||
temp[0] += *pSamp;
|
||||
if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
|
||||
pSamp = pStart;
|
||||
}
|
||||
|
||||
gBatVoltageValue[0] = temp[0] / (NUM_VOLTAGE_SAMPLE >> 1);
|
||||
for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++)
|
||||
{
|
||||
temp[1] += *pSamp;
|
||||
if((++pSamp - pStart) > NUM_VOLTAGE_SAMPLE)
|
||||
pSamp = pStart;
|
||||
}
|
||||
|
||||
gBatVoltageValue[1] = temp[1] / (NUM_VOLTAGE_SAMPLE >> 1);
|
||||
|
||||
gBatVoltage = gBatVoltageValue[1];
|
||||
|
||||
gBatSlopeValue = gBatVoltageValue[0] - gBatVoltageValue[1];
|
||||
//DBG("gBatSlopeValue=%d,gBatVoltageValue[1]=%d\n",gBatSlopeValue,gBatVoltageValue[1]);
|
||||
|
||||
if(gBatVoltageValue[1] < BATT_ZERO_VOL_VALUE)
|
||||
{
|
||||
gBatUseStatus = BAT_RELEASE_STATUS; //电池耗尽状态
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gBatSlopeValue < 0)
|
||||
{
|
||||
gNumLoader = 0;
|
||||
|
||||
//连续多次电压降低率为负表示充电状态
|
||||
if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
|
||||
gMaxCharge = 2;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
|
||||
gMaxCharge = 3;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
|
||||
gMaxCharge = 4;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
|
||||
gMaxCharge = 2;
|
||||
if((++gNumCharge >= gMaxCharge) && (gBatStatus != POWER_SUPPLY_STATUS_NOT_CHARGING))
|
||||
{
|
||||
gBatUseStatus = BAT_CHARGE_STATUS; //充电状态
|
||||
gNumCharge = gMaxCharge ;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBatUseStatus = BAT_CHANGE_STATUS; //波动状态
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gNumCharge = 0;
|
||||
//连续多次电压降低率为正表示用电状态
|
||||
if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0)
|
||||
gMaxCharge = 2;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1)
|
||||
gMaxCharge = 3;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2)
|
||||
gMaxCharge = 4;
|
||||
else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3)
|
||||
gMaxLoader = 2;
|
||||
|
||||
if((++gNumLoader >= gMaxLoader) && (gBatStatus == POWER_SUPPLY_STATUS_NOT_CHARGING))
|
||||
{
|
||||
gBatUseStatus = BAT_LOADER_STATUS;
|
||||
gNumLoader = gMaxLoader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBatUseStatus = BAT_CHANGE_STATUS; //波动状态
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void rk2818_get_bat_capacity(struct rk2818_battery_data *bat)
|
||||
{
|
||||
if(gFlagLoop)
|
||||
{
|
||||
if(gBatUseStatus == BAT_LOADER_STATUS)
|
||||
{
|
||||
//用电状态下出现负载变小容量变大时,不更新容量值
|
||||
if((gBatLastVoltage == 0) || (gBatVoltage <= gBatLastVoltage))
|
||||
{
|
||||
gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
|
||||
if(gBatCapacity >= 100)
|
||||
gBatCapacity = 100;
|
||||
else if(gBatCapacity < 0)
|
||||
gBatCapacity = 0;
|
||||
gBatLastVoltage = gBatVoltage;
|
||||
}
|
||||
|
||||
}
|
||||
else if(gBatUseStatus == BAT_CHARGE_STATUS)
|
||||
{
|
||||
//充电状态下容量降低时,不更新容量值
|
||||
if((gBatLastVoltage == 0) || (gBatVoltage >= gBatLastVoltage))
|
||||
{
|
||||
gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
|
||||
if(gBatCapacity >= 100)
|
||||
gBatCapacity = 100;
|
||||
else if(gBatCapacity < 0)
|
||||
gBatCapacity = 0;
|
||||
gBatLastVoltage = gBatVoltage;
|
||||
//DBG("BAT_CHARGE_STATUS\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//变化状态不更新容量
|
||||
//DBG("BAT_CHANGE_STATUS\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min);
|
||||
if(gBatCapacity >= 100)
|
||||
gBatCapacity = 100;
|
||||
else if(gBatCapacity < 0)
|
||||
gBatCapacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void rk2818_battery_timer_work(struct work_struct *work)
|
||||
{
|
||||
rk2818_get_bat_status(gBatteryData);
|
||||
rk2818_get_bat_health(gBatteryData);
|
||||
rk2818_get_bat_present(gBatteryData);
|
||||
rk2818_get_bat_voltage(gBatteryData);
|
||||
rk2818_get_bat_capacity(gBatteryData);
|
||||
|
||||
/*update battery parameter after adc and capacity has been changed*/
|
||||
if((gBatStatus != gBatLastStatus) || (gBatPresent != gBatLastPresent) || (gBatCapacity != gBatLastCapacity))
|
||||
{
|
||||
//gNumSamples = 0;
|
||||
gBatLastStatus = gBatStatus;
|
||||
gBatLastPresent = gBatPresent;
|
||||
gBatLastCapacity = gBatCapacity;
|
||||
power_supply_changed(&gBatteryData->battery);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void rk2818_batscan_timer(unsigned long data)
|
||||
{
|
||||
gBatteryData->timer.expires = jiffies + msecs_to_jiffies(TIMER_MS_COUNTS);
|
||||
add_timer(&gBatteryData->timer);
|
||||
schedule_work(&gBatteryData->timer_work);
|
||||
}
|
||||
|
||||
|
||||
static int rk2818_usb_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
charger_type_t charger;
|
||||
charger = CHARGER_USB;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
if (psy->type == POWER_SUPPLY_TYPE_USB)
|
||||
val->intval = dwc_vbus_status();
|
||||
DBG("%s:%d\n",__FUNCTION__,val->intval);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int rk2818_ac_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
// struct rk2818_battery_data *data = container_of(psy,
|
||||
// struct rk2818_battery_data, ac);
|
||||
int ret = 0;
|
||||
charger_type_t charger;
|
||||
charger = CHARGER_USB;
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
if (psy->type == POWER_SUPPLY_TYPE_MAINS)
|
||||
{
|
||||
if(gAdcValue[CHN_USB_ADC] > 250)
|
||||
val->intval = 1;
|
||||
else
|
||||
val->intval = 0;
|
||||
}
|
||||
DBG("%s:%d\n",__FUNCTION__,val->intval);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk2818_battery_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct rk2818_battery_data *data = container_of(psy,
|
||||
struct rk2818_battery_data, battery);
|
||||
int ret = 0;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
val->intval = gBatStatus;
|
||||
DBG("gBatStatus=%d\n",val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
val->intval = gBatHealth;
|
||||
DBG("gBatHealth=%d\n",val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
val->intval = gBatPresent;
|
||||
DBG("gBatPresent=%d\n",val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
if(gBatVoltageValue[1] == 0)
|
||||
val ->intval = gBatVoltage;
|
||||
else
|
||||
val ->intval = gBatVoltageValue[1];
|
||||
DBG("gBatVoltage=%d\n",val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TECHNOLOGY:
|
||||
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
val->intval = gBatCapacity;
|
||||
DBG("gBatCapacity=%d%%\n",val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
|
||||
val->intval = data->bat_max;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
|
||||
val->intval = data->bat_min;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum power_supply_property rk2818_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
};
|
||||
|
||||
static enum power_supply_property rk2818_usb_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
|
||||
|
||||
static enum power_supply_property rk2818_ac_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rk2818_battery_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
/* flush all pending status updates */
|
||||
flush_scheduled_work();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk2818_battery_resume(struct platform_device *dev)
|
||||
{
|
||||
/* things may have changed while we were away */
|
||||
schedule_work(&gBatteryData->timer_work);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rk2818_battery_suspend NULL
|
||||
#define rk2818_battery_resume NULL
|
||||
#endif
|
||||
|
||||
static irqreturn_t rk2818_battery_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag())) {//detech when charging
|
||||
gBatFullFlag = 1;
|
||||
}
|
||||
|
||||
DBG(KERN_INFO "-----battery is full-----\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk2818_battery_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct rk2818_battery_data *data;
|
||||
struct rk2818_battery_platform_data *pdata = pdev->dev.platform_data;
|
||||
int irq_flag;
|
||||
|
||||
if (pdata && pdata->io_init) {
|
||||
ret = pdata->io_init();
|
||||
if (ret)
|
||||
goto err_free_gpio1;
|
||||
}
|
||||
|
||||
ret = gpio_request(pdata->charge_ok_pin, NULL);
|
||||
if (ret) {
|
||||
printk("failed to request charge_ok gpio\n");
|
||||
goto err_free_gpio1;
|
||||
}
|
||||
|
||||
gpio_pull_updown(pdata->charge_ok_pin, GPIOPullUp);//important
|
||||
ret = gpio_direction_input(pdata->charge_ok_pin);
|
||||
if (ret) {
|
||||
printk("failed to set gpio charge_ok input\n");
|
||||
goto err_free_gpio1;
|
||||
}
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_data_alloc_failed;
|
||||
}
|
||||
spin_lock_init(&data->lock);
|
||||
|
||||
memset(gBatVoltageSamples, 0, sizeof(gBatVoltageSamples));
|
||||
|
||||
data->battery.properties = rk2818_battery_props;
|
||||
data->battery.num_properties = ARRAY_SIZE(rk2818_battery_props);
|
||||
data->battery.get_property = rk2818_battery_get_property;
|
||||
data->battery.name = "battery";
|
||||
data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
data->adc_bat_divider = 414;
|
||||
data->bat_max = BATT_MAX_VOL_VALUE;
|
||||
data->bat_min = BATT_ZERO_VOL_VALUE;
|
||||
DBG("bat_min = %d\n",data->bat_min);
|
||||
|
||||
data->usb.properties = rk2818_usb_props;
|
||||
data->usb.num_properties = ARRAY_SIZE(rk2818_ac_props);
|
||||
data->usb.get_property = rk2818_usb_get_property;
|
||||
data->usb.name = "usb";
|
||||
data->usb.type = POWER_SUPPLY_TYPE_USB;
|
||||
|
||||
data->ac.properties = rk2818_ac_props;
|
||||
data->ac.num_properties = ARRAY_SIZE(rk2818_ac_props);
|
||||
data->ac.get_property = rk2818_ac_get_property;
|
||||
data->ac.name = "ac";
|
||||
data->ac.type = POWER_SUPPLY_TYPE_MAINS;
|
||||
|
||||
data->charge_ok_pin = pdata->charge_ok_pin;
|
||||
data->charge_ok_level = pdata->charge_ok_level;
|
||||
|
||||
irq_flag = (!pdata->charge_ok_level) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(gpio_to_irq(pdata->charge_ok_pin), rk2818_battery_interrupt, irq_flag, "rk2818_battery", data);
|
||||
if (ret) {
|
||||
printk("failed to request irq\n");
|
||||
goto err_irq_failed;
|
||||
}
|
||||
|
||||
ret = power_supply_register(&pdev->dev, &data->ac);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_INFO "fail to power_supply_register\n");
|
||||
goto err_ac_failed;
|
||||
}
|
||||
|
||||
ret = power_supply_register(&pdev->dev, &data->usb);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_INFO "fail to power_supply_register\n");
|
||||
goto err_usb_failed;
|
||||
}
|
||||
|
||||
ret = power_supply_register(&pdev->dev, &data->battery);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_INFO "fail to power_supply_register\n");
|
||||
goto err_battery_failed;
|
||||
}
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
|
||||
pChargeregulator = regulator_get(&pdev->dev, "battery");
|
||||
if(IS_ERR(pChargeregulator))
|
||||
printk(KERN_ERR"fail to get regulator battery\n");
|
||||
else
|
||||
regulator_set_current_limit(pChargeregulator,0,475000);
|
||||
|
||||
INIT_WORK(&data->timer_work, rk2818_battery_timer_work);
|
||||
gBatteryData = data;
|
||||
|
||||
setup_timer(&data->timer, rk2818_batscan_timer, (unsigned long)data);
|
||||
data->timer.expires = jiffies+100;
|
||||
add_timer(&data->timer);
|
||||
printk(KERN_INFO "rk2818_battery: driver initialized\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_battery_failed:
|
||||
power_supply_unregister(&data->usb);
|
||||
err_usb_failed:
|
||||
power_supply_unregister(&data->ac);
|
||||
err_ac_failed:
|
||||
free_irq(gpio_to_irq(pdata->charge_ok_pin), data);
|
||||
err_irq_failed:
|
||||
kfree(data);
|
||||
err_data_alloc_failed:
|
||||
|
||||
err_free_gpio1:
|
||||
gpio_free(pdata->charge_ok_pin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk2818_battery_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk2818_battery_data *data = platform_get_drvdata(pdev);
|
||||
struct rk2818_battery_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
power_supply_unregister(&data->battery);
|
||||
power_supply_unregister(&data->usb);
|
||||
power_supply_unregister(&data->ac);
|
||||
free_irq(data->irq, data);
|
||||
gpio_free(pdata->charge_ok_pin);
|
||||
kfree(data);
|
||||
gBatteryData = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk2818_battery_device = {
|
||||
.probe = rk2818_battery_probe,
|
||||
.remove = rk2818_battery_remove,
|
||||
.suspend = rk2818_battery_suspend,
|
||||
.resume = rk2818_battery_resume,
|
||||
.driver = {
|
||||
.name = "rk2818-battery",
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init rk2818_battery_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk2818_battery_device);
|
||||
}
|
||||
|
||||
static void __exit rk2818_battery_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk2818_battery_device);
|
||||
}
|
||||
|
||||
module_init(rk2818_battery_init);
|
||||
module_exit(rk2818_battery_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Battery detect driver for the rk2818");
|
||||
MODULE_AUTHOR("luowei lw@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
@ -1477,32 +1477,6 @@ config SERIAL_BCM63XX_CONSOLE
|
|||
If you have enabled the serial port on the bcm63xx CPU
|
||||
you can make it the console by answering Y to this option.
|
||||
|
||||
config SERIAL_RK2818
|
||||
bool "RockChip rk2818 serial port support"
|
||||
depends on ARM && ARCH_RK2818
|
||||
select SERIAL_CORE
|
||||
|
||||
config UART0_RK2818
|
||||
bool "RockChip rk2818 serial port 0 support"
|
||||
depends on SERIAL_RK2818
|
||||
|
||||
config UART1_RK2818
|
||||
bool "RockChip rk2818 serial port 1 support"
|
||||
depends on SERIAL_RK2818
|
||||
|
||||
config UART2_RK2818
|
||||
bool "RockChip rk2818 serial port 2 support"
|
||||
depends on SERIAL_RK2818
|
||||
|
||||
config UART3_RK2818
|
||||
bool "RockChip rk2818 serial port 3 support"
|
||||
depends on SERIAL_RK2818
|
||||
|
||||
config SERIAL_RK2818_CONSOLE
|
||||
bool "Rockchip rk2818 serial console support"
|
||||
depends on SERIAL_RK2818=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
|
||||
config SERIAL_RK29
|
||||
bool "RockChip rk29 serial port support"
|
||||
depends on ARM && ARCH_RK29
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
|
|||
obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
|
||||
obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
|
||||
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
|
||||
obj-$(CONFIG_SERIAL_RK2818) += rk2818_serial.o
|
||||
ifeq ($(CONFIG_SERIAL_RK29_STANDARD),y)
|
||||
obj-$(CONFIG_SERIAL_RK29) += rk_serial.o
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,708 +0,0 @@
|
|||
/*
|
||||
* drivers/serial/rk2818_serial.c - driver for rk2818 serial device and console
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_SERIAL_RK2818_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
|
||||
#define SUPPORT_SYSRQ
|
||||
#endif
|
||||
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include "rk2818_serial.h"
|
||||
|
||||
/*
|
||||
* We wrap our port structure around the generic uart_port.
|
||||
*/
|
||||
struct rk2818_port {
|
||||
struct uart_port uart;
|
||||
char name[16];
|
||||
struct clk *clk;
|
||||
unsigned int imr;
|
||||
};
|
||||
|
||||
#define UART_TO_RK2818(uart_port) ((struct rk2818_port *) uart_port)
|
||||
#define RK2818_SERIAL_MAJOR TTY_MAJOR
|
||||
#define RK2818_SERIAL_MINOR 64
|
||||
|
||||
|
||||
static inline void rk2818_uart_write(struct uart_port *port, unsigned int val,
|
||||
unsigned int off)
|
||||
{
|
||||
__raw_writel(val, port->membase + off);
|
||||
}
|
||||
|
||||
static inline unsigned int rk2818_uart_read(struct uart_port *port, unsigned int off)
|
||||
{
|
||||
return __raw_readl(port->membase + off);
|
||||
}
|
||||
|
||||
static int rk2818_set_baud_rate(struct uart_port *port, unsigned int baud)
|
||||
{
|
||||
unsigned int uartTemp;
|
||||
|
||||
rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) | LCR_DLA_EN,UART_LCR);
|
||||
uartTemp = port->uartclk / (16 * baud);
|
||||
rk2818_uart_write(port,uartTemp & 0xff,UART_DLL);
|
||||
rk2818_uart_write(port,(uartTemp>>8) & 0xff,UART_DLH);
|
||||
rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) & (~LCR_DLA_EN),UART_LCR);
|
||||
return baud;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判断发送缓冲区是否为空
|
||||
*先以FIFO打开做,后面可以做成FIFO关或FIFO开。
|
||||
*/
|
||||
static u_int rk2818_serial_tx_empty(struct uart_port *port)
|
||||
{
|
||||
while(!(rk2818_uart_read(port,UART_USR)&UART_TRANSMIT_FIFO_EMPTY))
|
||||
cpu_relax();
|
||||
if(rk2818_uart_read(port,UART_USR)&UART_TRANSMIT_FIFO_EMPTY)
|
||||
{
|
||||
return (1);///1:空
|
||||
}else{
|
||||
return (0);///0:非空
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Power / Clock management.
|
||||
*/
|
||||
static void rk2818_serial_pm(struct uart_port *port, unsigned int state,
|
||||
unsigned int oldstate)
|
||||
{
|
||||
struct rk2818_port *rk2818_port = UART_TO_RK2818(port);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
/*
|
||||
* Enable the peripheral clock for this serial port.
|
||||
* This is called on uart_open() or a resume event.
|
||||
*/
|
||||
clk_enable(rk2818_port->clk);
|
||||
break;
|
||||
case 3:
|
||||
/*
|
||||
* Disable the peripheral clock for this serial port.
|
||||
* This is called on uart_close() or a suspend event.
|
||||
*/
|
||||
clk_disable(rk2818_port->clk);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "rk2818_serial: unknown pm %d\n", state);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return string describing the specified port
|
||||
*/
|
||||
static const char *rk2818_serial_type(struct uart_port *port)
|
||||
{
|
||||
return (port->type == PORT_RK2818) ? "RK2818_SERIAL" : NULL;
|
||||
}
|
||||
|
||||
static void rk2818_serial_enable_ms(struct uart_port *port)
|
||||
{
|
||||
#ifdef DEBUG_LHH
|
||||
printk("Enter::%s\n",__FUNCTION__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* no modem control lines */
|
||||
static unsigned int rk2818_serial_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
unsigned int status;
|
||||
|
||||
status = rk2818_uart_read(port,UART_MSR);
|
||||
if (status & UART_MSR_URCTS)
|
||||
{
|
||||
result = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
|
||||
printk("UART_GET_MSR:0x%x\n",result);
|
||||
}else{
|
||||
result = TIOCM_CAR | TIOCM_DSR;
|
||||
printk("UART_GET_MSR:0x%x\n",result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void rk2818_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
#ifdef DEBUG_LHH
|
||||
printk("Enter::%s\n",__FUNCTION__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop transmitting.
|
||||
*/
|
||||
static void rk2818_serial_stop_tx(struct uart_port *port)
|
||||
{
|
||||
#ifdef DEBUG_LHH
|
||||
printk("Enter::%s\n",__FUNCTION__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Start transmitting.
|
||||
*/
|
||||
static void rk2818_serial_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
while(!(uart_circ_empty(xmit)))
|
||||
{
|
||||
while (!(rk2818_uart_read(port,UART_USR) & UART_TRANSMIT_FIFO_NOT_FULL)){
|
||||
rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE|UART_IER_SEND_EMPTY_INT_ENABLE,UART_IER);
|
||||
return;
|
||||
}
|
||||
rk2818_uart_write(port,xmit->buf[xmit->tail],UART_THR);
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
port->icount.tx++;
|
||||
}
|
||||
if((uart_circ_empty(xmit)))
|
||||
rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE,UART_IER);
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop receiving - port is in process of being closed.
|
||||
*/
|
||||
static void rk2818_serial_stop_rx(struct uart_port *port)
|
||||
{
|
||||
#ifdef DEBUG_LHH
|
||||
printk("Enter::%s\n",__FUNCTION__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Control the transmission of a break signal
|
||||
*/
|
||||
static void rk2818_serial_break_ctl(struct uart_port *port, int break_state)
|
||||
{
|
||||
unsigned int temp;
|
||||
temp = rk2818_uart_read(port,UART_LCR);
|
||||
if (break_state != 0)
|
||||
temp = temp & (~BREAK_CONTROL_BIT);/* start break */
|
||||
else
|
||||
temp = temp | BREAK_CONTROL_BIT; /* stop break */
|
||||
rk2818_uart_write(port,temp,UART_LCR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Characters received (called from interrupt handler)
|
||||
*/
|
||||
static void rk2818_rx_chars(struct uart_port *port)
|
||||
{
|
||||
unsigned int ch, flag;
|
||||
while((rk2818_uart_read(port,UART_USR) & UART_RECEIVE_FIFO_NOT_EMPTY) == UART_RECEIVE_FIFO_NOT_EMPTY)
|
||||
{
|
||||
u32 lsr = rk2818_uart_read(port, UART_LSR);
|
||||
ch = rk2818_uart_read(port,UART_RBR);
|
||||
flag = TTY_NORMAL;
|
||||
port->icount.rx++;
|
||||
if (lsr & UART_BREAK_INT_BIT) {
|
||||
port->icount.brk++;
|
||||
if (uart_handle_break(port))
|
||||
continue;
|
||||
}
|
||||
if (uart_handle_sysrq_char(port, ch))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uart_insert_char(port, 0, 0, ch, flag);
|
||||
}
|
||||
tty_flip_buffer_push(port->state->port.tty);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler
|
||||
*/
|
||||
static irqreturn_t rk2818_uart_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
unsigned int status, pending;
|
||||
|
||||
status = rk2818_uart_read(port,UART_IIR);
|
||||
pending = status & 0x0f;
|
||||
if((pending == UART_IIR_RECV_AVAILABLE) || (pending == UART_IIR_CHAR_TIMEOUT))
|
||||
rk2818_rx_chars(port);
|
||||
if(pending == UART_IIR_THR_EMPTY)
|
||||
rk2818_serial_start_tx(port);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the port
|
||||
*/
|
||||
static void rk2818_serial_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct rk2818_port *rk2818_port = UART_TO_RK2818(port);
|
||||
rk2818_uart_write(port,0x00,UART_IER);
|
||||
clk_disable(rk2818_port->clk);
|
||||
free_irq(port->irq, port);
|
||||
}
|
||||
/*
|
||||
* Perform initialization and enable port for reception
|
||||
*/
|
||||
static int rk2818_serial_startup(struct uart_port *port)
|
||||
{
|
||||
struct rk2818_port *rk2818_port = UART_TO_RK2818(port);
|
||||
struct tty_struct *tty = port->state->port.tty;
|
||||
int retval;
|
||||
|
||||
retval = request_irq(port->irq,rk2818_uart_interrupt,IRQF_SHARED,
|
||||
tty ? tty->name : "rk2818_serial",port);
|
||||
if(retval)
|
||||
{
|
||||
printk("\nrk2818_serial_startup err \n");
|
||||
rk2818_serial_shutdown(port);
|
||||
return retval;
|
||||
}
|
||||
clk_enable(rk2818_port->clk);
|
||||
rk2818_uart_write(port,0xf1,UART_FCR);
|
||||
rk2818_uart_write(port,0x01,UART_SFE);///enable fifo
|
||||
rk2818_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE,UART_IER); //enable uart recevice IRQ
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the port parameters
|
||||
*/
|
||||
static void rk2818_serial_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
struct ktermios *old)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int mode, baud;
|
||||
unsigned int umcon,fcr;
|
||||
/* Get current mode register */
|
||||
mode = rk2818_uart_read(port,UART_LCR) & (BREAK_CONTROL_BIT | EVEN_PARITY_SELECT | PARITY_ENABLED
|
||||
| ONE_HALF_OR_TWO_BIT | UART_DATABIT_MASK);
|
||||
|
||||
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
|
||||
/* byte size */
|
||||
switch (termios->c_cflag & CSIZE) {
|
||||
case CS5:
|
||||
mode |= LCR_WLS_5;
|
||||
break;
|
||||
case CS6:
|
||||
mode |= LCR_WLS_6;
|
||||
break;
|
||||
case CS7:
|
||||
mode |= LCR_WLS_7;
|
||||
break;
|
||||
default:
|
||||
mode |= LCR_WLS_8;
|
||||
break;
|
||||
}
|
||||
|
||||
/* stop bits */
|
||||
if (termios->c_cflag & CSTOPB)
|
||||
mode |= ONE_STOP_BIT;
|
||||
|
||||
/* parity */
|
||||
if (termios->c_cflag & PARENB)
|
||||
{
|
||||
mode |= PARITY_ENABLED;
|
||||
if (termios->c_cflag & PARODD)
|
||||
mode |= ODD_PARITY;
|
||||
else
|
||||
mode |= EVEN_PARITY;
|
||||
}
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if(termios->c_cflag & CRTSCTS)
|
||||
{
|
||||
/*开启uart0硬件流控*/
|
||||
printk("start CRTSCTS control and baudrate is %d\n",baud);
|
||||
umcon=rk2818_uart_read(port,UART_MCR);
|
||||
printk("UART_GET_MCR umcon=0x%x\n",umcon);
|
||||
umcon |= UART_MCR_AFCEN;
|
||||
umcon |= UART_MCR_URRTS;
|
||||
umcon &=~UART_SIR_ENABLE;
|
||||
rk2818_uart_write(port,umcon,UART_MCR);
|
||||
printk("UART_GET_MCR umcon=0x%x\n",umcon);
|
||||
fcr=rk2818_uart_read(port,UART_FCR);
|
||||
printk("UART_GET_MCR fcr=0x%x\n",fcr);
|
||||
fcr |= UART_FCR_FIFO_ENABLE;
|
||||
rk2818_uart_write(port,fcr,UART_FCR);
|
||||
printk("UART_GET_MCR fcr=0x%x\n",fcr);
|
||||
}
|
||||
mode = mode | LCR_DLA_EN;
|
||||
while(rk2818_uart_read(port,UART_USR)&UART_USR_BUSY)
|
||||
cpu_relax();
|
||||
rk2818_uart_write(port,mode,UART_LCR);
|
||||
baud = rk2818_set_baud_rate(port, baud);
|
||||
uart_update_timeout(port, termios->c_cflag, baud);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
|
||||
static void rk2818_serial_release_port(struct uart_port *port)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(port->dev);
|
||||
struct resource *resource;
|
||||
resource_size_t size;
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (unlikely(!resource))
|
||||
return;
|
||||
size = resource->end - resource->start + 1;
|
||||
|
||||
release_mem_region(port->mapbase, size);
|
||||
iounmap(port->membase);
|
||||
port->membase = NULL;
|
||||
}
|
||||
|
||||
static int rk2818_serial_request_port(struct uart_port *port)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(port->dev);
|
||||
struct resource *resource;
|
||||
resource_size_t size;
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (unlikely(!resource))
|
||||
return -ENXIO;
|
||||
size = resource->end - resource->start + 1;
|
||||
|
||||
if (unlikely(!request_mem_region(port->mapbase, size, "rk2818_serial")))
|
||||
return -EBUSY;
|
||||
|
||||
port->membase = ioremap(port->mapbase, size);
|
||||
if (!port->membase) {
|
||||
release_mem_region(port->mapbase, size);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure/autoconfigure the port.
|
||||
*/
|
||||
static void rk2818_serial_config_port(struct uart_port *port, int flags)
|
||||
{
|
||||
if (flags & UART_CONFIG_TYPE) {
|
||||
port->type = PORT_RK2818;
|
||||
rk2818_serial_request_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the new serial_struct (for TIOCSSERIAL).
|
||||
*/
|
||||
static int rk2818_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||
{
|
||||
int ret = 0;
|
||||
if (ser->type != PORT_UNKNOWN && ser->type != PORT_RK2818)
|
||||
ret = -EINVAL;
|
||||
if (port->irq != ser->irq)
|
||||
ret = -EINVAL;
|
||||
if (ser->io_type != SERIAL_IO_MEM)
|
||||
ret = -EINVAL;
|
||||
if (port->uartclk / 16 != ser->baud_base)
|
||||
ret = -EINVAL;
|
||||
if ((void *)port->mapbase != ser->iomem_base)
|
||||
ret = -EINVAL;
|
||||
if (port->iobase != ser->port)
|
||||
ret = -EINVAL;
|
||||
if (ser->hub6 != 0)
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
/*
|
||||
* Console polling routines for writing and reading from the uart while
|
||||
* in an interrupt or debug context.
|
||||
*/
|
||||
|
||||
static int rk2818_serial_poll_get_char(struct uart_port *port)
|
||||
{
|
||||
while (!((rk2818_uart_read(port, UART_USR) & UART_RECEIVE_FIFO_NOT_EMPTY) == UART_RECEIVE_FIFO_NOT_EMPTY))
|
||||
barrier();
|
||||
return rk2818_uart_read(port, UART_RBR);
|
||||
}
|
||||
|
||||
static void rk2818_serial_poll_put_char(struct uart_port *port, unsigned char c)
|
||||
{
|
||||
while (!(rk2818_uart_read(port, UART_USR) & UART_TRANSMIT_FIFO_NOT_FULL))
|
||||
barrier();
|
||||
rk2818_uart_write(port, c, UART_THR);
|
||||
}
|
||||
#endif /* CONFIG_CONSOLE_POLL */
|
||||
|
||||
static struct uart_ops rk2818_uart_pops = {
|
||||
.tx_empty = rk2818_serial_tx_empty,
|
||||
.set_mctrl = rk2818_serial_set_mctrl,
|
||||
.get_mctrl = rk2818_serial_get_mctrl,
|
||||
.stop_tx = rk2818_serial_stop_tx,
|
||||
.start_tx = rk2818_serial_start_tx,
|
||||
.stop_rx = rk2818_serial_stop_rx,
|
||||
.enable_ms = rk2818_serial_enable_ms,
|
||||
.break_ctl = rk2818_serial_break_ctl,
|
||||
.startup = rk2818_serial_startup,
|
||||
.shutdown = rk2818_serial_shutdown,
|
||||
.set_termios = rk2818_serial_set_termios,
|
||||
.type = rk2818_serial_type,
|
||||
.release_port = rk2818_serial_release_port,
|
||||
.request_port = rk2818_serial_request_port,
|
||||
.config_port = rk2818_serial_config_port,
|
||||
.verify_port = rk2818_serial_verify_port,
|
||||
.pm = rk2818_serial_pm,
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
.poll_get_char = rk2818_serial_poll_get_char,
|
||||
.poll_put_char = rk2818_serial_poll_put_char,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static struct rk2818_port rk2818_uart_ports[] = {
|
||||
{
|
||||
.uart = {
|
||||
.iotype = UPIO_MEM,
|
||||
.ops = &rk2818_uart_pops,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.fifosize = 32,
|
||||
.line = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.uart = {
|
||||
.iotype = UPIO_MEM,
|
||||
.ops = &rk2818_uart_pops,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.fifosize = 32,
|
||||
.line = 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.uart = {
|
||||
.iotype = UPIO_MEM,
|
||||
.ops = &rk2818_uart_pops,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.fifosize = 32,
|
||||
.line = 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
.uart = {
|
||||
.iotype = UPIO_MEM,
|
||||
.ops = &rk2818_uart_pops,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.fifosize = 32,
|
||||
.line = 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_NR ARRAY_SIZE(rk2818_uart_ports)
|
||||
|
||||
static inline struct uart_port *get_port_from_line(unsigned int line)
|
||||
{
|
||||
return &rk2818_uart_ports[line].uart;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_RK2818_CONSOLE
|
||||
static void rk2818_console_putchar(struct uart_port *port, int ch)
|
||||
{
|
||||
while (!(rk2818_uart_read(port,UART_USR) & UART_TRANSMIT_FIFO_NOT_FULL))
|
||||
cpu_relax();
|
||||
rk2818_uart_write(port,ch,UART_THR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts are disabled on entering
|
||||
*/
|
||||
static void rk2818_console_write(struct console *co, const char *s, u_int count)
|
||||
{
|
||||
struct uart_port *port;
|
||||
struct rk2818_port *rk2818_port;
|
||||
|
||||
BUG_ON(co->index < 0 || co->index >= UART_NR);
|
||||
|
||||
port = get_port_from_line(co->index);
|
||||
rk2818_port = UART_TO_RK2818(port);
|
||||
|
||||
spin_lock(&port->lock);
|
||||
uart_console_write(port, s, count, rk2818_console_putchar);
|
||||
spin_unlock(&port->lock);
|
||||
}
|
||||
|
||||
static int __init rk2818_console_setup(struct console *co, char *options)
|
||||
{
|
||||
struct uart_port *port;
|
||||
int baud, flow, bits, parity;
|
||||
|
||||
if (unlikely(co->index >= UART_NR || co->index < 0))
|
||||
return -ENXIO;
|
||||
|
||||
port = get_port_from_line(co->index);
|
||||
|
||||
if (unlikely(!port->membase))
|
||||
return -ENXIO;
|
||||
|
||||
port->cons = co;
|
||||
|
||||
//rk2818_init_clock(port);
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
||||
bits = 8;
|
||||
parity = 'n';
|
||||
flow = 'n';
|
||||
rk2818_uart_write(port,rk2818_uart_read(port,UART_LCR) | LCR_WLS_8 | PARITY_DISABLED | ONE_STOP_BIT,UART_LCR); /* 8N1 */
|
||||
if (baud < 300 || baud > 115200)
|
||||
baud = 115200;
|
||||
rk2818_set_baud_rate(port, baud);
|
||||
|
||||
printk(KERN_INFO "rk2818_serial: console setup on port %d\n", port->line);
|
||||
|
||||
return uart_set_options(port, co, baud, parity, bits, flow);
|
||||
}
|
||||
|
||||
static struct uart_driver rk2818_uart_driver;
|
||||
|
||||
static struct console rk2818_console = {
|
||||
.name = "ttyS",
|
||||
.write = rk2818_console_write,
|
||||
.device = uart_console_device,
|
||||
.setup = rk2818_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = 1,
|
||||
.data = &rk2818_uart_driver,
|
||||
};
|
||||
|
||||
#define RK2818_CONSOLE (&rk2818_console)
|
||||
|
||||
#else
|
||||
#define RK2818_CONSOLE NULL
|
||||
#endif
|
||||
|
||||
static struct uart_driver rk2818_uart_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_name = "rk2818_serial",
|
||||
.dev_name = "ttyS",
|
||||
.nr = UART_NR,
|
||||
.cons = RK2818_CONSOLE,
|
||||
.major = RK2818_SERIAL_MAJOR,
|
||||
.minor = RK2818_SERIAL_MINOR,
|
||||
};
|
||||
|
||||
static int __devinit rk2818_serial_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk2818_port *rk2818_port;
|
||||
struct resource *resource;
|
||||
struct uart_port *port;
|
||||
struct rk2818_serial_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
|
||||
return -ENXIO;
|
||||
|
||||
printk(KERN_INFO "rk2818_serial: detected port %d\n", pdev->id);
|
||||
|
||||
if (pdata && pdata->io_init)
|
||||
pdata->io_init();
|
||||
|
||||
port = get_port_from_line(pdev->id);
|
||||
port->dev = &pdev->dev;
|
||||
rk2818_port = UART_TO_RK2818(port);
|
||||
|
||||
rk2818_port->clk = clk_get(&pdev->dev, "uart");
|
||||
if (unlikely(IS_ERR(rk2818_port->clk)))
|
||||
return PTR_ERR(rk2818_port->clk);
|
||||
port->uartclk = clk_get_rate(rk2818_port->clk);
|
||||
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (unlikely(!resource))
|
||||
return -ENXIO;
|
||||
port->mapbase = resource->start;
|
||||
|
||||
port->irq = platform_get_irq(pdev, 0);
|
||||
if (unlikely(port->irq < 0))
|
||||
return -ENXIO;
|
||||
|
||||
platform_set_drvdata(pdev, port);
|
||||
|
||||
return uart_add_one_port(&rk2818_uart_driver, port);
|
||||
}
|
||||
|
||||
static int __devexit rk2818_serial_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk2818_port *rk2818_port = platform_get_drvdata(pdev);
|
||||
|
||||
clk_put(rk2818_port->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk2818_platform_driver = {
|
||||
.remove = rk2818_serial_remove,
|
||||
.driver = {
|
||||
.name = "rk2818_serial",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rk2818_serial_init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = uart_register_driver(&rk2818_uart_driver);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
ret = platform_driver_probe(&rk2818_platform_driver, rk2818_serial_probe);
|
||||
if (unlikely(ret))
|
||||
uart_unregister_driver(&rk2818_uart_driver);
|
||||
|
||||
printk(KERN_INFO "rk2818_serial: driver initialized\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rk2818_serial_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_RK2818_CONSOLE
|
||||
unregister_console(&rk2818_console);
|
||||
#endif
|
||||
platform_driver_unregister(&rk2818_platform_driver);
|
||||
uart_unregister_driver(&rk2818_uart_driver);
|
||||
}
|
||||
|
||||
/*
|
||||
* While this can be a module, if builtin it's most likely the console
|
||||
* So let's leave module_exit but move module_init to an earlier place
|
||||
*/
|
||||
arch_initcall(rk2818_serial_init);
|
||||
module_exit(rk2818_serial_exit);
|
||||
|
||||
MODULE_AUTHOR("lhh lhh@rock-chips.com");
|
||||
MODULE_DESCRIPTION("Rockchip RK2818 Serial port driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user