Merge branch 'develop-3.0' of ssh://10.10.10.29/rk/kernel into develop-3.0

This commit is contained in:
ywj
2012-08-17 17:58:04 +08:00
11 changed files with 756 additions and 70 deletions

View File

@@ -25,4 +25,23 @@
#include <plat/rk_camera.h>
#define CONFIG_CAMERA_SCALE_CROP_MACHINE RK_CAM_SCALE_CROP_IPP
#if (CONFIG_CAMERA_SCALE_CROP_MACHINE==RK_CAM_SCALE_CROP_ARM)
#define CAMERA_SCALE_CROP_MACHINE "arm"
#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE==RK_CAM_SCALE_CROP_IPP)
#define CAMERA_SCALE_CROP_MACHINE "ipp"
#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE==RK_CAM_SCALE_CROP_RGA)
#define CAMERA_SCALE_CROP_MACHINE "rga"
#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE==RK_CAM_SCALE_CROP_PP)
#define CAMERA_SCALE_CROP_MACHINE "pp"
#endif
#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
#define CAMERA_VIDEOBUF_ARM_ACCESS 1
#else
#define CAMERA_VIDEOBUF_ARM_ACCESS 0
#endif
#endif

View File

@@ -5,6 +5,7 @@
#include <linux/mfd/wm831x/pmu.h>
#include <mach/sram.h>
#include <linux/earlysuspend.h>
#define cru_readl(offset) readl_relaxed(RK30_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0)
@@ -498,7 +499,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
.min_uV = 600000,
.max_uV = 1800000, //0.6-1.8V
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
},
.num_consumer_supplies = ARRAY_SIZE(dcdc1_consumers),
.consumer_supplies = dcdc1_consumers,
@@ -509,7 +511,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
.min_uV = 600000,
.max_uV = 1800000, //0.6-1.8V
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
},
.num_consumer_supplies = ARRAY_SIZE(dcdc2_consumers),
.consumer_supplies = dcdc2_consumers,
@@ -520,7 +523,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
.min_uV = 850000,
.max_uV = 3400000, //0.85-3.4V
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
},
.num_consumer_supplies = ARRAY_SIZE(dcdc3_consumers),
.consumer_supplies = dcdc3_consumers,
@@ -531,7 +535,8 @@ struct regulator_init_data wm831x_regulator_init_dcdc[WM831X_MAX_DCDC] = {
.min_uV = 850000,
.max_uV = 3400000, //0.85-3.4V
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_STANDBY | REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST | REGULATOR_MODE_IDLE,
},
.num_consumer_supplies = ARRAY_SIZE(dcdc4_consumers),
.consumer_supplies = dcdc4_consumers,
@@ -572,7 +577,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo1_consumers),
.consumer_supplies = ldo1_consumers,
@@ -583,7 +589,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
.consumer_supplies = ldo2_consumers,
@@ -594,7 +601,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo3_consumers),
.consumer_supplies = ldo3_consumers,
@@ -605,7 +613,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo4_consumers),
.consumer_supplies = ldo4_consumers,
@@ -616,7 +625,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo5_consumers),
.consumer_supplies = ldo5_consumers,
@@ -627,7 +637,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 900000,
.max_uV = 3300000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo6_consumers),
.consumer_supplies = ldo6_consumers,
@@ -638,7 +649,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 1000000,
.max_uV = 3500000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo7_consumers),
.consumer_supplies = ldo7_consumers,
@@ -649,7 +661,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 1000000,
.max_uV = 3500000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo8_consumers),
.consumer_supplies = ldo8_consumers,
@@ -660,7 +673,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 1000000,
.max_uV = 3500000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo9_consumers),
.consumer_supplies = ldo9_consumers,
@@ -671,7 +685,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 1000000,
.max_uV = 3500000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo10_consumers),
.consumer_supplies = ldo10_consumers,
@@ -682,7 +697,8 @@ struct regulator_init_data wm831x_regulator_init_ldo[WM831X_MAX_LDO] = {
.min_uV = 800000,
.max_uV = 1550000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
},
.num_consumer_supplies = ARRAY_SIZE(ldo11_consumers),
.consumer_supplies = ldo11_consumers,
@@ -777,6 +793,93 @@ out:
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
void wm831x_pmu_early_suspend(struct regulator_dev *rdev)
{
struct regulator *dcdc;
struct regulator *ldo;
printk("%s\n", __func__);
dcdc = regulator_get(NULL, "dcdc4"); //vcc_io
regulator_set_voltage(dcdc, 2800000, 2800000);
regulator_set_mode(dcdc, REGULATOR_MODE_STANDBY);
regulator_enable(dcdc);
printk("%s set dcdc4 vcc_io=%dmV end\n", __func__, regulator_get_voltage(dcdc));
regulator_put(dcdc);
udelay(100);
ldo = regulator_get(NULL, "ldo1"); //
regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo4");
regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo6");
regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo8");
regulator_set_mode(ldo, REGULATOR_MODE_IDLE);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
}
void wm831x_pmu_early_resume(struct regulator_dev *rdev)
{
struct regulator *dcdc;
struct regulator *ldo;
printk("%s\n", __func__);
dcdc = regulator_get(NULL, "dcdc4"); //vcc_io
regulator_set_voltage(dcdc, 3000000, 3000000);
regulator_set_mode(dcdc, REGULATOR_MODE_FAST);
regulator_enable(dcdc);
printk("%s set dcdc4 vcc_io=%dmV end\n", __func__, regulator_get_voltage(dcdc));
regulator_put(dcdc);
udelay(100);
ldo = regulator_get(NULL, "ldo1"); //
regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo4");
regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo6");
regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
ldo = regulator_get(NULL, "ldo8");
regulator_set_mode(ldo, REGULATOR_MODE_NORMAL);
regulator_enable(ldo);
regulator_put(ldo);
udelay(100);
}
#else
void wm831x_pmu_early_suspend(struct regulator_dev *rdev)
{
}
void wm831x_pmu_early_resume(struct regulator_dev *rdev)
{
}
#endif
void __sramfunc board_pmu_wm8326_suspend(void)
{
cru_writel(CRU_CLKGATE5_GRFCLK_ON,CRU_CLKGATE5_CON_ADDR); //open grf clk

View File

@@ -154,6 +154,12 @@
#define RK29_CAM_FLASHACTIVE_H (0x01<<RK29_CAM_FLASHACTIVE_BITPOS)
#define RK29_CAM_FLASHACTIVE_L (0x00<<RK29_CAM_FLASHACTIVE_BITPOS)
#define RK_CAM_SCALE_CROP_ARM 0
#define RK_CAM_SCALE_CROP_IPP 1
#define RK_CAM_SCALE_CROP_RGA 2
#define RK_CAM_SCALE_CROP_PP 3
/* v4l2_subdev_core_ops.ioctl ioctl_cmd macro */
#define RK29_CAM_SUBDEV_ACTIVATE 0x00
#define RK29_CAM_SUBDEV_DEACTIVATE 0x01
@@ -249,6 +255,7 @@ struct rk29camera_platform_ioctl_cb {
typedef struct rk29_camera_sensor_cb {
int (*sensor_cb)(void *arg);
int (*scale_crop_cb)(struct work_struct *work);
}rk29_camera_sensor_cb_s;
#endif /* __ASM_ARCH_CAMERA_H_ */

View File

@@ -38,7 +38,7 @@
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <mach/rk29-ipp.h>
#include <asm/cacheflush.h>
static int debug;
module_param(debug, int, S_IRUGO|S_IWUSR|S_IWGRP);
@@ -160,8 +160,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR|S_IWGRP);
*v0.x.c : fix work queue havn't been finished after close device;
*v0.x.d : fix error when calculate crop left-top point coordinate;
*v0.x.f : fix struct rk29_camera_work may be reentrant.
*v0.x.11: add support zoom by arm;
*/
#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0xf)
#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0x11)
/* limit to rk29 hardware capabilities */
#define RK29_CAM_BUS_PARAM (SOCAM_MASTER |\
@@ -238,6 +239,14 @@ struct rk29_camera_zoominfo
struct v4l2_crop a;
int zoom_rate;
};
#if CAMERA_VIDEOBUF_ARM_ACCESS
struct rk29_camera_vbinfo
{
unsigned int phy_addr;
void __iomem *vir_addr;
unsigned int size;
};
#endif
struct rk29_camera_dev
{
struct soc_camera_host soc_host;
@@ -270,8 +279,13 @@ struct rk29_camera_dev
unsigned long frame_interval;
unsigned int pixfmt;
unsigned int vipmem_phybase;
void __iomem *vipmem_virbase;
unsigned int vipmem_size;
unsigned int vipmem_bsize;
#if CAMERA_VIDEOBUF_ARM_ACCESS
struct rk29_camera_vbinfo *vbinfo;
unsigned int vbinfo_count;
#endif
int host_width;
int host_height;
int icd_width;
@@ -378,6 +392,22 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
}
pcdev->camera_work_count = (*count);
}
#if CAMERA_VIDEOBUF_ARM_ACCESS
if (pcdev->vbinfo && (pcdev->vbinfo_count != *count)) {
kfree(pcdev->vbinfo);
pcdev->vbinfo = NULL;
pcdev->vbinfo_count = 0x00;
}
if (pcdev->vbinfo == NULL) {
pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
if (pcdev->vbinfo == NULL) {
RK29CAMERA_TR("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
BUG();
}
pcdev->vbinfo_count = *count;
}
#endif
}
RK29CAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
@@ -498,7 +528,8 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq,
struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct rk29_camera_dev *pcdev = ici->priv;
struct rk29_camera_vbinfo *vb_info;
dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
vb, vb->baddr, vb->bsize);
@@ -512,6 +543,31 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq,
else
BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */
}
#if CAMERA_VIDEOBUF_ARM_ACCESS
if (pcdev->vbinfo) {
vb_info = pcdev->vbinfo+vb->i;
if ((vb_info->phy_addr != vb->boff) || (vb_info->size != vb->bsize)) {
if (vb_info->vir_addr) {
iounmap(vb_info->vir_addr);
release_mem_region(vb_info->phy_addr, vb_info->size);
vb_info->vir_addr = NULL;
vb_info->phy_addr = 0x00;
vb_info->size = 0x00;
}
if (request_mem_region(vb->boff,vb->bsize,"rk29_camera_vb")) {
vb_info->vir_addr = ioremap_cached(vb->boff,vb->bsize);
}
if (vb_info->vir_addr) {
vb_info->size = vb->bsize;
vb_info->phy_addr = vb->boff;
} else {
RK29CAMERA_TR("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
}
}
}
#endif
if (!pcdev->active) {
pcdev->active = vb;
rk29_videobuf_capture(vb);
@@ -541,7 +597,8 @@ static int rk29_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
rk29_pixfmt2ippfmt_err:
return -1;
}
static void rk29_camera_capture_process(struct work_struct *work)
#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
static int rk29_camera_scale_crop_ipp(struct work_struct *work)
{
struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
struct videobuf_buffer *vb = camera_work->vb;
@@ -550,7 +607,8 @@ static void rk29_camera_capture_process(struct work_struct *work)
unsigned long int flags;
int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
int scale_times,w,h,vipdata_base;
int ret = 0;
/*
*ddl@rock-chips.com:
* IPP Dest image resolution is 2047x1088, so scale operation break up some times
@@ -564,8 +622,6 @@ static void rk29_camera_capture_process(struct work_struct *work)
memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
down(&pcdev->zoominfo.sem);
ipp_req.timeout = 100;
ipp_req.flag = IPP_ROT_0;
ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
@@ -614,21 +670,170 @@ static void rk29_camera_capture_process(struct work_struct *work)
RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
goto do_ipp_err;
goto rk29_camera_scale_crop_ipp_end;
}
}
}
rk29_camera_scale_crop_ipp_end:
return ret;
}
#endif
#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
static int rk29_camera_scale_crop_arm(struct work_struct *work)
{
struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
struct videobuf_buffer *vb = camera_work->vb;
struct rk29_camera_dev *pcdev = camera_work->pcdev;
struct rk29_camera_vbinfo *vb_info;
unsigned char *psY,*pdY,*psUV,*pdUV;
unsigned char *src,*dst;
unsigned long src_phy,dst_phy;
int srcW,srcH,cropW,cropH,dstW,dstH;
long zoomindstxIntInv,zoomindstyIntInv;
long x,y;
long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
long sX,sY;
long r0,r1,a,b,c,d;
int ret = 0;
if (pcdev->icd_cb.sensor_cb)
(pcdev->icd_cb.sensor_cb)(vb);
do_ipp_err:
up(&pcdev->zoominfo.sem);
wake_up(&(camera_work->vb->done));
spin_lock_irqsave(&pcdev->camera_work_lock, flags);
list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
return;
src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
psUV = psY + pcdev->host_width*pcdev->host_height;
srcW = pcdev->host_width;
srcH = pcdev->host_height;
cropW = pcdev->zoominfo.a.c.width;
cropH = pcdev->zoominfo.a.c.height;
psY = psY + pcdev->host_width - pcdev->zoominfo.a.c.width;
psUV = psUV + pcdev->host_width - pcdev->zoominfo.a.c.width;
vb_info = pcdev->vbinfo+vb->i;
dst_phy = vb_info->phy_addr;
dst = pdY = (unsigned char*)vb_info->vir_addr;
pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
dstW = pcdev->icd->user_width;
dstH = pcdev->icd->user_height;
zoomindstxIntInv = ((unsigned long)cropW<<16)/dstW + 1;
zoomindstyIntInv = ((unsigned long)cropH<<16)/dstH + 1;
//y
//for(y = 0; y<dstH - 1 ; y++ ) {
for(y = 0; y<dstH; y++ ) {
yCoeff00 = (y*zoomindstyIntInv)&0xffff;
yCoeff01 = 0xffff - yCoeff00;
sY = (y*zoomindstyIntInv >> 16);
for(x = 0; x<dstW; x++ ) {
xCoeff00 = (x*zoomindstxIntInv)&0xffff;
xCoeff01 = 0xffff - xCoeff00;
sX = (x*zoomindstxIntInv >> 16);
a = psY[sY*srcW + sX];
b = psY[sY*srcW + sX + 1];
c = psY[(sY+1)*srcW + sX];
d = psY[(sY+1)*srcW + sX + 1];
r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
pdY[x] = r0;
}
pdY += dstW;
}
dstW /= 2;
dstH /= 2;
srcW /= 2;
srcH /= 2;
//UV
//for(y = 0; y<dstH - 1 ; y++ ) {
for(y = 0; y<dstH; y++ ) {
yCoeff00 = (y*zoomindstyIntInv)&0xffff;
yCoeff01 = 0xffff - yCoeff00;
sY = (y*zoomindstyIntInv >> 16);
for(x = 0; x<dstW; x++ ) {
xCoeff00 = (x*zoomindstxIntInv)&0xffff;
xCoeff01 = 0xffff - xCoeff00;
sX = (x*zoomindstxIntInv >> 16);
//U
a = psUV[(sY*srcW + sX)*2];
b = psUV[(sY*srcW + sX + 1)*2];
c = psUV[((sY+1)*srcW + sX)*2];
d = psUV[((sY+1)*srcW + sX + 1)*2];
r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
pdUV[x*2] = r0;
//V
a = psUV[(sY*srcW + sX)*2 + 1];
b = psUV[(sY*srcW + sX + 1)*2 + 1];
c = psUV[((sY+1)*srcW + sX)*2 + 1];
d = psUV[((sY+1)*srcW + sX + 1)*2 + 1];
r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
pdUV[x*2 + 1] = r0;
}
pdUV += dstW*2;
}
rk29_camera_scale_crop_arm_end:
dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
return ret;
}
#endif
static void rk29_camera_capture_process(struct work_struct *work)
{
struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work);
struct videobuf_buffer *vb = camera_work->vb;
struct rk29_camera_dev *pcdev = camera_work->pcdev;
//enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;
unsigned long flags = 0;
int err = 0;
if (!CAM_WORKQUEUE_IS_EN())
goto rk29_camera_capture_process_end;
down(&pcdev->zoominfo.sem);
if (pcdev->icd_cb.scale_crop_cb)
err = (pcdev->icd_cb.scale_crop_cb)(work);
up(&pcdev->zoominfo.sem);
if (pcdev->icd_cb.sensor_cb)
(pcdev->icd_cb.sensor_cb)(vb);
rk29_camera_capture_process_end:
if (err) {
vb->state = VIDEOBUF_ERROR;
} else {
if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
vb->state = VIDEOBUF_DONE;
vb->field_count++;
}
}
wake_up(&(camera_work->vb->done));
spin_lock_irqsave(&pcdev->camera_work_lock, flags);
list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);
return;
}
static irqreturn_t rk29_camera_irq(int irq, void *data)
{
@@ -680,13 +885,8 @@ static irqreturn_t rk29_camera_irq(int irq, void *data)
if (pcdev->active == NULL) {
RK29CAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
}
if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
vb->state = VIDEOBUF_DONE;
do_gettimeofday(&vb->ts);
vb->field_count++;
}
do_gettimeofday(&vb->ts);
if (CAM_WORKQUEUE_IS_EN()) {
if (!list_empty(&pcdev->camera_work_queue)) {
wk = list_entry(pcdev->camera_work_queue.next, struct rk29_camera_work, queue);
@@ -697,6 +897,10 @@ static irqreturn_t rk29_camera_irq(int irq, void *data)
queue_work(pcdev->camera_wq, &(wk->work));
}
} else {
if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
vb->state = VIDEOBUF_DONE;
vb->field_count++;
}
wake_up(&vb->done);
}
}
@@ -713,6 +917,8 @@ static void rk29_videobuf_release(struct videobuf_queue *vq,
struct soc_camera_device *icd = vq->priv_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct rk29_camera_dev *pcdev = ici->priv;
struct rk29_camera_vbinfo *vb_info =NULL;
#ifdef DEBUG
dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
@@ -732,17 +938,26 @@ static void rk29_videobuf_release(struct videobuf_queue *vq,
dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
break;
}
#endif
if(vb->i == 0){
flush_workqueue(pcdev->camera_wq);
}
#endif
if (vb == pcdev->active) {
RK29CAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
flush_workqueue(pcdev->camera_wq);
RK29CAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
}
flush_workqueue(pcdev->camera_wq);
#if CAMERA_VIDEOBUF_ARM_ACCESS
if (pcdev->vbinfo) {
vb_info = pcdev->vbinfo + vb->i;
if (vb_info->vir_addr) {
iounmap(vb_info->vir_addr);
release_mem_region(vb_info->phy_addr, vb_info->size);
memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
}
}
#endif
rk29_videobuf_free(vq, buf);
}
@@ -961,7 +1176,9 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct rk29_camera_dev *pcdev = ici->priv;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct rk29_camera_vbinfo *vb_info;
unsigned int i;
mutex_lock(&camera_lock);
BUG_ON(icd != pcdev->icd);
@@ -982,7 +1199,22 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
pcdev->camera_work_count = 0;
INIT_LIST_HEAD(&pcdev->camera_work_queue);
}
#if CAMERA_VIDEOBUF_ARM_ACCESS
if (pcdev->vbinfo) {
vb_info = pcdev->vbinfo;
for (i=0; i<pcdev->vbinfo_count; i++) {
if (vb_info->vir_addr) {
iounmap(vb_info->vir_addr);
release_mem_region(vb_info->phy_addr, vb_info->size);
memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
}
vb_info++;
}
kfree(pcdev->vbinfo);
pcdev->vbinfo = NULL;
pcdev->vbinfo_count = 0;
}
#endif
pcdev->active = NULL;
pcdev->icd = NULL;
pcdev->icd_cb.sensor_cb = NULL;
@@ -2053,8 +2285,8 @@ static int rk29_camera_probe(struct platform_device *pdev)
int irq,i;
int err = 0;
RK29CAMERA_TR("RK29 Camera driver version: v%d.%d.%d\n",(RK29_CAM_VERSION_CODE&0xff0000)>>16,
(RK29_CAM_VERSION_CODE&0xff00)>>8,RK29_CAM_VERSION_CODE&0xff);
RK29CAMERA_TR("RK29 Camera driver version: v%d.%d.%d Zoom by %s\n",(RK29_CAM_VERSION_CODE&0xff0000)>>16,
(RK29_CAM_VERSION_CODE&0xff00)>>8,RK29_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
@@ -2117,11 +2349,24 @@ static int rk29_camera_probe(struct platform_device *pdev)
if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) {
pcdev->vipmem_phybase = pcdev->pdata->meminfo.start;
pcdev->vipmem_size = pcdev->pdata->meminfo.size;
if (!request_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size,"rk29_vipmem")) {
err = -EBUSY;
goto exit_ioremap_vipmem;
}
pcdev->vipmem_virbase = ioremap_cached(pcdev->vipmem_phybase,pcdev->vipmem_size);
if (pcdev->vipmem_virbase == NULL) {
dev_err(pcdev->dev, "ioremap() of vip internal memory(Ex:IPP process/raw process) failed\n");
err = -ENXIO;
goto exit_ioremap_vipmem;
}
RK29CAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
} else {
RK29CAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__);
pcdev->vipmem_phybase = 0;
pcdev->vipmem_size = 0;
pcdev->vipmem_virbase = 0;
}
#endif
INIT_LIST_HEAD(&pcdev->capture);
@@ -2183,6 +2428,11 @@ static int rk29_camera_probe(struct platform_device *pdev)
pcdev->fps_timer.function = rk29_camera_fps_func;
pcdev->icd_cb.sensor_cb = NULL;
#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
pcdev->icd_cb.scale_crop_cb = rk29_camera_scale_crop_ipp;
#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
pcdev->icd_cb.scale_crop_cb = rk29_camera_scale_crop_arm;
#endif
RK29CAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__);
return 0;
@@ -2207,6 +2457,10 @@ exit_reqirq:
iounmap(pcdev->base);
exit_ioremap:
release_mem_region(res->start, res->end - res->start + 1);
exit_ioremap_vipmem:
if (pcdev->vipmem_virbase)
iounmap(pcdev->vipmem_virbase);
release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
exit_reqmem:
if (pcdev->aclk_ddr_lcdc) {
clk_put(pcdev->aclk_ddr_lcdc);
@@ -2277,6 +2531,9 @@ static int __devexit rk29_camera_remove(struct platform_device *pdev)
soc_camera_host_unregister(&pcdev->soc_host);
iounmap((void __iomem*)pcdev->vipmem_phybase);
release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
res = pcdev->res;
release_mem_region(res->start, res->end - res->start + 1);

View File

@@ -29,6 +29,11 @@
#include <linux/mfd/wm831x/pmu.h>
#include <mach/board.h>
#include <linux/earlysuspend.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct early_suspend wm831x_early_suspend;
#endif
/* Current settings - values are 2*2^(reg_val/4) microamps. These are
* exported since they are used by multiple drivers.
@@ -1465,6 +1470,10 @@ static struct mfd_cell backlight_devs[] = {
/*
* Instantiate the generic non-control parts of the device.
*/
__weak void wm831x_pmu_early_suspend(struct regulator_dev *rdev) {}
__weak void wm831x_pmu_early_resume(struct regulator_dev *rdev) {}
int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
{
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -1729,7 +1738,13 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
goto err_irq;
}
}
#ifdef CONFIG_HAS_EARLYSUSPEND
wm831x_early_suspend.level = 0xffff;
wm831x_early_suspend.suspend = wm831x_pmu_early_suspend;
wm831x_early_suspend.resume = wm831x_pmu_early_resume;
register_early_suspend(&wm831x_early_suspend);
#endif
return 0;
err_irq:

View File

@@ -206,7 +206,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
int ret;
printk("%s base=%x,mode=%x\n", __FUNCTION__,ldo->base,mode);
// printk("%s base=%x,mode=%x\n", __FUNCTION__,ldo->base,mode);
switch (mode) {
case REGULATOR_MODE_NORMAL:
ret = wm831x_set_bits(wm831x, on_reg,

View File

@@ -731,6 +731,16 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo
#endif
#ifdef CONFIG_ARCH_RK2928 //@lyz the same with RK30
/* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 ); //ep0 tx fifo
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 ); //ep1 tx fifo 256*4Byte
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 ); //ep3 tx fifo 128*4Byte
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo 128*4Byte
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo 128*4Byte
dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo 16*4Byte
#endif
if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
{

View File

@@ -1203,6 +1203,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
#ifdef CONFIG_ARCH_RK30
unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2);
#endif
#ifdef CONFIG_ARCH_RK2928
unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5);
#endif
#ifdef CONFIG_ARCH_RK29
regval = * otg_phy_con1;
@@ -1291,6 +1294,35 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
clk_disable(phyclk);
clk_disable(ahbclk);
#endif
#endif
//need to be checked @wlf
#ifdef CONFIG_ARCH_RK2928
#ifndef CONFIG_USB20_HOST
otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON5);
/*
* disable usb host 2.0 phy if not support
*/
phyclk = clk_get(NULL, "otgphy1");
if (IS_ERR(phyclk)) {
retval = PTR_ERR(phyclk);
DWC_ERROR("can't get USBPHY1 clock\n");
goto fail;
}
clk_enable(phyclk);
ahbclk = clk_get(NULL, "hclk_otg1");
if (IS_ERR(ahbclk)) {
retval = PTR_ERR(ahbclk);
DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
goto fail;
}
clk_enable(ahbclk);
*otg_phy_con = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend.
udelay(3);
clk_disable(phyclk);
clk_disable(ahbclk);
#endif
#endif
dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
@@ -1385,6 +1417,42 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
dwc_otg_device->phyclk = phyclk;
dwc_otg_device->ahbclk = ahbclk;
#endif
//need to be checked @wlf
#if 0//def CONFIG_ARCH_RK2928
otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5);
cru_set_soft_reset(SOFT_RST_USBPHY0, true);
cru_set_soft_reset(SOFT_RST_OTGC0, true);
cru_set_soft_reset(SOFT_RST_USBOTG0, true);
udelay(1);
cru_set_soft_reset(SOFT_RST_USBOTG0, false);
cru_set_soft_reset(SOFT_RST_OTGC0, false);
cru_set_soft_reset(SOFT_RST_USBPHY0, false);
phyclk = clk_get(NULL, "otgphy0");
if (IS_ERR(phyclk)) {
retval = PTR_ERR(phyclk);
DWC_ERROR("can't get USBPHY0 clock\n");
goto fail;
}
clk_enable(phyclk);
ahbclk = clk_get(NULL, "hclk_otg0");
if (IS_ERR(ahbclk)) {
retval = PTR_ERR(ahbclk);
DWC_ERROR("can't get USB otg0 ahb bus clock\n");
goto fail;
}
clk_enable(ahbclk);
/*
* Enable usb phy 0
*/
*otg_phy_con = (0x01<<16);
dwc_otg_device->phyclk = phyclk;
dwc_otg_device->ahbclk = ahbclk;
#endif
/*
* Map the DWC_otg Core memory into virtual address space.
*/
@@ -1519,6 +1587,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
#endif
#ifdef CONFIG_ARCH_RK30
USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);
#endif
#ifdef CONFIG_ARCH_RK2928
USB_IOMUX_INIT(GPIO3C1_OTG_DRVVBUS_NAME, GPIO3C_OTG_DRVVBUS);
#endif
/*
* Initialize the HCD
@@ -2057,7 +2128,10 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);
*otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.
#endif
#ifdef CONFIG_ARCH_RK2928
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5);
*otg_phy_con1 = (0x01<<16); // exit suspend.
#endif
#if 0
*otg_phy_con1 |= (0x01<<2);
*otg_phy_con1 |= (0x01<<3); // exit suspend.
@@ -2084,6 +2158,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
#ifdef CONFIG_ARCH_RK30
*(unsigned int*)(USBGRF_UOC1_CON2+4) = ((1<<5)|((1<<5)<<16));
#endif
#ifdef CONFIG_ARCH_RK2928
*(unsigned int*)(USBGRF_UOC1_CON5-4) = ((1<<5)|((1<<5)<<16));
#endif
if (dwc_otg_device == 0)
{
dev_err(dev, "kmalloc of dwc_otg_device failed\n");
@@ -2108,6 +2185,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
#ifdef CONFIG_ARCH_RK30
ahbclk = clk_get(NULL, "hclk_otg1");
#endif
#ifdef CONFIG_ARCH_RK2928
ahbclk = clk_get(NULL, "hclk_otg1"); //need to be checked @wlf
#endif
if (IS_ERR(ahbclk)) {
retval = PTR_ERR(ahbclk);
DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
@@ -2213,15 +2293,6 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
#endif
#ifdef CONFIG_ARCH_RK30
USB_IOMUX_INIT(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);
#ifdef CONFIG_MACH_RK30_DS1001B
USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_GPIO0A5);
if(gpio_request(RK30_PIN0_PA5,"host_drv")<0){
DWC_ERROR("request of host power control failed\n");
gpio_free(RK30_PIN0_PA5);
}
gpio_direction_output(RK30_PIN0_PA5, GPIO_HIGH);
gpio_set_value(RK30_PIN0_PA5, GPIO_HIGH);
#endif
#endif
/*
* Initialize the DWC_otg core.
@@ -2246,9 +2317,15 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
#ifndef CONFIG_USB20_HOST_EN
clk_disable(phyclk);
clk_disable(ahbclk);
#if defined(CONFIG_ARCH_RK29)
otgreg &= ~(0x01<<14); // suspend.
otgreg |= (0x01<<13); // software control
otgreg |= (0x01<<13); // software control enable
*otg_phy_con1 = otgreg;
#elif defined(CONFIG_ARCH_RK30)
*otg_phy_con1 = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend.
#elif defined(CONFIG_ARCH_RK2928)
*otg_phy_con1 = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend.
#endif
#endif
return 0;

View File

@@ -69,8 +69,10 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
return 0;
}
hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
#ifdef CONFIG_USB_SUSPEND
if((!dwc_otg_hcd->host_enabled)||(!hprt0.b.prtena))
return 0;
#endif
DWC_PRINT("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
if(hprt0.b.prtconnsts) // usb device connected
{
@@ -128,8 +130,10 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
DWC_PRINT("%s, usb device mode\n", __func__);
return 0;
}
#ifdef CONFIG_USB_SUSPEND
if(!dwc_otg_hcd->host_enabled)
return 0;
#endif
#ifndef CONFIG_DWC_REMOTE_WAKEUP
clk_enable(core_if->otg_dev->phyclk);
clk_enable(core_if->otg_dev->ahbclk);
@@ -149,8 +153,10 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
#ifdef CONFIG_USB_SUSPEND
if(!hprt0.b.prtena)
return 0;
#endif
DWC_PRINT("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
if(hprt0.b.prtconnsts)
{
@@ -617,6 +623,24 @@ static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend)
udelay(3);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
#if 0//def CONFIG_ARCH_RK2928
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
if(exitsuspend && (pcd->phy_suspend == 1)) {
clk_enable(pcd->otg_dev->ahbclk);
clk_enable(pcd->otg_dev->phyclk);
pcd->phy_suspend = 0;
*otg_phy_con1 = (0x01<<16); // exit suspend.
DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
}
if( !exitsuspend && (pcd->phy_suspend == 0)) {
pcd->phy_suspend = 1;
*otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend.
udelay(3);
clk_disable(pcd->otg_dev->phyclk);
clk_disable(pcd->otg_dev->ahbclk);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
return suspend;
}
@@ -663,7 +687,7 @@ static struct tasklet_struct reset_tasklet = {
.func = reset_tasklet_func,
.data = 0,
};
#ifdef CONFIG_ARCH_RK30
#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)
static void dwc_otg_hcd_enable(struct work_struct *work)
{
dwc_otg_hcd_t *dwc_otg_hcd;
@@ -721,7 +745,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
local_irq_save(flags);
// DWC_PRINT("%s hprt %x, grfstatus 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
#ifdef CONFIG_ARCH_RK30
if(usbgrf_status & (7<<22)){
#else //CONFIG_ARCH_RK2928
if(usbgrf_status & (7<<12)){
#endif
// usb device connected
dwc_otg_hcd->host_setenable = 1;
}
@@ -732,7 +760,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
}
if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){
DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
#ifdef CONFIG_ARCH_RK30
DWC_PRINT("%s schedule delaywork 0x%x, 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
#else //CONFIG_ARCH_RK2928
DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<12));
#endif
schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 8);
}
// dwc_otg_hcd->connect_detect_timer.expires = jiffies + (HZ<<1); /* 1 s */
@@ -1116,6 +1148,24 @@ static int32_t host20_phy_suspend_cb( void *_p, int suspend)
udelay(3);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
#if 0//def CONFIG_ARCH_RK2928
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
if(exitsuspend && (pcd->phy_suspend == 1)) {
clk_enable(pcd->otg_dev->ahbclk);
clk_enable(pcd->otg_dev->phyclk);
pcd->phy_suspend = 0;
*otg_phy_con1 = (0x01<<16); // exit suspend.
DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
}
if( !exitsuspend && (pcd->phy_suspend == 0)) {
pcd->phy_suspend = 1;
*otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend.
udelay(3);
clk_disable(pcd->otg_dev->phyclk);
clk_disable(pcd->otg_dev->ahbclk);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
return suspend;
}
@@ -1266,7 +1316,7 @@ int __devinit host20_hcd_init(struct device *dev)
goto error3;
}
#ifdef CONFIG_ARCH_RK30
#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)
dwc_otg_hcd->host_setenable = 1;
dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);

View File

@@ -189,7 +189,7 @@ void request_nuke( dwc_otg_pcd_ep_t *_ep )
* This function assigns periodic Tx FIFO to an periodic EP
* in shared Tx FIFO mode
*/
#ifdef CONFIG_ARCH_RK30
#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
{
uint32_t PerTxMsk = 1;
@@ -218,7 +218,7 @@ static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
* This function assigns periodic Tx FIFO to an periodic EP
* in Dedicated FIFOs mode
*/
#ifdef CONFIG_ARCH_RK30
#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
{
uint32_t TxMsk = 1;
@@ -304,7 +304,7 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep,
if(ep->dwc_ep.is_in)
{
#ifndef CONFIG_ARCH_RK29
#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
if(!pcd->otg_dev->core_if->en_multiple_tx_fifo)
{
ep->dwc_ep.tx_fifo_num = 0;
@@ -1497,6 +1497,10 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
* EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default
*/
#ifdef CONFIG_ARCH_RK30
if(i == 8)
continue;
#endif
#ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
if(i == 8)
continue;
#endif
@@ -1558,6 +1562,10 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
* EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default
*/
#ifdef CONFIG_ARCH_RK30
if(i == 9)
continue;
#endif
#ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
if(i == 9)
continue;
#endif
@@ -1663,7 +1671,25 @@ int dwc_otg20phy_suspend( int exitsuspend )
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
#ifdef CONFIG_ARCH_RK2928
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
if(exitsuspend && (pcd->phy_suspend == 1)) {
clk_enable(pcd->otg_dev->ahbclk);
clk_enable(pcd->otg_dev->phyclk);
pcd->phy_suspend = 0;
*otg_phy_con1 = (0x01<<16); // exit suspend.
DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
}
if( !exitsuspend && (pcd->phy_suspend == 0)) {
pcd->phy_suspend = 1;
*otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend.
// *otg_phy_con1 = 0x1D5 |(0x1ff<<16); // enter suspend. enable dm,dp debug_wlf @2012.8.10
udelay(3);
clk_disable(pcd->otg_dev->phyclk);
clk_disable(pcd->otg_dev->ahbclk);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
#endif
return pcd->phy_suspend;
}
@@ -1873,6 +1899,69 @@ connect:
return;
}
#endif
#ifdef CONFIG_ARCH_RK2928
static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
{
dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
unsigned long flags;
unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0<53><EFBFBD>б<EFBFBD>
local_irq_save(flags);
_pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
if((usbgrf_status &(1<<10)) == 0){ // id low //@lyz SOC_STATUS0[10] represents id_dig
if( _pcd->phy_suspend)
dwc_otg20phy_suspend( 1 );
}
else if(usbgrf_status & (1<<7)){ //@lyz SOC_STATUS0[7] represents bvalid
/* if usb not connect before ,then start connect */
if( _pcd->vbus_status == 0 ) {
DWC_PRINT("********vbus detect*********************************************\n");
dwc_otg_msc_lock(_pcd);
_pcd->vbus_status = 1;
if(_pcd->conn_en)
goto connect;
else
dwc_otg20phy_suspend( 0 );
}
else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
DWC_PRINT("********soft reconnect******************************************\n");
goto connect;
}
else if(_pcd->conn_status ==3){
//*<2A><><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>ʱ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˯<EFBFBD>ߣ<EFBFBD>yk@rk,20100331*//
dwc_otg_msc_unlock(_pcd);
_pcd->conn_status++;
if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
_pcd->vbus_status = 2;
}
}else {
_pcd->vbus_status = 0;
if(_pcd->conn_status)
{
_pcd->conn_status = 0;
dwc_otg_msc_unlock(_pcd);
}
/* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
if( _pcd->phy_suspend == 0 )
/* no vbus detect here , close usb phy */
dwc_otg20phy_suspend( 0 );
}
add_timer(&_pcd->check_vbus_timer);
local_irq_restore(flags);
return;
connect:
if( _pcd->phy_suspend == 1 )
dwc_otg20phy_suspend( 1 );
schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
_pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
add_timer(&_pcd->check_vbus_timer);
local_irq_restore(flags);
return;
}
#endif
#ifdef CONFIG_ARCH_RK29
/*
@@ -1980,6 +2069,56 @@ out:
return bus_status;
}
EXPORT_SYMBOL(dwc_otg_check_dpdm);
#endif
#ifdef CONFIG_ARCH_RK2928
int dwc_otg_check_dpdm(void)
{
static uint8_t * reg_base = 0;
volatile unsigned int * otg_dctl;
volatile unsigned int * otg_gotgctl;
volatile unsigned int * otg_hprt0;
int bus_status = 0;
unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5
// softreset & clockgate //@lyz modify RK2928_CRU_BASE
*(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5); // otg0 phy clkgate
udelay(3);
*(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5); // otg0 phy clkgate
dsb();
*(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16); // otg0 phy clkgate
*(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16); // otg0 hclk clkgate
*(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16); // hclk usb clkgate//@lyz to be check
// exit phy suspend
*otg_phy_con1 = ((0x01<<0)<<16); // exit suspend.@lyz
// soft connect
if(reg_base == 0){
reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz
if(!reg_base){
bus_status = -1;
goto out;
}
}
mdelay(105);
printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
otg_dctl = (unsigned int * )(reg_base+0x804);
otg_gotgctl = (unsigned int * )(reg_base);
otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
if(*otg_gotgctl &(1<<19)){
bus_status = 1;
*otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode
mdelay(50); // delay about 10ms
// check dp,dm
if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10]
bus_status = 2;
}
out:
return bus_status;
}
EXPORT_SYMBOL(dwc_otg_check_dpdm);
#endif
void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd )

View File

@@ -67,6 +67,15 @@
#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
#endif
#ifdef CONFIG_ARCH_RK2928
#include <mach/iomux.h>
#define GRF_REG_BASE RK2928_GRF_BASE
#define USBOTG_SIZE RK2928_USBOTG20_SIZE
#define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0x14c)
#define USBGRF_UOC0_CON5 (GRF_REG_BASE+0x17c)
#define USBGRF_UOC1_CON5 (GRF_REG_BASE+0x194)
#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
#endif
/**
* @file
*