Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: Staging: dream: remove dream driver and arch from tree
This commit is contained in:
commit
d56f84e7e3
|
@ -87,8 +87,6 @@ source "drivers/staging/rtl8712/Kconfig"
|
|||
|
||||
source "drivers/staging/frontier/Kconfig"
|
||||
|
||||
source "drivers/staging/dream/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
|
||||
source "drivers/staging/autofs/Kconfig"
|
||||
|
|
|
@ -28,7 +28,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/
|
|||
obj-$(CONFIG_R8712U) += rtl8712/
|
||||
obj-$(CONFIG_SPECTRA) += spectra/
|
||||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_DREAM) += dream/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
obj-$(CONFIG_AUTOFS_FS) += autofs/
|
||||
obj-$(CONFIG_IDE_PHISON) += phison/
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
config DREAM
|
||||
tristate "HTC Dream support"
|
||||
depends on MACH_TROUT
|
||||
|
||||
if DREAM
|
||||
|
||||
source "drivers/staging/dream/camera/Kconfig"
|
||||
|
||||
config INPUT_GPIO
|
||||
tristate "GPIO driver support"
|
||||
help
|
||||
Say Y here if you want to support gpio based keys, wheels etc...
|
||||
endif
|
|
@ -1,5 +0,0 @@
|
|||
ccflags-y:=-Idrivers/staging/dream/include
|
||||
obj-$(CONFIG_MSM_ADSP) += qdsp5/
|
||||
obj-$(CONFIG_MSM_CAMERA) += camera/
|
||||
obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
* camera driver uses old V4L API
|
||||
|
||||
* coding style in some places is lacking
|
||||
|
||||
* gpio_input.c has some features matrix_keypad lacks. They should be
|
||||
merged to gpio_input, with gpio_input.c removed
|
||||
|
||||
* pmem provides interface for userspace. Needs to be reviewed at least.
|
||||
|
||||
* it is probably possible to simplify touchscreen driver using threaded_irq's.
|
||||
|
||||
* touchscreen driver should be switched to oficial multitouch API
|
|
@ -1,46 +0,0 @@
|
|||
comment "Qualcomm MSM Camera And Video"
|
||||
|
||||
menuconfig MSM_CAMERA
|
||||
bool "Qualcomm MSM camera and video capture support"
|
||||
depends on ARCH_MSM && VIDEO_V4L2_COMMON
|
||||
help
|
||||
Say Y here to enable selecting the video adapters for
|
||||
Qualcomm msm camera and video encoding
|
||||
|
||||
config MSM_CAMERA_DEBUG
|
||||
bool "Qualcomm MSM camera debugging with printk"
|
||||
depends on MSM_CAMERA
|
||||
help
|
||||
Enable printk() debug for msm camera
|
||||
|
||||
config MSM_CAMERA_FLASH
|
||||
bool "Qualcomm MSM camera flash support"
|
||||
depends on MSM_CAMERA && BROKEN
|
||||
---help---
|
||||
Enable support for LED flash for msm camera
|
||||
|
||||
|
||||
comment "Camera Sensor Selection"
|
||||
config MT9T013
|
||||
bool "Sensor mt9t013 (BAYER 3M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 3M Bayer Sensor with AutoFocus
|
||||
|
||||
config MT9D112
|
||||
bool "Sensor mt9d112 (YUV 2M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 2M YUV Sensor
|
||||
|
||||
config MT9P012
|
||||
bool "Sensor mt9p012 (BAYER 5M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 5M Bayer Sensor with Autofocus
|
||||
|
||||
config S5K3E2FX
|
||||
bool "Sensor s5k3e2fx (Samsung 5M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
Samsung 5M with Autofocus
|
|
@ -1,8 +0,0 @@
|
|||
ccflags-y:=-Idrivers/staging/dream/include
|
||||
obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
|
||||
obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
|
||||
obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
|
||||
obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o
|
||||
obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
|
||||
obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o
|
||||
obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
|
File diff suppressed because it is too large
Load Diff
|
@ -1,291 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM Incorporated
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
#define CAMIF_CFG_RMSK 0x1fffff
|
||||
#define CAM_SEL_BMSK 0x2
|
||||
#define CAM_PCLK_SRC_SEL_BMSK 0x60000
|
||||
#define CAM_PCLK_INVERT_BMSK 0x80000
|
||||
#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
|
||||
#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
|
||||
#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
|
||||
|
||||
#define CAM_SEL_SHFT 0x1
|
||||
#define CAM_PCLK_SRC_SEL_SHFT 0x11
|
||||
#define CAM_PCLK_INVERT_SHFT 0x13
|
||||
#define CAM_PAD_REG_SW_RESET_SHFT 0x14
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
|
||||
#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
|
||||
#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
|
||||
#define APPS_RESET_OFFSET 0x00000210
|
||||
|
||||
static struct clk *camio_vfe_mdc_clk;
|
||||
static struct clk *camio_mdc_clk;
|
||||
static struct clk *camio_vfe_clk;
|
||||
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
extern int clk_set_flags(struct clk *clk, unsigned long flags);
|
||||
|
||||
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = -1;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_enable(clk);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = -1;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_disable(clk);
|
||||
clk_put(clk);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_clk_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_clk;
|
||||
|
||||
if (clk != ERR_PTR(-ENOENT))
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_enable(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camio_ext = camdev->ioext;
|
||||
|
||||
appio = request_mem_region(camio_ext.appphy,
|
||||
camio_ext.appsz, pdev->name);
|
||||
if (!appio) {
|
||||
rc = -EBUSY;
|
||||
goto enable_fail;
|
||||
}
|
||||
|
||||
appbase = ioremap(camio_ext.appphy,
|
||||
camio_ext.appsz);
|
||||
if (!appbase) {
|
||||
rc = -ENOMEM;
|
||||
goto apps_no_mem;
|
||||
}
|
||||
|
||||
mdcio = request_mem_region(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz, pdev->name);
|
||||
if (!mdcio) {
|
||||
rc = -EBUSY;
|
||||
goto mdc_busy;
|
||||
}
|
||||
|
||||
mdcbase = ioremap(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz);
|
||||
if (!mdcbase) {
|
||||
rc = -ENOMEM;
|
||||
goto mdc_no_mem;
|
||||
}
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
|
||||
msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_enable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
return 0;
|
||||
|
||||
mdc_no_mem:
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
mdc_busy:
|
||||
iounmap(appbase);
|
||||
apps_no_mem:
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
enable_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_disable(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
iounmap(mdcbase);
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
iounmap(appbase);
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
|
||||
msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_disable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
/* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
|
||||
mask = CAM_SEL_BMSK |
|
||||
CAM_PCLK_SRC_SEL_BMSK |
|
||||
CAM_PCLK_INVERT_BMSK;
|
||||
|
||||
value = 1 << CAM_SEL_SHFT |
|
||||
3 << CAM_PCLK_SRC_SEL_SHFT |
|
||||
0 << CAM_PCLK_INVERT_SHFT;
|
||||
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_vfe_blk_reset(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val |= 0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val &= ~0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset_2(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
|
||||
{
|
||||
struct clk *clk = NULL;
|
||||
|
||||
clk = camio_vfe_clk;
|
||||
|
||||
if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
|
||||
switch (srctype) {
|
||||
case MSM_CAMIO_CLK_SRC_INTERNAL:
|
||||
clk_set_flags(clk, 0x00000100 << 1);
|
||||
break;
|
||||
|
||||
case MSM_CAMIO_CLK_SRC_EXTERNAL:
|
||||
clk_set_flags(clk, 0x00000100);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int msm_camio_probe_on(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
camdev->camera_gpio_on();
|
||||
return msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
}
|
||||
|
||||
int msm_camio_probe_off(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
camdev->camera_gpio_off();
|
||||
return msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
}
|
|
@ -1,320 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM Incorporated
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
#define CAMIF_CFG_RMSK 0x1fffff
|
||||
#define CAM_SEL_BMSK 0x2
|
||||
#define CAM_PCLK_SRC_SEL_BMSK 0x60000
|
||||
#define CAM_PCLK_INVERT_BMSK 0x80000
|
||||
#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
|
||||
#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
|
||||
#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
|
||||
|
||||
#define CAM_SEL_SHFT 0x1
|
||||
#define CAM_PCLK_SRC_SEL_SHFT 0x11
|
||||
#define CAM_PCLK_INVERT_SHFT 0x13
|
||||
#define CAM_PAD_REG_SW_RESET_SHFT 0x14
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
|
||||
#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
|
||||
#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
|
||||
#define APPS_RESET_OFFSET 0x00000210
|
||||
|
||||
static struct clk *camio_vfe_mdc_clk;
|
||||
static struct clk *camio_mdc_clk;
|
||||
static struct clk *camio_vfe_clk;
|
||||
static struct clk *camio_vfe_axi_clk;
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
extern int clk_set_flags(struct clk *clk, unsigned long flags);
|
||||
|
||||
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
camio_vfe_mdc_clk =
|
||||
clk = clk_get(NULL, "vfe_mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
camio_mdc_clk =
|
||||
clk = clk_get(NULL, "mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
camio_vfe_clk =
|
||||
clk = clk_get(NULL, "vfe_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_AXI_CLK:
|
||||
camio_vfe_axi_clk =
|
||||
clk = clk_get(NULL, "vfe_axi_clk");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk))
|
||||
clk_enable(clk);
|
||||
else
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_AXI_CLK:
|
||||
clk = camio_vfe_axi_clk;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_disable(clk);
|
||||
clk_put(clk);
|
||||
} else
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_clk_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_mdc_clk;
|
||||
|
||||
/* TODO: check return */
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_enable(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camio_ext = camdev->ioext;
|
||||
|
||||
appio = request_mem_region(camio_ext.appphy,
|
||||
camio_ext.appsz, pdev->name);
|
||||
if (!appio) {
|
||||
rc = -EBUSY;
|
||||
goto enable_fail;
|
||||
}
|
||||
|
||||
appbase = ioremap(camio_ext.appphy,
|
||||
camio_ext.appsz);
|
||||
if (!appbase) {
|
||||
rc = -ENOMEM;
|
||||
goto apps_no_mem;
|
||||
}
|
||||
|
||||
mdcio = request_mem_region(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz, pdev->name);
|
||||
if (!mdcio) {
|
||||
rc = -EBUSY;
|
||||
goto mdc_busy;
|
||||
}
|
||||
|
||||
mdcbase = ioremap(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz);
|
||||
if (!mdcbase) {
|
||||
rc = -ENOMEM;
|
||||
goto mdc_no_mem;
|
||||
}
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
|
||||
msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_enable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
|
||||
return 0;
|
||||
|
||||
mdc_no_mem:
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
mdc_busy:
|
||||
iounmap(appbase);
|
||||
apps_no_mem:
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
enable_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_disable(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
iounmap(mdcbase);
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
iounmap(appbase);
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
|
||||
msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
/* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
|
||||
mask = CAM_SEL_BMSK |
|
||||
CAM_PCLK_SRC_SEL_BMSK |
|
||||
CAM_PCLK_INVERT_BMSK |
|
||||
EXT_CAM_HSYNC_POL_SEL_BMSK |
|
||||
EXT_CAM_VSYNC_POL_SEL_BMSK |
|
||||
MDDI_CLK_CHICKEN_BIT_BMSK;
|
||||
|
||||
value = 1 << CAM_SEL_SHFT |
|
||||
3 << CAM_PCLK_SRC_SEL_SHFT |
|
||||
0 << CAM_PCLK_INVERT_SHFT |
|
||||
0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
|
||||
0 << EXT_CAM_VSYNC_POL_SEL_SHFT |
|
||||
0 << MDDI_CLK_CHICKEN_BIT_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
/* todo: check return */
|
||||
if (camio_vfe_clk)
|
||||
clk_set_rate(camio_vfe_clk, 96000000);
|
||||
}
|
||||
|
||||
void msm_camio_vfe_blk_reset(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val |= 0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val &= ~0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset_2(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
|
||||
{
|
||||
struct clk *clk = NULL;
|
||||
|
||||
clk = camio_vfe_clk;
|
||||
|
||||
if (clk != NULL) {
|
||||
switch (srctype) {
|
||||
case MSM_CAMIO_CLK_SRC_INTERNAL:
|
||||
clk_set_flags(clk, 0x00000100 << 1);
|
||||
break;
|
||||
|
||||
case MSM_CAMIO_CLK_SRC_EXTERNAL:
|
||||
clk_set_flags(clk, 0x00000100);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm_camio_clk_axi_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_axi_clk;
|
||||
/* todo: check return */
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_probe_on(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
||||
|
||||
int msm_camio_probe_off(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
|
@ -1,798 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/camera.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
/*#include <linux/platform_device.h>*/
|
||||
|
||||
#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \
|
||||
struct v4l2_buffer)
|
||||
|
||||
#define MSM_V4L2_GET_PICTURE _IOWR('V', BASE_VIDIOC_PRIVATE+2, \
|
||||
struct v4l2_buffer)
|
||||
|
||||
#define MSM_V4L2_DEVICE_NAME "msm_v4l2"
|
||||
|
||||
#define MSM_V4L2_PROC_NAME "msm_v4l2"
|
||||
|
||||
#define MSM_V4L2_DEVNUM_MPEG2 0
|
||||
#define MSM_V4L2_DEVNUM_YUV 20
|
||||
|
||||
/* HVGA-P (portrait) and HVGA-L (landscape) */
|
||||
#define MSM_V4L2_WIDTH 480
|
||||
#define MSM_V4L2_HEIGHT 320
|
||||
|
||||
#if 1
|
||||
#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args)
|
||||
#else
|
||||
#define D(fmt, args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define PREVIEW_FRAMES_NUM 4
|
||||
|
||||
struct msm_v4l2_device {
|
||||
struct list_head read_queue;
|
||||
struct v4l2_format current_cap_format;
|
||||
struct v4l2_format current_pix_format;
|
||||
struct video_device *pvdev;
|
||||
struct msm_v4l2_driver *drv;
|
||||
uint8_t opencnt;
|
||||
|
||||
spinlock_t read_queue_lock;
|
||||
};
|
||||
|
||||
static struct msm_v4l2_device *g_pmsm_v4l2_dev;
|
||||
|
||||
|
||||
static DEFINE_MUTEX(msm_v4l2_opencnt_lock);
|
||||
|
||||
static int msm_v4l2_open(struct file *f)
|
||||
{
|
||||
int rc = 0;
|
||||
D("%s\n", __func__);
|
||||
mutex_lock(&msm_v4l2_opencnt_lock);
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
rc = g_pmsm_v4l2_dev->drv->open(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
MSM_APPS_ID_V4L2);
|
||||
}
|
||||
g_pmsm_v4l2_dev->opencnt++;
|
||||
mutex_unlock(&msm_v4l2_opencnt_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_v4l2_release(struct file *f)
|
||||
{
|
||||
int rc = 0;
|
||||
D("%s\n", __func__);
|
||||
mutex_lock(&msm_v4l2_opencnt_lock);
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
g_pmsm_v4l2_dev->opencnt--;
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
rc = g_pmsm_v4l2_dev->drv->release(
|
||||
g_pmsm_v4l2_dev->drv->sync);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&msm_v4l2_opencnt_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w)
|
||||
{
|
||||
return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w);
|
||||
}
|
||||
|
||||
static long msm_v4l2_ioctl(struct file *filep,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__);
|
||||
|
||||
switch (cmd) {
|
||||
case MSM_V4L2_START_SNAPSHOT:
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_ioctl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
D("msm_v4l2_ioctl, MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n",
|
||||
cmd);
|
||||
ctrlcmd->type = MSM_V4L2_SNAPSHOT;
|
||||
return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
case MSM_V4L2_GET_PICTURE:
|
||||
D("msm_v4l2_ioctl, MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd);
|
||||
ctrlcmd = (struct msm_ctrl_cmd *)arg;
|
||||
return g_pmsm_v4l2_dev->drv->get_pict(
|
||||
g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
|
||||
default:
|
||||
D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd);
|
||||
return video_ioctl2(filep, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_v4l2_release_dev(struct video_device *d)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
}
|
||||
|
||||
static int msm_v4l2_querycap(struct file *f,
|
||||
void *pctx, struct v4l2_capability *pcaps)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver));
|
||||
strncpy(pcaps->card,
|
||||
MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card));
|
||||
pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_queryctrl(struct file *f,
|
||||
void *pctx, struct v4l2_queryctrl *pqctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_QUERY_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_queryctrl);
|
||||
ctrlcmd->value = pqctrl;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_GET_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_control);
|
||||
ctrlcmd->value = c;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_SET_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_control);
|
||||
ctrlcmd->value = c;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_reqbufs(struct file *f,
|
||||
void *pctx, struct v4l2_requestbuffers *b)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
struct msm_pmem_info pmem_buf;
|
||||
#if 0
|
||||
__u32 width = 0;
|
||||
__u32 height = 0;
|
||||
__u32 y_size = 0;
|
||||
__u32 y_pad = 0;
|
||||
|
||||
/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */
|
||||
width = 640;
|
||||
/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */
|
||||
height = 480;
|
||||
|
||||
D("%s: width = %d, height = %d\n", __func__, width, height);
|
||||
|
||||
y_size = width * height;
|
||||
y_pad = y_size % 4;
|
||||
#endif
|
||||
|
||||
__u32 y_pad = pb->bytesused % 4;
|
||||
|
||||
/* V4L2 videodev will do the copy_from_user. */
|
||||
|
||||
memset(&pmem_buf, 0, sizeof(struct msm_pmem_info));
|
||||
pmem_buf.type = MSM_PMEM_OUTPUT2;
|
||||
pmem_buf.vaddr = (void *)pb->m.userptr;
|
||||
pmem_buf.y_off = 0;
|
||||
pmem_buf.fd = (int)pb->reserved;
|
||||
/* pmem_buf.cbcr_off = (y_size + y_pad); */
|
||||
pmem_buf.cbcr_off = (pb->bytesused + y_pad);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
/*
|
||||
__u32 y_size = 0;
|
||||
__u32 y_pad = 0;
|
||||
__u32 width = 0;
|
||||
__u32 height = 0;
|
||||
*/
|
||||
|
||||
__u32 y_pad = 0;
|
||||
|
||||
struct msm_pmem_info meminfo;
|
||||
struct msm_frame frame;
|
||||
static int cnt;
|
||||
|
||||
if ((pb->flags >> 16) & 0x0001) {
|
||||
/* this is for previwe */
|
||||
#if 0
|
||||
width = 640;
|
||||
height = 480;
|
||||
|
||||
/* V4L2 videodev will do the copy_from_user. */
|
||||
D("%s: width = %d, height = %d\n", __func__, width, height);
|
||||
y_size = width * height;
|
||||
y_pad = y_size % 4;
|
||||
#endif
|
||||
|
||||
y_pad = pb->bytesused % 4;
|
||||
|
||||
if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
|
||||
/* this qbuf is actually for releasing */
|
||||
|
||||
frame.buffer = pb->m.userptr;
|
||||
frame.y_off = 0;
|
||||
/* frame.cbcr_off = (y_size + y_pad); */
|
||||
frame.cbcr_off = (pb->bytesused + y_pad);
|
||||
frame.fd = pb->reserved;
|
||||
|
||||
D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n",
|
||||
pb->bytesused);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->put_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n",
|
||||
pb->bytesused);
|
||||
|
||||
meminfo.type = MSM_PMEM_OUTPUT2;
|
||||
meminfo.fd = (int)pb->reserved;
|
||||
meminfo.vaddr = (void *)pb->m.userptr;
|
||||
meminfo.y_off = 0;
|
||||
/* meminfo.cbcr_off = (y_size + y_pad); */
|
||||
meminfo.cbcr_off = (pb->bytesused + y_pad);
|
||||
if (cnt == PREVIEW_FRAMES_NUM - 1)
|
||||
meminfo.active = 0;
|
||||
else
|
||||
meminfo.active = 1;
|
||||
cnt++;
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
|
||||
&meminfo);
|
||||
} else if ((pb->flags) & 0x0001) {
|
||||
/* this is for snapshot */
|
||||
|
||||
__u32 y_size = 0;
|
||||
|
||||
if ((pb->flags >> 8) & 0x01) {
|
||||
|
||||
y_size = pb->bytesused;
|
||||
|
||||
meminfo.type = MSM_PMEM_THUMBAIL;
|
||||
} else if ((pb->flags >> 9) & 0x01) {
|
||||
|
||||
y_size = pb->bytesused;
|
||||
|
||||
meminfo.type = MSM_PMEM_MAINIMG;
|
||||
}
|
||||
|
||||
y_pad = y_size % 4;
|
||||
|
||||
meminfo.fd = (int)pb->reserved;
|
||||
meminfo.vaddr = (void *)pb->m.userptr;
|
||||
meminfo.y_off = 0;
|
||||
/* meminfo.cbcr_off = (y_size + y_pad); */
|
||||
meminfo.cbcr_off = (y_size + y_pad);
|
||||
meminfo.active = 1;
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
|
||||
&meminfo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
struct msm_frame frame;
|
||||
D("%s\n", __func__);
|
||||
|
||||
/* V4L2 videodev will do the copy_to_user. */
|
||||
if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
|
||||
D("%s, %d\n", __func__, __LINE__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->get_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
|
||||
pb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pb->m.userptr = (unsigned long)frame.buffer; /* FIXME */
|
||||
pb->reserved = (int)frame.fd;
|
||||
/* pb->length = (int)frame.cbcr_off; */
|
||||
|
||||
pb->bytesused = frame.cbcr_off;
|
||||
|
||||
} else if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
|
||||
__u32 y_pad = pb->bytesused % 4;
|
||||
|
||||
frame.buffer = pb->m.userptr;
|
||||
frame.y_off = 0;
|
||||
/* frame.cbcr_off = (y_size + y_pad); */
|
||||
frame.cbcr_off = (pb->bytesused + y_pad);
|
||||
frame.fd = pb->reserved;
|
||||
|
||||
g_pmsm_v4l2_dev->drv->put_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_STREAM_ON;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
D("%s after drv->ctrl \n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_STREAM_OFF;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_enum_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_fmtdesc *pfmtdesc)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_enum_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_fmtdesc *pfmtdesc)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
|
||||
switch (pfmtdesc->index) {
|
||||
case 0:
|
||||
pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pfmtdesc->flags = 0;
|
||||
strncpy(pfmtdesc->description, "YUV 4:2:0",
|
||||
sizeof(pfmtdesc->description));
|
||||
pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
|
||||
pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
|
||||
pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
pfmt->fmt.pix.field = V4L2_FIELD_ANY;
|
||||
pfmt->fmt.pix.bytesperline = 0;
|
||||
pfmt->fmt.pix.sizeimage = 0;
|
||||
pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
|
||||
pfmt->fmt.pix.priv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_VID_CAP_TYPE;
|
||||
ctrlcmd->length = sizeof(struct v4l2_format);
|
||||
ctrlcmd->value = pfmt;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
kfree(ctrlcmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* FIXEME */
|
||||
if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) {
|
||||
kfree(ctrlcmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Ok, but check other params, too. */
|
||||
|
||||
#if 0
|
||||
memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt,
|
||||
sizeof(struct v4l2_format));
|
||||
#endif
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
|
||||
pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
|
||||
pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
|
||||
pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
pfmt->fmt.pix.field = V4L2_FIELD_ANY;
|
||||
pfmt->fmt.pix.bytesperline = 0;
|
||||
pfmt->fmt.pix.sizeimage = 0;
|
||||
pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
|
||||
pfmt->fmt.pix.priv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_jpegcomp(struct file *f,
|
||||
void *pctx, struct v4l2_jpegcompression *pcomp)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_jpegcomp(struct file *f,
|
||||
void *pctx, struct v4l2_jpegcompression *pcomp)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len = 0;
|
||||
len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n");
|
||||
|
||||
if (g_pmsm_v4l2_dev) {
|
||||
len += snprintf(pbuf, strlen("mode: ") + 1, "mode: ");
|
||||
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.type
|
||||
== V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
len += snprintf(pbuf, strlen("capture\n") + 1,
|
||||
"capture\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
|
||||
len += snprintf(pbuf, 21, "resolution: %dx%d\n",
|
||||
g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
|
||||
width,
|
||||
g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
|
||||
height);
|
||||
|
||||
len += snprintf(pbuf,
|
||||
strlen("pixel format: ") + 1, "pixel format: ");
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat
|
||||
== V4L2_PIX_FMT_YVU420)
|
||||
len += snprintf(pbuf, strlen("yvu420\n") + 1,
|
||||
"yvu420\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
|
||||
len += snprintf(pbuf, strlen("colorspace: ") + 1,
|
||||
"colorspace: ");
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace
|
||||
== V4L2_COLORSPACE_JPEG)
|
||||
len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
}
|
||||
|
||||
*eof = 1;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct v4l2_file_operations msm_v4l2_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = msm_v4l2_open,
|
||||
.poll = msm_v4l2_poll,
|
||||
.release = msm_v4l2_release,
|
||||
.ioctl = msm_v4l2_ioctl,
|
||||
};
|
||||
|
||||
static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev)
|
||||
{
|
||||
pmsm_v4l2_dev->read_queue_lock =
|
||||
__SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock);
|
||||
INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue);
|
||||
}
|
||||
|
||||
static int msm_v4l2_try_fmt_cap(struct file *file,
|
||||
void *fh, struct v4l2_format *f)
|
||||
{
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mm_v4l2_try_fmt_type_private(struct file *file,
|
||||
void *fh, struct v4l2_format *f)
|
||||
{
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* should the following structure be used instead of the code in the function?
|
||||
* static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
|
||||
* .vidioc_querycap = ....
|
||||
* }
|
||||
*/
|
||||
static const struct v4l2_ioctl_ops msm_ioctl_ops = {
|
||||
.vidioc_querycap = msm_v4l2_querycap,
|
||||
.vidioc_s_std = msm_v4l2_s_std,
|
||||
|
||||
.vidioc_queryctrl = msm_v4l2_queryctrl,
|
||||
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
|
||||
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
|
||||
|
||||
.vidioc_reqbufs = msm_v4l2_reqbufs,
|
||||
.vidioc_querybuf = msm_v4l2_querybuf,
|
||||
.vidioc_qbuf = msm_v4l2_qbuf,
|
||||
.vidioc_dqbuf = msm_v4l2_dqbuf,
|
||||
|
||||
.vidioc_streamon = msm_v4l2_streamon,
|
||||
.vidioc_streamoff = msm_v4l2_streamoff,
|
||||
|
||||
.vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay,
|
||||
.vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap,
|
||||
|
||||
.vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap,
|
||||
.vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private,
|
||||
|
||||
.vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap,
|
||||
.vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap,
|
||||
.vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay,
|
||||
.vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay,
|
||||
.vidioc_overlay = msm_v4l2_overlay,
|
||||
|
||||
.vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp,
|
||||
.vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp,
|
||||
};
|
||||
|
||||
static int msm_v4l2_video_dev_init(struct video_device *pvd)
|
||||
{
|
||||
strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name));
|
||||
pvd->vfl_type = 1;
|
||||
pvd->fops = &msm_v4l2_fops;
|
||||
pvd->release = msm_v4l2_release_dev;
|
||||
pvd->minor = -1;
|
||||
pvd->ioctl_ops = &msm_ioctl_ops;
|
||||
return msm_v4l2_register(g_pmsm_v4l2_dev->drv);
|
||||
}
|
||||
|
||||
static int __init msm_v4l2_init(void)
|
||||
{
|
||||
int rc = -ENOMEM;
|
||||
struct video_device *pvdev = NULL;
|
||||
struct msm_v4l2_device *pmsm_v4l2_dev = NULL;
|
||||
D("%s\n", __func__);
|
||||
|
||||
pvdev = video_device_alloc();
|
||||
if (pvdev == NULL)
|
||||
return rc;
|
||||
|
||||
pmsm_v4l2_dev =
|
||||
kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL);
|
||||
if (pmsm_v4l2_dev == NULL) {
|
||||
video_device_release(pvdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
msm_v4l2_dev_init(pmsm_v4l2_dev);
|
||||
|
||||
g_pmsm_v4l2_dev = pmsm_v4l2_dev;
|
||||
g_pmsm_v4l2_dev->pvdev = pvdev;
|
||||
|
||||
g_pmsm_v4l2_dev->drv =
|
||||
kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL);
|
||||
if (!g_pmsm_v4l2_dev->drv) {
|
||||
video_device_release(pvdev);
|
||||
kfree(pmsm_v4l2_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_v4l2_video_dev_init(pvdev);
|
||||
if (rc < 0) {
|
||||
video_device_release(pvdev);
|
||||
kfree(g_pmsm_v4l2_dev->drv);
|
||||
kfree(pmsm_v4l2_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (video_register_device(pvdev, VFL_TYPE_GRABBER,
|
||||
MSM_V4L2_DEVNUM_YUV)) {
|
||||
D("failed to register device\n");
|
||||
video_device_release(pvdev);
|
||||
kfree(g_pmsm_v4l2_dev);
|
||||
g_pmsm_v4l2_dev = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
#ifdef CONFIG_PROC_FS
|
||||
create_proc_read_entry(MSM_V4L2_PROC_NAME,
|
||||
0, NULL, msm_v4l2_read_proc, NULL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit msm_v4l2_exit(void)
|
||||
{
|
||||
struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev;
|
||||
D("%s\n", __func__);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry(MSM_V4L2_PROC_NAME, NULL);
|
||||
#endif
|
||||
video_unregister_device(pvdev);
|
||||
video_device_release(pvdev);
|
||||
|
||||
msm_v4l2_unregister(g_pmsm_v4l2_dev->drv);
|
||||
|
||||
kfree(g_pmsm_v4l2_dev->drv);
|
||||
g_pmsm_v4l2_dev->drv = NULL;
|
||||
|
||||
kfree(g_pmsm_v4l2_dev);
|
||||
g_pmsm_v4l2_dev = NULL;
|
||||
}
|
||||
|
||||
module_init(msm_v4l2_init);
|
||||
module_exit(msm_v4l2_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM V4L2 driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -1,702 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include <linux/msm_adsp.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include <linux/slab.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wait.h>
|
||||
#include "msm_vfe7x.h"
|
||||
|
||||
#define QDSP_CMDQUEUE QDSP_vfeCommandQueue
|
||||
|
||||
#define VFE_RESET_CMD 0
|
||||
#define VFE_START_CMD 1
|
||||
#define VFE_STOP_CMD 2
|
||||
#define VFE_FRAME_ACK 20
|
||||
#define STATS_AF_ACK 21
|
||||
#define STATS_WE_ACK 22
|
||||
|
||||
#define MSG_STOP_ACK 1
|
||||
#define MSG_SNAPSHOT 2
|
||||
#define MSG_OUTPUT1 6
|
||||
#define MSG_OUTPUT2 7
|
||||
#define MSG_STATS_AF 8
|
||||
#define MSG_STATS_WE 9
|
||||
|
||||
static struct msm_adsp_module *qcam_mod;
|
||||
static struct msm_adsp_module *vfe_mod;
|
||||
static struct msm_vfe_callback *resp;
|
||||
static void *extdata;
|
||||
static uint32_t extlen;
|
||||
|
||||
struct mutex vfe_lock;
|
||||
static void *vfe_syncdata;
|
||||
static uint8_t vfestopped;
|
||||
|
||||
static struct stop_event stopevent;
|
||||
|
||||
static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
|
||||
enum vfe_resp_msg type,
|
||||
void *data, void **ext, int32_t *elen)
|
||||
{
|
||||
switch (type) {
|
||||
case VFE_MSG_OUTPUT1:
|
||||
case VFE_MSG_OUTPUT2: {
|
||||
pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
|
||||
pinfo->cbcr_phy =
|
||||
((struct vfe_endframe *)data)->cbcr_address;
|
||||
|
||||
CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
|
||||
pinfo->y_phy, pinfo->cbcr_phy);
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->bl_evencol =
|
||||
((struct vfe_endframe *)data)->blacklevelevencolumn;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->bl_oddcol =
|
||||
((struct vfe_endframe *)data)->blackleveloddcolumn;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
|
||||
((struct vfe_endframe *)data)->greendefectpixelcount;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
|
||||
((struct vfe_endframe *)data)->redbluedefectpixelcount;
|
||||
|
||||
*ext = extdata;
|
||||
*elen = extlen;
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_MSG_STATS_AF:
|
||||
case VFE_MSG_STATS_WE:
|
||||
pinfo->sbuf_phy = *(uint32_t *)data;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
uint32_t evt_buf[3];
|
||||
struct msm_vfe_resp *rp;
|
||||
void *data;
|
||||
|
||||
len = (id == (uint16_t)-1) ? 0 : len;
|
||||
data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata);
|
||||
|
||||
if (!data) {
|
||||
pr_err("rp: cannot allocate buffer\n");
|
||||
return;
|
||||
}
|
||||
rp = (struct msm_vfe_resp *)data;
|
||||
rp->evt_msg.len = len;
|
||||
|
||||
if (id == ((uint16_t)-1)) {
|
||||
/* event */
|
||||
rp->type = VFE_EVENT;
|
||||
rp->evt_msg.type = MSM_CAMERA_EVT;
|
||||
getevent(evt_buf, sizeof(evt_buf));
|
||||
rp->evt_msg.msg_id = evt_buf[0];
|
||||
resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata);
|
||||
} else {
|
||||
/* messages */
|
||||
rp->evt_msg.type = MSM_CAMERA_MSG;
|
||||
rp->evt_msg.msg_id = id;
|
||||
rp->evt_msg.data = rp + 1;
|
||||
getevent(rp->evt_msg.data, len);
|
||||
|
||||
switch (rp->evt_msg.msg_id) {
|
||||
case MSG_SNAPSHOT:
|
||||
rp->type = VFE_MSG_SNAPSHOT;
|
||||
break;
|
||||
|
||||
case MSG_OUTPUT1:
|
||||
rp->type = VFE_MSG_OUTPUT1;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1,
|
||||
rp->evt_msg.data, &(rp->extdata),
|
||||
&(rp->extlen));
|
||||
break;
|
||||
|
||||
case MSG_OUTPUT2:
|
||||
rp->type = VFE_MSG_OUTPUT2;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2,
|
||||
rp->evt_msg.data, &(rp->extdata),
|
||||
&(rp->extlen));
|
||||
break;
|
||||
|
||||
case MSG_STATS_AF:
|
||||
rp->type = VFE_MSG_STATS_AF;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
|
||||
rp->evt_msg.data, NULL, NULL);
|
||||
break;
|
||||
|
||||
case MSG_STATS_WE:
|
||||
rp->type = VFE_MSG_STATS_WE;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
|
||||
rp->evt_msg.data, NULL, NULL);
|
||||
|
||||
CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
|
||||
break;
|
||||
|
||||
case MSG_STOP_ACK:
|
||||
rp->type = VFE_MSG_GENERAL;
|
||||
stopevent.state = 1;
|
||||
wake_up(&stopevent.wait);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
rp->type = VFE_MSG_GENERAL;
|
||||
break;
|
||||
}
|
||||
resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata);
|
||||
}
|
||||
}
|
||||
|
||||
static struct msm_adsp_ops vfe_7x_sync = {
|
||||
.event = vfe_7x_ops,
|
||||
};
|
||||
|
||||
static int vfe_7x_enable(struct camera_enable_cmd *enable)
|
||||
{
|
||||
int rc = -EFAULT;
|
||||
|
||||
if (!strcmp(enable->name, "QCAMTASK"))
|
||||
rc = msm_adsp_enable(qcam_mod);
|
||||
else if (!strcmp(enable->name, "VFETASK"))
|
||||
rc = msm_adsp_enable(vfe_mod);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_disable(struct camera_enable_cmd *enable,
|
||||
struct platform_device *dev __attribute__((unused)))
|
||||
{
|
||||
int rc = -EFAULT;
|
||||
|
||||
if (!strcmp(enable->name, "QCAMTASK"))
|
||||
rc = msm_adsp_disable(qcam_mod);
|
||||
else if (!strcmp(enable->name, "VFETASK"))
|
||||
rc = msm_adsp_disable(vfe_mod);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_stop(void)
|
||||
{
|
||||
int rc = 0;
|
||||
uint32_t stopcmd = VFE_STOP_CMD;
|
||||
rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
|
||||
&stopcmd, sizeof(uint32_t));
|
||||
if (rc < 0) {
|
||||
CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
stopevent.state = 0;
|
||||
rc = wait_event_timeout(stopevent.wait,
|
||||
stopevent.state != 0,
|
||||
msecs_to_jiffies(stopevent.timeout));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void vfe_7x_release(struct platform_device *pdev)
|
||||
{
|
||||
mutex_lock(&vfe_lock);
|
||||
vfe_syncdata = NULL;
|
||||
mutex_unlock(&vfe_lock);
|
||||
|
||||
if (!vfestopped) {
|
||||
CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
|
||||
vfe_7x_stop();
|
||||
} else
|
||||
vfestopped = 0;
|
||||
|
||||
msm_adsp_disable(qcam_mod);
|
||||
msm_adsp_disable(vfe_mod);
|
||||
|
||||
msm_adsp_put(qcam_mod);
|
||||
msm_adsp_put(vfe_mod);
|
||||
|
||||
msm_camio_disable(pdev);
|
||||
|
||||
kfree(extdata);
|
||||
extlen = 0;
|
||||
}
|
||||
|
||||
static int vfe_7x_init(struct msm_vfe_callback *presp,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
init_waitqueue_head(&stopevent.wait);
|
||||
stopevent.timeout = 200;
|
||||
stopevent.state = 0;
|
||||
|
||||
if (presp && presp->vfe_resp)
|
||||
resp = presp;
|
||||
else
|
||||
return -EFAULT;
|
||||
|
||||
/* Bring up all the required GPIOs and Clocks */
|
||||
rc = msm_camio_enable(dev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
|
||||
extlen = sizeof(struct vfe_frame_extra);
|
||||
|
||||
extdata = kmalloc(extlen, GFP_ATOMIC);
|
||||
if (!extdata) {
|
||||
rc = -ENOMEM;
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
|
||||
if (rc) {
|
||||
rc = -EBUSY;
|
||||
goto get_qcam_fail;
|
||||
}
|
||||
|
||||
rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
|
||||
if (rc) {
|
||||
rc = -EBUSY;
|
||||
goto get_vfe_fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
get_vfe_fail:
|
||||
msm_adsp_put(qcam_mod);
|
||||
get_qcam_fail:
|
||||
kfree(extdata);
|
||||
init_fail:
|
||||
extlen = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_config_axi(int mode,
|
||||
struct axidata *ad, struct axiout *ao)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
unsigned long *bptr;
|
||||
int cnt;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = ad->region;
|
||||
|
||||
CDBG("bufnum1 = %d\n", ad->bufnum1);
|
||||
CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
bptr = &ao->output1buffer1_y_phy;
|
||||
for (cnt = 0; cnt < ad->bufnum1; cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
|
||||
bptr++;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
regptr--;
|
||||
for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
bptr++;
|
||||
}
|
||||
} /* if OUTPUT1 or Both */
|
||||
|
||||
if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = &(ad->region[ad->bufnum1]);
|
||||
|
||||
CDBG("bufnum2 = %d\n", ad->bufnum2);
|
||||
CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
bptr = &ao->output2buffer1_y_phy;
|
||||
for (cnt = 0; cnt < ad->bufnum2; cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
|
||||
bptr++;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
regptr--;
|
||||
for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
bptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
unsigned char buf[256];
|
||||
|
||||
struct vfe_stats_ack sack;
|
||||
struct axidata *axid;
|
||||
uint32_t i;
|
||||
|
||||
struct vfe_stats_we_cfg *scfg = NULL;
|
||||
struct vfe_stats_af_cfg *sfcfg = NULL;
|
||||
|
||||
struct axiout *axio = NULL;
|
||||
void *cmd_data = NULL;
|
||||
void *cmd_data_alloc = NULL;
|
||||
long rc = 0;
|
||||
struct msm_vfe_command_7k *vfecmd;
|
||||
|
||||
vfecmd =
|
||||
kmalloc(sizeof(struct msm_vfe_command_7k),
|
||||
GFP_ATOMIC);
|
||||
if (!vfecmd) {
|
||||
pr_err("vfecmd alloc failed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
|
||||
if (copy_from_user(vfecmd,
|
||||
(void __user *)(cmd->value),
|
||||
sizeof(struct msm_vfe_command_7k))) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd->cmd_type) {
|
||||
case CMD_STATS_ENABLE:
|
||||
case CMD_STATS_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
scfg =
|
||||
kmalloc(sizeof(struct vfe_stats_we_cfg),
|
||||
GFP_ATOMIC);
|
||||
if (!scfg) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(scfg,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
|
||||
axid->bufnum1, scfg->wb_expstatsenable);
|
||||
|
||||
if (axid->bufnum1 > 0) {
|
||||
regptr = axid->region;
|
||||
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
|
||||
CDBG("STATS_ENABLE, phy = 0x%lx\n",
|
||||
regptr->paddr);
|
||||
|
||||
scfg->wb_expstatoutputbuffer[i] =
|
||||
(void *)regptr->paddr;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
cmd_data = scfg;
|
||||
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_ENABLE:
|
||||
case CMD_STATS_AF_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sfcfg =
|
||||
kmalloc(sizeof(struct vfe_stats_af_cfg),
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!sfcfg) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(sfcfg,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
|
||||
axid->bufnum1, sfcfg->af_enable);
|
||||
|
||||
if (axid->bufnum1 > 0) {
|
||||
regptr = axid->region;
|
||||
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
|
||||
CDBG("STATS_ENABLE, phy = 0x%lx\n",
|
||||
regptr->paddr);
|
||||
|
||||
sfcfg->af_outbuf[i] =
|
||||
(void *)regptr->paddr;
|
||||
|
||||
regptr++;
|
||||
}
|
||||
|
||||
cmd_data = sfcfg;
|
||||
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FRAME_BUF_RELEASE: {
|
||||
struct msm_frame *b;
|
||||
unsigned long p;
|
||||
struct vfe_outputack fack;
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
b = (struct msm_frame *)(cmd->value);
|
||||
p = *(unsigned long *)data;
|
||||
|
||||
fack.header = VFE_FRAME_ACK;
|
||||
|
||||
fack.output2newybufferaddress =
|
||||
(void *)(p + b->y_off);
|
||||
|
||||
fack.output2newcbcrbufferaddress =
|
||||
(void *)(p + b->cbcr_off);
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_outputack);
|
||||
cmd_data = &fack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SNAP_BUF_RELEASE:
|
||||
break;
|
||||
|
||||
case CMD_STATS_BUF_RELEASE: {
|
||||
CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sack.header = STATS_WE_ACK;
|
||||
sack.bufaddr = (void *)*(uint32_t *)data;
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_stats_ack);
|
||||
cmd_data = &sack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_BUF_RELEASE: {
|
||||
CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sack.header = STATS_AF_ACK;
|
||||
sack.bufaddr = (void *)*(uint32_t *)data;
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_stats_ack);
|
||||
cmd_data = &sack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GENERAL:
|
||||
case CMD_STATS_DISABLE: {
|
||||
if (vfecmd->length > 256) {
|
||||
cmd_data_alloc =
|
||||
cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
|
||||
if (!cmd_data) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
} else
|
||||
cmd_data = buf;
|
||||
|
||||
if (copy_from_user(cmd_data,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
if (vfecmd->queue == QDSP_CMDQUEUE) {
|
||||
switch (*(uint32_t *)cmd_data) {
|
||||
case VFE_RESET_CMD:
|
||||
msm_camio_vfe_blk_reset();
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfestopped = 0;
|
||||
break;
|
||||
|
||||
case VFE_START_CMD:
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfestopped = 0;
|
||||
break;
|
||||
|
||||
case VFE_STOP_CMD:
|
||||
vfestopped = 1;
|
||||
goto config_send;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* QDSP_CMDQUEUE */
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT1: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_1, axid, axio);
|
||||
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT2:
|
||||
case CMD_RAW_PICT_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_2, axid, axio);
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_SNAP_O1_AND_O2: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
|
||||
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
if (vfestopped)
|
||||
goto config_done;
|
||||
|
||||
config_send:
|
||||
CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
|
||||
rc = msm_adsp_write(vfe_mod, vfecmd->queue,
|
||||
cmd_data, vfecmd->length);
|
||||
|
||||
config_done:
|
||||
if (cmd_data_alloc != NULL)
|
||||
kfree(cmd_data_alloc);
|
||||
|
||||
config_failure:
|
||||
kfree(scfg);
|
||||
kfree(axio);
|
||||
kfree(vfecmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
|
||||
{
|
||||
mutex_init(&vfe_lock);
|
||||
fptr->vfe_init = vfe_7x_init;
|
||||
fptr->vfe_enable = vfe_7x_enable;
|
||||
fptr->vfe_config = vfe_7x_config;
|
||||
fptr->vfe_disable = vfe_7x_disable;
|
||||
fptr->vfe_release = vfe_7x_release;
|
||||
vfe_syncdata = data;
|
||||
}
|
|
@ -1,255 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#ifndef __MSM_VFE7X_H__
|
||||
#define __MSM_VFE7X_H__
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
struct vfe_frame_extra {
|
||||
uint32_t bl_evencol;
|
||||
uint32_t bl_oddcol;
|
||||
uint16_t g_def_p_cnt;
|
||||
uint16_t r_b_def_p_cnt;
|
||||
};
|
||||
|
||||
struct vfe_endframe {
|
||||
uint32_t y_address;
|
||||
uint32_t cbcr_address;
|
||||
|
||||
unsigned int blacklevelevencolumn:23;
|
||||
uint16_t reserved1:9;
|
||||
unsigned int blackleveloddcolumn:23;
|
||||
uint16_t reserved2:9;
|
||||
|
||||
uint16_t greendefectpixelcount:8;
|
||||
uint16_t reserved3:8;
|
||||
uint16_t redbluedefectpixelcount:8;
|
||||
uint16_t reserved4:8;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_outputack {
|
||||
uint32_t header;
|
||||
void *output2newybufferaddress;
|
||||
void *output2newcbcrbufferaddress;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_ack {
|
||||
uint32_t header;
|
||||
/* MUST BE 64 bit ALIGNED */
|
||||
void *bufaddr;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
/* AXI Output Config Command sent to DSP */
|
||||
struct axiout {
|
||||
uint32_t cmdheader:32;
|
||||
int outputmode:3;
|
||||
uint8_t format:2;
|
||||
uint32_t /* reserved */ : 27;
|
||||
|
||||
/* AXI Output 1 Y Configuration, Part 1 */
|
||||
uint32_t out1yimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out1yimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 Y Configuration, Part 2 */
|
||||
uint8_t out1yburstlen:2;
|
||||
uint32_t out1ynumrows:12;
|
||||
uint32_t out1yrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 CbCr Configuration, Part 1 */
|
||||
uint32_t out1cbcrimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out1cbcrimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 CbCr Configuration, Part 2 */
|
||||
uint8_t out1cbcrburstlen:2;
|
||||
uint32_t out1cbcrnumrows:12;
|
||||
uint32_t out1cbcrrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 Y Configuration, Part 1 */
|
||||
uint32_t out2yimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out2yimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 Y Configuration, Part 2 */
|
||||
uint8_t out2yburstlen:2;
|
||||
uint32_t out2ynumrows:12;
|
||||
uint32_t out2yrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 CbCr Configuration, Part 1 */
|
||||
uint32_t out2cbcrimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out2cbcrimagewidtein64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 CbCr Configuration, Part 2 */
|
||||
uint8_t out2cbcrburstlen:2;
|
||||
uint32_t out2cbcrnumrows:12;
|
||||
uint32_t out2cbcrrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* Address configuration:
|
||||
* output1 phisycal address */
|
||||
unsigned long output1buffer1_y_phy;
|
||||
unsigned long output1buffer1_cbcr_phy;
|
||||
unsigned long output1buffer2_y_phy;
|
||||
unsigned long output1buffer2_cbcr_phy;
|
||||
unsigned long output1buffer3_y_phy;
|
||||
unsigned long output1buffer3_cbcr_phy;
|
||||
unsigned long output1buffer4_y_phy;
|
||||
unsigned long output1buffer4_cbcr_phy;
|
||||
unsigned long output1buffer5_y_phy;
|
||||
unsigned long output1buffer5_cbcr_phy;
|
||||
unsigned long output1buffer6_y_phy;
|
||||
unsigned long output1buffer6_cbcr_phy;
|
||||
unsigned long output1buffer7_y_phy;
|
||||
unsigned long output1buffer7_cbcr_phy;
|
||||
unsigned long output1buffer8_y_phy;
|
||||
unsigned long output1buffer8_cbcr_phy;
|
||||
|
||||
/* output2 phisycal address */
|
||||
unsigned long output2buffer1_y_phy;
|
||||
unsigned long output2buffer1_cbcr_phy;
|
||||
unsigned long output2buffer2_y_phy;
|
||||
unsigned long output2buffer2_cbcr_phy;
|
||||
unsigned long output2buffer3_y_phy;
|
||||
unsigned long output2buffer3_cbcr_phy;
|
||||
unsigned long output2buffer4_y_phy;
|
||||
unsigned long output2buffer4_cbcr_phy;
|
||||
unsigned long output2buffer5_y_phy;
|
||||
unsigned long output2buffer5_cbcr_phy;
|
||||
unsigned long output2buffer6_y_phy;
|
||||
unsigned long output2buffer6_cbcr_phy;
|
||||
unsigned long output2buffer7_y_phy;
|
||||
unsigned long output2buffer7_cbcr_phy;
|
||||
unsigned long output2buffer8_y_phy;
|
||||
unsigned long output2buffer8_cbcr_phy;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_we_cfg {
|
||||
uint32_t header;
|
||||
|
||||
/* White Balance/Exposure Statistic Selection */
|
||||
uint8_t wb_expstatsenable:1;
|
||||
uint8_t wb_expstatbuspriorityselection:1;
|
||||
unsigned int wb_expstatbuspriorityvalue:4;
|
||||
unsigned int /* reserved */ : 26;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 1 */
|
||||
uint8_t exposurestatregions:1;
|
||||
uint8_t exposurestatsubregions:1;
|
||||
unsigned int /* reserved */ : 14;
|
||||
|
||||
unsigned int whitebalanceminimumy:8;
|
||||
unsigned int whitebalancemaximumy:8;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 2 */
|
||||
uint8_t wb_expstatslopeofneutralregionline[
|
||||
NUM_WB_EXP_NEUTRAL_REGION_LINES];
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 3 */
|
||||
unsigned int wb_expstatcrinterceptofneutralregionline2:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int wb_expstatcbinterceptofneutralreginnline1:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 4 */
|
||||
unsigned int wb_expstatcrinterceptofneutralregionline4:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int wb_expstatcbinterceptofneutralregionline3:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
|
||||
/* White Balance/Exposure Statistic Output Buffer Header */
|
||||
unsigned int wb_expmetricheaderpattern:8;
|
||||
unsigned int /* reserved */ : 24;
|
||||
|
||||
/* White Balance/Exposure Statistic Output Buffers-MUST
|
||||
* BE 64 bit ALIGNED */
|
||||
void *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_af_cfg {
|
||||
uint32_t header;
|
||||
|
||||
/* Autofocus Statistic Selection */
|
||||
uint8_t af_enable:1;
|
||||
uint8_t af_busprioritysel:1;
|
||||
unsigned int af_buspriorityval:4;
|
||||
unsigned int /* reserved */ : 26;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 1 */
|
||||
unsigned int af_singlewinvoffset:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int af_singlewinhoffset:12;
|
||||
unsigned int /* reserved */ : 3;
|
||||
uint8_t af_winmode:1;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 2 */
|
||||
unsigned int af_singglewinvh:11;
|
||||
unsigned int /* reserved */ : 5;
|
||||
unsigned int af_singlewinhw:11;
|
||||
unsigned int /* reserved */ : 5;
|
||||
|
||||
/* Autofocus Statistic Configuration, Parts 3-6 */
|
||||
uint8_t af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 7 */
|
||||
signed int af_metrichpfcoefa00:5;
|
||||
signed int af_metrichpfcoefa04:5;
|
||||
unsigned int af_metricmaxval:11;
|
||||
uint8_t af_metricsel:1;
|
||||
unsigned int /* reserved */ : 10;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 8 */
|
||||
signed int af_metrichpfcoefa20:5;
|
||||
signed int af_metrichpfcoefa21:5;
|
||||
signed int af_metrichpfcoefa22:5;
|
||||
signed int af_metrichpfcoefa23:5;
|
||||
signed int af_metrichpfcoefa24:5;
|
||||
unsigned int /* reserved */ : 7;
|
||||
|
||||
/* Autofocus Statistic Output Buffer Header */
|
||||
unsigned int af_metrichp:8;
|
||||
unsigned int /* reserved */ : 24;
|
||||
|
||||
/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
|
||||
void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
|
||||
} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
|
||||
|
||||
struct msm_camera_frame_msg {
|
||||
unsigned long output_y_address;
|
||||
unsigned long output_cbcr_address;
|
||||
|
||||
unsigned int blacklevelevenColumn:23;
|
||||
uint16_t reserved1:9;
|
||||
unsigned int blackleveloddColumn:23;
|
||||
uint16_t reserved2:9;
|
||||
|
||||
uint16_t greendefectpixelcount:8;
|
||||
uint16_t reserved3:8;
|
||||
uint16_t redbluedefectpixelcount:8;
|
||||
uint16_t reserved4:8;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
/* New one for 7k */
|
||||
struct msm_vfe_command_7k {
|
||||
uint16_t queue;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct stop_event {
|
||||
wait_queue_head_t wait;
|
||||
int state;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __MSM_VFE7X_H__ */
|
|
@ -1,736 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <mach/irqs.h>
|
||||
#include "msm_vfe8x_proc.h"
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
struct mutex vfe_lock;
|
||||
static void *vfe_syncdata;
|
||||
|
||||
static int vfe_enable(struct camera_enable_cmd *enable)
|
||||
{
|
||||
int rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_disable(struct camera_enable_cmd *enable,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
vfe_stop();
|
||||
|
||||
msm_camio_disable(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void vfe_release(struct platform_device *dev)
|
||||
{
|
||||
msm_camio_disable(dev);
|
||||
vfe_cmd_release(dev);
|
||||
|
||||
mutex_lock(&vfe_lock);
|
||||
vfe_syncdata = NULL;
|
||||
mutex_unlock(&vfe_lock);
|
||||
}
|
||||
|
||||
static void vfe_config_axi(int mode,
|
||||
struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
int i, j;
|
||||
uint32_t *p1, *p2;
|
||||
|
||||
if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = ad->region;
|
||||
for (i = 0;
|
||||
i < ad->bufnum1; i++) {
|
||||
|
||||
p1 = &(ao->output1.outputY.outFragments[i][0]);
|
||||
p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
|
||||
|
||||
for (j = 0;
|
||||
j < ao->output1.fragmentCount; j++) {
|
||||
|
||||
*p1 = regptr->paddr + regptr->y_off;
|
||||
p1++;
|
||||
|
||||
*p2 = regptr->paddr + regptr->cbcr_off;
|
||||
p2++;
|
||||
}
|
||||
regptr++;
|
||||
}
|
||||
} /* if OUTPUT1 or Both */
|
||||
|
||||
if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
|
||||
|
||||
regptr = &(ad->region[ad->bufnum1]);
|
||||
CDBG("bufnum2 = %d\n", ad->bufnum2);
|
||||
|
||||
for (i = 0;
|
||||
i < ad->bufnum2; i++) {
|
||||
|
||||
p1 = &(ao->output2.outputY.outFragments[i][0]);
|
||||
p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
|
||||
|
||||
CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
for (j = 0;
|
||||
j < ao->output2.fragmentCount; j++) {
|
||||
|
||||
*p1 = regptr->paddr + regptr->y_off;
|
||||
CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
|
||||
p1++;
|
||||
|
||||
*p2 = regptr->paddr + regptr->cbcr_off;
|
||||
CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
|
||||
p2++;
|
||||
}
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
|
||||
|
||||
switch (cmd->id) {
|
||||
case VFE_CMD_ID_RESET:
|
||||
msm_camio_vfe_blk_reset();
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfe_reset();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_START: {
|
||||
struct vfe_cmd_start start;
|
||||
if (copy_from_user(&start,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
/* msm_camio_camif_pad_reg_reset_2(); */
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
vfe_start(&start);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CAMIF_CONFIG: {
|
||||
struct vfe_cmd_camif_config camif;
|
||||
if (copy_from_user(&camif,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_camif_config(&camif);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
|
||||
struct vfe_cmd_black_level_config bl;
|
||||
if (copy_from_user(&bl,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_black_level_config(&bl);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ROLL_OFF_CONFIG: {
|
||||
struct vfe_cmd_roll_off_config rolloff;
|
||||
if (copy_from_user(&rolloff,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_roll_off_config(&rolloff);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
|
||||
struct vfe_cmd_demux_channel_gain_config demuxc;
|
||||
if (copy_from_user(&demuxc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
/* demux is always enabled. */
|
||||
vfe_demux_channel_gain_config(&demuxc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_CONFIG: {
|
||||
struct vfe_cmd_demosaic_config demosaic;
|
||||
if (copy_from_user(&demosaic,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_config(&demosaic);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FOV_CROP_CONFIG:
|
||||
case VFE_CMD_ID_FOV_CROP_UPDATE: {
|
||||
struct vfe_cmd_fov_crop_config fov;
|
||||
if (copy_from_user(&fov,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_fov_crop_config(&fov);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_MAIN_SCALER_CONFIG:
|
||||
case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
|
||||
struct vfe_cmd_main_scaler_config mainds;
|
||||
if (copy_from_user(&mainds,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_main_scaler_config(&mainds);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
|
||||
case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
|
||||
struct vfe_cmd_white_balance_config wb;
|
||||
if (copy_from_user(&wb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_white_balance_config(&wb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
|
||||
case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
|
||||
struct vfe_cmd_color_correction_config cc;
|
||||
if (copy_from_user(&cc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_color_correction_config(&cc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_LA_CONFIG: {
|
||||
struct vfe_cmd_la_config la;
|
||||
if (copy_from_user(&la,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_la_config(&la);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
|
||||
struct vfe_cmd_rgb_gamma_config rgb;
|
||||
if (copy_from_user(&rgb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
rc = vfe_rgb_gamma_config(&rgb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
|
||||
case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
|
||||
struct vfe_cmd_chroma_enhan_config chrom;
|
||||
if (copy_from_user(&chrom,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_enhan_config(&chrom);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
|
||||
case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
|
||||
struct vfe_cmd_chroma_suppression_config chromsup;
|
||||
if (copy_from_user(&chromsup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_sup_config(&chromsup);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASF_CONFIG: {
|
||||
struct vfe_cmd_asf_config asf;
|
||||
if (copy_from_user(&asf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_asf_config(&asf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_SCALER2Y_CONFIG:
|
||||
case VFE_CMD_ID_SCALER2Y_UPDATE: {
|
||||
struct vfe_cmd_scaler2_config ds2y;
|
||||
if (copy_from_user(&ds2y,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_scaler2y_config(&ds2y);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_SCALER2CbCr_CONFIG:
|
||||
case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
|
||||
struct vfe_cmd_scaler2_config ds2cbcr;
|
||||
if (copy_from_user(&ds2cbcr,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_scaler2cbcr_config(&ds2cbcr);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
|
||||
struct vfe_cmd_chroma_subsample_config sub;
|
||||
if (copy_from_user(&sub,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_subsample_config(&sub);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
|
||||
struct vfe_cmd_frame_skip_config fskip;
|
||||
if (copy_from_user(&fskip,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_frame_skip_config(&fskip);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
|
||||
struct vfe_cmd_output_clamp_config clamp;
|
||||
if (copy_from_user(&clamp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_output_clamp_config(&clamp);
|
||||
}
|
||||
break;
|
||||
|
||||
/* module update commands */
|
||||
case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
|
||||
struct vfe_cmd_black_level_config blk;
|
||||
if (copy_from_user(&blk,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_black_level_update(&blk);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
|
||||
struct vfe_cmd_demux_channel_gain_config dmu;
|
||||
if (copy_from_user(&dmu,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demux_channel_gain_update(&dmu);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
|
||||
struct vfe_cmd_demosaic_bpc_update demo_bpc;
|
||||
if (copy_from_user(&demo_bpc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_bpc_update(&demo_bpc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
|
||||
struct vfe_cmd_demosaic_abf_update demo_abf;
|
||||
if (copy_from_user(&demo_abf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_abf_update(&demo_abf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_LA_UPDATE: {
|
||||
struct vfe_cmd_la_config la;
|
||||
if (copy_from_user(&la,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_la_update(&la);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
|
||||
struct vfe_cmd_rgb_gamma_config rgb;
|
||||
if (copy_from_user(&rgb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
rc = vfe_rgb_gamma_update(&rgb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASF_UPDATE: {
|
||||
struct vfe_cmd_asf_update asf;
|
||||
if (copy_from_user(&asf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_asf_update(&asf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
|
||||
struct vfe_cmd_frame_skip_update fskip;
|
||||
if (copy_from_user(&fskip,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_frame_skip_update(&fskip);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
|
||||
struct vfe_cmds_camif_frame fup;
|
||||
if (copy_from_user(&fup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_camif_frame_update(&fup);
|
||||
}
|
||||
break;
|
||||
|
||||
/* stats update commands */
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
|
||||
struct vfe_cmd_stats_af_update afup;
|
||||
if (copy_from_user(&afup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_update_af(&afup);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
|
||||
struct vfe_cmd_stats_wb_exp_update wbexp;
|
||||
if (copy_from_user(&wbexp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_update_wb_exp(&wbexp);
|
||||
}
|
||||
break;
|
||||
|
||||
/* control of start, stop, update, etc... */
|
||||
case VFE_CMD_ID_STOP:
|
||||
vfe_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_GET_HW_VERSION:
|
||||
break;
|
||||
|
||||
/* stats */
|
||||
case VFE_CMD_ID_STATS_SETTING: {
|
||||
struct vfe_cmd_stats_setting stats;
|
||||
if (copy_from_user(&stats,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_setting(&stats);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
|
||||
struct vfe_cmd_stats_af_start af;
|
||||
if (copy_from_user(&af,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_start_af(&af);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
|
||||
vfe_stats_af_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_START: {
|
||||
struct vfe_cmd_stats_wb_exp_start awexp;
|
||||
if (copy_from_user(&awexp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_start_wb_exp(&awexp);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_STOP:
|
||||
vfe_stats_wb_exp_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASYNC_TIMER_SETTING:
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_UPDATE:
|
||||
vfe_update();
|
||||
break;
|
||||
|
||||
/* test gen */
|
||||
case VFE_CMD_ID_TEST_GEN_START:
|
||||
break;
|
||||
|
||||
/*
|
||||
acknowledge from upper layer
|
||||
these are not in general command.
|
||||
|
||||
case VFE_CMD_ID_OUTPUT1_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_OUTPUT2_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_EPOCH1_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_EPOCH2_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_STATS_WB_EXP_ACK:
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
struct msm_vfe_command_8k vfecmd;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
void *cmd_data = NULL;
|
||||
long rc = 0;
|
||||
|
||||
struct vfe_cmd_axi_output_config *axio = NULL;
|
||||
struct vfe_cmd_stats_setting *scfg = NULL;
|
||||
|
||||
if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
|
||||
|
||||
if (copy_from_user(&vfecmd,
|
||||
(void __user *)(cmd->value),
|
||||
sizeof(struct msm_vfe_command_8k)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
|
||||
|
||||
switch (cmd->cmd_type) {
|
||||
case CMD_GENERAL:
|
||||
rc = vfe_proc_general(&vfecmd);
|
||||
break;
|
||||
|
||||
case CMD_STATS_ENABLE:
|
||||
case CMD_STATS_AXI_CFG: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
scfg =
|
||||
kmalloc(sizeof(struct vfe_cmd_stats_setting),
|
||||
GFP_ATOMIC);
|
||||
if (!scfg)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(scfg,
|
||||
(void __user *)(vfecmd.value),
|
||||
vfecmd.length)) {
|
||||
|
||||
kfree(scfg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
regptr = axid->region;
|
||||
if (axid->bufnum1 > 0) {
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
scfg->awbBuffer[i] =
|
||||
(uint32_t)(regptr->paddr);
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (axid->bufnum2 > 0) {
|
||||
for (i = 0; i < axid->bufnum2; i++) {
|
||||
scfg->afBuffer[i] =
|
||||
(uint32_t)(regptr->paddr);
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
|
||||
vfe_stats_config(scfg);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_AXI_CFG: {
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FRAME_BUF_RELEASE: {
|
||||
/* preview buffer release */
|
||||
struct msm_frame *b;
|
||||
unsigned long p;
|
||||
struct vfe_cmd_output_ack fack;
|
||||
|
||||
if (!data)
|
||||
return -EFAULT;
|
||||
|
||||
b = (struct msm_frame *)(cmd->value);
|
||||
p = *(unsigned long *)data;
|
||||
|
||||
b->path = MSM_FRAME_ENC;
|
||||
|
||||
fack.ybufaddr[0] =
|
||||
(uint32_t)(p + b->y_off);
|
||||
|
||||
fack.chromabufaddr[0] =
|
||||
(uint32_t)(p + b->cbcr_off);
|
||||
|
||||
if (b->path == MSM_FRAME_PREV_1)
|
||||
vfe_output1_ack(&fack);
|
||||
|
||||
if (b->path == MSM_FRAME_ENC ||
|
||||
b->path == MSM_FRAME_PREV_2)
|
||||
vfe_output2_ack(&fack);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SNAP_BUF_RELEASE: {
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_BUF_RELEASE: {
|
||||
struct vfe_cmd_stats_wb_exp_ack sack;
|
||||
|
||||
if (!data)
|
||||
return -EFAULT;
|
||||
|
||||
sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
|
||||
vfe_stats_wb_exp_ack(&sack);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT1: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio = memdup_user((void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config));
|
||||
if (IS_ERR(axio))
|
||||
return PTR_ERR(axio);
|
||||
|
||||
vfe_config_axi(OUTPUT_1, axid, axio);
|
||||
vfe_axi_output_config(axio);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT2:
|
||||
case CMD_RAW_PICT_AXI_CFG: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio = memdup_user((void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config));
|
||||
if (IS_ERR(axio))
|
||||
return PTR_ERR(axio);
|
||||
|
||||
vfe_config_axi(OUTPUT_2, axid, axio);
|
||||
|
||||
axio->outputDataSize = 0;
|
||||
vfe_axi_output_config(axio);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_SNAP_O1_AND_O2: {
|
||||
struct axidata *axid;
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio = memdup_user((void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config));
|
||||
if (IS_ERR(axio))
|
||||
return PTR_ERR(axio);
|
||||
|
||||
vfe_config_axi(OUTPUT_1_AND_2,
|
||||
axid, axio);
|
||||
vfe_axi_output_config(axio);
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
kfree(scfg);
|
||||
|
||||
kfree(axio);
|
||||
|
||||
/*
|
||||
if (cmd->length > 256 &&
|
||||
cmd_data &&
|
||||
(cmd->cmd_type == CMD_GENERAL ||
|
||||
cmd->cmd_type == CMD_STATS_DISABLE)) {
|
||||
kfree(cmd_data);
|
||||
}
|
||||
*/
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_init(struct msm_vfe_callback *presp,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = vfe_cmd_init(presp, dev, vfe_syncdata);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Bring up all the required GPIOs and Clocks */
|
||||
return msm_camio_enable(dev);
|
||||
}
|
||||
|
||||
void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
|
||||
{
|
||||
mutex_init(&vfe_lock);
|
||||
fptr->vfe_init = vfe_init;
|
||||
fptr->vfe_enable = vfe_enable;
|
||||
fptr->vfe_config = vfe_config;
|
||||
fptr->vfe_disable = vfe_disable;
|
||||
fptr->vfe_release = vfe_release;
|
||||
vfe_syncdata = data;
|
||||
}
|
|
@ -1,895 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#ifndef __MSM_VFE8X_H__
|
||||
#define __MSM_VFE8X_H__
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define boolean uint8_t
|
||||
|
||||
enum VFE_STATE {
|
||||
VFE_STATE_IDLE,
|
||||
VFE_STATE_ACTIVE
|
||||
};
|
||||
|
||||
enum vfe_cmd_id {
|
||||
/*
|
||||
*Important! Command_ID are arranged in order.
|
||||
*Don't change!*/
|
||||
VFE_CMD_ID_START,
|
||||
VFE_CMD_ID_RESET,
|
||||
|
||||
/* bus and camif config */
|
||||
VFE_CMD_ID_AXI_INPUT_CONFIG,
|
||||
VFE_CMD_ID_CAMIF_CONFIG,
|
||||
VFE_CMD_ID_AXI_OUTPUT_CONFIG,
|
||||
|
||||
/* module config */
|
||||
VFE_CMD_ID_BLACK_LEVEL_CONFIG,
|
||||
VFE_CMD_ID_ROLL_OFF_CONFIG,
|
||||
VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
|
||||
VFE_CMD_ID_DEMOSAIC_CONFIG,
|
||||
VFE_CMD_ID_FOV_CROP_CONFIG,
|
||||
VFE_CMD_ID_MAIN_SCALER_CONFIG,
|
||||
VFE_CMD_ID_WHITE_BALANCE_CONFIG,
|
||||
VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
|
||||
VFE_CMD_ID_LA_CONFIG,
|
||||
VFE_CMD_ID_RGB_GAMMA_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
|
||||
VFE_CMD_ID_ASF_CONFIG,
|
||||
VFE_CMD_ID_SCALER2Y_CONFIG,
|
||||
VFE_CMD_ID_SCALER2CbCr_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
|
||||
VFE_CMD_ID_FRAME_SKIP_CONFIG,
|
||||
VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
|
||||
|
||||
/* test gen */
|
||||
VFE_CMD_ID_TEST_GEN_START,
|
||||
|
||||
VFE_CMD_ID_UPDATE,
|
||||
|
||||
/* ackownledge from upper layer */
|
||||
VFE_CMD_ID_OUTPUT1_ACK,
|
||||
VFE_CMD_ID_OUTPUT2_ACK,
|
||||
VFE_CMD_ID_EPOCH1_ACK,
|
||||
VFE_CMD_ID_EPOCH2_ACK,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
|
||||
VFE_CMD_ID_STATS_WB_EXP_ACK,
|
||||
|
||||
/* module update commands */
|
||||
VFE_CMD_ID_BLACK_LEVEL_UPDATE,
|
||||
VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
|
||||
VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
|
||||
VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
|
||||
VFE_CMD_ID_FOV_CROP_UPDATE,
|
||||
VFE_CMD_ID_WHITE_BALANCE_UPDATE,
|
||||
VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
|
||||
VFE_CMD_ID_LA_UPDATE,
|
||||
VFE_CMD_ID_RGB_GAMMA_UPDATE,
|
||||
VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
|
||||
VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
|
||||
VFE_CMD_ID_MAIN_SCALER_UPDATE,
|
||||
VFE_CMD_ID_SCALER2CbCr_UPDATE,
|
||||
VFE_CMD_ID_SCALER2Y_UPDATE,
|
||||
VFE_CMD_ID_ASF_UPDATE,
|
||||
VFE_CMD_ID_FRAME_SKIP_UPDATE,
|
||||
VFE_CMD_ID_CAMIF_FRAME_UPDATE,
|
||||
|
||||
/* stats update commands */
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
|
||||
VFE_CMD_ID_STATS_WB_EXP_UPDATE,
|
||||
|
||||
/* control of start, stop, update, etc... */
|
||||
VFE_CMD_ID_STOP,
|
||||
VFE_CMD_ID_GET_HW_VERSION,
|
||||
|
||||
/* stats */
|
||||
VFE_CMD_ID_STATS_SETTING,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_START,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
|
||||
VFE_CMD_ID_STATS_WB_EXP_START,
|
||||
VFE_CMD_ID_STATS_WB_EXP_STOP,
|
||||
|
||||
VFE_CMD_ID_ASYNC_TIMER_SETTING,
|
||||
|
||||
/* max id */
|
||||
VFE_CMD_ID_MAX
|
||||
};
|
||||
|
||||
struct vfe_cmd_hw_version {
|
||||
uint32_t minorVersion;
|
||||
uint32_t majorVersion;
|
||||
uint32_t coreVersion;
|
||||
};
|
||||
|
||||
enum VFE_CAMIF_SYNC_EDGE {
|
||||
VFE_CAMIF_SYNC_EDGE_ActiveHigh,
|
||||
VFE_CAMIF_SYNC_EDGE_ActiveLow
|
||||
};
|
||||
|
||||
enum VFE_CAMIF_SYNC_MODE {
|
||||
VFE_CAMIF_SYNC_MODE_APS,
|
||||
VFE_CAMIF_SYNC_MODE_EFS,
|
||||
VFE_CAMIF_SYNC_MODE_ELS,
|
||||
VFE_CAMIF_SYNC_MODE_ILLEGAL
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_efs {
|
||||
uint8_t efsendofline;
|
||||
uint8_t efsstartofline;
|
||||
uint8_t efsendofframe;
|
||||
uint8_t efsstartofframe;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_frame {
|
||||
uint16_t pixelsPerLine;
|
||||
uint16_t linesPerFrame;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_window {
|
||||
uint16_t firstpixel;
|
||||
uint16_t lastpixel;
|
||||
uint16_t firstline;
|
||||
uint16_t lastline;
|
||||
};
|
||||
|
||||
enum CAMIF_SUBSAMPLE_FRAME_SKIP {
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_0,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_subsample {
|
||||
uint16_t pixelskipmask;
|
||||
uint16_t lineskipmask;
|
||||
enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
|
||||
uint8_t frameskipmode;
|
||||
uint8_t pixelskipwrap;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_epoch {
|
||||
uint8_t enable;
|
||||
uint16_t lineindex;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_cfg {
|
||||
enum VFE_CAMIF_SYNC_EDGE vSyncEdge;
|
||||
enum VFE_CAMIF_SYNC_EDGE hSyncEdge;
|
||||
enum VFE_CAMIF_SYNC_MODE syncMode;
|
||||
uint8_t vfeSubSampleEnable;
|
||||
uint8_t busSubSampleEnable;
|
||||
uint8_t irqSubSampleEnable;
|
||||
uint8_t binningEnable;
|
||||
uint8_t misrEnable;
|
||||
};
|
||||
|
||||
struct vfe_cmd_camif_config {
|
||||
struct vfe_cmds_camif_cfg camifConfig;
|
||||
struct vfe_cmds_camif_efs EFS;
|
||||
struct vfe_cmds_camif_frame frame;
|
||||
struct vfe_cmds_camif_window window;
|
||||
struct vfe_cmds_camif_subsample subsample;
|
||||
struct vfe_cmds_camif_epoch epoch1;
|
||||
struct vfe_cmds_camif_epoch epoch2;
|
||||
};
|
||||
|
||||
enum VFE_AXI_OUTPUT_MODE {
|
||||
VFE_AXI_OUTPUT_MODE_Output1,
|
||||
VFE_AXI_OUTPUT_MODE_Output2,
|
||||
VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
|
||||
VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
|
||||
VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
|
||||
VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
|
||||
VFE_AXI_LAST_OUTPUT_MODE_ENUM
|
||||
};
|
||||
|
||||
enum VFE_RAW_WR_PATH_SEL {
|
||||
VFE_RAW_OUTPUT_DISABLED,
|
||||
VFE_RAW_OUTPUT_ENC_CBCR_PATH,
|
||||
VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
|
||||
VFE_RAW_OUTPUT_PATH_INVALID
|
||||
};
|
||||
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE {
|
||||
VFE_RAW_PIXEL_DATA_SIZE_8BIT,
|
||||
VFE_RAW_PIXEL_DATA_SIZE_10BIT,
|
||||
VFE_RAW_PIXEL_DATA_SIZE_12BIT,
|
||||
};
|
||||
|
||||
#define VFE_AXI_OUTPUT_BURST_LENGTH 4
|
||||
#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
|
||||
#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT 3
|
||||
|
||||
struct vfe_cmds_axi_out_per_component {
|
||||
uint16_t imageWidth;
|
||||
uint16_t imageHeight;
|
||||
uint16_t outRowCount;
|
||||
uint16_t outRowIncrement;
|
||||
uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
|
||||
[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
};
|
||||
|
||||
struct vfe_cmds_axi_per_output_path {
|
||||
uint8_t fragmentCount;
|
||||
struct vfe_cmds_axi_out_per_component outputY;
|
||||
struct vfe_cmds_axi_out_per_component outputCbcr;
|
||||
};
|
||||
|
||||
enum VFE_AXI_BURST_LENGTH {
|
||||
VFE_AXI_BURST_LENGTH_IS_2 = 2,
|
||||
VFE_AXI_BURST_LENGTH_IS_4 = 4,
|
||||
VFE_AXI_BURST_LENGTH_IS_8 = 8,
|
||||
VFE_AXI_BURST_LENGTH_IS_16 = 16
|
||||
};
|
||||
|
||||
struct vfe_cmd_axi_output_config {
|
||||
enum VFE_AXI_BURST_LENGTH burstLength;
|
||||
enum VFE_AXI_OUTPUT_MODE outputMode;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
|
||||
struct vfe_cmds_axi_per_output_path output1;
|
||||
struct vfe_cmds_axi_per_output_path output2;
|
||||
};
|
||||
|
||||
struct vfe_cmd_fov_crop_config {
|
||||
uint8_t enable;
|
||||
uint16_t firstPixel;
|
||||
uint16_t lastPixel;
|
||||
uint16_t firstLine;
|
||||
uint16_t lastLine;
|
||||
};
|
||||
|
||||
struct vfe_cmds_main_scaler_stripe_init {
|
||||
uint16_t MNCounterInit;
|
||||
uint16_t phaseInit;
|
||||
};
|
||||
|
||||
struct vfe_cmds_scaler_one_dimension {
|
||||
uint8_t enable;
|
||||
uint16_t inputSize;
|
||||
uint16_t outputSize;
|
||||
uint32_t phaseMultiplicationFactor;
|
||||
uint8_t interpolationResolution;
|
||||
};
|
||||
|
||||
struct vfe_cmd_main_scaler_config {
|
||||
uint8_t enable;
|
||||
struct vfe_cmds_scaler_one_dimension hconfig;
|
||||
struct vfe_cmds_scaler_one_dimension vconfig;
|
||||
struct vfe_cmds_main_scaler_stripe_init MNInitH;
|
||||
struct vfe_cmds_main_scaler_stripe_init MNInitV;
|
||||
};
|
||||
|
||||
struct vfe_cmd_scaler2_config {
|
||||
uint8_t enable;
|
||||
struct vfe_cmds_scaler_one_dimension hconfig;
|
||||
struct vfe_cmds_scaler_one_dimension vconfig;
|
||||
};
|
||||
|
||||
struct vfe_cmd_frame_skip_config {
|
||||
uint8_t output1Period;
|
||||
uint32_t output1Pattern;
|
||||
uint8_t output2Period;
|
||||
uint32_t output2Pattern;
|
||||
};
|
||||
|
||||
struct vfe_cmd_frame_skip_update {
|
||||
uint32_t output1Pattern;
|
||||
uint32_t output2Pattern;
|
||||
};
|
||||
|
||||
struct vfe_cmd_output_clamp_config {
|
||||
uint8_t minCh0;
|
||||
uint8_t minCh1;
|
||||
uint8_t minCh2;
|
||||
uint8_t maxCh0;
|
||||
uint8_t maxCh1;
|
||||
uint8_t maxCh2;
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_subsample_config {
|
||||
uint8_t enable;
|
||||
uint8_t cropEnable;
|
||||
uint8_t vsubSampleEnable;
|
||||
uint8_t hsubSampleEnable;
|
||||
uint8_t vCosited;
|
||||
uint8_t hCosited;
|
||||
uint8_t vCositedPhase;
|
||||
uint8_t hCositedPhase;
|
||||
uint16_t cropWidthFirstPixel;
|
||||
uint16_t cropWidthLastPixel;
|
||||
uint16_t cropHeightFirstLine;
|
||||
uint16_t cropHeightLastLine;
|
||||
};
|
||||
|
||||
enum VFE_START_INPUT_SOURCE {
|
||||
VFE_START_INPUT_SOURCE_CAMIF,
|
||||
VFE_START_INPUT_SOURCE_TESTGEN,
|
||||
VFE_START_INPUT_SOURCE_AXI,
|
||||
VFE_START_INPUT_SOURCE_INVALID
|
||||
};
|
||||
|
||||
enum VFE_START_OPERATION_MODE {
|
||||
VFE_START_OPERATION_MODE_CONTINUOUS,
|
||||
VFE_START_OPERATION_MODE_SNAPSHOT
|
||||
};
|
||||
|
||||
enum VFE_START_PIXEL_PATTERN {
|
||||
VFE_BAYER_RGRGRG,
|
||||
VFE_BAYER_GRGRGR,
|
||||
VFE_BAYER_BGBGBG,
|
||||
VFE_BAYER_GBGBGB,
|
||||
VFE_YUV_YCbYCr,
|
||||
VFE_YUV_YCrYCb,
|
||||
VFE_YUV_CbYCrY,
|
||||
VFE_YUV_CrYCbY
|
||||
};
|
||||
|
||||
enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
|
||||
VFE_BAYER_RAW,
|
||||
VFE_YUV_INTERLEAVED,
|
||||
VFE_YUV_PSEUDO_PLANAR_Y,
|
||||
VFE_YUV_PSEUDO_PLANAR_CBCR
|
||||
};
|
||||
|
||||
enum VFE_YUV_INPUT_COSITING_MODE {
|
||||
VFE_YUV_COSITED,
|
||||
VFE_YUV_INTERPOLATED
|
||||
};
|
||||
|
||||
struct vfe_cmd_start {
|
||||
enum VFE_START_INPUT_SOURCE inputSource;
|
||||
enum VFE_START_OPERATION_MODE operationMode;
|
||||
uint8_t snapshotCount;
|
||||
enum VFE_START_PIXEL_PATTERN pixel;
|
||||
enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
|
||||
};
|
||||
|
||||
struct vfe_cmd_output_ack {
|
||||
uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
};
|
||||
|
||||
#define VFE_STATS_BUFFER_COUNT 3
|
||||
|
||||
struct vfe_cmd_stats_setting {
|
||||
uint16_t frameHDimension;
|
||||
uint16_t frameVDimension;
|
||||
uint8_t afBusPrioritySelection;
|
||||
uint8_t afBusPriority;
|
||||
uint8_t awbBusPrioritySelection;
|
||||
uint8_t awbBusPriority;
|
||||
uint8_t histBusPrioritySelection;
|
||||
uint8_t histBusPriority;
|
||||
uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_start {
|
||||
uint8_t enable;
|
||||
uint8_t windowMode;
|
||||
uint16_t windowHOffset;
|
||||
uint16_t windowVOffset;
|
||||
uint16_t windowWidth;
|
||||
uint16_t windowHeight;
|
||||
uint8_t gridForMultiWindows[16];
|
||||
uint8_t metricSelection;
|
||||
int16_t metricMax;
|
||||
int8_t highPassCoef[7];
|
||||
int8_t bufferHeader;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_update {
|
||||
uint8_t windowMode;
|
||||
uint16_t windowHOffset;
|
||||
uint16_t windowVOffset;
|
||||
uint16_t windowWidth;
|
||||
uint16_t windowHeight;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_start {
|
||||
uint8_t enable;
|
||||
uint8_t wbExpRegions;
|
||||
uint8_t wbExpSubRegion;
|
||||
uint8_t awbYMin;
|
||||
uint8_t awbYMax;
|
||||
int8_t awbMCFG[4];
|
||||
int16_t awbCCFG[4];
|
||||
int8_t axwHeader;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_update {
|
||||
uint8_t wbExpRegions;
|
||||
uint8_t wbExpSubRegion;
|
||||
int8_t awbYMin;
|
||||
int8_t awbYMax;
|
||||
int8_t awbMCFG[4];
|
||||
int16_t awbCCFG[4];
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_ack {
|
||||
uint32_t nextAFOutputBufferAddr;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_ack {
|
||||
uint32_t nextWbExpOutputBufferAddr;
|
||||
};
|
||||
|
||||
struct vfe_cmd_black_level_config {
|
||||
uint8_t enable;
|
||||
uint16_t evenEvenAdjustment;
|
||||
uint16_t evenOddAdjustment;
|
||||
uint16_t oddEvenAdjustment;
|
||||
uint16_t oddOddAdjustment;
|
||||
};
|
||||
|
||||
/* 13*1 */
|
||||
#define VFE_ROLL_OFF_INIT_TABLE_SIZE 13
|
||||
/* 13*16 */
|
||||
#define VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
|
||||
|
||||
struct vfe_cmd_roll_off_config {
|
||||
uint8_t enable;
|
||||
uint16_t gridWidth;
|
||||
uint16_t gridHeight;
|
||||
uint16_t yDelta;
|
||||
uint8_t gridXIndex;
|
||||
uint8_t gridYIndex;
|
||||
uint16_t gridPixelXIndex;
|
||||
uint16_t gridPixelYIndex;
|
||||
uint16_t yDeltaAccum;
|
||||
uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
int16_t deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct vfe_cmd_demux_channel_gain_config {
|
||||
uint16_t ch0EvenGain;
|
||||
uint16_t ch0OddGain;
|
||||
uint16_t ch1Gain;
|
||||
uint16_t ch2Gain;
|
||||
};
|
||||
|
||||
struct vfe_cmds_demosaic_abf {
|
||||
uint8_t enable;
|
||||
uint8_t forceOn;
|
||||
uint8_t shift;
|
||||
uint16_t lpThreshold;
|
||||
uint16_t max;
|
||||
uint16_t min;
|
||||
uint8_t ratio;
|
||||
};
|
||||
|
||||
struct vfe_cmds_demosaic_bpc {
|
||||
uint8_t enable;
|
||||
uint16_t fmaxThreshold;
|
||||
uint16_t fminThreshold;
|
||||
uint16_t redDiffThreshold;
|
||||
uint16_t blueDiffThreshold;
|
||||
uint16_t greenDiffThreshold;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_config {
|
||||
uint8_t enable;
|
||||
uint8_t slopeShift;
|
||||
struct vfe_cmds_demosaic_abf abfConfig;
|
||||
struct vfe_cmds_demosaic_bpc bpcConfig;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_bpc_update {
|
||||
struct vfe_cmds_demosaic_bpc bpcUpdate;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_abf_update {
|
||||
struct vfe_cmds_demosaic_abf abfUpdate;
|
||||
};
|
||||
|
||||
struct vfe_cmd_white_balance_config {
|
||||
uint8_t enable;
|
||||
uint16_t ch2Gain;
|
||||
uint16_t ch1Gain;
|
||||
uint16_t ch0Gain;
|
||||
};
|
||||
|
||||
enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
|
||||
COEF_IS_Q7_SIGNED,
|
||||
COEF_IS_Q8_SIGNED,
|
||||
COEF_IS_Q9_SIGNED,
|
||||
COEF_IS_Q10_SIGNED
|
||||
};
|
||||
|
||||
struct vfe_cmd_color_correction_config {
|
||||
uint8_t enable;
|
||||
enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
|
||||
int16_t C0;
|
||||
int16_t C1;
|
||||
int16_t C2;
|
||||
int16_t C3;
|
||||
int16_t C4;
|
||||
int16_t C5;
|
||||
int16_t C6;
|
||||
int16_t C7;
|
||||
int16_t C8;
|
||||
int16_t K0;
|
||||
int16_t K1;
|
||||
int16_t K2;
|
||||
};
|
||||
|
||||
#define VFE_LA_TABLE_LENGTH 256
|
||||
struct vfe_cmd_la_config {
|
||||
uint8_t enable;
|
||||
int16_t table[VFE_LA_TABLE_LENGTH];
|
||||
};
|
||||
|
||||
#define VFE_GAMMA_TABLE_LENGTH 256
|
||||
enum VFE_RGB_GAMMA_TABLE_SELECT {
|
||||
RGB_GAMMA_CH0_SELECTED,
|
||||
RGB_GAMMA_CH1_SELECTED,
|
||||
RGB_GAMMA_CH2_SELECTED,
|
||||
RGB_GAMMA_CH0_CH1_SELECTED,
|
||||
RGB_GAMMA_CH0_CH2_SELECTED,
|
||||
RGB_GAMMA_CH1_CH2_SELECTED,
|
||||
RGB_GAMMA_CH0_CH1_CH2_SELECTED
|
||||
};
|
||||
|
||||
struct vfe_cmd_rgb_gamma_config {
|
||||
uint8_t enable;
|
||||
enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
|
||||
int16_t table[VFE_GAMMA_TABLE_LENGTH];
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_enhan_config {
|
||||
uint8_t enable;
|
||||
int16_t am;
|
||||
int16_t ap;
|
||||
int16_t bm;
|
||||
int16_t bp;
|
||||
int16_t cm;
|
||||
int16_t cp;
|
||||
int16_t dm;
|
||||
int16_t dp;
|
||||
int16_t kcr;
|
||||
int16_t kcb;
|
||||
int16_t RGBtoYConversionV0;
|
||||
int16_t RGBtoYConversionV1;
|
||||
int16_t RGBtoYConversionV2;
|
||||
uint8_t RGBtoYConversionOffset;
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_suppression_config {
|
||||
uint8_t enable;
|
||||
uint8_t m1;
|
||||
uint8_t m3;
|
||||
uint8_t n1;
|
||||
uint8_t n3;
|
||||
uint8_t nn1;
|
||||
uint8_t mm1;
|
||||
};
|
||||
|
||||
struct vfe_cmd_asf_config {
|
||||
uint8_t enable;
|
||||
uint8_t smoothFilterEnabled;
|
||||
uint8_t sharpMode;
|
||||
uint8_t smoothCoefCenter;
|
||||
uint8_t smoothCoefSurr;
|
||||
uint8_t normalizeFactor;
|
||||
uint8_t sharpK1;
|
||||
uint8_t sharpK2;
|
||||
uint8_t sharpThreshE1;
|
||||
int8_t sharpThreshE2;
|
||||
int8_t sharpThreshE3;
|
||||
int8_t sharpThreshE4;
|
||||
int8_t sharpThreshE5;
|
||||
int8_t filter1Coefficients[9];
|
||||
int8_t filter2Coefficients[9];
|
||||
uint8_t cropEnable;
|
||||
uint16_t cropFirstPixel;
|
||||
uint16_t cropLastPixel;
|
||||
uint16_t cropFirstLine;
|
||||
uint16_t cropLastLine;
|
||||
};
|
||||
|
||||
struct vfe_cmd_asf_update {
|
||||
uint8_t enable;
|
||||
uint8_t smoothFilterEnabled;
|
||||
uint8_t sharpMode;
|
||||
uint8_t smoothCoefCenter;
|
||||
uint8_t smoothCoefSurr;
|
||||
uint8_t normalizeFactor;
|
||||
uint8_t sharpK1;
|
||||
uint8_t sharpK2;
|
||||
uint8_t sharpThreshE1;
|
||||
int8_t sharpThreshE2;
|
||||
int8_t sharpThreshE3;
|
||||
int8_t sharpThreshE4;
|
||||
int8_t sharpThreshE5;
|
||||
int8_t filter1Coefficients[9];
|
||||
int8_t filter2Coefficients[9];
|
||||
uint8_t cropEnable;
|
||||
};
|
||||
|
||||
enum VFE_TEST_GEN_SYNC_EDGE {
|
||||
VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
|
||||
VFE_TEST_GEN_SYNC_EDGE_ActiveLow
|
||||
};
|
||||
|
||||
struct vfe_cmd_test_gen_start {
|
||||
uint8_t pixelDataSelect;
|
||||
uint8_t systematicDataSelect;
|
||||
enum VFE_TEST_GEN_SYNC_EDGE hsyncEdge;
|
||||
enum VFE_TEST_GEN_SYNC_EDGE vsyncEdge;
|
||||
uint16_t numFrame;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
|
||||
uint16_t imageWidth;
|
||||
uint16_t imageHeight;
|
||||
uint32_t startOfFrameOffset;
|
||||
uint32_t endOfFrameNOffset;
|
||||
uint16_t startOfLineOffset;
|
||||
uint16_t endOfLineNOffset;
|
||||
uint16_t hbi;
|
||||
uint8_t vblEnable;
|
||||
uint16_t vbl;
|
||||
uint8_t startOfFrameDummyLine;
|
||||
uint8_t endOfFrameDummyLine;
|
||||
uint8_t unicolorBarEnable;
|
||||
uint8_t colorBarsSplitEnable;
|
||||
uint8_t unicolorBarSelect;
|
||||
enum VFE_START_PIXEL_PATTERN colorBarsPixelPattern;
|
||||
uint8_t colorBarsRotatePeriod;
|
||||
uint16_t testGenRandomSeed;
|
||||
};
|
||||
|
||||
struct vfe_cmd_bus_pm_start {
|
||||
uint8_t output2YWrPmEnable;
|
||||
uint8_t output2CbcrWrPmEnable;
|
||||
uint8_t output1YWrPmEnable;
|
||||
uint8_t output1CbcrWrPmEnable;
|
||||
};
|
||||
|
||||
struct vfe_cmd_camif_frame_update {
|
||||
struct vfe_cmds_camif_frame camifFrame;
|
||||
};
|
||||
|
||||
struct vfe_cmd_sync_timer_setting {
|
||||
uint8_t whichSyncTimer;
|
||||
uint8_t operation;
|
||||
uint8_t polarity;
|
||||
uint16_t repeatCount;
|
||||
uint16_t hsyncCount;
|
||||
uint32_t pclkCount;
|
||||
uint32_t outputDuration;
|
||||
};
|
||||
|
||||
struct vfe_cmd_async_timer_setting {
|
||||
uint8_t whichAsyncTimer;
|
||||
uint8_t operation;
|
||||
uint8_t polarity;
|
||||
uint16_t repeatCount;
|
||||
uint16_t inactiveCount;
|
||||
uint32_t activeCount;
|
||||
};
|
||||
|
||||
struct vfe_frame_skip_counts {
|
||||
uint32_t totalFrameCount;
|
||||
uint32_t output1Count;
|
||||
uint32_t output2Count;
|
||||
};
|
||||
|
||||
enum VFE_AXI_RD_UNPACK_HBI_SEL {
|
||||
VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
|
||||
};
|
||||
|
||||
struct vfe_cmd_axi_input_config {
|
||||
uint32_t fragAddr[4];
|
||||
uint8_t totalFragmentCount;
|
||||
uint16_t ySize;
|
||||
uint16_t xOffset;
|
||||
uint16_t xSize;
|
||||
uint16_t rowIncrement;
|
||||
uint16_t numOfRows;
|
||||
enum VFE_AXI_BURST_LENGTH burstLength;
|
||||
uint8_t unpackPhase;
|
||||
enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE pixelSize;
|
||||
uint8_t padRepeatCountLeft;
|
||||
uint8_t padRepeatCountRight;
|
||||
uint8_t padRepeatCountTop;
|
||||
uint8_t padRepeatCountBottom;
|
||||
uint8_t padLeftComponentSelectCycle0;
|
||||
uint8_t padLeftComponentSelectCycle1;
|
||||
uint8_t padLeftComponentSelectCycle2;
|
||||
uint8_t padLeftComponentSelectCycle3;
|
||||
uint8_t padLeftStopCycle0;
|
||||
uint8_t padLeftStopCycle1;
|
||||
uint8_t padLeftStopCycle2;
|
||||
uint8_t padLeftStopCycle3;
|
||||
uint8_t padRightComponentSelectCycle0;
|
||||
uint8_t padRightComponentSelectCycle1;
|
||||
uint8_t padRightComponentSelectCycle2;
|
||||
uint8_t padRightComponentSelectCycle3;
|
||||
uint8_t padRightStopCycle0;
|
||||
uint8_t padRightStopCycle1;
|
||||
uint8_t padRightStopCycle2;
|
||||
uint8_t padRightStopCycle3;
|
||||
uint8_t padTopLineCount;
|
||||
uint8_t padBottomLineCount;
|
||||
};
|
||||
|
||||
struct vfe_interrupt_status {
|
||||
uint8_t camifErrorIrq;
|
||||
uint8_t camifSofIrq;
|
||||
uint8_t camifEolIrq;
|
||||
uint8_t camifEofIrq;
|
||||
uint8_t camifEpoch1Irq;
|
||||
uint8_t camifEpoch2Irq;
|
||||
uint8_t camifOverflowIrq;
|
||||
uint8_t ceIrq;
|
||||
uint8_t regUpdateIrq;
|
||||
uint8_t resetAckIrq;
|
||||
uint8_t encYPingpongIrq;
|
||||
uint8_t encCbcrPingpongIrq;
|
||||
uint8_t viewYPingpongIrq;
|
||||
uint8_t viewCbcrPingpongIrq;
|
||||
uint8_t rdPingpongIrq;
|
||||
uint8_t afPingpongIrq;
|
||||
uint8_t awbPingpongIrq;
|
||||
uint8_t histPingpongIrq;
|
||||
uint8_t encIrq;
|
||||
uint8_t viewIrq;
|
||||
uint8_t busOverflowIrq;
|
||||
uint8_t afOverflowIrq;
|
||||
uint8_t awbOverflowIrq;
|
||||
uint8_t syncTimer0Irq;
|
||||
uint8_t syncTimer1Irq;
|
||||
uint8_t syncTimer2Irq;
|
||||
uint8_t asyncTimer0Irq;
|
||||
uint8_t asyncTimer1Irq;
|
||||
uint8_t asyncTimer2Irq;
|
||||
uint8_t asyncTimer3Irq;
|
||||
uint8_t axiErrorIrq;
|
||||
uint8_t violationIrq;
|
||||
uint8_t anyErrorIrqs;
|
||||
uint8_t anyOutput1PathIrqs;
|
||||
uint8_t anyOutput2PathIrqs;
|
||||
uint8_t anyOutputPathIrqs;
|
||||
uint8_t anyAsyncTimerIrqs;
|
||||
uint8_t anySyncTimerIrqs;
|
||||
uint8_t anyIrqForActiveStatesOnly;
|
||||
};
|
||||
|
||||
enum VFE_MESSAGE_ID {
|
||||
VFE_MSG_ID_RESET_ACK,
|
||||
VFE_MSG_ID_START_ACK,
|
||||
VFE_MSG_ID_STOP_ACK,
|
||||
VFE_MSG_ID_UPDATE_ACK,
|
||||
VFE_MSG_ID_OUTPUT1,
|
||||
VFE_MSG_ID_OUTPUT2,
|
||||
VFE_MSG_ID_SNAPSHOT_DONE,
|
||||
VFE_MSG_ID_STATS_AUTOFOCUS,
|
||||
VFE_MSG_ID_STATS_WB_EXP,
|
||||
VFE_MSG_ID_EPOCH1,
|
||||
VFE_MSG_ID_EPOCH2,
|
||||
VFE_MSG_ID_SYNC_TIMER0_DONE,
|
||||
VFE_MSG_ID_SYNC_TIMER1_DONE,
|
||||
VFE_MSG_ID_SYNC_TIMER2_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER0_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER1_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER2_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER3_DONE,
|
||||
VFE_MSG_ID_AF_OVERFLOW,
|
||||
VFE_MSG_ID_AWB_OVERFLOW,
|
||||
VFE_MSG_ID_AXI_ERROR,
|
||||
VFE_MSG_ID_CAMIF_OVERFLOW,
|
||||
VFE_MSG_ID_VIOLATION,
|
||||
VFE_MSG_ID_CAMIF_ERROR,
|
||||
VFE_MSG_ID_BUS_OVERFLOW,
|
||||
};
|
||||
|
||||
struct vfe_msg_stats_autofocus {
|
||||
uint32_t afBuffer;
|
||||
uint32_t frameCounter;
|
||||
};
|
||||
|
||||
struct vfe_msg_stats_wb_exp {
|
||||
uint32_t awbBuffer;
|
||||
uint32_t frameCounter;
|
||||
};
|
||||
|
||||
struct vfe_frame_bpc_info {
|
||||
uint32_t greenDefectPixelCount;
|
||||
uint32_t redBlueDefectPixelCount;
|
||||
};
|
||||
|
||||
struct vfe_frame_asf_info {
|
||||
uint32_t asfMaxEdge;
|
||||
uint32_t asfHbiCount;
|
||||
};
|
||||
|
||||
struct vfe_msg_camif_status {
|
||||
uint8_t camifState;
|
||||
uint32_t pixelCount;
|
||||
uint32_t lineCount;
|
||||
};
|
||||
|
||||
struct vfe_bus_pm_per_path {
|
||||
uint32_t yWrPmStats0;
|
||||
uint32_t yWrPmStats1;
|
||||
uint32_t cbcrWrPmStats0;
|
||||
uint32_t cbcrWrPmStats1;
|
||||
};
|
||||
|
||||
struct vfe_bus_performance_monitor {
|
||||
struct vfe_bus_pm_per_path encPathPmInfo;
|
||||
struct vfe_bus_pm_per_path viewPathPmInfo;
|
||||
};
|
||||
|
||||
struct vfe_irq_thread_msg {
|
||||
uint32_t vfeIrqStatus;
|
||||
uint32_t camifStatus;
|
||||
uint32_t demosaicStatus;
|
||||
uint32_t asfMaxEdge;
|
||||
struct vfe_bus_performance_monitor pmInfo;
|
||||
};
|
||||
|
||||
struct vfe_msg_output {
|
||||
uint32_t yBuffer;
|
||||
uint32_t cbcrBuffer;
|
||||
struct vfe_frame_bpc_info bpcInfo;
|
||||
struct vfe_frame_asf_info asfInfo;
|
||||
uint32_t frameCounter;
|
||||
struct vfe_bus_pm_per_path pmData;
|
||||
};
|
||||
|
||||
struct vfe_message {
|
||||
enum VFE_MESSAGE_ID _d;
|
||||
union {
|
||||
struct vfe_msg_output msgOutput1;
|
||||
struct vfe_msg_output msgOutput2;
|
||||
struct vfe_msg_stats_autofocus msgStatsAf;
|
||||
struct vfe_msg_stats_wb_exp msgStatsWbExp;
|
||||
struct vfe_msg_camif_status msgCamifError;
|
||||
struct vfe_bus_performance_monitor msgBusOverflow;
|
||||
} _u;
|
||||
};
|
||||
|
||||
/* New one for 8k */
|
||||
struct msm_vfe_command_8k {
|
||||
int32_t id;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct vfe_frame_extra {
|
||||
struct vfe_frame_bpc_info bpcInfo;
|
||||
struct vfe_frame_asf_info asfInfo;
|
||||
uint32_t frameCounter;
|
||||
struct vfe_bus_pm_per_path pmData;
|
||||
};
|
||||
#endif /* __MSM_VFE8X_H__ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,762 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/gpio.h>
|
||||
#include "mt9d112.h"
|
||||
|
||||
/* Micron MT9D112 Registers and their values */
|
||||
/* Sensor Core Registers */
|
||||
#define REG_MT9D112_MODEL_ID 0x3000
|
||||
#define MT9D112_MODEL_ID 0x1580
|
||||
|
||||
/* SOC Registers Page 1 */
|
||||
#define REG_MT9D112_SENSOR_RESET 0x301A
|
||||
#define REG_MT9D112_STANDBY_CONTROL 0x3202
|
||||
#define REG_MT9D112_MCU_BOOT 0x3386
|
||||
|
||||
struct mt9d112_work {
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static struct mt9d112_work *mt9d112_sensorw;
|
||||
static struct i2c_client *mt9d112_client;
|
||||
|
||||
struct mt9d112_ctrl {
|
||||
const struct msm_camera_sensor_info *sensordata;
|
||||
};
|
||||
|
||||
|
||||
static struct mt9d112_ctrl *mt9d112_ctrl;
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
|
||||
DECLARE_MUTEX(mt9d112_sem);
|
||||
|
||||
|
||||
/*=============================================================
|
||||
EXTERNAL DECLARATIONS
|
||||
==============================================================*/
|
||||
extern struct mt9d112_reg mt9d112_regs;
|
||||
|
||||
|
||||
/*=============================================================*/
|
||||
|
||||
static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = gpio_request(dev->sensor_reset, "mt9d112");
|
||||
|
||||
if (!rc) {
|
||||
rc = gpio_direction_output(dev->sensor_reset, 0);
|
||||
mdelay(20);
|
||||
rc = gpio_direction_output(dev->sensor_reset, 1);
|
||||
}
|
||||
|
||||
gpio_free(dev->sensor_reset);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_txdata(unsigned short saddr,
|
||||
unsigned char *txdata, int length)
|
||||
{
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = 0,
|
||||
.len = length,
|
||||
.buf = txdata,
|
||||
},
|
||||
};
|
||||
|
||||
if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
|
||||
CDBG("mt9d112_i2c_txdata failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_write(unsigned short saddr,
|
||||
unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
|
||||
{
|
||||
int32_t rc = -EIO;
|
||||
unsigned char buf[4];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
switch (width) {
|
||||
case WORD_LEN: {
|
||||
buf[0] = (waddr & 0xFF00)>>8;
|
||||
buf[1] = (waddr & 0x00FF);
|
||||
buf[2] = (wdata & 0xFF00)>>8;
|
||||
buf[3] = (wdata & 0x00FF);
|
||||
|
||||
rc = mt9d112_i2c_txdata(saddr, buf, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case BYTE_LEN: {
|
||||
buf[0] = waddr;
|
||||
buf[1] = wdata;
|
||||
rc = mt9d112_i2c_txdata(saddr, buf, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
CDBG(
|
||||
"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
|
||||
waddr, wdata);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_write_table(
|
||||
struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
|
||||
int num_of_items_in_table)
|
||||
{
|
||||
int i;
|
||||
int32_t rc = -EIO;
|
||||
|
||||
for (i = 0; i < num_of_items_in_table; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
reg_conf_tbl->waddr, reg_conf_tbl->wdata,
|
||||
reg_conf_tbl->width);
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (reg_conf_tbl->mdelay_time != 0)
|
||||
mdelay(reg_conf_tbl->mdelay_time);
|
||||
reg_conf_tbl++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_i2c_rxdata(unsigned short saddr,
|
||||
unsigned char *rxdata, int length)
|
||||
{
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = rxdata,
|
||||
},
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = length,
|
||||
.buf = rxdata,
|
||||
},
|
||||
};
|
||||
|
||||
if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
|
||||
CDBG("mt9d112_i2c_rxdata failed!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_read(unsigned short saddr,
|
||||
unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
unsigned char buf[4];
|
||||
|
||||
if (!rdata)
|
||||
return -EIO;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
switch (width) {
|
||||
case WORD_LEN: {
|
||||
buf[0] = (raddr & 0xFF00)>>8;
|
||||
buf[1] = (raddr & 0x00FF);
|
||||
|
||||
rc = mt9d112_i2c_rxdata(saddr, buf, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*rdata = buf[0] << 8 | buf[1];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
CDBG("mt9d112_i2c_read failed!\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_set_lens_roll_off(void)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
|
||||
mt9d112_regs.rftbl_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long mt9d112_reg_init(void)
|
||||
{
|
||||
int32_t array_length;
|
||||
int32_t i;
|
||||
long rc;
|
||||
|
||||
/* PLL Setup Start */
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
|
||||
mt9d112_regs.plltbl_size);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
/* PLL Setup End */
|
||||
|
||||
array_length = mt9d112_regs.prev_snap_reg_settings_size;
|
||||
|
||||
/* Configure sensor for Preview mode and Snapshot mode */
|
||||
for (i = 0; i < array_length; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
mt9d112_regs.prev_snap_reg_settings[i].register_address,
|
||||
mt9d112_regs.prev_snap_reg_settings[i].register_value,
|
||||
WORD_LEN);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Configure for Noise Reduction, Saturation and Aperture Correction */
|
||||
array_length = mt9d112_regs.noise_reduction_reg_settings_size;
|
||||
|
||||
for (i = 0; i < array_length; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
mt9d112_regs.noise_reduction_reg_settings[i].register_address,
|
||||
mt9d112_regs.noise_reduction_reg_settings[i].register_value,
|
||||
WORD_LEN);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set Color Kill Saturation point to optimum value */
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x35A4,
|
||||
0x0593,
|
||||
WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
|
||||
mt9d112_regs.stbl_size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_set_lens_roll_off();
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mt9d112_set_sensor_mode(int mode)
|
||||
{
|
||||
uint16_t clock;
|
||||
long rc = 0;
|
||||
|
||||
switch (mode) {
|
||||
case SENSOR_PREVIEW_MODE:
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA20C, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0004, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA215, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0004, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA20B, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0000, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
clock = 0x0250;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x341C, clock, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0001, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mdelay(5);
|
||||
break;
|
||||
|
||||
case SENSOR_SNAPSHOT_MODE:
|
||||
/* Switch to lower fps for Snapshot */
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x341C, 0x0120, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA120, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0002, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0002, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mt9d112_set_effect(int mode, int effect)
|
||||
{
|
||||
uint16_t reg_addr;
|
||||
uint16_t reg_val;
|
||||
long rc = 0;
|
||||
|
||||
switch (mode) {
|
||||
case SENSOR_PREVIEW_MODE:
|
||||
/* Context A Special Effects */
|
||||
reg_addr = 0x2799;
|
||||
break;
|
||||
|
||||
case SENSOR_SNAPSHOT_MODE:
|
||||
/* Context B Special Effects */
|
||||
reg_addr = 0x279B;
|
||||
break;
|
||||
|
||||
default:
|
||||
reg_addr = 0x2799;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (effect) {
|
||||
case CAMERA_EFFECT_OFF: {
|
||||
reg_val = 0x6440;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_MONO: {
|
||||
reg_val = 0x6441;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_NEGATIVE: {
|
||||
reg_val = 0x6443;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_SOLARIZE: {
|
||||
reg_val = 0x6445;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_SEPIA: {
|
||||
reg_val = 0x6442;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_PASTEL:
|
||||
case CAMERA_EFFECT_MOSAIC:
|
||||
case CAMERA_EFFECT_RESIZE:
|
||||
return -EINVAL;
|
||||
|
||||
default: {
|
||||
reg_val = 0x6440;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Refresh Sequencer */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0005, WORD_LEN);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
|
||||
{
|
||||
uint16_t model_id = 0;
|
||||
int rc = 0;
|
||||
|
||||
CDBG("init entry \n");
|
||||
rc = mt9d112_reset(data);
|
||||
if (rc < 0) {
|
||||
CDBG("reset failed!\n");
|
||||
goto init_probe_fail;
|
||||
}
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron suggested Power up block Start:
|
||||
* Put MCU into Reset - Stop MCU */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
/* Pull MCU from Reset - Start MCU */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron Suggested - Power up block */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
/* FUSED_DEFECT_CORRECTION */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x33F4, 0x031D, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron suggested Power up block End */
|
||||
/* Read the Model ID of the sensor */
|
||||
rc = mt9d112_i2c_read(mt9d112_client->addr,
|
||||
REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
CDBG("mt9d112 model_id = 0x%x\n", model_id);
|
||||
|
||||
/* Check if it matches it with the value in Datasheet */
|
||||
if (model_id != MT9D112_MODEL_ID) {
|
||||
rc = -EINVAL;
|
||||
goto init_probe_fail;
|
||||
}
|
||||
|
||||
rc = mt9d112_reg_init();
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
return rc;
|
||||
|
||||
init_probe_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
|
||||
if (!mt9d112_ctrl) {
|
||||
CDBG("mt9d112_init failed!\n");
|
||||
rc = -ENOMEM;
|
||||
goto init_done;
|
||||
}
|
||||
|
||||
if (data)
|
||||
mt9d112_ctrl->sensordata = data;
|
||||
|
||||
/* Input MCLK = 24MHz */
|
||||
msm_camio_clk_rate_set(24000000);
|
||||
mdelay(5);
|
||||
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
|
||||
rc = mt9d112_sensor_init_probe(data);
|
||||
if (rc < 0) {
|
||||
CDBG("mt9d112_sensor_init failed!\n");
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
init_done:
|
||||
return rc;
|
||||
|
||||
init_fail:
|
||||
kfree(mt9d112_ctrl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_init_client(struct i2c_client *client)
|
||||
{
|
||||
/* Initialize the MSM_CAMI2C Chip */
|
||||
init_waitqueue_head(&mt9d112_wait_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_config(void __user *argp)
|
||||
{
|
||||
struct sensor_cfg_data cfg_data;
|
||||
long rc = 0;
|
||||
|
||||
if (copy_from_user(&cfg_data,
|
||||
(void *)argp,
|
||||
sizeof(struct sensor_cfg_data)))
|
||||
return -EFAULT;
|
||||
|
||||
/* down(&mt9d112_sem); */
|
||||
|
||||
CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
|
||||
cfg_data.cfgtype, cfg_data.mode);
|
||||
|
||||
switch (cfg_data.cfgtype) {
|
||||
case CFG_SET_MODE:
|
||||
rc = mt9d112_set_sensor_mode(
|
||||
cfg_data.mode);
|
||||
break;
|
||||
|
||||
case CFG_SET_EFFECT:
|
||||
rc = mt9d112_set_effect(cfg_data.mode,
|
||||
cfg_data.cfg.effect);
|
||||
break;
|
||||
|
||||
case CFG_GET_AF_MAX_STEPS:
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* up(&mt9d112_sem); */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_release(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* down(&mt9d112_sem); */
|
||||
|
||||
kfree(mt9d112_ctrl);
|
||||
/* up(&mt9d112_sem); */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int rc = 0;
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
rc = -ENOTSUPP;
|
||||
goto probe_failure;
|
||||
}
|
||||
|
||||
mt9d112_sensorw =
|
||||
kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
|
||||
|
||||
if (!mt9d112_sensorw) {
|
||||
rc = -ENOMEM;
|
||||
goto probe_failure;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, mt9d112_sensorw);
|
||||
mt9d112_init_client(client);
|
||||
mt9d112_client = client;
|
||||
|
||||
CDBG("mt9d112_probe succeeded!\n");
|
||||
|
||||
return 0;
|
||||
|
||||
probe_failure:
|
||||
kfree(mt9d112_sensorw);
|
||||
mt9d112_sensorw = NULL;
|
||||
CDBG("mt9d112_probe failed!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mt9d112_i2c_id[] = {
|
||||
{ "mt9d112", 0},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver mt9d112_i2c_driver = {
|
||||
.id_table = mt9d112_i2c_id,
|
||||
.probe = mt9d112_i2c_probe,
|
||||
.remove = __exit_p(mt9d112_i2c_remove),
|
||||
.driver = {
|
||||
.name = "mt9d112",
|
||||
},
|
||||
};
|
||||
|
||||
static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
|
||||
struct msm_sensor_ctrl *s)
|
||||
{
|
||||
int rc = i2c_add_driver(&mt9d112_i2c_driver);
|
||||
if (rc < 0 || mt9d112_client == NULL) {
|
||||
rc = -ENOTSUPP;
|
||||
goto probe_done;
|
||||
}
|
||||
|
||||
/* Input MCLK = 24MHz */
|
||||
msm_camio_clk_rate_set(24000000);
|
||||
mdelay(5);
|
||||
|
||||
rc = mt9d112_sensor_init_probe(info);
|
||||
if (rc < 0)
|
||||
goto probe_done;
|
||||
|
||||
s->s_init = mt9d112_sensor_init;
|
||||
s->s_release = mt9d112_sensor_release;
|
||||
s->s_config = mt9d112_sensor_config;
|
||||
|
||||
probe_done:
|
||||
CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __mt9d112_probe(struct platform_device *pdev)
|
||||
{
|
||||
return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
|
||||
}
|
||||
|
||||
static struct platform_driver msm_camera_driver = {
|
||||
.probe = __mt9d112_probe,
|
||||
.driver = {
|
||||
.name = "msm_camera_mt9d112",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mt9d112_init(void)
|
||||
{
|
||||
return platform_driver_register(&msm_camera_driver);
|
||||
}
|
||||
|
||||
module_init(mt9d112_init);
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef MT9D112_H
|
||||
#define MT9D112_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
enum mt9d112_width {
|
||||
WORD_LEN,
|
||||
BYTE_LEN
|
||||
};
|
||||
|
||||
struct mt9d112_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
enum mt9d112_width width;
|
||||
unsigned short mdelay_time;
|
||||
};
|
||||
|
||||
struct mt9d112_reg {
|
||||
const struct register_address_value_pair *prev_snap_reg_settings;
|
||||
uint16_t prev_snap_reg_settings_size;
|
||||
const struct register_address_value_pair *noise_reduction_reg_settings;
|
||||
uint16_t noise_reduction_reg_settings_size;
|
||||
const struct mt9d112_i2c_reg_conf *plltbl;
|
||||
uint16_t plltbl_size;
|
||||
const struct mt9d112_i2c_reg_conf *stbl;
|
||||
uint16_t stbl_size;
|
||||
const struct mt9d112_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* MT9D112_H */
|
|
@ -1,307 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9d112.h"
|
||||
|
||||
struct register_address_value_pair
|
||||
preview_snapshot_mode_reg_settings_array[] = {
|
||||
{0x338C, 0x2703},
|
||||
{0x3390, 800}, /* Output Width (P) = 640 */
|
||||
{0x338C, 0x2705},
|
||||
{0x3390, 600}, /* Output Height (P) = 480 */
|
||||
{0x338C, 0x2707},
|
||||
{0x3390, 0x0640}, /* Output Width (S) = 1600 */
|
||||
{0x338C, 0x2709},
|
||||
{0x3390, 0x04B0}, /* Output Height (S) = 1200 */
|
||||
{0x338C, 0x270D},
|
||||
{0x3390, 0x0000}, /* Row Start (P) = 0 */
|
||||
{0x338C, 0x270F},
|
||||
{0x3390, 0x0000}, /* Column Start (P) = 0 */
|
||||
{0x338C, 0x2711},
|
||||
{0x3390, 0x04BD}, /* Row End (P) = 1213 */
|
||||
{0x338C, 0x2713},
|
||||
{0x3390, 0x064D}, /* Column End (P) = 1613 */
|
||||
{0x338C, 0x2715},
|
||||
{0x3390, 0x0000}, /* Extra Delay (P) = 0 */
|
||||
{0x338C, 0x2717},
|
||||
{0x3390, 0x2111}, /* Row Speed (P) = 8465 */
|
||||
{0x338C, 0x2719},
|
||||
{0x3390, 0x046C}, /* Read Mode (P) = 1132 */
|
||||
{0x338C, 0x271B},
|
||||
{0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
|
||||
{0x338C, 0x271D},
|
||||
{0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
|
||||
{0x338C, 0x271F},
|
||||
{0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
|
||||
{0x338C, 0x2721},
|
||||
{0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
|
||||
{0x338C, 0x2723},
|
||||
{0x3390, 659}, /* Frame Lines (P) = 679 */
|
||||
{0x338C, 0x2725},
|
||||
{0x3390, 0x0824}, /* Line Length (P) = 2084 */
|
||||
{0x338C, 0x2727},
|
||||
{0x3390, 0x2020},
|
||||
{0x338C, 0x2729},
|
||||
{0x3390, 0x2020},
|
||||
{0x338C, 0x272B},
|
||||
{0x3390, 0x1020},
|
||||
{0x338C, 0x272D},
|
||||
{0x3390, 0x2007},
|
||||
{0x338C, 0x272F},
|
||||
{0x3390, 0x0004}, /* Row Start(S) = 4 */
|
||||
{0x338C, 0x2731},
|
||||
{0x3390, 0x0004}, /* Column Start(S) = 4 */
|
||||
{0x338C, 0x2733},
|
||||
{0x3390, 0x04BB}, /* Row End(S) = 1211 */
|
||||
{0x338C, 0x2735},
|
||||
{0x3390, 0x064B}, /* Column End(S) = 1611 */
|
||||
{0x338C, 0x2737},
|
||||
{0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
|
||||
{0x338C, 0x2739},
|
||||
{0x3390, 0x2111}, /* Row Speed(S) = 8465 */
|
||||
{0x338C, 0x273B},
|
||||
{0x3390, 0x0024}, /* Read Mode(S) = 36 */
|
||||
{0x338C, 0x273D},
|
||||
{0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
|
||||
{0x338C, 0x2741},
|
||||
{0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
|
||||
{0x338C, 0x2745},
|
||||
{0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
|
||||
{0x338C, 0x2747},
|
||||
{0x3390, 0x0824}, /* Line Length(S) = 2084 */
|
||||
{0x338C, 0x2751},
|
||||
{0x3390, 0x0000}, /* Crop_X0(P) = 0 */
|
||||
{0x338C, 0x2753},
|
||||
{0x3390, 0x0320}, /* Crop_X1(P) = 800 */
|
||||
{0x338C, 0x2755},
|
||||
{0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
|
||||
{0x338C, 0x2757},
|
||||
{0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
|
||||
{0x338C, 0x275F},
|
||||
{0x3390, 0x0000}, /* Crop_X0(S) = 0 */
|
||||
{0x338C, 0x2761},
|
||||
{0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
|
||||
{0x338C, 0x2763},
|
||||
{0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
|
||||
{0x338C, 0x2765},
|
||||
{0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
|
||||
{0x338C, 0x222E},
|
||||
{0x3390, 0x00A0}, /* R9 Step = 160 */
|
||||
{0x338C, 0xA408},
|
||||
{0x3390, 0x001F},
|
||||
{0x338C, 0xA409},
|
||||
{0x3390, 0x0021},
|
||||
{0x338C, 0xA40A},
|
||||
{0x3390, 0x0025},
|
||||
{0x338C, 0xA40B},
|
||||
{0x3390, 0x0027},
|
||||
{0x338C, 0x2411},
|
||||
{0x3390, 0x00A0},
|
||||
{0x338C, 0x2413},
|
||||
{0x3390, 0x00C0},
|
||||
{0x338C, 0x2415},
|
||||
{0x3390, 0x00A0},
|
||||
{0x338C, 0x2417},
|
||||
{0x3390, 0x00C0},
|
||||
{0x338C, 0x2799},
|
||||
{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
|
||||
{0x338C, 0x279B},
|
||||
{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
|
||||
};
|
||||
|
||||
static struct register_address_value_pair
|
||||
noise_reduction_reg_settings_array[] = {
|
||||
{0x338C, 0xA76D},
|
||||
{0x3390, 0x0003},
|
||||
{0x338C, 0xA76E},
|
||||
{0x3390, 0x0003},
|
||||
{0x338C, 0xA76F},
|
||||
{0x3390, 0},
|
||||
{0x338C, 0xA770},
|
||||
{0x3390, 21},
|
||||
{0x338C, 0xA771},
|
||||
{0x3390, 37},
|
||||
{0x338C, 0xA772},
|
||||
{0x3390, 63},
|
||||
{0x338C, 0xA773},
|
||||
{0x3390, 100},
|
||||
{0x338C, 0xA774},
|
||||
{0x3390, 128},
|
||||
{0x338C, 0xA775},
|
||||
{0x3390, 151},
|
||||
{0x338C, 0xA776},
|
||||
{0x3390, 169},
|
||||
{0x338C, 0xA777},
|
||||
{0x3390, 186},
|
||||
{0x338C, 0xA778},
|
||||
{0x3390, 199},
|
||||
{0x338C, 0xA779},
|
||||
{0x3390, 210},
|
||||
{0x338C, 0xA77A},
|
||||
{0x3390, 220},
|
||||
{0x338C, 0xA77B},
|
||||
{0x3390, 228},
|
||||
{0x338C, 0xA77C},
|
||||
{0x3390, 234},
|
||||
{0x338C, 0xA77D},
|
||||
{0x3390, 240},
|
||||
{0x338C, 0xA77E},
|
||||
{0x3390, 244},
|
||||
{0x338C, 0xA77F},
|
||||
{0x3390, 248},
|
||||
{0x338C, 0xA780},
|
||||
{0x3390, 252},
|
||||
{0x338C, 0xA781},
|
||||
{0x3390, 255},
|
||||
{0x338C, 0xA782},
|
||||
{0x3390, 0},
|
||||
{0x338C, 0xA783},
|
||||
{0x3390, 21},
|
||||
{0x338C, 0xA784},
|
||||
{0x3390, 37},
|
||||
{0x338C, 0xA785},
|
||||
{0x3390, 63},
|
||||
{0x338C, 0xA786},
|
||||
{0x3390, 100},
|
||||
{0x338C, 0xA787},
|
||||
{0x3390, 128},
|
||||
{0x338C, 0xA788},
|
||||
{0x3390, 151},
|
||||
{0x338C, 0xA789},
|
||||
{0x3390, 169},
|
||||
{0x338C, 0xA78A},
|
||||
{0x3390, 186},
|
||||
{0x338C, 0xA78B},
|
||||
{0x3390, 199},
|
||||
{0x338C, 0xA78C},
|
||||
{0x3390, 210},
|
||||
{0x338C, 0xA78D},
|
||||
{0x3390, 220},
|
||||
{0x338C, 0xA78E},
|
||||
{0x3390, 228},
|
||||
{0x338C, 0xA78F},
|
||||
{0x3390, 234},
|
||||
{0x338C, 0xA790},
|
||||
{0x3390, 240},
|
||||
{0x338C, 0xA791},
|
||||
{0x3390, 244},
|
||||
{0x338C, 0xA793},
|
||||
{0x3390, 252},
|
||||
{0x338C, 0xA794},
|
||||
{0x3390, 255},
|
||||
{0x338C, 0xA103},
|
||||
{0x3390, 6},
|
||||
};
|
||||
|
||||
static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
|
||||
{ 0x34CE, 0x81A0, WORD_LEN, 0 },
|
||||
{ 0x34D0, 0x6331, WORD_LEN, 0 },
|
||||
{ 0x34D2, 0x3394, WORD_LEN, 0 },
|
||||
{ 0x34D4, 0x9966, WORD_LEN, 0 },
|
||||
{ 0x34D6, 0x4B25, WORD_LEN, 0 },
|
||||
{ 0x34D8, 0x2670, WORD_LEN, 0 },
|
||||
{ 0x34DA, 0x724C, WORD_LEN, 0 },
|
||||
{ 0x34DC, 0xFFFD, WORD_LEN, 0 },
|
||||
{ 0x34DE, 0x00CA, WORD_LEN, 0 },
|
||||
{ 0x34E6, 0x00AC, WORD_LEN, 0 },
|
||||
{ 0x34EE, 0x0EE1, WORD_LEN, 0 },
|
||||
{ 0x34F6, 0x0D87, WORD_LEN, 0 },
|
||||
{ 0x3500, 0xE1F7, WORD_LEN, 0 },
|
||||
{ 0x3508, 0x1CF4, WORD_LEN, 0 },
|
||||
{ 0x3510, 0x1D28, WORD_LEN, 0 },
|
||||
{ 0x3518, 0x1F26, WORD_LEN, 0 },
|
||||
{ 0x3520, 0x2220, WORD_LEN, 0 },
|
||||
{ 0x3528, 0x333D, WORD_LEN, 0 },
|
||||
{ 0x3530, 0x15D9, WORD_LEN, 0 },
|
||||
{ 0x3538, 0xCFB8, WORD_LEN, 0 },
|
||||
{ 0x354C, 0x05FE, WORD_LEN, 0 },
|
||||
{ 0x3544, 0x05F8, WORD_LEN, 0 },
|
||||
{ 0x355C, 0x0596, WORD_LEN, 0 },
|
||||
{ 0x3554, 0x0611, WORD_LEN, 0 },
|
||||
{ 0x34E0, 0x00F2, WORD_LEN, 0 },
|
||||
{ 0x34E8, 0x00A8, WORD_LEN, 0 },
|
||||
{ 0x34F0, 0x0F7B, WORD_LEN, 0 },
|
||||
{ 0x34F8, 0x0CD7, WORD_LEN, 0 },
|
||||
{ 0x3502, 0xFEDB, WORD_LEN, 0 },
|
||||
{ 0x350A, 0x13E4, WORD_LEN, 0 },
|
||||
{ 0x3512, 0x1F2C, WORD_LEN, 0 },
|
||||
{ 0x351A, 0x1D20, WORD_LEN, 0 },
|
||||
{ 0x3522, 0x2422, WORD_LEN, 0 },
|
||||
{ 0x352A, 0x2925, WORD_LEN, 0 },
|
||||
{ 0x3532, 0x1D04, WORD_LEN, 0 },
|
||||
{ 0x353A, 0xFBF2, WORD_LEN, 0 },
|
||||
{ 0x354E, 0x0616, WORD_LEN, 0 },
|
||||
{ 0x3546, 0x0597, WORD_LEN, 0 },
|
||||
{ 0x355E, 0x05CD, WORD_LEN, 0 },
|
||||
{ 0x3556, 0x0529, WORD_LEN, 0 },
|
||||
{ 0x34E4, 0x00B2, WORD_LEN, 0 },
|
||||
{ 0x34EC, 0x005E, WORD_LEN, 0 },
|
||||
{ 0x34F4, 0x0F43, WORD_LEN, 0 },
|
||||
{ 0x34FC, 0x0E2F, WORD_LEN, 0 },
|
||||
{ 0x3506, 0xF9FC, WORD_LEN, 0 },
|
||||
{ 0x350E, 0x0CE4, WORD_LEN, 0 },
|
||||
{ 0x3516, 0x1E1E, WORD_LEN, 0 },
|
||||
{ 0x351E, 0x1B19, WORD_LEN, 0 },
|
||||
{ 0x3526, 0x151B, WORD_LEN, 0 },
|
||||
{ 0x352E, 0x1416, WORD_LEN, 0 },
|
||||
{ 0x3536, 0x10FC, WORD_LEN, 0 },
|
||||
{ 0x353E, 0xC018, WORD_LEN, 0 },
|
||||
{ 0x3552, 0x06B4, WORD_LEN, 0 },
|
||||
{ 0x354A, 0x0506, WORD_LEN, 0 },
|
||||
{ 0x3562, 0x06AB, WORD_LEN, 0 },
|
||||
{ 0x355A, 0x063A, WORD_LEN, 0 },
|
||||
{ 0x34E2, 0x00E5, WORD_LEN, 0 },
|
||||
{ 0x34EA, 0x008B, WORD_LEN, 0 },
|
||||
{ 0x34F2, 0x0E4C, WORD_LEN, 0 },
|
||||
{ 0x34FA, 0x0CA3, WORD_LEN, 0 },
|
||||
{ 0x3504, 0x0907, WORD_LEN, 0 },
|
||||
{ 0x350C, 0x1DFD, WORD_LEN, 0 },
|
||||
{ 0x3514, 0x1E24, WORD_LEN, 0 },
|
||||
{ 0x351C, 0x2529, WORD_LEN, 0 },
|
||||
{ 0x3524, 0x1D20, WORD_LEN, 0 },
|
||||
{ 0x352C, 0x2332, WORD_LEN, 0 },
|
||||
{ 0x3534, 0x10E9, WORD_LEN, 0 },
|
||||
{ 0x353C, 0x0BCB, WORD_LEN, 0 },
|
||||
{ 0x3550, 0x04EF, WORD_LEN, 0 },
|
||||
{ 0x3548, 0x0609, WORD_LEN, 0 },
|
||||
{ 0x3560, 0x0580, WORD_LEN, 0 },
|
||||
{ 0x3558, 0x05DD, WORD_LEN, 0 },
|
||||
{ 0x3540, 0x0000, WORD_LEN, 0 },
|
||||
{ 0x3542, 0x0000, WORD_LEN, 0 }
|
||||
};
|
||||
|
||||
static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
|
||||
{ 0x341E, 0x8F09, WORD_LEN, 0 },
|
||||
{ 0x341C, 0x0250, WORD_LEN, 0 },
|
||||
{ 0x341E, 0x8F09, WORD_LEN, 5 },
|
||||
{ 0x341E, 0x8F08, WORD_LEN, 0 }
|
||||
};
|
||||
|
||||
/* Refresh Sequencer */
|
||||
static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
|
||||
{ 0x338C, 0x2799, WORD_LEN, 0},
|
||||
{ 0x3390, 0x6440, WORD_LEN, 5},
|
||||
{ 0x338C, 0x279B, WORD_LEN, 0},
|
||||
{ 0x3390, 0x6440, WORD_LEN, 5},
|
||||
{ 0x338C, 0xA103, WORD_LEN, 0},
|
||||
{ 0x3390, 0x0005, WORD_LEN, 5},
|
||||
{ 0x338C, 0xA103, WORD_LEN, 0},
|
||||
{ 0x3390, 0x0006, WORD_LEN, 5}
|
||||
};
|
||||
|
||||
struct mt9d112_reg mt9d112_regs = {
|
||||
.prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
|
||||
.prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array),
|
||||
.noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
|
||||
.noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array),
|
||||
.plltbl = pll_setup_tbl,
|
||||
.plltbl_size = ARRAY_SIZE(pll_setup_tbl),
|
||||
.stbl = sequencer_tbl,
|
||||
.stbl_size = ARRAY_SIZE(sequencer_tbl),
|
||||
.rftbl = lens_roll_off_tbl,
|
||||
.rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MT9T012_H
|
||||
#define MT9T012_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct reg_struct {
|
||||
uint16_t vt_pix_clk_div; /* 0x0300 */
|
||||
uint16_t vt_sys_clk_div; /* 0x0302 */
|
||||
uint16_t pre_pll_clk_div; /* 0x0304 */
|
||||
uint16_t pll_multiplier; /* 0x0306 */
|
||||
uint16_t op_pix_clk_div; /* 0x0308 */
|
||||
uint16_t op_sys_clk_div; /* 0x030A */
|
||||
uint16_t scale_m; /* 0x0404 */
|
||||
uint16_t row_speed; /* 0x3016 */
|
||||
uint16_t x_addr_start; /* 0x3004 */
|
||||
uint16_t x_addr_end; /* 0x3008 */
|
||||
uint16_t y_addr_start; /* 0x3002 */
|
||||
uint16_t y_addr_end; /* 0x3006 */
|
||||
uint16_t read_mode; /* 0x3040 */
|
||||
uint16_t x_output_size ; /* 0x034C */
|
||||
uint16_t y_output_size; /* 0x034E */
|
||||
uint16_t line_length_pck; /* 0x300C */
|
||||
uint16_t frame_length_lines; /* 0x300A */
|
||||
uint16_t coarse_int_time; /* 0x3012 */
|
||||
uint16_t fine_int_time; /* 0x3014 */
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_reg {
|
||||
struct reg_struct *reg_pat;
|
||||
uint16_t reg_pat_size;
|
||||
struct mt9p012_i2c_reg_conf *ttbl;
|
||||
uint16_t ttbl_size;
|
||||
struct mt9p012_i2c_reg_conf *lctbl;
|
||||
uint16_t lctbl_size;
|
||||
struct mt9p012_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* MT9T012_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,573 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9p012.h"
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/*Micron settings from Applications for lower power consumption.*/
|
||||
struct reg_struct mt9p012_reg_pat[2] = {
|
||||
{ /* Preview */
|
||||
/* vt_pix_clk_div REG=0x0300 */
|
||||
6, /* 5 */
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 */
|
||||
60,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8, /* 10 */
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2597,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1949,
|
||||
|
||||
/* read_mode REG=0x3040
|
||||
* Preview 2x2 skipping */
|
||||
0x00C3,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
1296,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
972,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
3784,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
1057,
|
||||
|
||||
/* coarse_integration_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_integration_time REG=0x3014 */
|
||||
1764
|
||||
},
|
||||
{ /*Snapshot*/
|
||||
/* vt_pix_clk_div REG=0x0300 */
|
||||
6,
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306
|
||||
* 60 for 10fps snapshot */
|
||||
60,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2615,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1967,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x0041,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
2608,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
1960,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
3911,
|
||||
|
||||
/* frame_length_lines REG=0x300A //10 fps snapshot */
|
||||
2045,
|
||||
|
||||
/* coarse_integration_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_integration_time REG=0x3014 */
|
||||
882
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = {
|
||||
{0x3044, 0x0544 & 0xFBFF},
|
||||
{0x30CA, 0x0004 | 0x0001},
|
||||
{0x30D4, 0x9020 & 0x7FFF},
|
||||
{0x31E0, 0x0003 & 0xFFFE},
|
||||
{0x3180, 0x91FF & 0x7FFF},
|
||||
{0x301A, (0x10CC | 0x8000) & 0xFFF7},
|
||||
{0x301E, 0x0000},
|
||||
{0x3780, 0x0000},
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = {
|
||||
/* [Lens shading 85 Percent TL84] */
|
||||
/* P_RD_P0Q0 */
|
||||
{0x360A, 0x7FEF},
|
||||
/* P_RD_P0Q1 */
|
||||
{0x360C, 0x232C},
|
||||
/* P_RD_P0Q2 */
|
||||
{0x360E, 0x7050},
|
||||
/* P_RD_P0Q3 */
|
||||
{0x3610, 0xF3CC},
|
||||
/* P_RD_P0Q4 */
|
||||
{0x3612, 0x89D1},
|
||||
/* P_RD_P1Q0 */
|
||||
{0x364A, 0xBE0D},
|
||||
/* P_RD_P1Q1 */
|
||||
{0x364C, 0x9ACB},
|
||||
/* P_RD_P1Q2 */
|
||||
{0x364E, 0x2150},
|
||||
/* P_RD_P1Q3 */
|
||||
{0x3650, 0xB26B},
|
||||
/* P_RD_P1Q4 */
|
||||
{0x3652, 0x9511},
|
||||
/* P_RD_P2Q0 */
|
||||
{0x368A, 0x2151},
|
||||
/* P_RD_P2Q1 */
|
||||
{0x368C, 0x00AD},
|
||||
/* P_RD_P2Q2 */
|
||||
{0x368E, 0x8334},
|
||||
/* P_RD_P2Q3 */
|
||||
{0x3690, 0x478E},
|
||||
/* P_RD_P2Q4 */
|
||||
{0x3692, 0x0515},
|
||||
/* P_RD_P3Q0 */
|
||||
{0x36CA, 0x0710},
|
||||
/* P_RD_P3Q1 */
|
||||
{0x36CC, 0x452D},
|
||||
/* P_RD_P3Q2 */
|
||||
{0x36CE, 0xF352},
|
||||
/* P_RD_P3Q3 */
|
||||
{0x36D0, 0x190F},
|
||||
/* P_RD_P3Q4 */
|
||||
{0x36D2, 0x4413},
|
||||
/* P_RD_P4Q0 */
|
||||
{0x370A, 0xD112},
|
||||
/* P_RD_P4Q1 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q2 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q3 */
|
||||
{0x3710, 0xDC11},
|
||||
/* P_RD_P4Q4 */
|
||||
{0x3712, 0xD776},
|
||||
/* P_GR_P0Q0 */
|
||||
{0x3600, 0x1750},
|
||||
/* P_GR_P0Q1 */
|
||||
{0x3602, 0xF0AC},
|
||||
/* P_GR_P0Q2 */
|
||||
{0x3604, 0x4711},
|
||||
/* P_GR_P0Q3 */
|
||||
{0x3606, 0x07CE},
|
||||
/* P_GR_P0Q4 */
|
||||
{0x3608, 0x96B2},
|
||||
/* P_GR_P1Q0 */
|
||||
{0x3640, 0xA9AE},
|
||||
/* P_GR_P1Q1 */
|
||||
{0x3642, 0xF9AC},
|
||||
/* P_GR_P1Q2 */
|
||||
{0x3644, 0x39F1},
|
||||
/* P_GR_P1Q3 */
|
||||
{0x3646, 0x016F},
|
||||
/* P_GR_P1Q4 */
|
||||
{0x3648, 0x8AB2},
|
||||
/* P_GR_P2Q0 */
|
||||
{0x3680, 0x1752},
|
||||
/* P_GR_P2Q1 */
|
||||
{0x3682, 0x70F0},
|
||||
/* P_GR_P2Q2 */
|
||||
{0x3684, 0x83F5},
|
||||
/* P_GR_P2Q3 */
|
||||
{0x3686, 0x8392},
|
||||
/* P_GR_P2Q4 */
|
||||
{0x3688, 0x1FD6},
|
||||
/* P_GR_P3Q0 */
|
||||
{0x36C0, 0x1131},
|
||||
/* P_GR_P3Q1 */
|
||||
{0x36C2, 0x3DAF},
|
||||
/* P_GR_P3Q2 */
|
||||
{0x36C4, 0x89B4},
|
||||
/* P_GR_P3Q3 */
|
||||
{0x36C6, 0xA391},
|
||||
/* P_GR_P3Q4 */
|
||||
{0x36C8, 0x1334},
|
||||
/* P_GR_P4Q0 */
|
||||
{0x3700, 0xDC13},
|
||||
/* P_GR_P4Q1 */
|
||||
{0x3702, 0xD052},
|
||||
/* P_GR_P4Q2 */
|
||||
{0x3704, 0x5156},
|
||||
/* P_GR_P4Q3 */
|
||||
{0x3706, 0x1F13},
|
||||
/* P_GR_P4Q4 */
|
||||
{0x3708, 0x8C38},
|
||||
/* P_BL_P0Q0 */
|
||||
{0x3614, 0x0050},
|
||||
/* P_BL_P0Q1 */
|
||||
{0x3616, 0xBD4C},
|
||||
/* P_BL_P0Q2 */
|
||||
{0x3618, 0x41B0},
|
||||
/* P_BL_P0Q3 */
|
||||
{0x361A, 0x660D},
|
||||
/* P_BL_P0Q4 */
|
||||
{0x361C, 0xC590},
|
||||
/* P_BL_P1Q0 */
|
||||
{0x3654, 0x87EC},
|
||||
/* P_BL_P1Q1 */
|
||||
{0x3656, 0xE44C},
|
||||
/* P_BL_P1Q2 */
|
||||
{0x3658, 0x302E},
|
||||
/* P_BL_P1Q3 */
|
||||
{0x365A, 0x106E},
|
||||
/* P_BL_P1Q4 */
|
||||
{0x365C, 0xB58E},
|
||||
/* P_BL_P2Q0 */
|
||||
{0x3694, 0x0DD1},
|
||||
/* P_BL_P2Q1 */
|
||||
{0x3696, 0x2A50},
|
||||
/* P_BL_P2Q2 */
|
||||
{0x3698, 0xC793},
|
||||
/* P_BL_P2Q3 */
|
||||
{0x369A, 0xE8F1},
|
||||
/* P_BL_P2Q4 */
|
||||
{0x369C, 0x4174},
|
||||
/* P_BL_P3Q0 */
|
||||
{0x36D4, 0x01EF},
|
||||
/* P_BL_P3Q1 */
|
||||
{0x36D6, 0x06CF},
|
||||
/* P_BL_P3Q2 */
|
||||
{0x36D8, 0x8D91},
|
||||
/* P_BL_P3Q3 */
|
||||
{0x36DA, 0x91F0},
|
||||
/* P_BL_P3Q4 */
|
||||
{0x36DC, 0x52EF},
|
||||
/* P_BL_P4Q0 */
|
||||
{0x3714, 0xA6D2},
|
||||
/* P_BL_P4Q1 */
|
||||
{0x3716, 0xA312},
|
||||
/* P_BL_P4Q2 */
|
||||
{0x3718, 0x2695},
|
||||
/* P_BL_P4Q3 */
|
||||
{0x371A, 0x3953},
|
||||
/* P_BL_P4Q4 */
|
||||
{0x371C, 0x9356},
|
||||
/* P_GB_P0Q0 */
|
||||
{0x361E, 0x7EAF},
|
||||
/* P_GB_P0Q1 */
|
||||
{0x3620, 0x2A4C},
|
||||
/* P_GB_P0Q2 */
|
||||
{0x3622, 0x49F0},
|
||||
{0x3624, 0xF1EC},
|
||||
/* P_GB_P0Q4 */
|
||||
{0x3626, 0xC670},
|
||||
/* P_GB_P1Q0 */
|
||||
{0x365E, 0x8E0C},
|
||||
/* P_GB_P1Q1 */
|
||||
{0x3660, 0xC2A9},
|
||||
/* P_GB_P1Q2 */
|
||||
{0x3662, 0x274F},
|
||||
/* P_GB_P1Q3 */
|
||||
{0x3664, 0xADAB},
|
||||
/* P_GB_P1Q4 */
|
||||
{0x3666, 0x8EF0},
|
||||
/* P_GB_P2Q0 */
|
||||
{0x369E, 0x09B1},
|
||||
/* P_GB_P2Q1 */
|
||||
{0x36A0, 0xAA2E},
|
||||
/* P_GB_P2Q2 */
|
||||
{0x36A2, 0xC3D3},
|
||||
/* P_GB_P2Q3 */
|
||||
{0x36A4, 0x7FAF},
|
||||
/* P_GB_P2Q4 */
|
||||
{0x36A6, 0x3F34},
|
||||
/* P_GB_P3Q0 */
|
||||
{0x36DE, 0x4C8F},
|
||||
/* P_GB_P3Q1 */
|
||||
{0x36E0, 0x886E},
|
||||
/* P_GB_P3Q2 */
|
||||
{0x36E2, 0xE831},
|
||||
/* P_GB_P3Q3 */
|
||||
{0x36E4, 0x1FD0},
|
||||
/* P_GB_P3Q4 */
|
||||
{0x36E6, 0x1192},
|
||||
/* P_GB_P4Q0 */
|
||||
{0x371E, 0xB952},
|
||||
/* P_GB_P4Q1 */
|
||||
{0x3720, 0x6DCF},
|
||||
/* P_GB_P4Q2 */
|
||||
{0x3722, 0x1B55},
|
||||
/* P_GB_P4Q3 */
|
||||
{0x3724, 0xA112},
|
||||
/* P_GB_P4Q4 */
|
||||
{0x3726, 0x82F6},
|
||||
/* POLY_ORIGIN_C */
|
||||
{0x3782, 0x0510},
|
||||
/* POLY_ORIGIN_R */
|
||||
{0x3784, 0x0390},
|
||||
/* POLY_SC_ENABLE */
|
||||
{0x3780, 0x8000},
|
||||
};
|
||||
|
||||
/* rolloff table for illuminant A */
|
||||
struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = {
|
||||
/* P_RD_P0Q0 */
|
||||
{0x360A, 0x7FEF},
|
||||
/* P_RD_P0Q1 */
|
||||
{0x360C, 0x232C},
|
||||
/* P_RD_P0Q2 */
|
||||
{0x360E, 0x7050},
|
||||
/* P_RD_P0Q3 */
|
||||
{0x3610, 0xF3CC},
|
||||
/* P_RD_P0Q4 */
|
||||
{0x3612, 0x89D1},
|
||||
/* P_RD_P1Q0 */
|
||||
{0x364A, 0xBE0D},
|
||||
/* P_RD_P1Q1 */
|
||||
{0x364C, 0x9ACB},
|
||||
/* P_RD_P1Q2 */
|
||||
{0x364E, 0x2150},
|
||||
/* P_RD_P1Q3 */
|
||||
{0x3650, 0xB26B},
|
||||
/* P_RD_P1Q4 */
|
||||
{0x3652, 0x9511},
|
||||
/* P_RD_P2Q0 */
|
||||
{0x368A, 0x2151},
|
||||
/* P_RD_P2Q1 */
|
||||
{0x368C, 0x00AD},
|
||||
/* P_RD_P2Q2 */
|
||||
{0x368E, 0x8334},
|
||||
/* P_RD_P2Q3 */
|
||||
{0x3690, 0x478E},
|
||||
/* P_RD_P2Q4 */
|
||||
{0x3692, 0x0515},
|
||||
/* P_RD_P3Q0 */
|
||||
{0x36CA, 0x0710},
|
||||
/* P_RD_P3Q1 */
|
||||
{0x36CC, 0x452D},
|
||||
/* P_RD_P3Q2 */
|
||||
{0x36CE, 0xF352},
|
||||
/* P_RD_P3Q3 */
|
||||
{0x36D0, 0x190F},
|
||||
/* P_RD_P3Q4 */
|
||||
{0x36D2, 0x4413},
|
||||
/* P_RD_P4Q0 */
|
||||
{0x370A, 0xD112},
|
||||
/* P_RD_P4Q1 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q2 */
|
||||
{0x370E, 0x6375},
|
||||
/* P_RD_P4Q3 */
|
||||
{0x3710, 0xDC11},
|
||||
/* P_RD_P4Q4 */
|
||||
{0x3712, 0xD776},
|
||||
/* P_GR_P0Q0 */
|
||||
{0x3600, 0x1750},
|
||||
/* P_GR_P0Q1 */
|
||||
{0x3602, 0xF0AC},
|
||||
/* P_GR_P0Q2 */
|
||||
{0x3604, 0x4711},
|
||||
/* P_GR_P0Q3 */
|
||||
{0x3606, 0x07CE},
|
||||
/* P_GR_P0Q4 */
|
||||
{0x3608, 0x96B2},
|
||||
/* P_GR_P1Q0 */
|
||||
{0x3640, 0xA9AE},
|
||||
/* P_GR_P1Q1 */
|
||||
{0x3642, 0xF9AC},
|
||||
/* P_GR_P1Q2 */
|
||||
{0x3644, 0x39F1},
|
||||
/* P_GR_P1Q3 */
|
||||
{0x3646, 0x016F},
|
||||
/* P_GR_P1Q4 */
|
||||
{0x3648, 0x8AB2},
|
||||
/* P_GR_P2Q0 */
|
||||
{0x3680, 0x1752},
|
||||
/* P_GR_P2Q1 */
|
||||
{0x3682, 0x70F0},
|
||||
/* P_GR_P2Q2 */
|
||||
{0x3684, 0x83F5},
|
||||
/* P_GR_P2Q3 */
|
||||
{0x3686, 0x8392},
|
||||
/* P_GR_P2Q4 */
|
||||
{0x3688, 0x1FD6},
|
||||
/* P_GR_P3Q0 */
|
||||
{0x36C0, 0x1131},
|
||||
/* P_GR_P3Q1 */
|
||||
{0x36C2, 0x3DAF},
|
||||
/* P_GR_P3Q2 */
|
||||
{0x36C4, 0x89B4},
|
||||
/* P_GR_P3Q3 */
|
||||
{0x36C6, 0xA391},
|
||||
/* P_GR_P3Q4 */
|
||||
{0x36C8, 0x1334},
|
||||
/* P_GR_P4Q0 */
|
||||
{0x3700, 0xDC13},
|
||||
/* P_GR_P4Q1 */
|
||||
{0x3702, 0xD052},
|
||||
/* P_GR_P4Q2 */
|
||||
{0x3704, 0x5156},
|
||||
/* P_GR_P4Q3 */
|
||||
{0x3706, 0x1F13},
|
||||
/* P_GR_P4Q4 */
|
||||
{0x3708, 0x8C38},
|
||||
/* P_BL_P0Q0 */
|
||||
{0x3614, 0x0050},
|
||||
/* P_BL_P0Q1 */
|
||||
{0x3616, 0xBD4C},
|
||||
/* P_BL_P0Q2 */
|
||||
{0x3618, 0x41B0},
|
||||
/* P_BL_P0Q3 */
|
||||
{0x361A, 0x660D},
|
||||
/* P_BL_P0Q4 */
|
||||
{0x361C, 0xC590},
|
||||
/* P_BL_P1Q0 */
|
||||
{0x3654, 0x87EC},
|
||||
/* P_BL_P1Q1 */
|
||||
{0x3656, 0xE44C},
|
||||
/* P_BL_P1Q2 */
|
||||
{0x3658, 0x302E},
|
||||
/* P_BL_P1Q3 */
|
||||
{0x365A, 0x106E},
|
||||
/* P_BL_P1Q4 */
|
||||
{0x365C, 0xB58E},
|
||||
/* P_BL_P2Q0 */
|
||||
{0x3694, 0x0DD1},
|
||||
/* P_BL_P2Q1 */
|
||||
{0x3696, 0x2A50},
|
||||
/* P_BL_P2Q2 */
|
||||
{0x3698, 0xC793},
|
||||
/* P_BL_P2Q3 */
|
||||
{0x369A, 0xE8F1},
|
||||
/* P_BL_P2Q4 */
|
||||
{0x369C, 0x4174},
|
||||
/* P_BL_P3Q0 */
|
||||
{0x36D4, 0x01EF},
|
||||
/* P_BL_P3Q1 */
|
||||
{0x36D6, 0x06CF},
|
||||
/* P_BL_P3Q2 */
|
||||
{0x36D8, 0x8D91},
|
||||
/* P_BL_P3Q3 */
|
||||
{0x36DA, 0x91F0},
|
||||
/* P_BL_P3Q4 */
|
||||
{0x36DC, 0x52EF},
|
||||
/* P_BL_P4Q0 */
|
||||
{0x3714, 0xA6D2},
|
||||
/* P_BL_P4Q1 */
|
||||
{0x3716, 0xA312},
|
||||
/* P_BL_P4Q2 */
|
||||
{0x3718, 0x2695},
|
||||
/* P_BL_P4Q3 */
|
||||
{0x371A, 0x3953},
|
||||
/* P_BL_P4Q4 */
|
||||
{0x371C, 0x9356},
|
||||
/* P_GB_P0Q0 */
|
||||
{0x361E, 0x7EAF},
|
||||
/* P_GB_P0Q1 */
|
||||
{0x3620, 0x2A4C},
|
||||
/* P_GB_P0Q2 */
|
||||
{0x3622, 0x49F0},
|
||||
{0x3624, 0xF1EC},
|
||||
/* P_GB_P0Q4 */
|
||||
{0x3626, 0xC670},
|
||||
/* P_GB_P1Q0 */
|
||||
{0x365E, 0x8E0C},
|
||||
/* P_GB_P1Q1 */
|
||||
{0x3660, 0xC2A9},
|
||||
/* P_GB_P1Q2 */
|
||||
{0x3662, 0x274F},
|
||||
/* P_GB_P1Q3 */
|
||||
{0x3664, 0xADAB},
|
||||
/* P_GB_P1Q4 */
|
||||
{0x3666, 0x8EF0},
|
||||
/* P_GB_P2Q0 */
|
||||
{0x369E, 0x09B1},
|
||||
/* P_GB_P2Q1 */
|
||||
{0x36A0, 0xAA2E},
|
||||
/* P_GB_P2Q2 */
|
||||
{0x36A2, 0xC3D3},
|
||||
/* P_GB_P2Q3 */
|
||||
{0x36A4, 0x7FAF},
|
||||
/* P_GB_P2Q4 */
|
||||
{0x36A6, 0x3F34},
|
||||
/* P_GB_P3Q0 */
|
||||
{0x36DE, 0x4C8F},
|
||||
/* P_GB_P3Q1 */
|
||||
{0x36E0, 0x886E},
|
||||
/* P_GB_P3Q2 */
|
||||
{0x36E2, 0xE831},
|
||||
/* P_GB_P3Q3 */
|
||||
{0x36E4, 0x1FD0},
|
||||
/* P_GB_P3Q4 */
|
||||
{0x36E6, 0x1192},
|
||||
/* P_GB_P4Q0 */
|
||||
{0x371E, 0xB952},
|
||||
/* P_GB_P4Q1 */
|
||||
{0x3720, 0x6DCF},
|
||||
/* P_GB_P4Q2 */
|
||||
{0x3722, 0x1B55},
|
||||
/* P_GB_P4Q3 */
|
||||
{0x3724, 0xA112},
|
||||
/* P_GB_P4Q4 */
|
||||
{0x3726, 0x82F6},
|
||||
/* POLY_ORIGIN_C */
|
||||
{0x3782, 0x0510},
|
||||
/* POLY_ORIGIN_R */
|
||||
{0x3784, 0x0390},
|
||||
/* POLY_SC_ENABLE */
|
||||
{0x3780, 0x8000},
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_reg mt9p012_regs = {
|
||||
.reg_pat = &mt9p012_reg_pat[0],
|
||||
.reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
|
||||
.ttbl = &mt9p012_test_tbl[0],
|
||||
.ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
|
||||
.lctbl = &mt9p012_lc_tbl[0],
|
||||
.lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl),
|
||||
.rftbl = &mt9p012_rolloff_tbl[0],
|
||||
.rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef MT9T013_H
|
||||
#define MT9T013_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct reg_struct {
|
||||
uint16_t vt_pix_clk_div; /* 0x0300 */
|
||||
uint16_t vt_sys_clk_div; /* 0x0302 */
|
||||
uint16_t pre_pll_clk_div; /* 0x0304 */
|
||||
uint16_t pll_multiplier; /* 0x0306 */
|
||||
uint16_t op_pix_clk_div; /* 0x0308 */
|
||||
uint16_t op_sys_clk_div; /* 0x030A */
|
||||
uint16_t scale_m; /* 0x0404 */
|
||||
uint16_t row_speed; /* 0x3016 */
|
||||
uint16_t x_addr_start; /* 0x3004 */
|
||||
uint16_t x_addr_end; /* 0x3008 */
|
||||
uint16_t y_addr_start; /* 0x3002 */
|
||||
uint16_t y_addr_end; /* 0x3006 */
|
||||
uint16_t read_mode; /* 0x3040 */
|
||||
uint16_t x_output_size; /* 0x034C */
|
||||
uint16_t y_output_size; /* 0x034E */
|
||||
uint16_t line_length_pck; /* 0x300C */
|
||||
uint16_t frame_length_lines; /* 0x300A */
|
||||
uint16_t coarse_int_time; /* 0x3012 */
|
||||
uint16_t fine_int_time; /* 0x3014 */
|
||||
};
|
||||
|
||||
struct mt9t013_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
};
|
||||
|
||||
struct mt9t013_reg {
|
||||
struct reg_struct *reg_pat;
|
||||
uint16_t reg_pat_size;
|
||||
struct mt9t013_i2c_reg_conf *ttbl;
|
||||
uint16_t ttbl_size;
|
||||
struct mt9t013_i2c_reg_conf *lctbl;
|
||||
uint16_t lctbl_size;
|
||||
struct mt9t013_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* #define MT9T013_H */
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9t013.h"
|
||||
#include <linux/kernel.h>
|
||||
|
||||
struct reg_struct const mt9t013_reg_pat[2] = {
|
||||
{ /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
|
||||
/* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
|
||||
* if this change */
|
||||
8,
|
||||
|
||||
/* vt_sys_clk_div: REG=0x0302 update get_snapshot_fps
|
||||
* if this change */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
|
||||
* if this change */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 60 for 30fps preview, 40
|
||||
* for 20fps preview
|
||||
* 46 for 30fps preview, try 47/48 to increase further */
|
||||
46,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2053,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1541,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x046C,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
1024,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
768,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
2616,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
916,
|
||||
|
||||
/* coarse_int_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_int_time REG=0x3014 */
|
||||
1461
|
||||
},
|
||||
{ /*Snapshot */
|
||||
/* vt_pix_clk_div REG=0x0300 update get_snapshot_fps
|
||||
* if this change */
|
||||
8,
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 update get_snapshot_fps
|
||||
* if this change */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
|
||||
* if this change */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 50 for 15fps snapshot,
|
||||
* 40 for 10fps snapshot
|
||||
* 46 for 30fps snapshot, try 47/48 to increase further */
|
||||
46,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2071,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1551,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x0024,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
2064,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
1544,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
2952,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
1629,
|
||||
|
||||
/* coarse_int_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_int_time REG=0x3014 */
|
||||
733
|
||||
}
|
||||
};
|
||||
|
||||
struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = {
|
||||
{ 0x3044, 0x0544 & 0xFBFF },
|
||||
{ 0x30CA, 0x0004 | 0x0001 },
|
||||
{ 0x30D4, 0x9020 & 0x7FFF },
|
||||
{ 0x31E0, 0x0003 & 0xFFFE },
|
||||
{ 0x3180, 0x91FF & 0x7FFF },
|
||||
{ 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
|
||||
{ 0x301E, 0x0000 },
|
||||
{ 0x3780, 0x0000 },
|
||||
};
|
||||
|
||||
/* [Lens shading 85 Percent TL84] */
|
||||
struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = {
|
||||
{ 0x360A, 0x0290 }, /* P_RD_P0Q0 */
|
||||
{ 0x360C, 0xC92D }, /* P_RD_P0Q1 */
|
||||
{ 0x360E, 0x0771 }, /* P_RD_P0Q2 */
|
||||
{ 0x3610, 0xE38C }, /* P_RD_P0Q3 */
|
||||
{ 0x3612, 0xD74F }, /* P_RD_P0Q4 */
|
||||
{ 0x364A, 0x168C }, /* P_RD_P1Q0 */
|
||||
{ 0x364C, 0xCACB }, /* P_RD_P1Q1 */
|
||||
{ 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
|
||||
{ 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
|
||||
{ 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
|
||||
{ 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
|
||||
{ 0x368C, 0x200B }, /* P_RD_P2Q1 */
|
||||
{ 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
|
||||
{ 0x3690, 0xD04F }, /* P_RD_P2Q3 */
|
||||
{ 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
|
||||
{ 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
|
||||
{ 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
|
||||
{ 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
|
||||
{ 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
|
||||
{ 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
|
||||
{ 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
|
||||
{ 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
|
||||
{ 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
|
||||
{ 0x3710, 0x8195 }, /* P_RD_P4Q3 */
|
||||
{ 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
|
||||
{ 0x3600, 0x0230 }, /* P_GR_P0Q0 */
|
||||
{ 0x3602, 0x58AD }, /* P_GR_P0Q1 */
|
||||
{ 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
|
||||
{ 0x3606, 0x260D }, /* P_GR_P0Q3 */
|
||||
{ 0x3608, 0xF530 }, /* P_GR_P0Q4 */
|
||||
{ 0x3640, 0x17EB }, /* P_GR_P1Q0 */
|
||||
{ 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
|
||||
{ 0x3644, 0x87CE }, /* P_GR_P1Q2 */
|
||||
{ 0x3646, 0xC02E }, /* P_GR_P1Q3 */
|
||||
{ 0x3648, 0xF48F }, /* P_GR_P1Q4 */
|
||||
{ 0x3680, 0x5350 }, /* P_GR_P2Q0 */
|
||||
{ 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
|
||||
{ 0x3684, 0x4312 }, /* P_GR_P2Q2 */
|
||||
{ 0x3686, 0xC652 }, /* P_GR_P2Q3 */
|
||||
{ 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
|
||||
{ 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
|
||||
{ 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
|
||||
{ 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
|
||||
{ 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
|
||||
{ 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
|
||||
{ 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
|
||||
{ 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
|
||||
{ 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
|
||||
{ 0x3706, 0xB594 }, /* P_GR_P4Q3 */
|
||||
{ 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
|
||||
{ 0x3614, 0x0230 }, /* P_BL_P0Q0 */
|
||||
{ 0x3616, 0x160D }, /* P_BL_P0Q1 */
|
||||
{ 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
|
||||
{ 0x361A, 0x98AB }, /* P_BL_P0Q3 */
|
||||
{ 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
|
||||
{ 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
|
||||
{ 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
|
||||
{ 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
|
||||
{ 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
|
||||
{ 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
|
||||
{ 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
|
||||
{ 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
|
||||
{ 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
|
||||
{ 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
|
||||
{ 0x369C, 0xC374 }, /* P_BL_P2Q4 */
|
||||
{ 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
|
||||
{ 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
|
||||
{ 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
|
||||
{ 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
|
||||
{ 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
|
||||
{ 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
|
||||
{ 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
|
||||
{ 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
|
||||
{ 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
|
||||
{ 0x371C, 0x6338 }, /* P_BL_P4Q4 */
|
||||
{ 0x361E, 0x0350 }, /* P_GB_P0Q0 */
|
||||
{ 0x3620, 0x91AE }, /* P_GB_P0Q1 */
|
||||
{ 0x3622, 0x0571 }, /* P_GB_P0Q2 */
|
||||
{ 0x3624, 0x100D }, /* P_GB_P0Q3 */
|
||||
{ 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
|
||||
{ 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
|
||||
{ 0x3660, 0x50ED }, /* P_GB_P1Q1 */
|
||||
{ 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
|
||||
{ 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
|
||||
{ 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
|
||||
{ 0x369E, 0x5470 }, /* P_GB_P2Q0 */
|
||||
{ 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
|
||||
{ 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
|
||||
{ 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
|
||||
{ 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
|
||||
{ 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
|
||||
{ 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
|
||||
{ 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
|
||||
{ 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
|
||||
{ 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
|
||||
{ 0x371E, 0x9651 }, /* P_GB_P4Q0 */
|
||||
{ 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
|
||||
{ 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
|
||||
{ 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
|
||||
{ 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
|
||||
{ 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
|
||||
{ 0x3784, 0x0320 }, /* POLY_ORIGIN_R */
|
||||
{ 0x3780, 0x8000 } /* POLY_SC_ENABLE */
|
||||
};
|
||||
|
||||
struct mt9t013_reg mt9t013_regs = {
|
||||
.reg_pat = &mt9t013_reg_pat[0],
|
||||
.reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
|
||||
.ttbl = &mt9t013_test_tbl[0],
|
||||
.ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
|
||||
.lctbl = &mt9t013_lc_tbl[0],
|
||||
.lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
|
||||
.rftbl = &mt9t013_lc_tbl[0], /* &mt9t013_rolloff_tbl[0], */
|
||||
.rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef CAMSENSOR_S5K3E2FX
|
||||
#define CAMSENSOR_S5K3E2FX
|
||||
|
||||
#include <mach/board.h>
|
||||
#endif /* CAMSENSOR_S5K3E2FX */
|
|
@ -1,274 +0,0 @@
|
|||
/* arch/arm/mach-msm/generic_gpio.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/gpio.h>
|
||||
#include "gpio_chip.h"
|
||||
|
||||
#define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5)
|
||||
|
||||
struct gpio_state {
|
||||
unsigned long flags;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(gpio_chips_lock);
|
||||
static LIST_HEAD(gpio_chip_list);
|
||||
static struct gpio_chip **gpio_chip_array;
|
||||
static unsigned long gpio_chip_array_size;
|
||||
|
||||
int register_gpio_chip(struct gpio_chip *new_gpio_chip)
|
||||
{
|
||||
int err = 0;
|
||||
struct gpio_chip *gpio_chip;
|
||||
int i;
|
||||
unsigned long irq_flags;
|
||||
unsigned int chip_array_start_index, chip_array_end_index;
|
||||
|
||||
new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL);
|
||||
if (new_gpio_chip->state == NULL) {
|
||||
printk(KERN_ERR "register_gpio_chip: failed to allocate state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start);
|
||||
chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end);
|
||||
if (chip_array_end_index >= gpio_chip_array_size) {
|
||||
struct gpio_chip **new_gpio_chip_array;
|
||||
unsigned long new_gpio_chip_array_size = chip_array_end_index + 1;
|
||||
|
||||
new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC);
|
||||
if (new_gpio_chip_array == NULL) {
|
||||
printk(KERN_ERR "register_gpio_chip: failed to allocate array\n");
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
for (i = 0; i < gpio_chip_array_size; i++)
|
||||
new_gpio_chip_array[i] = gpio_chip_array[i];
|
||||
for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++)
|
||||
new_gpio_chip_array[i] = NULL;
|
||||
gpio_chip_array = new_gpio_chip_array;
|
||||
gpio_chip_array_size = new_gpio_chip_array_size;
|
||||
}
|
||||
list_for_each_entry(gpio_chip, &gpio_chip_list, list) {
|
||||
if (gpio_chip->start > new_gpio_chip->end) {
|
||||
list_add_tail(&new_gpio_chip->list, &gpio_chip->list);
|
||||
goto added;
|
||||
}
|
||||
if (gpio_chip->end >= new_gpio_chip->start) {
|
||||
printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n",
|
||||
new_gpio_chip->start, new_gpio_chip->end,
|
||||
gpio_chip->start, gpio_chip->end);
|
||||
err = -EBUSY;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
list_add_tail(&new_gpio_chip->list, &gpio_chip_list);
|
||||
added:
|
||||
for (i = chip_array_start_index; i <= chip_array_end_index; i++) {
|
||||
if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start)
|
||||
gpio_chip_array[i] = new_gpio_chip;
|
||||
}
|
||||
failed:
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
if (err)
|
||||
kfree(new_gpio_chip->state);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio)
|
||||
{
|
||||
unsigned long i;
|
||||
struct gpio_chip *chip;
|
||||
|
||||
i = GPIO_NUM_TO_CHIP_INDEX(gpio);
|
||||
if (i >= gpio_chip_array_size)
|
||||
return NULL;
|
||||
chip = gpio_chip_array[i];
|
||||
if (chip == NULL)
|
||||
return NULL;
|
||||
list_for_each_entry_from(chip, &gpio_chip_list, list) {
|
||||
if (gpio < chip->start)
|
||||
return NULL;
|
||||
if (gpio <= chip->end)
|
||||
return chip;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int request_gpio(unsigned int gpio, unsigned long flags)
|
||||
{
|
||||
int err = 0;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
unsigned long chip_index;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip == NULL) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
chip_index = gpio - chip->start;
|
||||
if (chip->state[chip_index].refcount == 0) {
|
||||
chip->configure(chip, gpio, flags);
|
||||
chip->state[chip_index].flags = flags;
|
||||
chip->state[chip_index].refcount++;
|
||||
} else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED))
|
||||
chip->state[chip_index].refcount++;
|
||||
else
|
||||
err = -EBUSY;
|
||||
err:
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
return request_gpio(gpio, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_request);
|
||||
|
||||
void gpio_free(unsigned gpio)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
unsigned long chip_index;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip) {
|
||||
chip_index = gpio - chip->start;
|
||||
chip->state[chip_index].refcount--;
|
||||
}
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_free);
|
||||
|
||||
static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip && chip->get_irq_num)
|
||||
ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
int ret, irq;
|
||||
ret = gpio_get_irq_num(gpio, &irq, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
return irq;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_to_irq);
|
||||
|
||||
int gpio_configure(unsigned int gpio, unsigned long flags)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip)
|
||||
ret = chip->configure(chip, gpio, flags);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_configure);
|
||||
|
||||
int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
return gpio_configure(gpio, GPIOF_INPUT);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_input);
|
||||
|
||||
int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
gpio_set_value(gpio, value);
|
||||
return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_output);
|
||||
|
||||
int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip && chip->read)
|
||||
ret = chip->read(chip, gpio);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_get_value);
|
||||
|
||||
void gpio_set_value(unsigned gpio, int on)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip && chip->write)
|
||||
ret = chip->write(chip, gpio, on);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_set_value);
|
||||
|
||||
int gpio_read_detect_status(unsigned int gpio)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip && chip->read_detect_status)
|
||||
ret = chip->read_detect_status(chip, gpio);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_read_detect_status);
|
||||
|
||||
int gpio_clear_detect_status(unsigned int gpio)
|
||||
{
|
||||
int ret = -ENOTSUPP;
|
||||
struct gpio_chip *chip;
|
||||
unsigned long irq_flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_chips_lock, irq_flags);
|
||||
chip = get_gpio_chip_locked(gpio);
|
||||
if (chip && chip->clear_detect_status)
|
||||
ret = chip->clear_detect_status(chip, gpio);
|
||||
spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_clear_detect_status);
|
|
@ -1,181 +0,0 @@
|
|||
/* drivers/input/misc/gpio_axis.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_event.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
struct gpio_axis_state {
|
||||
struct input_dev *input_dev;
|
||||
struct gpio_event_axis_info *info;
|
||||
uint32_t pos;
|
||||
};
|
||||
|
||||
uint16_t gpio_axis_4bit_gray_map_table[] = {
|
||||
[0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */
|
||||
[0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */
|
||||
[0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */
|
||||
[0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */
|
||||
[0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */
|
||||
[0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */
|
||||
[0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */
|
||||
[0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */
|
||||
};
|
||||
uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in)
|
||||
{
|
||||
return gpio_axis_4bit_gray_map_table[in];
|
||||
}
|
||||
|
||||
uint16_t gpio_axis_5bit_singletrack_map_table[] = {
|
||||
[0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */
|
||||
[0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */
|
||||
[0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */
|
||||
[0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */
|
||||
[0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */
|
||||
[0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */
|
||||
[0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */
|
||||
[0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */
|
||||
[0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */
|
||||
[0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */
|
||||
};
|
||||
uint16_t gpio_axis_5bit_singletrack_map(
|
||||
struct gpio_event_axis_info *info, uint16_t in)
|
||||
{
|
||||
return gpio_axis_5bit_singletrack_map_table[in];
|
||||
}
|
||||
|
||||
static void gpio_event_update_axis(struct gpio_axis_state *as, int report)
|
||||
{
|
||||
struct gpio_event_axis_info *ai = as->info;
|
||||
int i;
|
||||
int change;
|
||||
uint16_t state = 0;
|
||||
uint16_t pos;
|
||||
uint16_t old_pos = as->pos;
|
||||
for (i = ai->count - 1; i >= 0; i--)
|
||||
state = (state << 1) | gpio_get_value(ai->gpio[i]);
|
||||
pos = ai->map(ai, state);
|
||||
if (ai->flags & GPIOEAF_PRINT_RAW)
|
||||
pr_info("axis %d-%d raw %x, pos %d -> %d\n",
|
||||
ai->type, ai->code, state, old_pos, pos);
|
||||
if (report && pos != old_pos) {
|
||||
if (ai->type == EV_REL) {
|
||||
change = (ai->decoded_size + pos - old_pos) %
|
||||
ai->decoded_size;
|
||||
if (change > ai->decoded_size / 2)
|
||||
change -= ai->decoded_size;
|
||||
if (change == ai->decoded_size / 2) {
|
||||
if (ai->flags & GPIOEAF_PRINT_EVENT)
|
||||
pr_info("axis %d-%d unknown direction, "
|
||||
"pos %d -> %d\n", ai->type,
|
||||
ai->code, old_pos, pos);
|
||||
change = 0; /* no closest direction */
|
||||
}
|
||||
if (ai->flags & GPIOEAF_PRINT_EVENT)
|
||||
pr_info("axis %d-%d change %d\n",
|
||||
ai->type, ai->code, change);
|
||||
input_report_rel(as->input_dev, ai->code, change);
|
||||
} else {
|
||||
if (ai->flags & GPIOEAF_PRINT_EVENT)
|
||||
pr_info("axis %d-%d now %d\n",
|
||||
ai->type, ai->code, pos);
|
||||
input_event(as->input_dev, ai->type, ai->code, pos);
|
||||
}
|
||||
input_sync(as->input_dev);
|
||||
}
|
||||
as->pos = pos;
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_axis_state *as = dev_id;
|
||||
gpio_event_update_axis(as, 1);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int gpio_event_axis_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
int irq;
|
||||
struct gpio_event_axis_info *ai;
|
||||
struct gpio_axis_state *as;
|
||||
|
||||
ai = container_of(info, struct gpio_event_axis_info, info);
|
||||
if (func == GPIO_EVENT_FUNC_SUSPEND) {
|
||||
for (i = 0; i < ai->count; i++)
|
||||
disable_irq(gpio_to_irq(ai->gpio[i]));
|
||||
return 0;
|
||||
}
|
||||
if (func == GPIO_EVENT_FUNC_RESUME) {
|
||||
for (i = 0; i < ai->count; i++)
|
||||
enable_irq(gpio_to_irq(ai->gpio[i]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_INIT) {
|
||||
*data = as = kmalloc(sizeof(*as), GFP_KERNEL);
|
||||
if (as == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_axis_state_failed;
|
||||
}
|
||||
as->input_dev = input_dev;
|
||||
as->info = ai;
|
||||
|
||||
input_set_capability(input_dev, ai->type, ai->code);
|
||||
if (ai->type == EV_ABS) {
|
||||
input_set_abs_params(input_dev, ai->code, 0,
|
||||
ai->decoded_size - 1, 0, 0);
|
||||
}
|
||||
for (i = 0; i < ai->count; i++) {
|
||||
ret = gpio_request(ai->gpio[i], "gpio_event_axis");
|
||||
if (ret < 0)
|
||||
goto err_request_gpio_failed;
|
||||
ret = gpio_direction_input(ai->gpio[i]);
|
||||
if (ret < 0)
|
||||
goto err_gpio_direction_input_failed;
|
||||
ret = irq = gpio_to_irq(ai->gpio[i]);
|
||||
if (ret < 0)
|
||||
goto err_get_irq_num_failed;
|
||||
ret = request_irq(irq, gpio_axis_irq_handler,
|
||||
IRQF_TRIGGER_RISING |
|
||||
IRQF_TRIGGER_FALLING,
|
||||
"gpio_event_axis", as);
|
||||
if (ret < 0)
|
||||
goto err_request_irq_failed;
|
||||
}
|
||||
gpio_event_update_axis(as, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
as = *data;
|
||||
for (i = ai->count - 1; i >= 0; i--) {
|
||||
free_irq(gpio_to_irq(ai->gpio[i]), as);
|
||||
err_request_irq_failed:
|
||||
err_get_irq_num_failed:
|
||||
err_gpio_direction_input_failed:
|
||||
gpio_free(ai->gpio[i]);
|
||||
err_request_gpio_failed:
|
||||
;
|
||||
}
|
||||
kfree(as);
|
||||
*data = NULL;
|
||||
err_alloc_axis_state_failed:
|
||||
return ret;
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
/* drivers/input/misc/gpio_event.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_event.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct gpio_event {
|
||||
struct input_dev *input_dev;
|
||||
const struct gpio_event_platform_data *info;
|
||||
void *state[0];
|
||||
};
|
||||
|
||||
static int gpio_input_event(
|
||||
struct input_dev *dev, unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
int tmp_ret;
|
||||
struct gpio_event_info **ii;
|
||||
struct gpio_event *ip = input_get_drvdata(dev);
|
||||
|
||||
for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
|
||||
if ((*ii)->event) {
|
||||
tmp_ret = (*ii)->event(ip->input_dev, *ii,
|
||||
&ip->state[i], type, code, value);
|
||||
if (tmp_ret)
|
||||
ret = tmp_ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_event_call_all_func(struct gpio_event *ip, int func)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
struct gpio_event_info **ii;
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
|
||||
ii = ip->info->info;
|
||||
for (i = 0; i < ip->info->info_count; i++, ii++) {
|
||||
if ((*ii)->func == NULL) {
|
||||
ret = -ENODEV;
|
||||
pr_err("gpio_event_probe: Incomplete pdata, "
|
||||
"no function\n");
|
||||
goto err_no_func;
|
||||
}
|
||||
ret = (*ii)->func(ip->input_dev, *ii, &ip->state[i],
|
||||
func);
|
||||
if (ret) {
|
||||
pr_err("gpio_event_probe: function failed\n");
|
||||
goto err_func_failed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
i = ip->info->info_count;
|
||||
ii = ip->info->info + i;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
ii--;
|
||||
(*ii)->func(ip->input_dev, *ii, &ip->state[i], func & ~1);
|
||||
err_func_failed:
|
||||
err_no_func:
|
||||
;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
void gpio_event_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct gpio_event *ip;
|
||||
ip = container_of(h, struct gpio_event, early_suspend);
|
||||
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
|
||||
ip->info->power(ip->info, 0);
|
||||
}
|
||||
|
||||
void gpio_event_resume(struct early_suspend *h)
|
||||
{
|
||||
struct gpio_event *ip;
|
||||
ip = container_of(h, struct gpio_event, early_suspend);
|
||||
ip->info->power(ip->info, 1);
|
||||
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init gpio_event_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
struct gpio_event *ip;
|
||||
struct input_dev *input_dev;
|
||||
struct gpio_event_platform_data *event_info;
|
||||
|
||||
event_info = pdev->dev.platform_data;
|
||||
if (event_info == NULL) {
|
||||
pr_err("gpio_event_probe: No pdata\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (event_info->name == NULL ||
|
||||
event_info->info == NULL ||
|
||||
event_info->info_count == 0) {
|
||||
pr_err("gpio_event_probe: Incomplete pdata\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ip = kzalloc(sizeof(*ip) +
|
||||
sizeof(ip->state[0]) * event_info->info_count, GFP_KERNEL);
|
||||
if (ip == NULL) {
|
||||
err = -ENOMEM;
|
||||
pr_err("gpio_event_probe: Failed to allocate private data\n");
|
||||
goto err_kp_alloc_failed;
|
||||
}
|
||||
platform_set_drvdata(pdev, ip);
|
||||
|
||||
input_dev = input_allocate_device();
|
||||
if (input_dev == NULL) {
|
||||
err = -ENOMEM;
|
||||
pr_err("gpio_event_probe: Failed to allocate input device\n");
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
input_set_drvdata(input_dev, ip);
|
||||
ip->input_dev = input_dev;
|
||||
ip->info = event_info;
|
||||
if (event_info->power) {
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
||||
ip->early_suspend.suspend = gpio_event_suspend;
|
||||
ip->early_suspend.resume = gpio_event_resume;
|
||||
register_early_suspend(&ip->early_suspend);
|
||||
#endif
|
||||
ip->info->power(ip->info, 1);
|
||||
}
|
||||
|
||||
input_dev->name = ip->info->name;
|
||||
input_dev->event = gpio_input_event;
|
||||
|
||||
err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
|
||||
if (err)
|
||||
goto err_call_all_func_failed;
|
||||
|
||||
err = input_register_device(input_dev);
|
||||
if (err) {
|
||||
pr_err("gpio_event_probe: Unable to register %s input device\n",
|
||||
input_dev->name);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_input_register_device_failed:
|
||||
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
|
||||
err_call_all_func_failed:
|
||||
if (event_info->power) {
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ip->early_suspend);
|
||||
#endif
|
||||
ip->info->power(ip->info, 0);
|
||||
}
|
||||
input_free_device(input_dev);
|
||||
err_input_dev_alloc_failed:
|
||||
kfree(ip);
|
||||
err_kp_alloc_failed:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gpio_event_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_event *ip = platform_get_drvdata(pdev);
|
||||
|
||||
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
|
||||
if (ip->info->power) {
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ip->early_suspend);
|
||||
#endif
|
||||
ip->info->power(ip->info, 0);
|
||||
}
|
||||
input_unregister_device(ip->input_dev);
|
||||
kfree(ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver gpio_event_driver = {
|
||||
.probe = gpio_event_probe,
|
||||
.remove = gpio_event_remove,
|
||||
.driver = {
|
||||
.name = GPIO_EVENT_DEV_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit gpio_event_init(void)
|
||||
{
|
||||
return platform_driver_register(&gpio_event_driver);
|
||||
}
|
||||
|
||||
static void __exit gpio_event_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gpio_event_driver);
|
||||
}
|
||||
|
||||
module_init(gpio_event_init);
|
||||
module_exit(gpio_event_exit);
|
||||
|
||||
MODULE_DESCRIPTION("GPIO Event Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,337 +0,0 @@
|
|||
/* drivers/input/misc/gpio_input.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/gpio.h>
|
||||
#include <linux/gpio_event.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
enum {
|
||||
DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
|
||||
DEBOUNCE_PRESSED = BIT(1),
|
||||
DEBOUNCE_NOTPRESSED = BIT(2),
|
||||
DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
|
||||
DEBOUNCE_POLL = BIT(4), /* Stable polling state */
|
||||
|
||||
DEBOUNCE_UNKNOWN =
|
||||
DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
|
||||
};
|
||||
|
||||
struct gpio_key_state {
|
||||
struct gpio_input_state *ds;
|
||||
uint8_t debounce;
|
||||
};
|
||||
|
||||
struct gpio_input_state {
|
||||
struct input_dev *input_dev;
|
||||
const struct gpio_event_input_info *info;
|
||||
struct hrtimer timer;
|
||||
int use_irq;
|
||||
int debounce_count;
|
||||
spinlock_t irq_lock;
|
||||
struct gpio_key_state key_state[0];
|
||||
};
|
||||
|
||||
static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
int i;
|
||||
int pressed;
|
||||
struct gpio_input_state *ds =
|
||||
container_of(timer, struct gpio_input_state, timer);
|
||||
unsigned gpio_flags = ds->info->flags;
|
||||
unsigned npolarity;
|
||||
int nkeys = ds->info->keymap_size;
|
||||
const struct gpio_event_direct_entry *key_entry;
|
||||
struct gpio_key_state *key_state;
|
||||
unsigned long irqflags;
|
||||
uint8_t debounce;
|
||||
|
||||
#if 0
|
||||
key_entry = kp->keys_info->keymap;
|
||||
key_state = kp->key_state;
|
||||
for (i = 0; i < nkeys; i++, key_entry++, key_state++)
|
||||
pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
|
||||
gpio_read_detect_status(key_entry->gpio));
|
||||
#endif
|
||||
key_entry = ds->info->keymap;
|
||||
key_state = ds->key_state;
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
|
||||
debounce = key_state->debounce;
|
||||
if (debounce & DEBOUNCE_WAIT_IRQ)
|
||||
continue;
|
||||
if (key_state->debounce & DEBOUNCE_UNSTABLE) {
|
||||
debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
|
||||
enable_irq(gpio_to_irq(key_entry->gpio));
|
||||
pr_info("gpio_keys_scan_keys: key %x-%x, %d "
|
||||
"(%d) continue debounce\n",
|
||||
ds->info->type, key_entry->code,
|
||||
i, key_entry->gpio);
|
||||
}
|
||||
npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
|
||||
pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
|
||||
if (debounce & DEBOUNCE_POLL) {
|
||||
if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
|
||||
ds->debounce_count++;
|
||||
key_state->debounce = DEBOUNCE_UNKNOWN;
|
||||
if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
|
||||
pr_info("gpio_keys_scan_keys: key %x-"
|
||||
"%x, %d (%d) start debounce\n",
|
||||
ds->info->type, key_entry->code,
|
||||
i, key_entry->gpio);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
|
||||
if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
|
||||
pr_info("gpio_keys_scan_keys: key %x-%x, %d "
|
||||
"(%d) debounce pressed 1\n",
|
||||
ds->info->type, key_entry->code,
|
||||
i, key_entry->gpio);
|
||||
key_state->debounce = DEBOUNCE_PRESSED;
|
||||
continue;
|
||||
}
|
||||
if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
|
||||
if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
|
||||
pr_info("gpio_keys_scan_keys: key %x-%x, %d "
|
||||
"(%d) debounce pressed 0\n",
|
||||
ds->info->type, key_entry->code,
|
||||
i, key_entry->gpio);
|
||||
key_state->debounce = DEBOUNCE_NOTPRESSED;
|
||||
continue;
|
||||
}
|
||||
/* key is stable */
|
||||
ds->debounce_count--;
|
||||
if (ds->use_irq)
|
||||
key_state->debounce |= DEBOUNCE_WAIT_IRQ;
|
||||
else
|
||||
key_state->debounce |= DEBOUNCE_POLL;
|
||||
if (gpio_flags & GPIOEDF_PRINT_KEYS)
|
||||
pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
|
||||
"changed to %d\n", ds->info->type,
|
||||
key_entry->code, i, key_entry->gpio, pressed);
|
||||
input_event(ds->input_dev, ds->info->type,
|
||||
key_entry->code, pressed);
|
||||
}
|
||||
|
||||
#if 0
|
||||
key_entry = kp->keys_info->keymap;
|
||||
key_state = kp->key_state;
|
||||
for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
|
||||
pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
|
||||
gpio_read_detect_status(key_entry->gpio));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ds->debounce_count)
|
||||
hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
|
||||
else if (!ds->use_irq)
|
||||
hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
|
||||
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_key_state *ks = dev_id;
|
||||
struct gpio_input_state *ds = ks->ds;
|
||||
int keymap_index = ks - ds->key_state;
|
||||
const struct gpio_event_direct_entry *key_entry;
|
||||
unsigned long irqflags;
|
||||
int pressed;
|
||||
|
||||
if (!ds->use_irq)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
key_entry = &ds->info->keymap[keymap_index];
|
||||
|
||||
if (ds->info->debounce_time.tv64) {
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
|
||||
ks->debounce = DEBOUNCE_UNKNOWN;
|
||||
if (ds->debounce_count++ == 0) {
|
||||
hrtimer_start(
|
||||
&ds->timer, ds->info->debounce_time,
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
|
||||
pr_info("gpio_event_input_irq_handler: "
|
||||
"key %x-%x, %d (%d) start debounce\n",
|
||||
ds->info->type, key_entry->code,
|
||||
keymap_index, key_entry->gpio);
|
||||
} else {
|
||||
disable_irq(irq);
|
||||
ks->debounce = DEBOUNCE_UNSTABLE;
|
||||
}
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
} else {
|
||||
pressed = gpio_get_value(key_entry->gpio) ^
|
||||
!(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
|
||||
if (ds->info->flags & GPIOEDF_PRINT_KEYS)
|
||||
pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
|
||||
"(%d) changed to %d\n",
|
||||
ds->info->type, key_entry->code, keymap_index,
|
||||
key_entry->gpio, pressed);
|
||||
input_event(ds->input_dev, ds->info->type,
|
||||
key_entry->code, pressed);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
unsigned int irq;
|
||||
unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
|
||||
for (i = 0; i < ds->info->keymap_size; i++) {
|
||||
err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
|
||||
if (err < 0)
|
||||
goto err_gpio_get_irq_num_failed;
|
||||
err = request_irq(irq, gpio_event_input_irq_handler,
|
||||
req_flags, "gpio_keys", &ds->key_state[i]);
|
||||
if (err) {
|
||||
pr_err("gpio_event_input_request_irqs: request_irq "
|
||||
"failed for input %d, irq %d\n",
|
||||
ds->info->keymap[i].gpio, irq);
|
||||
goto err_request_irq_failed;
|
||||
}
|
||||
enable_irq_wake(irq);
|
||||
}
|
||||
return 0;
|
||||
|
||||
for (i = ds->info->keymap_size - 1; i >= 0; i--) {
|
||||
free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
|
||||
&ds->key_state[i]);
|
||||
err_request_irq_failed:
|
||||
err_gpio_get_irq_num_failed:
|
||||
;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpio_event_input_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
unsigned long irqflags;
|
||||
struct gpio_event_input_info *di;
|
||||
struct gpio_input_state *ds = *data;
|
||||
|
||||
di = container_of(info, struct gpio_event_input_info, info);
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_SUSPEND) {
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
if (ds->use_irq)
|
||||
for (i = 0; i < di->keymap_size; i++)
|
||||
disable_irq(gpio_to_irq(di->keymap[i].gpio));
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
hrtimer_cancel(&ds->timer);
|
||||
return 0;
|
||||
}
|
||||
if (func == GPIO_EVENT_FUNC_RESUME) {
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
if (ds->use_irq)
|
||||
for (i = 0; i < di->keymap_size; i++)
|
||||
enable_irq(gpio_to_irq(di->keymap[i].gpio));
|
||||
hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_INIT) {
|
||||
if (ktime_to_ns(di->poll_time) <= 0)
|
||||
di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
|
||||
|
||||
*data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
|
||||
di->keymap_size, GFP_KERNEL);
|
||||
if (ds == NULL) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("gpio_event_input_func: "
|
||||
"Failed to allocate private data\n");
|
||||
goto err_ds_alloc_failed;
|
||||
}
|
||||
ds->debounce_count = di->keymap_size;
|
||||
ds->input_dev = input_dev;
|
||||
ds->info = di;
|
||||
spin_lock_init(&ds->irq_lock);
|
||||
|
||||
for (i = 0; i < di->keymap_size; i++) {
|
||||
input_set_capability(input_dev, di->type,
|
||||
di->keymap[i].code);
|
||||
ds->key_state[i].ds = ds;
|
||||
ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
|
||||
}
|
||||
|
||||
for (i = 0; i < di->keymap_size; i++) {
|
||||
ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
|
||||
if (ret) {
|
||||
pr_err("gpio_event_input_func: gpio_request "
|
||||
"failed for %d\n", di->keymap[i].gpio);
|
||||
goto err_gpio_request_failed;
|
||||
}
|
||||
ret = gpio_direction_input(di->keymap[i].gpio);
|
||||
if (ret) {
|
||||
pr_err("gpio_event_input_func: "
|
||||
"gpio_direction_input failed for %d\n",
|
||||
di->keymap[i].gpio);
|
||||
goto err_gpio_configure_failed;
|
||||
}
|
||||
}
|
||||
|
||||
ret = gpio_event_input_request_irqs(ds);
|
||||
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
ds->use_irq = ret == 0;
|
||||
|
||||
pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
|
||||
"mode\n",
|
||||
input_dev->name, ret == 0 ? "interrupt" : "polling");
|
||||
|
||||
hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
ds->timer.function = gpio_event_input_timer_func;
|
||||
hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
spin_lock_irqsave(&ds->irq_lock, irqflags);
|
||||
hrtimer_cancel(&ds->timer);
|
||||
if (ds->use_irq) {
|
||||
for (i = di->keymap_size - 1; i >= 0; i--) {
|
||||
free_irq(gpio_to_irq(di->keymap[i].gpio),
|
||||
&ds->key_state[i]);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ds->irq_lock, irqflags);
|
||||
|
||||
for (i = di->keymap_size - 1; i >= 0; i--) {
|
||||
err_gpio_configure_failed:
|
||||
gpio_free(di->keymap[i].gpio);
|
||||
err_gpio_request_failed:
|
||||
;
|
||||
}
|
||||
kfree(ds);
|
||||
err_ds_alloc_failed:
|
||||
return ret;
|
||||
}
|
|
@ -1,399 +0,0 @@
|
|||
/* drivers/input/misc/gpio_matrix.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_event.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
struct gpio_kp {
|
||||
struct input_dev *input_dev;
|
||||
struct gpio_event_matrix_info *keypad_info;
|
||||
struct hrtimer timer;
|
||||
int current_output;
|
||||
unsigned int use_irq:1;
|
||||
unsigned int key_state_changed:1;
|
||||
unsigned int last_key_state_changed:1;
|
||||
unsigned int some_keys_pressed:2;
|
||||
unsigned long keys_pressed[0];
|
||||
};
|
||||
|
||||
static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
|
||||
{
|
||||
struct gpio_event_matrix_info *mi = kp->keypad_info;
|
||||
int key_index = out * mi->ninputs + in;
|
||||
unsigned short keycode = mi->keymap[key_index];;
|
||||
|
||||
if (!test_bit(keycode, kp->input_dev->key)) {
|
||||
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
|
||||
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
|
||||
"cleared\n", keycode, out, in,
|
||||
mi->output_gpios[out], mi->input_gpios[in]);
|
||||
__clear_bit(key_index, kp->keys_pressed);
|
||||
} else {
|
||||
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
|
||||
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
|
||||
"not cleared\n", keycode, out, in,
|
||||
mi->output_gpios[out], mi->input_gpios[in]);
|
||||
}
|
||||
}
|
||||
|
||||
static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
|
||||
{
|
||||
int rv = 0;
|
||||
int key_index;
|
||||
|
||||
key_index = out * kp->keypad_info->ninputs + in;
|
||||
while (out < kp->keypad_info->noutputs) {
|
||||
if (test_bit(key_index, kp->keys_pressed)) {
|
||||
rv = 1;
|
||||
clear_phantom_key(kp, out, in);
|
||||
}
|
||||
key_index += kp->keypad_info->ninputs;
|
||||
out++;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void remove_phantom_keys(struct gpio_kp *kp)
|
||||
{
|
||||
int out, in, inp;
|
||||
int key_index;
|
||||
|
||||
if (kp->some_keys_pressed < 3)
|
||||
return;
|
||||
|
||||
for (out = 0; out < kp->keypad_info->noutputs; out++) {
|
||||
inp = -1;
|
||||
key_index = out * kp->keypad_info->ninputs;
|
||||
for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
|
||||
if (test_bit(key_index, kp->keys_pressed)) {
|
||||
if (inp == -1) {
|
||||
inp = in;
|
||||
continue;
|
||||
}
|
||||
if (inp >= 0) {
|
||||
if (!restore_keys_for_input(kp, out + 1,
|
||||
inp))
|
||||
break;
|
||||
clear_phantom_key(kp, out, inp);
|
||||
inp = -2;
|
||||
}
|
||||
restore_keys_for_input(kp, out, in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
|
||||
{
|
||||
struct gpio_event_matrix_info *mi = kp->keypad_info;
|
||||
int pressed = test_bit(key_index, kp->keys_pressed);
|
||||
unsigned short keycode = mi->keymap[key_index];
|
||||
if (pressed != test_bit(keycode, kp->input_dev->key)) {
|
||||
if (keycode == KEY_RESERVED) {
|
||||
if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
|
||||
pr_info("gpiomatrix: unmapped key, %d-%d "
|
||||
"(%d-%d) changed to %d\n",
|
||||
out, in, mi->output_gpios[out],
|
||||
mi->input_gpios[in], pressed);
|
||||
} else {
|
||||
if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
|
||||
pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
|
||||
"changed to %d\n", keycode,
|
||||
out, in, mi->output_gpios[out],
|
||||
mi->input_gpios[in], pressed);
|
||||
input_report_key(kp->input_dev, keycode, pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
int out, in;
|
||||
int key_index;
|
||||
int gpio;
|
||||
struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
|
||||
struct gpio_event_matrix_info *mi = kp->keypad_info;
|
||||
unsigned gpio_keypad_flags = mi->flags;
|
||||
unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
|
||||
|
||||
out = kp->current_output;
|
||||
if (out == mi->noutputs) {
|
||||
out = 0;
|
||||
kp->last_key_state_changed = kp->key_state_changed;
|
||||
kp->key_state_changed = 0;
|
||||
kp->some_keys_pressed = 0;
|
||||
} else {
|
||||
key_index = out * mi->ninputs;
|
||||
for (in = 0; in < mi->ninputs; in++, key_index++) {
|
||||
gpio = mi->input_gpios[in];
|
||||
if (gpio_get_value(gpio) ^ !polarity) {
|
||||
if (kp->some_keys_pressed < 3)
|
||||
kp->some_keys_pressed++;
|
||||
kp->key_state_changed |= !__test_and_set_bit(
|
||||
key_index, kp->keys_pressed);
|
||||
} else
|
||||
kp->key_state_changed |= __test_and_clear_bit(
|
||||
key_index, kp->keys_pressed);
|
||||
}
|
||||
gpio = mi->output_gpios[out];
|
||||
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
|
||||
gpio_set_value(gpio, !polarity);
|
||||
else
|
||||
gpio_direction_input(gpio);
|
||||
out++;
|
||||
}
|
||||
kp->current_output = out;
|
||||
if (out < mi->noutputs) {
|
||||
gpio = mi->output_gpios[out];
|
||||
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
|
||||
gpio_set_value(gpio, polarity);
|
||||
else
|
||||
gpio_direction_output(gpio, polarity);
|
||||
hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
|
||||
if (kp->key_state_changed) {
|
||||
hrtimer_start(&kp->timer, mi->debounce_delay,
|
||||
HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
kp->key_state_changed = kp->last_key_state_changed;
|
||||
}
|
||||
if (kp->key_state_changed) {
|
||||
if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
|
||||
remove_phantom_keys(kp);
|
||||
key_index = 0;
|
||||
for (out = 0; out < mi->noutputs; out++)
|
||||
for (in = 0; in < mi->ninputs; in++, key_index++)
|
||||
report_key(kp, key_index, out, in);
|
||||
}
|
||||
if (!kp->use_irq || kp->some_keys_pressed) {
|
||||
hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
/* No keys are pressed, reenable interrupt */
|
||||
for (out = 0; out < mi->noutputs; out++) {
|
||||
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
|
||||
gpio_set_value(mi->output_gpios[out], polarity);
|
||||
else
|
||||
gpio_direction_output(mi->output_gpios[out], polarity);
|
||||
}
|
||||
for (in = 0; in < mi->ninputs; in++)
|
||||
enable_irq(gpio_to_irq(mi->input_gpios[in]));
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
|
||||
{
|
||||
int i;
|
||||
struct gpio_kp *kp = dev_id;
|
||||
struct gpio_event_matrix_info *mi = kp->keypad_info;
|
||||
unsigned gpio_keypad_flags = mi->flags;
|
||||
|
||||
if (!kp->use_irq) /* ignore interrupt while registering the handler */
|
||||
return IRQ_HANDLED;
|
||||
|
||||
for (i = 0; i < mi->ninputs; i++)
|
||||
disable_irq(gpio_to_irq(mi->input_gpios[i]));
|
||||
for (i = 0; i < mi->noutputs; i++) {
|
||||
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
|
||||
gpio_set_value(mi->output_gpios[i],
|
||||
!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
|
||||
else
|
||||
gpio_direction_input(mi->output_gpios[i]);
|
||||
}
|
||||
hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int gpio_keypad_request_irqs(struct gpio_kp *kp)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
unsigned int irq;
|
||||
unsigned long request_flags;
|
||||
struct gpio_event_matrix_info *mi = kp->keypad_info;
|
||||
|
||||
switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
|
||||
default:
|
||||
request_flags = IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
case GPIOKPF_ACTIVE_HIGH:
|
||||
request_flags = IRQF_TRIGGER_RISING;
|
||||
break;
|
||||
case GPIOKPF_LEVEL_TRIGGERED_IRQ:
|
||||
request_flags = IRQF_TRIGGER_LOW;
|
||||
break;
|
||||
case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
|
||||
request_flags = IRQF_TRIGGER_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < mi->ninputs; i++) {
|
||||
err = irq = gpio_to_irq(mi->input_gpios[i]);
|
||||
if (err < 0)
|
||||
goto err_gpio_get_irq_num_failed;
|
||||
err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
|
||||
"gpio_kp", kp);
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: request_irq failed for input %d, "
|
||||
"irq %d\n", mi->input_gpios[i], irq);
|
||||
goto err_request_irq_failed;
|
||||
}
|
||||
err = set_irq_wake(irq, 1);
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: set_irq_wake failed for input %d, "
|
||||
"irq %d\n", mi->input_gpios[i], irq);
|
||||
}
|
||||
disable_irq(irq);
|
||||
}
|
||||
return 0;
|
||||
|
||||
for (i = mi->noutputs - 1; i >= 0; i--) {
|
||||
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
|
||||
err_request_irq_failed:
|
||||
err_gpio_get_irq_num_failed:
|
||||
;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpio_event_matrix_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
int key_count;
|
||||
struct gpio_kp *kp;
|
||||
struct gpio_event_matrix_info *mi;
|
||||
|
||||
mi = container_of(info, struct gpio_event_matrix_info, info);
|
||||
if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
|
||||
/* TODO: disable scanning */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_INIT) {
|
||||
if (mi->keymap == NULL ||
|
||||
mi->input_gpios == NULL ||
|
||||
mi->output_gpios == NULL) {
|
||||
err = -ENODEV;
|
||||
pr_err("gpiomatrix: Incomplete pdata\n");
|
||||
goto err_invalid_platform_data;
|
||||
}
|
||||
key_count = mi->ninputs * mi->noutputs;
|
||||
|
||||
*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
|
||||
BITS_TO_LONGS(key_count), GFP_KERNEL);
|
||||
if (kp == NULL) {
|
||||
err = -ENOMEM;
|
||||
pr_err("gpiomatrix: Failed to allocate private data\n");
|
||||
goto err_kp_alloc_failed;
|
||||
}
|
||||
kp->input_dev = input_dev;
|
||||
kp->keypad_info = mi;
|
||||
set_bit(EV_KEY, input_dev->evbit);
|
||||
for (i = 0; i < key_count; i++) {
|
||||
if (mi->keymap[i])
|
||||
set_bit(mi->keymap[i] & KEY_MAX,
|
||||
input_dev->keybit);
|
||||
}
|
||||
|
||||
for (i = 0; i < mi->noutputs; i++) {
|
||||
if (gpio_cansleep(mi->output_gpios[i])) {
|
||||
pr_err("gpiomatrix: unsupported output gpio %d,"
|
||||
" can sleep\n", mi->output_gpios[i]);
|
||||
err = -EINVAL;
|
||||
goto err_request_output_gpio_failed;
|
||||
}
|
||||
err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: gpio_request failed for "
|
||||
"output %d\n", mi->output_gpios[i]);
|
||||
goto err_request_output_gpio_failed;
|
||||
}
|
||||
if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
|
||||
err = gpio_direction_output(mi->output_gpios[i],
|
||||
!(mi->flags & GPIOKPF_ACTIVE_HIGH));
|
||||
else
|
||||
err = gpio_direction_input(mi->output_gpios[i]);
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: gpio_configure failed for "
|
||||
"output %d\n", mi->output_gpios[i]);
|
||||
goto err_output_gpio_configure_failed;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < mi->ninputs; i++) {
|
||||
err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: gpio_request failed for "
|
||||
"input %d\n", mi->input_gpios[i]);
|
||||
goto err_request_input_gpio_failed;
|
||||
}
|
||||
err = gpio_direction_input(mi->input_gpios[i]);
|
||||
if (err) {
|
||||
pr_err("gpiomatrix: gpio_direction_input failed"
|
||||
" for input %d\n", mi->input_gpios[i]);
|
||||
goto err_gpio_direction_input_failed;
|
||||
}
|
||||
}
|
||||
kp->current_output = mi->noutputs;
|
||||
kp->key_state_changed = 1;
|
||||
|
||||
hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
kp->timer.function = gpio_keypad_timer_func;
|
||||
err = gpio_keypad_request_irqs(kp);
|
||||
kp->use_irq = err == 0;
|
||||
|
||||
pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s "
|
||||
"in %s mode\n", input_dev->name,
|
||||
kp->use_irq ? "interrupt" : "polling");
|
||||
|
||||
hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
kp = *data;
|
||||
|
||||
if (kp->use_irq)
|
||||
for (i = mi->noutputs - 1; i >= 0; i--)
|
||||
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
|
||||
|
||||
hrtimer_cancel(&kp->timer);
|
||||
for (i = mi->noutputs - 1; i >= 0; i--) {
|
||||
err_gpio_direction_input_failed:
|
||||
gpio_free(mi->input_gpios[i]);
|
||||
err_request_input_gpio_failed:
|
||||
;
|
||||
}
|
||||
for (i = mi->noutputs - 1; i >= 0; i--) {
|
||||
err_output_gpio_configure_failed:
|
||||
gpio_free(mi->output_gpios[i]);
|
||||
err_request_output_gpio_failed:
|
||||
;
|
||||
}
|
||||
kfree(kp);
|
||||
err_kp_alloc_failed:
|
||||
err_invalid_platform_data:
|
||||
return err;
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* drivers/input/misc/gpio_output.c
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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/gpio.h>
|
||||
#include <linux/gpio_event.h>
|
||||
|
||||
int gpio_event_output_event(
|
||||
struct input_dev *input_dev, struct gpio_event_info *info, void **data,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int i;
|
||||
struct gpio_event_output_info *oi;
|
||||
oi = container_of(info, struct gpio_event_output_info, info);
|
||||
if (type != oi->type)
|
||||
return 0;
|
||||
if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
|
||||
value = !value;
|
||||
for (i = 0; i < oi->keymap_size; i++)
|
||||
if (code == oi->keymap[i].code)
|
||||
gpio_set_value(oi->keymap[i].gpio, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_event_output_func(
|
||||
struct input_dev *input_dev, struct gpio_event_info *info, void **data,
|
||||
int func)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
struct gpio_event_output_info *oi;
|
||||
oi = container_of(info, struct gpio_event_output_info, info);
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
|
||||
return 0;
|
||||
|
||||
if (func == GPIO_EVENT_FUNC_INIT) {
|
||||
int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
|
||||
for (i = 0; i < oi->keymap_size; i++)
|
||||
input_set_capability(input_dev, oi->type,
|
||||
oi->keymap[i].code);
|
||||
|
||||
for (i = 0; i < oi->keymap_size; i++) {
|
||||
ret = gpio_request(oi->keymap[i].gpio,
|
||||
"gpio_event_output");
|
||||
if (ret) {
|
||||
pr_err("gpio_event_output_func: gpio_request "
|
||||
"failed for %d\n", oi->keymap[i].gpio);
|
||||
goto err_gpio_request_failed;
|
||||
}
|
||||
ret = gpio_direction_output(oi->keymap[i].gpio,
|
||||
output_level);
|
||||
if (ret) {
|
||||
pr_err("gpio_event_output_func: "
|
||||
"gpio_direction_output failed for %d\n",
|
||||
oi->keymap[i].gpio);
|
||||
goto err_gpio_direction_output_failed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
for (i = oi->keymap_size - 1; i >= 0; i--) {
|
||||
err_gpio_direction_output_failed:
|
||||
gpio_free(oi->keymap[i].gpio);
|
||||
err_gpio_request_failed:
|
||||
;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/android_pmem.h
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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 _ANDROID_PMEM_H_
|
||||
#define _ANDROID_PMEM_H_
|
||||
|
||||
#define PMEM_IOCTL_MAGIC 'p'
|
||||
#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
|
||||
#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
|
||||
#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
|
||||
#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
|
||||
/* This ioctl will allocate pmem space, backing the file, it will fail
|
||||
* if the file already has an allocation, pass it the len as the argument
|
||||
* to the ioctl */
|
||||
#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
|
||||
/* This will connect a one pmem file to another, pass the file that is already
|
||||
* backed in memory as the argument to the ioctl
|
||||
*/
|
||||
#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
|
||||
/* Returns the total size of the pmem region it is sent to as a pmem_region
|
||||
* struct (with offset set to 0).
|
||||
*/
|
||||
#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
|
||||
/* Revokes gpu registers and resets the gpu. Pass a pointer to the
|
||||
* start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
|
||||
*/
|
||||
#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
|
||||
#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
|
||||
#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
|
||||
|
||||
int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
|
||||
unsigned long *end, struct file **filp);
|
||||
int get_pmem_user_addr(struct file *file, unsigned long *start,
|
||||
unsigned long *end);
|
||||
void put_pmem_file(struct file* file);
|
||||
void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
|
||||
|
||||
struct android_pmem_platform_data
|
||||
{
|
||||
const char* name;
|
||||
/* starting physical address of memory region */
|
||||
unsigned long start;
|
||||
/* size of memory region */
|
||||
unsigned long size;
|
||||
/* set to indicate the region should not be managed with an allocator */
|
||||
unsigned no_allocator;
|
||||
/* set to indicate maps of this region should be cached, if a mix of
|
||||
* cached and uncached is desired, set this and open the device with
|
||||
* O_SYNC to get an uncached region */
|
||||
unsigned cached;
|
||||
/* The MSM7k has bits to enable a write buffer in the bus controller*/
|
||||
unsigned buffered;
|
||||
};
|
||||
|
||||
struct pmem_region {
|
||||
unsigned long offset;
|
||||
unsigned long len;
|
||||
};
|
||||
|
||||
int pmem_setup(struct android_pmem_platform_data *pdata,
|
||||
long (*ioctl)(struct file *, unsigned int, unsigned long),
|
||||
int (*release)(struct inode *, struct file *));
|
||||
|
||||
int pmem_remap(struct pmem_region *region, struct file *file,
|
||||
unsigned operation);
|
||||
|
||||
#endif //_ANDROID_PPP_H_
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/gpio_event.h
|
||||
*
|
||||
* Copyright (C) 2007 Google, 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 _LINUX_GPIO_EVENT_H
|
||||
#define _LINUX_GPIO_EVENT_H
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
enum {
|
||||
GPIO_EVENT_FUNC_UNINIT = 0x0,
|
||||
GPIO_EVENT_FUNC_INIT = 0x1,
|
||||
GPIO_EVENT_FUNC_SUSPEND = 0x2,
|
||||
GPIO_EVENT_FUNC_RESUME = 0x3,
|
||||
};
|
||||
struct gpio_event_info {
|
||||
int (*func)(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info,
|
||||
void **data, int func);
|
||||
int (*event)(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info,
|
||||
void **data, unsigned int type,
|
||||
unsigned int code, int value); /* out events */
|
||||
};
|
||||
|
||||
struct gpio_event_platform_data {
|
||||
const char *name;
|
||||
struct gpio_event_info **info;
|
||||
size_t info_count;
|
||||
int (*power)(const struct gpio_event_platform_data *pdata, bool on);
|
||||
};
|
||||
|
||||
#define GPIO_EVENT_DEV_NAME "gpio-event"
|
||||
|
||||
/* Key matrix */
|
||||
|
||||
enum gpio_event_matrix_flags {
|
||||
/* unset: drive active output low, set: drive active output high */
|
||||
GPIOKPF_ACTIVE_HIGH = 1U << 0,
|
||||
GPIOKPF_DEBOUNCE = 1U << 1,
|
||||
GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
|
||||
GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
|
||||
GPIOKPF_DEBOUNCE,
|
||||
GPIOKPF_DRIVE_INACTIVE = 1U << 3,
|
||||
GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4,
|
||||
GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16,
|
||||
GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17,
|
||||
GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18,
|
||||
};
|
||||
|
||||
extern int gpio_event_matrix_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func);
|
||||
struct gpio_event_matrix_info {
|
||||
/* initialize to gpio_event_matrix_func */
|
||||
struct gpio_event_info info;
|
||||
/* size must be ninputs * noutputs */
|
||||
const unsigned short *keymap;
|
||||
unsigned int *input_gpios;
|
||||
unsigned int *output_gpios;
|
||||
unsigned int ninputs;
|
||||
unsigned int noutputs;
|
||||
/* time to wait before reading inputs after driving each output */
|
||||
ktime_t settle_time;
|
||||
/* time to wait before scanning the keypad a second time */
|
||||
ktime_t debounce_delay;
|
||||
ktime_t poll_time;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
/* Directly connected inputs and outputs */
|
||||
|
||||
enum gpio_event_direct_flags {
|
||||
GPIOEDF_ACTIVE_HIGH = 1U << 0,
|
||||
/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */
|
||||
/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
|
||||
GPIOEDF_PRINT_KEYS = 1U << 8,
|
||||
GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9,
|
||||
};
|
||||
|
||||
struct gpio_event_direct_entry {
|
||||
uint32_t gpio:23;
|
||||
uint32_t code:9;
|
||||
};
|
||||
|
||||
/* inputs */
|
||||
extern int gpio_event_input_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func);
|
||||
struct gpio_event_input_info {
|
||||
/* initialize to gpio_event_input_func */
|
||||
struct gpio_event_info info;
|
||||
ktime_t debounce_time;
|
||||
ktime_t poll_time;
|
||||
uint16_t flags;
|
||||
uint16_t type;
|
||||
const struct gpio_event_direct_entry *keymap;
|
||||
size_t keymap_size;
|
||||
};
|
||||
|
||||
/* outputs */
|
||||
extern int gpio_event_output_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func);
|
||||
extern int gpio_event_output_event(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data,
|
||||
unsigned int type, unsigned int code, int value);
|
||||
struct gpio_event_output_info {
|
||||
/* initialize to gpio_event_output_func and gpio_event_output_event */
|
||||
struct gpio_event_info info;
|
||||
uint16_t flags;
|
||||
uint16_t type;
|
||||
const struct gpio_event_direct_entry *keymap;
|
||||
size_t keymap_size;
|
||||
};
|
||||
|
||||
|
||||
/* axes */
|
||||
|
||||
enum gpio_event_axis_flags {
|
||||
GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16,
|
||||
GPIOEAF_PRINT_RAW = 1U << 17,
|
||||
GPIOEAF_PRINT_EVENT = 1U << 18,
|
||||
};
|
||||
|
||||
extern int gpio_event_axis_func(struct input_dev *input_dev,
|
||||
struct gpio_event_info *info, void **data, int func);
|
||||
struct gpio_event_axis_info {
|
||||
/* initialize to gpio_event_axis_func */
|
||||
struct gpio_event_info info;
|
||||
uint8_t count;
|
||||
uint8_t type; /* EV_REL or EV_ABS */
|
||||
uint16_t code;
|
||||
uint16_t decoded_size;
|
||||
uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
|
||||
uint32_t *gpio;
|
||||
uint32_t flags;
|
||||
};
|
||||
#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
|
||||
#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
|
||||
uint16_t gpio_axis_4bit_gray_map(
|
||||
struct gpio_event_axis_info *info, uint16_t in);
|
||||
uint16_t gpio_axis_5bit_singletrack_map(
|
||||
struct gpio_event_axis_info *info, uint16_t in);
|
||||
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/msm_adsp.h
|
||||
*
|
||||
* Copyright (c) QUALCOMM Incorporated
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: Iliyan Malchev <ibm@android.com>
|
||||
*
|
||||
* 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 __LINUX_MSM_ADSP_H
|
||||
#define __LINUX_MSM_ADSP_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define ADSP_IOCTL_MAGIC 'q'
|
||||
|
||||
/* ADSP_IOCTL_WRITE_COMMAND */
|
||||
struct adsp_command_t {
|
||||
uint16_t queue;
|
||||
uint32_t len; /* bytes */
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
/* ADSP_IOCTL_GET_EVENT */
|
||||
struct adsp_event_t {
|
||||
uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */
|
||||
uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */
|
||||
uint16_t msg_id;
|
||||
uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */
|
||||
uint32_t len; /* size in, number of bytes out */
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
#define ADSP_IOCTL_ENABLE \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_DISABLE \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_DISABLE_ACK \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_WRITE_COMMAND \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
|
||||
|
||||
#define ADSP_IOCTL_GET_EVENT \
|
||||
_IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
|
||||
|
||||
#define ADSP_IOCTL_SET_CLKRATE \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_DISABLE_EVENT_RSP \
|
||||
_IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
|
||||
|
||||
struct adsp_pmem_info {
|
||||
int fd;
|
||||
void *vaddr;
|
||||
};
|
||||
|
||||
#define ADSP_IOCTL_REGISTER_PMEM \
|
||||
_IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_UNREGISTER_PMEM \
|
||||
_IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
|
||||
|
||||
/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
|
||||
* until the device is closed and reopened. Useful for
|
||||
* terminating event dispatch threads
|
||||
*/
|
||||
#define ADSP_IOCTL_ABORT_EVENT_READ \
|
||||
_IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
|
||||
|
||||
#define ADSP_IOCTL_LINK_TASK \
|
||||
_IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
|
||||
|
||||
#endif
|
|
@ -1,115 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/msm_audio.h
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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 __LINUX_MSM_AUDIO_H
|
||||
#define __LINUX_MSM_AUDIO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <asm/sizes.h>
|
||||
|
||||
/* PCM Audio */
|
||||
|
||||
#define AUDIO_IOCTL_MAGIC 'a'
|
||||
|
||||
#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
|
||||
#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
|
||||
#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
|
||||
#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
|
||||
#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
|
||||
#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
|
||||
#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
|
||||
#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
|
||||
#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
|
||||
#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
|
||||
#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
|
||||
#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
|
||||
#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
|
||||
#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
|
||||
#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
|
||||
#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
|
||||
#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
|
||||
#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
|
||||
#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
|
||||
|
||||
#define AUDIO_MAX_COMMON_IOCTL_NUM 100
|
||||
|
||||
#define AUDIO_MAX_COMMON_IOCTL_NUM 100
|
||||
|
||||
struct msm_audio_config {
|
||||
uint32_t buffer_size;
|
||||
uint32_t buffer_count;
|
||||
uint32_t channel_count;
|
||||
uint32_t sample_rate;
|
||||
uint32_t type;
|
||||
uint32_t unused[3];
|
||||
};
|
||||
|
||||
struct msm_audio_stats {
|
||||
uint32_t byte_count;
|
||||
uint32_t sample_count;
|
||||
uint32_t unused[2];
|
||||
};
|
||||
|
||||
/* Audio routing */
|
||||
|
||||
#define SND_IOCTL_MAGIC 's'
|
||||
|
||||
#define SND_MUTE_UNMUTED 0
|
||||
#define SND_MUTE_MUTED 1
|
||||
|
||||
struct msm_snd_device_config {
|
||||
uint32_t device;
|
||||
uint32_t ear_mute;
|
||||
uint32_t mic_mute;
|
||||
};
|
||||
|
||||
#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
|
||||
|
||||
#define SND_METHOD_VOICE 0
|
||||
|
||||
struct msm_snd_volume_config {
|
||||
uint32_t device;
|
||||
uint32_t method;
|
||||
uint32_t volume;
|
||||
};
|
||||
|
||||
#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
|
||||
|
||||
/* Returns the number of SND endpoints supported. */
|
||||
|
||||
#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
|
||||
|
||||
struct msm_snd_endpoint {
|
||||
int id; /* input and output */
|
||||
char name[64]; /* output only */
|
||||
};
|
||||
|
||||
/* Takes an index between 0 and one less than the number returned by
|
||||
* SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
|
||||
* SND endpoint. On input, the .id field contains the number of the
|
||||
* endpoint, and on exit it contains the SND index, while .name contains
|
||||
* the description of the endpoint.
|
||||
*/
|
||||
|
||||
#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
|
||||
|
||||
struct msm_audio_pcm_config {
|
||||
uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
|
||||
uint32_t buffer_count; /* Number of buffers to allocate */
|
||||
uint32_t buffer_size; /* Size of buffer for capturing of
|
||||
PCM samples */
|
||||
};
|
||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/msm_rpcrouter.h
|
||||
*
|
||||
* Copyright (c) QUALCOMM Incorporated
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: San Mehat <san@android.com>
|
||||
*
|
||||
* 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 __LINUX_MSM_RPCROUTER_H
|
||||
#define __LINUX_MSM_RPCROUTER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define RPC_ROUTER_VERSION_V1 0x00010000
|
||||
|
||||
struct rpcrouter_ioctl_server_args {
|
||||
uint32_t prog;
|
||||
uint32_t vers;
|
||||
};
|
||||
|
||||
#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
|
||||
|
||||
#define RPC_ROUTER_IOCTL_GET_VERSION \
|
||||
_IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
|
||||
|
||||
#define RPC_ROUTER_IOCTL_GET_MTU \
|
||||
_IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
|
||||
|
||||
#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
|
||||
_IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
|
||||
|
||||
#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
|
||||
_IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
|
||||
|
||||
#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
|
||||
_IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
|
||||
|
||||
#endif
|
|
@ -1,91 +0,0 @@
|
|||
/* drivers/staging/dream/include/linux/wakelock.h
|
||||
*
|
||||
* Copyright (C) 2007-2008 Google, 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 _LINUX_WAKELOCK_H
|
||||
#define _LINUX_WAKELOCK_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
/* A wake_lock prevents the system from entering suspend or other low power
|
||||
* states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
|
||||
* prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
|
||||
* states that cause large interrupt latencies or that disable a set of
|
||||
* interrupts will not entered from idle until the wake_locks are released.
|
||||
*/
|
||||
|
||||
enum {
|
||||
WAKE_LOCK_SUSPEND, /* Prevent suspend */
|
||||
WAKE_LOCK_IDLE, /* Prevent low power idle */
|
||||
WAKE_LOCK_TYPE_COUNT
|
||||
};
|
||||
|
||||
struct wake_lock {
|
||||
#ifdef CONFIG_HAS_WAKELOCK
|
||||
struct list_head link;
|
||||
int flags;
|
||||
const char *name;
|
||||
unsigned long expires;
|
||||
#ifdef CONFIG_WAKELOCK_STAT
|
||||
struct {
|
||||
int count;
|
||||
int expire_count;
|
||||
int wakeup_count;
|
||||
ktime_t total_time;
|
||||
ktime_t prevent_suspend_time;
|
||||
ktime_t max_time;
|
||||
ktime_t last_time;
|
||||
} stat;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HAS_WAKELOCK
|
||||
|
||||
void wake_lock_init(struct wake_lock *lock, int type, const char *name);
|
||||
void wake_lock_destroy(struct wake_lock *lock);
|
||||
void wake_lock(struct wake_lock *lock);
|
||||
void wake_lock_timeout(struct wake_lock *lock, long timeout);
|
||||
void wake_unlock(struct wake_lock *lock);
|
||||
|
||||
/* wake_lock_active returns a non-zero value if the wake_lock is currently
|
||||
* locked. If the wake_lock has a timeout, it does not check the timeout
|
||||
* but if the timeout had aready been checked it will return 0.
|
||||
*/
|
||||
int wake_lock_active(struct wake_lock *lock);
|
||||
|
||||
/* has_wake_lock returns 0 if no wake locks of the specified type are active,
|
||||
* and non-zero if one or more wake locks are held. Specifically it returns
|
||||
* -1 if one or more wake locks with no timeout are active or the
|
||||
* number of jiffies until all active wake locks time out.
|
||||
*/
|
||||
long has_wake_lock(int type);
|
||||
|
||||
#else
|
||||
|
||||
static inline void wake_lock_init(struct wake_lock *lock, int type,
|
||||
const char *name) {}
|
||||
static inline void wake_lock_destroy(struct wake_lock *lock) {}
|
||||
static inline void wake_lock(struct wake_lock *lock) {}
|
||||
static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
|
||||
static inline void wake_unlock(struct wake_lock *lock) {}
|
||||
|
||||
static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
|
||||
static inline long has_wake_lock(int type) { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef __ASM__ARCH_CAMERA_H
|
||||
#define __ASM__ARCH_CAMERA_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "linux/types.h"
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <media/msm_camera.h>
|
||||
|
||||
#ifdef CONFIG_MSM_CAMERA_DEBUG
|
||||
#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
|
||||
#else
|
||||
#define CDBG(fmt, args...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define MSM_CAMERA_MSG 0
|
||||
#define MSM_CAMERA_EVT 1
|
||||
#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
|
||||
#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3
|
||||
#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
|
||||
#define NUM_AF_STAT_OUTPUT_BUFFERS 3
|
||||
|
||||
enum msm_queue {
|
||||
MSM_CAM_Q_CTRL, /* control command or control command status */
|
||||
MSM_CAM_Q_VFE_EVT, /* adsp event */
|
||||
MSM_CAM_Q_VFE_MSG, /* adsp message */
|
||||
MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
|
||||
};
|
||||
|
||||
enum vfe_resp_msg {
|
||||
VFE_EVENT,
|
||||
VFE_MSG_GENERAL,
|
||||
VFE_MSG_SNAPSHOT,
|
||||
VFE_MSG_OUTPUT1,
|
||||
VFE_MSG_OUTPUT2,
|
||||
VFE_MSG_STATS_AF,
|
||||
VFE_MSG_STATS_WE,
|
||||
};
|
||||
|
||||
struct msm_vfe_phy_info {
|
||||
uint32_t sbuf_phy;
|
||||
uint32_t y_phy;
|
||||
uint32_t cbcr_phy;
|
||||
};
|
||||
|
||||
struct msm_vfe_resp {
|
||||
enum vfe_resp_msg type;
|
||||
struct msm_vfe_evt_msg evt_msg;
|
||||
struct msm_vfe_phy_info phy;
|
||||
void *extdata;
|
||||
int32_t extlen;
|
||||
};
|
||||
|
||||
struct msm_vfe_callback {
|
||||
void (*vfe_resp)(struct msm_vfe_resp *,
|
||||
enum msm_queue, void *syncdata);
|
||||
void* (*vfe_alloc)(int, void *syncdata);
|
||||
};
|
||||
|
||||
struct msm_camvfe_fn {
|
||||
int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
|
||||
int (*vfe_enable)(struct camera_enable_cmd *);
|
||||
int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
|
||||
int (*vfe_disable)(struct camera_enable_cmd *,
|
||||
struct platform_device *dev);
|
||||
void (*vfe_release)(struct platform_device *);
|
||||
};
|
||||
|
||||
struct msm_sensor_ctrl {
|
||||
int (*s_init)(const struct msm_camera_sensor_info *);
|
||||
int (*s_release)(void);
|
||||
int (*s_config)(void __user *);
|
||||
};
|
||||
|
||||
struct msm_sync {
|
||||
/* These two queues are accessed from a process context only. */
|
||||
struct hlist_head frame; /* most-frequently accessed */
|
||||
struct hlist_head stats;
|
||||
|
||||
/* The message queue is used by the control thread to send commands
|
||||
* to the config thread, and also by the DSP to send messages to the
|
||||
* config thread. Thus it is the only queue that is accessed from
|
||||
* both interrupt and process context.
|
||||
*/
|
||||
spinlock_t msg_event_q_lock;
|
||||
struct list_head msg_event_q;
|
||||
wait_queue_head_t msg_event_wait;
|
||||
|
||||
/* This queue contains preview frames. It is accessed by the DSP (in
|
||||
* in interrupt context, and by the frame thread.
|
||||
*/
|
||||
spinlock_t prev_frame_q_lock;
|
||||
struct list_head prev_frame_q;
|
||||
wait_queue_head_t prev_frame_wait;
|
||||
int unblock_poll_frame;
|
||||
|
||||
/* This queue contains snapshot frames. It is accessed by the DSP (in
|
||||
* interrupt context, and by the control thread.
|
||||
*/
|
||||
spinlock_t pict_frame_q_lock;
|
||||
struct list_head pict_frame_q;
|
||||
wait_queue_head_t pict_frame_wait;
|
||||
|
||||
struct msm_camera_sensor_info *sdata;
|
||||
struct msm_camvfe_fn vfefn;
|
||||
struct msm_sensor_ctrl sctrl;
|
||||
struct platform_device *pdev;
|
||||
uint8_t opencnt;
|
||||
void *cropinfo;
|
||||
int croplen;
|
||||
unsigned pict_pp;
|
||||
|
||||
const char *apps_id;
|
||||
|
||||
struct mutex lock;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define MSM_APPS_ID_V4L2 "msm_v4l2"
|
||||
#define MSM_APPS_ID_PROP "msm_qct"
|
||||
|
||||
struct msm_device {
|
||||
struct msm_sync *sync; /* most-frequently accessed */
|
||||
struct device *device;
|
||||
struct cdev cdev;
|
||||
/* opened is meaningful only for the config and frame nodes,
|
||||
* which may be opened only once.
|
||||
*/
|
||||
atomic_t opened;
|
||||
};
|
||||
|
||||
struct msm_control_device_queue {
|
||||
spinlock_t ctrl_status_q_lock;
|
||||
struct list_head ctrl_status_q;
|
||||
wait_queue_head_t ctrl_status_wait;
|
||||
};
|
||||
|
||||
struct msm_control_device {
|
||||
struct msm_device *pmsm;
|
||||
|
||||
/* This queue used by the config thread to send responses back to the
|
||||
* control thread. It is accessed only from a process context.
|
||||
*/
|
||||
struct msm_control_device_queue ctrl_q;
|
||||
};
|
||||
|
||||
/* this structure is used in kernel */
|
||||
struct msm_queue_cmd {
|
||||
struct list_head list;
|
||||
enum msm_queue type;
|
||||
void *command;
|
||||
};
|
||||
|
||||
struct register_address_value_pair {
|
||||
uint16_t register_address;
|
||||
uint16_t register_value;
|
||||
};
|
||||
|
||||
struct msm_pmem_region {
|
||||
struct hlist_node list;
|
||||
int type;
|
||||
void *vaddr;
|
||||
unsigned long paddr;
|
||||
unsigned long len;
|
||||
struct file *file;
|
||||
uint32_t y_off;
|
||||
uint32_t cbcr_off;
|
||||
int fd;
|
||||
uint8_t active;
|
||||
};
|
||||
|
||||
struct axidata {
|
||||
uint32_t bufnum1;
|
||||
uint32_t bufnum2;
|
||||
struct msm_pmem_region *region;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MSM_CAMERA_FLASH
|
||||
int msm_camera_flash_set_led_state(unsigned led_state);
|
||||
#else
|
||||
static inline int msm_camera_flash_set_led_state(unsigned led_state)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Below functions are added for V4L2 kernel APIs */
|
||||
struct msm_v4l2_driver {
|
||||
struct msm_sync *sync;
|
||||
int (*open)(struct msm_sync *, const char *apps_id);
|
||||
int (*release)(struct msm_sync *);
|
||||
int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
|
||||
int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
|
||||
int (*get_frame) (struct msm_sync *, struct msm_frame *);
|
||||
int (*put_frame) (struct msm_sync *, struct msm_frame *);
|
||||
int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
|
||||
unsigned int (*drv_poll) (struct msm_sync *, struct file *,
|
||||
struct poll_table_struct *);
|
||||
};
|
||||
|
||||
int msm_v4l2_register(struct msm_v4l2_driver *);
|
||||
int msm_v4l2_unregister(struct msm_v4l2_driver *);
|
||||
|
||||
void msm_camvfe_init(void);
|
||||
int msm_camvfe_check(void *);
|
||||
void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
|
||||
int msm_camera_drv_start(struct platform_device *dev,
|
||||
int (*sensor_probe)(const struct msm_camera_sensor_info *,
|
||||
struct msm_sensor_ctrl *));
|
||||
|
||||
enum msm_camio_clk_type {
|
||||
CAMIO_VFE_MDC_CLK,
|
||||
CAMIO_MDC_CLK,
|
||||
CAMIO_VFE_CLK,
|
||||
CAMIO_VFE_AXI_CLK,
|
||||
|
||||
CAMIO_MAX_CLK
|
||||
};
|
||||
|
||||
enum msm_camio_clk_src_type {
|
||||
MSM_CAMIO_CLK_SRC_INTERNAL,
|
||||
MSM_CAMIO_CLK_SRC_EXTERNAL,
|
||||
MSM_CAMIO_CLK_SRC_MAX
|
||||
};
|
||||
|
||||
enum msm_s_test_mode {
|
||||
S_TEST_OFF,
|
||||
S_TEST_1,
|
||||
S_TEST_2,
|
||||
S_TEST_3
|
||||
};
|
||||
|
||||
enum msm_s_resolution {
|
||||
S_QTR_SIZE,
|
||||
S_FULL_SIZE,
|
||||
S_INVALID_SIZE
|
||||
};
|
||||
|
||||
enum msm_s_reg_update {
|
||||
/* Sensor egisters that need to be updated during initialization */
|
||||
S_REG_INIT,
|
||||
/* Sensor egisters that needs periodic I2C writes */
|
||||
S_UPDATE_PERIODIC,
|
||||
/* All the sensor Registers will be updated */
|
||||
S_UPDATE_ALL,
|
||||
/* Not valid update */
|
||||
S_UPDATE_INVALID
|
||||
};
|
||||
|
||||
enum msm_s_setting {
|
||||
S_RES_PREVIEW,
|
||||
S_RES_CAPTURE
|
||||
};
|
||||
|
||||
int msm_camio_enable(struct platform_device *dev);
|
||||
|
||||
int msm_camio_clk_enable(enum msm_camio_clk_type clk);
|
||||
int msm_camio_clk_disable(enum msm_camio_clk_type clk);
|
||||
int msm_camio_clk_config(uint32_t freq);
|
||||
void msm_camio_clk_rate_set(int rate);
|
||||
void msm_camio_clk_axi_rate_set(int rate);
|
||||
|
||||
void msm_camio_camif_pad_reg_reset(void);
|
||||
void msm_camio_camif_pad_reg_reset_2(void);
|
||||
|
||||
void msm_camio_vfe_blk_reset(void);
|
||||
|
||||
void msm_camio_clk_sel(enum msm_camio_clk_src_type);
|
||||
void msm_camio_disable(struct platform_device *);
|
||||
int msm_camio_probe_on(struct platform_device *);
|
||||
int msm_camio_probe_off(struct platform_device *);
|
||||
#endif
|
|
@ -1,112 +0,0 @@
|
|||
/* include/asm-arm/arch-msm/msm_adsp.h
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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_MSM_ADSP_H
|
||||
#define __ASM__ARCH_MSM_ADSP_H
|
||||
|
||||
struct msm_adsp_module;
|
||||
|
||||
struct msm_adsp_ops {
|
||||
/* event is called from interrupt context when a message
|
||||
* arrives from the DSP. Use the provided function pointer
|
||||
* to copy the message into a local buffer. Do NOT call
|
||||
* it multiple times.
|
||||
*/
|
||||
void (*event)(void *driver_data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len));
|
||||
};
|
||||
|
||||
/* Get, Put, Enable, and Disable are synchronous and must only
|
||||
* be called from thread context. Enable and Disable will block
|
||||
* up to one second in the event of a fatal DSP error but are
|
||||
* much faster otherwise.
|
||||
*/
|
||||
int msm_adsp_get(const char *name, struct msm_adsp_module **module,
|
||||
struct msm_adsp_ops *ops, void *driver_data);
|
||||
void msm_adsp_put(struct msm_adsp_module *module);
|
||||
int msm_adsp_enable(struct msm_adsp_module *module);
|
||||
int msm_adsp_disable(struct msm_adsp_module *module);
|
||||
int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
|
||||
|
||||
/* Write is safe to call from interrupt context.
|
||||
*/
|
||||
int msm_adsp_write(struct msm_adsp_module *module,
|
||||
unsigned queue_id,
|
||||
void *data, size_t len);
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
/* Command Queue Indexes */
|
||||
#define QDSP_lpmCommandQueue 0
|
||||
#define QDSP_mpuAfeQueue 1
|
||||
#define QDSP_mpuGraphicsCmdQueue 2
|
||||
#define QDSP_mpuModmathCmdQueue 3
|
||||
#define QDSP_mpuVDecCmdQueue 4
|
||||
#define QDSP_mpuVDecPktQueue 5
|
||||
#define QDSP_mpuVEncCmdQueue 6
|
||||
#define QDSP_rxMpuDecCmdQueue 7
|
||||
#define QDSP_rxMpuDecPktQueue 8
|
||||
#define QDSP_txMpuEncQueue 9
|
||||
#define QDSP_uPAudPPCmd1Queue 10
|
||||
#define QDSP_uPAudPPCmd2Queue 11
|
||||
#define QDSP_uPAudPPCmd3Queue 12
|
||||
#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
|
||||
#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
|
||||
#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
|
||||
#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
|
||||
#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
|
||||
#define QDSP_uPAudPreProcCmdQueue 18
|
||||
#define QDSP_uPAudRecBitStreamQueue 19
|
||||
#define QDSP_uPAudRecCmdQueue 20
|
||||
#define QDSP_uPDiagQueue 21
|
||||
#define QDSP_uPJpegActionCmdQueue 22
|
||||
#define QDSP_uPJpegCfgCmdQueue 23
|
||||
#define QDSP_uPVocProcQueue 24
|
||||
#define QDSP_vfeCommandQueue 25
|
||||
#define QDSP_vfeCommandScaleQueue 26
|
||||
#define QDSP_vfeCommandTableQueue 27
|
||||
#define QDSP_MAX_NUM_QUEUES 28
|
||||
#else
|
||||
/* Command Queue Indexes */
|
||||
#define QDSP_lpmCommandQueue 0
|
||||
#define QDSP_mpuAfeQueue 1
|
||||
#define QDSP_mpuGraphicsCmdQueue 2
|
||||
#define QDSP_mpuModmathCmdQueue 3
|
||||
#define QDSP_mpuVDecCmdQueue 4
|
||||
#define QDSP_mpuVDecPktQueue 5
|
||||
#define QDSP_mpuVEncCmdQueue 6
|
||||
#define QDSP_rxMpuDecCmdQueue 7
|
||||
#define QDSP_rxMpuDecPktQueue 8
|
||||
#define QDSP_txMpuEncQueue 9
|
||||
#define QDSP_uPAudPPCmd1Queue 10
|
||||
#define QDSP_uPAudPPCmd2Queue 11
|
||||
#define QDSP_uPAudPPCmd3Queue 12
|
||||
#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
|
||||
#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
|
||||
#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
|
||||
#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
|
||||
#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
|
||||
#define QDSP_uPAudPreProcCmdQueue 18
|
||||
#define QDSP_uPAudRecBitStreamQueue 19
|
||||
#define QDSP_uPAudRecCmdQueue 20
|
||||
#define QDSP_uPJpegActionCmdQueue 21
|
||||
#define QDSP_uPJpegCfgCmdQueue 22
|
||||
#define QDSP_uPVocProcQueue 23
|
||||
#define QDSP_vfeCommandQueue 24
|
||||
#define QDSP_vfeCommandScaleQueue 25
|
||||
#define QDSP_vfeCommandTableQueue 26
|
||||
#define QDSP_QUEUE_MAX 26
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,179 +0,0 @@
|
|||
/** include/asm-arm/arch-msm/msm_rpcrouter.h
|
||||
*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Copyright (c) 2007-2009 QUALCOMM Incorporated
|
||||
* Author: San Mehat <san@android.com>
|
||||
*
|
||||
* 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_MSM_RPCROUTER_H
|
||||
#define __ASM__ARCH_MSM_RPCROUTER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
/* RPC API version structure
|
||||
* Version bit 31 : 1->hashkey versioning,
|
||||
* 0->major-minor (backward compatible) versioning
|
||||
* hashkey versioning:
|
||||
* Version bits 31-0 hashkey
|
||||
* major-minor (backward compatible) versioning
|
||||
* Version bits 30-28 reserved (no match)
|
||||
* Version bits 27-16 major (must match)
|
||||
* Version bits 15-0 minor (greater or equal)
|
||||
*/
|
||||
#define RPC_VERSION_MODE_MASK 0x80000000
|
||||
#define RPC_VERSION_MAJOR_MASK 0x0fff0000
|
||||
#define RPC_VERSION_MAJOR_OFFSET 16
|
||||
#define RPC_VERSION_MINOR_MASK 0x0000ffff
|
||||
|
||||
#define MSM_RPC_VERS(major, minor) \
|
||||
((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \
|
||||
RPC_VERSION_MAJOR_MASK) | \
|
||||
((minor) & RPC_VERSION_MINOR_MASK)))
|
||||
#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \
|
||||
RPC_VERSION_MAJOR_OFFSET)
|
||||
#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
|
||||
#else
|
||||
#define MSM_RPC_VERS(major, minor) (major)
|
||||
#define MSM_RPC_GET_MAJOR(vers) (vers)
|
||||
#define MSM_RPC_GET_MINOR(vers) 0
|
||||
#endif
|
||||
|
||||
struct msm_rpc_endpoint;
|
||||
|
||||
struct rpcsvr_platform_device
|
||||
{
|
||||
struct platform_device base;
|
||||
uint32_t prog;
|
||||
uint32_t vers;
|
||||
};
|
||||
|
||||
#define RPC_DATA_IN 0
|
||||
/*
|
||||
* Structures for sending / receiving direct RPC requests
|
||||
* XXX: Any cred/verif lengths > 0 not supported
|
||||
*/
|
||||
|
||||
struct rpc_request_hdr
|
||||
{
|
||||
uint32_t xid;
|
||||
uint32_t type; /* 0 */
|
||||
uint32_t rpc_vers; /* 2 */
|
||||
uint32_t prog;
|
||||
uint32_t vers;
|
||||
uint32_t procedure;
|
||||
uint32_t cred_flavor;
|
||||
uint32_t cred_length;
|
||||
uint32_t verf_flavor;
|
||||
uint32_t verf_length;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t low;
|
||||
uint32_t high;
|
||||
} rpc_reply_progmismatch_data;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
} rpc_denied_reply_hdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t verf_flavor;
|
||||
uint32_t verf_length;
|
||||
uint32_t accept_stat;
|
||||
#define RPC_ACCEPTSTAT_SUCCESS 0
|
||||
#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
|
||||
#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
|
||||
#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
|
||||
#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
|
||||
#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
|
||||
#define RPC_ACCEPTSTAT_PROG_LOCKED 6
|
||||
/*
|
||||
* Following data is dependant on accept_stat
|
||||
* If ACCEPTSTAT == PROG_MISMATCH then there is a
|
||||
* 'rpc_reply_progmismatch_data' structure following the header.
|
||||
* Otherwise the data is procedure specific
|
||||
*/
|
||||
} rpc_accepted_reply_hdr;
|
||||
|
||||
struct rpc_reply_hdr
|
||||
{
|
||||
uint32_t xid;
|
||||
uint32_t type;
|
||||
uint32_t reply_stat;
|
||||
#define RPCMSG_REPLYSTAT_ACCEPTED 0
|
||||
#define RPCMSG_REPLYSTAT_DENIED 1
|
||||
union {
|
||||
rpc_accepted_reply_hdr acc_hdr;
|
||||
rpc_denied_reply_hdr dny_hdr;
|
||||
} data;
|
||||
};
|
||||
|
||||
/* flags for msm_rpc_connect() */
|
||||
#define MSM_RPC_UNINTERRUPTIBLE 0x0001
|
||||
|
||||
/* use IS_ERR() to check for failure */
|
||||
struct msm_rpc_endpoint *msm_rpc_open(void);
|
||||
/* Connect with the specified server version */
|
||||
struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
|
||||
uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
|
||||
/* check if server version can handle client requested version */
|
||||
int msm_rpc_is_compatible_version(uint32_t server_version,
|
||||
uint32_t client_version);
|
||||
|
||||
int msm_rpc_close(struct msm_rpc_endpoint *ept);
|
||||
int msm_rpc_write(struct msm_rpc_endpoint *ept,
|
||||
void *data, int len);
|
||||
int msm_rpc_read(struct msm_rpc_endpoint *ept,
|
||||
void **data, unsigned len, long timeout);
|
||||
void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
|
||||
uint32_t prog, uint32_t vers, uint32_t proc);
|
||||
int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
|
||||
uint32_t prog, uint32_t vers);
|
||||
int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
|
||||
uint32_t prog, uint32_t vers);
|
||||
|
||||
/* simple blocking rpc call
|
||||
*
|
||||
* request is mandatory and must have a rpc_request_hdr
|
||||
* at the start. The header will be filled out for you.
|
||||
*
|
||||
* reply provides a buffer for replies of reply_max_size
|
||||
*/
|
||||
int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
|
||||
void *request, int request_size,
|
||||
void *reply, int reply_max_size,
|
||||
long timeout);
|
||||
int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
|
||||
void *request, int request_size,
|
||||
long timeout);
|
||||
|
||||
struct msm_rpc_server
|
||||
{
|
||||
struct list_head list;
|
||||
uint32_t flags;
|
||||
|
||||
uint32_t prog;
|
||||
uint32_t vers;
|
||||
|
||||
int (*rpc_call)(struct msm_rpc_server *server,
|
||||
struct rpc_request_hdr *req, unsigned len);
|
||||
};
|
||||
|
||||
int msm_rpc_create_server(struct msm_rpc_server *server);
|
||||
|
||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||
/* linux/include/asm-arm/arch-msm/msm_smd.h
|
||||
*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: Brian Swetland <swetland@google.com>
|
||||
*
|
||||
* 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_MSM_SMD_H
|
||||
#define __ASM_ARCH_MSM_SMD_H
|
||||
|
||||
typedef struct smd_channel smd_channel_t;
|
||||
|
||||
/* warning: notify() may be called before open returns */
|
||||
int smd_open(const char *name, smd_channel_t **ch, void *priv,
|
||||
void (*notify)(void *priv, unsigned event));
|
||||
|
||||
#define SMD_EVENT_DATA 1
|
||||
#define SMD_EVENT_OPEN 2
|
||||
#define SMD_EVENT_CLOSE 3
|
||||
|
||||
int smd_close(smd_channel_t *ch);
|
||||
|
||||
/* passing a null pointer for data reads and discards */
|
||||
int smd_read(smd_channel_t *ch, void *data, int len);
|
||||
|
||||
/* Write to stream channels may do a partial write and return
|
||||
** the length actually written.
|
||||
** Write to packet channels will never do a partial write --
|
||||
** it will return the requested length written or an error.
|
||||
*/
|
||||
int smd_write(smd_channel_t *ch, const void *data, int len);
|
||||
|
||||
int smd_write_avail(smd_channel_t *ch);
|
||||
int smd_read_avail(smd_channel_t *ch);
|
||||
|
||||
/* Returns the total size of the current packet being read.
|
||||
** Returns 0 if no packets available or a stream channel.
|
||||
*/
|
||||
int smd_cur_packet_size(smd_channel_t *ch);
|
||||
|
||||
/* used for tty unthrottling and the like -- causes the notify()
|
||||
** callback to be called from the same lock context as is used
|
||||
** when it is called from channel updates
|
||||
*/
|
||||
void smd_kick(smd_channel_t *ch);
|
||||
|
||||
|
||||
#if 0
|
||||
/* these are interruptable waits which will block you until the specified
|
||||
** number of bytes are readable or writable.
|
||||
*/
|
||||
int smd_wait_until_readable(smd_channel_t *ch, int bytes);
|
||||
int smd_wait_until_writable(smd_channel_t *ch, int bytes);
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SMD_PORT_DS = 0,
|
||||
SMD_PORT_DIAG,
|
||||
SMD_PORT_RPC_CALL,
|
||||
SMD_PORT_RPC_REPLY,
|
||||
SMD_PORT_BT,
|
||||
SMD_PORT_CONTROL,
|
||||
SMD_PORT_MEMCPY_SPARE1,
|
||||
SMD_PORT_DATA1,
|
||||
SMD_PORT_DATA2,
|
||||
SMD_PORT_DATA3,
|
||||
SMD_PORT_DATA4,
|
||||
SMD_PORT_DATA5,
|
||||
SMD_PORT_DATA6,
|
||||
SMD_PORT_DATA7,
|
||||
SMD_PORT_DATA8,
|
||||
SMD_PORT_DATA9,
|
||||
SMD_PORT_DATA10,
|
||||
SMD_PORT_DATA11,
|
||||
SMD_PORT_DATA12,
|
||||
SMD_PORT_DATA13,
|
||||
SMD_PORT_DATA14,
|
||||
SMD_PORT_DATA15,
|
||||
SMD_PORT_DATA16,
|
||||
SMD_PORT_DATA17,
|
||||
SMD_PORT_DATA18,
|
||||
SMD_PORT_DATA19,
|
||||
SMD_PORT_DATA20,
|
||||
SMD_PORT_GPS_NMEA,
|
||||
SMD_PORT_BRIDGE_1,
|
||||
SMD_PORT_BRIDGE_2,
|
||||
SMD_PORT_BRIDGE_3,
|
||||
SMD_PORT_BRIDGE_4,
|
||||
SMD_PORT_BRIDGE_5,
|
||||
SMD_PORT_LOOPBACK,
|
||||
SMD_PORT_CS_APPS_MODEM,
|
||||
SMD_PORT_CS_APPS_DSP,
|
||||
SMD_PORT_CS_MODEM_DSP,
|
||||
SMD_NUM_PORTS,
|
||||
} smd_port_id_type;
|
||||
|
||||
#endif
|
|
@ -1,94 +0,0 @@
|
|||
#ifndef QDSP5AUDPLAYCMDI_H
|
||||
#define QDSP5AUDPLAYCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Command Interface for AUDPLAYTASK on QDSP5
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
|
||||
audplay_cmd_dec_data_avail
|
||||
Send buffer to AUDPLAY task
|
||||
|
||||
|
||||
Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000
|
||||
#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \
|
||||
sizeof(audplay_cmd_bitstream_data_avail)
|
||||
|
||||
/* Type specification of dec_data_avail message sent to AUDPLAYTASK
|
||||
*/
|
||||
typedef struct {
|
||||
/*command ID*/
|
||||
unsigned int cmd_id;
|
||||
|
||||
/* Decoder ID for which message is being sent */
|
||||
unsigned int decoder_id;
|
||||
|
||||
/* Start address of data in ARM global memory */
|
||||
unsigned int buf_ptr;
|
||||
|
||||
/* Number of 16-bit words of bit-stream data contiguously available at the
|
||||
* above-mentioned address. */
|
||||
unsigned int buf_size;
|
||||
|
||||
/* Partition number used by audPlayTask to communicate with DSP's RTOS
|
||||
* kernel */
|
||||
unsigned int partition_number;
|
||||
} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
|
||||
|
||||
#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
|
||||
#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
|
||||
sizeof(struct audplay_cmd_hpcm_buf_cfg)
|
||||
|
||||
struct audplay_cmd_hpcm_buf_cfg {
|
||||
unsigned int cmd_id;
|
||||
unsigned int hostpcm_config;
|
||||
unsigned int feedback_frequency;
|
||||
unsigned int byte_swap;
|
||||
unsigned int max_buffers;
|
||||
unsigned int partition_number;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
|
||||
#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
|
||||
sizeof(struct audplay_cmd_buffer_update)
|
||||
|
||||
struct audplay_cmd_buffer_refresh {
|
||||
unsigned int cmd_id;
|
||||
unsigned int num_buffers;
|
||||
unsigned int buf_read_count;
|
||||
unsigned int buf0_address;
|
||||
unsigned int buf0_length;
|
||||
unsigned int buf1_address;
|
||||
unsigned int buf1_length;
|
||||
} __attribute__((packed));
|
||||
#endif /* QDSP5AUDPLAYCMD_H */
|
|
@ -1,70 +0,0 @@
|
|||
#ifndef QDSP5AUDPLAYMSG_H
|
||||
#define QDSP5AUDPLAYMSG_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
Q D S P 5 A U D I O P L A Y T A S K M S G
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Message sent by AUDPLAY task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
|
||||
Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
|
||||
|
||||
===========================================================================*/
|
||||
#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001
|
||||
#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \
|
||||
sizeof(audplay_msg_dec_needs_data)
|
||||
|
||||
typedef struct{
|
||||
/* reserved*/
|
||||
unsigned int dec_id;
|
||||
|
||||
/* The read pointer offset of external memory until which the
|
||||
* bitstream has been DMAed in. */
|
||||
unsigned int adecDataReadPtrOffset;
|
||||
|
||||
/* The buffer size of external memory. */
|
||||
unsigned int adecDataBufSize;
|
||||
|
||||
unsigned int bitstream_free_len;
|
||||
unsigned int bitstream_write_ptr;
|
||||
unsigned int bitstarem_buf_start;
|
||||
unsigned int bitstream_buf_len;
|
||||
} __attribute__((packed)) audplay_msg_dec_needs_data;
|
||||
|
||||
#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
|
||||
#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
|
||||
sizeof(struct audplay_msg_buffer_update)
|
||||
|
||||
struct audplay_msg_buffer_update {
|
||||
unsigned int buffer_write_count;
|
||||
unsigned int num_of_buffer;
|
||||
unsigned int buf0_address;
|
||||
unsigned int buf0_length;
|
||||
unsigned int buf1_address;
|
||||
unsigned int buf1_length;
|
||||
} __attribute__((packed));
|
||||
#endif /* QDSP5AUDPLAYMSG_H */
|
|
@ -1,914 +0,0 @@
|
|||
#ifndef QDSP5AUDPPCMDI_H
|
||||
#define QDSP5AUDPPCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by AUDPP Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* ARM to AUDPPTASK Commands
|
||||
*
|
||||
* ARM uses three command queues to communicate with AUDPPTASK
|
||||
* 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
|
||||
* Location : MEMA
|
||||
* Buffer Size : 6 words
|
||||
* No of buffers in a queue : 20 for gaming audio and 5 for other images
|
||||
* 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
|
||||
* Location : MEMA
|
||||
* Buffer Size : 23
|
||||
* No of buffers in a queue : 2
|
||||
* 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
|
||||
* Location : MEMA
|
||||
* Buffer Size : 145
|
||||
* No of buffers in a queue : 3
|
||||
*/
|
||||
|
||||
/*
|
||||
* Commands Related to uPAudPPCmd1Queue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command Structure to enable or disable the active decoders
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_DEC_TYPE 0x0001
|
||||
#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type)
|
||||
|
||||
/* Enable the decoder */
|
||||
#define AUDPP_CMD_DEC_TYPE_M 0x000F
|
||||
|
||||
#define AUDPP_CMD_ENA_DEC_V 0x4000
|
||||
#define AUDPP_CMD_DIS_DEC_V 0x0000
|
||||
#define AUDPP_CMD_DEC_STATE_M 0x4000
|
||||
|
||||
#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000
|
||||
#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000
|
||||
|
||||
|
||||
/* Type specification of cmd_cfg_dec */
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short dec0_cfg;
|
||||
unsigned short dec1_cfg;
|
||||
unsigned short dec2_cfg;
|
||||
unsigned short dec3_cfg;
|
||||
unsigned short dec4_cfg;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_dec_type;
|
||||
|
||||
/*
|
||||
* Command Structure to Pause , Resume and flushes the selected audio decoders
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_DEC_CTRL 0x0002
|
||||
#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl)
|
||||
|
||||
/* Decoder control commands for pause, resume and flush */
|
||||
#define AUDPP_CMD_FLUSH_V 0x2000
|
||||
|
||||
#define AUDPP_CMD_PAUSE_V 0x4000
|
||||
#define AUDPP_CMD_RESUME_V 0x0000
|
||||
|
||||
#define AUDPP_CMD_UPDATE_V 0x8000
|
||||
#define AUDPP_CMD_IGNORE_V 0x0000
|
||||
|
||||
|
||||
/* Type Spec for decoder control command*/
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short dec0_ctrl;
|
||||
unsigned short dec1_ctrl;
|
||||
unsigned short dec2_ctrl;
|
||||
unsigned short dec3_ctrl;
|
||||
unsigned short dec4_ctrl;
|
||||
} __attribute__((packed)) audpp_cmd_dec_ctrl;
|
||||
|
||||
/*
|
||||
* Command Structure to Configure the AVSync FeedBack Mechanism
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_AVSYNC 0x0003
|
||||
#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_number;
|
||||
unsigned short interrupt_interval_lsw;
|
||||
unsigned short interrupt_interval_msw;
|
||||
} __attribute__((packed)) audpp_cmd_avsync;
|
||||
|
||||
/*
|
||||
* Command Structure to enable or disable(sleep) the AUDPPTASK
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG 0x0004
|
||||
#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg)
|
||||
|
||||
#define AUDPP_CMD_CFG_SLEEP 0x0000
|
||||
#define AUDPP_CMD_CFG_ENABLE 0xFFFF
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short cfg;
|
||||
} __attribute__((packed)) audpp_cmd_cfg;
|
||||
|
||||
/*
|
||||
* Command Structure to Inject or drop the specified no of samples
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_ADJUST_SAMP 0x0005
|
||||
#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp)
|
||||
|
||||
#define AUDPP_CMD_SAMP_DROP -1
|
||||
#define AUDPP_CMD_SAMP_INSERT 0x0001
|
||||
|
||||
#define AUDPP_CMD_NUM_SAMPLES 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_no;
|
||||
signed short sample_insert_or_drop;
|
||||
unsigned short num_samples;
|
||||
} __attribute__((packed)) audpp_cmd_adjust_samp;
|
||||
|
||||
/*
|
||||
* Command Structure to Configure AVSync Feedback Mechanism
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_AVSYNC_CMD_2 0x0006
|
||||
#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_number;
|
||||
unsigned short interrupt_interval_lsw;
|
||||
unsigned short interrupt_interval_msw;
|
||||
unsigned short sample_counter_dlsw;
|
||||
unsigned short sample_counter_dmsw;
|
||||
unsigned short sample_counter_msw;
|
||||
unsigned short byte_counter_dlsw;
|
||||
unsigned short byte_counter_dmsw;
|
||||
unsigned short byte_counter_msw;
|
||||
} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
|
||||
|
||||
/*
|
||||
* Command Structure to Configure AVSync Feedback Mechanism
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_AVSYNC_CMD_3 0x0007
|
||||
#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_number;
|
||||
unsigned short interrupt_interval_lsw;
|
||||
unsigned short interrupt_interval_msw;
|
||||
unsigned short sample_counter_dlsw;
|
||||
unsigned short sample_counter_dmsw;
|
||||
unsigned short sample_counter_msw;
|
||||
unsigned short byte_counter_dlsw;
|
||||
unsigned short byte_counter_dmsw;
|
||||
unsigned short byte_counter_msw;
|
||||
} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
|
||||
|
||||
#define AUDPP_CMD_ROUTING_MODE 0x0008
|
||||
#define AUDPP_CMD_ROUTING_MODE_LEN \
|
||||
sizeof(struct audpp_cmd_routing_mode)
|
||||
|
||||
struct audpp_cmd_routing_mode {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_number;
|
||||
unsigned short routing_mode;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Commands Related to uPAudPPCmd2Queue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (Common)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \
|
||||
sizeof(audpp_cmd_cfg_adec_params_common)
|
||||
|
||||
#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000
|
||||
#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000
|
||||
|
||||
#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000
|
||||
#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000
|
||||
|
||||
/* Sampling frequency*/
|
||||
#define AUDPP_CMD_SAMP_RATE_96000 0x0000
|
||||
#define AUDPP_CMD_SAMP_RATE_88200 0x0001
|
||||
#define AUDPP_CMD_SAMP_RATE_64000 0x0002
|
||||
#define AUDPP_CMD_SAMP_RATE_48000 0x0003
|
||||
#define AUDPP_CMD_SAMP_RATE_44100 0x0004
|
||||
#define AUDPP_CMD_SAMP_RATE_32000 0x0005
|
||||
#define AUDPP_CMD_SAMP_RATE_24000 0x0006
|
||||
#define AUDPP_CMD_SAMP_RATE_22050 0x0007
|
||||
#define AUDPP_CMD_SAMP_RATE_16000 0x0008
|
||||
#define AUDPP_CMD_SAMP_RATE_12000 0x0009
|
||||
#define AUDPP_CMD_SAMP_RATE_11025 0x000A
|
||||
#define AUDPP_CMD_SAMP_RATE_8000 0x000B
|
||||
|
||||
|
||||
/*
|
||||
* Type specification of cmd_adec_cfg sent to all decoder
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short length;
|
||||
unsigned short dec_id;
|
||||
unsigned short status_msg_flag;
|
||||
unsigned short decoder_frame_counter_msg_period;
|
||||
unsigned short input_sampling_frequency;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (Wav)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \
|
||||
sizeof(audpp_cmd_cfg_adec_params_wav)
|
||||
|
||||
|
||||
#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001
|
||||
#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002
|
||||
|
||||
#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000
|
||||
#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001
|
||||
#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
unsigned short stereo_cfg;
|
||||
unsigned short pcm_width;
|
||||
unsigned short sign;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (ADPCM)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \
|
||||
sizeof(audpp_cmd_cfg_adec_params_adpcm)
|
||||
|
||||
|
||||
#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001
|
||||
#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
unsigned short stereo_cfg;
|
||||
unsigned short block_size;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (MP3)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \
|
||||
sizeof(audpp_cmd_cfg_adec_params_mp3)
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
|
||||
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (AAC)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \
|
||||
sizeof(audpp_cmd_cfg_adec_params_aac)
|
||||
|
||||
|
||||
#define AUDPP_CMD_AAC_FORMAT_ADTS -1
|
||||
#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000
|
||||
#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001
|
||||
#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002
|
||||
|
||||
#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002
|
||||
#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004
|
||||
#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011
|
||||
|
||||
#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001
|
||||
#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000
|
||||
|
||||
#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001
|
||||
#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
signed short format;
|
||||
unsigned short audio_object;
|
||||
unsigned short ep_config;
|
||||
unsigned short aac_section_data_resilience_flag;
|
||||
unsigned short aac_scalefactor_data_resilience_flag;
|
||||
unsigned short aac_spectral_data_resilience_flag;
|
||||
unsigned short sbr_on_flag;
|
||||
unsigned short sbr_ps_on_flag;
|
||||
unsigned short dual_mono_mode;
|
||||
unsigned short channel_configuration;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
|
||||
|
||||
/*
|
||||
* Command Structure to configure Per decoder Parameters (V13K)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \
|
||||
sizeof(struct audpp_cmd_cfg_adec_params_v13k)
|
||||
|
||||
|
||||
#define AUDPP_CMD_STEREO_CFG_MONO 0x0001
|
||||
#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002
|
||||
|
||||
struct audpp_cmd_cfg_adec_params_v13k {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
unsigned short stereo_cfg;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
|
||||
sizeof(struct audpp_cmd_cfg_adec_params_evrc)
|
||||
|
||||
struct audpp_cmd_cfg_adec_params_evrc {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
unsigned short stereo_cfg;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* Command Structure to configure the HOST PCM interface
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF 0x0001
|
||||
#define AUDPP_CMD_PCM_INTF_2 0x0002
|
||||
#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf)
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001
|
||||
#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002
|
||||
|
||||
/* These two values differentiate the two types of commands that could be issued
|
||||
* Interface configuration command and Buffer update command */
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000
|
||||
#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F
|
||||
#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008
|
||||
#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004
|
||||
|
||||
/* These flags control the enabling and disabling of the interface together
|
||||
* with host interface bit mask. */
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_ENA_V -1
|
||||
#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000
|
||||
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0
|
||||
#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1
|
||||
|
||||
|
||||
#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5
|
||||
#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short object_num;
|
||||
signed short config;
|
||||
unsigned short intf_type;
|
||||
|
||||
/* DSP -> ARM Configuration */
|
||||
unsigned short read_buf1LSW;
|
||||
unsigned short read_buf1MSW;
|
||||
unsigned short read_buf1_len;
|
||||
|
||||
unsigned short read_buf2LSW;
|
||||
unsigned short read_buf2MSW;
|
||||
unsigned short read_buf2_len;
|
||||
/* 0:HOST_PCM_INTF disable
|
||||
** 0xFFFF: HOST_PCM_INTF enable
|
||||
*/
|
||||
signed short dsp_to_arm_flag;
|
||||
unsigned short partition_number;
|
||||
|
||||
/* ARM -> DSP Configuration */
|
||||
unsigned short write_buf1LSW;
|
||||
unsigned short write_buf1MSW;
|
||||
unsigned short write_buf1_len;
|
||||
|
||||
unsigned short write_buf2LSW;
|
||||
unsigned short write_buf2MSW;
|
||||
unsigned short write_buf2_len;
|
||||
|
||||
/* 0:HOST_PCM_INTF disable
|
||||
** 0xFFFF: HOST_PCM_INTF enable
|
||||
*/
|
||||
signed short arm_to_rx_flag;
|
||||
unsigned short weight_decoder_to_rx;
|
||||
unsigned short weight_arm_to_rx;
|
||||
|
||||
unsigned short partition_number_arm_to_dsp;
|
||||
unsigned short sample_rate;
|
||||
unsigned short channel_mode;
|
||||
} __attribute__((packed)) audpp_cmd_pcm_intf;
|
||||
|
||||
/*
|
||||
** BUFFER UPDATE COMMAND
|
||||
*/
|
||||
#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \
|
||||
sizeof(audpp_cmd_pcm_intf_send_buffer)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short host_pcm_object;
|
||||
/* set config = 0xFFFF for configuration*/
|
||||
signed short config;
|
||||
unsigned short intf_type;
|
||||
unsigned short dsp_to_arm_buf_id;
|
||||
unsigned short arm_to_dsp_buf_id;
|
||||
unsigned short arm_to_dsp_buf_len;
|
||||
} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
|
||||
|
||||
|
||||
/*
|
||||
* Commands Related to uPAudPPCmd3Queue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing params (Commmon)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_common)
|
||||
|
||||
#define AUDPP_CMD_OBJ0_UPDATE 0x8000
|
||||
#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_OBJ1_UPDATE 0x8000
|
||||
#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_OBJ2_UPDATE 0x8000
|
||||
#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_OBJ3_UPDATE 0x8000
|
||||
#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_OBJ4_UPDATE 0x8000
|
||||
#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_HPCM_UPDATE 0x8000
|
||||
#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000
|
||||
|
||||
#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000
|
||||
#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short obj0_cfg;
|
||||
unsigned short obj1_cfg;
|
||||
unsigned short obj2_cfg;
|
||||
unsigned short obj3_cfg;
|
||||
unsigned short obj4_cfg;
|
||||
unsigned short host_pcm_obj_cfg;
|
||||
unsigned short comman_cfg;
|
||||
unsigned short command_type;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing params (Volume)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_volume)
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
unsigned short volume;
|
||||
unsigned short pan;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing params (PCM Filter) --DOUBT
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned short numerator_b0_filter_lsw;
|
||||
unsigned short numerator_b0_filter_msw;
|
||||
unsigned short numerator_b1_filter_lsw;
|
||||
unsigned short numerator_b1_filter_msw;
|
||||
unsigned short numerator_b2_filter_lsw;
|
||||
unsigned short numerator_b2_filter_msw;
|
||||
} __attribute__((packed)) numerator;
|
||||
|
||||
typedef struct {
|
||||
unsigned short denominator_a0_filter_lsw;
|
||||
unsigned short denominator_a0_filter_msw;
|
||||
unsigned short denominator_a1_filter_lsw;
|
||||
unsigned short denominator_a1_filter_msw;
|
||||
} __attribute__((packed)) denominator;
|
||||
|
||||
typedef struct {
|
||||
unsigned short shift_factor_0;
|
||||
} __attribute__((packed)) shift_factor;
|
||||
|
||||
typedef struct {
|
||||
unsigned short pan_filter_0;
|
||||
} __attribute__((packed)) pan;
|
||||
|
||||
typedef struct {
|
||||
numerator numerator_filter;
|
||||
denominator denominator_filter;
|
||||
shift_factor shift_factor_filter;
|
||||
pan pan_filter;
|
||||
} __attribute__((packed)) filter_1;
|
||||
|
||||
typedef struct {
|
||||
numerator numerator_filter[2];
|
||||
denominator denominator_filter[2];
|
||||
shift_factor shift_factor_filter[2];
|
||||
pan pan_filter[2];
|
||||
} __attribute__((packed)) filter_2;
|
||||
|
||||
typedef struct {
|
||||
numerator numerator_filter[3];
|
||||
denominator denominator_filter[3];
|
||||
shift_factor shift_factor_filter[3];
|
||||
pan pan_filter[3];
|
||||
} __attribute__((packed)) filter_3;
|
||||
|
||||
typedef struct {
|
||||
numerator numerator_filter[4];
|
||||
denominator denominator_filter[4];
|
||||
shift_factor shift_factor_filter[4];
|
||||
pan pan_filter[4];
|
||||
} __attribute__((packed)) filter_4;
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_pcm)
|
||||
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
unsigned short active_flag;
|
||||
unsigned short num_bands;
|
||||
union {
|
||||
filter_1 filter_1_params;
|
||||
filter_2 filter_2_params;
|
||||
filter_3 filter_3_params;
|
||||
filter_4 filter_4_params;
|
||||
} __attribute__((packed)) params_filter;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
|
||||
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters (equalizer)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_eqalizer)
|
||||
|
||||
typedef struct {
|
||||
unsigned short numerator_coeff_0_lsw;
|
||||
unsigned short numerator_coeff_0_msw;
|
||||
unsigned short numerator_coeff_1_lsw;
|
||||
unsigned short numerator_coeff_1_msw;
|
||||
unsigned short numerator_coeff_2_lsw;
|
||||
unsigned short numerator_coeff_2_msw;
|
||||
} __attribute__((packed)) eq_numerator;
|
||||
|
||||
typedef struct {
|
||||
unsigned short denominator_coeff_0_lsw;
|
||||
unsigned short denominator_coeff_0_msw;
|
||||
unsigned short denominator_coeff_1_lsw;
|
||||
unsigned short denominator_coeff_1_msw;
|
||||
} __attribute__((packed)) eq_denominator;
|
||||
|
||||
typedef struct {
|
||||
unsigned short shift_factor;
|
||||
} __attribute__((packed)) eq_shiftfactor;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator;
|
||||
eq_denominator denominator;
|
||||
eq_shiftfactor shiftfactor;
|
||||
} __attribute__((packed)) eq_coeff_1;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[2];
|
||||
eq_denominator denominator[2];
|
||||
eq_shiftfactor shiftfactor[2];
|
||||
} __attribute__((packed)) eq_coeff_2;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[3];
|
||||
eq_denominator denominator[3];
|
||||
eq_shiftfactor shiftfactor[3];
|
||||
} __attribute__((packed)) eq_coeff_3;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[4];
|
||||
eq_denominator denominator[4];
|
||||
eq_shiftfactor shiftfactor[4];
|
||||
} __attribute__((packed)) eq_coeff_4;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[5];
|
||||
eq_denominator denominator[5];
|
||||
eq_shiftfactor shiftfactor[5];
|
||||
} __attribute__((packed)) eq_coeff_5;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[6];
|
||||
eq_denominator denominator[6];
|
||||
eq_shiftfactor shiftfactor[6];
|
||||
} __attribute__((packed)) eq_coeff_6;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[7];
|
||||
eq_denominator denominator[7];
|
||||
eq_shiftfactor shiftfactor[7];
|
||||
} __attribute__((packed)) eq_coeff_7;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[8];
|
||||
eq_denominator denominator[8];
|
||||
eq_shiftfactor shiftfactor[8];
|
||||
} __attribute__((packed)) eq_coeff_8;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[9];
|
||||
eq_denominator denominator[9];
|
||||
eq_shiftfactor shiftfactor[9];
|
||||
} __attribute__((packed)) eq_coeff_9;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[10];
|
||||
eq_denominator denominator[10];
|
||||
eq_shiftfactor shiftfactor[10];
|
||||
} __attribute__((packed)) eq_coeff_10;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[11];
|
||||
eq_denominator denominator[11];
|
||||
eq_shiftfactor shiftfactor[11];
|
||||
} __attribute__((packed)) eq_coeff_11;
|
||||
|
||||
typedef struct {
|
||||
eq_numerator numerator[12];
|
||||
eq_denominator denominator[12];
|
||||
eq_shiftfactor shiftfactor[12];
|
||||
} __attribute__((packed)) eq_coeff_12;
|
||||
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
unsigned short eq_flag;
|
||||
unsigned short num_bands;
|
||||
union {
|
||||
eq_coeff_1 eq_coeffs_1;
|
||||
eq_coeff_2 eq_coeffs_2;
|
||||
eq_coeff_3 eq_coeffs_3;
|
||||
eq_coeff_4 eq_coeffs_4;
|
||||
eq_coeff_5 eq_coeffs_5;
|
||||
eq_coeff_6 eq_coeffs_6;
|
||||
eq_coeff_7 eq_coeffs_7;
|
||||
eq_coeff_8 eq_coeffs_8;
|
||||
eq_coeff_9 eq_coeffs_9;
|
||||
eq_coeff_10 eq_coeffs_10;
|
||||
eq_coeff_11 eq_coeffs_11;
|
||||
eq_coeff_12 eq_coeffs_12;
|
||||
} __attribute__((packed)) eq_coeff;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
|
||||
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters (ADRC)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_adrc)
|
||||
|
||||
|
||||
#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000
|
||||
#define AUDPP_CMD_ADRC_FLAG_ENA -1
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
signed short adrc_flag;
|
||||
unsigned short compression_th;
|
||||
unsigned short compression_slope;
|
||||
unsigned short rms_time;
|
||||
unsigned short attack_const_lsw;
|
||||
unsigned short attack_const_msw;
|
||||
unsigned short release_const_lsw;
|
||||
unsigned short release_const_msw;
|
||||
unsigned short adrc_system_delay;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters(Spectrum Analizer)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_spectram)
|
||||
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
unsigned short sample_interval;
|
||||
unsigned short num_coeff;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters (QConcert)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_qconcert)
|
||||
|
||||
|
||||
#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1
|
||||
#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000
|
||||
|
||||
#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1
|
||||
#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000
|
||||
#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001
|
||||
#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002
|
||||
|
||||
#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF
|
||||
#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027
|
||||
|
||||
|
||||
#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF
|
||||
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
signed short enable_flag;
|
||||
signed short output_mode;
|
||||
signed short gain;
|
||||
signed short expansion;
|
||||
signed short delay;
|
||||
unsigned short stages_per_mode;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters (Side Chain)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_sidechain)
|
||||
|
||||
|
||||
#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000
|
||||
#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
signed short active_flag;
|
||||
unsigned short num_bands;
|
||||
union {
|
||||
filter_1 filter_1_params;
|
||||
filter_2 filter_2_params;
|
||||
filter_3 filter_3_params;
|
||||
filter_4 filter_4_params;
|
||||
} __attribute__((packed)) params_filter;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
|
||||
|
||||
|
||||
/*
|
||||
* Command Structure to configure post processing parameters (QAFX)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \
|
||||
sizeof(audpp_cmd_cfg_object_params_qafx)
|
||||
|
||||
#define AUDPP_CMD_QAFX_ENA_DISA 0x0000
|
||||
#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1
|
||||
#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001
|
||||
|
||||
#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100
|
||||
#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010
|
||||
#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000
|
||||
|
||||
#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100
|
||||
#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101
|
||||
#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102
|
||||
#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103
|
||||
#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107
|
||||
|
||||
#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010
|
||||
#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011
|
||||
#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012
|
||||
#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013
|
||||
#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014
|
||||
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
signed short enable;
|
||||
unsigned short command_type;
|
||||
unsigned short num_commands;
|
||||
unsigned short commands;
|
||||
} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
|
||||
|
||||
/*
|
||||
* Command Structure to enable , disable or configure the reverberation effect
|
||||
* (Common)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_REVERB_CONFIG 0x0001
|
||||
#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \
|
||||
sizeof(audpp_cmd_reverb_config_common)
|
||||
|
||||
#define AUDPP_CMD_ENA_ENA 0xFFFF
|
||||
#define AUDPP_CMD_ENA_DIS 0x0000
|
||||
#define AUDPP_CMD_ENA_CFG 0x0001
|
||||
|
||||
#define AUDPP_CMD_CMD_TYPE_ENV 0x0104
|
||||
#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015
|
||||
#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short enable;
|
||||
unsigned short cmd_type;
|
||||
} __attribute__((packed)) audpp_cmd_reverb_config_common;
|
||||
|
||||
/*
|
||||
* Command Structure to enable , disable or configure the reverberation effect
|
||||
* (ENV-0x0104)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \
|
||||
sizeof(audpp_cmd_reverb_config_env_104)
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_reverb_config_common common;
|
||||
unsigned short env_gain;
|
||||
unsigned short decay_msw;
|
||||
unsigned short decay_lsw;
|
||||
unsigned short decay_timeratio_msw;
|
||||
unsigned short decay_timeratio_lsw;
|
||||
unsigned short delay_time;
|
||||
unsigned short reverb_gain;
|
||||
unsigned short reverb_delay;
|
||||
} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
|
||||
|
||||
/*
|
||||
* Command Structure to enable , disable or configure the reverberation effect
|
||||
* (ENV-0x0015)
|
||||
*/
|
||||
|
||||
#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \
|
||||
sizeof(audpp_cmd_reverb_config_env_15)
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_reverb_config_common common;
|
||||
unsigned short object_num;
|
||||
unsigned short absolute_gain;
|
||||
} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
|
||||
|
||||
|
||||
#endif /* QDSP5AUDPPCMDI_H */
|
||||
|
|
@ -1,318 +0,0 @@
|
|||
#ifndef QDSP5AUDPPMSG_H
|
||||
#define QDSP5AUDPPMSG_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
Messages sent by AUDPPTASK to ARM
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* AUDPPTASK uses audPPuPRlist to send messages to the ARM
|
||||
* Location : MEMA
|
||||
* Buffer Size : 45
|
||||
* No of Buffers in a queue : 5 for gaming audio and 1 for other images
|
||||
*/
|
||||
|
||||
/*
|
||||
* MSG to Informs the ARM os Success/Failure of bringing up the decoder
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_STATUS_MSG 0x0001
|
||||
#define AUDPP_MSG_STATUS_MSG_LEN \
|
||||
sizeof(audpp_msg_status_msg)
|
||||
|
||||
#define AUDPP_MSG_STATUS_SLEEP 0x0000
|
||||
#define AUDPP_MSG__STATUS_INIT 0x0001
|
||||
#define AUDPP_MSG_MSG_STATUS_CFG 0x0002
|
||||
#define AUDPP_MSG_STATUS_PLAY 0x0003
|
||||
|
||||
#define AUDPP_MSG_REASON_MIPS 0x0000
|
||||
#define AUDPP_MSG_REASON_MEM 0x0001
|
||||
|
||||
typedef struct{
|
||||
unsigned short dec_id;
|
||||
unsigned short status;
|
||||
unsigned short reason;
|
||||
} __attribute__((packed)) audpp_msg_status_msg;
|
||||
|
||||
/*
|
||||
* MSG to communicate the spectrum analyzer output bands to the ARM
|
||||
*/
|
||||
#define AUDPP_MSG_SPA_BANDS 0x0002
|
||||
#define AUDPP_MSG_SPA_BANDS_LEN \
|
||||
sizeof(audpp_msg_spa_bands)
|
||||
|
||||
typedef struct {
|
||||
unsigned short current_object;
|
||||
unsigned short spa_band_1;
|
||||
unsigned short spa_band_2;
|
||||
unsigned short spa_band_3;
|
||||
unsigned short spa_band_4;
|
||||
unsigned short spa_band_5;
|
||||
unsigned short spa_band_6;
|
||||
unsigned short spa_band_7;
|
||||
unsigned short spa_band_8;
|
||||
unsigned short spa_band_9;
|
||||
unsigned short spa_band_10;
|
||||
unsigned short spa_band_11;
|
||||
unsigned short spa_band_12;
|
||||
unsigned short spa_band_13;
|
||||
unsigned short spa_band_14;
|
||||
unsigned short spa_band_15;
|
||||
unsigned short spa_band_16;
|
||||
unsigned short spa_band_17;
|
||||
unsigned short spa_band_18;
|
||||
unsigned short spa_band_19;
|
||||
unsigned short spa_band_20;
|
||||
unsigned short spa_band_21;
|
||||
unsigned short spa_band_22;
|
||||
unsigned short spa_band_23;
|
||||
unsigned short spa_band_24;
|
||||
unsigned short spa_band_25;
|
||||
unsigned short spa_band_26;
|
||||
unsigned short spa_band_27;
|
||||
unsigned short spa_band_28;
|
||||
unsigned short spa_band_29;
|
||||
unsigned short spa_band_30;
|
||||
unsigned short spa_band_31;
|
||||
unsigned short spa_band_32;
|
||||
} __attribute__((packed)) audpp_msg_spa_bands;
|
||||
|
||||
/*
|
||||
* MSG to communicate the PCM I/O buffer status to ARM
|
||||
*/
|
||||
#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003
|
||||
#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \
|
||||
sizeof(audpp_msg_host_pcm_intf_msg)
|
||||
|
||||
#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000
|
||||
#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001
|
||||
#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002
|
||||
#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003
|
||||
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A
|
||||
#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B
|
||||
|
||||
#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001
|
||||
#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002
|
||||
|
||||
typedef struct{
|
||||
unsigned short obj_num;
|
||||
unsigned short numbers_of_samples;
|
||||
unsigned short host_pcm_id;
|
||||
unsigned short buf_indx;
|
||||
unsigned short samp_freq_indx;
|
||||
unsigned short channel_mode;
|
||||
} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
|
||||
|
||||
|
||||
/*
|
||||
* MSG to communicate 3D position of the source and listener , source volume
|
||||
* source rolloff, source orientation
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_QAFX_POS 0x0004
|
||||
#define AUDPP_MSG_QAFX_POS_LEN \
|
||||
sizeof(audpp_msg_qafx_pos)
|
||||
|
||||
typedef struct {
|
||||
unsigned short current_object;
|
||||
unsigned short x_pos_lis_msw;
|
||||
unsigned short x_pos_lis_lsw;
|
||||
unsigned short y_pos_lis_msw;
|
||||
unsigned short y_pos_lis_lsw;
|
||||
unsigned short z_pos_lis_msw;
|
||||
unsigned short z_pos_lis_lsw;
|
||||
unsigned short x_fwd_msw;
|
||||
unsigned short x_fwd_lsw;
|
||||
unsigned short y_fwd_msw;
|
||||
unsigned short y_fwd_lsw;
|
||||
unsigned short z_fwd_msw;
|
||||
unsigned short z_fwd_lsw;
|
||||
unsigned short x_up_msw;
|
||||
unsigned short x_up_lsw;
|
||||
unsigned short y_up_msw;
|
||||
unsigned short y_up_lsw;
|
||||
unsigned short z_up_msw;
|
||||
unsigned short z_up_lsw;
|
||||
unsigned short x_vel_lis_msw;
|
||||
unsigned short x_vel_lis_lsw;
|
||||
unsigned short y_vel_lis_msw;
|
||||
unsigned short y_vel_lis_lsw;
|
||||
unsigned short z_vel_lis_msw;
|
||||
unsigned short z_vel_lis_lsw;
|
||||
unsigned short threed_enable_flag;
|
||||
unsigned short volume;
|
||||
unsigned short x_pos_source_msw;
|
||||
unsigned short x_pos_source_lsw;
|
||||
unsigned short y_pos_source_msw;
|
||||
unsigned short y_pos_source_lsw;
|
||||
unsigned short z_pos_source_msw;
|
||||
unsigned short z_pos_source_lsw;
|
||||
unsigned short max_dist_0_msw;
|
||||
unsigned short max_dist_0_lsw;
|
||||
unsigned short min_dist_0_msw;
|
||||
unsigned short min_dist_0_lsw;
|
||||
unsigned short roll_off_factor;
|
||||
unsigned short mute_after_max_flag;
|
||||
unsigned short x_vel_source_msw;
|
||||
unsigned short x_vel_source_lsw;
|
||||
unsigned short y_vel_source_msw;
|
||||
unsigned short y_vel_source_lsw;
|
||||
unsigned short z_vel_source_msw;
|
||||
unsigned short z_vel_source_lsw;
|
||||
} __attribute__((packed)) audpp_msg_qafx_pos;
|
||||
|
||||
/*
|
||||
* MSG to provide AVSYNC feedback from DSP to ARM
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_AVSYNC_MSG 0x0005
|
||||
#define AUDPP_MSG_AVSYNC_MSG_LEN \
|
||||
sizeof(audpp_msg_avsync_msg)
|
||||
|
||||
typedef struct {
|
||||
unsigned short active_flag;
|
||||
unsigned short num_samples_counter0_HSW;
|
||||
unsigned short num_samples_counter0_MSW;
|
||||
unsigned short num_samples_counter0_LSW;
|
||||
unsigned short num_bytes_counter0_HSW;
|
||||
unsigned short num_bytes_counter0_MSW;
|
||||
unsigned short num_bytes_counter0_LSW;
|
||||
unsigned short samp_freq_obj_0;
|
||||
unsigned short samp_freq_obj_1;
|
||||
unsigned short samp_freq_obj_2;
|
||||
unsigned short samp_freq_obj_3;
|
||||
unsigned short samp_freq_obj_4;
|
||||
unsigned short samp_freq_obj_5;
|
||||
unsigned short samp_freq_obj_6;
|
||||
unsigned short samp_freq_obj_7;
|
||||
unsigned short samp_freq_obj_8;
|
||||
unsigned short samp_freq_obj_9;
|
||||
unsigned short samp_freq_obj_10;
|
||||
unsigned short samp_freq_obj_11;
|
||||
unsigned short samp_freq_obj_12;
|
||||
unsigned short samp_freq_obj_13;
|
||||
unsigned short samp_freq_obj_14;
|
||||
unsigned short samp_freq_obj_15;
|
||||
unsigned short num_samples_counter4_HSW;
|
||||
unsigned short num_samples_counter4_MSW;
|
||||
unsigned short num_samples_counter4_LSW;
|
||||
unsigned short num_bytes_counter4_HSW;
|
||||
unsigned short num_bytes_counter4_MSW;
|
||||
unsigned short num_bytes_counter4_LSW;
|
||||
} __attribute__((packed)) audpp_msg_avsync_msg;
|
||||
|
||||
/*
|
||||
* MSG to provide PCM DMA Missed feedback from the DSP to ARM
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_PCMDMAMISSED 0x0006
|
||||
#define AUDPP_MSG_PCMDMAMISSED_LEN \
|
||||
sizeof(audpp_msg_pcmdmamissed);
|
||||
|
||||
typedef struct{
|
||||
/*
|
||||
** Bit 0 0 = PCM DMA not missed for object 0
|
||||
** 1 = PCM DMA missed for object0
|
||||
** Bit 1 0 = PCM DMA not missed for object 1
|
||||
** 1 = PCM DMA missed for object1
|
||||
** Bit 2 0 = PCM DMA not missed for object 2
|
||||
** 1 = PCM DMA missed for object2
|
||||
** Bit 3 0 = PCM DMA not missed for object 3
|
||||
** 1 = PCM DMA missed for object3
|
||||
** Bit 4 0 = PCM DMA not missed for object 4
|
||||
** 1 = PCM DMA missed for object4
|
||||
*/
|
||||
unsigned short pcmdmamissed;
|
||||
} __attribute__((packed)) audpp_msg_pcmdmamissed;
|
||||
|
||||
/*
|
||||
* MSG to AUDPP enable or disable feedback form DSP to ARM
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_CFG_MSG 0x0007
|
||||
#define AUDPP_MSG_CFG_MSG_LEN \
|
||||
sizeof(audpp_msg_cfg_msg)
|
||||
|
||||
#define AUDPP_MSG_ENA_ENA 0xFFFF
|
||||
#define AUDPP_MSG_ENA_DIS 0x0000
|
||||
|
||||
typedef struct{
|
||||
/* Enabled - 0xffff
|
||||
** Disabled - 0
|
||||
*/
|
||||
unsigned short enabled;
|
||||
} __attribute__((packed)) audpp_msg_cfg_msg;
|
||||
|
||||
/*
|
||||
* MSG to communicate the reverb per object volume
|
||||
*/
|
||||
|
||||
#define AUDPP_MSG_QREVERB_VOLUME 0x0008
|
||||
#define AUDPP_MSG_QREVERB_VOLUME_LEN \
|
||||
sizeof(audpp_msg_qreverb_volume)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short obj_0_gain;
|
||||
unsigned short obj_1_gain;
|
||||
unsigned short obj_2_gain;
|
||||
unsigned short obj_3_gain;
|
||||
unsigned short obj_4_gain;
|
||||
unsigned short hpcm_obj_volume;
|
||||
} __attribute__((packed)) audpp_msg_qreverb_volume;
|
||||
|
||||
#define AUDPP_MSG_ROUTING_ACK 0x0009
|
||||
#define AUDPP_MSG_ROUTING_ACK_LEN \
|
||||
sizeof(struct audpp_msg_routing_ack)
|
||||
|
||||
struct audpp_msg_routing_ack {
|
||||
unsigned short dec_id;
|
||||
unsigned short routing_mode;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define AUDPP_MSG_FLUSH_ACK 0x000A
|
||||
|
||||
#endif /* QDSP5AUDPPMSG_H */
|
|
@ -1,256 +0,0 @@
|
|||
#ifndef QDSP5AUDPREPROCCMDI_H
|
||||
#define QDSP5AUDPREPROCCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by AUDPREPROC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* AUDIOPREPROC COMMANDS:
|
||||
* ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
|
||||
* Location : MEMB
|
||||
* Buffer size : 51
|
||||
* Number of buffers in a queue : 3
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command to configure the parameters of AGC
|
||||
*/
|
||||
|
||||
#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000
|
||||
#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \
|
||||
sizeof(audpreproc_cmd_cfg_agc_params)
|
||||
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E
|
||||
#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F
|
||||
|
||||
#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1
|
||||
#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000
|
||||
|
||||
#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1
|
||||
#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000
|
||||
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E
|
||||
#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short tx_agc_param_mask;
|
||||
unsigned short tx_agc_enable_flag;
|
||||
unsigned short static_gain;
|
||||
signed short adaptive_gain_flag;
|
||||
unsigned short expander_th;
|
||||
unsigned short expander_slope;
|
||||
unsigned short compressor_th;
|
||||
unsigned short compressor_slope;
|
||||
unsigned short param_mask;
|
||||
unsigned short aig_attackk;
|
||||
unsigned short aig_leak_down;
|
||||
unsigned short aig_leak_up;
|
||||
unsigned short aig_max;
|
||||
unsigned short aig_min;
|
||||
unsigned short aig_releasek;
|
||||
unsigned short aig_leakrate_fast;
|
||||
unsigned short aig_leakrate_slow;
|
||||
unsigned short attackk_msw;
|
||||
unsigned short attackk_lsw;
|
||||
unsigned short delay;
|
||||
unsigned short releasek_msw;
|
||||
unsigned short releasek_lsw;
|
||||
unsigned short rms_tav;
|
||||
} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure the params of Advanved AGC
|
||||
*/
|
||||
|
||||
#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001
|
||||
#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \
|
||||
sizeof(audpreproc_cmd_cfg_agc_params_2)
|
||||
|
||||
#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1;
|
||||
#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000;
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short agc_param_mask;
|
||||
signed short tx_agc_enable_flag;
|
||||
unsigned short comp_static_gain;
|
||||
unsigned short exp_th;
|
||||
unsigned short exp_slope;
|
||||
unsigned short comp_th;
|
||||
unsigned short comp_slope;
|
||||
unsigned short comp_rms_tav;
|
||||
unsigned short comp_samp_mask;
|
||||
unsigned short comp_attackk_msw;
|
||||
unsigned short comp_attackk_lsw;
|
||||
unsigned short comp_releasek_msw;
|
||||
unsigned short comp_releasek_lsw;
|
||||
unsigned short comp_delay;
|
||||
unsigned short comp_makeup_gain;
|
||||
} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
|
||||
|
||||
/*
|
||||
* Command to configure params for ns
|
||||
*/
|
||||
|
||||
#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002
|
||||
#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \
|
||||
sizeof(audpreproc_cmd_cfg_ns_params)
|
||||
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000
|
||||
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000
|
||||
#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short ec_mode_new;
|
||||
unsigned short dens_gamma_n;
|
||||
unsigned short dens_nfe_block_size;
|
||||
unsigned short dens_limit_ns;
|
||||
unsigned short dens_limit_ns_d;
|
||||
unsigned short wb_gamma_e;
|
||||
unsigned short wb_gamma_n;
|
||||
} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
|
||||
|
||||
/*
|
||||
* Command to configure parameters for IIR tuning filter
|
||||
*/
|
||||
|
||||
#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003
|
||||
#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \
|
||||
sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
|
||||
|
||||
#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000
|
||||
#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short active_flag;
|
||||
unsigned short num_bands;
|
||||
unsigned short numerator_coeff_b0_filter0_lsw;
|
||||
unsigned short numerator_coeff_b0_filter0_msw;
|
||||
unsigned short numerator_coeff_b1_filter0_lsw;
|
||||
unsigned short numerator_coeff_b1_filter0_msw;
|
||||
unsigned short numerator_coeff_b2_filter0_lsw;
|
||||
unsigned short numerator_coeff_b2_filter0_msw;
|
||||
unsigned short numerator_coeff_b0_filter1_lsw;
|
||||
unsigned short numerator_coeff_b0_filter1_msw;
|
||||
unsigned short numerator_coeff_b1_filter1_lsw;
|
||||
unsigned short numerator_coeff_b1_filter1_msw;
|
||||
unsigned short numerator_coeff_b2_filter1_lsw;
|
||||
unsigned short numerator_coeff_b2_filter1_msw;
|
||||
unsigned short numerator_coeff_b0_filter2_lsw;
|
||||
unsigned short numerator_coeff_b0_filter2_msw;
|
||||
unsigned short numerator_coeff_b1_filter2_lsw;
|
||||
unsigned short numerator_coeff_b1_filter2_msw;
|
||||
unsigned short numerator_coeff_b2_filter2_lsw;
|
||||
unsigned short numerator_coeff_b2_filter2_msw;
|
||||
unsigned short numerator_coeff_b0_filter3_lsw;
|
||||
unsigned short numerator_coeff_b0_filter3_msw;
|
||||
unsigned short numerator_coeff_b1_filter3_lsw;
|
||||
unsigned short numerator_coeff_b1_filter3_msw;
|
||||
unsigned short numerator_coeff_b2_filter3_lsw;
|
||||
unsigned short numerator_coeff_b2_filter3_msw;
|
||||
unsigned short denominator_coeff_a0_filter0_lsw;
|
||||
unsigned short denominator_coeff_a0_filter0_msw;
|
||||
unsigned short denominator_coeff_a1_filter0_lsw;
|
||||
unsigned short denominator_coeff_a1_filter0_msw;
|
||||
unsigned short denominator_coeff_a0_filter1_lsw;
|
||||
unsigned short denominator_coeff_a0_filter1_msw;
|
||||
unsigned short denominator_coeff_a1_filter1_lsw;
|
||||
unsigned short denominator_coeff_a1_filter1_msw;
|
||||
unsigned short denominator_coeff_a0_filter2_lsw;
|
||||
unsigned short denominator_coeff_a0_filter2_msw;
|
||||
unsigned short denominator_coeff_a1_filter2_lsw;
|
||||
unsigned short denominator_coeff_a1_filter2_msw;
|
||||
unsigned short denominator_coeff_a0_filter3_lsw;
|
||||
unsigned short denominator_coeff_a0_filter3_msw;
|
||||
unsigned short denominator_coeff_a1_filter3_lsw;
|
||||
unsigned short denominator_coeff_a1_filter3_msw;
|
||||
|
||||
unsigned short shift_factor_filter0;
|
||||
unsigned short shift_factor_filter1;
|
||||
unsigned short shift_factor_filter2;
|
||||
unsigned short shift_factor_filter3;
|
||||
|
||||
unsigned short channel_selected0;
|
||||
unsigned short channel_selected1;
|
||||
unsigned short channel_selected2;
|
||||
unsigned short channel_selected3;
|
||||
} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
|
||||
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
#ifndef QDSP5AUDPREPROCMSG_H
|
||||
#define QDSP5AUDPREPROCMSG_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
A U D I O P R E P R O C E S S I N G M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of messages
|
||||
that are rcvd by AUDPREPROC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* ADSPREPROCTASK Messages
|
||||
* AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
|
||||
* Location : MEMA
|
||||
* Message Length : 2
|
||||
*/
|
||||
|
||||
/*
|
||||
* Message to indicate particular feature has been enabled or disabled
|
||||
*/
|
||||
|
||||
|
||||
#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000
|
||||
#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \
|
||||
sizeof(audpreproc_msg_cmd_cfg_done_msg)
|
||||
|
||||
#define AUDPREPROC_MSG_TYPE_AGC 0x0000
|
||||
#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001
|
||||
#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002
|
||||
|
||||
|
||||
#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1
|
||||
#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000
|
||||
|
||||
typedef struct {
|
||||
unsigned short type;
|
||||
signed short status_flag;
|
||||
} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
|
||||
|
||||
|
||||
/*
|
||||
* Message to indicate particular feature has selected for wrong samp freq
|
||||
*/
|
||||
|
||||
#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001
|
||||
#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \
|
||||
sizeof(audpreproc_msg_error_msg_id)
|
||||
|
||||
#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000
|
||||
|
||||
typedef struct {
|
||||
unsigned short err_index;
|
||||
} __attribute__((packed)) audpreproc_msg_error_msg_id;
|
||||
|
||||
#endif
|
|
@ -1,176 +0,0 @@
|
|||
#ifndef QDSP5AUDRECCMDI_H
|
||||
#define QDSP5AUDRECCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
A U D I O R E C O R D I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by AUDREC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*
|
||||
* AUDRECTASK COMMANDS
|
||||
* ARM uses 2 queues to communicate with the AUDRECTASK
|
||||
* 1.uPAudRecCmdQueue
|
||||
* Location :MEMC
|
||||
* Buffer Size : 8
|
||||
* No of Buffers in a queue : 3
|
||||
* 2.audRecUpBitStreamQueue
|
||||
* Location : MEMC
|
||||
* Buffer Size : 4
|
||||
* No of buffers in a queue : 2
|
||||
*/
|
||||
|
||||
/*
|
||||
* Commands on uPAudRecCmdQueue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command to initiate and terminate the audio recording section
|
||||
*/
|
||||
|
||||
#define AUDREC_CMD_CFG 0x0000
|
||||
#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg)
|
||||
|
||||
#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000
|
||||
#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001
|
||||
|
||||
#define AUDREC_CMD_TYPE_0_ENA 0x4000
|
||||
#define AUDREC_CMD_TYPE_0_DIS 0x0000
|
||||
|
||||
#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000
|
||||
#define AUDREC_CMD_TYPE_0_UPDATE 0x8000
|
||||
|
||||
#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002
|
||||
|
||||
#define AUDREC_CMD_TYPE_1_ENA 0x4000
|
||||
#define AUDREC_CMD_TYPE_1_DIS 0x0000
|
||||
|
||||
#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000
|
||||
#define AUDREC_CMD_TYPE_1_UPDATE 0x8000
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short type_0;
|
||||
unsigned short type_1;
|
||||
} __attribute__((packed)) audrec_cmd_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure the recording parameters for RecType0(AAC/WAV) encoder
|
||||
*/
|
||||
|
||||
#define AUDREC_CMD_AREC0PARAM_CFG 0x0001
|
||||
#define AUDREC_CMD_AREC0PARAM_CFG_LEN \
|
||||
sizeof(audrec_cmd_arec0param_cfg)
|
||||
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004
|
||||
#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003
|
||||
|
||||
#define AUDREC_CMD_STEREO_MODE_MONO 0x0000
|
||||
#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short ptr_to_extpkt_buffer_msw;
|
||||
unsigned short ptr_to_extpkt_buffer_lsw;
|
||||
unsigned short buf_len;
|
||||
unsigned short samp_rate_index;
|
||||
unsigned short stereo_mode;
|
||||
unsigned short rec_quality;
|
||||
} __attribute__((packed)) audrec_cmd_arec0param_cfg;
|
||||
|
||||
/*
|
||||
* Command to configure the recording parameters for RecType1(SBC) encoder
|
||||
*/
|
||||
|
||||
#define AUDREC_CMD_AREC1PARAM_CFG 0x0002
|
||||
#define AUDREC_CMD_AREC1PARAM_CFG_LEN \
|
||||
sizeof(audrec_cmd_arec1param_cfg)
|
||||
|
||||
#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000
|
||||
#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001
|
||||
#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002
|
||||
#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003
|
||||
|
||||
#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010
|
||||
#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000
|
||||
#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040
|
||||
#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050
|
||||
#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060
|
||||
#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000
|
||||
#define AUDREC_CMD_PARAM_BUF_SNR 0x0100
|
||||
#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short ptr_to_extpkt_buffer_msw;
|
||||
unsigned short ptr_to_extpkt_buffer_lsw;
|
||||
unsigned short buf_len;
|
||||
unsigned short param_buf;
|
||||
unsigned short bit_rate_0;
|
||||
unsigned short bit_rate_1;
|
||||
} __attribute__((packed)) audrec_cmd_arec1param_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Commands on audRecUpBitStreamQueue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command to indicate the current packet read count
|
||||
*/
|
||||
|
||||
#define AUDREC_CMD_PACKET_EXT_PTR 0x0000
|
||||
#define AUDREC_CMD_PACKET_EXT_PTR_LEN \
|
||||
sizeof(audrec_cmd_packet_ext_ptr)
|
||||
|
||||
#define AUDREC_CMD_TYPE_0 0x0000
|
||||
#define AUDREC_CMD_TYPE_1 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short type;
|
||||
unsigned short curr_rec_count_msw;
|
||||
unsigned short curr_rec_count_lsw;
|
||||
} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
|
||||
|
||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||
#ifndef QDSP5AUDRECMSGI_H
|
||||
#define QDSP5AUDRECMSGI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
A U D I O R E C O R D M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of messages
|
||||
that are sent by AUDREC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*
|
||||
* AUDRECTASK MESSAGES
|
||||
* AUDRECTASK uses audRecUpRlist to communicate with ARM
|
||||
* Location : MEMC
|
||||
* Buffer size : 4
|
||||
* No of buffers in a queue : 2
|
||||
*/
|
||||
|
||||
/*
|
||||
* Message to notify that config command is done
|
||||
*/
|
||||
|
||||
#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002
|
||||
#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \
|
||||
sizeof(audrec_msg_cmd_cfg_done_msg)
|
||||
|
||||
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000
|
||||
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000
|
||||
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000
|
||||
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000
|
||||
#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000
|
||||
|
||||
typedef struct {
|
||||
unsigned short type_0;
|
||||
unsigned short type_1;
|
||||
} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify arec0/1 cfg done and recording params revd by task
|
||||
*/
|
||||
|
||||
#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003
|
||||
#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \
|
||||
sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
|
||||
|
||||
#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000
|
||||
#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short type;
|
||||
} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify no more buffers are available in ext mem to DME
|
||||
*/
|
||||
|
||||
#define AUDREC_MSG_FATAL_ERR_MSG 0x0004
|
||||
#define AUDREC_MSG_FATAL_ERR_MSG_LEN \
|
||||
sizeof(audrec_msg_fatal_err_msg)
|
||||
|
||||
#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000
|
||||
#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short type;
|
||||
} __attribute__((packed))audrec_msg_fatal_err_msg;
|
||||
|
||||
/*
|
||||
* Message to notify DME deliverd the encoded pkt to ext pkt buffer
|
||||
*/
|
||||
|
||||
#define AUDREC_MSG_PACKET_READY_MSG 0x0005
|
||||
#define AUDREC_MSG_PACKET_READY_MSG_LEN \
|
||||
sizeof(audrec_msg_packet_ready_msg)
|
||||
|
||||
#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000
|
||||
#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short type;
|
||||
unsigned short pkt_counter_msw;
|
||||
unsigned short pkt_counter_lsw;
|
||||
unsigned short pkt_read_cnt_msw;
|
||||
unsigned short pkt_read_cnt_lsw;
|
||||
} __attribute__((packed))audrec_msg_packet_ready_msg;
|
||||
|
||||
#endif
|
|
@ -1,376 +0,0 @@
|
|||
#ifndef QDSP5VIDJPEGCMDI_H
|
||||
#define QDSP5VIDJPEGCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
J P E G I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by JPEG Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
06/09/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* ARM to JPEG configuration commands are passed through the
|
||||
* uPJpegCfgCmdQueue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command to configure JPEG Encoder
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_ENC_CFG 0x0000
|
||||
#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg)
|
||||
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001
|
||||
#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002
|
||||
|
||||
#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF
|
||||
#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000
|
||||
#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001
|
||||
#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000
|
||||
|
||||
#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int process_cfg;
|
||||
unsigned int ip_size_cfg;
|
||||
unsigned int op_size_cfg;
|
||||
unsigned int frag_cfg;
|
||||
unsigned int frag_cfg_part[16];
|
||||
|
||||
unsigned int part_num;
|
||||
|
||||
unsigned int op_buf_0_cfg_part1;
|
||||
unsigned int op_buf_0_cfg_part2;
|
||||
unsigned int op_buf_1_cfg_part1;
|
||||
unsigned int op_buf_1_cfg_part2;
|
||||
|
||||
unsigned int luma_qunt_table[32];
|
||||
unsigned int chroma_qunt_table[32];
|
||||
|
||||
unsigned int upsamp_ip_size_cfg;
|
||||
unsigned int upsamp_ip_frame_off;
|
||||
unsigned int upsamp_pp_filter_coeff[64];
|
||||
} __attribute__((packed)) jpeg_cmd_enc_cfg;
|
||||
|
||||
/*
|
||||
* Command to configure JPEG Decoder
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_DEC_CFG 0x0001
|
||||
#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg)
|
||||
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001
|
||||
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000
|
||||
#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000
|
||||
|
||||
#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000
|
||||
#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int img_dimension_cfg;
|
||||
unsigned int op_data_format;
|
||||
unsigned int restart_interval;
|
||||
unsigned int ip_buf_partition_num;
|
||||
unsigned int ip_stream_buf_cfg_part1;
|
||||
unsigned int ip_stream_buf_cfg_part2;
|
||||
unsigned int ip_stream_buf_cfg_part3;
|
||||
unsigned int op_stream_buf_0_cfg_part1;
|
||||
unsigned int op_stream_buf_0_cfg_part2;
|
||||
unsigned int op_stream_buf_0_cfg_part3;
|
||||
unsigned int op_stream_buf_1_cfg_part1;
|
||||
unsigned int op_stream_buf_1_cfg_part2;
|
||||
unsigned int op_stream_buf_1_cfg_part3;
|
||||
unsigned int luma_qunt_table_0_3;
|
||||
unsigned int luma_qunt_table_4_7;
|
||||
unsigned int luma_qunt_table_8_11;
|
||||
unsigned int luma_qunt_table_12_15;
|
||||
unsigned int luma_qunt_table_16_19;
|
||||
unsigned int luma_qunt_table_20_23;
|
||||
unsigned int luma_qunt_table_24_27;
|
||||
unsigned int luma_qunt_table_28_31;
|
||||
unsigned int luma_qunt_table_32_35;
|
||||
unsigned int luma_qunt_table_36_39;
|
||||
unsigned int luma_qunt_table_40_43;
|
||||
unsigned int luma_qunt_table_44_47;
|
||||
unsigned int luma_qunt_table_48_51;
|
||||
unsigned int luma_qunt_table_52_55;
|
||||
unsigned int luma_qunt_table_56_59;
|
||||
unsigned int luma_qunt_table_60_63;
|
||||
unsigned int chroma_qunt_table_0_3;
|
||||
unsigned int chroma_qunt_table_4_7;
|
||||
unsigned int chroma_qunt_table_8_11;
|
||||
unsigned int chroma_qunt_table_12_15;
|
||||
unsigned int chroma_qunt_table_16_19;
|
||||
unsigned int chroma_qunt_table_20_23;
|
||||
unsigned int chroma_qunt_table_24_27;
|
||||
unsigned int chroma_qunt_table_28_31;
|
||||
unsigned int chroma_qunt_table_32_35;
|
||||
unsigned int chroma_qunt_table_36_39;
|
||||
unsigned int chroma_qunt_table_40_43;
|
||||
unsigned int chroma_qunt_table_44_47;
|
||||
unsigned int chroma_qunt_table_48_51;
|
||||
unsigned int chroma_qunt_table_52_55;
|
||||
unsigned int chroma_qunt_table_56_59;
|
||||
unsigned int chroma_qunt_table_60_63;
|
||||
unsigned int luma_dc_hm_code_cnt_table_0_3;
|
||||
unsigned int luma_dc_hm_code_cnt_table_4_7;
|
||||
unsigned int luma_dc_hm_code_cnt_table_8_11;
|
||||
unsigned int luma_dc_hm_code_cnt_table_12_15;
|
||||
unsigned int luma_dc_hm_code_val_table_0_3;
|
||||
unsigned int luma_dc_hm_code_val_table_4_7;
|
||||
unsigned int luma_dc_hm_code_val_table_8_11;
|
||||
unsigned int chroma_dc_hm_code_cnt_table_0_3;
|
||||
unsigned int chroma_dc_hm_code_cnt_table_4_7;
|
||||
unsigned int chroma_dc_hm_code_cnt_table_8_11;
|
||||
unsigned int chroma_dc_hm_code_cnt_table_12_15;
|
||||
unsigned int chroma_dc_hm_code_val_table_0_3;
|
||||
unsigned int chroma_dc_hm_code_val_table_4_7;
|
||||
unsigned int chroma_dc_hm_code_val_table_8_11;
|
||||
unsigned int luma_ac_hm_code_cnt_table_0_3;
|
||||
unsigned int luma_ac_hm_code_cnt_table_4_7;
|
||||
unsigned int luma_ac_hm_code_cnt_table_8_11;
|
||||
unsigned int luma_ac_hm_code_cnt_table_12_15;
|
||||
unsigned int luma_ac_hm_code_val_table_0_3;
|
||||
unsigned int luma_ac_hm_code_val_table_4_7;
|
||||
unsigned int luma_ac_hm_code_val_table_8_11;
|
||||
unsigned int luma_ac_hm_code_val_table_12_15;
|
||||
unsigned int luma_ac_hm_code_val_table_16_19;
|
||||
unsigned int luma_ac_hm_code_val_table_20_23;
|
||||
unsigned int luma_ac_hm_code_val_table_24_27;
|
||||
unsigned int luma_ac_hm_code_val_table_28_31;
|
||||
unsigned int luma_ac_hm_code_val_table_32_35;
|
||||
unsigned int luma_ac_hm_code_val_table_36_39;
|
||||
unsigned int luma_ac_hm_code_val_table_40_43;
|
||||
unsigned int luma_ac_hm_code_val_table_44_47;
|
||||
unsigned int luma_ac_hm_code_val_table_48_51;
|
||||
unsigned int luma_ac_hm_code_val_table_52_55;
|
||||
unsigned int luma_ac_hm_code_val_table_56_59;
|
||||
unsigned int luma_ac_hm_code_val_table_60_63;
|
||||
unsigned int luma_ac_hm_code_val_table_64_67;
|
||||
unsigned int luma_ac_hm_code_val_table_68_71;
|
||||
unsigned int luma_ac_hm_code_val_table_72_75;
|
||||
unsigned int luma_ac_hm_code_val_table_76_79;
|
||||
unsigned int luma_ac_hm_code_val_table_80_83;
|
||||
unsigned int luma_ac_hm_code_val_table_84_87;
|
||||
unsigned int luma_ac_hm_code_val_table_88_91;
|
||||
unsigned int luma_ac_hm_code_val_table_92_95;
|
||||
unsigned int luma_ac_hm_code_val_table_96_99;
|
||||
unsigned int luma_ac_hm_code_val_table_100_103;
|
||||
unsigned int luma_ac_hm_code_val_table_104_107;
|
||||
unsigned int luma_ac_hm_code_val_table_108_111;
|
||||
unsigned int luma_ac_hm_code_val_table_112_115;
|
||||
unsigned int luma_ac_hm_code_val_table_116_119;
|
||||
unsigned int luma_ac_hm_code_val_table_120_123;
|
||||
unsigned int luma_ac_hm_code_val_table_124_127;
|
||||
unsigned int luma_ac_hm_code_val_table_128_131;
|
||||
unsigned int luma_ac_hm_code_val_table_132_135;
|
||||
unsigned int luma_ac_hm_code_val_table_136_139;
|
||||
unsigned int luma_ac_hm_code_val_table_140_143;
|
||||
unsigned int luma_ac_hm_code_val_table_144_147;
|
||||
unsigned int luma_ac_hm_code_val_table_148_151;
|
||||
unsigned int luma_ac_hm_code_val_table_152_155;
|
||||
unsigned int luma_ac_hm_code_val_table_156_159;
|
||||
unsigned int luma_ac_hm_code_val_table_160_161;
|
||||
unsigned int chroma_ac_hm_code_cnt_table_0_3;
|
||||
unsigned int chroma_ac_hm_code_cnt_table_4_7;
|
||||
unsigned int chroma_ac_hm_code_cnt_table_8_11;
|
||||
unsigned int chroma_ac_hm_code_cnt_table_12_15;
|
||||
unsigned int chroma_ac_hm_code_val_table_0_3;
|
||||
unsigned int chroma_ac_hm_code_val_table_4_7;
|
||||
unsigned int chroma_ac_hm_code_val_table_8_11;
|
||||
unsigned int chroma_ac_hm_code_val_table_12_15;
|
||||
unsigned int chroma_ac_hm_code_val_table_16_19;
|
||||
unsigned int chroma_ac_hm_code_val_table_20_23;
|
||||
unsigned int chroma_ac_hm_code_val_table_24_27;
|
||||
unsigned int chroma_ac_hm_code_val_table_28_31;
|
||||
unsigned int chroma_ac_hm_code_val_table_32_35;
|
||||
unsigned int chroma_ac_hm_code_val_table_36_39;
|
||||
unsigned int chroma_ac_hm_code_val_table_40_43;
|
||||
unsigned int chroma_ac_hm_code_val_table_44_47;
|
||||
unsigned int chroma_ac_hm_code_val_table_48_51;
|
||||
unsigned int chroma_ac_hm_code_val_table_52_55;
|
||||
unsigned int chroma_ac_hm_code_val_table_56_59;
|
||||
unsigned int chroma_ac_hm_code_val_table_60_63;
|
||||
unsigned int chroma_ac_hm_code_val_table_64_67;
|
||||
unsigned int chroma_ac_hm_code_val_table_68_71;
|
||||
unsigned int chroma_ac_hm_code_val_table_72_75;
|
||||
unsigned int chroma_ac_hm_code_val_table_76_79;
|
||||
unsigned int chroma_ac_hm_code_val_table_80_83;
|
||||
unsigned int chroma_ac_hm_code_val_table_84_87;
|
||||
unsigned int chroma_ac_hm_code_val_table_88_91;
|
||||
unsigned int chroma_ac_hm_code_val_table_92_95;
|
||||
unsigned int chroma_ac_hm_code_val_table_96_99;
|
||||
unsigned int chroma_ac_hm_code_val_table_100_103;
|
||||
unsigned int chroma_ac_hm_code_val_table_104_107;
|
||||
unsigned int chroma_ac_hm_code_val_table_108_111;
|
||||
unsigned int chroma_ac_hm_code_val_table_112_115;
|
||||
unsigned int chroma_ac_hm_code_val_table_116_119;
|
||||
unsigned int chroma_ac_hm_code_val_table_120_123;
|
||||
unsigned int chroma_ac_hm_code_val_table_124_127;
|
||||
unsigned int chroma_ac_hm_code_val_table_128_131;
|
||||
unsigned int chroma_ac_hm_code_val_table_132_135;
|
||||
unsigned int chroma_ac_hm_code_val_table_136_139;
|
||||
unsigned int chroma_ac_hm_code_val_table_140_143;
|
||||
unsigned int chroma_ac_hm_code_val_table_144_147;
|
||||
unsigned int chroma_ac_hm_code_val_table_148_151;
|
||||
unsigned int chroma_ac_hm_code_val_table_152_155;
|
||||
unsigned int chroma_ac_hm_code_val_table_156_159;
|
||||
unsigned int chroma_ac_hm_code_val_table_160_161;
|
||||
} __attribute__((packed)) jpeg_cmd_dec_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* ARM to JPEG configuration commands are passed through the
|
||||
* uPJpegActionCmdQueue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command to start the encode process
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_ENC_ENCODE 0x0000
|
||||
#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) jpeg_cmd_enc_encode;
|
||||
|
||||
|
||||
/*
|
||||
* Command to transition from current state of encoder to IDLE state
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_ENC_IDLE 0x0001
|
||||
#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) jpeg_cmd_enc_idle;
|
||||
|
||||
|
||||
/*
|
||||
* Command to inform the encoder that another buffer is ready
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_ENC_OP_CONSUMED 0x0002
|
||||
#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int op_buf_addr;
|
||||
unsigned int op_buf_size;
|
||||
} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
|
||||
|
||||
|
||||
/*
|
||||
* Command to start the decoding process
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_DEC_DECODE 0x0003
|
||||
#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) jpeg_cmd_dec_decode;
|
||||
|
||||
|
||||
/*
|
||||
* Command to transition from the current state of decoder to IDLE
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_DEC_IDLE 0x0004
|
||||
#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) jpeg_cmd_dec_idle;
|
||||
|
||||
|
||||
/*
|
||||
* Command to inform that an op buffer is ready for use
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_DEC_OP_CONSUMED 0x0005
|
||||
#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int luma_op_buf_addr;
|
||||
unsigned int luma_op_buf_size;
|
||||
unsigned int chroma_op_buf_addr;
|
||||
} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
|
||||
|
||||
|
||||
/*
|
||||
* Command to pass a new ip buffer to the jpeg decoder
|
||||
*/
|
||||
|
||||
#define JPEG_CMD_DEC_IP 0x0006
|
||||
#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len)
|
||||
|
||||
#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000
|
||||
#define JPEG_CMD_EOI_INDICATOR_END 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int ip_buf_addr;
|
||||
unsigned int ip_buf_size;
|
||||
unsigned int eoi_indicator;
|
||||
} __attribute__((packed)) jpeg_cmd_dec_ip;
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,177 +0,0 @@
|
|||
#ifndef QDSP5VIDJPEGMSGI_H
|
||||
#define QDSP5VIDJPEGMSGI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
J P E G I N T E R N A L M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of messages
|
||||
that are sent by JPEG Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
05/10/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* Messages from JPEG task to ARM through jpeguPMsgQueue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Message is ACK for CMD_JPEGE_ENCODE cmd
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_ENC_ENCODE_ACK 0x0000
|
||||
#define JPEG_MSG_ENC_ENCODE_ACK_LEN \
|
||||
sizeof(jpeg_msg_enc_encode_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) jpeg_msg_enc_encode_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message informs the up when op buffer is ready for consumption and
|
||||
* when encoding is complete or errors
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_ENC_OP_PRODUCED 0x0001
|
||||
#define JPEG_MSG_ENC_OP_PRODUCED_LEN \
|
||||
sizeof(jpeg_msg_enc_op_produced)
|
||||
|
||||
#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000
|
||||
#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001
|
||||
#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000
|
||||
|
||||
typedef struct {
|
||||
unsigned int op_buf_addr;
|
||||
unsigned int op_buf_size;
|
||||
unsigned int op_buf_status;
|
||||
} __attribute__((packed)) jpeg_msg_enc_op_produced;
|
||||
|
||||
|
||||
/*
|
||||
* Message to ack CMD_JPEGE_IDLE
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_ENC_IDLE_ACK 0x0002
|
||||
#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack)
|
||||
|
||||
|
||||
typedef struct {
|
||||
} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to indicate the illegal command
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003
|
||||
#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \
|
||||
sizeof(jpeg_msg_enc_illegal_command)
|
||||
|
||||
typedef struct {
|
||||
unsigned int status;
|
||||
} __attribute__((packed)) jpeg_msg_enc_illegal_command;
|
||||
|
||||
|
||||
/*
|
||||
* Message to ACK CMD_JPEGD_DECODE
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_DEC_DECODE_ACK 0x0004
|
||||
#define JPEG_MSG_DEC_DECODE_ACK_LEN \
|
||||
sizeof(jpeg_msg_dec_decode_ack)
|
||||
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) jpeg_msg_dec_decode_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to inform up that an op buffer is ready for consumption and when
|
||||
* decoding is complete or an error occurs
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_DEC_OP_PRODUCED 0x0005
|
||||
#define JPEG_MSG_DEC_OP_PRODUCED_LEN \
|
||||
sizeof(jpeg_msg_dec_op_produced)
|
||||
|
||||
#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000
|
||||
#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned int luma_op_buf_addr;
|
||||
unsigned int chroma_op_buf_addr;
|
||||
unsigned int num_mcus;
|
||||
unsigned int op_buf_status;
|
||||
} __attribute__((packed)) jpeg_msg_dec_op_produced;
|
||||
|
||||
/*
|
||||
* Message to ack CMD_JPEGD_IDLE cmd
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_DEC_IDLE_ACK 0x0006
|
||||
#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack)
|
||||
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) jpeg_msg_dec_idle_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to indicate illegal cmd was received
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007
|
||||
#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \
|
||||
sizeof(jpeg_msg_dec_illegal_command)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int status;
|
||||
} __attribute__((packed)) jpeg_msg_dec_illegal_command;
|
||||
|
||||
/*
|
||||
* Message to request up for the next segment of ip bit stream
|
||||
*/
|
||||
|
||||
#define JPEG_MSG_DEC_IP_REQUEST 0x0008
|
||||
#define JPEG_MSG_DEC_IP_REQUEST_LEN \
|
||||
sizeof(jpeg_msg_dec_ip_request)
|
||||
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) jpeg_msg_dec_ip_request;
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
#ifndef QDSP5LPMCMDI_H
|
||||
#define QDSP5LPMCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
L P M I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by LPM Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
06/12/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
/*
|
||||
* Command to start LPM processing based on the config params
|
||||
*/
|
||||
|
||||
#define LPM_CMD_START 0x0000
|
||||
#define LPM_CMD_START_LEN sizeof(lpm_cmd_start)
|
||||
|
||||
#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000
|
||||
#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int ip_data_cfg_part1;
|
||||
unsigned int ip_data_cfg_part2;
|
||||
unsigned int ip_data_cfg_part3;
|
||||
unsigned int ip_data_cfg_part4;
|
||||
unsigned int op_data_cfg_part1;
|
||||
unsigned int op_data_cfg_part2;
|
||||
unsigned int op_data_cfg_part3;
|
||||
unsigned int spatial_filter_part[32];
|
||||
} __attribute__((packed)) lpm_cmd_start;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to stop LPM processing
|
||||
*/
|
||||
|
||||
#define LPM_CMD_IDLE 0x0001
|
||||
#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
} __attribute__((packed)) lpm_cmd_idle;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,80 +0,0 @@
|
|||
#ifndef QDSP5LPMMSGI_H
|
||||
#define QDSP5LPMMSGI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
L P M I N T E R N A L M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by LPM Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
06/12/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_LPM_IDLE command
|
||||
*/
|
||||
|
||||
#define LPM_MSG_IDLE_ACK 0x0000
|
||||
#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) lpm_msg_idle_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_LPM_START command
|
||||
*/
|
||||
|
||||
|
||||
#define LPM_MSG_START_ACK 0x0001
|
||||
#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack)
|
||||
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) lpm_msg_start_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that LPM processing is complete
|
||||
*/
|
||||
|
||||
#define LPM_MSG_DONE 0x0002
|
||||
#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) lpm_msg_done;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,235 +0,0 @@
|
|||
#ifndef QDSP5VIDDECCMDI_H
|
||||
#define QDSP5VIDDECCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
V I D E O D E C O D E R I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by VIDDEC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
05/10/08 ac initial version
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
/*
|
||||
* Command to inform VIDDEC that new subframe packet is ready
|
||||
*/
|
||||
|
||||
#define VIDDEC_CMD_SUBFRAME_PKT 0x0000
|
||||
#define VIDDEC_CMD_SUBFRAME_PKT_LEN \
|
||||
sizeof(viddec_cmd_subframe_pkt)
|
||||
|
||||
#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000
|
||||
#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001
|
||||
|
||||
#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000
|
||||
#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001
|
||||
#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002
|
||||
#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003
|
||||
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007
|
||||
#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short packet_seq_number;
|
||||
unsigned short codec_instance_id;
|
||||
unsigned short subframe_packet_size_high;
|
||||
unsigned short subframe_packet_size_low;
|
||||
unsigned short subframe_packet_high;
|
||||
unsigned short subframe_packet_low;
|
||||
unsigned short subframe_packet_partition;
|
||||
unsigned short statistics_packet_size_high;
|
||||
unsigned short statistics_packet_size_low;
|
||||
unsigned short statistics_packet_high;
|
||||
unsigned short statistics_packet_low;
|
||||
unsigned short statistics_partition;
|
||||
unsigned short subframe_info_1;
|
||||
unsigned short subframe_info_0;
|
||||
unsigned short codec_selection_word;
|
||||
unsigned short num_mbs;
|
||||
} __attribute__((packed)) viddec_cmd_subframe_pkt;
|
||||
|
||||
|
||||
/*
|
||||
* Command to inform VIDDEC task that post processing is required for the frame
|
||||
*/
|
||||
|
||||
#define VIDDEC_CMD_PP_ENABLE 0x0001
|
||||
#define VIDDEC_CMD_PP_ENABLE_LEN \
|
||||
sizeof(viddec_cmd_pp_enable)
|
||||
|
||||
#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000
|
||||
#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short packet_seq_num;
|
||||
unsigned short codec_instance_id;
|
||||
unsigned short postproc_info_0;
|
||||
unsigned short codec_selection_word;
|
||||
unsigned short pp_output_addr_high;
|
||||
unsigned short pp_output_addr_low;
|
||||
unsigned short postproc_info_1;
|
||||
unsigned short load_sharing_packet_size_high;
|
||||
unsigned short load_sharing_packet_size_low;
|
||||
unsigned short load_sharing_packet_high;
|
||||
unsigned short load_sharing_packet_low;
|
||||
unsigned short load_sharing_partition;
|
||||
unsigned short pp_param_0;
|
||||
unsigned short pp_param_1;
|
||||
unsigned short pp_param_2;
|
||||
unsigned short pp_param_3;
|
||||
} __attribute__((packed)) viddec_cmd_pp_enable;
|
||||
|
||||
|
||||
/*
|
||||
* FRAME Header Packet : It is at the start of new frame
|
||||
*/
|
||||
|
||||
#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002
|
||||
#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \
|
||||
sizeof(viddec_cmd_frame_header_packet)
|
||||
|
||||
#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000
|
||||
#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800
|
||||
|
||||
typedef struct {
|
||||
unsigned short packet_id;
|
||||
unsigned short x_dimension;
|
||||
unsigned short y_dimension;
|
||||
unsigned short line_width;
|
||||
unsigned short frame_info_0;
|
||||
unsigned short frame_buffer_0_high;
|
||||
unsigned short frame_buffer_0_low;
|
||||
unsigned short frame_buffer_1_high;
|
||||
unsigned short frame_buffer_1_low;
|
||||
unsigned short frame_buffer_2_high;
|
||||
unsigned short frame_buffer_2_low;
|
||||
unsigned short frame_buffer_3_high;
|
||||
unsigned short frame_buffer_3_low;
|
||||
unsigned short frame_buffer_4_high;
|
||||
unsigned short frame_buffer_4_low;
|
||||
unsigned short frame_buffer_5_high;
|
||||
unsigned short frame_buffer_5_low;
|
||||
unsigned short frame_buffer_6_high;
|
||||
unsigned short frame_buffer_6_low;
|
||||
unsigned short frame_buffer_7_high;
|
||||
unsigned short frame_buffer_7_low;
|
||||
unsigned short frame_buffer_8_high;
|
||||
unsigned short frame_buffer_8_low;
|
||||
unsigned short frame_buffer_9_high;
|
||||
unsigned short frame_buffer_9_low;
|
||||
unsigned short frame_buffer_10_high;
|
||||
unsigned short frame_buffer_10_low;
|
||||
unsigned short frame_buffer_11_high;
|
||||
unsigned short frame_buffer_11_low;
|
||||
unsigned short frame_buffer_12_high;
|
||||
unsigned short frame_buffer_12_low;
|
||||
unsigned short frame_buffer_13_high;
|
||||
unsigned short frame_buffer_13_low;
|
||||
unsigned short frame_buffer_14_high;
|
||||
unsigned short frame_buffer_14_low;
|
||||
unsigned short frame_buffer_15_high;
|
||||
unsigned short frame_buffer_15_low;
|
||||
unsigned short output_frame_buffer_high;
|
||||
unsigned short output_frame_buffer_low;
|
||||
unsigned short end_of_packet_marker;
|
||||
} __attribute__((packed)) viddec_cmd_frame_header_packet;
|
||||
|
||||
|
||||
/*
|
||||
* SLICE HEADER PACKET
|
||||
* I-Slice and P-Slice
|
||||
*/
|
||||
|
||||
#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003
|
||||
#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \
|
||||
sizeof(viddec_cmd_slice_header_pkt_islice)
|
||||
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000
|
||||
#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800
|
||||
|
||||
#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short packet_id;
|
||||
unsigned short slice_info_0;
|
||||
unsigned short slice_info_1;
|
||||
unsigned short slice_info_2;
|
||||
unsigned short num_bytes_in_rbsp_high;
|
||||
unsigned short num_bytes_in_rbsp_low;
|
||||
unsigned short num_bytes_in_rbsp_consumed;
|
||||
unsigned short end_of_packet_marker;
|
||||
} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
|
||||
|
||||
|
||||
#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003
|
||||
#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \
|
||||
sizeof(viddec_cmd_slice_header_pkt_pslice)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short packet_id;
|
||||
unsigned short slice_info_0;
|
||||
unsigned short slice_info_1;
|
||||
unsigned short slice_info_2;
|
||||
unsigned short slice_info_3;
|
||||
unsigned short refidx_l0_map_tab_info_0;
|
||||
unsigned short refidx_l0_map_tab_info_1;
|
||||
unsigned short refidx_l0_map_tab_info_2;
|
||||
unsigned short refidx_l0_map_tab_info_3;
|
||||
unsigned short num_bytes_in_rbsp_high;
|
||||
unsigned short num_bytes_in_rbsp_low;
|
||||
unsigned short num_bytes_in_rbsp_consumed;
|
||||
unsigned short end_of_packet_marker;
|
||||
} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||
#ifndef QDSP5VIDDECMSGI_H
|
||||
#define QDSP5VIDDECMSGI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
V I D E O D E C O D E R I N T E R N A L M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of messages
|
||||
that are sent by VIDDEC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
05/10/08 ac initial version
|
||||
===========================================================================*/
|
||||
|
||||
/*
|
||||
* Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
|
||||
*/
|
||||
|
||||
#define VIDDEC_MSG_SUBF_DONE 0x0000
|
||||
#define VIDDEC_MSG_SUBF_DONE_LEN \
|
||||
sizeof(viddec_msg_subf_done)
|
||||
|
||||
typedef struct {
|
||||
unsigned short packet_seq_number;
|
||||
unsigned short codec_instance_id;
|
||||
} __attribute__((packed)) viddec_msg_subf_done;
|
||||
|
||||
|
||||
/*
|
||||
* Message to inform ARM one frame has been decoded
|
||||
*/
|
||||
|
||||
#define VIDDEC_MSG_FRAME_DONE 0x0001
|
||||
#define VIDDEC_MSG_FRAME_DONE_LEN \
|
||||
sizeof(viddec_msg_frame_done)
|
||||
|
||||
typedef struct {
|
||||
unsigned short packet_seq_number;
|
||||
unsigned short codec_instance_id;
|
||||
} __attribute__((packed)) viddec_msg_frame_done;
|
||||
|
||||
|
||||
/*
|
||||
* Message to inform ARM that post processing frame has been decoded
|
||||
*/
|
||||
|
||||
#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002
|
||||
#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \
|
||||
sizeof(viddec_msg_pp_enable_cmd_done)
|
||||
|
||||
typedef struct {
|
||||
unsigned short packet_seq_number;
|
||||
unsigned short codec_instance_id;
|
||||
} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
|
||||
|
||||
|
||||
/*
|
||||
* Message to inform ARM that one post processing frame has been decoded
|
||||
*/
|
||||
|
||||
|
||||
#define VIDDEC_MSG_PP_FRAME_DONE 0x0003
|
||||
#define VIDDEC_MSG_PP_FRAME_DONE_LEN \
|
||||
sizeof(viddec_msg_pp_frame_done)
|
||||
|
||||
#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000
|
||||
#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short packet_seq_number;
|
||||
unsigned short codec_instance_id;
|
||||
unsigned short display_worthy;
|
||||
} __attribute__((packed)) viddec_msg_pp_frame_done;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,212 +0,0 @@
|
|||
#ifndef QDSP5VIDENCCMDI_H
|
||||
#define QDSP5VIDENCCMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
V I D E O E N C O D E R I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by VIDENC Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 2008 by QUALCOMM, Incorporated.
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
09/25/08 umeshp initial version
|
||||
===========================================================================*/
|
||||
|
||||
#define VIDENC_CMD_CFG 0x0000
|
||||
#define VIDENC_CMD_ACTIVE 0x0001
|
||||
#define VIDENC_CMD_IDLE 0x0002
|
||||
#define VIDENC_CMD_FRAME_START 0x0003
|
||||
#define VIDENC_CMD_STATUS_QUERY 0x0004
|
||||
#define VIDENC_CMD_RC_CFG 0x0005
|
||||
#define VIDENC_CMD_DIS_CFG 0x0006
|
||||
#define VIDENC_CMD_DIS 0x0007
|
||||
#define VIDENC_CMD_INTRA_REFRESH 0x0008
|
||||
#define VIDENC_CMD_DIGITAL_ZOOM 0x0009
|
||||
|
||||
|
||||
/*
|
||||
* Command to pass the frame message information to VIDENC
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_FRAME_START_LEN \
|
||||
sizeof(videnc_cmd_frame_start)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short frame_info;
|
||||
unsigned short frame_rho_budget_word_high;
|
||||
unsigned short frame_rho_budget_word_low;
|
||||
unsigned short input_luma_addr_high;
|
||||
unsigned short input_luma_addr_low;
|
||||
unsigned short input_chroma_addr_high;
|
||||
unsigned short input_chroma_addr_low;
|
||||
unsigned short ref_vop_buf_ptr_high;
|
||||
unsigned short ref_vop_buf_ptr_low;
|
||||
unsigned short enc_pkt_buf_ptr_high;
|
||||
unsigned short enc_pkt_buf_ptr_low;
|
||||
unsigned short enc_pkt_buf_size_high;
|
||||
unsigned short enc_pkt_buf_size_low;
|
||||
unsigned short unfilt_recon_vop_buf_ptr_high;
|
||||
unsigned short unfilt_recon_vop_buf_ptr_low;
|
||||
unsigned short filt_recon_vop_buf_ptr_high;
|
||||
unsigned short filt_recon_vop_buf_ptr_low;
|
||||
} __attribute__((packed)) videnc_cmd_frame_start;
|
||||
|
||||
/*
|
||||
* Command to pass the frame-level digital stabilization parameters to VIDENC
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_DIS_LEN \
|
||||
sizeof(videnc_cmd_dis)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short vfe_out_prev_luma_addr_high;
|
||||
unsigned short vfe_out_prev_luma_addr_low;
|
||||
unsigned short stabilization_info;
|
||||
} __attribute__((packed)) videnc_cmd_dis;
|
||||
|
||||
/*
|
||||
* Command to pass the codec related parameters to VIDENC
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_CFG_LEN \
|
||||
sizeof(videnc_cmd_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short cfg_info_0;
|
||||
unsigned short cfg_info_1;
|
||||
unsigned short four_mv_threshold;
|
||||
unsigned short ise_fse_mv_cost_fac;
|
||||
unsigned short venc_frame_dim;
|
||||
unsigned short venc_DM_partition;
|
||||
} __attribute__((packed)) videnc_cmd_cfg;
|
||||
|
||||
/*
|
||||
* Command to start the video encoding
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_ACTIVE_LEN \
|
||||
sizeof(videnc_cmd_active)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) videnc_cmd_active;
|
||||
|
||||
/*
|
||||
* Command to stop the video encoding
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_IDLE_LEN \
|
||||
sizeof(videnc_cmd_idle)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) videnc_cmd_idle;
|
||||
|
||||
/*
|
||||
* Command to query staus of VIDENC
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_STATUS_QUERY_LEN \
|
||||
sizeof(videnc_cmd_status_query)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) videnc_cmd_status_query;
|
||||
|
||||
/*
|
||||
* Command to set rate control for a frame
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_RC_CFG_LEN \
|
||||
sizeof(videnc_cmd_rc_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short max_frame_qp_delta;
|
||||
unsigned short max_min_frame_qp;
|
||||
} __attribute__((packed)) videnc_cmd_rc_cfg;
|
||||
|
||||
/*
|
||||
* Command to set intra-refreshing
|
||||
*/
|
||||
|
||||
|
||||
#define VIDENC_CMD_INTRA_REFRESH_LEN \
|
||||
sizeof(videnc_cmd_intra_refresh)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short num_mb_refresh;
|
||||
unsigned short mb_index[15];
|
||||
} __attribute__((packed)) videnc_cmd_intra_refresh;
|
||||
|
||||
/*
|
||||
* Command to pass digital zoom information to the VIDENC
|
||||
*/
|
||||
#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
|
||||
sizeof(videnc_cmd_digital_zoom)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short digital_zoom_en;
|
||||
unsigned short luma_frame_shift_X;
|
||||
unsigned short luma_frame_shift_Y;
|
||||
unsigned short up_ip_luma_rows;
|
||||
unsigned short up_ip_luma_cols;
|
||||
unsigned short up_ip_chroma_rows;
|
||||
unsigned short up_ip_chroma_cols;
|
||||
unsigned short luma_ph_incr_V_low;
|
||||
unsigned short luma_ph_incr_V_high;
|
||||
unsigned short luma_ph_incr_H_low;
|
||||
unsigned short luma_ph_incr_H_high;
|
||||
unsigned short chroma_ph_incr_V_low;
|
||||
unsigned short chroma_ph_incr_V_high;
|
||||
unsigned short chroma_ph_incr_H_low;
|
||||
unsigned short chroma_ph_incr_H_high;
|
||||
} __attribute__((packed)) videnc_cmd_digital_zoom;
|
||||
|
||||
/*
|
||||
* Command to configure digital stabilization parameters
|
||||
*/
|
||||
|
||||
#define VIDENC_CMD_DIS_CFG_LEN \
|
||||
sizeof(videnc_cmd_dis_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
unsigned short image_stab_subf_start_row_col;
|
||||
unsigned short image_stab_subf_dim;
|
||||
unsigned short image_stab_info_0;
|
||||
} __attribute__((packed)) videnc_cmd_dis_cfg;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,910 +0,0 @@
|
|||
#ifndef QDSP5VFECMDI_H
|
||||
#define QDSP5VFECMDI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
V F E I N T E R N A L C O M M A N D S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are accepted by VFE Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
06/12/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
/******************************************************************************
|
||||
* Commands through vfeCommandScaleQueue
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Command to program scaler for op1 . max op of scaler is VGA
|
||||
*/
|
||||
|
||||
|
||||
#define VFE_CMD_SCALE_OP1_CFG 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_CFG_LEN \
|
||||
sizeof(vfe_cmd_scale_op1_cfg)
|
||||
|
||||
#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010
|
||||
#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080
|
||||
|
||||
#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
|
||||
#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int scale_op1_sel;
|
||||
unsigned int y_scaler_cfg_part1;
|
||||
unsigned int y_scaler_cfg_part2;
|
||||
unsigned int cbcr_scaler_cfg_part1;
|
||||
unsigned int cbcr_scaler_cfg_part2;
|
||||
unsigned int cbcr_scaler_cfg_part3;
|
||||
unsigned int pp_y_scaler_cfg_part1;
|
||||
unsigned int pp_y_scaler_cfg_part2;
|
||||
unsigned int y_scaler_v_coeff_bank_part1[16];
|
||||
unsigned int y_scaler_v_coeff_bank_part2[16];
|
||||
unsigned int y_scaler_h_coeff_bank_part1[16];
|
||||
unsigned int y_scaler_h_coeff_bank_part2[16];
|
||||
} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program scaler for op2
|
||||
*/
|
||||
|
||||
#define VFE_CMD_SCALE_OP2_CFG 0x0001
|
||||
#define VFE_CMD_SCALE_OP2_CFG_LEN \
|
||||
sizeof(vfe_cmd_scale_op2_cfg)
|
||||
|
||||
#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010
|
||||
#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000
|
||||
#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080
|
||||
|
||||
#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
|
||||
#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int scale_op2_sel;
|
||||
unsigned int y_scaler_cfg_part1;
|
||||
unsigned int y_scaler_cfg_part2;
|
||||
unsigned int cbcr_scaler_cfg_part1;
|
||||
unsigned int cbcr_scaler_cfg_part2;
|
||||
unsigned int cbcr_scaler_cfg_part3;
|
||||
unsigned int pp_y_scaler_cfg_part1;
|
||||
unsigned int pp_y_scaler_cfg_part2;
|
||||
unsigned int y_scaler_v_coeff_bank_part1[16];
|
||||
unsigned int y_scaler_v_coeff_bank_part2[16];
|
||||
unsigned int y_scaler_h_coeff_bank_part1[16];
|
||||
unsigned int y_scaler_h_coeff_bank_part2[16];
|
||||
} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Commands through vfeCommandTableQueue
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Command to program the AXI ip paths
|
||||
*/
|
||||
|
||||
#define VFE_CMD_AXI_IP_CFG 0x0000
|
||||
#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg)
|
||||
|
||||
#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000
|
||||
#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001
|
||||
#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int ip_sel;
|
||||
unsigned int ip_cfg_part1;
|
||||
unsigned int ip_cfg_part2;
|
||||
unsigned int ip_unpack_cfg_part[6];
|
||||
unsigned int ip_buf_addr[8];
|
||||
} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program axi op paths
|
||||
*/
|
||||
|
||||
#define VFE_CMD_AXI_OP_CFG 0x0001
|
||||
#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg)
|
||||
|
||||
#define VFE_CMD_OP_SEL_OP1 0x0000
|
||||
#define VFE_CMD_OP_SEL_OP2 0x0001
|
||||
#define VFE_CMD_OP_SEL_OP1_OP2 0x0002
|
||||
#define VFE_CMD_OP_SEL_CTOA 0x0003
|
||||
#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004
|
||||
#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005
|
||||
#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000
|
||||
#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008
|
||||
#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int op_sel;
|
||||
unsigned int op1_y_cfg_part1;
|
||||
unsigned int op1_y_cfg_part2;
|
||||
unsigned int op1_cbcr_cfg_part1;
|
||||
unsigned int op1_cbcr_cfg_part2;
|
||||
unsigned int op2_y_cfg_part1;
|
||||
unsigned int op2_y_cfg_part2;
|
||||
unsigned int op2_cbcr_cfg_part1;
|
||||
unsigned int op2_cbcr_cfg_part2;
|
||||
unsigned int op1_buf1_addr[16];
|
||||
unsigned int op2_buf1_addr[16];
|
||||
} __attribute__((packed)) vfe_cmd_axi_op_cfg;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the roll off correction module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_ROLLOFF_CFG 0x0002
|
||||
#define VFE_CMD_ROLLOFF_CFG_LEN \
|
||||
sizeof(vfe_cmd_rolloff_cfg)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int correction_opt_center_pos;
|
||||
unsigned int radius_square_entry[32];
|
||||
unsigned int red_table_entry[32];
|
||||
unsigned int green_table_entry[32];
|
||||
unsigned int blue_table_entry[32];
|
||||
} __attribute__((packed)) vfe_cmd_rolloff_cfg;
|
||||
|
||||
/*
|
||||
* Command to program RGB gamma table
|
||||
*/
|
||||
|
||||
#define VFE_CMD_RGB_GAMMA_CFG 0x0003
|
||||
#define VFE_CMD_RGB_GAMMA_CFG_LEN \
|
||||
sizeof(vfe_cmd_rgb_gamma_cfg)
|
||||
|
||||
#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000
|
||||
#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int rgb_gamma_sel;
|
||||
unsigned int rgb_gamma_entry[256];
|
||||
} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program luma gamma table for the noise reduction path
|
||||
*/
|
||||
|
||||
#define VFE_CMD_Y_GAMMA_CFG 0x0004
|
||||
#define VFE_CMD_Y_GAMMA_CFG_LEN \
|
||||
sizeof(vfe_cmd_y_gamma_cfg)
|
||||
|
||||
#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000
|
||||
#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int y_gamma_sel;
|
||||
unsigned int y_gamma_entry[256];
|
||||
} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Commands through vfeCommandQueue
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Command to reset the VFE to a known good state.All previously programmed
|
||||
* Params will be lost
|
||||
*/
|
||||
|
||||
|
||||
#define VFE_CMD_RESET 0x0000
|
||||
#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) vfe_cmd_reset;
|
||||
|
||||
|
||||
/*
|
||||
* Command to start VFE processing based on the config params
|
||||
*/
|
||||
|
||||
|
||||
#define VFE_CMD_START 0x0001
|
||||
#define VFE_CMD_START_LEN sizeof(vfe_cmd_start)
|
||||
|
||||
#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000
|
||||
#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001
|
||||
#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000
|
||||
#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002
|
||||
|
||||
#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001
|
||||
#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002
|
||||
#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004
|
||||
#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008
|
||||
#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010
|
||||
#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020
|
||||
#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000
|
||||
#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int startup_params;
|
||||
unsigned int image_pipeline;
|
||||
unsigned int frame_dimension;
|
||||
} __attribute__((packed)) vfe_cmd_start;
|
||||
|
||||
|
||||
/*
|
||||
* Command to halt all processing
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STOP 0x0002
|
||||
#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) vfe_cmd_stop;
|
||||
|
||||
|
||||
/*
|
||||
* Command to commit the params that have been programmed to take
|
||||
* effect on the next frame
|
||||
*/
|
||||
|
||||
#define VFE_CMD_UPDATE 0x0003
|
||||
#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) vfe_cmd_update;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program CAMIF module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_CAMIF_CFG 0x0004
|
||||
#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg)
|
||||
|
||||
#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000
|
||||
#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002
|
||||
#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000
|
||||
#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004
|
||||
#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000
|
||||
#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008
|
||||
#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010
|
||||
#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018
|
||||
#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000
|
||||
#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020
|
||||
#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000
|
||||
#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080
|
||||
#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000
|
||||
#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800
|
||||
|
||||
#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000
|
||||
#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010
|
||||
|
||||
#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000
|
||||
#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000
|
||||
#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000
|
||||
#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int cfg;
|
||||
unsigned int efs_cfg;
|
||||
unsigned int frame_cfg;
|
||||
unsigned int window_width_cfg;
|
||||
unsigned int window_height_cfg;
|
||||
unsigned int subsamp1_cfg;
|
||||
unsigned int subsamp2_cfg;
|
||||
unsigned int epoch_irq;
|
||||
} __attribute__((packed)) vfe_cmd_camif_cfg;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the black level module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_BLACK_LVL_CFG 0x0005
|
||||
#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg)
|
||||
|
||||
#define VFE_CMD_BL_SEL_MANUAL 0x0000
|
||||
#define VFE_CMD_BL_SEL_AUTO 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int black_lvl_sel;
|
||||
unsigned int cfg_part[3];
|
||||
} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the active region by cropping the region of interest
|
||||
*/
|
||||
|
||||
#define VFE_CMD_ACTIVE_REGION_CFG 0x0006
|
||||
#define VFE_CMD_ACTIVE_REGION_CFG_LEN \
|
||||
sizeof(vfe_cmd_active_region_cfg)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int cfg_part1;
|
||||
unsigned int cfg_part2;
|
||||
} __attribute__((packed)) vfe_cmd_active_region_cfg;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the defective pixel correction(DPC) ,
|
||||
* adaptive bayer filter (ABF) and demosaic modules
|
||||
*/
|
||||
|
||||
#define VFE_CMD_DEMOSAIC_CFG 0x0007
|
||||
#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg)
|
||||
|
||||
#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001
|
||||
#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002
|
||||
#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000
|
||||
#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int demosaic_part1;
|
||||
unsigned int demosaic_part2;
|
||||
unsigned int demosaic_part3;
|
||||
unsigned int demosaic_part4;
|
||||
unsigned int demosaic_part5;
|
||||
} __attribute__((packed)) vfe_cmd_demosaic_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the ip format
|
||||
*/
|
||||
|
||||
#define VFE_CMD_IP_FORMAT_CFG 0x0008
|
||||
#define VFE_CMD_IP_FORMAT_CFG_LEN \
|
||||
sizeof(vfe_cmd_ip_format_cfg)
|
||||
|
||||
#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000
|
||||
#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001
|
||||
#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002
|
||||
#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003
|
||||
#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004
|
||||
#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005
|
||||
#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006
|
||||
#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007
|
||||
#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000
|
||||
#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int ip_format_sel;
|
||||
unsigned int balance_gains_part1;
|
||||
unsigned int balance_gains_part2;
|
||||
} __attribute__((packed)) vfe_cmd_ip_format_cfg;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to program max and min allowed op values
|
||||
*/
|
||||
|
||||
#define VFE_CMD_OP_CLAMP_CFG 0x0009
|
||||
#define VFE_CMD_OP_CLAMP_CFG_LEN \
|
||||
sizeof(vfe_cmd_op_clamp_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int op_clamp_max;
|
||||
unsigned int op_clamp_min;
|
||||
} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program chroma sub sample module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A
|
||||
#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \
|
||||
sizeof(vfe_cmd_chroma_subsample_cfg)
|
||||
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000
|
||||
#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int chroma_subsamp_sel;
|
||||
} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the white balance module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_WHITE_BALANCE_CFG 0x000B
|
||||
#define VFE_CMD_WHITE_BALANCE_CFG_LEN \
|
||||
sizeof(vfe_cmd_white_balance_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int white_balance_gains;
|
||||
} __attribute__((packed)) vfe_cmd_white_balance_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program the color processing module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_COLOR_PROCESS_CFG 0x000C
|
||||
#define VFE_CMD_COLOR_PROCESS_CFG_LEN \
|
||||
sizeof(vfe_cmd_color_process_cfg)
|
||||
|
||||
#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000
|
||||
#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001
|
||||
#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002
|
||||
#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int color_correction_part1;
|
||||
unsigned int color_correction_part2;
|
||||
unsigned int color_correction_part3;
|
||||
unsigned int color_correction_part4;
|
||||
unsigned int color_correction_part5;
|
||||
unsigned int color_correction_part6;
|
||||
unsigned int color_correction_part7;
|
||||
unsigned int chroma_enhance_part1;
|
||||
unsigned int chroma_enhance_part2;
|
||||
unsigned int chroma_enhance_part3;
|
||||
unsigned int chroma_enhance_part4;
|
||||
unsigned int chroma_enhance_part5;
|
||||
unsigned int luma_calc_part1;
|
||||
unsigned int luma_calc_part2;
|
||||
} __attribute__((packed)) vfe_cmd_color_process_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program adaptive filter module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_ADP_FILTER_CFG 0x000D
|
||||
#define VFE_CMD_ADP_FILTER_CFG_LEN \
|
||||
sizeof(vfe_cmd_adp_filter_cfg)
|
||||
|
||||
#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000
|
||||
#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001
|
||||
#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000
|
||||
#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002
|
||||
#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004
|
||||
#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int asf_cfg_part[7];
|
||||
} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program for frame skip pattern for op1 and op2
|
||||
*/
|
||||
|
||||
#define VFE_CMD_FRAME_SKIP_CFG 0x000E
|
||||
#define VFE_CMD_FRAME_SKIP_CFG_LEN \
|
||||
sizeof(vfe_cmd_frame_skip_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int frame_skip_pattern_op1;
|
||||
unsigned int frame_skip_pattern_op2;
|
||||
} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program field-of-view crop for digital zoom
|
||||
*/
|
||||
|
||||
#define VFE_CMD_FOV_CROP 0x000F
|
||||
#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int fov_crop_part1;
|
||||
unsigned int fov_crop_part2;
|
||||
} __attribute__((packed)) vfe_cmd_fov_crop;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to program auto focus(AF) statistics module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010
|
||||
#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \
|
||||
sizeof(vfe_cmd_stats_autofocus_cfg)
|
||||
|
||||
#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000
|
||||
#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001
|
||||
#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000
|
||||
#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002
|
||||
#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000
|
||||
#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int af_stats_sel;
|
||||
unsigned int af_stats_cfg_part[8];
|
||||
unsigned int af_stats_op_buf_hdr;
|
||||
unsigned int af_stats_op_buf[3];
|
||||
} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program White balance(wb) and exposure (exp)
|
||||
* statistics module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_WB_EXP_CFG 0x0011
|
||||
#define VFE_CMD_STATS_WB_EXP_CFG_LEN \
|
||||
sizeof(vfe_cmd_stats_wb_exp_cfg)
|
||||
|
||||
#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000
|
||||
#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001
|
||||
#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000
|
||||
#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002
|
||||
|
||||
#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000
|
||||
#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001
|
||||
#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000
|
||||
#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int wb_exp_stats_sel;
|
||||
unsigned int wb_exp_stats_cfg_part1;
|
||||
unsigned int wb_exp_stats_cfg_part2;
|
||||
unsigned int wb_exp_stats_cfg_part3;
|
||||
unsigned int wb_exp_stats_cfg_part4;
|
||||
unsigned int wb_exp_stats_op_buf_hdr;
|
||||
unsigned int wb_exp_stats_op_buf[3];
|
||||
} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program histogram(hg) stats module
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_HG_CFG 0x0012
|
||||
#define VFE_CMD_STATS_HG_CFG_LEN \
|
||||
sizeof(vfe_cmd_stats_hg_cfg)
|
||||
|
||||
#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000
|
||||
#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int hg_stats_sel;
|
||||
unsigned int hg_stats_cfg_part1;
|
||||
unsigned int hg_stats_cfg_part2;
|
||||
unsigned int hg_stats_op_buf_hdr;
|
||||
unsigned int hg_stats_op_buf;
|
||||
} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge last MSG_VFE_OP1 message
|
||||
*/
|
||||
|
||||
#define VFE_CMD_OP1_ACK 0x0013
|
||||
#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int op1_buf_y_addr;
|
||||
unsigned int op1_buf_cbcr_addr;
|
||||
} __attribute__((packed)) vfe_cmd_op1_ack;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge last MSG_VFE_OP2 message
|
||||
*/
|
||||
|
||||
#define VFE_CMD_OP2_ACK 0x0014
|
||||
#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int op2_buf_y_addr;
|
||||
unsigned int op2_buf_cbcr_addr;
|
||||
} __attribute__((packed)) vfe_cmd_op2_ack;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_AF_ACK 0x0015
|
||||
#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int af_stats_op_buf;
|
||||
} __attribute__((packed)) vfe_cmd_stats_af_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge MSG_VFE_STATS_WB_EXP msg
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_WB_EXP_ACK 0x0016
|
||||
#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int wb_exp_stats_op_buf;
|
||||
} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge MSG_VFE_EPOCH1 message
|
||||
*/
|
||||
|
||||
#define VFE_CMD_EPOCH1_ACK 0x0017
|
||||
#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) vfe_cmd_epoch1_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Command to acknowledge MSG_VFE_EPOCH2 message
|
||||
*/
|
||||
|
||||
#define VFE_CMD_EPOCH2_ACK 0x0018
|
||||
#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack)
|
||||
|
||||
typedef struct {
|
||||
unsigned short cmd_id;
|
||||
} __attribute__((packed)) vfe_cmd_epoch2_ack;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure, enable or disable synchronous timer1
|
||||
*/
|
||||
|
||||
#define VFE_CMD_SYNC_TIMER1_CFG 0x0019
|
||||
#define VFE_CMD_SYNC_TIMER1_CFG_LEN \
|
||||
sizeof(vfe_cmd_sync_timer1_cfg)
|
||||
|
||||
#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000
|
||||
#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001
|
||||
#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000
|
||||
#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int sync_t1_cfg_part1;
|
||||
unsigned int sync_t1_h_sync_countdown;
|
||||
unsigned int sync_t1_pclk_countdown;
|
||||
unsigned int sync_t1_duration;
|
||||
} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure, enable or disable synchronous timer1
|
||||
*/
|
||||
|
||||
#define VFE_CMD_SYNC_TIMER2_CFG 0x001A
|
||||
#define VFE_CMD_SYNC_TIMER2_CFG_LEN \
|
||||
sizeof(vfe_cmd_sync_timer2_cfg)
|
||||
|
||||
#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000
|
||||
#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001
|
||||
#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000
|
||||
#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int sync_t2_cfg_part1;
|
||||
unsigned int sync_t2_h_sync_countdown;
|
||||
unsigned int sync_t2_pclk_countdown;
|
||||
unsigned int sync_t2_duration;
|
||||
} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure and start asynchronous timer1
|
||||
*/
|
||||
|
||||
#define VFE_CMD_ASYNC_TIMER1_START 0x001B
|
||||
#define VFE_CMD_ASYNC_TIMER1_START_LEN \
|
||||
sizeof(vfe_cmd_async_timer1_start)
|
||||
|
||||
#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000
|
||||
#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001
|
||||
#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000
|
||||
#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int async_t1a_cfg;
|
||||
unsigned int async_t1b_cfg;
|
||||
unsigned int async_t1_polarity;
|
||||
} __attribute__((packed)) vfe_cmd_async_timer1_start;
|
||||
|
||||
|
||||
/*
|
||||
* Command to configure and start asynchronous timer2
|
||||
*/
|
||||
|
||||
#define VFE_CMD_ASYNC_TIMER2_START 0x001C
|
||||
#define VFE_CMD_ASYNC_TIMER2_START_LEN \
|
||||
sizeof(vfe_cmd_async_timer2_start)
|
||||
|
||||
#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000
|
||||
#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001
|
||||
#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000
|
||||
#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int async_t2a_cfg;
|
||||
unsigned int async_t2b_cfg;
|
||||
unsigned int async_t2_polarity;
|
||||
} __attribute__((packed)) vfe_cmd_async_timer2_start;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program partial configurations of auto focus(af)
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_AF_UPDATE 0x001D
|
||||
#define VFE_CMD_STATS_AF_UPDATE_LEN \
|
||||
sizeof(vfe_cmd_stats_af_update)
|
||||
|
||||
#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000
|
||||
#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int af_update_part1;
|
||||
unsigned int af_update_part2;
|
||||
} __attribute__((packed)) vfe_cmd_stats_af_update;
|
||||
|
||||
|
||||
/*
|
||||
* Command to program partial cfg of wb and exp
|
||||
*/
|
||||
|
||||
#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E
|
||||
#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \
|
||||
sizeof(vfe_cmd_stats_wb_exp_update)
|
||||
|
||||
#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000
|
||||
#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001
|
||||
#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000
|
||||
#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int wb_exp_update_part1;
|
||||
unsigned int wb_exp_update_part2;
|
||||
unsigned int wb_exp_update_part3;
|
||||
unsigned int wb_exp_update_part4;
|
||||
} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Command to re program the CAMIF FRAME CONFIG settings
|
||||
*/
|
||||
|
||||
#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F
|
||||
#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \
|
||||
sizeof(vfe_cmd_update_camif_frame_cfg)
|
||||
|
||||
typedef struct {
|
||||
unsigned int cmd_id;
|
||||
unsigned int camif_frame_cfg;
|
||||
} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,290 +0,0 @@
|
|||
#ifndef QDSP5VFEMSGI_H
|
||||
#define QDSP5VFEMSGI_H
|
||||
|
||||
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
|
||||
|
||||
V F E I N T E R N A L M E S S A G E S
|
||||
|
||||
GENERAL DESCRIPTION
|
||||
This file contains defintions of format blocks of commands
|
||||
that are sent by VFE Task
|
||||
|
||||
REFERENCES
|
||||
None
|
||||
|
||||
EXTERNALIZED FUNCTIONS
|
||||
None
|
||||
|
||||
Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
|
||||
|
||||
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.
|
||||
|
||||
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
|
||||
/*===========================================================================
|
||||
|
||||
EDIT HISTORY FOR FILE
|
||||
|
||||
This section contains comments describing changes made to this file.
|
||||
Notice that changes are listed in reverse chronological order.
|
||||
|
||||
$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
|
||||
Revision History:
|
||||
|
||||
when who what, where, why
|
||||
-------- --- ----------------------------------------------------------
|
||||
06/12/08 sv initial version
|
||||
===========================================================================*/
|
||||
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_VFE_REST command
|
||||
*/
|
||||
|
||||
#define VFE_MSG_RESET_ACK 0x0000
|
||||
#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_reset_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_VFE_START command
|
||||
*/
|
||||
|
||||
#define VFE_MSG_START_ACK 0x0001
|
||||
#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_start_ack;
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_VFE_STOP command
|
||||
*/
|
||||
|
||||
#define VFE_MSG_STOP_ACK 0x0002
|
||||
#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_stop_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to acknowledge CMD_VFE_UPDATE command
|
||||
*/
|
||||
|
||||
#define VFE_MSG_UPDATE_ACK 0x0003
|
||||
#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_update_ack;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that snapshot processing is complete
|
||||
* and that the VFE is now STATE_VFE_IDLE
|
||||
*/
|
||||
|
||||
#define VFE_MSG_SNAPSHOT_DONE 0x0004
|
||||
#define VFE_MSG_SNAPSHOT_DONE_LEN \
|
||||
sizeof(vfe_msg_snapshot_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_snapshot_done;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify ARM that illegal cmd was received and
|
||||
* system is in the IDLE state
|
||||
*/
|
||||
|
||||
#define VFE_MSG_ILLEGAL_CMD 0x0005
|
||||
#define VFE_MSG_ILLEGAL_CMD_LEN \
|
||||
sizeof(vfe_msg_illegal_cmd)
|
||||
|
||||
typedef struct {
|
||||
unsigned int status;
|
||||
} __attribute__((packed)) vfe_msg_illegal_cmd;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify ARM that op1 buf is full and ready
|
||||
*/
|
||||
|
||||
#define VFE_MSG_OP1 0x0006
|
||||
#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1)
|
||||
|
||||
typedef struct {
|
||||
unsigned int op1_buf_y_addr;
|
||||
unsigned int op1_buf_cbcr_addr;
|
||||
unsigned int black_level_even_col;
|
||||
unsigned int black_level_odd_col;
|
||||
unsigned int defect_pixels_detected;
|
||||
unsigned int asf_max_edge;
|
||||
} __attribute__((packed)) vfe_msg_op1;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify ARM that op2 buf is full and ready
|
||||
*/
|
||||
|
||||
#define VFE_MSG_OP2 0x0007
|
||||
#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2)
|
||||
|
||||
typedef struct {
|
||||
unsigned int op2_buf_y_addr;
|
||||
unsigned int op2_buf_cbcr_addr;
|
||||
unsigned int black_level_even_col;
|
||||
unsigned int black_level_odd_col;
|
||||
unsigned int defect_pixels_detected;
|
||||
unsigned int asf_max_edge;
|
||||
} __attribute__((packed)) vfe_msg_op2;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify ARM that autofocus(af) stats are ready
|
||||
*/
|
||||
|
||||
#define VFE_MSG_STATS_AF 0x0008
|
||||
#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af)
|
||||
|
||||
typedef struct {
|
||||
unsigned int af_stats_op_buffer;
|
||||
} __attribute__((packed)) vfe_msg_stats_af;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify ARM that white balance(wb) and exposure (exp)
|
||||
* stats are ready
|
||||
*/
|
||||
|
||||
#define VFE_MSG_STATS_WB_EXP 0x0009
|
||||
#define VFE_MSG_STATS_WB_EXP_LEN \
|
||||
sizeof(vfe_msg_stats_wb_exp)
|
||||
|
||||
typedef struct {
|
||||
unsigned int wb_exp_stats_op_buf;
|
||||
} __attribute__((packed)) vfe_msg_stats_wb_exp;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that histogram(hg) stats are ready
|
||||
*/
|
||||
|
||||
#define VFE_MSG_STATS_HG 0x000A
|
||||
#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg)
|
||||
|
||||
typedef struct {
|
||||
unsigned int hg_stats_op_buf;
|
||||
} __attribute__((packed)) vfe_msg_stats_hg;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that epoch1 event occurred in the CAMIF
|
||||
*/
|
||||
|
||||
#define VFE_MSG_EPOCH1 0x000B
|
||||
#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_epoch1;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that epoch2 event occurred in the CAMIF
|
||||
*/
|
||||
|
||||
#define VFE_MSG_EPOCH2 0x000C
|
||||
#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_epoch2;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that sync timer1 op is completed
|
||||
*/
|
||||
|
||||
#define VFE_MSG_SYNC_T1_DONE 0x000D
|
||||
#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_sync_t1_done;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that sync timer2 op is completed
|
||||
*/
|
||||
|
||||
#define VFE_MSG_SYNC_T2_DONE 0x000E
|
||||
#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_sync_t2_done;
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that async t1 operation completed
|
||||
*/
|
||||
|
||||
#define VFE_MSG_ASYNC_T1_DONE 0x000F
|
||||
#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_async_t1_done;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that async t2 operation completed
|
||||
*/
|
||||
|
||||
#define VFE_MSG_ASYNC_T2_DONE 0x0010
|
||||
#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done)
|
||||
|
||||
typedef struct {
|
||||
} __attribute__((packed)) vfe_msg_async_t2_done;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Message to notify the ARM that an error has occurred
|
||||
*/
|
||||
|
||||
#define VFE_MSG_ERROR 0x0011
|
||||
#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error)
|
||||
|
||||
#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000
|
||||
#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001
|
||||
#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002
|
||||
#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004
|
||||
#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008
|
||||
#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010
|
||||
#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020
|
||||
#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000
|
||||
#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040
|
||||
#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000
|
||||
#define VFE_MSG_ERR_COND_AXI_ERR 0x0080
|
||||
|
||||
#define VFE_MSG_CAMIF_STS_IDLE 0x0000
|
||||
#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001
|
||||
|
||||
typedef struct {
|
||||
unsigned int err_cond;
|
||||
unsigned int camif_sts;
|
||||
} __attribute__((packed)) vfe_msg_error;
|
||||
|
||||
|
||||
#endif
|
|
@ -1,388 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#ifndef __LINUX_MSM_CAMERA_H
|
||||
#define __LINUX_MSM_CAMERA_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define MSM_CAM_IOCTL_MAGIC 'm'
|
||||
|
||||
#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
|
||||
_IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
|
||||
|
||||
#define MSM_CAM_IOCTL_REGISTER_PMEM \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
|
||||
|
||||
#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
|
||||
|
||||
#define MSM_CAM_IOCTL_CTRL_COMMAND \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_CONFIG_VFE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_GET_STATS \
|
||||
_IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
|
||||
|
||||
#define MSM_CAM_IOCTL_GETFRAME \
|
||||
_IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
|
||||
|
||||
#define MSM_CAM_IOCTL_ENABLE_VFE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_CONFIG_CMD \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_DISABLE_VFE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_VFE_APPS_RESET \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
|
||||
|
||||
#define MSM_CAM_IOCTL_AXI_CONFIG \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_GET_PICTURE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
|
||||
|
||||
#define MSM_CAM_IOCTL_SET_CROP \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
|
||||
|
||||
#define MSM_CAM_IOCTL_PICT_PP \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
|
||||
|
||||
#define MSM_CAM_IOCTL_PICT_PP_DONE \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
|
||||
|
||||
#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
|
||||
|
||||
#define MSM_CAMERA_LED_OFF 0
|
||||
#define MSM_CAMERA_LED_LOW 1
|
||||
#define MSM_CAMERA_LED_HIGH 2
|
||||
|
||||
#define MSM_CAM_IOCTL_FLASH_LED_CFG \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
|
||||
|
||||
#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
|
||||
_IO(MSM_CAM_IOCTL_MAGIC, 23)
|
||||
|
||||
#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
|
||||
_IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
|
||||
|
||||
#define MAX_SENSOR_NUM 3
|
||||
#define MAX_SENSOR_NAME 32
|
||||
|
||||
#define MSM_CAM_CTRL_CMD_DONE 0
|
||||
#define MSM_CAM_SENSOR_VFE_CMD 1
|
||||
|
||||
/*****************************************************
|
||||
* structure
|
||||
*****************************************************/
|
||||
|
||||
/* define five type of structures for userspace <==> kernel
|
||||
* space communication:
|
||||
* command 1 - 2 are from userspace ==> kernel
|
||||
* command 3 - 4 are from kernel ==> userspace
|
||||
*
|
||||
* 1. control command: control command(from control thread),
|
||||
* control status (from config thread);
|
||||
*/
|
||||
struct msm_ctrl_cmd {
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
uint16_t status;
|
||||
uint32_t timeout_ms;
|
||||
int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
|
||||
};
|
||||
|
||||
struct msm_vfe_evt_msg {
|
||||
unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
|
||||
unsigned short msg_id;
|
||||
unsigned int len; /* size in, number of bytes out */
|
||||
void *data;
|
||||
};
|
||||
|
||||
#define MSM_CAM_RESP_CTRL 0
|
||||
#define MSM_CAM_RESP_STAT_EVT_MSG 1
|
||||
#define MSM_CAM_RESP_V4L2 2
|
||||
#define MSM_CAM_RESP_MAX 3
|
||||
|
||||
/* this one is used to send ctrl/status up to config thread */
|
||||
struct msm_stats_event_ctrl {
|
||||
/* 0 - ctrl_cmd from control thread,
|
||||
* 1 - stats/event kernel,
|
||||
* 2 - V4L control or read request */
|
||||
int resptype;
|
||||
int timeout_ms;
|
||||
struct msm_ctrl_cmd ctrl_cmd;
|
||||
/* struct vfe_event_t stats_event; */
|
||||
struct msm_vfe_evt_msg stats_event;
|
||||
};
|
||||
|
||||
/* 2. config command: config command(from config thread); */
|
||||
struct msm_camera_cfg_cmd {
|
||||
/* what to config:
|
||||
* 1 - sensor config, 2 - vfe config */
|
||||
uint16_t cfg_type;
|
||||
|
||||
/* sensor config type */
|
||||
uint16_t cmd_type;
|
||||
uint16_t queue;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
#define CMD_GENERAL 0
|
||||
#define CMD_AXI_CFG_OUT1 1
|
||||
#define CMD_AXI_CFG_SNAP_O1_AND_O2 2
|
||||
#define CMD_AXI_CFG_OUT2 3
|
||||
#define CMD_PICT_T_AXI_CFG 4
|
||||
#define CMD_PICT_M_AXI_CFG 5
|
||||
#define CMD_RAW_PICT_AXI_CFG 6
|
||||
#define CMD_STATS_AXI_CFG 7
|
||||
#define CMD_STATS_AF_AXI_CFG 8
|
||||
#define CMD_FRAME_BUF_RELEASE 9
|
||||
#define CMD_PREV_BUF_CFG 10
|
||||
#define CMD_SNAP_BUF_RELEASE 11
|
||||
#define CMD_SNAP_BUF_CFG 12
|
||||
#define CMD_STATS_DISABLE 13
|
||||
#define CMD_STATS_ENABLE 14
|
||||
#define CMD_STATS_AF_ENABLE 15
|
||||
#define CMD_STATS_BUF_RELEASE 16
|
||||
#define CMD_STATS_AF_BUF_RELEASE 17
|
||||
#define UPDATE_STATS_INVALID 18
|
||||
|
||||
/* vfe config command: config command(from config thread)*/
|
||||
struct msm_vfe_cfg_cmd {
|
||||
int cmd_type;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
#define MAX_CAMERA_ENABLE_NAME_LEN 32
|
||||
struct camera_enable_cmd {
|
||||
char name[MAX_CAMERA_ENABLE_NAME_LEN];
|
||||
};
|
||||
|
||||
#define MSM_PMEM_OUTPUT1 0
|
||||
#define MSM_PMEM_OUTPUT2 1
|
||||
#define MSM_PMEM_OUTPUT1_OUTPUT2 2
|
||||
#define MSM_PMEM_THUMBAIL 3
|
||||
#define MSM_PMEM_MAINIMG 4
|
||||
#define MSM_PMEM_RAW_MAINIMG 5
|
||||
#define MSM_PMEM_AEC_AWB 6
|
||||
#define MSM_PMEM_AF 7
|
||||
#define MSM_PMEM_MAX 8
|
||||
|
||||
#define FRAME_PREVIEW_OUTPUT1 0
|
||||
#define FRAME_PREVIEW_OUTPUT2 1
|
||||
#define FRAME_SNAPSHOT 2
|
||||
#define FRAME_THUMBAIL 3
|
||||
#define FRAME_RAW_SNAPSHOT 4
|
||||
#define FRAME_MAX 5
|
||||
|
||||
struct msm_pmem_info {
|
||||
int type;
|
||||
int fd;
|
||||
void *vaddr;
|
||||
uint32_t y_off;
|
||||
uint32_t cbcr_off;
|
||||
uint8_t active;
|
||||
};
|
||||
|
||||
struct outputCfg {
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
|
||||
uint32_t window_height_firstline;
|
||||
uint32_t window_height_lastline;
|
||||
};
|
||||
|
||||
#define OUTPUT_1 0
|
||||
#define OUTPUT_2 1
|
||||
#define OUTPUT_1_AND_2 2
|
||||
#define CAMIF_TO_AXI_VIA_OUTPUT_2 3
|
||||
#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
|
||||
#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
|
||||
#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
|
||||
|
||||
#define MSM_FRAME_PREV_1 0
|
||||
#define MSM_FRAME_PREV_2 1
|
||||
#define MSM_FRAME_ENC 2
|
||||
|
||||
struct msm_frame {
|
||||
int path;
|
||||
unsigned long buffer;
|
||||
uint32_t y_off;
|
||||
uint32_t cbcr_off;
|
||||
int fd;
|
||||
|
||||
void *cropinfo;
|
||||
int croplen;
|
||||
};
|
||||
|
||||
#define STAT_AEAW 0
|
||||
#define STAT_AF 1
|
||||
#define STAT_MAX 2
|
||||
|
||||
struct msm_stats_buf {
|
||||
int type;
|
||||
unsigned long buffer;
|
||||
int fd;
|
||||
};
|
||||
|
||||
#define MSM_V4L2_VID_CAP_TYPE 0
|
||||
#define MSM_V4L2_STREAM_ON 1
|
||||
#define MSM_V4L2_STREAM_OFF 2
|
||||
#define MSM_V4L2_SNAPSHOT 3
|
||||
#define MSM_V4L2_QUERY_CTRL 4
|
||||
#define MSM_V4L2_GET_CTRL 5
|
||||
#define MSM_V4L2_SET_CTRL 6
|
||||
#define MSM_V4L2_QUERY 7
|
||||
#define MSM_V4L2_MAX 8
|
||||
|
||||
struct crop_info {
|
||||
void *info;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct msm_postproc {
|
||||
int ftnum;
|
||||
struct msm_frame fthumnail;
|
||||
int fmnum;
|
||||
struct msm_frame fmain;
|
||||
};
|
||||
|
||||
struct msm_snapshot_pp_status {
|
||||
void *status;
|
||||
};
|
||||
|
||||
#define CFG_SET_MODE 0
|
||||
#define CFG_SET_EFFECT 1
|
||||
#define CFG_START 2
|
||||
#define CFG_PWR_UP 3
|
||||
#define CFG_PWR_DOWN 4
|
||||
#define CFG_WRITE_EXPOSURE_GAIN 5
|
||||
#define CFG_SET_DEFAULT_FOCUS 6
|
||||
#define CFG_MOVE_FOCUS 7
|
||||
#define CFG_REGISTER_TO_REAL_GAIN 8
|
||||
#define CFG_REAL_TO_REGISTER_GAIN 9
|
||||
#define CFG_SET_FPS 10
|
||||
#define CFG_SET_PICT_FPS 11
|
||||
#define CFG_SET_BRIGHTNESS 12
|
||||
#define CFG_SET_CONTRAST 13
|
||||
#define CFG_SET_ZOOM 14
|
||||
#define CFG_SET_EXPOSURE_MODE 15
|
||||
#define CFG_SET_WB 16
|
||||
#define CFG_SET_ANTIBANDING 17
|
||||
#define CFG_SET_EXP_GAIN 18
|
||||
#define CFG_SET_PICT_EXP_GAIN 19
|
||||
#define CFG_SET_LENS_SHADING 20
|
||||
#define CFG_GET_PICT_FPS 21
|
||||
#define CFG_GET_PREV_L_PF 22
|
||||
#define CFG_GET_PREV_P_PL 23
|
||||
#define CFG_GET_PICT_L_PF 24
|
||||
#define CFG_GET_PICT_P_PL 25
|
||||
#define CFG_GET_AF_MAX_STEPS 26
|
||||
#define CFG_GET_PICT_MAX_EXP_LC 27
|
||||
#define CFG_MAX 28
|
||||
|
||||
#define MOVE_NEAR 0
|
||||
#define MOVE_FAR 1
|
||||
|
||||
#define SENSOR_PREVIEW_MODE 0
|
||||
#define SENSOR_SNAPSHOT_MODE 1
|
||||
#define SENSOR_RAW_SNAPSHOT_MODE 2
|
||||
|
||||
#define SENSOR_QTR_SIZE 0
|
||||
#define SENSOR_FULL_SIZE 1
|
||||
#define SENSOR_INVALID_SIZE 2
|
||||
|
||||
#define CAMERA_EFFECT_OFF 0
|
||||
#define CAMERA_EFFECT_MONO 1
|
||||
#define CAMERA_EFFECT_NEGATIVE 2
|
||||
#define CAMERA_EFFECT_SOLARIZE 3
|
||||
#define CAMERA_EFFECT_PASTEL 4
|
||||
#define CAMERA_EFFECT_MOSAIC 5
|
||||
#define CAMERA_EFFECT_RESIZE 6
|
||||
#define CAMERA_EFFECT_SEPIA 7
|
||||
#define CAMERA_EFFECT_POSTERIZE 8
|
||||
#define CAMERA_EFFECT_WHITEBOARD 9
|
||||
#define CAMERA_EFFECT_BLACKBOARD 10
|
||||
#define CAMERA_EFFECT_AQUA 11
|
||||
#define CAMERA_EFFECT_MAX 12
|
||||
|
||||
struct sensor_pict_fps {
|
||||
uint16_t prevfps;
|
||||
uint16_t pictfps;
|
||||
};
|
||||
|
||||
struct exp_gain_cfg {
|
||||
uint16_t gain;
|
||||
uint32_t line;
|
||||
};
|
||||
|
||||
struct focus_cfg {
|
||||
int32_t steps;
|
||||
int dir;
|
||||
};
|
||||
|
||||
struct fps_cfg {
|
||||
uint16_t f_mult;
|
||||
uint16_t fps_div;
|
||||
uint32_t pict_fps_div;
|
||||
};
|
||||
|
||||
struct sensor_cfg_data {
|
||||
int cfgtype;
|
||||
int mode;
|
||||
int rs;
|
||||
uint8_t max_steps;
|
||||
|
||||
union {
|
||||
int8_t effect;
|
||||
uint8_t lens_shading;
|
||||
uint16_t prevl_pf;
|
||||
uint16_t prevp_pl;
|
||||
uint16_t pictl_pf;
|
||||
uint16_t pictp_pl;
|
||||
uint32_t pict_max_exp_lc;
|
||||
uint16_t p_fps;
|
||||
struct sensor_pict_fps gfps;
|
||||
struct exp_gain_cfg exp_gain;
|
||||
struct focus_cfg focus;
|
||||
struct fps_cfg fps;
|
||||
} cfg;
|
||||
};
|
||||
|
||||
#define GET_NAME 0
|
||||
#define GET_PREVIEW_LINE_PER_FRAME 1
|
||||
#define GET_PREVIEW_PIXELS_PER_LINE 2
|
||||
#define GET_SNAPSHOT_LINE_PER_FRAME 3
|
||||
#define GET_SNAPSHOT_PIXELS_PER_LINE 4
|
||||
#define GET_SNAPSHOT_FPS 5
|
||||
#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6
|
||||
|
||||
struct msm_camsensor_info {
|
||||
char name[MAX_SENSOR_NAME];
|
||||
uint8_t flash_enabled;
|
||||
};
|
||||
#endif /* __LINUX_MSM_CAMERA_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,18 +0,0 @@
|
|||
ccflags-y:=-Idrivers/staging/dream/include
|
||||
obj-y += adsp.o
|
||||
ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
|
||||
obj-y += adsp_info.o
|
||||
obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o
|
||||
else
|
||||
obj-y += adsp_6225.o
|
||||
endif
|
||||
|
||||
obj-y += adsp_driver.o
|
||||
obj-y += adsp_video_verify_cmd.o
|
||||
obj-y += adsp_videoenc_verify_cmd.o
|
||||
obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o
|
||||
obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o
|
||||
obj-y += adsp_lpm_verify_cmd.o
|
||||
obj-y += audio_out.o audio_in.o audio_mp3.o audmgr.o audpp.o
|
||||
obj-y += snd.o
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,369 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp.h
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Author: Iliyan Malchev <ibm@android.com>
|
||||
*
|
||||
* 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_MSM_ADSP_H
|
||||
#define _ARCH_ARM_MACH_MSM_ADSP_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_adsp.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
|
||||
int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
|
||||
unsigned long len);
|
||||
int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
|
||||
unsigned long *kvaddr, unsigned long len);
|
||||
int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr);
|
||||
|
||||
int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size);
|
||||
int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size);
|
||||
int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size);
|
||||
int adsp_video_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size);
|
||||
int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size);
|
||||
|
||||
|
||||
struct adsp_event;
|
||||
|
||||
int adsp_vfe_patch_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event);
|
||||
|
||||
int adsp_jpeg_patch_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event);
|
||||
|
||||
|
||||
struct adsp_module_info {
|
||||
const char *name;
|
||||
const char *pdev_name;
|
||||
uint32_t id;
|
||||
const char *clk_name;
|
||||
unsigned long clk_rate;
|
||||
int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
|
||||
size_t);
|
||||
int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
|
||||
};
|
||||
|
||||
#define ADSP_EVENT_MAX_SIZE 496
|
||||
#define EVENT_LEN 12
|
||||
#define EVENT_MSG_ID ((uint16_t)~0)
|
||||
|
||||
struct adsp_event {
|
||||
struct list_head list;
|
||||
uint32_t size; /* always in bytes */
|
||||
uint16_t msg_id;
|
||||
uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */
|
||||
int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */
|
||||
union {
|
||||
uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2];
|
||||
uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4];
|
||||
} data;
|
||||
};
|
||||
|
||||
struct adsp_info {
|
||||
uint32_t send_irq;
|
||||
uint32_t read_ctrl;
|
||||
uint32_t write_ctrl;
|
||||
|
||||
uint32_t max_msg16_size;
|
||||
uint32_t max_msg32_size;
|
||||
|
||||
uint32_t max_task_id;
|
||||
uint32_t max_module_id;
|
||||
uint32_t max_queue_id;
|
||||
uint32_t max_image_id;
|
||||
|
||||
/* for each image id, a map of queue id to offset */
|
||||
uint32_t **queue_offset;
|
||||
|
||||
/* for each image id, a map of task id to module id */
|
||||
uint32_t **task_to_module;
|
||||
|
||||
/* for each module id, map of module id to module */
|
||||
struct msm_adsp_module **id_to_module;
|
||||
|
||||
uint32_t module_count;
|
||||
struct adsp_module_info *module;
|
||||
|
||||
/* stats */
|
||||
uint32_t events_received;
|
||||
uint32_t event_backlog_max;
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
/* rpc_client for init_info */
|
||||
struct msm_rpc_endpoint *init_info_rpc_client;
|
||||
struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr;
|
||||
wait_queue_head_t init_info_wait;
|
||||
unsigned init_info_state;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define RPC_ADSP_RTOS_ATOM_PROG 0x3000000a
|
||||
#define RPC_ADSP_RTOS_MTOA_PROG 0x3000000b
|
||||
#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0
|
||||
#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0
|
||||
#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2
|
||||
#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(1,0)
|
||||
#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(2,1) /* must be actual vers */
|
||||
#define MSM_ADSP_DRIVER_NAME "rs3000000a:00010000"
|
||||
#elif (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225)
|
||||
#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x71d1094b, 0)
|
||||
#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0xee3a9966, 0)
|
||||
#define MSM_ADSP_DRIVER_NAME "rs3000000a:71d1094b"
|
||||
#elif CONFIG_MSM_AMSS_VERSION == 6210
|
||||
#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x20f17fd3, 0)
|
||||
#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0x75babbd6, 0)
|
||||
#define MSM_ADSP_DRIVER_NAME "rs3000000a:20f17fd3"
|
||||
#else
|
||||
#error "Unknown AMSS version"
|
||||
#endif
|
||||
|
||||
enum rpc_adsp_rtos_proc_type {
|
||||
RPC_ADSP_RTOS_PROC_NONE = 0,
|
||||
RPC_ADSP_RTOS_PROC_MODEM = 1,
|
||||
RPC_ADSP_RTOS_PROC_APPS = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
RPC_ADSP_RTOS_CMD_REGISTER_APP,
|
||||
RPC_ADSP_RTOS_CMD_ENABLE,
|
||||
RPC_ADSP_RTOS_CMD_DISABLE,
|
||||
RPC_ADSP_RTOS_CMD_KERNEL_COMMAND,
|
||||
RPC_ADSP_RTOS_CMD_16_COMMAND,
|
||||
RPC_ADSP_RTOS_CMD_32_COMMAND,
|
||||
RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP,
|
||||
RPC_ADSP_RTOS_CMD_REMOTE_EVENT,
|
||||
RPC_ADSP_RTOS_CMD_SET_STATE,
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
|
||||
RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum rpc_adsp_rtos_mod_status_type {
|
||||
RPC_ADSP_RTOS_MOD_READY,
|
||||
RPC_ADSP_RTOS_MOD_DISABLE,
|
||||
RPC_ADSP_RTOS_SERVICE_RESET,
|
||||
RPC_ADSP_RTOS_CMD_FAIL,
|
||||
RPC_ADSP_RTOS_CMD_SUCCESS,
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
RPC_ADSP_RTOS_INIT_INFO,
|
||||
RPC_ADSP_RTOS_DISABLE_FAIL,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rpc_adsp_rtos_app_to_modem_args_t {
|
||||
struct rpc_request_hdr hdr;
|
||||
uint32_t gotit; /* if 1, the next elements are present */
|
||||
uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
|
||||
uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
|
||||
uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
|
||||
};
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
enum qdsp_image_type {
|
||||
QDSP_IMAGE_COMBO,
|
||||
QDSP_IMAGE_GAUDIO,
|
||||
QDSP_IMAGE_QTV_LP,
|
||||
QDSP_IMAGE_MAX,
|
||||
/* DO NOT USE: Force this enum to be a 32bit type to improve speed */
|
||||
QDSP_IMAGE_32BIT_DUMMY = 0x10000
|
||||
};
|
||||
|
||||
struct adsp_rtos_mp_mtoa_header_type {
|
||||
enum rpc_adsp_rtos_mod_status_type event;
|
||||
enum rpc_adsp_rtos_proc_type proc_id;
|
||||
};
|
||||
|
||||
/* ADSP RTOS MP Communications - Modem to APP's Event Info*/
|
||||
struct adsp_rtos_mp_mtoa_type {
|
||||
uint32_t module;
|
||||
uint32_t image;
|
||||
uint32_t apps_okts;
|
||||
};
|
||||
|
||||
/* ADSP RTOS MP Communications - Modem to APP's Init Info */
|
||||
#define IMG_MAX 8
|
||||
#define ENTRIES_MAX 64
|
||||
|
||||
struct queue_to_offset_type {
|
||||
uint32_t queue;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct adsp_rtos_mp_mtoa_init_info_type {
|
||||
uint32_t image_count;
|
||||
uint32_t num_queue_offsets;
|
||||
struct queue_to_offset_type queue_offsets_tbl[IMG_MAX][ENTRIES_MAX];
|
||||
uint32_t num_task_module_entries;
|
||||
uint32_t task_to_module_tbl[IMG_MAX][ENTRIES_MAX];
|
||||
|
||||
uint32_t module_table_size;
|
||||
uint32_t module_entries[ENTRIES_MAX];
|
||||
/*
|
||||
* queue_offsets[] is to store only queue_offsets
|
||||
*/
|
||||
uint32_t queue_offsets[IMG_MAX][ENTRIES_MAX];
|
||||
};
|
||||
|
||||
struct adsp_rtos_mp_mtoa_s_type {
|
||||
struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header;
|
||||
|
||||
uint32_t desc_field;
|
||||
union {
|
||||
struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet;
|
||||
struct adsp_rtos_mp_mtoa_type mp_mtoa_packet;
|
||||
} adsp_rtos_mp_mtoa_data;
|
||||
};
|
||||
|
||||
struct rpc_adsp_rtos_modem_to_app_args_t {
|
||||
struct rpc_request_hdr hdr;
|
||||
uint32_t gotit; /* if 1, the next elements are present */
|
||||
struct adsp_rtos_mp_mtoa_s_type mtoa_pkt;
|
||||
};
|
||||
#else
|
||||
struct rpc_adsp_rtos_modem_to_app_args_t {
|
||||
struct rpc_request_hdr hdr;
|
||||
uint32_t gotit; /* if 1, the next elements are present */
|
||||
uint32_t event; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
|
||||
uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
|
||||
uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
|
||||
uint32_t image; /* RPC_QDSP_IMAGE_GAUDIO */
|
||||
};
|
||||
#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
|
||||
|
||||
#define ADSP_STATE_DISABLED 0
|
||||
#define ADSP_STATE_ENABLING 1
|
||||
#define ADSP_STATE_ENABLED 2
|
||||
#define ADSP_STATE_DISABLING 3
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
#define ADSP_STATE_INIT_INFO 4
|
||||
#endif
|
||||
|
||||
struct msm_adsp_module {
|
||||
struct mutex lock;
|
||||
const char *name;
|
||||
unsigned id;
|
||||
struct adsp_info *info;
|
||||
|
||||
struct msm_rpc_endpoint *rpc_client;
|
||||
struct msm_adsp_ops *ops;
|
||||
void *driver_data;
|
||||
|
||||
/* statistics */
|
||||
unsigned num_commands;
|
||||
unsigned num_events;
|
||||
|
||||
wait_queue_head_t state_wait;
|
||||
unsigned state;
|
||||
|
||||
struct platform_device pdev;
|
||||
struct clk *clk;
|
||||
int open_count;
|
||||
|
||||
struct mutex pmem_regions_lock;
|
||||
struct hlist_head pmem_regions;
|
||||
int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
|
||||
size_t);
|
||||
int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
|
||||
};
|
||||
|
||||
extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned);
|
||||
extern int adsp_init_info(struct adsp_info *info);
|
||||
|
||||
/* Value to indicate that a queue is not defined for a particular image */
|
||||
#if CONFIG_MSM_AMSS_VERSION >= 6350
|
||||
#define QDSP_RTOS_NO_QUEUE 0xfffffffe
|
||||
#else
|
||||
#define QDSP_RTOS_NO_QUEUE 0xffffffff
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constants used to communicate with the ADSP RTOS
|
||||
*/
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M 0x80000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V 0x80000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V 0x00000000U
|
||||
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M 0x70000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V 0x00000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V 0x10000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V 0x70000000U
|
||||
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M 0x0E000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V 0x00000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V 0x02000000U
|
||||
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M 0x01000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V 0x00000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V 0x01000000U
|
||||
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M 0x00FFFFFFU
|
||||
|
||||
/* Combination of MUTEX and CMD bits to check if the DSP is busy */
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M 0xF0000000U
|
||||
#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V 0x70000000U
|
||||
|
||||
/* RTOS to Host processor command mask values */
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M 0x80000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V 0x00000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V 0x80000000U
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CMD_M 0x60000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V 0x00000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V 0x20000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V 0x60000000U
|
||||
|
||||
/* Combination of FLAG and COMMAND bits to check if MSG ready */
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_READY_M 0xE0000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_READY_V 0xA0000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CONT_V 0xC0000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_DONE_V 0xE0000000U
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M 0x18000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V 0x00000000U
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M 0x04000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V 0x00000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V 0x04000000U
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M 0x03000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V 0x00000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V 0x01000000U
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU
|
||||
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M 0x000000FFU
|
||||
#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M 0x0000FF00U
|
||||
|
||||
/* Base address of DSP and DSP hardware registers */
|
||||
#define QDSP_RAMC_OFFSET 0x400000
|
||||
|
||||
#endif /* _ARCH_ARM_MACH_MSM_ADSP_H */
|
|
@ -1,283 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_6210.h
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated.
|
||||
*
|
||||
* 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 "adsp.h"
|
||||
|
||||
/* Firmware modules */
|
||||
typedef enum {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEO_AAC_VOC,
|
||||
QDSP_MODULE_PCM_DEC,
|
||||
QDSP_MODULE_AUDIO_DEC_MP3,
|
||||
QDSP_MODULE_AUDIO_DEC_AAC,
|
||||
QDSP_MODULE_AUDIO_DEC_WMA,
|
||||
QDSP_MODULE_HOSTPCM,
|
||||
QDSP_MODULE_DTMF,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_SBC_ENC,
|
||||
QDSP_MODULE_VOC,
|
||||
QDSP_MODULE_VOC_PCM,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_WAV_ENC,
|
||||
QDSP_MODULE_AACLC_ENC,
|
||||
QDSP_MODULE_VIDEO_AMR,
|
||||
QDSP_MODULE_VOC_AMR,
|
||||
QDSP_MODULE_VOC_EVRC,
|
||||
QDSP_MODULE_VOC_13K,
|
||||
QDSP_MODULE_VOC_FGV,
|
||||
QDSP_MODULE_DIAGTASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_QCAMTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MIDI,
|
||||
QDSP_MODULE_GAUDIO,
|
||||
QDSP_MODULE_VDEC_LP_MODE,
|
||||
QDSP_MODULE_MAX,
|
||||
} qdsp_module_type;
|
||||
|
||||
#define QDSP_RTOS_MAX_TASK_ID 19U
|
||||
|
||||
/* Table of modules indexed by task ID for the GAUDIO image */
|
||||
static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the GAUDIO image */
|
||||
static uint32_t qdsp_gaudio_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x3be, /* QDSP_mpuAfeQueue */
|
||||
0x3ee, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x3c2, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x3c6, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x3ca, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x3da, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
0x3de, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
0x3e2, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
0x3e6, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
0x3ea, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x3ce, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x3d6, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x3d2, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the COMBO image */
|
||||
static qdsp_module_type qdsp_combo_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the COMBO image */
|
||||
static uint32_t qdsp_combo_queue_offset_table[] = {
|
||||
0x585, /* QDSP_lpmCommandQueue */
|
||||
0x52d, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
0x541, /* QDSP_mpuModmathCmdQueue */
|
||||
0x555, /* QDSP_mpuVDecCmdQueue */
|
||||
0x559, /* QDSP_mpuVDecPktQueue */
|
||||
0x551, /* QDSP_mpuVEncCmdQueue */
|
||||
0x535, /* QDSP_rxMpuDecCmdQueue */
|
||||
0x539, /* QDSP_rxMpuDecPktQueue */
|
||||
0x53d, /* QDSP_txMpuEncQueue */
|
||||
0x55d, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x561, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x565, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x575, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
0x579, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x569, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x571, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x56d, /* QDSP_uPAudRecCmdQueue */
|
||||
0x581, /* QDSP_uPJpegActionCmdQueue */
|
||||
0x57d, /* QDSP_uPJpegCfgCmdQueue */
|
||||
0x531, /* QDSP_uPVocProcQueue */
|
||||
0x545, /* QDSP_vfeCommandQueue */
|
||||
0x54d, /* QDSP_vfeCommandScaleQueue */
|
||||
0x549 /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the QTV_LP image */
|
||||
static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the QTV_LP image */
|
||||
static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x40c, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
0x410, /* QDSP_mpuVDecCmdQueue */
|
||||
0x414, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x41c, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x420, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x424, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x430, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x418, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x42c, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x428, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Tables to convert tasks to modules */
|
||||
static uint32_t *qdsp_task_to_module[] = {
|
||||
qdsp_combo_task_to_module_table,
|
||||
qdsp_gaudio_task_to_module_table,
|
||||
qdsp_qtv_lp_task_to_module_table,
|
||||
};
|
||||
|
||||
/* Tables to retrieve queue offsets */
|
||||
static uint32_t *qdsp_queue_offset_table[] = {
|
||||
qdsp_combo_queue_offset_table,
|
||||
qdsp_gaudio_queue_offset_table,
|
||||
qdsp_qtv_lp_queue_offset_table,
|
||||
};
|
||||
|
||||
#define QDSP_MODULE(n) \
|
||||
{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
|
||||
|
||||
static struct adsp_module_info module_info[] = {
|
||||
QDSP_MODULE(AUDPPTASK),
|
||||
QDSP_MODULE(AUDRECTASK),
|
||||
QDSP_MODULE(AUDPREPROCTASK),
|
||||
QDSP_MODULE(VFETASK),
|
||||
QDSP_MODULE(QCAMTASK),
|
||||
QDSP_MODULE(LPMTASK),
|
||||
QDSP_MODULE(JPEGTASK),
|
||||
QDSP_MODULE(VIDEOTASK),
|
||||
QDSP_MODULE(VDEC_LP_MODE),
|
||||
};
|
||||
|
||||
int adsp_init_info(struct adsp_info *info)
|
||||
{
|
||||
info->send_irq = 0x00c00200;
|
||||
info->read_ctrl = 0x00400038;
|
||||
info->write_ctrl = 0x00400034;
|
||||
|
||||
info->max_msg16_size = 193;
|
||||
info->max_msg32_size = 8;
|
||||
|
||||
info->max_task_id = 16;
|
||||
info->max_module_id = QDSP_MODULE_MAX - 1;
|
||||
info->max_queue_id = QDSP_QUEUE_MAX;
|
||||
info->max_image_id = 2;
|
||||
info->queue_offset = qdsp_queue_offset_table;
|
||||
info->task_to_module = qdsp_task_to_module;
|
||||
|
||||
info->module_count = ARRAY_SIZE(module_info);
|
||||
info->module = module_info;
|
||||
return 0;
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_6220.h
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated.
|
||||
*
|
||||
* 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 "adsp.h"
|
||||
|
||||
/* Firmware modules */
|
||||
typedef enum {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEO_AAC_VOC,
|
||||
QDSP_MODULE_PCM_DEC,
|
||||
QDSP_MODULE_AUDIO_DEC_MP3,
|
||||
QDSP_MODULE_AUDIO_DEC_AAC,
|
||||
QDSP_MODULE_AUDIO_DEC_WMA,
|
||||
QDSP_MODULE_HOSTPCM,
|
||||
QDSP_MODULE_DTMF,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_SBC_ENC,
|
||||
QDSP_MODULE_VOC,
|
||||
QDSP_MODULE_VOC_PCM,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_WAV_ENC,
|
||||
QDSP_MODULE_AACLC_ENC,
|
||||
QDSP_MODULE_VIDEO_AMR,
|
||||
QDSP_MODULE_VOC_AMR,
|
||||
QDSP_MODULE_VOC_EVRC,
|
||||
QDSP_MODULE_VOC_13K,
|
||||
QDSP_MODULE_VOC_FGV,
|
||||
QDSP_MODULE_DIAGTASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_QCAMTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MIDI,
|
||||
QDSP_MODULE_GAUDIO,
|
||||
QDSP_MODULE_VDEC_LP_MODE,
|
||||
QDSP_MODULE_MAX,
|
||||
} qdsp_module_type;
|
||||
|
||||
#define QDSP_RTOS_MAX_TASK_ID 19U
|
||||
|
||||
/* Table of modules indexed by task ID for the GAUDIO image */
|
||||
static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the GAUDIO image */
|
||||
static uint32_t qdsp_gaudio_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x3f0, /* QDSP_mpuAfeQueue */
|
||||
0x420, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x3f4, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x3f8, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x3fc, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x400, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x408, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x404, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the COMBO image */
|
||||
static qdsp_module_type qdsp_combo_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the COMBO image */
|
||||
static uint32_t qdsp_combo_queue_offset_table[] = {
|
||||
0x6f2, /* QDSP_lpmCommandQueue */
|
||||
0x69e, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
0x6b2, /* QDSP_mpuModmathCmdQueue */
|
||||
0x6c6, /* QDSP_mpuVDecCmdQueue */
|
||||
0x6ca, /* QDSP_mpuVDecPktQueue */
|
||||
0x6c2, /* QDSP_mpuVEncCmdQueue */
|
||||
0x6a6, /* QDSP_rxMpuDecCmdQueue */
|
||||
0x6aa, /* QDSP_rxMpuDecPktQueue */
|
||||
0x6ae, /* QDSP_txMpuEncQueue */
|
||||
0x6ce, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x6d2, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x6d6, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x6e6, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x6da, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x6e2, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x6de, /* QDSP_uPAudRecCmdQueue */
|
||||
0x6ee, /* QDSP_uPJpegActionCmdQueue */
|
||||
0x6ea, /* QDSP_uPJpegCfgCmdQueue */
|
||||
0x6a2, /* QDSP_uPVocProcQueue */
|
||||
0x6b6, /* QDSP_vfeCommandQueue */
|
||||
0x6be, /* QDSP_vfeCommandScaleQueue */
|
||||
0x6ba /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the QTV_LP image */
|
||||
static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the QTV_LP image */
|
||||
static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x430, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
0x434, /* QDSP_mpuVDecCmdQueue */
|
||||
0x438, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x440, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x444, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x448, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x454, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x43c, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x450, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x44c, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
|
||||
};
|
||||
|
||||
/* Tables to convert tasks to modules */
|
||||
static qdsp_module_type *qdsp_task_to_module[] = {
|
||||
qdsp_combo_task_to_module_table,
|
||||
qdsp_gaudio_task_to_module_table,
|
||||
qdsp_qtv_lp_task_to_module_table,
|
||||
};
|
||||
|
||||
/* Tables to retrieve queue offsets */
|
||||
static uint32_t *qdsp_queue_offset_table[] = {
|
||||
qdsp_combo_queue_offset_table,
|
||||
qdsp_gaudio_queue_offset_table,
|
||||
qdsp_qtv_lp_queue_offset_table,
|
||||
};
|
||||
|
||||
#define QDSP_MODULE(n) \
|
||||
{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
|
||||
|
||||
static struct adsp_module_info module_info[] = {
|
||||
QDSP_MODULE(AUDPLAY0TASK),
|
||||
QDSP_MODULE(AUDPPTASK),
|
||||
QDSP_MODULE(AUDPREPROCTASK),
|
||||
QDSP_MODULE(AUDRECTASK),
|
||||
QDSP_MODULE(VFETASK),
|
||||
QDSP_MODULE(QCAMTASK),
|
||||
QDSP_MODULE(LPMTASK),
|
||||
QDSP_MODULE(JPEGTASK),
|
||||
QDSP_MODULE(VIDEOTASK),
|
||||
QDSP_MODULE(VDEC_LP_MODE),
|
||||
};
|
||||
|
||||
int adsp_init_info(struct adsp_info *info)
|
||||
{
|
||||
info->send_irq = 0x00c00200;
|
||||
info->read_ctrl = 0x00400038;
|
||||
info->write_ctrl = 0x00400034;
|
||||
|
||||
info->max_msg16_size = 193;
|
||||
info->max_msg32_size = 8;
|
||||
|
||||
info->max_task_id = 16;
|
||||
info->max_module_id = QDSP_MODULE_MAX - 1;
|
||||
info->max_queue_id = QDSP_QUEUE_MAX;
|
||||
info->max_image_id = 2;
|
||||
info->queue_offset = qdsp_queue_offset_table;
|
||||
info->task_to_module = qdsp_task_to_module;
|
||||
|
||||
info->module_count = ARRAY_SIZE(module_info);
|
||||
info->module = module_info;
|
||||
return 0;
|
||||
}
|
|
@ -1,328 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_6225.h
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated.
|
||||
*
|
||||
* 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 "adsp.h"
|
||||
|
||||
/* Firmware modules */
|
||||
typedef enum {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEO_AAC_VOC,
|
||||
QDSP_MODULE_PCM_DEC,
|
||||
QDSP_MODULE_AUDIO_DEC_MP3,
|
||||
QDSP_MODULE_AUDIO_DEC_AAC,
|
||||
QDSP_MODULE_AUDIO_DEC_WMA,
|
||||
QDSP_MODULE_HOSTPCM,
|
||||
QDSP_MODULE_DTMF,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_SBC_ENC,
|
||||
QDSP_MODULE_VOC_UMTS,
|
||||
QDSP_MODULE_VOC_CDMA,
|
||||
QDSP_MODULE_VOC_PCM,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_WAV_ENC,
|
||||
QDSP_MODULE_AACLC_ENC,
|
||||
QDSP_MODULE_VIDEO_AMR,
|
||||
QDSP_MODULE_VOC_AMR,
|
||||
QDSP_MODULE_VOC_EVRC,
|
||||
QDSP_MODULE_VOC_13K,
|
||||
QDSP_MODULE_VOC_FGV,
|
||||
QDSP_MODULE_DIAGTASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_QCAMTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MIDI,
|
||||
QDSP_MODULE_GAUDIO,
|
||||
QDSP_MODULE_VDEC_LP_MODE,
|
||||
QDSP_MODULE_MAX,
|
||||
} qdsp_module_type;
|
||||
|
||||
#define QDSP_RTOS_MAX_TASK_ID 30U
|
||||
|
||||
/* Table of modules indexed by task ID for the GAUDIO image */
|
||||
static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_AUDPLAY2TASK,
|
||||
QDSP_MODULE_AUDPLAY3TASK,
|
||||
QDSP_MODULE_AUDPLAY4TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_GRAPHICSTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the GAUDIO image */
|
||||
static uint32_t qdsp_gaudio_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x3f0, /* QDSP_mpuAfeQueue */
|
||||
0x420, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x3f4, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x3f8, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x3fc, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x400, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x408, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x404, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the COMBO image */
|
||||
static qdsp_module_type qdsp_combo_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_VOCDECTASK,
|
||||
QDSP_MODULE_VOCENCTASK,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_VIDEOENCTASK,
|
||||
QDSP_MODULE_VOICEPROCTASK,
|
||||
QDSP_MODULE_VFETASK,
|
||||
QDSP_MODULE_JPEGTASK,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_AUDPLAY1TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_LPMTASK,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MODMATHTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_DIAGTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the COMBO image */
|
||||
static uint32_t qdsp_combo_queue_offset_table[] = {
|
||||
0x714, /* QDSP_lpmCommandQueue */
|
||||
0x6bc, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
0x6d0, /* QDSP_mpuModmathCmdQueue */
|
||||
0x6e8, /* QDSP_mpuVDecCmdQueue */
|
||||
0x6ec, /* QDSP_mpuVDecPktQueue */
|
||||
0x6e4, /* QDSP_mpuVEncCmdQueue */
|
||||
0x6c4, /* QDSP_rxMpuDecCmdQueue */
|
||||
0x6c8, /* QDSP_rxMpuDecPktQueue */
|
||||
0x6cc, /* QDSP_txMpuEncQueue */
|
||||
0x6f0, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x6f4, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x6f8, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x708, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x6fc, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x704, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x700, /* QDSP_uPAudRecCmdQueue */
|
||||
0x710, /* QDSP_uPJpegActionCmdQueue */
|
||||
0x70c, /* QDSP_uPJpegCfgCmdQueue */
|
||||
0x6c0, /* QDSP_uPVocProcQueue */
|
||||
0x6d8, /* QDSP_vfeCommandQueue */
|
||||
0x6e0, /* QDSP_vfeCommandScaleQueue */
|
||||
0x6dc, /* QDSP_vfeCommandTableQueue */
|
||||
0x6d4, /* QDSP_uPDiagQueue */
|
||||
};
|
||||
|
||||
/* Table of modules indexed by task ID for the QTV_LP image */
|
||||
static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
|
||||
QDSP_MODULE_KERNEL,
|
||||
QDSP_MODULE_AFETASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_VIDEOTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDPPTASK,
|
||||
QDSP_MODULE_AUDPLAY0TASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_AUDRECTASK,
|
||||
QDSP_MODULE_AUDPREPROCTASK,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
QDSP_MODULE_MAX,
|
||||
};
|
||||
|
||||
/* Queue offset table indexed by queue ID for the QTV_LP image */
|
||||
static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
|
||||
0x3fe, /* QDSP_mpuAfeQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
|
||||
0x402, /* QDSP_mpuVDecCmdQueue */
|
||||
0x406, /* QDSP_mpuVDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
|
||||
0x40e, /* QDSP_uPAudPPCmd1Queue */
|
||||
0x412, /* QDSP_uPAudPPCmd2Queue */
|
||||
0x416, /* QDSP_uPAudPPCmd3Queue */
|
||||
0x422, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
|
||||
0x40a, /* QDSP_uPAudPreProcCmdQueue */
|
||||
0x41e, /* QDSP_uPAudRecBitStreamQueue */
|
||||
0x41a, /* QDSP_uPAudRecCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */
|
||||
QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */
|
||||
};
|
||||
|
||||
/* Tables to convert tasks to modules */
|
||||
static qdsp_module_type *qdsp_task_to_module[] = {
|
||||
qdsp_combo_task_to_module_table,
|
||||
qdsp_gaudio_task_to_module_table,
|
||||
qdsp_qtv_lp_task_to_module_table,
|
||||
};
|
||||
|
||||
/* Tables to retrieve queue offsets */
|
||||
static uint32_t *qdsp_queue_offset_table[] = {
|
||||
qdsp_combo_queue_offset_table,
|
||||
qdsp_gaudio_queue_offset_table,
|
||||
qdsp_qtv_lp_queue_offset_table,
|
||||
};
|
||||
|
||||
#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
|
||||
{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
|
||||
.clk_name = clkname, .clk_rate = clkrate, \
|
||||
.verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
|
||||
|
||||
static struct adsp_module_info module_info[] = {
|
||||
QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
|
||||
adsp_vfe_patch_event),
|
||||
QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
|
||||
QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd,
|
||||
adsp_jpeg_patch_event),
|
||||
QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
|
||||
adsp_video_verify_cmd, NULL),
|
||||
QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
|
||||
adsp_videoenc_verify_cmd, NULL),
|
||||
};
|
||||
|
||||
int adsp_init_info(struct adsp_info *info)
|
||||
{
|
||||
info->send_irq = 0x00c00200;
|
||||
info->read_ctrl = 0x00400038;
|
||||
info->write_ctrl = 0x00400034;
|
||||
|
||||
info->max_msg16_size = 193;
|
||||
info->max_msg32_size = 8;
|
||||
|
||||
info->max_task_id = 16;
|
||||
info->max_module_id = QDSP_MODULE_MAX - 1;
|
||||
info->max_queue_id = QDSP_QUEUE_MAX;
|
||||
info->max_image_id = 2;
|
||||
info->queue_offset = qdsp_queue_offset_table;
|
||||
info->task_to_module = qdsp_task_to_module;
|
||||
|
||||
info->module_count = ARRAY_SIZE(module_info);
|
||||
info->module = module_info;
|
||||
return 0;
|
||||
}
|
|
@ -1,643 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_driver.c
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Author: Iliyan Malchev <ibm@android.com>
|
||||
*
|
||||
* 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/cdev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include "adsp.h"
|
||||
|
||||
#include <linux/msm_adsp.h>
|
||||
#include <linux/android_pmem.h>
|
||||
|
||||
struct adsp_pmem_region {
|
||||
struct hlist_node list;
|
||||
void *vaddr;
|
||||
unsigned long paddr;
|
||||
unsigned long kvaddr;
|
||||
unsigned long len;
|
||||
struct file *file;
|
||||
};
|
||||
|
||||
struct adsp_device {
|
||||
struct msm_adsp_module *module;
|
||||
|
||||
spinlock_t event_queue_lock;
|
||||
wait_queue_head_t event_wait;
|
||||
struct list_head event_queue;
|
||||
int abort;
|
||||
|
||||
const char *name;
|
||||
struct device *device;
|
||||
struct cdev cdev;
|
||||
};
|
||||
|
||||
static struct adsp_device *inode_to_device(struct inode *inode);
|
||||
|
||||
#define __CONTAINS(r, v, l) ({ \
|
||||
typeof(r) __r = r; \
|
||||
typeof(v) __v = v; \
|
||||
typeof(v) __e = __v + l; \
|
||||
int res = __v >= __r->vaddr && \
|
||||
__e <= __r->vaddr + __r->len; \
|
||||
res; \
|
||||
})
|
||||
|
||||
#define CONTAINS(r1, r2) ({ \
|
||||
typeof(r2) __r2 = r2; \
|
||||
__CONTAINS(r1, __r2->vaddr, __r2->len); \
|
||||
})
|
||||
|
||||
#define IN_RANGE(r, v) ({ \
|
||||
typeof(r) __r = r; \
|
||||
typeof(v) __vv = v; \
|
||||
int res = ((__vv >= __r->vaddr) && \
|
||||
(__vv < (__r->vaddr + __r->len))); \
|
||||
res; \
|
||||
})
|
||||
|
||||
#define OVERLAPS(r1, r2) ({ \
|
||||
typeof(r1) __r1 = r1; \
|
||||
typeof(r2) __r2 = r2; \
|
||||
typeof(__r2->vaddr) __v = __r2->vaddr; \
|
||||
typeof(__v) __e = __v + __r2->len - 1; \
|
||||
int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \
|
||||
res; \
|
||||
})
|
||||
|
||||
static int adsp_pmem_check(struct msm_adsp_module *module,
|
||||
void *vaddr, unsigned long len)
|
||||
{
|
||||
struct adsp_pmem_region *region_elt;
|
||||
struct hlist_node *node;
|
||||
struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };
|
||||
|
||||
hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
|
||||
if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
|
||||
OVERLAPS(region_elt, &t)) {
|
||||
printk(KERN_ERR "adsp: module %s:"
|
||||
" region (vaddr %p len %ld)"
|
||||
" clashes with registered region"
|
||||
" (vaddr %p paddr %p len %ld)\n",
|
||||
module->name,
|
||||
vaddr, len,
|
||||
region_elt->vaddr,
|
||||
(void *)region_elt->paddr,
|
||||
region_elt->len);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adsp_pmem_add(struct msm_adsp_module *module,
|
||||
struct adsp_pmem_info *info)
|
||||
{
|
||||
unsigned long paddr, kvaddr, len;
|
||||
struct file *file;
|
||||
struct adsp_pmem_region *region;
|
||||
int rc = -EINVAL;
|
||||
|
||||
mutex_lock(&module->pmem_regions_lock);
|
||||
region = kmalloc(sizeof(*region), GFP_KERNEL);
|
||||
if (!region) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
INIT_HLIST_NODE(®ion->list);
|
||||
if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
|
||||
kfree(region);
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = adsp_pmem_check(module, info->vaddr, len);
|
||||
if (rc < 0) {
|
||||
put_pmem_file(file);
|
||||
kfree(region);
|
||||
goto end;
|
||||
}
|
||||
|
||||
region->vaddr = info->vaddr;
|
||||
region->paddr = paddr;
|
||||
region->kvaddr = kvaddr;
|
||||
region->len = len;
|
||||
region->file = file;
|
||||
|
||||
hlist_add_head(®ion->list, &module->pmem_regions);
|
||||
end:
|
||||
mutex_unlock(&module->pmem_regions_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
|
||||
unsigned long len, struct adsp_pmem_region **region)
|
||||
{
|
||||
struct hlist_node *node;
|
||||
void *vaddr = *addr;
|
||||
struct adsp_pmem_region *region_elt;
|
||||
|
||||
int match_count = 0;
|
||||
|
||||
*region = NULL;
|
||||
|
||||
/* returns physical address or zero */
|
||||
hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
|
||||
if (vaddr >= region_elt->vaddr &&
|
||||
vaddr < region_elt->vaddr + region_elt->len &&
|
||||
vaddr + len <= region_elt->vaddr + region_elt->len) {
|
||||
/* offset since we could pass vaddr inside a registerd
|
||||
* pmem buffer
|
||||
*/
|
||||
|
||||
match_count++;
|
||||
if (!*region)
|
||||
*region = region_elt;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_count > 1) {
|
||||
printk(KERN_ERR "adsp: module %s: "
|
||||
"multiple hits for vaddr %p, len %ld\n",
|
||||
module->name, vaddr, len);
|
||||
hlist_for_each_entry(region_elt, node,
|
||||
&module->pmem_regions, list) {
|
||||
if (vaddr >= region_elt->vaddr &&
|
||||
vaddr < region_elt->vaddr + region_elt->len &&
|
||||
vaddr + len <= region_elt->vaddr + region_elt->len)
|
||||
printk(KERN_ERR "\t%p, %ld --> %p\n",
|
||||
region_elt->vaddr,
|
||||
region_elt->len,
|
||||
(void *)region_elt->paddr);
|
||||
}
|
||||
}
|
||||
|
||||
return *region ? 0 : -1;
|
||||
}
|
||||
|
||||
int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
|
||||
unsigned long *kvaddr, unsigned long len)
|
||||
{
|
||||
struct adsp_pmem_region *region;
|
||||
void *vaddr = *addr;
|
||||
unsigned long *paddr = (unsigned long *)addr;
|
||||
int ret;
|
||||
|
||||
ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "adsp: not patching %s (paddr & kvaddr),"
|
||||
" lookup (%p, %ld) failed\n",
|
||||
module->name, vaddr, len);
|
||||
return ret;
|
||||
}
|
||||
*paddr = region->paddr + (vaddr - region->vaddr);
|
||||
*kvaddr = region->kvaddr + (vaddr - region->vaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
|
||||
unsigned long len)
|
||||
{
|
||||
struct adsp_pmem_region *region;
|
||||
void *vaddr = *addr;
|
||||
unsigned long *paddr = (unsigned long *)addr;
|
||||
int ret;
|
||||
|
||||
ret = adsp_pmem_lookup_vaddr(module, addr, len, ®ion);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "adsp: not patching %s, lookup (%p, %ld) failed\n",
|
||||
module->name, vaddr, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*paddr = region->paddr + (vaddr - region->vaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adsp_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
/* call the per module verifier */
|
||||
if (module->verify_cmd)
|
||||
return module->verify_cmd(module, queue_id, cmd_data,
|
||||
cmd_size);
|
||||
else
|
||||
printk(KERN_INFO "adsp: no packet verifying function "
|
||||
"for task %s\n", module->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long adsp_write_cmd(struct adsp_device *adev, void __user *arg)
|
||||
{
|
||||
struct adsp_command_t cmd;
|
||||
unsigned char buf[256];
|
||||
void *cmd_data;
|
||||
long rc;
|
||||
|
||||
if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
|
||||
return -EFAULT;
|
||||
|
||||
if (cmd.len > 256) {
|
||||
cmd_data = kmalloc(cmd.len, GFP_USER);
|
||||
if (!cmd_data)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
cmd_data = buf;
|
||||
}
|
||||
|
||||
if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) {
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_lock(&adev->module->pmem_regions_lock);
|
||||
if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) {
|
||||
printk(KERN_ERR "module %s: verify failed.\n",
|
||||
adev->module->name);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len);
|
||||
end:
|
||||
mutex_unlock(&adev->module->pmem_regions_lock);
|
||||
|
||||
if (cmd.len > 256)
|
||||
kfree(cmd_data);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int adsp_events_pending(struct adsp_device *adev)
|
||||
{
|
||||
unsigned long flags;
|
||||
int yes;
|
||||
spin_lock_irqsave(&adev->event_queue_lock, flags);
|
||||
yes = !list_empty(&adev->event_queue);
|
||||
spin_unlock_irqrestore(&adev->event_queue_lock, flags);
|
||||
return yes || adev->abort;
|
||||
}
|
||||
|
||||
static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr,
|
||||
struct adsp_pmem_region **region)
|
||||
{
|
||||
struct hlist_node *node;
|
||||
unsigned long paddr = (unsigned long)(*addr);
|
||||
struct adsp_pmem_region *region_elt;
|
||||
|
||||
hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
|
||||
if (paddr >= region_elt->paddr &&
|
||||
paddr < region_elt->paddr + region_elt->len) {
|
||||
*region = region_elt;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr)
|
||||
{
|
||||
struct adsp_pmem_region *region;
|
||||
unsigned long paddr = (unsigned long)(*addr);
|
||||
unsigned long *vaddr = (unsigned long *)addr;
|
||||
int ret;
|
||||
|
||||
ret = adsp_pmem_lookup_paddr(module, addr, ®ion);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "adsp: not patching %s, paddr %p lookup failed\n",
|
||||
module->name, vaddr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*vaddr = (unsigned long)region->vaddr + (paddr - region->paddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adsp_patch_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event)
|
||||
{
|
||||
/* call the per-module msg verifier */
|
||||
if (module->patch_event)
|
||||
return module->patch_event(module, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long adsp_get_event(struct adsp_device *adev, void __user *arg)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct adsp_event *data = NULL;
|
||||
struct adsp_event_t evt;
|
||||
int timeout;
|
||||
long rc = 0;
|
||||
|
||||
if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t)))
|
||||
return -EFAULT;
|
||||
|
||||
timeout = (int)evt.timeout_ms;
|
||||
|
||||
if (timeout > 0) {
|
||||
rc = wait_event_interruptible_timeout(
|
||||
adev->event_wait, adsp_events_pending(adev),
|
||||
msecs_to_jiffies(timeout));
|
||||
if (rc == 0)
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
rc = wait_event_interruptible(
|
||||
adev->event_wait, adsp_events_pending(adev));
|
||||
}
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (adev->abort)
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_irqsave(&adev->event_queue_lock, flags);
|
||||
if (!list_empty(&adev->event_queue)) {
|
||||
data = list_first_entry(&adev->event_queue,
|
||||
struct adsp_event, list);
|
||||
list_del(&data->list);
|
||||
}
|
||||
spin_unlock_irqrestore(&adev->event_queue_lock, flags);
|
||||
|
||||
if (!data)
|
||||
return -EAGAIN;
|
||||
|
||||
/* DSP messages are type 0; they may contain physical addresses */
|
||||
if (data->type == 0)
|
||||
adsp_patch_event(adev->module, data);
|
||||
|
||||
/* map adsp_event --> adsp_event_t */
|
||||
if (evt.len < data->size) {
|
||||
rc = -ETOOSMALL;
|
||||
goto end;
|
||||
}
|
||||
if (data->msg_id != EVENT_MSG_ID) {
|
||||
if (copy_to_user((void *)(evt.data), data->data.msg16,
|
||||
data->size)) {
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (copy_to_user((void *)(evt.data), data->data.msg32,
|
||||
data->size)) {
|
||||
rc = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */
|
||||
evt.msg_id = data->msg_id;
|
||||
evt.flags = data->is16;
|
||||
evt.len = data->size;
|
||||
if (copy_to_user(arg, &evt, sizeof(evt)))
|
||||
rc = -EFAULT;
|
||||
end:
|
||||
kfree(data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct adsp_device *adev = filp->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case ADSP_IOCTL_ENABLE:
|
||||
return msm_adsp_enable(adev->module);
|
||||
|
||||
case ADSP_IOCTL_DISABLE:
|
||||
return msm_adsp_disable(adev->module);
|
||||
|
||||
case ADSP_IOCTL_DISABLE_EVENT_RSP:
|
||||
return 0;
|
||||
|
||||
case ADSP_IOCTL_DISABLE_ACK:
|
||||
pr_err("adsp: ADSP_IOCTL_DISABLE_ACK is not implemented.\n");
|
||||
break;
|
||||
|
||||
case ADSP_IOCTL_WRITE_COMMAND:
|
||||
return adsp_write_cmd(adev, (void __user *) arg);
|
||||
|
||||
case ADSP_IOCTL_GET_EVENT:
|
||||
return adsp_get_event(adev, (void __user *) arg);
|
||||
|
||||
case ADSP_IOCTL_SET_CLKRATE: {
|
||||
#if CONFIG_MSM_AMSS_VERSION==6350
|
||||
unsigned long clk_rate;
|
||||
if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate)))
|
||||
return -EFAULT;
|
||||
return adsp_set_clkrate(adev->module, clk_rate);
|
||||
#endif
|
||||
}
|
||||
|
||||
case ADSP_IOCTL_REGISTER_PMEM: {
|
||||
struct adsp_pmem_info info;
|
||||
if (copy_from_user(&info, (void *) arg, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return adsp_pmem_add(adev->module, &info);
|
||||
}
|
||||
|
||||
case ADSP_IOCTL_ABORT_EVENT_READ:
|
||||
adev->abort = 1;
|
||||
wake_up(&adev->event_wait);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int adsp_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct adsp_device *adev = filp->private_data;
|
||||
struct msm_adsp_module *module = adev->module;
|
||||
struct hlist_node *node, *tmp;
|
||||
struct adsp_pmem_region *region;
|
||||
|
||||
pr_info("adsp_release() '%s'\n", adev->name);
|
||||
|
||||
/* clear module before putting it to avoid race with open() */
|
||||
adev->module = NULL;
|
||||
|
||||
mutex_lock(&module->pmem_regions_lock);
|
||||
hlist_for_each_safe(node, tmp, &module->pmem_regions) {
|
||||
region = hlist_entry(node, struct adsp_pmem_region, list);
|
||||
hlist_del(node);
|
||||
put_pmem_file(region->file);
|
||||
kfree(region);
|
||||
}
|
||||
mutex_unlock(&module->pmem_regions_lock);
|
||||
BUG_ON(!hlist_empty(&module->pmem_regions));
|
||||
|
||||
msm_adsp_put(module);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adsp_event(void *driver_data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
struct adsp_device *adev = driver_data;
|
||||
struct adsp_event *event;
|
||||
unsigned long flags;
|
||||
|
||||
if (len > ADSP_EVENT_MAX_SIZE) {
|
||||
pr_err("adsp_event: event too large (%d bytes)\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
event = kmalloc(sizeof(*event), GFP_ATOMIC);
|
||||
if (!event) {
|
||||
pr_err("adsp_event: cannot allocate buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != EVENT_MSG_ID) {
|
||||
event->type = 0;
|
||||
event->is16 = 0;
|
||||
event->msg_id = id;
|
||||
event->size = len;
|
||||
|
||||
getevent(event->data.msg16, len);
|
||||
} else {
|
||||
event->type = 1;
|
||||
event->is16 = 1;
|
||||
event->msg_id = id;
|
||||
event->size = len;
|
||||
getevent(event->data.msg32, len);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&adev->event_queue_lock, flags);
|
||||
list_add_tail(&event->list, &adev->event_queue);
|
||||
spin_unlock_irqrestore(&adev->event_queue_lock, flags);
|
||||
wake_up(&adev->event_wait);
|
||||
}
|
||||
|
||||
static struct msm_adsp_ops adsp_ops = {
|
||||
.event = adsp_event,
|
||||
};
|
||||
|
||||
static int adsp_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct adsp_device *adev;
|
||||
int rc;
|
||||
|
||||
rc = nonseekable_open(inode, filp);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
adev = inode_to_device(inode);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("adsp_open() name = '%s'\n", adev->name);
|
||||
|
||||
rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pr_info("adsp_open() module '%s' adev %p\n", adev->name, adev);
|
||||
filp->private_data = adev;
|
||||
adev->abort = 0;
|
||||
INIT_HLIST_HEAD(&adev->module->pmem_regions);
|
||||
mutex_init(&adev->module->pmem_regions_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned adsp_device_count;
|
||||
static struct adsp_device *adsp_devices;
|
||||
|
||||
static struct adsp_device *inode_to_device(struct inode *inode)
|
||||
{
|
||||
unsigned n = MINOR(inode->i_rdev);
|
||||
if (n < adsp_device_count) {
|
||||
if (adsp_devices[n].device)
|
||||
return adsp_devices + n;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dev_t adsp_devno;
|
||||
static struct class *adsp_class;
|
||||
|
||||
static struct file_operations adsp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = adsp_open,
|
||||
.unlocked_ioctl = adsp_ioctl,
|
||||
.release = adsp_release,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
static void adsp_create(struct adsp_device *adev, const char *name,
|
||||
struct device *parent, dev_t devt)
|
||||
{
|
||||
struct device *dev;
|
||||
int rc;
|
||||
|
||||
dev = device_create(adsp_class, parent, devt, "%s", name);
|
||||
if (IS_ERR(dev))
|
||||
return;
|
||||
|
||||
init_waitqueue_head(&adev->event_wait);
|
||||
INIT_LIST_HEAD(&adev->event_queue);
|
||||
spin_lock_init(&adev->event_queue_lock);
|
||||
|
||||
cdev_init(&adev->cdev, &adsp_fops);
|
||||
adev->cdev.owner = THIS_MODULE;
|
||||
|
||||
rc = cdev_add(&adev->cdev, devt, 1);
|
||||
if (rc < 0) {
|
||||
device_destroy(adsp_class, devt);
|
||||
} else {
|
||||
adev->device = dev;
|
||||
adev->name = name;
|
||||
}
|
||||
}
|
||||
|
||||
void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n)
|
||||
{
|
||||
int rc;
|
||||
|
||||
adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL);
|
||||
if (!adsp_devices)
|
||||
return;
|
||||
|
||||
adsp_class = class_create(THIS_MODULE, "adsp");
|
||||
if (IS_ERR(adsp_class))
|
||||
goto fail_create_class;
|
||||
|
||||
rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp");
|
||||
if (rc < 0)
|
||||
goto fail_alloc_region;
|
||||
|
||||
adsp_device_count = n;
|
||||
for (n = 0; n < adsp_device_count; n++) {
|
||||
adsp_create(adsp_devices + n,
|
||||
modules[n].name, &modules[n].pdev.dev,
|
||||
MKDEV(MAJOR(adsp_devno), n));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail_alloc_region:
|
||||
class_unregister(adsp_class);
|
||||
fail_create_class:
|
||||
kfree(adsp_devices);
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/* arch/arm/mach-msm/adsp_info.c
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated.
|
||||
* Copyright (c) 2008 QUALCOMM USA, 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 "adsp.h"
|
||||
|
||||
/* Firmware modules */
|
||||
#define QDSP_MODULE_KERNEL 0x0106dd4e
|
||||
#define QDSP_MODULE_AFETASK 0x0106dd6f
|
||||
#define QDSP_MODULE_AUDPLAY0TASK 0x0106dd70
|
||||
#define QDSP_MODULE_AUDPLAY1TASK 0x0106dd71
|
||||
#define QDSP_MODULE_AUDPPTASK 0x0106dd72
|
||||
#define QDSP_MODULE_VIDEOTASK 0x0106dd73
|
||||
#define QDSP_MODULE_VIDEO_AAC_VOC 0x0106dd74
|
||||
#define QDSP_MODULE_PCM_DEC 0x0106dd75
|
||||
#define QDSP_MODULE_AUDIO_DEC_MP3 0x0106dd76
|
||||
#define QDSP_MODULE_AUDIO_DEC_AAC 0x0106dd77
|
||||
#define QDSP_MODULE_AUDIO_DEC_WMA 0x0106dd78
|
||||
#define QDSP_MODULE_HOSTPCM 0x0106dd79
|
||||
#define QDSP_MODULE_DTMF 0x0106dd7a
|
||||
#define QDSP_MODULE_AUDRECTASK 0x0106dd7b
|
||||
#define QDSP_MODULE_AUDPREPROCTASK 0x0106dd7c
|
||||
#define QDSP_MODULE_SBC_ENC 0x0106dd7d
|
||||
#define QDSP_MODULE_VOC_UMTS 0x0106dd9a
|
||||
#define QDSP_MODULE_VOC_CDMA 0x0106dd98
|
||||
#define QDSP_MODULE_VOC_PCM 0x0106dd7f
|
||||
#define QDSP_MODULE_VOCENCTASK 0x0106dd80
|
||||
#define QDSP_MODULE_VOCDECTASK 0x0106dd81
|
||||
#define QDSP_MODULE_VOICEPROCTASK 0x0106dd82
|
||||
#define QDSP_MODULE_VIDEOENCTASK 0x0106dd83
|
||||
#define QDSP_MODULE_VFETASK 0x0106dd84
|
||||
#define QDSP_MODULE_WAV_ENC 0x0106dd85
|
||||
#define QDSP_MODULE_AACLC_ENC 0x0106dd86
|
||||
#define QDSP_MODULE_VIDEO_AMR 0x0106dd87
|
||||
#define QDSP_MODULE_VOC_AMR 0x0106dd88
|
||||
#define QDSP_MODULE_VOC_EVRC 0x0106dd89
|
||||
#define QDSP_MODULE_VOC_13K 0x0106dd8a
|
||||
#define QDSP_MODULE_VOC_FGV 0x0106dd8b
|
||||
#define QDSP_MODULE_DIAGTASK 0x0106dd8c
|
||||
#define QDSP_MODULE_JPEGTASK 0x0106dd8d
|
||||
#define QDSP_MODULE_LPMTASK 0x0106dd8e
|
||||
#define QDSP_MODULE_QCAMTASK 0x0106dd8f
|
||||
#define QDSP_MODULE_MODMATHTASK 0x0106dd90
|
||||
#define QDSP_MODULE_AUDPLAY2TASK 0x0106dd91
|
||||
#define QDSP_MODULE_AUDPLAY3TASK 0x0106dd92
|
||||
#define QDSP_MODULE_AUDPLAY4TASK 0x0106dd93
|
||||
#define QDSP_MODULE_GRAPHICSTASK 0x0106dd94
|
||||
#define QDSP_MODULE_MIDI 0x0106dd95
|
||||
#define QDSP_MODULE_GAUDIO 0x0106dd96
|
||||
#define QDSP_MODULE_VDEC_LP_MODE 0x0106dd97
|
||||
#define QDSP_MODULE_MAX 0x7fffffff
|
||||
|
||||
/* DO NOT USE: Force this enum to be a 32bit type to improve speed */
|
||||
#define QDSP_MODULE_32BIT_DUMMY 0x10000
|
||||
|
||||
static uint32_t *qdsp_task_to_module[IMG_MAX];
|
||||
static uint32_t *qdsp_queue_offset_table[IMG_MAX];
|
||||
|
||||
#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
|
||||
{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
|
||||
.clk_name = clkname, .clk_rate = clkrate, \
|
||||
.verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
|
||||
|
||||
static struct adsp_module_info module_info[] = {
|
||||
QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
|
||||
adsp_vfe_patch_event),
|
||||
QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
|
||||
QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd,
|
||||
adsp_jpeg_patch_event),
|
||||
QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
|
||||
adsp_video_verify_cmd, NULL),
|
||||
QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
|
||||
QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
|
||||
adsp_videoenc_verify_cmd, NULL),
|
||||
};
|
||||
|
||||
int adsp_init_info(struct adsp_info *info)
|
||||
{
|
||||
uint32_t img_num;
|
||||
|
||||
info->send_irq = 0x00c00200;
|
||||
info->read_ctrl = 0x00400038;
|
||||
info->write_ctrl = 0x00400034;
|
||||
|
||||
info->max_msg16_size = 193;
|
||||
info->max_msg32_size = 8;
|
||||
for (img_num = 0; img_num < IMG_MAX; img_num++)
|
||||
qdsp_queue_offset_table[img_num] =
|
||||
&info->init_info_ptr->queue_offsets[img_num][0];
|
||||
|
||||
for (img_num = 0; img_num < IMG_MAX; img_num++)
|
||||
qdsp_task_to_module[img_num] =
|
||||
&info->init_info_ptr->task_to_module_tbl[img_num][0];
|
||||
info->max_task_id = 30;
|
||||
info->max_module_id = QDSP_MODULE_MAX - 1;
|
||||
info->max_queue_id = QDSP_MAX_NUM_QUEUES;
|
||||
info->max_image_id = 2;
|
||||
info->queue_offset = qdsp_queue_offset_table;
|
||||
info->task_to_module = qdsp_task_to_module;
|
||||
|
||||
info->module_count = ARRAY_SIZE(module_info);
|
||||
info->module = module_info;
|
||||
return 0;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
|
||||
*
|
||||
* Verification code for aDSP JPEG events.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/qdsp5/qdsp5jpegmsg.h>
|
||||
#include "adsp.h"
|
||||
|
||||
int adsp_jpeg_patch_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event)
|
||||
{
|
||||
if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) {
|
||||
jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16;
|
||||
return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
|
||||
*
|
||||
* Verification code for aDSP JPEG packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/qdsp5/qdsp5jpegcmdi.h>
|
||||
#include "adsp.h"
|
||||
|
||||
static uint32_t dec_fmt;
|
||||
|
||||
static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size,
|
||||
uint32_t *chroma_size)
|
||||
{
|
||||
uint32_t fmt, luma_width, luma_height;
|
||||
|
||||
fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M;
|
||||
luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M)
|
||||
>> 16;
|
||||
luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M;
|
||||
*luma_size = luma_width * luma_height;
|
||||
if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2)
|
||||
*chroma_size = *luma_size/2;
|
||||
else
|
||||
*chroma_size = *luma_size;
|
||||
}
|
||||
|
||||
static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data;
|
||||
uint32_t luma_size, chroma_size;
|
||||
int i, num_frags;
|
||||
|
||||
if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) {
|
||||
printk(KERN_ERR "adsp: module %s: JPEG ENC CFG invalid cmd_size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
get_sizes(cmd, &luma_size, &chroma_size);
|
||||
num_frags = (cmd->process_cfg >> 10) & 0xf;
|
||||
num_frags = ((num_frags == 1) ? num_frags : num_frags * 2);
|
||||
for (i = 0; i < num_frags; i += 2) {
|
||||
if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) ||
|
||||
adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1,
|
||||
cmd->op_buf_0_cfg_part2) ||
|
||||
adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1,
|
||||
cmd->op_buf_1_cfg_part2))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data;
|
||||
uint32_t div;
|
||||
|
||||
if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) {
|
||||
printk(KERN_ERR "adsp: module %s: JPEG DEC CFG invalid cmd_size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1,
|
||||
cmd->ip_stream_buf_cfg_part2) ||
|
||||
adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1,
|
||||
cmd->op_stream_buf_0_cfg_part2) ||
|
||||
adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1,
|
||||
cmd->op_stream_buf_1_cfg_part2))
|
||||
return -1;
|
||||
dec_fmt = cmd->op_data_format &
|
||||
JPEG_CMD_DEC_OP_DATA_FORMAT_M;
|
||||
div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
|
||||
if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3,
|
||||
cmd->op_stream_buf_0_cfg_part2 / div) ||
|
||||
adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3,
|
||||
cmd->op_stream_buf_1_cfg_part2 / div))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
|
||||
switch(cmd_id) {
|
||||
case JPEG_CMD_ENC_CFG:
|
||||
return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size);
|
||||
case JPEG_CMD_DEC_CFG:
|
||||
return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size);
|
||||
default:
|
||||
if (cmd_id > 1) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid JPEG CFG cmd_id %d\n", module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_jpeg_action_cmd(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
|
||||
switch (cmd_id) {
|
||||
case JPEG_CMD_ENC_OP_CONSUMED:
|
||||
{
|
||||
jpeg_cmd_enc_op_consumed *cmd =
|
||||
(jpeg_cmd_enc_op_consumed *)cmd_data;
|
||||
|
||||
if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
|
||||
printk(KERN_ERR "adsp: module %s: JPEG_CMD_ENC_OP_CONSUMED invalid size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr,
|
||||
cmd->op_buf_size))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case JPEG_CMD_DEC_OP_CONSUMED:
|
||||
{
|
||||
uint32_t div;
|
||||
jpeg_cmd_dec_op_consumed *cmd =
|
||||
(jpeg_cmd_dec_op_consumed *)cmd_data;
|
||||
|
||||
if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
|
||||
printk(KERN_ERR "adsp: module %s: JPEG_CMD_DEC_OP_CONSUMED invalid size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
|
||||
if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr,
|
||||
cmd->luma_op_buf_size) ||
|
||||
adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr,
|
||||
cmd->luma_op_buf_size / div))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (cmd_id > 7) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
|
||||
module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
switch(queue_id) {
|
||||
case QDSP_uPJpegCfgCmdQueue:
|
||||
return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size);
|
||||
case QDSP_uPJpegActionCmdQueue:
|
||||
return verify_jpeg_action_cmd(module, cmd_data, cmd_size);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
|
||||
*
|
||||
* Verificion code for aDSP LPM packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/qdsp5/qdsp5lpmcmdi.h>
|
||||
#include "adsp.h"
|
||||
|
||||
int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id, col_height, input_row_incr, output_row_incr,
|
||||
input_size, output_size;
|
||||
uint32_t size_mask = 0x0fff;
|
||||
lpm_cmd_start *cmd;
|
||||
|
||||
if (queue_id != QDSP_lpmCommandQueue) {
|
||||
printk(KERN_ERR "adsp: module %s: wrong queue id %d\n",
|
||||
module->name, queue_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd = (lpm_cmd_start *)cmd_data;
|
||||
cmd_id = cmd->cmd_id;
|
||||
|
||||
if (cmd_id == LPM_CMD_START) {
|
||||
if (cmd_size != sizeof(lpm_cmd_start)) {
|
||||
printk(KERN_ERR "adsp: module %s: wrong size %d, expect %d\n",
|
||||
module->name, cmd_size, sizeof(lpm_cmd_start));
|
||||
return -1;
|
||||
}
|
||||
col_height = cmd->ip_data_cfg_part1 & size_mask;
|
||||
input_row_incr = cmd->ip_data_cfg_part2 & size_mask;
|
||||
output_row_incr = cmd->op_data_cfg_part1 & size_mask;
|
||||
input_size = col_height * input_row_incr;
|
||||
output_size = col_height * output_row_incr;
|
||||
if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module,
|
||||
(void **)(&cmd->ip_data_cfg_part4),
|
||||
input_size)) ||
|
||||
(cmd->op_data_cfg_part3 && adsp_pmem_fixup(module,
|
||||
(void **)(&cmd->op_data_cfg_part3),
|
||||
output_size)))
|
||||
return -1;
|
||||
} else if (cmd_id > 1) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
|
||||
module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
|
||||
*
|
||||
* Verification code for aDSP VFE packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/qdsp5/qdsp5vfemsg.h>
|
||||
#include "adsp.h"
|
||||
|
||||
static int patch_op_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event)
|
||||
{
|
||||
vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16;
|
||||
if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) ||
|
||||
adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int patch_af_wb_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event)
|
||||
{
|
||||
vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16;
|
||||
return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf);
|
||||
}
|
||||
|
||||
int adsp_vfe_patch_event(struct msm_adsp_module *module,
|
||||
struct adsp_event *event)
|
||||
{
|
||||
switch(event->msg_id) {
|
||||
case VFE_MSG_OP1:
|
||||
case VFE_MSG_OP2:
|
||||
return patch_op_event(module, event);
|
||||
case VFE_MSG_STATS_AF:
|
||||
case VFE_MSG_STATS_WB_EXP:
|
||||
return patch_af_wb_event(module, event);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
|
||||
*
|
||||
* Verification code for aDSP VFE packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/qdsp5/qdsp5vfecmdi.h>
|
||||
#include "adsp.h"
|
||||
|
||||
static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
|
||||
static uint32_t af_size = 4228;
|
||||
static uint32_t awb_size = 8196;
|
||||
|
||||
static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
|
||||
void **addr_y = (void **)&cmd->op1_buf_y_addr;
|
||||
void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_op1_ack))
|
||||
return -1;
|
||||
if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
|
||||
(*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
int i;
|
||||
vfe_cmd_stats_autofocus_cfg *cmd =
|
||||
(vfe_cmd_stats_autofocus_cfg *)cmd_data;
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
void **addr = (void **)(&cmd->af_stats_op_buf[i]);
|
||||
if (*addr && adsp_pmem_fixup(module, addr, af_size))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
vfe_cmd_stats_wb_exp_cfg *cmd =
|
||||
(vfe_cmd_stats_wb_exp_cfg *)cmd_data;
|
||||
int i;
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
|
||||
if (*addr && adsp_pmem_fixup(module, addr, awb_size))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
|
||||
void **addr = (void **)&cmd->af_stats_op_buf;
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
|
||||
return -1;
|
||||
|
||||
if (*addr && adsp_pmem_fixup(module, addr, af_size))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
vfe_cmd_stats_wb_exp_ack *cmd =
|
||||
(vfe_cmd_stats_wb_exp_ack *)cmd_data;
|
||||
void **addr = (void **)&cmd->wb_exp_stats_op_buf;
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
|
||||
return -1;
|
||||
|
||||
if (*addr && adsp_pmem_fixup(module, addr, awb_size))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_vfe_command(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
|
||||
switch (cmd_id) {
|
||||
case VFE_CMD_OP1_ACK:
|
||||
return verify_cmd_op_ack(module, cmd_data, cmd_size);
|
||||
case VFE_CMD_OP2_ACK:
|
||||
return verify_cmd_op_ack(module, cmd_data, cmd_size);
|
||||
case VFE_CMD_STATS_AUTOFOCUS_CFG:
|
||||
return verify_cmd_stats_autofocus_cfg(module, cmd_data,
|
||||
cmd_size);
|
||||
case VFE_CMD_STATS_WB_EXP_CFG:
|
||||
return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
|
||||
case VFE_CMD_STATS_AF_ACK:
|
||||
return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
|
||||
case VFE_CMD_STATS_WB_EXP_ACK:
|
||||
return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
|
||||
default:
|
||||
if (cmd_id > 29) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_vfe_command_scale(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
|
||||
// FIXME: check the size
|
||||
if (cmd_id > 1) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t get_size(uint32_t hw)
|
||||
{
|
||||
uint32_t height, width;
|
||||
uint32_t height_mask = 0x3ffc;
|
||||
uint32_t width_mask = 0x3ffc000;
|
||||
|
||||
height = (hw & height_mask) >> 2;
|
||||
width = (hw & width_mask) >> 14 ;
|
||||
return height * width;
|
||||
}
|
||||
|
||||
static int verify_vfe_command_table(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
|
||||
int i;
|
||||
|
||||
switch (cmd_id) {
|
||||
case VFE_CMD_AXI_IP_CFG:
|
||||
{
|
||||
vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
|
||||
uint32_t size;
|
||||
if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
size = get_size(cmd->ip_cfg_part2);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
void **addr = (void **)
|
||||
&cmd->ip_buf_addr[i];
|
||||
if (*addr && adsp_pmem_fixup(module, addr, size))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
case VFE_CMD_AXI_OP_CFG:
|
||||
{
|
||||
vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
|
||||
void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
|
||||
|
||||
if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
|
||||
module->name, cmd_size);
|
||||
return -1;
|
||||
}
|
||||
size1_y = get_size(cmd->op1_y_cfg_part2);
|
||||
size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
|
||||
size2_y = get_size(cmd->op2_y_cfg_part2);
|
||||
size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
|
||||
for (i = 0; i < 8; i++) {
|
||||
addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
|
||||
addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
|
||||
addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
|
||||
addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
|
||||
/*
|
||||
printk("module %s: [%d] %p %p %p %p\n",
|
||||
module->name, i,
|
||||
*addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
|
||||
*/
|
||||
if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
|
||||
(*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
|
||||
(*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
|
||||
(*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
default:
|
||||
if (cmd_id > 4) {
|
||||
printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
|
||||
module->name, cmd_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
switch (queue_id) {
|
||||
case QDSP_vfeCommandQueue:
|
||||
return verify_vfe_command(module, cmd_data, cmd_size);
|
||||
case QDSP_vfeCommandScaleQueue:
|
||||
return verify_vfe_command_scale(module, cmd_data, cmd_size);
|
||||
case QDSP_vfeCommandTableQueue:
|
||||
return verify_vfe_command_table(module, cmd_data, cmd_size);
|
||||
default:
|
||||
printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
|
||||
module->name, queue_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
|
||||
*
|
||||
* Verificion code for aDSP VDEC packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/io.h>
|
||||
|
||||
#define ADSP_DEBUG_MSGS 0
|
||||
#if ADSP_DEBUG_MSGS
|
||||
#define DLOG(fmt,args...) \
|
||||
do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
|
||||
##args); } \
|
||||
while (0)
|
||||
#else
|
||||
#define DLOG(x...) do {} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#include <mach/qdsp5/qdsp5vdeccmdi.h>
|
||||
#include "adsp.h"
|
||||
|
||||
static inline void *high_low_short_to_ptr(unsigned short high,
|
||||
unsigned short low)
|
||||
{
|
||||
return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
|
||||
}
|
||||
|
||||
static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
|
||||
unsigned short *low)
|
||||
{
|
||||
*high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
|
||||
*low = (unsigned short)((unsigned long)ptr & 0xffff);
|
||||
}
|
||||
|
||||
static int pmem_fixup_high_low(unsigned short *high,
|
||||
unsigned short *low,
|
||||
unsigned short size_high,
|
||||
unsigned short size_low,
|
||||
struct msm_adsp_module *module,
|
||||
unsigned long *addr, unsigned long *size)
|
||||
{
|
||||
void *phys_addr;
|
||||
unsigned long phys_size;
|
||||
unsigned long kvaddr;
|
||||
|
||||
phys_addr = high_low_short_to_ptr(*high, *low);
|
||||
phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
|
||||
DLOG("virt %x %x\n", phys_addr, phys_size);
|
||||
if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
|
||||
DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
|
||||
*high, *low, size_high, size_low, phys_addr, phys_size);
|
||||
return -1;
|
||||
}
|
||||
ptr_to_high_low_short(phys_addr, high, low);
|
||||
DLOG("phys %x %x\n", phys_addr, phys_size);
|
||||
if (addr)
|
||||
*addr = kvaddr;
|
||||
if (size)
|
||||
*size = phys_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_vdec_pkt_cmd(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
|
||||
viddec_cmd_subframe_pkt *pkt;
|
||||
unsigned long subframe_pkt_addr;
|
||||
unsigned long subframe_pkt_size;
|
||||
viddec_cmd_frame_header_packet *frame_header_pkt;
|
||||
int i, num_addr, skip;
|
||||
unsigned short *frame_buffer_high, *frame_buffer_low;
|
||||
unsigned long frame_buffer_size;
|
||||
unsigned short frame_buffer_size_high, frame_buffer_size_low;
|
||||
|
||||
DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
|
||||
if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) {
|
||||
printk(KERN_INFO "adsp_video: unknown video packet %u\n",
|
||||
cmd_id);
|
||||
return 0;
|
||||
}
|
||||
if (cmd_size < sizeof(viddec_cmd_subframe_pkt))
|
||||
return -1;
|
||||
|
||||
pkt = (viddec_cmd_subframe_pkt *)cmd_data;
|
||||
|
||||
if (pmem_fixup_high_low(&(pkt->subframe_packet_high),
|
||||
&(pkt->subframe_packet_low),
|
||||
pkt->subframe_packet_size_high,
|
||||
pkt->subframe_packet_size_low,
|
||||
module,
|
||||
&subframe_pkt_addr,
|
||||
&subframe_pkt_size))
|
||||
return -1;
|
||||
|
||||
/* deref those ptrs and check if they are a frame header packet */
|
||||
frame_header_pkt = (viddec_cmd_frame_header_packet *)subframe_pkt_addr;
|
||||
|
||||
switch (frame_header_pkt->packet_id) {
|
||||
case 0xB201: /* h.264 */
|
||||
num_addr = skip = 8;
|
||||
break;
|
||||
case 0x4D01: /* mpeg-4 and h.263 */
|
||||
num_addr = 3;
|
||||
skip = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
frame_buffer_high = &frame_header_pkt->frame_buffer_0_high;
|
||||
frame_buffer_low = &frame_header_pkt->frame_buffer_0_low;
|
||||
frame_buffer_size = (frame_header_pkt->x_dimension *
|
||||
frame_header_pkt->y_dimension * 3) / 2;
|
||||
ptr_to_high_low_short((void *)frame_buffer_size,
|
||||
&frame_buffer_size_high,
|
||||
&frame_buffer_size_low);
|
||||
for (i = 0; i < num_addr; i++) {
|
||||
if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
|
||||
frame_buffer_size_high,
|
||||
frame_buffer_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
frame_buffer_high += 2;
|
||||
frame_buffer_low += 2;
|
||||
}
|
||||
/* Patch the output buffer. */
|
||||
frame_buffer_high += 2*skip;
|
||||
frame_buffer_low += 2*skip;
|
||||
if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
|
||||
frame_buffer_size_high,
|
||||
frame_buffer_size_low, module, NULL, NULL))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adsp_video_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
switch (queue_id) {
|
||||
case QDSP_mpuVDecPktQueue:
|
||||
DLOG("\n");
|
||||
return verify_vdec_pkt_cmd(module, cmd_data, cmd_size);
|
||||
default:
|
||||
printk(KERN_INFO "unknown video queue %u\n", queue_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
|
||||
*
|
||||
* Verificion code for aDSP VENC packets from userspace.
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM Incorporated
|
||||
* Copyright (C) 2008 Google, 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/io.h>
|
||||
|
||||
#define ADSP_DEBUG_MSGS 0
|
||||
#if ADSP_DEBUG_MSGS
|
||||
#define DLOG(fmt,args...) \
|
||||
do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
|
||||
##args); } \
|
||||
while (0)
|
||||
#else
|
||||
#define DLOG(x...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#include <mach/qdsp5/qdsp5venccmdi.h>
|
||||
#include "adsp.h"
|
||||
|
||||
|
||||
static unsigned short x_dimension, y_dimension;
|
||||
|
||||
static inline void *high_low_short_to_ptr(unsigned short high,
|
||||
unsigned short low)
|
||||
{
|
||||
return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
|
||||
}
|
||||
|
||||
static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
|
||||
unsigned short *low)
|
||||
{
|
||||
*high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
|
||||
*low = (unsigned short)((unsigned long)ptr & 0xffff);
|
||||
}
|
||||
|
||||
static int pmem_fixup_high_low(unsigned short *high,
|
||||
unsigned short *low,
|
||||
unsigned short size_high,
|
||||
unsigned short size_low,
|
||||
struct msm_adsp_module *module,
|
||||
unsigned long *addr, unsigned long *size)
|
||||
{
|
||||
void *phys_addr;
|
||||
unsigned long phys_size;
|
||||
unsigned long kvaddr;
|
||||
|
||||
phys_addr = high_low_short_to_ptr(*high, *low);
|
||||
phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
|
||||
DLOG("virt %x %x\n", phys_addr, phys_size);
|
||||
if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
|
||||
DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
|
||||
*high, *low, size_high, size_low, phys_addr, phys_size);
|
||||
return -1;
|
||||
}
|
||||
ptr_to_high_low_short(phys_addr, high, low);
|
||||
DLOG("phys %x %x\n", phys_addr, phys_size);
|
||||
if (addr)
|
||||
*addr = kvaddr;
|
||||
if (size)
|
||||
*size = phys_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_venc_cmd(struct msm_adsp_module *module,
|
||||
void *cmd_data, size_t cmd_size)
|
||||
{
|
||||
unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
|
||||
unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
|
||||
unsigned short frame_buf_size_high, frame_buf_size_low;
|
||||
unsigned short luma_buf_size_high, luma_buf_size_low;
|
||||
unsigned short chroma_buf_size_high, chroma_buf_size_low;
|
||||
videnc_cmd_cfg *config_cmd;
|
||||
videnc_cmd_frame_start *frame_cmd;
|
||||
videnc_cmd_dis *dis_cmd;
|
||||
|
||||
DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
|
||||
switch (cmd_id) {
|
||||
case VIDENC_CMD_ACTIVE:
|
||||
if (cmd_size < sizeof(videnc_cmd_active))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_IDLE:
|
||||
if (cmd_size < sizeof(videnc_cmd_idle))
|
||||
return -1;
|
||||
x_dimension = y_dimension = 0;
|
||||
break;
|
||||
case VIDENC_CMD_STATUS_QUERY:
|
||||
if (cmd_size < sizeof(videnc_cmd_status_query))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_RC_CFG:
|
||||
if (cmd_size < sizeof(videnc_cmd_rc_cfg))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_INTRA_REFRESH:
|
||||
if (cmd_size < sizeof(videnc_cmd_intra_refresh))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_DIGITAL_ZOOM:
|
||||
if (cmd_size < sizeof(videnc_cmd_digital_zoom))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_DIS_CFG:
|
||||
if (cmd_size < sizeof(videnc_cmd_dis_cfg))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_CFG:
|
||||
if (cmd_size < sizeof(videnc_cmd_cfg))
|
||||
return -1;
|
||||
config_cmd = (videnc_cmd_cfg *)cmd_data;
|
||||
x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
|
||||
x_dimension = x_dimension*16;
|
||||
y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
|
||||
y_dimension = y_dimension * 16;
|
||||
break;
|
||||
case VIDENC_CMD_FRAME_START:
|
||||
if (cmd_size < sizeof(videnc_cmd_frame_start))
|
||||
return -1;
|
||||
frame_cmd = (videnc_cmd_frame_start *)cmd_data;
|
||||
luma_buf_size = x_dimension * y_dimension;
|
||||
chroma_buf_size = luma_buf_size>>1;
|
||||
frame_buf_size = luma_buf_size + chroma_buf_size;
|
||||
ptr_to_high_low_short((void *)luma_buf_size,
|
||||
&luma_buf_size_high,
|
||||
&luma_buf_size_low);
|
||||
ptr_to_high_low_short((void *)chroma_buf_size,
|
||||
&chroma_buf_size_high,
|
||||
&chroma_buf_size_low);
|
||||
ptr_to_high_low_short((void *)frame_buf_size,
|
||||
&frame_buf_size_high,
|
||||
&frame_buf_size_low);
|
||||
/* Address of raw Y data. */
|
||||
if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
|
||||
&frame_cmd->input_luma_addr_low,
|
||||
luma_buf_size_high,
|
||||
luma_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
/* Address of raw CbCr data */
|
||||
if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
|
||||
&frame_cmd->input_chroma_addr_low,
|
||||
chroma_buf_size_high,
|
||||
chroma_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
/* Reference VOP */
|
||||
if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
|
||||
&frame_cmd->ref_vop_buf_ptr_low,
|
||||
frame_buf_size_high,
|
||||
frame_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
/* Encoded Packet Address */
|
||||
if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
|
||||
&frame_cmd->enc_pkt_buf_ptr_low,
|
||||
frame_cmd->enc_pkt_buf_size_high,
|
||||
frame_cmd->enc_pkt_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
/* Unfiltered VOP Buffer Address */
|
||||
if (pmem_fixup_high_low(
|
||||
&frame_cmd->unfilt_recon_vop_buf_ptr_high,
|
||||
&frame_cmd->unfilt_recon_vop_buf_ptr_low,
|
||||
frame_buf_size_high,
|
||||
frame_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
/* Filtered VOP Buffer Address */
|
||||
if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
|
||||
&frame_cmd->filt_recon_vop_buf_ptr_low,
|
||||
frame_buf_size_high,
|
||||
frame_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
break;
|
||||
case VIDENC_CMD_DIS:
|
||||
if (cmd_size < sizeof(videnc_cmd_dis))
|
||||
return -1;
|
||||
dis_cmd = (videnc_cmd_dis *)cmd_data;
|
||||
luma_buf_size = x_dimension * y_dimension;
|
||||
ptr_to_high_low_short((void *)luma_buf_size,
|
||||
&luma_buf_size_high,
|
||||
&luma_buf_size_low);
|
||||
/* Prev VFE Luma Output Address */
|
||||
if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
|
||||
&dis_cmd->vfe_out_prev_luma_addr_low,
|
||||
luma_buf_size_high,
|
||||
luma_buf_size_low,
|
||||
module,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
|
||||
cmd_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
|
||||
unsigned int queue_id, void *cmd_data,
|
||||
size_t cmd_size)
|
||||
{
|
||||
switch (queue_id) {
|
||||
case QDSP_mpuVEncCmdQueue:
|
||||
DLOG("\n");
|
||||
return verify_venc_cmd(module, cmd_data, cmd_size);
|
||||
default:
|
||||
printk(KERN_INFO "unknown video queue %u\n", queue_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,875 +0,0 @@
|
|||
/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c
|
||||
*
|
||||
* amrnb audio decoder device
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM USA, INC.
|
||||
*
|
||||
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC Corporation
|
||||
*
|
||||
* All source code in this file is licensed under the following license except
|
||||
* where indicated.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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, you can find it at http://www.fsf.org
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
#include <mach/qdsp5/qdsp5audplaycmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audplaymsg.h>
|
||||
|
||||
/* for queue ids - should be relative to module number*/
|
||||
#include "adsp.h"
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define dprintk(format, arg...) \
|
||||
printk(KERN_DEBUG format, ## arg)
|
||||
#else
|
||||
#define dprintk(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define BUFSZ 1024 /* Hold minimum 700ms voice data */
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
|
||||
#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
|
||||
#define AUDDEC_DEC_AMRNB 10
|
||||
|
||||
#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
|
||||
#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */
|
||||
#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
|
||||
but support 2 buffers currently */
|
||||
#define ROUTING_MODE_FTRT 1
|
||||
#define ROUTING_MODE_RT 2
|
||||
/* Decoder status received from AUDPPTASK */
|
||||
#define AUDPP_DEC_STATUS_SLEEP 0
|
||||
#define AUDPP_DEC_STATUS_INIT 1
|
||||
#define AUDPP_DEC_STATUS_CFG 2
|
||||
#define AUDPP_DEC_STATUS_PLAY 3
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
unsigned size;
|
||||
unsigned used; /* Input usage actual DSP produced PCM size */
|
||||
unsigned addr;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
struct buffer out[2];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
uint8_t out_head;
|
||||
uint8_t out_tail;
|
||||
uint8_t out_needed; /* number of buffers the dsp is waiting for */
|
||||
|
||||
atomic_t out_bytes;
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex write_lock;
|
||||
wait_queue_head_t write_wait;
|
||||
|
||||
/* Host PCM section */
|
||||
struct buffer in[PCM_BUF_MAX_COUNT];
|
||||
struct mutex read_lock;
|
||||
wait_queue_head_t read_wait; /* Wait queue for read */
|
||||
char *read_data; /* pointer to reader buffer */
|
||||
dma_addr_t read_phys; /* physical address of reader buffer */
|
||||
uint8_t read_next; /* index to input buffers to be read next */
|
||||
uint8_t fill_next; /* index to buffer that DSP should be filling */
|
||||
uint8_t pcm_buf_count; /* number of pcm buffer allocated */
|
||||
/* ---- End of Host PCM section */
|
||||
|
||||
struct msm_adsp_module *audplay;
|
||||
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
uint8_t opened:1;
|
||||
uint8_t enabled:1;
|
||||
uint8_t running:1;
|
||||
uint8_t stopped:1; /* set when stopped, cleared on flush */
|
||||
uint8_t pcm_feedback:1;
|
||||
uint8_t buf_refresh:1;
|
||||
|
||||
unsigned volume;
|
||||
|
||||
uint16_t dec_id;
|
||||
uint32_t read_ptr_offset;
|
||||
};
|
||||
|
||||
struct audpp_cmd_cfg_adec_params_amrnb {
|
||||
audpp_cmd_cfg_adec_params_common common;
|
||||
unsigned short stereo_cfg;
|
||||
} __attribute__((packed)) ;
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable);
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio);
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio);
|
||||
static void audamrnb_send_data(struct audio *audio, unsigned needed);
|
||||
static void audamrnb_config_hostpcm(struct audio *audio);
|
||||
static void audamrnb_buffer_refresh(struct audio *audio);
|
||||
static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audamrnb_enable(struct audio *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
dprintk("audamrnb_enable()\n");
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
audio->out_tail = 0;
|
||||
audio->out_needed = 0;
|
||||
|
||||
cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msm_adsp_enable(audio->audplay)) {
|
||||
pr_err("audio: msm_adsp_enable(audplay) failed\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) {
|
||||
pr_err("audio: audpp_enable() failed\n");
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
audio->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audamrnb_disable(struct audio *audio)
|
||||
{
|
||||
dprintk("audamrnb_disable()\n");
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
auddec_dsp_config(audio, 0);
|
||||
wake_up(&audio->write_wait);
|
||||
wake_up(&audio->read_wait);
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audpp_disable(audio->dec_id, audio);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
static void audamrnb_update_pcm_buf_entry(struct audio *audio,
|
||||
uint32_t *payload)
|
||||
{
|
||||
uint8_t index;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
for (index = 0; index < payload[1]; index++) {
|
||||
if (audio->in[audio->fill_next].addr ==
|
||||
payload[2 + index * 2]) {
|
||||
dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n",
|
||||
audio->fill_next);
|
||||
audio->in[audio->fill_next].used =
|
||||
payload[3 + index * 2];
|
||||
if ((++audio->fill_next) == audio->pcm_buf_count)
|
||||
audio->fill_next = 0;
|
||||
|
||||
} else {
|
||||
pr_err
|
||||
("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n"
|
||||
, audio->in[audio->fill_next].addr,
|
||||
payload[1 + index * 2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (audio->in[audio->fill_next].used == 0) {
|
||||
audamrnb_buffer_refresh(audio);
|
||||
} else {
|
||||
dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n");
|
||||
audio->buf_refresh = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
wake_up(&audio->read_wait);
|
||||
}
|
||||
|
||||
static void audplay_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent) (void *ptr, size_t len))
|
||||
{
|
||||
struct audio *audio = data;
|
||||
uint32_t msg[28];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
dprintk("audplay_dsp_event: msg_id=%x\n", id);
|
||||
|
||||
switch (id) {
|
||||
case AUDPLAY_MSG_DEC_NEEDS_DATA:
|
||||
audamrnb_send_data(audio, 1);
|
||||
break;
|
||||
|
||||
case AUDPLAY_MSG_BUFFER_UPDATE:
|
||||
audamrnb_update_pcm_buf_entry(audio, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("unexpected message from decoder \n");
|
||||
}
|
||||
}
|
||||
|
||||
static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg)
|
||||
{
|
||||
struct audio *audio = private;
|
||||
|
||||
switch (id) {
|
||||
case AUDPP_MSG_STATUS_MSG:{
|
||||
unsigned status = msg[1];
|
||||
|
||||
switch (status) {
|
||||
case AUDPP_DEC_STATUS_SLEEP:
|
||||
dprintk("decoder status: sleep \n");
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_INIT:
|
||||
dprintk("decoder status: init \n");
|
||||
audpp_cmd_cfg_routing_mode(audio);
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_CFG:
|
||||
dprintk("decoder status: cfg \n");
|
||||
break;
|
||||
case AUDPP_DEC_STATUS_PLAY:
|
||||
dprintk("decoder status: play \n");
|
||||
if (audio->pcm_feedback) {
|
||||
audamrnb_config_hostpcm(audio);
|
||||
audamrnb_buffer_refresh(audio);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown decoder status \n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n");
|
||||
auddec_dsp_config(audio, 1);
|
||||
audio->out_needed = 0;
|
||||
audio->running = 1;
|
||||
audpp_set_volume_and_pan(audio->dec_id, audio->volume,
|
||||
0);
|
||||
audpp_avsync(audio->dec_id, 22050);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n");
|
||||
audpp_avsync(audio->dec_id, 0);
|
||||
audio->running = 0;
|
||||
} else {
|
||||
pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDPP_MSG_ROUTING_ACK:
|
||||
dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
|
||||
audpp_cmd_cfg_adec_params(audio);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct msm_adsp_ops audplay_adsp_ops_amrnb = {
|
||||
.event = audplay_dsp_event,
|
||||
};
|
||||
|
||||
#define audplay_send_queue0(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
|
||||
cmd, len)
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable)
|
||||
{
|
||||
audpp_cmd_cfg_dec_type cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
|
||||
if (enable)
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
|
||||
AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB;
|
||||
else
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
|
||||
|
||||
return audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_cfg_adec_params_amrnb cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
|
||||
cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
|
||||
cmd.common.dec_id = audio->dec_id;
|
||||
cmd.common.input_sampling_frequency = 8000;
|
||||
cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
|
||||
|
||||
audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_routing_mode cmd;
|
||||
dprintk("audpp_cmd_cfg_routing_mode()\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
|
||||
cmd.object_number = audio->dec_id;
|
||||
if (audio->pcm_feedback)
|
||||
cmd.routing_mode = ROUTING_MODE_FTRT;
|
||||
else
|
||||
cmd.routing_mode = ROUTING_MODE_RT;
|
||||
|
||||
audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audplay_dsp_send_data_avail(struct audio *audio,
|
||||
unsigned idx, unsigned len)
|
||||
{
|
||||
audplay_cmd_bitstream_data_avail cmd;
|
||||
|
||||
cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
|
||||
cmd.decoder_id = audio->dec_id;
|
||||
cmd.buf_ptr = audio->out[idx].addr;
|
||||
cmd.buf_size = len / 2;
|
||||
cmd.partition_number = 0;
|
||||
return audplay_send_queue0(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audamrnb_buffer_refresh(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_buffer_refresh refresh_cmd;
|
||||
|
||||
refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
|
||||
refresh_cmd.num_buffers = 1;
|
||||
refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
|
||||
refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
|
||||
(audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ);
|
||||
refresh_cmd.buf_read_count = 0;
|
||||
dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
|
||||
refresh_cmd.buf0_address, refresh_cmd.buf0_length);
|
||||
(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
|
||||
}
|
||||
|
||||
static void audamrnb_config_hostpcm(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
|
||||
|
||||
dprintk("audamrnb_config_hostpcm()\n");
|
||||
cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
|
||||
cfg_cmd.max_buffers = audio->pcm_buf_count;
|
||||
cfg_cmd.byte_swap = 0;
|
||||
cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
|
||||
cfg_cmd.feedback_frequency = 1;
|
||||
cfg_cmd.partition_number = 0;
|
||||
(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
|
||||
|
||||
}
|
||||
|
||||
static void audamrnb_send_data(struct audio *audio, unsigned needed)
|
||||
{
|
||||
struct buffer *frame;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (!audio->running)
|
||||
goto done;
|
||||
|
||||
if (needed) {
|
||||
/* We were called from the callback because the DSP
|
||||
* requested more data. Note that the DSP does want
|
||||
* more data, and if a buffer was in-flight, mark it
|
||||
* as available (since the DSP must now be done with
|
||||
* it).
|
||||
*/
|
||||
audio->out_needed = 1;
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used == 0xffffffff) {
|
||||
frame->used = 0;
|
||||
audio->out_tail ^= 1;
|
||||
wake_up(&audio->write_wait);
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->out_needed) {
|
||||
/* If the DSP currently wants data and we have a
|
||||
* buffer available, we will send it and reset
|
||||
* the needed flag. We'll mark the buffer as in-flight
|
||||
* so that it won't be recycled until the next buffer
|
||||
* is requested
|
||||
*/
|
||||
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used) {
|
||||
BUG_ON(frame->used == 0xffffffff);
|
||||
/* printk("frame %d busy\n", audio->out_tail); */
|
||||
audplay_dsp_send_data_avail(audio, audio->out_tail,
|
||||
frame->used);
|
||||
frame->used = 0xffffffff;
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static void audamrnb_flush(struct audio *audio)
|
||||
{
|
||||
audio->out[0].used = 0;
|
||||
audio->out[1].used = 0;
|
||||
audio->out_head = 0;
|
||||
audio->out_tail = 0;
|
||||
audio->stopped = 0;
|
||||
atomic_set(&audio->out_bytes, 0);
|
||||
}
|
||||
|
||||
static void audamrnb_flush_pcm_buf(struct audio *audio)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
|
||||
audio->in[index].used = 0;
|
||||
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
}
|
||||
|
||||
static long audamrnb_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
dprintk("audamrnb_ioctl() cmd = %d\n", cmd);
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
|
||||
stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
|
||||
if (copy_to_user((void *)arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (cmd == AUDIO_SET_VOLUME) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->volume = arg;
|
||||
if (audio->running)
|
||||
audpp_set_volume_and_pan(audio->dec_id, arg, 0);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audamrnb_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audamrnb_disable(audio);
|
||||
audio->stopped = 1;
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
if (audio->stopped) {
|
||||
/* Make sure we're stopped and we wake any threads
|
||||
* that might be blocked holding the write_lock.
|
||||
* While audio->stopped write threads will always
|
||||
* exit immediately.
|
||||
*/
|
||||
wake_up(&audio->write_wait);
|
||||
mutex_lock(&audio->write_lock);
|
||||
audamrnb_flush(audio);
|
||||
mutex_unlock(&audio->write_lock);
|
||||
wake_up(&audio->read_wait);
|
||||
mutex_lock(&audio->read_lock);
|
||||
audamrnb_flush_pcm_buf(audio);
|
||||
mutex_unlock(&audio->read_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
case AUDIO_SET_CONFIG:{
|
||||
dprintk("AUDIO_SET_CONFIG not applicable \n");
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG:{
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = 8000;
|
||||
config.channel_count = 1;
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
config.unused[3] = 0;
|
||||
if (copy_to_user((void *)arg, &config,
|
||||
sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
config.pcm_feedback = 0;
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
if (copy_to_user((void *)arg, &config,
|
||||
sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
if (copy_from_user
|
||||
(&config, (void *)arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
|
||||
(config.buffer_count == 1))
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
|
||||
if (config.buffer_size < PCM_BUFSZ_MIN)
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
|
||||
/* Check if pcm feedback is required */
|
||||
if ((config.pcm_feedback) && (!audio->read_data)) {
|
||||
dprintk("audamrnb_ioctl: allocate PCM buf %d\n",
|
||||
config.buffer_count *
|
||||
config.buffer_size);
|
||||
audio->read_data =
|
||||
dma_alloc_coherent(NULL,
|
||||
config.buffer_size *
|
||||
config.buffer_count,
|
||||
&audio->read_phys,
|
||||
GFP_KERNEL);
|
||||
if (!audio->read_data) {
|
||||
pr_err("audamrnb_ioctl: no mem for pcm buf\n");
|
||||
rc = -1;
|
||||
} else {
|
||||
uint8_t index;
|
||||
uint32_t offset = 0;
|
||||
audio->pcm_feedback = 1;
|
||||
audio->buf_refresh = 0;
|
||||
audio->pcm_buf_count =
|
||||
config.buffer_count;
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
|
||||
for (index = 0;
|
||||
index < config.buffer_count; index++) {
|
||||
audio->in[index].data =
|
||||
audio->read_data + offset;
|
||||
audio->in[index].addr =
|
||||
audio->read_phys + offset;
|
||||
audio->in[index].size =
|
||||
config.buffer_size;
|
||||
audio->in[index].used = 0;
|
||||
offset += config.buffer_size;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
int rc = 0;
|
||||
|
||||
if (!audio->pcm_feedback)
|
||||
return 0; /* PCM feedback is not enabled. Nothing to read */
|
||||
|
||||
mutex_lock(&audio->read_lock);
|
||||
dprintk("audamrnb_read() %d \n", count);
|
||||
while (count > 0) {
|
||||
rc = wait_event_interruptible(audio->read_wait,
|
||||
(audio->in[audio->read_next].
|
||||
used > 0) || (audio->stopped));
|
||||
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count < audio->in[audio->read_next].used) {
|
||||
/* Read must happen in frame boundary. Since driver does
|
||||
* not know frame size, read count must be greater or
|
||||
* equal to size of PCM samples
|
||||
*/
|
||||
dprintk("audamrnb_read:read stop - partial frame\n");
|
||||
break;
|
||||
} else {
|
||||
dprintk("audamrnb_read: read from in[%d]\n",
|
||||
audio->read_next);
|
||||
if (copy_to_user
|
||||
(buf, audio->in[audio->read_next].data,
|
||||
audio->in[audio->read_next].used)) {
|
||||
pr_err("audamrnb_read: invalid addr %x \n",
|
||||
(unsigned int)buf);
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
count -= audio->in[audio->read_next].used;
|
||||
buf += audio->in[audio->read_next].used;
|
||||
audio->in[audio->read_next].used = 0;
|
||||
if ((++audio->read_next) == audio->pcm_buf_count)
|
||||
audio->read_next = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->buf_refresh) {
|
||||
audio->buf_refresh = 0;
|
||||
dprintk("audamrnb_read: kick start pcm feedback again\n");
|
||||
audamrnb_buffer_refresh(audio);
|
||||
}
|
||||
|
||||
mutex_unlock(&audio->read_lock);
|
||||
|
||||
if (buf > start)
|
||||
rc = buf - start;
|
||||
|
||||
dprintk("audamrnb_read: read %d bytes\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audamrnb_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
struct buffer *frame;
|
||||
size_t xfer;
|
||||
int rc = 0;
|
||||
|
||||
if (count & 1)
|
||||
return -EINVAL;
|
||||
dprintk("audamrnb_write() \n");
|
||||
mutex_lock(&audio->write_lock);
|
||||
while (count > 0) {
|
||||
frame = audio->out + audio->out_head;
|
||||
rc = wait_event_interruptible(audio->write_wait,
|
||||
(frame->used == 0)
|
||||
|| (audio->stopped));
|
||||
dprintk("audamrnb_write() buffer available\n");
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
xfer = (count > frame->size) ? frame->size : count;
|
||||
if (copy_from_user(frame->data, buf, xfer)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
frame->used = xfer;
|
||||
audio->out_head ^= 1;
|
||||
count -= xfer;
|
||||
buf += xfer;
|
||||
|
||||
audamrnb_send_data(audio, 0);
|
||||
|
||||
}
|
||||
mutex_unlock(&audio->write_lock);
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audamrnb_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
|
||||
dprintk("audamrnb_release()\n");
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
audamrnb_disable(audio);
|
||||
audamrnb_flush(audio);
|
||||
audamrnb_flush_pcm_buf(audio);
|
||||
msm_adsp_put(audio->audplay);
|
||||
audio->audplay = NULL;
|
||||
audio->opened = 0;
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
audio->data = NULL;
|
||||
if (audio->read_data != NULL) {
|
||||
dma_free_coherent(NULL,
|
||||
audio->in[0].size * audio->pcm_buf_count,
|
||||
audio->read_data, audio->read_phys);
|
||||
audio->read_data = NULL;
|
||||
}
|
||||
audio->pcm_feedback = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio the_amrnb_audio;
|
||||
|
||||
static int audamrnb_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_amrnb_audio;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
|
||||
if (audio->opened) {
|
||||
pr_err("audio: busy\n");
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!audio->data) {
|
||||
audio->data = dma_alloc_coherent(NULL, DMASZ,
|
||||
&audio->phys, GFP_KERNEL);
|
||||
if (!audio->data) {
|
||||
pr_err("audio: could not allocate DMA buffers\n");
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
|
||||
&audplay_adsp_ops_amrnb, audio);
|
||||
if (rc) {
|
||||
pr_err("audio: failed to get audplay0 dsp module\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
audio->data = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
audio->dec_id = 0;
|
||||
|
||||
audio->out[0].data = audio->data + 0;
|
||||
audio->out[0].addr = audio->phys + 0;
|
||||
audio->out[0].size = BUFSZ;
|
||||
|
||||
audio->out[1].data = audio->data + BUFSZ;
|
||||
audio->out[1].addr = audio->phys + BUFSZ;
|
||||
audio->out[1].size = BUFSZ;
|
||||
|
||||
audio->volume = 0x2000; /* Q13 1.0 */
|
||||
|
||||
audamrnb_flush(audio);
|
||||
|
||||
file->private_data = audio;
|
||||
audio->opened = 1;
|
||||
rc = 0;
|
||||
done:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations audio_amrnb_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audamrnb_open,
|
||||
.release = audamrnb_release,
|
||||
.read = audamrnb_read,
|
||||
.write = audamrnb_write,
|
||||
.unlocked_ioctl = audamrnb_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_amrnb_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_amrnb",
|
||||
.fops = &audio_amrnb_fops,
|
||||
};
|
||||
|
||||
static int __init audamrnb_init(void)
|
||||
{
|
||||
mutex_init(&the_amrnb_audio.lock);
|
||||
mutex_init(&the_amrnb_audio.write_lock);
|
||||
mutex_init(&the_amrnb_audio.read_lock);
|
||||
spin_lock_init(&the_amrnb_audio.dsp_lock);
|
||||
init_waitqueue_head(&the_amrnb_audio.write_wait);
|
||||
init_waitqueue_head(&the_amrnb_audio.read_wait);
|
||||
the_amrnb_audio.read_data = NULL;
|
||||
return misc_register(&audio_amrnb_misc);
|
||||
}
|
||||
|
||||
static void __exit audamrnb_exit(void)
|
||||
{
|
||||
misc_deregister(&audio_amrnb_misc);
|
||||
}
|
||||
|
||||
module_init(audamrnb_init);
|
||||
module_exit(audamrnb_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM AMR-NB driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("QUALCOMM Inc");
|
|
@ -1,847 +0,0 @@
|
|||
/* arch/arm/mach-msm/audio_evrc.c
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM USA, INC.
|
||||
*
|
||||
* This code also borrows from audio_aac.c, which is
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC 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.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
#include <mach/qdsp5/qdsp5audplaycmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audplaymsg.h>
|
||||
|
||||
#include "adsp.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintk(format, arg...) \
|
||||
printk(KERN_DEBUG format, ## arg)
|
||||
#else
|
||||
#define dprintk(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/* Hold 30 packets of 24 bytes each*/
|
||||
#define BUFSZ 720
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
|
||||
#define AUDDEC_DEC_EVRC 12
|
||||
|
||||
#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
|
||||
#define PCM_BUF_MAX_COUNT 5
|
||||
/* DSP only accepts 5 buffers at most
|
||||
* but support 2 buffers currently
|
||||
*/
|
||||
#define EVRC_DECODED_FRSZ 320 /* EVRC 20ms 8KHz mono PCM size */
|
||||
|
||||
#define ROUTING_MODE_FTRT 1
|
||||
#define ROUTING_MODE_RT 2
|
||||
/* Decoder status received from AUDPPTASK */
|
||||
#define AUDPP_DEC_STATUS_SLEEP 0
|
||||
#define AUDPP_DEC_STATUS_INIT 1
|
||||
#define AUDPP_DEC_STATUS_CFG 2
|
||||
#define AUDPP_DEC_STATUS_PLAY 3
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
unsigned size;
|
||||
unsigned used; /* Input usage actual DSP produced PCM size */
|
||||
unsigned addr;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
struct buffer out[2];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
uint8_t out_head;
|
||||
uint8_t out_tail;
|
||||
uint8_t out_needed; /* number of buffers the dsp is waiting for */
|
||||
|
||||
atomic_t out_bytes;
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex write_lock;
|
||||
wait_queue_head_t write_wait;
|
||||
|
||||
/* Host PCM section */
|
||||
struct buffer in[PCM_BUF_MAX_COUNT];
|
||||
struct mutex read_lock;
|
||||
wait_queue_head_t read_wait; /* Wait queue for read */
|
||||
char *read_data; /* pointer to reader buffer */
|
||||
dma_addr_t read_phys; /* physical address of reader buffer */
|
||||
uint8_t read_next; /* index to input buffers to be read next */
|
||||
uint8_t fill_next; /* index to buffer that DSP should be filling */
|
||||
uint8_t pcm_buf_count; /* number of pcm buffer allocated */
|
||||
/* ---- End of Host PCM section */
|
||||
|
||||
struct msm_adsp_module *audplay;
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
uint8_t opened:1;
|
||||
uint8_t enabled:1;
|
||||
uint8_t running:1;
|
||||
uint8_t stopped:1; /* set when stopped, cleared on flush */
|
||||
uint8_t pcm_feedback:1;
|
||||
uint8_t buf_refresh:1;
|
||||
|
||||
unsigned volume;
|
||||
uint16_t dec_id;
|
||||
uint32_t read_ptr_offset;
|
||||
};
|
||||
static struct audio the_evrc_audio;
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable);
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio);
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio);
|
||||
static void audevrc_send_data(struct audio *audio, unsigned needed);
|
||||
static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
|
||||
static void audevrc_config_hostpcm(struct audio *audio);
|
||||
static void audevrc_buffer_refresh(struct audio *audio);
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audevrc_enable(struct audio *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
audio->out_tail = 0;
|
||||
audio->out_needed = 0;
|
||||
|
||||
cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_EVRC;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msm_adsp_enable(audio->audplay)) {
|
||||
pr_err("audio: msm_adsp_enable(audplay) failed\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) {
|
||||
pr_err("audio: audpp_enable() failed\n");
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
audio->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audevrc_disable(struct audio *audio)
|
||||
{
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
auddec_dsp_config(audio, 0);
|
||||
wake_up(&audio->write_wait);
|
||||
wake_up(&audio->read_wait);
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audpp_disable(audio->dec_id, audio);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
|
||||
static void audevrc_update_pcm_buf_entry(struct audio *audio,
|
||||
uint32_t *payload)
|
||||
{
|
||||
uint8_t index;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
for (index = 0; index < payload[1]; index++) {
|
||||
if (audio->in[audio->fill_next].addr
|
||||
== payload[2 + index * 2]) {
|
||||
dprintk("audevrc_update_pcm_buf_entry: in[%d] ready\n",
|
||||
audio->fill_next);
|
||||
audio->in[audio->fill_next].used =
|
||||
payload[3 + index * 2];
|
||||
if ((++audio->fill_next) == audio->pcm_buf_count)
|
||||
audio->fill_next = 0;
|
||||
|
||||
} else {
|
||||
pr_err
|
||||
("audevrc_update_pcm_buf_entry: expected=%x ret=%x\n",
|
||||
audio->in[audio->fill_next].addr,
|
||||
payload[1 + index * 2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (audio->in[audio->fill_next].used == 0) {
|
||||
audevrc_buffer_refresh(audio);
|
||||
} else {
|
||||
dprintk("audevrc_update_pcm_buf_entry: read cannot keep up\n");
|
||||
audio->buf_refresh = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
wake_up(&audio->read_wait);
|
||||
}
|
||||
|
||||
static void audplay_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent) (void *ptr, size_t len))
|
||||
{
|
||||
struct audio *audio = data;
|
||||
uint32_t msg[28];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
dprintk("audplay_dsp_event: msg_id=%x\n", id);
|
||||
switch (id) {
|
||||
case AUDPLAY_MSG_DEC_NEEDS_DATA:
|
||||
audevrc_send_data(audio, 1);
|
||||
break;
|
||||
case AUDPLAY_MSG_BUFFER_UPDATE:
|
||||
dprintk("audevrc_update_pcm_buf_entry:======> \n");
|
||||
audevrc_update_pcm_buf_entry(audio, msg);
|
||||
break;
|
||||
default:
|
||||
pr_err("unexpected message from decoder \n");
|
||||
}
|
||||
}
|
||||
|
||||
static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg)
|
||||
{
|
||||
struct audio *audio = private;
|
||||
|
||||
switch (id) {
|
||||
case AUDPP_MSG_STATUS_MSG:{
|
||||
unsigned status = msg[1];
|
||||
|
||||
switch (status) {
|
||||
case AUDPP_DEC_STATUS_SLEEP:
|
||||
dprintk("decoder status: sleep \n");
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_INIT:
|
||||
dprintk("decoder status: init \n");
|
||||
audpp_cmd_cfg_routing_mode(audio);
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_CFG:
|
||||
dprintk("decoder status: cfg \n");
|
||||
break;
|
||||
case AUDPP_DEC_STATUS_PLAY:
|
||||
dprintk("decoder status: play \n");
|
||||
if (audio->pcm_feedback) {
|
||||
audevrc_config_hostpcm(audio);
|
||||
audevrc_buffer_refresh(audio);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown decoder status \n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
dprintk("audevrc_dsp_event: CFG_MSG ENABLE\n");
|
||||
auddec_dsp_config(audio, 1);
|
||||
audio->out_needed = 0;
|
||||
audio->running = 1;
|
||||
audpp_set_volume_and_pan(audio->dec_id, audio->volume,
|
||||
0);
|
||||
audpp_avsync(audio->dec_id, 22050);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
dprintk("audevrc_dsp_event: CFG_MSG DISABLE\n");
|
||||
audpp_avsync(audio->dec_id, 0);
|
||||
audio->running = 0;
|
||||
} else {
|
||||
pr_err("audevrc_dsp_event: CFG_MSG %d?\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDPP_MSG_ROUTING_ACK:
|
||||
dprintk("audevrc_dsp_event: ROUTING_ACK\n");
|
||||
audpp_cmd_cfg_adec_params(audio);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("audevrc_dsp_event: UNKNOWN (%d)\n", id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct msm_adsp_ops audplay_adsp_ops_evrc = {
|
||||
.event = audplay_dsp_event,
|
||||
};
|
||||
|
||||
#define audplay_send_queue0(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
|
||||
cmd, len)
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable)
|
||||
{
|
||||
audpp_cmd_cfg_dec_type cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
|
||||
if (enable)
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
|
||||
AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC;
|
||||
else
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
|
||||
|
||||
return audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_cfg_adec_params_evrc cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
|
||||
cmd.common.length = sizeof(cmd);
|
||||
cmd.common.dec_id = audio->dec_id;
|
||||
cmd.common.input_sampling_frequency = 8000;
|
||||
cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
|
||||
|
||||
audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_routing_mode cmd;
|
||||
dprintk("audpp_cmd_cfg_routing_mode()\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
|
||||
cmd.object_number = audio->dec_id;
|
||||
if (audio->pcm_feedback)
|
||||
cmd.routing_mode = ROUTING_MODE_FTRT;
|
||||
else
|
||||
cmd.routing_mode = ROUTING_MODE_RT;
|
||||
|
||||
audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audplay_dsp_send_data_avail(struct audio *audio,
|
||||
unsigned idx, unsigned len)
|
||||
{
|
||||
audplay_cmd_bitstream_data_avail cmd;
|
||||
|
||||
cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
|
||||
cmd.decoder_id = audio->dec_id;
|
||||
cmd.buf_ptr = audio->out[idx].addr;
|
||||
cmd.buf_size = len / 2;
|
||||
cmd.partition_number = 0;
|
||||
return audplay_send_queue0(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audevrc_buffer_refresh(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_buffer_refresh refresh_cmd;
|
||||
|
||||
refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
|
||||
refresh_cmd.num_buffers = 1;
|
||||
refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
|
||||
refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
|
||||
|
||||
refresh_cmd.buf_read_count = 0;
|
||||
dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
|
||||
refresh_cmd.buf0_address, refresh_cmd.buf0_length);
|
||||
audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
|
||||
}
|
||||
|
||||
static void audevrc_config_hostpcm(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
|
||||
|
||||
dprintk("audevrc_config_hostpcm()\n");
|
||||
cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
|
||||
cfg_cmd.max_buffers = 1;
|
||||
cfg_cmd.byte_swap = 0;
|
||||
cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
|
||||
cfg_cmd.feedback_frequency = 1;
|
||||
cfg_cmd.partition_number = 0;
|
||||
audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
|
||||
|
||||
}
|
||||
|
||||
static void audevrc_send_data(struct audio *audio, unsigned needed)
|
||||
{
|
||||
struct buffer *frame;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (!audio->running)
|
||||
goto done;
|
||||
|
||||
if (needed) {
|
||||
/* We were called from the callback because the DSP
|
||||
* requested more data. Note that the DSP does want
|
||||
* more data, and if a buffer was in-flight, mark it
|
||||
* as available (since the DSP must now be done with
|
||||
* it).
|
||||
*/
|
||||
audio->out_needed = 1;
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used == 0xffffffff) {
|
||||
dprintk("frame %d free\n", audio->out_tail);
|
||||
frame->used = 0;
|
||||
audio->out_tail ^= 1;
|
||||
wake_up(&audio->write_wait);
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->out_needed) {
|
||||
/* If the DSP currently wants data and we have a
|
||||
* buffer available, we will send it and reset
|
||||
* the needed flag. We'll mark the buffer as in-flight
|
||||
* so that it won't be recycled until the next buffer
|
||||
* is requested
|
||||
*/
|
||||
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used) {
|
||||
BUG_ON(frame->used == 0xffffffff);
|
||||
dprintk("frame %d busy\n", audio->out_tail);
|
||||
audplay_dsp_send_data_avail(audio, audio->out_tail,
|
||||
frame->used);
|
||||
frame->used = 0xffffffff;
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static void audevrc_flush(struct audio *audio)
|
||||
{
|
||||
audio->out[0].used = 0;
|
||||
audio->out[1].used = 0;
|
||||
audio->out_head = 0;
|
||||
audio->out_tail = 0;
|
||||
audio->stopped = 0;
|
||||
atomic_set(&audio->out_bytes, 0);
|
||||
}
|
||||
|
||||
static void audevrc_flush_pcm_buf(struct audio *audio)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
|
||||
audio->in[index].used = 0;
|
||||
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
}
|
||||
|
||||
static long audevrc_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
dprintk("audevrc_ioctl() cmd = %d\n", cmd);
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
|
||||
stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
|
||||
if (copy_to_user((void *)arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (cmd == AUDIO_SET_VOLUME) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->volume = arg;
|
||||
if (audio->running)
|
||||
audpp_set_volume_and_pan(audio->dec_id, arg, 0);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audevrc_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audevrc_disable(audio);
|
||||
audio->stopped = 1;
|
||||
break;
|
||||
case AUDIO_SET_CONFIG:{
|
||||
dprintk("AUDIO_SET_CONFIG not applicable \n");
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG:{
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = 8000;
|
||||
config.channel_count = 1;
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
config.unused[3] = 0;
|
||||
if (copy_to_user((void *)arg, &config, sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
config.pcm_feedback = 0;
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
if (copy_to_user((void *)arg, &config, sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
if (copy_from_user
|
||||
(&config, (void *)arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
|
||||
(config.buffer_count == 1))
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
|
||||
if (config.buffer_size < PCM_BUFSZ_MIN)
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
|
||||
/* Check if pcm feedback is required */
|
||||
if ((config.pcm_feedback) && (!audio->read_data)) {
|
||||
dprintk("audevrc_ioctl: allocate PCM buf %d\n",
|
||||
config.buffer_count *
|
||||
config.buffer_size);
|
||||
audio->read_data =
|
||||
dma_alloc_coherent(NULL,
|
||||
config.buffer_size *
|
||||
config.buffer_count,
|
||||
&audio->read_phys,
|
||||
GFP_KERNEL);
|
||||
if (!audio->read_data) {
|
||||
pr_err
|
||||
("audevrc_ioctl: no mem for pcm buf\n");
|
||||
rc = -1;
|
||||
} else {
|
||||
uint8_t index;
|
||||
uint32_t offset = 0;
|
||||
audio->pcm_feedback = 1;
|
||||
audio->buf_refresh = 0;
|
||||
audio->pcm_buf_count =
|
||||
config.buffer_count;
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
|
||||
for (index = 0;
|
||||
index < config.buffer_count;
|
||||
index++) {
|
||||
audio->in[index].data =
|
||||
audio->read_data + offset;
|
||||
audio->in[index].addr =
|
||||
audio->read_phys + offset;
|
||||
audio->in[index].size =
|
||||
config.buffer_size;
|
||||
audio->in[index].used = 0;
|
||||
offset += config.buffer_size;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDIO_PAUSE:
|
||||
dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
|
||||
rc = audpp_pause(audio->dec_id, (int) arg);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
int rc = 0;
|
||||
if (!audio->pcm_feedback) {
|
||||
return 0;
|
||||
/* PCM feedback is not enabled. Nothing to read */
|
||||
}
|
||||
mutex_lock(&audio->read_lock);
|
||||
dprintk("audevrc_read() \n");
|
||||
while (count > 0) {
|
||||
rc = wait_event_interruptible(audio->read_wait,
|
||||
(audio->in[audio->read_next].
|
||||
used > 0) || (audio->stopped));
|
||||
dprintk("audevrc_read() wait terminated \n");
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
if (count < audio->in[audio->read_next].used) {
|
||||
/* Read must happen in frame boundary. Since driver does
|
||||
* not know frame size, read count must be greater or
|
||||
* equal to size of PCM samples
|
||||
*/
|
||||
dprintk("audevrc_read:read stop - partial frame\n");
|
||||
break;
|
||||
} else {
|
||||
dprintk("audevrc_read: read from in[%d]\n",
|
||||
audio->read_next);
|
||||
if (copy_to_user
|
||||
(buf, audio->in[audio->read_next].data,
|
||||
audio->in[audio->read_next].used)) {
|
||||
pr_err("audevrc_read: invalid addr %x \n",
|
||||
(unsigned int)buf);
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
count -= audio->in[audio->read_next].used;
|
||||
buf += audio->in[audio->read_next].used;
|
||||
audio->in[audio->read_next].used = 0;
|
||||
if ((++audio->read_next) == audio->pcm_buf_count)
|
||||
audio->read_next = 0;
|
||||
if (audio->in[audio->read_next].used == 0)
|
||||
break; /* No data ready at this moment
|
||||
* Exit while loop to prevent
|
||||
* output thread sleep too long
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
if (audio->buf_refresh) {
|
||||
audio->buf_refresh = 0;
|
||||
dprintk("audevrc_read: kick start pcm feedback again\n");
|
||||
audevrc_buffer_refresh(audio);
|
||||
}
|
||||
mutex_unlock(&audio->read_lock);
|
||||
if (buf > start)
|
||||
rc = buf - start;
|
||||
dprintk("audevrc_read: read %d bytes\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audevrc_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
struct buffer *frame;
|
||||
size_t xfer;
|
||||
int rc = 0;
|
||||
|
||||
if (count & 1)
|
||||
return -EINVAL;
|
||||
mutex_lock(&audio->write_lock);
|
||||
dprintk("audevrc_write() \n");
|
||||
while (count > 0) {
|
||||
frame = audio->out + audio->out_head;
|
||||
rc = wait_event_interruptible(audio->write_wait,
|
||||
(frame->used == 0)
|
||||
|| (audio->stopped));
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
xfer = (count > frame->size) ? frame->size : count;
|
||||
if (copy_from_user(frame->data, buf, xfer)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
frame->used = xfer;
|
||||
audio->out_head ^= 1;
|
||||
count -= xfer;
|
||||
buf += xfer;
|
||||
|
||||
audevrc_send_data(audio, 0);
|
||||
|
||||
}
|
||||
mutex_unlock(&audio->write_lock);
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audevrc_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
|
||||
dprintk("audevrc_release()\n");
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
audevrc_disable(audio);
|
||||
audevrc_flush(audio);
|
||||
audevrc_flush_pcm_buf(audio);
|
||||
msm_adsp_put(audio->audplay);
|
||||
audio->audplay = NULL;
|
||||
audio->opened = 0;
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
audio->data = NULL;
|
||||
if (audio->read_data != NULL) {
|
||||
dma_free_coherent(NULL,
|
||||
audio->in[0].size * audio->pcm_buf_count,
|
||||
audio->read_data, audio->read_phys);
|
||||
audio->read_data = NULL;
|
||||
}
|
||||
audio->pcm_feedback = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio the_evrc_audio;
|
||||
|
||||
static int audevrc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_evrc_audio;
|
||||
int rc;
|
||||
|
||||
if (audio->opened) {
|
||||
pr_err("audio: busy\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Acquire Lock */
|
||||
mutex_lock(&audio->lock);
|
||||
|
||||
if (!audio->data) {
|
||||
audio->data = dma_alloc_coherent(NULL, DMASZ,
|
||||
&audio->phys, GFP_KERNEL);
|
||||
if (!audio->data) {
|
||||
pr_err("audio: could not allocate DMA buffers\n");
|
||||
rc = -ENOMEM;
|
||||
goto dma_fail;
|
||||
}
|
||||
}
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc)
|
||||
goto audmgr_fail;
|
||||
|
||||
rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
|
||||
&audplay_adsp_ops_evrc, audio);
|
||||
if (rc) {
|
||||
pr_err("audio: failed to get audplay0 dsp module\n");
|
||||
goto adsp_fail;
|
||||
}
|
||||
|
||||
audio->dec_id = 0;
|
||||
|
||||
audio->out[0].data = audio->data + 0;
|
||||
audio->out[0].addr = audio->phys + 0;
|
||||
audio->out[0].size = BUFSZ;
|
||||
|
||||
audio->out[1].data = audio->data + BUFSZ;
|
||||
audio->out[1].addr = audio->phys + BUFSZ;
|
||||
audio->out[1].size = BUFSZ;
|
||||
|
||||
audio->volume = 0x3FFF;
|
||||
|
||||
audevrc_flush(audio);
|
||||
|
||||
audio->opened = 1;
|
||||
file->private_data = audio;
|
||||
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
|
||||
adsp_fail:
|
||||
audmgr_close(&audio->audmgr);
|
||||
audmgr_fail:
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
dma_fail:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations audio_evrc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audevrc_open,
|
||||
.release = audevrc_release,
|
||||
.read = audevrc_read,
|
||||
.write = audevrc_write,
|
||||
.unlocked_ioctl = audevrc_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_evrc_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_evrc",
|
||||
.fops = &audio_evrc_fops,
|
||||
};
|
||||
|
||||
static int __init audevrc_init(void)
|
||||
{
|
||||
mutex_init(&the_evrc_audio.lock);
|
||||
mutex_init(&the_evrc_audio.write_lock);
|
||||
mutex_init(&the_evrc_audio.read_lock);
|
||||
spin_lock_init(&the_evrc_audio.dsp_lock);
|
||||
init_waitqueue_head(&the_evrc_audio.write_wait);
|
||||
init_waitqueue_head(&the_evrc_audio.read_wait);
|
||||
the_evrc_audio.read_data = NULL;
|
||||
return misc_register(&audio_evrc_misc);
|
||||
}
|
||||
|
||||
static void __exit audevrc_exit(void)
|
||||
{
|
||||
misc_deregister(&audio_evrc_misc);
|
||||
}
|
||||
|
||||
module_init(audevrc_init);
|
||||
module_exit(audevrc_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM EVRC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("QUALCOMM Inc");
|
|
@ -1,970 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audio_in.c
|
||||
*
|
||||
* pcm audio input device
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC 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/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audpreproccmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audpreprocmsg.h>
|
||||
#include <mach/qdsp5/qdsp5audreccmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audrecmsg.h>
|
||||
|
||||
/* for queue ids - should be relative to module number*/
|
||||
#include "adsp.h"
|
||||
|
||||
/* FRAME_NUM must be a power of two */
|
||||
#define FRAME_NUM (8)
|
||||
#define FRAME_SIZE (2052 * 2)
|
||||
#define MONO_DATA_SIZE (2048)
|
||||
#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2)
|
||||
#define DMASZ (FRAME_SIZE * FRAME_NUM)
|
||||
|
||||
#define AGC_PARAM_SIZE (20)
|
||||
#define NS_PARAM_SIZE (6)
|
||||
#define IIR_PARAM_SIZE (48)
|
||||
#define DEBUG (0)
|
||||
|
||||
#define AGC_ENABLE 0x0001
|
||||
#define NS_ENABLE 0x0002
|
||||
#define IIR_ENABLE 0x0004
|
||||
|
||||
struct tx_agc_config {
|
||||
uint16_t agc_params[AGC_PARAM_SIZE];
|
||||
};
|
||||
|
||||
struct ns_config {
|
||||
uint16_t ns_params[NS_PARAM_SIZE];
|
||||
};
|
||||
|
||||
struct tx_iir_filter {
|
||||
uint16_t num_bands;
|
||||
uint16_t iir_params[IIR_PARAM_SIZE];
|
||||
};
|
||||
|
||||
struct audpre_cmd_iir_config_type {
|
||||
uint16_t cmd_id;
|
||||
uint16_t active_flag;
|
||||
uint16_t num_bands;
|
||||
uint16_t iir_params[IIR_PARAM_SIZE];
|
||||
};
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
uint32_t size;
|
||||
uint32_t read;
|
||||
uint32_t addr;
|
||||
};
|
||||
|
||||
struct audio_in {
|
||||
struct buffer in[FRAME_NUM];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
atomic_t in_bytes;
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex read_lock;
|
||||
wait_queue_head_t wait;
|
||||
|
||||
struct msm_adsp_module *audpre;
|
||||
struct msm_adsp_module *audrec;
|
||||
|
||||
/* configuration to use on next enable */
|
||||
uint32_t samp_rate;
|
||||
uint32_t channel_mode;
|
||||
uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
|
||||
uint32_t type; /* 0 for PCM ,1 for AAC */
|
||||
uint32_t dsp_cnt;
|
||||
uint32_t in_head; /* next buffer dsp will write */
|
||||
uint32_t in_tail; /* next buffer read() will read */
|
||||
uint32_t in_count; /* number of buffers available to read() */
|
||||
|
||||
unsigned short samp_rate_index;
|
||||
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
int opened;
|
||||
int enabled;
|
||||
int running;
|
||||
int stopped; /* set when stopped, cleared on flush */
|
||||
|
||||
/* audpre settings */
|
||||
int agc_enable;
|
||||
struct tx_agc_config agc;
|
||||
|
||||
int ns_enable;
|
||||
struct ns_config ns;
|
||||
|
||||
int iir_enable;
|
||||
struct tx_iir_filter iir;
|
||||
};
|
||||
|
||||
static int audio_in_dsp_enable(struct audio_in *audio, int enable);
|
||||
static int audio_in_encoder_config(struct audio_in *audio);
|
||||
static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
|
||||
static void audio_flush(struct audio_in *audio);
|
||||
static int audio_dsp_set_agc(struct audio_in *audio);
|
||||
static int audio_dsp_set_ns(struct audio_in *audio);
|
||||
static int audio_dsp_set_tx_iir(struct audio_in *audio);
|
||||
|
||||
static unsigned convert_dsp_samp_index(unsigned index)
|
||||
{
|
||||
switch (index) {
|
||||
case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000;
|
||||
case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100;
|
||||
case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000;
|
||||
case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000;
|
||||
case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050;
|
||||
case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000;
|
||||
case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000;
|
||||
case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025;
|
||||
case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000;
|
||||
default: return AUDREC_CMD_SAMP_RATE_INDX_11025;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned convert_samp_rate(unsigned hz)
|
||||
{
|
||||
switch (hz) {
|
||||
case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
|
||||
case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
|
||||
case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
|
||||
case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
|
||||
case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
|
||||
case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
|
||||
case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
|
||||
case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000;
|
||||
default: return RPC_AUD_DEF_SAMPLE_RATE_11025;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned convert_samp_index(unsigned index)
|
||||
{
|
||||
switch (index) {
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025;
|
||||
case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000;
|
||||
default: return 11025;
|
||||
}
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_in_enable(struct audio_in *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
cfg.tx_rate = audio->samp_rate;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
|
||||
if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_PCM;
|
||||
else
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_AAC;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msm_adsp_enable(audio->audpre)) {
|
||||
pr_err("audrec: msm_adsp_enable(audpre) failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (msm_adsp_enable(audio->audrec)) {
|
||||
pr_err("audrec: msm_adsp_enable(audrec) failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
audio->enabled = 1;
|
||||
audio_in_dsp_enable(audio, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_in_disable(struct audio_in *audio)
|
||||
{
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
|
||||
audio_in_dsp_enable(audio, 0);
|
||||
|
||||
wake_up(&audio->wait);
|
||||
|
||||
msm_adsp_disable(audio->audrec);
|
||||
msm_adsp_disable(audio->audpre);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
static void audpre_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
uint16_t msg[2];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
switch (id) {
|
||||
case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
|
||||
pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
|
||||
break;
|
||||
case AUDPREPROC_MSG_ERROR_MSG_ID:
|
||||
pr_info("audpre: err_index %d\n", msg[0]);
|
||||
break;
|
||||
default:
|
||||
pr_err("audpre: unknown event %d\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
struct audio_frame {
|
||||
uint16_t count_low;
|
||||
uint16_t count_high;
|
||||
uint16_t bytes;
|
||||
uint16_t unknown;
|
||||
unsigned char samples[];
|
||||
} __attribute__((packed));
|
||||
|
||||
static void audio_in_get_dsp_frames(struct audio_in *audio)
|
||||
{
|
||||
struct audio_frame *frame;
|
||||
uint32_t index;
|
||||
unsigned long flags;
|
||||
|
||||
index = audio->in_head;
|
||||
|
||||
/* XXX check for bogus frame size? */
|
||||
|
||||
frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame));
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->in[index].size = frame->bytes;
|
||||
|
||||
audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
|
||||
|
||||
/* If overflow, move the tail index foward. */
|
||||
if (audio->in_head == audio->in_tail)
|
||||
audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
|
||||
else
|
||||
audio->in_count++;
|
||||
|
||||
audio_dsp_read_buffer(audio, audio->dsp_cnt++);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
|
||||
wake_up(&audio->wait);
|
||||
}
|
||||
|
||||
static void audrec_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
struct audio_in *audio = data;
|
||||
uint16_t msg[3];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
switch (id) {
|
||||
case AUDREC_MSG_CMD_CFG_DONE_MSG:
|
||||
if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) {
|
||||
if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) {
|
||||
pr_info("audpre: CFG ENABLED\n");
|
||||
audio_dsp_set_agc(audio);
|
||||
audio_dsp_set_ns(audio);
|
||||
audio_dsp_set_tx_iir(audio);
|
||||
audio_in_encoder_config(audio);
|
||||
} else {
|
||||
pr_info("audrec: CFG SLEEP\n");
|
||||
audio->running = 0;
|
||||
}
|
||||
} else {
|
||||
pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
|
||||
pr_info("audrec: PARAM CFG DONE\n");
|
||||
audio->running = 1;
|
||||
break;
|
||||
}
|
||||
case AUDREC_MSG_FATAL_ERR_MSG:
|
||||
pr_err("audrec: ERROR %x\n", msg[0]);
|
||||
break;
|
||||
case AUDREC_MSG_PACKET_READY_MSG:
|
||||
/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */
|
||||
audio_in_get_dsp_frames(audio);
|
||||
break;
|
||||
default:
|
||||
pr_err("audrec: unknown event %d\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
struct msm_adsp_ops audpre_adsp_ops = {
|
||||
.event = audpre_dsp_event,
|
||||
};
|
||||
|
||||
struct msm_adsp_ops audrec_adsp_ops = {
|
||||
.event = audrec_dsp_event,
|
||||
};
|
||||
|
||||
|
||||
#define audio_send_queue_pre(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
|
||||
#define audio_send_queue_recbs(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len)
|
||||
#define audio_send_queue_rec(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audrec, \
|
||||
QDSP_uPAudRecCmdQueue, cmd, len)
|
||||
|
||||
static int audio_dsp_set_agc(struct audio_in *audio)
|
||||
{
|
||||
audpreproc_cmd_cfg_agc_params cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
|
||||
|
||||
if (audio->agc_enable) {
|
||||
/* cmd.tx_agc_param_mask = 0xFE00 from sample code */
|
||||
cmd.tx_agc_param_mask =
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) |
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
|
||||
cmd.tx_agc_enable_flag =
|
||||
AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
|
||||
memcpy(&cmd.static_gain, &audio->agc.agc_params[0],
|
||||
sizeof(uint16_t) * 6);
|
||||
/* cmd.param_mask = 0xFFF0 from sample code */
|
||||
cmd.param_mask =
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) |
|
||||
(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK);
|
||||
memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6],
|
||||
sizeof(uint16_t) * 14);
|
||||
|
||||
} else {
|
||||
cmd.tx_agc_param_mask =
|
||||
(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
|
||||
cmd.tx_agc_enable_flag =
|
||||
AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
|
||||
}
|
||||
#if DEBUG
|
||||
pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
|
||||
pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask);
|
||||
pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag);
|
||||
pr_info("static_gain = 0x%04x\n", cmd.static_gain);
|
||||
pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag);
|
||||
pr_info("expander_th = 0x%04x\n", cmd.expander_th);
|
||||
pr_info("expander_slope = 0x%04x\n", cmd.expander_slope);
|
||||
pr_info("compressor_th = 0x%04x\n", cmd.compressor_th);
|
||||
pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope);
|
||||
pr_info("param_mask = 0x%04x\n", cmd.param_mask);
|
||||
pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk);
|
||||
pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down);
|
||||
pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up);
|
||||
pr_info("aig_max = 0x%04x\n", cmd.aig_max);
|
||||
pr_info("aig_min = 0x%04x\n", cmd.aig_min);
|
||||
pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek);
|
||||
pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast);
|
||||
pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow);
|
||||
pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw);
|
||||
pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw);
|
||||
pr_info("delay = 0x%04x\n", cmd.delay);
|
||||
pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw);
|
||||
pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw);
|
||||
pr_info("rms_tav = 0x%04x\n", cmd.rms_tav);
|
||||
#endif
|
||||
return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_set_ns(struct audio_in *audio)
|
||||
{
|
||||
audpreproc_cmd_cfg_ns_params cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
|
||||
|
||||
if (audio->ns_enable) {
|
||||
/* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */
|
||||
cmd.ec_mode_new =
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA;
|
||||
memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params,
|
||||
sizeof(audio->ns.ns_params));
|
||||
} else {
|
||||
cmd.ec_mode_new =
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS |
|
||||
AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS;
|
||||
}
|
||||
#if DEBUG
|
||||
pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
|
||||
pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new);
|
||||
pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n);
|
||||
pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size);
|
||||
pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns);
|
||||
pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d);
|
||||
pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e);
|
||||
pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n);
|
||||
#endif
|
||||
return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_set_tx_iir(struct audio_in *audio)
|
||||
{
|
||||
struct audpre_cmd_iir_config_type cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
|
||||
|
||||
if (audio->iir_enable) {
|
||||
cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
|
||||
cmd.num_bands = audio->iir.num_bands;
|
||||
memcpy(&cmd.iir_params, &audio->iir.iir_params,
|
||||
sizeof(audio->iir.iir_params));
|
||||
} else {
|
||||
cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;
|
||||
}
|
||||
#if DEBUG
|
||||
pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
|
||||
pr_info("active_flag = 0x%04x\n", cmd.active_flag);
|
||||
#endif
|
||||
return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_in_dsp_enable(struct audio_in *audio, int enable)
|
||||
{
|
||||
audrec_cmd_cfg cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDREC_CMD_CFG;
|
||||
cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS;
|
||||
cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type);
|
||||
cmd.type_1 = 0;
|
||||
|
||||
return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_in_encoder_config(struct audio_in *audio)
|
||||
{
|
||||
audrec_cmd_arec0param_cfg cmd;
|
||||
uint16_t *data = (void *) audio->data;
|
||||
unsigned n;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG;
|
||||
cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16;
|
||||
cmd.ptr_to_extpkt_buffer_lsw = audio->phys;
|
||||
cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */
|
||||
cmd.samp_rate_index = audio->samp_rate_index;
|
||||
cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */
|
||||
|
||||
/* FIXME have no idea why cmd.rec_quality is fixed
|
||||
* as 0x1C00 from sample code
|
||||
*/
|
||||
cmd.rec_quality = 0x1C00;
|
||||
|
||||
/* prepare buffer pointers:
|
||||
* Mono: 1024 samples + 4 halfword header
|
||||
* Stereo: 2048 samples + 4 halfword header
|
||||
* AAC
|
||||
* Mono/Stere: 768 + 4 halfword header
|
||||
*/
|
||||
for (n = 0; n < FRAME_NUM; n++) {
|
||||
audio->in[n].data = data + 4;
|
||||
if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
|
||||
data += (4 + (audio->channel_mode ? 2048 : 1024));
|
||||
else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
|
||||
data += (4 + 768);
|
||||
}
|
||||
|
||||
return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
|
||||
{
|
||||
audrec_cmd_packet_ext_ptr cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
|
||||
/* Both WAV and AAC use AUDREC_CMD_TYPE_0 */
|
||||
cmd.type = AUDREC_CMD_TYPE_0;
|
||||
cmd.curr_rec_count_msw = read_cnt >> 16;
|
||||
cmd.curr_rec_count_lsw = read_cnt;
|
||||
|
||||
return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static void audio_enable_agc(struct audio_in *audio, int enable)
|
||||
{
|
||||
if (audio->agc_enable != enable) {
|
||||
audio->agc_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_agc(audio);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_enable_ns(struct audio_in *audio, int enable)
|
||||
{
|
||||
if (audio->ns_enable != enable) {
|
||||
audio->ns_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_ns(audio);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_enable_tx_iir(struct audio_in *audio, int enable)
|
||||
{
|
||||
if (audio->iir_enable != enable) {
|
||||
audio->iir_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_tx_iir(audio);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_flush(struct audio_in *audio)
|
||||
{
|
||||
int i;
|
||||
|
||||
audio->dsp_cnt = 0;
|
||||
audio->in_head = 0;
|
||||
audio->in_tail = 0;
|
||||
audio->in_count = 0;
|
||||
for (i = 0; i < FRAME_NUM; i++) {
|
||||
audio->in[i].size = 0;
|
||||
audio->in[i].read = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static long audio_in_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct audio_in *audio = file->private_data;
|
||||
int rc;
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = atomic_read(&audio->in_bytes);
|
||||
if (copy_to_user((void *) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audio_in_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audio_in_disable(audio);
|
||||
audio->stopped = 1;
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
if (audio->stopped) {
|
||||
/* Make sure we're stopped and we wake any threads
|
||||
* that might be blocked holding the read_lock.
|
||||
* While audio->stopped read threads will always
|
||||
* exit immediately.
|
||||
*/
|
||||
wake_up(&audio->wait);
|
||||
mutex_lock(&audio->read_lock);
|
||||
audio_flush(audio);
|
||||
mutex_unlock(&audio->read_lock);
|
||||
}
|
||||
case AUDIO_SET_CONFIG: {
|
||||
struct msm_audio_config cfg;
|
||||
if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (cfg.channel_count == 1) {
|
||||
cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO;
|
||||
} else if (cfg.channel_count == 2) {
|
||||
cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cfg.type == 0) {
|
||||
cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV;
|
||||
} else if (cfg.type == 1) {
|
||||
cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
audio->samp_rate = convert_samp_rate(cfg.sample_rate);
|
||||
audio->samp_rate_index =
|
||||
convert_dsp_samp_index(cfg.sample_rate);
|
||||
audio->channel_mode = cfg.channel_count;
|
||||
audio->buffer_size =
|
||||
audio->channel_mode ? STEREO_DATA_SIZE
|
||||
: MONO_DATA_SIZE;
|
||||
audio->type = cfg.type;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config cfg;
|
||||
cfg.buffer_size = audio->buffer_size;
|
||||
cfg.buffer_count = FRAME_NUM;
|
||||
cfg.sample_rate = convert_samp_index(audio->samp_rate);
|
||||
if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
|
||||
cfg.channel_count = 1;
|
||||
else
|
||||
cfg.channel_count = 2;
|
||||
if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
|
||||
cfg.type = 0;
|
||||
else
|
||||
cfg.type = 1;
|
||||
cfg.unused[0] = 0;
|
||||
cfg.unused[1] = 0;
|
||||
cfg.unused[2] = 0;
|
||||
if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audio_in_read(struct file *file,
|
||||
char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio_in *audio = file->private_data;
|
||||
unsigned long flags;
|
||||
const char __user *start = buf;
|
||||
void *data;
|
||||
uint32_t index;
|
||||
uint32_t size;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&audio->read_lock);
|
||||
while (count > 0) {
|
||||
rc = wait_event_interruptible(
|
||||
audio->wait, (audio->in_count > 0) || audio->stopped);
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
index = audio->in_tail;
|
||||
data = (uint8_t *) audio->in[index].data;
|
||||
size = audio->in[index].size;
|
||||
if (count >= size) {
|
||||
if (copy_to_user(buf, data, size)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (index != audio->in_tail) {
|
||||
/* overrun -- data is invalid and we need to retry */
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
continue;
|
||||
}
|
||||
audio->in[index].size = 0;
|
||||
audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
|
||||
audio->in_count--;
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
count -= size;
|
||||
buf += size;
|
||||
if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
|
||||
break;
|
||||
} else {
|
||||
pr_err("audio_in: short read\n");
|
||||
break;
|
||||
}
|
||||
if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
|
||||
break; /* AAC only read one frame */
|
||||
}
|
||||
mutex_unlock(&audio->read_lock);
|
||||
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audio_in_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int audio_in_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio_in *audio = file->private_data;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
audio_in_disable(audio);
|
||||
audio_flush(audio);
|
||||
msm_adsp_put(audio->audrec);
|
||||
msm_adsp_put(audio->audpre);
|
||||
audio->audrec = NULL;
|
||||
audio->audpre = NULL;
|
||||
audio->opened = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio_in the_audio_in;
|
||||
|
||||
static int audio_in_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio_in *audio = &the_audio_in;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
if (audio->opened) {
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Settings will be re-config at AUDIO_SET_CONFIG,
|
||||
* but at least we need to have initial config
|
||||
*/
|
||||
audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
|
||||
audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
|
||||
audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
|
||||
audio->buffer_size = MONO_DATA_SIZE;
|
||||
audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV;
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc)
|
||||
goto done;
|
||||
rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
|
||||
&audpre_adsp_ops, audio);
|
||||
if (rc)
|
||||
goto done;
|
||||
rc = msm_adsp_get("AUDRECTASK", &audio->audrec,
|
||||
&audrec_adsp_ops, audio);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
audio->dsp_cnt = 0;
|
||||
audio->stopped = 0;
|
||||
|
||||
audio_flush(audio);
|
||||
|
||||
file->private_data = audio;
|
||||
audio->opened = 1;
|
||||
rc = 0;
|
||||
done:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct audio_in *audio = file->private_data;
|
||||
int rc = 0, enable;
|
||||
uint16_t enable_mask;
|
||||
#if DEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_ENABLE_AUDPRE: {
|
||||
if (copy_from_user(&enable_mask, (void *) arg,
|
||||
sizeof(enable_mask)))
|
||||
goto out_fault;
|
||||
|
||||
enable = (enable_mask & AGC_ENABLE) ? 1 : 0;
|
||||
audio_enable_agc(audio, enable);
|
||||
enable = (enable_mask & NS_ENABLE) ? 1 : 0;
|
||||
audio_enable_ns(audio, enable);
|
||||
enable = (enable_mask & IIR_ENABLE) ? 1 : 0;
|
||||
audio_enable_tx_iir(audio, enable);
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_AGC: {
|
||||
if (copy_from_user(&audio->agc, (void *) arg,
|
||||
sizeof(audio->agc)))
|
||||
goto out_fault;
|
||||
#if DEBUG
|
||||
pr_info("set agc\n");
|
||||
for (i = 0; i < AGC_PARAM_SIZE; i++) \
|
||||
pr_info("agc_params[%d] = 0x%04x\n", i,
|
||||
audio->agc.agc_params[i]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_NS: {
|
||||
if (copy_from_user(&audio->ns, (void *) arg,
|
||||
sizeof(audio->ns)))
|
||||
goto out_fault;
|
||||
#if DEBUG
|
||||
pr_info("set ns\n");
|
||||
for (i = 0; i < NS_PARAM_SIZE; i++) \
|
||||
pr_info("ns_params[%d] = 0x%04x\n",
|
||||
i, audio->ns.ns_params[i]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_TX_IIR: {
|
||||
if (copy_from_user(&audio->iir, (void *) arg,
|
||||
sizeof(audio->iir)))
|
||||
goto out_fault;
|
||||
#if DEBUG
|
||||
pr_info("set iir\n");
|
||||
pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands);
|
||||
for (i = 0; i < IIR_PARAM_SIZE; i++) \
|
||||
pr_info("iir_params[%d] = 0x%04x\n",
|
||||
i, audio->iir.iir_params[i]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
out_fault:
|
||||
rc = -EFAULT;
|
||||
out:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audpre_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio_in *audio = &the_audio_in;
|
||||
file->private_data = audio;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations audio_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audio_in_open,
|
||||
.release = audio_in_release,
|
||||
.read = audio_in_read,
|
||||
.write = audio_in_write,
|
||||
.unlocked_ioctl = audio_in_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static struct file_operations audpre_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audpre_open,
|
||||
.unlocked_ioctl = audpre_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_in_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_pcm_in",
|
||||
.fops = &audio_fops,
|
||||
};
|
||||
|
||||
struct miscdevice audpre_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_audpre",
|
||||
.fops = &audpre_fops,
|
||||
};
|
||||
|
||||
static int __init audio_in_init(void)
|
||||
{
|
||||
int rc;
|
||||
the_audio_in.data = dma_alloc_coherent(NULL, DMASZ,
|
||||
&the_audio_in.phys, GFP_KERNEL);
|
||||
if (!the_audio_in.data) {
|
||||
printk(KERN_ERR "%s: Unable to allocate DMA buffer\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&the_audio_in.lock);
|
||||
mutex_init(&the_audio_in.read_lock);
|
||||
spin_lock_init(&the_audio_in.dsp_lock);
|
||||
init_waitqueue_head(&the_audio_in.wait);
|
||||
rc = misc_register(&audio_in_misc);
|
||||
if (!rc) {
|
||||
rc = misc_register(&audpre_misc);
|
||||
if (rc < 0)
|
||||
misc_deregister(&audio_in_misc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
device_initcall(audio_in_init);
|
|
@ -1,972 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audio_mp3.c
|
||||
*
|
||||
* mp3 audio output device
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC 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/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
#include <mach/qdsp5/qdsp5audplaycmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audplaymsg.h>
|
||||
|
||||
/* for queue ids - should be relative to module number*/
|
||||
#include "adsp.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintk(format, arg...) \
|
||||
printk(KERN_DEBUG format, ## arg)
|
||||
#else
|
||||
#define dprintk(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/* Size must be power of 2 */
|
||||
#define BUFSZ_MAX 32768
|
||||
#define BUFSZ_MIN 4096
|
||||
#define DMASZ_MAX (BUFSZ_MAX * 2)
|
||||
#define DMASZ_MIN (BUFSZ_MIN * 2)
|
||||
|
||||
#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
|
||||
#define AUDDEC_DEC_MP3 2
|
||||
|
||||
#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */
|
||||
#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
|
||||
but support 2 buffers currently */
|
||||
#define ROUTING_MODE_FTRT 1
|
||||
#define ROUTING_MODE_RT 2
|
||||
/* Decoder status received from AUDPPTASK */
|
||||
#define AUDPP_DEC_STATUS_SLEEP 0
|
||||
#define AUDPP_DEC_STATUS_INIT 1
|
||||
#define AUDPP_DEC_STATUS_CFG 2
|
||||
#define AUDPP_DEC_STATUS_PLAY 3
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
unsigned size;
|
||||
unsigned used; /* Input usage actual DSP produced PCM size */
|
||||
unsigned addr;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
struct buffer out[2];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
uint8_t out_head;
|
||||
uint8_t out_tail;
|
||||
uint8_t out_needed; /* number of buffers the dsp is waiting for */
|
||||
unsigned out_dma_sz;
|
||||
|
||||
atomic_t out_bytes;
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex write_lock;
|
||||
wait_queue_head_t write_wait;
|
||||
|
||||
/* Host PCM section */
|
||||
struct buffer in[PCM_BUF_MAX_COUNT];
|
||||
struct mutex read_lock;
|
||||
wait_queue_head_t read_wait; /* Wait queue for read */
|
||||
char *read_data; /* pointer to reader buffer */
|
||||
dma_addr_t read_phys; /* physical address of reader buffer */
|
||||
uint8_t read_next; /* index to input buffers to be read next */
|
||||
uint8_t fill_next; /* index to buffer that DSP should be filling */
|
||||
uint8_t pcm_buf_count; /* number of pcm buffer allocated */
|
||||
/* ---- End of Host PCM section */
|
||||
|
||||
struct msm_adsp_module *audplay;
|
||||
|
||||
/* configuration to use on next enable */
|
||||
uint32_t out_sample_rate;
|
||||
uint32_t out_channel_mode;
|
||||
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
int rflush; /* Read flush */
|
||||
int wflush; /* Write flush */
|
||||
int opened;
|
||||
int enabled;
|
||||
int running;
|
||||
int stopped; /* set when stopped, cleared on flush */
|
||||
int pcm_feedback;
|
||||
int buf_refresh;
|
||||
|
||||
int reserved; /* A byte is being reserved */
|
||||
char rsv_byte; /* Handle odd length user data */
|
||||
|
||||
unsigned volume;
|
||||
|
||||
uint16_t dec_id;
|
||||
uint32_t read_ptr_offset;
|
||||
};
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable);
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio);
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio);
|
||||
static void audplay_send_data(struct audio *audio, unsigned needed);
|
||||
static void audplay_config_hostpcm(struct audio *audio);
|
||||
static void audplay_buffer_refresh(struct audio *audio);
|
||||
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_enable(struct audio *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
pr_info("audio_enable()\n");
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
audio->out_tail = 0;
|
||||
audio->out_needed = 0;
|
||||
|
||||
cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_MP3;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msm_adsp_enable(audio->audplay)) {
|
||||
pr_err("audio: msm_adsp_enable(audplay) failed\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
|
||||
pr_err("audio: audpp_enable() failed\n");
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
audio->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_disable(struct audio *audio)
|
||||
{
|
||||
pr_info("audio_disable()\n");
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
auddec_dsp_config(audio, 0);
|
||||
wake_up(&audio->write_wait);
|
||||
wake_up(&audio->read_wait);
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audpp_disable(audio->dec_id, audio);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
|
||||
{
|
||||
uint8_t index;
|
||||
unsigned long flags;
|
||||
|
||||
if (audio->rflush) {
|
||||
audio->buf_refresh = 1;
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
for (index = 0; index < payload[1]; index++) {
|
||||
if (audio->in[audio->fill_next].addr ==
|
||||
payload[2 + index * 2]) {
|
||||
pr_info("audio_update_pcm_buf_entry: in[%d] ready\n",
|
||||
audio->fill_next);
|
||||
audio->in[audio->fill_next].used =
|
||||
payload[3 + index * 2];
|
||||
if ((++audio->fill_next) == audio->pcm_buf_count)
|
||||
audio->fill_next = 0;
|
||||
|
||||
} else {
|
||||
pr_err
|
||||
("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
|
||||
, audio->in[audio->fill_next].addr,
|
||||
payload[1 + index * 2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (audio->in[audio->fill_next].used == 0) {
|
||||
audplay_buffer_refresh(audio);
|
||||
} else {
|
||||
pr_info("audio_update_pcm_buf_entry: read cannot keep up\n");
|
||||
audio->buf_refresh = 1;
|
||||
}
|
||||
wake_up(&audio->read_wait);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
|
||||
}
|
||||
|
||||
static void audplay_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent) (void *ptr, size_t len))
|
||||
{
|
||||
struct audio *audio = data;
|
||||
uint32_t msg[28];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
dprintk("audplay_dsp_event: msg_id=%x\n", id);
|
||||
|
||||
switch (id) {
|
||||
case AUDPLAY_MSG_DEC_NEEDS_DATA:
|
||||
audplay_send_data(audio, 1);
|
||||
break;
|
||||
|
||||
case AUDPLAY_MSG_BUFFER_UPDATE:
|
||||
audio_update_pcm_buf_entry(audio, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("unexpected message from decoder \n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
|
||||
{
|
||||
struct audio *audio = private;
|
||||
|
||||
switch (id) {
|
||||
case AUDPP_MSG_STATUS_MSG:{
|
||||
unsigned status = msg[1];
|
||||
|
||||
switch (status) {
|
||||
case AUDPP_DEC_STATUS_SLEEP:
|
||||
pr_info("decoder status: sleep \n");
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_INIT:
|
||||
pr_info("decoder status: init \n");
|
||||
audpp_cmd_cfg_routing_mode(audio);
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_CFG:
|
||||
pr_info("decoder status: cfg \n");
|
||||
break;
|
||||
case AUDPP_DEC_STATUS_PLAY:
|
||||
pr_info("decoder status: play \n");
|
||||
if (audio->pcm_feedback) {
|
||||
audplay_config_hostpcm(audio);
|
||||
audplay_buffer_refresh(audio);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown decoder status \n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
|
||||
auddec_dsp_config(audio, 1);
|
||||
audio->out_needed = 0;
|
||||
audio->running = 1;
|
||||
audpp_set_volume_and_pan(audio->dec_id, audio->volume,
|
||||
0);
|
||||
audpp_avsync(audio->dec_id, 22050);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
|
||||
audpp_avsync(audio->dec_id, 0);
|
||||
audio->running = 0;
|
||||
} else {
|
||||
pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDPP_MSG_ROUTING_ACK:
|
||||
pr_info("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
|
||||
audpp_cmd_cfg_adec_params(audio);
|
||||
break;
|
||||
|
||||
case AUDPP_MSG_FLUSH_ACK:
|
||||
dprintk("%s: FLUSH_ACK\n", __func__);
|
||||
audio->wflush = 0;
|
||||
audio->rflush = 0;
|
||||
if (audio->pcm_feedback)
|
||||
audplay_buffer_refresh(audio);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct msm_adsp_ops audplay_adsp_ops = {
|
||||
.event = audplay_dsp_event,
|
||||
};
|
||||
|
||||
|
||||
#define audplay_send_queue0(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
|
||||
cmd, len)
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable)
|
||||
{
|
||||
audpp_cmd_cfg_dec_type cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
|
||||
if (enable)
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
|
||||
AUDPP_CMD_ENA_DEC_V |
|
||||
AUDDEC_DEC_MP3;
|
||||
else
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
|
||||
AUDPP_CMD_DIS_DEC_V;
|
||||
|
||||
return audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio)
|
||||
{
|
||||
audpp_cmd_cfg_adec_params_mp3 cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
|
||||
cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN;
|
||||
cmd.common.dec_id = audio->dec_id;
|
||||
cmd.common.input_sampling_frequency = audio->out_sample_rate;
|
||||
|
||||
audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_routing_mode cmd;
|
||||
pr_info("audpp_cmd_cfg_routing_mode()\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
|
||||
cmd.object_number = audio->dec_id;
|
||||
if (audio->pcm_feedback)
|
||||
cmd.routing_mode = ROUTING_MODE_FTRT;
|
||||
else
|
||||
cmd.routing_mode = ROUTING_MODE_RT;
|
||||
|
||||
audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audplay_dsp_send_data_avail(struct audio *audio,
|
||||
unsigned idx, unsigned len)
|
||||
{
|
||||
audplay_cmd_bitstream_data_avail cmd;
|
||||
|
||||
cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
|
||||
cmd.decoder_id = audio->dec_id;
|
||||
cmd.buf_ptr = audio->out[idx].addr;
|
||||
cmd.buf_size = len/2;
|
||||
cmd.partition_number = 0;
|
||||
return audplay_send_queue0(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audplay_buffer_refresh(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_buffer_refresh refresh_cmd;
|
||||
|
||||
refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
|
||||
refresh_cmd.num_buffers = 1;
|
||||
refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
|
||||
refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
|
||||
(audio->in[audio->fill_next].size % 576); /* Mp3 frame size */
|
||||
refresh_cmd.buf_read_count = 0;
|
||||
pr_info("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
|
||||
refresh_cmd.buf0_address, refresh_cmd.buf0_length);
|
||||
(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
|
||||
}
|
||||
|
||||
static void audplay_config_hostpcm(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
|
||||
|
||||
pr_info("audplay_config_hostpcm()\n");
|
||||
cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
|
||||
cfg_cmd.max_buffers = 1;
|
||||
cfg_cmd.byte_swap = 0;
|
||||
cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
|
||||
cfg_cmd.feedback_frequency = 1;
|
||||
cfg_cmd.partition_number = 0;
|
||||
(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
|
||||
|
||||
}
|
||||
|
||||
static void audplay_send_data(struct audio *audio, unsigned needed)
|
||||
{
|
||||
struct buffer *frame;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (!audio->running)
|
||||
goto done;
|
||||
|
||||
if (audio->wflush) {
|
||||
audio->out_needed = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (needed && !audio->wflush) {
|
||||
/* We were called from the callback because the DSP
|
||||
* requested more data. Note that the DSP does want
|
||||
* more data, and if a buffer was in-flight, mark it
|
||||
* as available (since the DSP must now be done with
|
||||
* it).
|
||||
*/
|
||||
audio->out_needed = 1;
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used == 0xffffffff) {
|
||||
dprintk("frame %d free\n", audio->out_tail);
|
||||
frame->used = 0;
|
||||
audio->out_tail ^= 1;
|
||||
wake_up(&audio->write_wait);
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->out_needed) {
|
||||
/* If the DSP currently wants data and we have a
|
||||
* buffer available, we will send it and reset
|
||||
* the needed flag. We'll mark the buffer as in-flight
|
||||
* so that it won't be recycled until the next buffer
|
||||
* is requested
|
||||
*/
|
||||
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used) {
|
||||
BUG_ON(frame->used == 0xffffffff);
|
||||
dprintk("frame %d busy\n", audio->out_tail);
|
||||
audplay_dsp_send_data_avail(audio, audio->out_tail,
|
||||
frame->used);
|
||||
frame->used = 0xffffffff;
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static void audio_flush(struct audio *audio)
|
||||
{
|
||||
audio->out[0].used = 0;
|
||||
audio->out[1].used = 0;
|
||||
audio->out_head = 0;
|
||||
audio->out_tail = 0;
|
||||
audio->reserved = 0;
|
||||
atomic_set(&audio->out_bytes, 0);
|
||||
}
|
||||
|
||||
static void audio_flush_pcm_buf(struct audio *audio)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
|
||||
audio->in[index].used = 0;
|
||||
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
}
|
||||
|
||||
static void audio_ioport_reset(struct audio *audio)
|
||||
{
|
||||
/* Make sure read/write thread are free from
|
||||
* sleep and knowing that system is not able
|
||||
* to process io request at the moment
|
||||
*/
|
||||
wake_up(&audio->write_wait);
|
||||
mutex_lock(&audio->write_lock);
|
||||
audio_flush(audio);
|
||||
mutex_unlock(&audio->write_lock);
|
||||
wake_up(&audio->read_wait);
|
||||
mutex_lock(&audio->read_lock);
|
||||
audio_flush_pcm_buf(audio);
|
||||
mutex_unlock(&audio->read_lock);
|
||||
}
|
||||
|
||||
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
pr_info("audio_ioctl() cmd = %d\n", cmd);
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
|
||||
stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
|
||||
if (copy_to_user((void *) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (cmd == AUDIO_SET_VOLUME) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->volume = arg;
|
||||
if (audio->running)
|
||||
audpp_set_volume_and_pan(audio->dec_id, arg, 0);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audio_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audio_disable(audio);
|
||||
audio->stopped = 1;
|
||||
audio_ioport_reset(audio);
|
||||
audio->stopped = 0;
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
dprintk("%s: AUDIO_FLUSH\n", __func__);
|
||||
audio->rflush = 1;
|
||||
audio->wflush = 1;
|
||||
audio_ioport_reset(audio);
|
||||
audio->rflush = 0;
|
||||
audio->wflush = 0;
|
||||
|
||||
if (audio->buf_refresh) {
|
||||
audio->buf_refresh = 0;
|
||||
audplay_buffer_refresh(audio);
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_SET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
if (copy_from_user(&config, (void *) arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (config.channel_count == 1) {
|
||||
config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
|
||||
} else if (config.channel_count == 2) {
|
||||
config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
audio->out_sample_rate = config.sample_rate;
|
||||
audio->out_channel_mode = config.channel_count;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = (audio->out_dma_sz >> 1);
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = audio->out_sample_rate;
|
||||
if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
|
||||
config.channel_count = 1;
|
||||
} else {
|
||||
config.channel_count = 2;
|
||||
}
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
config.unused[3] = 0;
|
||||
if (copy_to_user((void *) arg, &config, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
config.pcm_feedback = 0;
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
if (copy_to_user((void *)arg, &config,
|
||||
sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
if (copy_from_user
|
||||
(&config, (void *)arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
|
||||
(config.buffer_count == 1))
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
|
||||
if (config.buffer_size < PCM_BUFSZ_MIN)
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
|
||||
/* Check if pcm feedback is required */
|
||||
if ((config.pcm_feedback) && (!audio->read_data)) {
|
||||
pr_info("ioctl: allocate PCM buffer %d\n",
|
||||
config.buffer_count *
|
||||
config.buffer_size);
|
||||
audio->read_data =
|
||||
dma_alloc_coherent(NULL,
|
||||
config.buffer_size *
|
||||
config.buffer_count,
|
||||
&audio->read_phys,
|
||||
GFP_KERNEL);
|
||||
if (!audio->read_data) {
|
||||
pr_err("audio_mp3: malloc pcm buf failed\n");
|
||||
rc = -1;
|
||||
} else {
|
||||
uint8_t index;
|
||||
uint32_t offset = 0;
|
||||
audio->pcm_feedback = 1;
|
||||
audio->buf_refresh = 0;
|
||||
audio->pcm_buf_count =
|
||||
config.buffer_count;
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
|
||||
for (index = 0;
|
||||
index < config.buffer_count;
|
||||
index++) {
|
||||
audio->in[index].data =
|
||||
audio->read_data + offset;
|
||||
audio->in[index].addr =
|
||||
audio->read_phys + offset;
|
||||
audio->in[index].size =
|
||||
config.buffer_size;
|
||||
audio->in[index].used = 0;
|
||||
offset += config.buffer_size;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDIO_PAUSE:
|
||||
dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
|
||||
rc = audpp_pause(audio->dec_id, (int) arg);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
int rc = 0;
|
||||
|
||||
if (!audio->pcm_feedback)
|
||||
return 0; /* PCM feedback disabled. Nothing to read */
|
||||
|
||||
mutex_lock(&audio->read_lock);
|
||||
pr_info("audio_read() %d \n", count);
|
||||
while (count > 0) {
|
||||
rc = wait_event_interruptible(audio->read_wait,
|
||||
(audio->in[audio->read_next].
|
||||
used > 0) || (audio->stopped)
|
||||
|| (audio->rflush));
|
||||
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
if (audio->stopped || audio->rflush) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count < audio->in[audio->read_next].used) {
|
||||
/* Read must happen in frame boundary. Since
|
||||
* driver does not know frame size, read count
|
||||
* must be greater or equal
|
||||
* to size of PCM samples
|
||||
*/
|
||||
pr_info("audio_read: no partial frame done reading\n");
|
||||
break;
|
||||
} else {
|
||||
pr_info("audio_read: read from in[%d]\n",
|
||||
audio->read_next);
|
||||
if (copy_to_user
|
||||
(buf, audio->in[audio->read_next].data,
|
||||
audio->in[audio->read_next].used)) {
|
||||
pr_err("audio_read: invalid addr %x \n",
|
||||
(unsigned int)buf);
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
count -= audio->in[audio->read_next].used;
|
||||
buf += audio->in[audio->read_next].used;
|
||||
audio->in[audio->read_next].used = 0;
|
||||
if ((++audio->read_next) == audio->pcm_buf_count)
|
||||
audio->read_next = 0;
|
||||
if (audio->in[audio->read_next].used == 0)
|
||||
break; /* No data ready at this moment
|
||||
* Exit while loop to prevent
|
||||
* output thread sleep too long
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* don't feed output buffer to HW decoder during flushing
|
||||
* buffer refresh command will be sent once flush completes
|
||||
* send buf refresh command here can confuse HW decoder
|
||||
*/
|
||||
if (audio->buf_refresh && !audio->rflush) {
|
||||
audio->buf_refresh = 0;
|
||||
pr_info("audio_read: kick start pcm feedback again\n");
|
||||
audplay_buffer_refresh(audio);
|
||||
}
|
||||
|
||||
mutex_unlock(&audio->read_lock);
|
||||
|
||||
if (buf > start)
|
||||
rc = buf - start;
|
||||
|
||||
pr_info("audio_read: read %d bytes\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audio_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
struct buffer *frame;
|
||||
size_t xfer;
|
||||
char *cpy_ptr;
|
||||
int rc = 0;
|
||||
unsigned dsize;
|
||||
|
||||
mutex_lock(&audio->write_lock);
|
||||
while (count > 0) {
|
||||
frame = audio->out + audio->out_head;
|
||||
cpy_ptr = frame->data;
|
||||
dsize = 0;
|
||||
rc = wait_event_interruptible(audio->write_wait,
|
||||
(frame->used == 0)
|
||||
|| (audio->stopped)
|
||||
|| (audio->wflush));
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped || audio->wflush) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (audio->reserved) {
|
||||
dprintk("%s: append reserved byte %x\n",
|
||||
__func__, audio->rsv_byte);
|
||||
*cpy_ptr = audio->rsv_byte;
|
||||
xfer = (count > (frame->size - 1)) ?
|
||||
frame->size - 1 : count;
|
||||
cpy_ptr++;
|
||||
dsize = 1;
|
||||
audio->reserved = 0;
|
||||
} else
|
||||
xfer = (count > frame->size) ? frame->size : count;
|
||||
|
||||
if (copy_from_user(cpy_ptr, buf, xfer)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
dsize += xfer;
|
||||
if (dsize & 1) {
|
||||
audio->rsv_byte = ((char *) frame->data)[dsize - 1];
|
||||
dprintk("%s: odd length buf reserve last byte %x\n",
|
||||
__func__, audio->rsv_byte);
|
||||
audio->reserved = 1;
|
||||
dsize--;
|
||||
}
|
||||
count -= xfer;
|
||||
buf += xfer;
|
||||
|
||||
if (dsize > 0) {
|
||||
audio->out_head ^= 1;
|
||||
frame->used = dsize;
|
||||
audplay_send_data(audio, 0);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&audio->write_lock);
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audio_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
|
||||
dprintk("audio_release()\n");
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
audio_disable(audio);
|
||||
audio_flush(audio);
|
||||
audio_flush_pcm_buf(audio);
|
||||
msm_adsp_put(audio->audplay);
|
||||
audio->audplay = NULL;
|
||||
audio->opened = 0;
|
||||
audio->reserved = 0;
|
||||
dma_free_coherent(NULL, audio->out_dma_sz, audio->data, audio->phys);
|
||||
audio->data = NULL;
|
||||
if (audio->read_data != NULL) {
|
||||
dma_free_coherent(NULL,
|
||||
audio->in[0].size * audio->pcm_buf_count,
|
||||
audio->read_data, audio->read_phys);
|
||||
audio->read_data = NULL;
|
||||
}
|
||||
audio->pcm_feedback = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio the_mp3_audio;
|
||||
|
||||
static int audio_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_mp3_audio;
|
||||
int rc;
|
||||
unsigned pmem_sz;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
|
||||
if (audio->opened) {
|
||||
pr_err("audio: busy\n");
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pmem_sz = DMASZ_MAX;
|
||||
|
||||
while (pmem_sz >= DMASZ_MIN) {
|
||||
audio->data = dma_alloc_coherent(NULL, pmem_sz,
|
||||
&audio->phys, GFP_KERNEL);
|
||||
if (audio->data)
|
||||
break;
|
||||
else if (pmem_sz == DMASZ_MIN) {
|
||||
pr_err("audio: could not allocate DMA buffers\n");
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
} else
|
||||
pmem_sz >>= 1;
|
||||
}
|
||||
|
||||
dprintk("%s: allocated %d bytes DMA buffer\n", __func__, pmem_sz);
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc) {
|
||||
dma_free_coherent(NULL, pmem_sz,
|
||||
audio->data, audio->phys);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, &audplay_adsp_ops,
|
||||
audio);
|
||||
if (rc) {
|
||||
pr_err("audio: failed to get audplay0 dsp module\n");
|
||||
dma_free_coherent(NULL, pmem_sz,
|
||||
audio->data, audio->phys);
|
||||
audmgr_close(&audio->audmgr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
audio->out_dma_sz = pmem_sz;
|
||||
pmem_sz >>= 1; /* Shift by 1 to get size of ping pong buffer */
|
||||
|
||||
audio->out_sample_rate = 44100;
|
||||
audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
|
||||
audio->dec_id = 0;
|
||||
|
||||
audio->out[0].data = audio->data + 0;
|
||||
audio->out[0].addr = audio->phys + 0;
|
||||
audio->out[0].size = pmem_sz;
|
||||
|
||||
audio->out[1].data = audio->data + pmem_sz;
|
||||
audio->out[1].addr = audio->phys + pmem_sz;
|
||||
audio->out[1].size = pmem_sz;
|
||||
|
||||
audio->volume = 0x2000; /* equal to Q13 number 1.0 Unit Gain */
|
||||
|
||||
audio_flush(audio);
|
||||
|
||||
file->private_data = audio;
|
||||
audio->opened = 1;
|
||||
rc = 0;
|
||||
done:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations audio_mp3_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audio_open,
|
||||
.release = audio_release,
|
||||
.read = audio_read,
|
||||
.write = audio_write,
|
||||
.unlocked_ioctl = audio_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_mp3_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_mp3",
|
||||
.fops = &audio_mp3_fops,
|
||||
};
|
||||
|
||||
static int __init audio_init(void)
|
||||
{
|
||||
mutex_init(&the_mp3_audio.lock);
|
||||
mutex_init(&the_mp3_audio.write_lock);
|
||||
mutex_init(&the_mp3_audio.read_lock);
|
||||
spin_lock_init(&the_mp3_audio.dsp_lock);
|
||||
init_waitqueue_head(&the_mp3_audio.write_wait);
|
||||
init_waitqueue_head(&the_mp3_audio.read_wait);
|
||||
the_mp3_audio.read_data = NULL;
|
||||
return misc_register(&audio_mp3_misc);
|
||||
}
|
||||
|
||||
device_initcall(audio_init);
|
|
@ -1,841 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audio_out.c
|
||||
*
|
||||
* pcm audio output device
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC 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/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
|
||||
#include "evlog.h"
|
||||
|
||||
#define LOG_AUDIO_EVENTS 1
|
||||
#define LOG_AUDIO_FAULTS 0
|
||||
|
||||
enum {
|
||||
EV_NULL,
|
||||
EV_OPEN,
|
||||
EV_WRITE,
|
||||
EV_RETURN,
|
||||
EV_IOCTL,
|
||||
EV_WRITE_WAIT,
|
||||
EV_WAIT_EVENT,
|
||||
EV_FILL_BUFFER,
|
||||
EV_SEND_BUFFER,
|
||||
EV_DSP_EVENT,
|
||||
EV_ENABLE,
|
||||
};
|
||||
|
||||
#if (LOG_AUDIO_EVENTS != 1)
|
||||
static inline void LOG(unsigned id, unsigned arg) {}
|
||||
#else
|
||||
static const char *pcm_log_strings[] = {
|
||||
"NULL",
|
||||
"OPEN",
|
||||
"WRITE",
|
||||
"RETURN",
|
||||
"IOCTL",
|
||||
"WRITE_WAIT",
|
||||
"WAIT_EVENT",
|
||||
"FILL_BUFFER",
|
||||
"SEND_BUFFER",
|
||||
"DSP_EVENT",
|
||||
"ENABLE",
|
||||
};
|
||||
|
||||
DECLARE_LOG(pcm_log, 64, pcm_log_strings);
|
||||
|
||||
static int __init _pcm_log_init(void)
|
||||
{
|
||||
return ev_log_init(&pcm_log);
|
||||
}
|
||||
module_init(_pcm_log_init);
|
||||
|
||||
#define LOG(id,arg) ev_log_write(&pcm_log, id, arg)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define BUFSZ (960 * 5)
|
||||
#define DMASZ (BUFSZ * 2)
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
|
||||
#define AUDPP_CMD_EQ_FLAG_DIS 0x0000
|
||||
#define AUDPP_CMD_EQ_FLAG_ENA -1
|
||||
#define AUDPP_CMD_IIR_FLAG_DIS 0x0000
|
||||
#define AUDPP_CMD_IIR_FLAG_ENA -1
|
||||
|
||||
#define AUDPP_CMD_IIR_TUNING_FILTER 1
|
||||
#define AUDPP_CMD_EQUALIZER 2
|
||||
#define AUDPP_CMD_ADRC 3
|
||||
|
||||
#define ADRC_ENABLE 0x0001
|
||||
#define EQ_ENABLE 0x0002
|
||||
#define IIR_ENABLE 0x0004
|
||||
|
||||
struct adrc_filter {
|
||||
uint16_t compression_th;
|
||||
uint16_t compression_slope;
|
||||
uint16_t rms_time;
|
||||
uint16_t attack_const_lsw;
|
||||
uint16_t attack_const_msw;
|
||||
uint16_t release_const_lsw;
|
||||
uint16_t release_const_msw;
|
||||
uint16_t adrc_system_delay;
|
||||
};
|
||||
|
||||
struct eqalizer {
|
||||
uint16_t num_bands;
|
||||
uint16_t eq_params[132];
|
||||
};
|
||||
|
||||
struct rx_iir_filter {
|
||||
uint16_t num_bands;
|
||||
uint16_t iir_params[48];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
uint16_t eq_flag;
|
||||
uint16_t num_bands;
|
||||
uint16_t eq_params[132];
|
||||
} audpp_cmd_cfg_object_params_eq;
|
||||
|
||||
typedef struct {
|
||||
audpp_cmd_cfg_object_params_common common;
|
||||
uint16_t active_flag;
|
||||
uint16_t num_bands;
|
||||
uint16_t iir_params[48];
|
||||
} audpp_cmd_cfg_object_params_rx_iir;
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
unsigned size;
|
||||
unsigned used;
|
||||
unsigned addr;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
struct buffer out[2];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
uint8_t out_head;
|
||||
uint8_t out_tail;
|
||||
uint8_t out_needed; /* number of buffers the dsp is waiting for */
|
||||
|
||||
atomic_t out_bytes;
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex write_lock;
|
||||
wait_queue_head_t wait;
|
||||
|
||||
/* configuration to use on next enable */
|
||||
uint32_t out_sample_rate;
|
||||
uint32_t out_channel_mode;
|
||||
uint32_t out_weight;
|
||||
uint32_t out_buffer_size;
|
||||
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
int opened;
|
||||
int enabled;
|
||||
int running;
|
||||
int stopped; /* set when stopped, cleared on flush */
|
||||
unsigned volume;
|
||||
|
||||
int adrc_enable;
|
||||
struct adrc_filter adrc;
|
||||
|
||||
int eq_enable;
|
||||
struct eqalizer eq;
|
||||
|
||||
int rx_iir_enable;
|
||||
struct rx_iir_filter iir;
|
||||
};
|
||||
|
||||
static void audio_prevent_sleep(struct audio *audio)
|
||||
{
|
||||
printk(KERN_INFO "++++++++++++++++++++++++++++++\n");
|
||||
}
|
||||
|
||||
static void audio_allow_sleep(struct audio *audio)
|
||||
{
|
||||
printk(KERN_INFO "------------------------------\n");
|
||||
}
|
||||
|
||||
static int audio_dsp_out_enable(struct audio *audio, int yes);
|
||||
static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len);
|
||||
static int audio_dsp_set_adrc(struct audio *audio);
|
||||
static int audio_dsp_set_eq(struct audio *audio);
|
||||
static int audio_dsp_set_rx_iir(struct audio *audio);
|
||||
|
||||
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_enable(struct audio *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
pr_info("audio_enable()\n");
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
/* refuse to start if we're not ready */
|
||||
if (!audio->out[0].used || !audio->out[1].used)
|
||||
return -EIO;
|
||||
|
||||
/* we start buffers 0 and 1, so buffer 0 will be the
|
||||
* next one the dsp will want
|
||||
*/
|
||||
audio->out_tail = 0;
|
||||
audio->out_needed = 0;
|
||||
|
||||
cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM;
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_PCM;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
audio_prevent_sleep(audio);
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0) {
|
||||
audio_allow_sleep(audio);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (audpp_enable(-1, audio_dsp_event, audio)) {
|
||||
pr_err("audio: audpp_enable() failed\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio_allow_sleep(audio);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
audio->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audio_disable(struct audio *audio)
|
||||
{
|
||||
pr_info("audio_disable()\n");
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
audio_dsp_out_enable(audio, 0);
|
||||
|
||||
audpp_disable(-1, audio);
|
||||
|
||||
wake_up(&audio->wait);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio->out_needed = 0;
|
||||
audio_allow_sleep(audio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
|
||||
{
|
||||
struct audio *audio = private;
|
||||
struct buffer *frame;
|
||||
unsigned long flags;
|
||||
|
||||
LOG(EV_DSP_EVENT, id);
|
||||
switch (id) {
|
||||
case AUDPP_MSG_HOST_PCM_INTF_MSG: {
|
||||
unsigned id = msg[2];
|
||||
unsigned idx = msg[3] - 1;
|
||||
|
||||
/* pr_info("audio_dsp_event: HOST_PCM id %d idx %d\n", id, idx); */
|
||||
if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) {
|
||||
pr_err("bogus id\n");
|
||||
break;
|
||||
}
|
||||
if (idx > 1) {
|
||||
pr_err("bogus buffer idx\n");
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (audio->running) {
|
||||
atomic_add(audio->out[idx].used, &audio->out_bytes);
|
||||
audio->out[idx].used = 0;
|
||||
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used) {
|
||||
audio_dsp_send_buffer(
|
||||
audio, audio->out_tail, frame->used);
|
||||
audio->out_tail ^= 1;
|
||||
} else {
|
||||
audio->out_needed++;
|
||||
}
|
||||
wake_up(&audio->wait);
|
||||
}
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_PCMDMAMISSED:
|
||||
pr_info("audio_dsp_event: PCMDMAMISSED %d\n", msg[0]);
|
||||
break;
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
LOG(EV_ENABLE, 1);
|
||||
pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
|
||||
audio->out_needed = 0;
|
||||
audio->running = 1;
|
||||
audpp_set_volume_and_pan(5, audio->volume, 0);
|
||||
audio_dsp_set_adrc(audio);
|
||||
audio_dsp_set_eq(audio);
|
||||
audio_dsp_set_rx_iir(audio);
|
||||
audio_dsp_out_enable(audio, 1);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
LOG(EV_ENABLE, 0);
|
||||
pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
|
||||
audio->running = 0;
|
||||
} else {
|
||||
pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
static int audio_dsp_out_enable(struct audio *audio, int yes)
|
||||
{
|
||||
audpp_cmd_pcm_intf cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_PCM_INTF_2;
|
||||
cmd.object_num = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
|
||||
cmd.config = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V;
|
||||
cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
|
||||
|
||||
if (yes) {
|
||||
cmd.write_buf1LSW = audio->out[0].addr;
|
||||
cmd.write_buf1MSW = audio->out[0].addr >> 16;
|
||||
cmd.write_buf1_len = audio->out[0].size;
|
||||
cmd.write_buf2LSW = audio->out[1].addr;
|
||||
cmd.write_buf2MSW = audio->out[1].addr >> 16;
|
||||
cmd.write_buf2_len = audio->out[1].size;
|
||||
cmd.arm_to_rx_flag = AUDPP_CMD_PCM_INTF_ENA_V;
|
||||
cmd.weight_decoder_to_rx = audio->out_weight;
|
||||
cmd.weight_arm_to_rx = 1;
|
||||
cmd.partition_number_arm_to_dsp = 0;
|
||||
cmd.sample_rate = audio->out_sample_rate;
|
||||
cmd.channel_mode = audio->out_channel_mode;
|
||||
}
|
||||
|
||||
return audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len)
|
||||
{
|
||||
audpp_cmd_pcm_intf_send_buffer cmd;
|
||||
|
||||
cmd.cmd_id = AUDPP_CMD_PCM_INTF_2;
|
||||
cmd.host_pcm_object = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
|
||||
cmd.config = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V;
|
||||
cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
|
||||
cmd.dsp_to_arm_buf_id = 0;
|
||||
cmd.arm_to_dsp_buf_id = idx + 1;
|
||||
cmd.arm_to_dsp_buf_len = len;
|
||||
|
||||
LOG(EV_SEND_BUFFER, idx);
|
||||
return audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_set_adrc(struct audio *audio)
|
||||
{
|
||||
audpp_cmd_cfg_object_params_adrc cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
|
||||
cmd.common.command_type = AUDPP_CMD_ADRC;
|
||||
|
||||
if (audio->adrc_enable) {
|
||||
cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_ENA;
|
||||
cmd.compression_th = audio->adrc.compression_th;
|
||||
cmd.compression_slope = audio->adrc.compression_slope;
|
||||
cmd.rms_time = audio->adrc.rms_time;
|
||||
cmd.attack_const_lsw = audio->adrc.attack_const_lsw;
|
||||
cmd.attack_const_msw = audio->adrc.attack_const_msw;
|
||||
cmd.release_const_lsw = audio->adrc.release_const_lsw;
|
||||
cmd.release_const_msw = audio->adrc.release_const_msw;
|
||||
cmd.adrc_system_delay = audio->adrc.adrc_system_delay;
|
||||
} else {
|
||||
cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_DIS;
|
||||
}
|
||||
return audpp_send_queue3(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_set_eq(struct audio *audio)
|
||||
{
|
||||
audpp_cmd_cfg_object_params_eq cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
|
||||
cmd.common.command_type = AUDPP_CMD_EQUALIZER;
|
||||
|
||||
if (audio->eq_enable) {
|
||||
cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA;
|
||||
cmd.num_bands = audio->eq.num_bands;
|
||||
memcpy(&cmd.eq_params, audio->eq.eq_params,
|
||||
sizeof(audio->eq.eq_params));
|
||||
} else {
|
||||
cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS;
|
||||
}
|
||||
return audpp_send_queue3(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audio_dsp_set_rx_iir(struct audio *audio)
|
||||
{
|
||||
audpp_cmd_cfg_object_params_rx_iir cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
|
||||
cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER;
|
||||
|
||||
if (audio->rx_iir_enable) {
|
||||
cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA;
|
||||
cmd.num_bands = audio->iir.num_bands;
|
||||
memcpy(&cmd.iir_params, audio->iir.iir_params,
|
||||
sizeof(audio->iir.iir_params));
|
||||
} else {
|
||||
cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS;
|
||||
}
|
||||
|
||||
return audpp_send_queue3(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static int audio_enable_adrc(struct audio *audio, int enable)
|
||||
{
|
||||
if (audio->adrc_enable != enable) {
|
||||
audio->adrc_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_adrc(audio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audio_enable_eq(struct audio *audio, int enable)
|
||||
{
|
||||
if (audio->eq_enable != enable) {
|
||||
audio->eq_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_eq(audio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audio_enable_rx_iir(struct audio *audio, int enable)
|
||||
{
|
||||
if (audio->rx_iir_enable != enable) {
|
||||
audio->rx_iir_enable = enable;
|
||||
if (audio->running)
|
||||
audio_dsp_set_rx_iir(audio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void audio_flush(struct audio *audio)
|
||||
{
|
||||
audio->out[0].used = 0;
|
||||
audio->out[1].used = 0;
|
||||
audio->out_head = 0;
|
||||
audio->out_tail = 0;
|
||||
audio->stopped = 0;
|
||||
}
|
||||
|
||||
static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc;
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = atomic_read(&audio->out_bytes);
|
||||
if (copy_to_user((void*) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (cmd == AUDIO_SET_VOLUME) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->volume = arg;
|
||||
if (audio->running)
|
||||
audpp_set_volume_and_pan(6, arg, 0);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
LOG(EV_IOCTL, cmd);
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audio_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audio_disable(audio);
|
||||
audio->stopped = 1;
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
if (audio->stopped) {
|
||||
/* Make sure we're stopped and we wake any threads
|
||||
* that might be blocked holding the write_lock.
|
||||
* While audio->stopped write threads will always
|
||||
* exit immediately.
|
||||
*/
|
||||
wake_up(&audio->wait);
|
||||
mutex_lock(&audio->write_lock);
|
||||
audio_flush(audio);
|
||||
mutex_unlock(&audio->write_lock);
|
||||
}
|
||||
case AUDIO_SET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
if (copy_from_user(&config, (void*) arg, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (config.channel_count == 1) {
|
||||
config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
|
||||
} else if (config.channel_count == 2) {
|
||||
config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
audio->out_sample_rate = config.sample_rate;
|
||||
audio->out_channel_mode = config.channel_count;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_CONFIG: {
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_count = 2;
|
||||
config.sample_rate = audio->out_sample_rate;
|
||||
if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
|
||||
config.channel_count = 1;
|
||||
} else {
|
||||
config.channel_count = 2;
|
||||
}
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
config.unused[3] = 0;
|
||||
if (copy_to_user((void*) arg, &config, sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int rt_policy(int policy)
|
||||
{
|
||||
if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int task_has_rt_policy(struct task_struct *p)
|
||||
{
|
||||
return rt_policy(p->policy);
|
||||
}
|
||||
|
||||
static ssize_t audio_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct sched_param s = { .sched_priority = 1 };
|
||||
struct audio *audio = file->private_data;
|
||||
unsigned long flags;
|
||||
const char __user *start = buf;
|
||||
struct buffer *frame;
|
||||
size_t xfer;
|
||||
int old_prio = current->rt_priority;
|
||||
int old_policy = current->policy;
|
||||
int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
|
||||
int rc = 0;
|
||||
|
||||
LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24));
|
||||
|
||||
/* just for this write, set us real-time */
|
||||
if (!task_has_rt_policy(current)) {
|
||||
struct cred *new = prepare_creds();
|
||||
cap_raise(new->cap_effective, CAP_SYS_NICE);
|
||||
commit_creds(new);
|
||||
sched_setscheduler(current, SCHED_RR, &s);
|
||||
}
|
||||
|
||||
mutex_lock(&audio->write_lock);
|
||||
while (count > 0) {
|
||||
frame = audio->out + audio->out_head;
|
||||
|
||||
LOG(EV_WAIT_EVENT, 0);
|
||||
rc = wait_event_interruptible(audio->wait,
|
||||
(frame->used == 0) || (audio->stopped));
|
||||
LOG(EV_WAIT_EVENT, 1);
|
||||
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
xfer = count > frame->size ? frame->size : count;
|
||||
if (copy_from_user(frame->data, buf, xfer)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
frame->used = xfer;
|
||||
audio->out_head ^= 1;
|
||||
count -= xfer;
|
||||
buf += xfer;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
LOG(EV_FILL_BUFFER, audio->out_head ^ 1);
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used && audio->out_needed) {
|
||||
audio_dsp_send_buffer(audio, audio->out_tail, frame->used);
|
||||
audio->out_tail ^= 1;
|
||||
audio->out_needed--;
|
||||
}
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
mutex_unlock(&audio->write_lock);
|
||||
|
||||
/* restore scheduling policy and priority */
|
||||
if (!rt_policy(old_policy)) {
|
||||
struct sched_param v = { .sched_priority = old_prio };
|
||||
sched_setscheduler(current, old_policy, &v);
|
||||
if (likely(!cap_nice)) {
|
||||
struct cred *new = prepare_creds();
|
||||
cap_lower(new->cap_effective, CAP_SYS_NICE);
|
||||
commit_creds(new);
|
||||
sched_setscheduler(current, SCHED_RR, &s);
|
||||
}
|
||||
}
|
||||
|
||||
LOG(EV_RETURN,(buf > start) ? (buf - start) : rc);
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audio_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
|
||||
LOG(EV_OPEN, 0);
|
||||
mutex_lock(&audio->lock);
|
||||
audio_disable(audio);
|
||||
audio_flush(audio);
|
||||
audio->opened = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct audio the_audio;
|
||||
|
||||
static int audio_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_audio;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
|
||||
if (audio->opened) {
|
||||
pr_err("audio: busy\n");
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!audio->data) {
|
||||
audio->data = dma_alloc_coherent(NULL, DMASZ,
|
||||
&audio->phys, GFP_KERNEL);
|
||||
if (!audio->data) {
|
||||
pr_err("audio: could not allocate DMA buffers\n");
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
audio->out_buffer_size = BUFSZ;
|
||||
audio->out_sample_rate = 44100;
|
||||
audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
|
||||
audio->out_weight = 100;
|
||||
|
||||
audio->out[0].data = audio->data + 0;
|
||||
audio->out[0].addr = audio->phys + 0;
|
||||
audio->out[0].size = BUFSZ;
|
||||
|
||||
audio->out[1].data = audio->data + BUFSZ;
|
||||
audio->out[1].addr = audio->phys + BUFSZ;
|
||||
audio->out[1].size = BUFSZ;
|
||||
|
||||
audio->volume = 0x2000;
|
||||
|
||||
audio_flush(audio);
|
||||
|
||||
file->private_data = audio;
|
||||
audio->opened = 1;
|
||||
rc = 0;
|
||||
LOG(EV_OPEN, 1);
|
||||
done:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc = 0, enable;
|
||||
uint16_t enable_mask;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_ENABLE_AUDPP:
|
||||
if (copy_from_user(&enable_mask, (void *) arg, sizeof(enable_mask)))
|
||||
goto out_fault;
|
||||
|
||||
enable = (enable_mask & ADRC_ENABLE)? 1 : 0;
|
||||
audio_enable_adrc(audio, enable);
|
||||
enable = (enable_mask & EQ_ENABLE)? 1 : 0;
|
||||
audio_enable_eq(audio, enable);
|
||||
enable = (enable_mask & IIR_ENABLE)? 1 : 0;
|
||||
audio_enable_rx_iir(audio, enable);
|
||||
break;
|
||||
|
||||
case AUDIO_SET_ADRC:
|
||||
if (copy_from_user(&audio->adrc, (void*) arg, sizeof(audio->adrc)))
|
||||
goto out_fault;
|
||||
break;
|
||||
|
||||
case AUDIO_SET_EQ:
|
||||
if (copy_from_user(&audio->eq, (void*) arg, sizeof(audio->eq)))
|
||||
goto out_fault;
|
||||
break;
|
||||
|
||||
case AUDIO_SET_RX_IIR:
|
||||
if (copy_from_user(&audio->iir, (void*) arg, sizeof(audio->iir)))
|
||||
goto out_fault;
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
out_fault:
|
||||
rc = -EFAULT;
|
||||
out:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audpp_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_audio;
|
||||
|
||||
file->private_data = audio;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations audio_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audio_open,
|
||||
.release = audio_release,
|
||||
.read = audio_read,
|
||||
.write = audio_write,
|
||||
.unlocked_ioctl = audio_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static struct file_operations audpp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audpp_open,
|
||||
.unlocked_ioctl = audpp_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_pcm_out",
|
||||
.fops = &audio_fops,
|
||||
};
|
||||
|
||||
struct miscdevice audpp_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_pcm_ctl",
|
||||
.fops = &audpp_fops,
|
||||
};
|
||||
|
||||
static int __init audio_init(void)
|
||||
{
|
||||
mutex_init(&the_audio.lock);
|
||||
mutex_init(&the_audio.write_lock);
|
||||
spin_lock_init(&the_audio.dsp_lock);
|
||||
init_waitqueue_head(&the_audio.wait);
|
||||
return (misc_register(&audio_misc) || misc_register(&audpp_misc));
|
||||
}
|
||||
|
||||
device_initcall(audio_init);
|
|
@ -1,858 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audio_qcelp.c
|
||||
*
|
||||
* qcelp 13k audio decoder device
|
||||
*
|
||||
* Copyright (c) 2008 QUALCOMM USA, INC.
|
||||
*
|
||||
* This code is based in part on audio_mp3.c, which is
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
* Copyright (C) 2008 HTC 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.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <linux/msm_audio.h>
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
#include <mach/qdsp5/qdsp5audplaycmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audplaymsg.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
/* for queue ids - should be relative to module number*/
|
||||
#include "adsp.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintk(format, arg...) \
|
||||
printk(KERN_DEBUG format, ## arg)
|
||||
#else
|
||||
#define dprintk(format, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define BUFSZ 1080 /* QCELP 13K Hold 600ms packet data = 36 * 30 */
|
||||
#define BUF_COUNT 2
|
||||
#define DMASZ (BUFSZ * BUF_COUNT)
|
||||
|
||||
#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
|
||||
#define PCM_BUF_MAX_COUNT 5
|
||||
|
||||
#define AUDDEC_DEC_QCELP 9
|
||||
|
||||
#define ROUTING_MODE_FTRT 1
|
||||
#define ROUTING_MODE_RT 2
|
||||
/* Decoder status received from AUDPPTASK */
|
||||
#define AUDPP_DEC_STATUS_SLEEP 0
|
||||
#define AUDPP_DEC_STATUS_INIT 1
|
||||
#define AUDPP_DEC_STATUS_CFG 2
|
||||
#define AUDPP_DEC_STATUS_PLAY 3
|
||||
|
||||
struct buffer {
|
||||
void *data;
|
||||
unsigned size;
|
||||
unsigned used; /* Input usage actual DSP produced PCM size */
|
||||
unsigned addr;
|
||||
};
|
||||
|
||||
struct audio {
|
||||
struct buffer out[BUF_COUNT];
|
||||
|
||||
spinlock_t dsp_lock;
|
||||
|
||||
uint8_t out_head;
|
||||
uint8_t out_tail;
|
||||
uint8_t out_needed; /* number of buffers the dsp is waiting for */
|
||||
|
||||
struct mutex lock;
|
||||
struct mutex write_lock;
|
||||
wait_queue_head_t write_wait;
|
||||
|
||||
/* Host PCM section - START */
|
||||
struct buffer in[PCM_BUF_MAX_COUNT];
|
||||
struct mutex read_lock;
|
||||
wait_queue_head_t read_wait; /* Wait queue for read */
|
||||
char *read_data; /* pointer to reader buffer */
|
||||
dma_addr_t read_phys; /* physical address of reader buffer */
|
||||
uint8_t read_next; /* index to input buffers to be read next */
|
||||
uint8_t fill_next; /* index to buffer that DSP should be filling */
|
||||
uint8_t pcm_buf_count; /* number of pcm buffer allocated */
|
||||
/* Host PCM section - END */
|
||||
|
||||
struct msm_adsp_module *audplay;
|
||||
|
||||
struct audmgr audmgr;
|
||||
|
||||
/* data allocated for various buffers */
|
||||
char *data;
|
||||
dma_addr_t phys;
|
||||
|
||||
uint8_t opened:1;
|
||||
uint8_t enabled:1;
|
||||
uint8_t running:1;
|
||||
uint8_t stopped:1; /* set when stopped, cleared on flush */
|
||||
uint8_t pcm_feedback:1; /* set when non-tunnel mode */
|
||||
uint8_t buf_refresh:1;
|
||||
|
||||
unsigned volume;
|
||||
|
||||
uint16_t dec_id;
|
||||
};
|
||||
|
||||
static struct audio the_qcelp_audio;
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable);
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio);
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio);
|
||||
static void audqcelp_send_data(struct audio *audio, unsigned needed);
|
||||
static void audqcelp_config_hostpcm(struct audio *audio);
|
||||
static void audqcelp_buffer_refresh(struct audio *audio);
|
||||
static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audqcelp_enable(struct audio *audio)
|
||||
{
|
||||
struct audmgr_config cfg;
|
||||
int rc;
|
||||
|
||||
dprintk("audqcelp_enable()\n");
|
||||
|
||||
if (audio->enabled)
|
||||
return 0;
|
||||
|
||||
audio->out_tail = 0;
|
||||
audio->out_needed = 0;
|
||||
|
||||
cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
|
||||
cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
|
||||
cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
|
||||
cfg.codec = RPC_AUD_DEF_CODEC_13K;
|
||||
cfg.snd_method = RPC_SND_METHOD_MIDI;
|
||||
|
||||
rc = audmgr_enable(&audio->audmgr, &cfg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msm_adsp_enable(audio->audplay)) {
|
||||
pr_err("audio: msm_adsp_enable(audplay) failed\n");
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) {
|
||||
pr_err("audio: audpp_enable() failed\n");
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
return -ENODEV;
|
||||
}
|
||||
audio->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must be called with audio->lock held */
|
||||
static int audqcelp_disable(struct audio *audio)
|
||||
{
|
||||
dprintk("audqcelp_disable()\n");
|
||||
if (audio->enabled) {
|
||||
audio->enabled = 0;
|
||||
auddec_dsp_config(audio, 0);
|
||||
wake_up(&audio->write_wait);
|
||||
wake_up(&audio->read_wait);
|
||||
msm_adsp_disable(audio->audplay);
|
||||
audpp_disable(audio->dec_id, audio);
|
||||
audmgr_disable(&audio->audmgr);
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------- dsp --------------------- */
|
||||
static void audqcelp_update_pcm_buf_entry(struct audio *audio,
|
||||
uint32_t *payload)
|
||||
{
|
||||
uint8_t index;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
for (index = 0; index < payload[1]; index++) {
|
||||
if (audio->in[audio->fill_next].addr ==
|
||||
payload[2 + index * 2]) {
|
||||
dprintk("audqcelp_update_pcm_buf_entry: in[%d] ready\n",
|
||||
audio->fill_next);
|
||||
audio->in[audio->fill_next].used =
|
||||
payload[3 + index * 2];
|
||||
if ((++audio->fill_next) == audio->pcm_buf_count)
|
||||
audio->fill_next = 0;
|
||||
} else {
|
||||
pr_err(
|
||||
"audqcelp_update_pcm_buf_entry: expected=%x ret=%x\n",
|
||||
audio->in[audio->fill_next].addr,
|
||||
payload[1 + index * 2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (audio->in[audio->fill_next].used == 0) {
|
||||
audqcelp_buffer_refresh(audio);
|
||||
} else {
|
||||
dprintk("audqcelp_update_pcm_buf_entry: read cannot keep up\n");
|
||||
audio->buf_refresh = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
wake_up(&audio->read_wait);
|
||||
}
|
||||
|
||||
static void audplay_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent) (void *ptr, size_t len))
|
||||
{
|
||||
struct audio *audio = data;
|
||||
uint32_t msg[28];
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
dprintk("audplay_dsp_event: msg_id=%x\n", id);
|
||||
|
||||
switch (id) {
|
||||
case AUDPLAY_MSG_DEC_NEEDS_DATA:
|
||||
audqcelp_send_data(audio, 1);
|
||||
break;
|
||||
|
||||
case AUDPLAY_MSG_BUFFER_UPDATE:
|
||||
audqcelp_update_pcm_buf_entry(audio, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("unexpected message from decoder \n");
|
||||
}
|
||||
}
|
||||
|
||||
static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg)
|
||||
{
|
||||
struct audio *audio = private;
|
||||
|
||||
switch (id) {
|
||||
case AUDPP_MSG_STATUS_MSG:{
|
||||
unsigned status = msg[1];
|
||||
|
||||
switch (status) {
|
||||
case AUDPP_DEC_STATUS_SLEEP:
|
||||
dprintk("decoder status: sleep \n");
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_INIT:
|
||||
dprintk("decoder status: init \n");
|
||||
audpp_cmd_cfg_routing_mode(audio);
|
||||
break;
|
||||
|
||||
case AUDPP_DEC_STATUS_CFG:
|
||||
dprintk("decoder status: cfg \n");
|
||||
break;
|
||||
case AUDPP_DEC_STATUS_PLAY:
|
||||
dprintk("decoder status: play \n");
|
||||
if (audio->pcm_feedback) {
|
||||
audqcelp_config_hostpcm(audio);
|
||||
audqcelp_buffer_refresh(audio);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown decoder status \n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
dprintk("audqcelp_dsp_event: CFG_MSG ENABLE\n");
|
||||
auddec_dsp_config(audio, 1);
|
||||
audio->out_needed = 0;
|
||||
audio->running = 1;
|
||||
audpp_set_volume_and_pan(audio->dec_id, audio->volume,
|
||||
0);
|
||||
audpp_avsync(audio->dec_id, 22050);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
dprintk("audqcelp_dsp_event: CFG_MSG DISABLE\n");
|
||||
audpp_avsync(audio->dec_id, 0);
|
||||
audio->running = 0;
|
||||
} else {
|
||||
pr_err("audqcelp_dsp_event: CFG_MSG %d?\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDPP_MSG_ROUTING_ACK:
|
||||
dprintk("audqcelp_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
|
||||
audpp_cmd_cfg_adec_params(audio);
|
||||
break;
|
||||
default:
|
||||
pr_err("audqcelp_dsp_event: UNKNOWN (%d)\n", id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct msm_adsp_ops audplay_adsp_ops_qcelp = {
|
||||
.event = audplay_dsp_event,
|
||||
};
|
||||
|
||||
#define audplay_send_queue0(audio, cmd, len) \
|
||||
msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
|
||||
cmd, len)
|
||||
|
||||
static int auddec_dsp_config(struct audio *audio, int enable)
|
||||
{
|
||||
audpp_cmd_cfg_dec_type cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
|
||||
if (enable)
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
|
||||
AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP;
|
||||
else
|
||||
cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
|
||||
|
||||
return audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_adec_params(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_cfg_adec_params_v13k cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
|
||||
cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
|
||||
cmd.common.dec_id = audio->dec_id;
|
||||
cmd.common.input_sampling_frequency = 8000;
|
||||
cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
|
||||
|
||||
audpp_send_queue2(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_cmd_cfg_routing_mode(struct audio *audio)
|
||||
{
|
||||
struct audpp_cmd_routing_mode cmd;
|
||||
dprintk("audpp_cmd_cfg_routing_mode()\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
|
||||
cmd.object_number = audio->dec_id;
|
||||
if (audio->pcm_feedback)
|
||||
cmd.routing_mode = ROUTING_MODE_FTRT;
|
||||
else
|
||||
cmd.routing_mode = ROUTING_MODE_RT;
|
||||
audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int audplay_dsp_send_data_avail(struct audio *audio,
|
||||
unsigned idx, unsigned len)
|
||||
{
|
||||
audplay_cmd_bitstream_data_avail cmd;
|
||||
|
||||
cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
|
||||
cmd.decoder_id = audio->dec_id;
|
||||
cmd.buf_ptr = audio->out[idx].addr;
|
||||
cmd.buf_size = len / 2;
|
||||
cmd.partition_number = 0;
|
||||
return audplay_send_queue0(audio, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audqcelp_buffer_refresh(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_buffer_refresh refresh_cmd;
|
||||
|
||||
refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
|
||||
refresh_cmd.num_buffers = 1;
|
||||
refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
|
||||
refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
|
||||
refresh_cmd.buf_read_count = 0;
|
||||
dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
|
||||
refresh_cmd.buf0_address, refresh_cmd.buf0_length);
|
||||
|
||||
(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
|
||||
}
|
||||
|
||||
static void audqcelp_config_hostpcm(struct audio *audio)
|
||||
{
|
||||
struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
|
||||
|
||||
dprintk("audqcelp_config_hostpcm()\n");
|
||||
cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
|
||||
cfg_cmd.max_buffers = audio->pcm_buf_count;
|
||||
cfg_cmd.byte_swap = 0;
|
||||
cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
|
||||
cfg_cmd.feedback_frequency = 1;
|
||||
cfg_cmd.partition_number = 0;
|
||||
|
||||
(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
|
||||
}
|
||||
|
||||
static void audqcelp_send_data(struct audio *audio, unsigned needed)
|
||||
{
|
||||
struct buffer *frame;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
if (!audio->running)
|
||||
goto done;
|
||||
|
||||
if (needed) {
|
||||
/* We were called from the callback because the DSP
|
||||
* requested more data. Note that the DSP does want
|
||||
* more data, and if a buffer was in-flight, mark it
|
||||
* as available (since the DSP must now be done with
|
||||
* it).
|
||||
*/
|
||||
audio->out_needed = 1;
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used == 0xffffffff) {
|
||||
dprintk("frame %d free\n", audio->out_tail);
|
||||
frame->used = 0;
|
||||
audio->out_tail ^= 1;
|
||||
wake_up(&audio->write_wait);
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->out_needed) {
|
||||
/* If the DSP currently wants data and we have a
|
||||
* buffer available, we will send it and reset
|
||||
* the needed flag. We'll mark the buffer as in-flight
|
||||
* so that it won't be recycled until the next buffer
|
||||
* is requested
|
||||
*/
|
||||
|
||||
frame = audio->out + audio->out_tail;
|
||||
if (frame->used) {
|
||||
BUG_ON(frame->used == 0xffffffff);
|
||||
dprintk("frame %d busy\n", audio->out_tail);
|
||||
audplay_dsp_send_data_avail(audio, audio->out_tail,
|
||||
frame->used);
|
||||
frame->used = 0xffffffff;
|
||||
audio->out_needed = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
}
|
||||
|
||||
/* ------------------- device --------------------- */
|
||||
|
||||
static void audqcelp_flush(struct audio *audio)
|
||||
{
|
||||
audio->out[0].used = 0;
|
||||
audio->out[1].used = 0;
|
||||
audio->out_head = 0;
|
||||
audio->out_tail = 0;
|
||||
audio->stopped = 0;
|
||||
}
|
||||
|
||||
static void audqcelp_flush_pcm_buf(struct audio *audio)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
|
||||
audio->in[index].used = 0;
|
||||
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
}
|
||||
|
||||
static long audqcelp_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
dprintk("audqcelp_ioctl() cmd = %d\n", cmd);
|
||||
|
||||
if (cmd == AUDIO_GET_STATS) {
|
||||
struct msm_audio_stats stats;
|
||||
stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
|
||||
stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
|
||||
if (copy_to_user((void *)arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (cmd == AUDIO_SET_VOLUME) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&audio->dsp_lock, flags);
|
||||
audio->volume = arg;
|
||||
if (audio->running)
|
||||
audpp_set_volume_and_pan(audio->dec_id, arg, 0);
|
||||
spin_unlock_irqrestore(&audio->dsp_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&audio->lock);
|
||||
switch (cmd) {
|
||||
case AUDIO_START:
|
||||
rc = audqcelp_enable(audio);
|
||||
break;
|
||||
case AUDIO_STOP:
|
||||
rc = audqcelp_disable(audio);
|
||||
audio->stopped = 1;
|
||||
break;
|
||||
case AUDIO_FLUSH:
|
||||
if (audio->stopped) {
|
||||
/* Make sure we're stopped and we wake any threads
|
||||
* that might be blocked holding the write_lock.
|
||||
* While audio->stopped write threads will always
|
||||
* exit immediately.
|
||||
*/
|
||||
wake_up(&audio->write_wait);
|
||||
mutex_lock(&audio->write_lock);
|
||||
audqcelp_flush(audio);
|
||||
mutex_unlock(&audio->write_lock);
|
||||
wake_up(&audio->read_wait);
|
||||
mutex_lock(&audio->read_lock);
|
||||
audqcelp_flush_pcm_buf(audio);
|
||||
mutex_unlock(&audio->read_lock);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AUDIO_SET_CONFIG:
|
||||
dprintk("AUDIO_SET_CONFIG not applicable \n");
|
||||
break;
|
||||
case AUDIO_GET_CONFIG:{
|
||||
struct msm_audio_config config;
|
||||
config.buffer_size = BUFSZ;
|
||||
config.buffer_count = BUF_COUNT;
|
||||
config.sample_rate = 8000;
|
||||
config.channel_count = 1;
|
||||
config.unused[0] = 0;
|
||||
config.unused[1] = 0;
|
||||
config.unused[2] = 0;
|
||||
config.unused[3] = 0;
|
||||
if (copy_to_user((void *)arg, &config,
|
||||
sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
case AUDIO_GET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
|
||||
config.pcm_feedback = 0;
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
if (copy_to_user((void *)arg, &config,
|
||||
sizeof(config)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
case AUDIO_SET_PCM_CONFIG:{
|
||||
struct msm_audio_pcm_config config;
|
||||
|
||||
if (copy_from_user(&config, (void *)arg,
|
||||
sizeof(config))) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
|
||||
(config.buffer_count == 1))
|
||||
config.buffer_count = PCM_BUF_MAX_COUNT;
|
||||
|
||||
if (config.buffer_size < PCM_BUFSZ_MIN)
|
||||
config.buffer_size = PCM_BUFSZ_MIN;
|
||||
|
||||
/* Check if pcm feedback is required */
|
||||
if ((config.pcm_feedback) && (!audio->read_data)) {
|
||||
dprintk(
|
||||
"audqcelp_ioctl: allocate PCM buf %d\n",
|
||||
config.buffer_count * config.buffer_size);
|
||||
audio->read_data = dma_alloc_coherent(NULL,
|
||||
config.buffer_size * config.buffer_count,
|
||||
&audio->read_phys, GFP_KERNEL);
|
||||
if (!audio->read_data) {
|
||||
pr_err(
|
||||
"audqcelp_ioctl: no mem for pcm buf\n"
|
||||
);
|
||||
rc = -ENOMEM;
|
||||
} else {
|
||||
uint8_t index;
|
||||
uint32_t offset = 0;
|
||||
|
||||
audio->pcm_feedback = 1;
|
||||
audio->buf_refresh = 0;
|
||||
audio->pcm_buf_count =
|
||||
config.buffer_count;
|
||||
audio->read_next = 0;
|
||||
audio->fill_next = 0;
|
||||
|
||||
for (index = 0;
|
||||
index < config.buffer_count; index++) {
|
||||
audio->in[index].data =
|
||||
audio->read_data + offset;
|
||||
audio->in[index].addr =
|
||||
audio->read_phys + offset;
|
||||
audio->in[index].size =
|
||||
config.buffer_size;
|
||||
audio->in[index].used = 0;
|
||||
offset += config.buffer_size;
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUDIO_PAUSE:
|
||||
dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
|
||||
rc = audpp_pause(audio->dec_id, (int) arg);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
int rc = 0;
|
||||
|
||||
if (!audio->pcm_feedback)
|
||||
return 0; /* PCM feedback is not enabled. Nothing to read */
|
||||
|
||||
mutex_lock(&audio->read_lock);
|
||||
dprintk("audqcelp_read() %d \n", count);
|
||||
while (count > 0) {
|
||||
rc = wait_event_interruptible(audio->read_wait,
|
||||
(audio->in[audio->read_next].used > 0) ||
|
||||
(audio->stopped));
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count < audio->in[audio->read_next].used) {
|
||||
/* Read must happen in frame boundary. Since driver does
|
||||
not know frame size, read count must be greater or equal
|
||||
to size of PCM samples */
|
||||
dprintk("audqcelp_read:read stop - partial frame\n");
|
||||
break;
|
||||
} else {
|
||||
dprintk("audqcelp_read: read from in[%d]\n",
|
||||
audio->read_next);
|
||||
if (copy_to_user(buf,
|
||||
audio->in[audio->read_next].data,
|
||||
audio->in[audio->read_next].used)) {
|
||||
pr_err("audqcelp_read: invalid addr %x \n",
|
||||
(unsigned int)buf);
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
count -= audio->in[audio->read_next].used;
|
||||
buf += audio->in[audio->read_next].used;
|
||||
audio->in[audio->read_next].used = 0;
|
||||
if ((++audio->read_next) == audio->pcm_buf_count)
|
||||
audio->read_next = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (audio->buf_refresh) {
|
||||
audio->buf_refresh = 0;
|
||||
dprintk("audqcelp_read: kick start pcm feedback again\n");
|
||||
audqcelp_buffer_refresh(audio);
|
||||
}
|
||||
|
||||
mutex_unlock(&audio->read_lock);
|
||||
|
||||
if (buf > start)
|
||||
rc = buf - start;
|
||||
|
||||
dprintk("audqcelp_read: read %d bytes\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t audqcelp_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
const char __user *start = buf;
|
||||
struct buffer *frame;
|
||||
size_t xfer;
|
||||
int rc = 0;
|
||||
|
||||
if (count & 1)
|
||||
return -EINVAL;
|
||||
dprintk("audqcelp_write() \n");
|
||||
mutex_lock(&audio->write_lock);
|
||||
while (count > 0) {
|
||||
frame = audio->out + audio->out_head;
|
||||
rc = wait_event_interruptible(audio->write_wait,
|
||||
(frame->used == 0)
|
||||
|| (audio->stopped));
|
||||
dprintk("audqcelp_write() buffer available\n");
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (audio->stopped) {
|
||||
rc = -EBUSY;
|
||||
break;
|
||||
}
|
||||
xfer = (count > frame->size) ? frame->size : count;
|
||||
if (copy_from_user(frame->data, buf, xfer)) {
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
frame->used = xfer;
|
||||
audio->out_head ^= 1;
|
||||
count -= xfer;
|
||||
buf += xfer;
|
||||
|
||||
audqcelp_send_data(audio, 0);
|
||||
|
||||
}
|
||||
mutex_unlock(&audio->write_lock);
|
||||
if (buf > start)
|
||||
return buf - start;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audqcelp_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = file->private_data;
|
||||
|
||||
dprintk("audqcelp_release()\n");
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
audqcelp_disable(audio);
|
||||
audqcelp_flush(audio);
|
||||
audqcelp_flush_pcm_buf(audio);
|
||||
msm_adsp_put(audio->audplay);
|
||||
audio->audplay = NULL;
|
||||
audio->opened = 0;
|
||||
if (audio->data)
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
audio->data = NULL;
|
||||
if (audio->read_data) {
|
||||
dma_free_coherent(NULL,
|
||||
audio->in[0].size * audio->pcm_buf_count,
|
||||
audio->read_data, audio->read_phys);
|
||||
audio->read_data = NULL;
|
||||
}
|
||||
audio->pcm_feedback = 0;
|
||||
mutex_unlock(&audio->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audqcelp_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct audio *audio = &the_qcelp_audio;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&audio->lock);
|
||||
|
||||
if (audio->opened) {
|
||||
pr_err("audio: busy\n");
|
||||
rc = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
audio->data = dma_alloc_coherent(NULL, DMASZ,
|
||||
&audio->phys, GFP_KERNEL);
|
||||
if (!audio->data) {
|
||||
pr_err("audio: could not allocate DMA buffers\n");
|
||||
rc = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = audmgr_open(&audio->audmgr);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
|
||||
&audplay_adsp_ops_qcelp, audio);
|
||||
if (rc) {
|
||||
pr_err("audio: failed to get audplay0 dsp module\n");
|
||||
audmgr_close(&audio->audmgr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
audio->dec_id = 0;
|
||||
|
||||
audio->out[0].data = audio->data + 0;
|
||||
audio->out[0].addr = audio->phys + 0;
|
||||
audio->out[0].size = BUFSZ;
|
||||
|
||||
audio->out[1].data = audio->data + BUFSZ;
|
||||
audio->out[1].addr = audio->phys + BUFSZ;
|
||||
audio->out[1].size = BUFSZ;
|
||||
|
||||
audio->volume = 0x2000; /* Q13 1.0 */
|
||||
|
||||
audqcelp_flush(audio);
|
||||
|
||||
file->private_data = audio;
|
||||
audio->opened = 1;
|
||||
rc = 0;
|
||||
done:
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
err:
|
||||
dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
|
||||
mutex_unlock(&audio->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations audio_qcelp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = audqcelp_open,
|
||||
.release = audqcelp_release,
|
||||
.read = audqcelp_read,
|
||||
.write = audqcelp_write,
|
||||
.unlocked_ioctl = audqcelp_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice audio_qcelp_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_qcelp",
|
||||
.fops = &audio_qcelp_fops,
|
||||
};
|
||||
|
||||
static int __init audqcelp_init(void)
|
||||
{
|
||||
mutex_init(&the_qcelp_audio.lock);
|
||||
mutex_init(&the_qcelp_audio.write_lock);
|
||||
mutex_init(&the_qcelp_audio.read_lock);
|
||||
spin_lock_init(&the_qcelp_audio.dsp_lock);
|
||||
init_waitqueue_head(&the_qcelp_audio.write_wait);
|
||||
init_waitqueue_head(&the_qcelp_audio.read_wait);
|
||||
the_qcelp_audio.read_data = NULL;
|
||||
return misc_register(&audio_qcelp_misc);
|
||||
}
|
||||
|
||||
static void __exit audqcelp_exit(void)
|
||||
{
|
||||
misc_deregister(&audio_qcelp_misc);
|
||||
}
|
||||
|
||||
module_init(audqcelp_init);
|
||||
module_exit(audqcelp_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM QCELP 13K driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("QUALCOMM");
|
|
@ -1,314 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audmgr.c
|
||||
*
|
||||
* interface to "audmgr" service on the baseband cpu
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
|
||||
#define STATE_CLOSED 0
|
||||
#define STATE_DISABLED 1
|
||||
#define STATE_ENABLING 2
|
||||
#define STATE_ENABLED 3
|
||||
#define STATE_DISABLING 4
|
||||
#define STATE_ERROR 5
|
||||
|
||||
static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid)
|
||||
{
|
||||
uint32_t rep[6];
|
||||
|
||||
rep[0] = cpu_to_be32(xid);
|
||||
rep[1] = cpu_to_be32(1);
|
||||
rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
|
||||
rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
|
||||
rep[4] = 0;
|
||||
rep[5] = 0;
|
||||
|
||||
msm_rpc_write(ept, rep, sizeof(rep));
|
||||
}
|
||||
|
||||
static void process_audmgr_callback(struct audmgr *am,
|
||||
struct rpc_audmgr_cb_func_ptr *args,
|
||||
int len)
|
||||
{
|
||||
if (len < (sizeof(uint32_t) * 3))
|
||||
return;
|
||||
if (be32_to_cpu(args->set_to_one) != 1)
|
||||
return;
|
||||
|
||||
switch (be32_to_cpu(args->status)) {
|
||||
case RPC_AUDMGR_STATUS_READY:
|
||||
if (len < sizeof(uint32_t) * 4)
|
||||
break;
|
||||
am->handle = be32_to_cpu(args->u.handle);
|
||||
pr_info("audmgr: rpc READY handle=0x%08x\n", am->handle);
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
|
||||
uint32_t volume;
|
||||
if (len < sizeof(uint32_t) * 4)
|
||||
break;
|
||||
volume = be32_to_cpu(args->u.volume);
|
||||
pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume);
|
||||
am->state = STATE_ENABLED;
|
||||
wake_up(&am->wait);
|
||||
break;
|
||||
}
|
||||
case RPC_AUDMGR_STATUS_PENDING:
|
||||
pr_err("audmgr: PENDING?\n");
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_SUSPEND:
|
||||
pr_err("audmgr: SUSPEND?\n");
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_FAILURE:
|
||||
pr_err("audmgr: FAILURE\n");
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_VOLUME_CHANGE:
|
||||
pr_err("audmgr: VOLUME_CHANGE?\n");
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_DISABLED:
|
||||
pr_err("audmgr: DISABLED\n");
|
||||
am->state = STATE_DISABLED;
|
||||
wake_up(&am->wait);
|
||||
break;
|
||||
case RPC_AUDMGR_STATUS_ERROR:
|
||||
pr_err("audmgr: ERROR?\n");
|
||||
am->state = STATE_ERROR;
|
||||
wake_up(&am->wait);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_rpc_request(uint32_t proc, uint32_t xid,
|
||||
void *data, int len, void *private)
|
||||
{
|
||||
struct audmgr *am = private;
|
||||
uint32_t *x = data;
|
||||
|
||||
if (0) {
|
||||
int n = len / 4;
|
||||
pr_info("rpc_call proc %d:", proc);
|
||||
while (n--)
|
||||
printk(" %08x", be32_to_cpu(*x++));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
if (proc == AUDMGR_CB_FUNC_PTR)
|
||||
process_audmgr_callback(am, data, len);
|
||||
else
|
||||
pr_err("audmgr: unknown rpc proc %d\n", proc);
|
||||
rpc_ack(am->ept, xid);
|
||||
}
|
||||
|
||||
#define RPC_TYPE_REQUEST 0
|
||||
#define RPC_TYPE_REPLY 1
|
||||
|
||||
#define RPC_VERSION 2
|
||||
|
||||
#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2)
|
||||
#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr))
|
||||
#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3)
|
||||
#define RPC_REPLY_SZ (sizeof(uint32_t) * 6)
|
||||
|
||||
static int audmgr_rpc_thread(void *data)
|
||||
{
|
||||
struct audmgr *am = data;
|
||||
struct rpc_request_hdr *hdr = NULL;
|
||||
uint32_t type;
|
||||
int len;
|
||||
|
||||
pr_info("audmgr_rpc_thread() start\n");
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
if (hdr) {
|
||||
kfree(hdr);
|
||||
hdr = NULL;
|
||||
}
|
||||
len = msm_rpc_read(am->ept, (void **) &hdr, -1, -1);
|
||||
if (len < 0) {
|
||||
pr_err("audmgr: rpc read failed (%d)\n", len);
|
||||
break;
|
||||
}
|
||||
if (len < RPC_COMMON_HDR_SZ)
|
||||
continue;
|
||||
|
||||
type = be32_to_cpu(hdr->type);
|
||||
if (type == RPC_TYPE_REPLY) {
|
||||
struct rpc_reply_hdr *rep = (void *) hdr;
|
||||
uint32_t status;
|
||||
if (len < RPC_REPLY_HDR_SZ)
|
||||
continue;
|
||||
status = be32_to_cpu(rep->reply_stat);
|
||||
if (status == RPCMSG_REPLYSTAT_ACCEPTED) {
|
||||
status = be32_to_cpu(rep->data.acc_hdr.accept_stat);
|
||||
pr_info("audmgr: rpc_reply status %d\n", status);
|
||||
} else {
|
||||
pr_info("audmgr: rpc_reply denied!\n");
|
||||
}
|
||||
/* process reply */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len < RPC_REQUEST_HDR_SZ)
|
||||
continue;
|
||||
|
||||
process_rpc_request(be32_to_cpu(hdr->procedure),
|
||||
be32_to_cpu(hdr->xid),
|
||||
(void *) (hdr + 1),
|
||||
len - sizeof(*hdr),
|
||||
data);
|
||||
}
|
||||
pr_info("audmgr_rpc_thread() exit\n");
|
||||
if (hdr) {
|
||||
kfree(hdr);
|
||||
hdr = NULL;
|
||||
}
|
||||
am->task = NULL;
|
||||
wake_up(&am->wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct audmgr_enable_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
struct rpc_audmgr_enable_client_args args;
|
||||
};
|
||||
|
||||
struct audmgr_disable_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
int audmgr_open(struct audmgr *am)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (am->state != STATE_CLOSED)
|
||||
return 0;
|
||||
|
||||
am->ept = msm_rpc_connect(AUDMGR_PROG,
|
||||
AUDMGR_VERS,
|
||||
MSM_RPC_UNINTERRUPTIBLE);
|
||||
|
||||
init_waitqueue_head(&am->wait);
|
||||
|
||||
if (IS_ERR(am->ept)) {
|
||||
rc = PTR_ERR(am->ept);
|
||||
am->ept = NULL;
|
||||
pr_err("audmgr: failed to connect to audmgr svc\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
am->task = kthread_run(audmgr_rpc_thread, am, "audmgr_rpc");
|
||||
if (IS_ERR(am->task)) {
|
||||
rc = PTR_ERR(am->task);
|
||||
am->task = NULL;
|
||||
msm_rpc_close(am->ept);
|
||||
am->ept = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
am->state = STATE_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(audmgr_open);
|
||||
|
||||
int audmgr_close(struct audmgr *am)
|
||||
{
|
||||
return -EBUSY;
|
||||
}
|
||||
EXPORT_SYMBOL(audmgr_close);
|
||||
|
||||
int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg)
|
||||
{
|
||||
struct audmgr_enable_msg msg;
|
||||
int rc;
|
||||
|
||||
if (am->state == STATE_ENABLED)
|
||||
return 0;
|
||||
|
||||
if (am->state == STATE_DISABLING)
|
||||
pr_err("audmgr: state is DISABLING in enable?\n");
|
||||
am->state = STATE_ENABLING;
|
||||
|
||||
msg.args.set_to_one = cpu_to_be32(1);
|
||||
msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate);
|
||||
msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate);
|
||||
msg.args.def_method = cpu_to_be32(cfg->def_method);
|
||||
msg.args.codec_type = cpu_to_be32(cfg->codec);
|
||||
msg.args.snd_method = cpu_to_be32(cfg->snd_method);
|
||||
msg.args.cb_func = cpu_to_be32(0x11111111);
|
||||
msg.args.client_data = cpu_to_be32(0x11223344);
|
||||
|
||||
msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
|
||||
AUDMGR_ENABLE_CLIENT);
|
||||
|
||||
rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ);
|
||||
if (rc == 0) {
|
||||
pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am->state);
|
||||
BUG();
|
||||
}
|
||||
if (am->state == STATE_ENABLED)
|
||||
return 0;
|
||||
|
||||
pr_err("audmgr: unexpected state %d while enabling?!\n", am->state);
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL(audmgr_enable);
|
||||
|
||||
int audmgr_disable(struct audmgr *am)
|
||||
{
|
||||
struct audmgr_disable_msg msg;
|
||||
int rc;
|
||||
|
||||
if (am->state == STATE_DISABLED)
|
||||
return 0;
|
||||
|
||||
msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
|
||||
AUDMGR_DISABLE_CLIENT);
|
||||
msg.handle = cpu_to_be32(am->handle);
|
||||
|
||||
am->state = STATE_DISABLING;
|
||||
|
||||
rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ);
|
||||
if (rc == 0) {
|
||||
pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am->state);
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (am->state == STATE_DISABLED)
|
||||
return 0;
|
||||
|
||||
pr_err("audmgr: unexpected state %d while disabling?!\n", am->state);
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL(audmgr_disable);
|
|
@ -1,215 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audmgr.h
|
||||
*
|
||||
* Copyright 2008 (c) QUALCOMM Incorporated.
|
||||
* Copyright (C) 2008 Google, 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_MSM_AUDMGR_H
|
||||
#define _ARCH_ARM_MACH_MSM_AUDMGR_H
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION==6350
|
||||
#include "audmgr_new.h"
|
||||
#else
|
||||
|
||||
enum rpc_aud_def_sample_rate_type {
|
||||
RPC_AUD_DEF_SAMPLE_RATE_NONE,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_8000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_11025,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_12000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_16000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_22050,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_24000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_32000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_44100,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_48000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_MAX,
|
||||
};
|
||||
|
||||
enum rpc_aud_def_method_type {
|
||||
RPC_AUD_DEF_METHOD_NONE,
|
||||
RPC_AUD_DEF_METHOD_KEY_BEEP,
|
||||
RPC_AUD_DEF_METHOD_PLAYBACK,
|
||||
RPC_AUD_DEF_METHOD_VOICE,
|
||||
RPC_AUD_DEF_METHOD_RECORD,
|
||||
RPC_AUD_DEF_METHOD_HOST_PCM,
|
||||
RPC_AUD_DEF_METHOD_MIDI_OUT,
|
||||
RPC_AUD_DEF_METHOD_RECORD_SBC,
|
||||
RPC_AUD_DEF_METHOD_DTMF_RINGER,
|
||||
RPC_AUD_DEF_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum rpc_aud_def_codec_type {
|
||||
RPC_AUD_DEF_CODEC_NONE,
|
||||
RPC_AUD_DEF_CODEC_DTMF,
|
||||
RPC_AUD_DEF_CODEC_MIDI,
|
||||
RPC_AUD_DEF_CODEC_MP3,
|
||||
RPC_AUD_DEF_CODEC_PCM,
|
||||
RPC_AUD_DEF_CODEC_AAC,
|
||||
RPC_AUD_DEF_CODEC_WMA,
|
||||
RPC_AUD_DEF_CODEC_RA,
|
||||
RPC_AUD_DEF_CODEC_ADPCM,
|
||||
RPC_AUD_DEF_CODEC_GAUDIO,
|
||||
RPC_AUD_DEF_CODEC_VOC_EVRC,
|
||||
RPC_AUD_DEF_CODEC_VOC_13K,
|
||||
RPC_AUD_DEF_CODEC_VOC_4GV_NB,
|
||||
RPC_AUD_DEF_CODEC_VOC_AMR,
|
||||
RPC_AUD_DEF_CODEC_VOC_EFR,
|
||||
RPC_AUD_DEF_CODEC_VOC_FR,
|
||||
RPC_AUD_DEF_CODEC_VOC_HR,
|
||||
RPC_AUD_DEF_CODEC_VOC,
|
||||
RPC_AUD_DEF_CODEC_SBC,
|
||||
RPC_AUD_DEF_CODEC_VOC_PCM,
|
||||
RPC_AUD_DEF_CODEC_AMR_WB,
|
||||
RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
|
||||
RPC_AUD_DEF_CODEC_MAX,
|
||||
};
|
||||
|
||||
enum rpc_snd_method_type {
|
||||
RPC_SND_METHOD_VOICE = 0,
|
||||
RPC_SND_METHOD_KEY_BEEP,
|
||||
RPC_SND_METHOD_MESSAGE,
|
||||
RPC_SND_METHOD_RING,
|
||||
RPC_SND_METHOD_MIDI,
|
||||
RPC_SND_METHOD_AUX,
|
||||
RPC_SND_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum rpc_voc_codec_type {
|
||||
RPC_VOC_CODEC_DEFAULT,
|
||||
RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
|
||||
RPC_VOC_CODEC_ON_CHIP_1,
|
||||
RPC_VOC_CODEC_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_ON_CHIP_AUX,
|
||||
RPC_VOC_CODEC_BT_OFF_BOARD,
|
||||
RPC_VOC_CODEC_BT_A2DP,
|
||||
RPC_VOC_CODEC_OFF_BOARD,
|
||||
RPC_VOC_CODEC_SDAC,
|
||||
RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
|
||||
RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
|
||||
RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
|
||||
RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
|
||||
RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_TTY_ON_CHIP_1,
|
||||
RPC_VOC_CODEC_TTY_OFF_BOARD,
|
||||
RPC_VOC_CODEC_TTY_VCO,
|
||||
RPC_VOC_CODEC_TTY_HCO,
|
||||
RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
|
||||
RPC_VOC_CODEC_MAX,
|
||||
RPC_VOC_CODEC_NONE,
|
||||
};
|
||||
|
||||
enum rpc_audmgr_status_type {
|
||||
RPC_AUDMGR_STATUS_READY,
|
||||
RPC_AUDMGR_STATUS_CODEC_CONFIG,
|
||||
RPC_AUDMGR_STATUS_PENDING,
|
||||
RPC_AUDMGR_STATUS_SUSPEND,
|
||||
RPC_AUDMGR_STATUS_FAILURE,
|
||||
RPC_AUDMGR_STATUS_VOLUME_CHANGE,
|
||||
RPC_AUDMGR_STATUS_DISABLED,
|
||||
RPC_AUDMGR_STATUS_ERROR,
|
||||
};
|
||||
|
||||
struct rpc_audmgr_enable_client_args {
|
||||
uint32_t set_to_one;
|
||||
uint32_t tx_sample_rate;
|
||||
uint32_t rx_sample_rate;
|
||||
uint32_t def_method;
|
||||
uint32_t codec_type;
|
||||
uint32_t snd_method;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
#define AUDMGR_ENABLE_CLIENT 2
|
||||
#define AUDMGR_DISABLE_CLIENT 3
|
||||
#define AUDMGR_SUSPEND_EVENT_RSP 4
|
||||
#define AUDMGR_REGISTER_OPERATION_LISTENER 5
|
||||
#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6
|
||||
#define AUDMGR_REGISTER_CODEC_LISTENER 7
|
||||
#define AUDMGR_GET_RX_SAMPLE_RATE 8
|
||||
#define AUDMGR_GET_TX_SAMPLE_RATE 9
|
||||
#define AUDMGR_SET_DEVICE_MODE 10
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION < 6220
|
||||
#define AUDMGR_PROG_VERS "rs30000013:46255756"
|
||||
#define AUDMGR_PROG 0x30000013
|
||||
#define AUDMGR_VERS 0x46255756
|
||||
#else
|
||||
#define AUDMGR_PROG_VERS "rs30000013:e94e8f0c"
|
||||
#define AUDMGR_PROG 0x30000013
|
||||
#define AUDMGR_VERS 0xe94e8f0c
|
||||
#endif
|
||||
|
||||
struct rpc_audmgr_cb_func_ptr {
|
||||
uint32_t cb_id;
|
||||
uint32_t set_to_one;
|
||||
uint32_t status;
|
||||
union {
|
||||
uint32_t handle;
|
||||
uint32_t volume;
|
||||
|
||||
} u;
|
||||
};
|
||||
|
||||
#define AUDMGR_CB_FUNC_PTR 1
|
||||
#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2
|
||||
#define AUDMGR_CODEC_LSTR_FUNC_PTR 3
|
||||
|
||||
#if CONFIG_MSM_AMSS_VERSION < 6220
|
||||
#define AUDMGR_CB_PROG 0x31000013
|
||||
#define AUDMGR_CB_VERS 0x5fa922a9
|
||||
#else
|
||||
#define AUDMGR_CB_PROG 0x31000013
|
||||
#define AUDMGR_CB_VERS 0x21570ba7
|
||||
#endif
|
||||
|
||||
struct audmgr {
|
||||
wait_queue_head_t wait;
|
||||
uint32_t handle;
|
||||
struct msm_rpc_endpoint *ept;
|
||||
struct task_struct *task;
|
||||
int state;
|
||||
};
|
||||
|
||||
struct audmgr_config {
|
||||
uint32_t tx_rate;
|
||||
uint32_t rx_rate;
|
||||
uint32_t def_method;
|
||||
uint32_t codec;
|
||||
uint32_t snd_method;
|
||||
};
|
||||
|
||||
int audmgr_open(struct audmgr *am);
|
||||
int audmgr_close(struct audmgr *am);
|
||||
int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
|
||||
int audmgr_disable(struct audmgr *am);
|
||||
|
||||
typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
int audpp_enable(int id, audpp_event_func func, void *private);
|
||||
void audpp_disable(int id, void *private);
|
||||
|
||||
int audpp_send_queue1(void *cmd, unsigned len);
|
||||
int audpp_send_queue2(void *cmd, unsigned len);
|
||||
int audpp_send_queue3(void *cmd, unsigned len);
|
||||
|
||||
int audpp_pause(unsigned id, int pause);
|
||||
int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
|
||||
void audpp_avsync(int id, unsigned rate);
|
||||
unsigned audpp_avsync_sample_count(int id);
|
||||
unsigned audpp_avsync_byte_count(int id);
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -1,213 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/audmgr.h
|
||||
*
|
||||
* Copyright 2008 (c) QUALCOMM Incorporated.
|
||||
* Copyright (C) 2008 Google, 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_MSM_AUDMGR_NEW_H
|
||||
#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
|
||||
|
||||
enum rpc_aud_def_sample_rate_type {
|
||||
RPC_AUD_DEF_SAMPLE_RATE_NONE,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_8000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_11025,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_12000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_16000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_22050,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_24000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_32000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_44100,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_48000,
|
||||
RPC_AUD_DEF_SAMPLE_RATE_MAX,
|
||||
};
|
||||
|
||||
enum rpc_aud_def_method_type {
|
||||
RPC_AUD_DEF_METHOD_NONE,
|
||||
RPC_AUD_DEF_METHOD_KEY_BEEP,
|
||||
RPC_AUD_DEF_METHOD_PLAYBACK,
|
||||
RPC_AUD_DEF_METHOD_VOICE,
|
||||
RPC_AUD_DEF_METHOD_RECORD,
|
||||
RPC_AUD_DEF_METHOD_HOST_PCM,
|
||||
RPC_AUD_DEF_METHOD_MIDI_OUT,
|
||||
RPC_AUD_DEF_METHOD_RECORD_SBC,
|
||||
RPC_AUD_DEF_METHOD_DTMF_RINGER,
|
||||
RPC_AUD_DEF_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum rpc_aud_def_codec_type {
|
||||
RPC_AUD_DEF_CODEC_NONE,
|
||||
RPC_AUD_DEF_CODEC_DTMF,
|
||||
RPC_AUD_DEF_CODEC_MIDI,
|
||||
RPC_AUD_DEF_CODEC_MP3,
|
||||
RPC_AUD_DEF_CODEC_PCM,
|
||||
RPC_AUD_DEF_CODEC_AAC,
|
||||
RPC_AUD_DEF_CODEC_WMA,
|
||||
RPC_AUD_DEF_CODEC_RA,
|
||||
RPC_AUD_DEF_CODEC_ADPCM,
|
||||
RPC_AUD_DEF_CODEC_GAUDIO,
|
||||
RPC_AUD_DEF_CODEC_VOC_EVRC,
|
||||
RPC_AUD_DEF_CODEC_VOC_13K,
|
||||
RPC_AUD_DEF_CODEC_VOC_4GV_NB,
|
||||
RPC_AUD_DEF_CODEC_VOC_AMR,
|
||||
RPC_AUD_DEF_CODEC_VOC_EFR,
|
||||
RPC_AUD_DEF_CODEC_VOC_FR,
|
||||
RPC_AUD_DEF_CODEC_VOC_HR,
|
||||
RPC_AUD_DEF_CODEC_VOC_CDMA,
|
||||
RPC_AUD_DEF_CODEC_VOC_CDMA_WB,
|
||||
RPC_AUD_DEF_CODEC_VOC_UMTS,
|
||||
RPC_AUD_DEF_CODEC_VOC_UMTS_WB,
|
||||
RPC_AUD_DEF_CODEC_SBC,
|
||||
RPC_AUD_DEF_CODEC_VOC_PCM,
|
||||
RPC_AUD_DEF_CODEC_AMR_WB,
|
||||
RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
|
||||
RPC_AUD_DEF_CODEC_AAC_BSAC,
|
||||
RPC_AUD_DEF_CODEC_MAX,
|
||||
RPC_AUD_DEF_CODEC_AMR_NB,
|
||||
RPC_AUD_DEF_CODEC_13K,
|
||||
RPC_AUD_DEF_CODEC_EVRC,
|
||||
RPC_AUD_DEF_CODEC_MAX_002,
|
||||
};
|
||||
|
||||
enum rpc_snd_method_type {
|
||||
RPC_SND_METHOD_VOICE = 0,
|
||||
RPC_SND_METHOD_KEY_BEEP,
|
||||
RPC_SND_METHOD_MESSAGE,
|
||||
RPC_SND_METHOD_RING,
|
||||
RPC_SND_METHOD_MIDI,
|
||||
RPC_SND_METHOD_AUX,
|
||||
RPC_SND_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum rpc_voc_codec_type {
|
||||
RPC_VOC_CODEC_DEFAULT,
|
||||
RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
|
||||
RPC_VOC_CODEC_ON_CHIP_1,
|
||||
RPC_VOC_CODEC_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_ON_CHIP_AUX,
|
||||
RPC_VOC_CODEC_BT_OFF_BOARD,
|
||||
RPC_VOC_CODEC_BT_A2DP,
|
||||
RPC_VOC_CODEC_OFF_BOARD,
|
||||
RPC_VOC_CODEC_SDAC,
|
||||
RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
|
||||
RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
|
||||
RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
|
||||
RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
|
||||
RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
|
||||
RPC_VOC_CODEC_TTY_ON_CHIP_1,
|
||||
RPC_VOC_CODEC_TTY_OFF_BOARD,
|
||||
RPC_VOC_CODEC_TTY_VCO,
|
||||
RPC_VOC_CODEC_TTY_HCO,
|
||||
RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
|
||||
RPC_VOC_CODEC_MAX,
|
||||
RPC_VOC_CODEC_NONE,
|
||||
};
|
||||
|
||||
enum rpc_audmgr_status_type {
|
||||
RPC_AUDMGR_STATUS_READY,
|
||||
RPC_AUDMGR_STATUS_CODEC_CONFIG,
|
||||
RPC_AUDMGR_STATUS_PENDING,
|
||||
RPC_AUDMGR_STATUS_SUSPEND,
|
||||
RPC_AUDMGR_STATUS_FAILURE,
|
||||
RPC_AUDMGR_STATUS_VOLUME_CHANGE,
|
||||
RPC_AUDMGR_STATUS_DISABLED,
|
||||
RPC_AUDMGR_STATUS_ERROR,
|
||||
};
|
||||
|
||||
struct rpc_audmgr_enable_client_args {
|
||||
uint32_t set_to_one;
|
||||
uint32_t tx_sample_rate;
|
||||
uint32_t rx_sample_rate;
|
||||
uint32_t def_method;
|
||||
uint32_t codec_type;
|
||||
uint32_t snd_method;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
#define AUDMGR_ENABLE_CLIENT 2
|
||||
#define AUDMGR_DISABLE_CLIENT 3
|
||||
#define AUDMGR_SUSPEND_EVENT_RSP 4
|
||||
#define AUDMGR_REGISTER_OPERATION_LISTENER 5
|
||||
#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6
|
||||
#define AUDMGR_REGISTER_CODEC_LISTENER 7
|
||||
#define AUDMGR_GET_RX_SAMPLE_RATE 8
|
||||
#define AUDMGR_GET_TX_SAMPLE_RATE 9
|
||||
#define AUDMGR_SET_DEVICE_MODE 10
|
||||
|
||||
#define AUDMGR_PROG 0x30000013
|
||||
#define AUDMGR_VERS MSM_RPC_VERS(1,0)
|
||||
|
||||
struct rpc_audmgr_cb_func_ptr {
|
||||
uint32_t cb_id;
|
||||
uint32_t status; /* Audmgr status */
|
||||
uint32_t set_to_one; /* Pointer status (1 = valid, 0 = invalid) */
|
||||
uint32_t disc;
|
||||
/* disc = AUDMGR_STATUS_READY => data=handle
|
||||
disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle
|
||||
disc = AUDMGR_STATUS_DISABLED => data =status_disabled
|
||||
disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */
|
||||
union {
|
||||
uint32_t handle;
|
||||
uint32_t volume;
|
||||
uint32_t status_disabled;
|
||||
uint32_t volume_change;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define AUDMGR_CB_FUNC_PTR 1
|
||||
#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2
|
||||
#define AUDMGR_CODEC_LSTR_FUNC_PTR 3
|
||||
|
||||
#define AUDMGR_CB_PROG 0x31000013
|
||||
#define AUDMGR_CB_VERS 0xf8e3e2d9
|
||||
|
||||
struct audmgr {
|
||||
wait_queue_head_t wait;
|
||||
uint32_t handle;
|
||||
struct msm_rpc_endpoint *ept;
|
||||
struct task_struct *task;
|
||||
int state;
|
||||
};
|
||||
|
||||
struct audmgr_config {
|
||||
uint32_t tx_rate;
|
||||
uint32_t rx_rate;
|
||||
uint32_t def_method;
|
||||
uint32_t codec;
|
||||
uint32_t snd_method;
|
||||
};
|
||||
|
||||
int audmgr_open(struct audmgr *am);
|
||||
int audmgr_close(struct audmgr *am);
|
||||
int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
|
||||
int audmgr_disable(struct audmgr *am);
|
||||
|
||||
typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
|
||||
|
||||
int audpp_enable(int id, audpp_event_func func, void *private);
|
||||
void audpp_disable(int id, void *private);
|
||||
|
||||
int audpp_send_queue1(void *cmd, unsigned len);
|
||||
int audpp_send_queue2(void *cmd, unsigned len);
|
||||
int audpp_send_queue3(void *cmd, unsigned len);
|
||||
|
||||
int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
|
||||
int audpp_pause(unsigned id, int pause);
|
||||
int audpp_flush(unsigned id);
|
||||
void audpp_avsync(int id, unsigned rate);
|
||||
unsigned audpp_avsync_sample_count(int id);
|
||||
unsigned audpp_avsync_byte_count(int id);
|
||||
|
||||
#endif
|
|
@ -1,429 +0,0 @@
|
|||
|
||||
/* arch/arm/mach-msm/qdsp5/audpp.c
|
||||
*
|
||||
* common code to deal with the AUDPP dsp task (audio postproc)
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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/module.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
|
||||
#include "audmgr.h"
|
||||
|
||||
#include <mach/qdsp5/qdsp5audppcmdi.h>
|
||||
#include <mach/qdsp5/qdsp5audppmsg.h>
|
||||
|
||||
/* for queue ids - should be relative to module number*/
|
||||
#include "adsp.h"
|
||||
|
||||
#include "evlog.h"
|
||||
|
||||
|
||||
enum {
|
||||
EV_NULL,
|
||||
EV_ENABLE,
|
||||
EV_DISABLE,
|
||||
EV_EVENT,
|
||||
EV_DATA,
|
||||
};
|
||||
|
||||
static const char *dsp_log_strings[] = {
|
||||
"NULL",
|
||||
"ENABLE",
|
||||
"DISABLE",
|
||||
"EVENT",
|
||||
"DATA",
|
||||
};
|
||||
|
||||
DECLARE_LOG(dsp_log, 64, dsp_log_strings);
|
||||
|
||||
static int __init _dsp_log_init(void)
|
||||
{
|
||||
return ev_log_init(&dsp_log);
|
||||
}
|
||||
module_init(_dsp_log_init);
|
||||
#define LOG(id,arg) ev_log_write(&dsp_log, id, arg)
|
||||
|
||||
static DEFINE_MUTEX(audpp_lock);
|
||||
|
||||
#define CH_COUNT 5
|
||||
#define AUDPP_CLNT_MAX_COUNT 6
|
||||
#define AUDPP_AVSYNC_INFO_SIZE 7
|
||||
|
||||
struct audpp_state {
|
||||
struct msm_adsp_module *mod;
|
||||
audpp_event_func func[AUDPP_CLNT_MAX_COUNT];
|
||||
void *private[AUDPP_CLNT_MAX_COUNT];
|
||||
struct mutex *lock;
|
||||
unsigned open_count;
|
||||
unsigned enabled;
|
||||
|
||||
/* which channels are actually enabled */
|
||||
unsigned avsync_mask;
|
||||
|
||||
/* flags, 48 bits sample/bytes counter per channel */
|
||||
uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1];
|
||||
};
|
||||
|
||||
struct audpp_state the_audpp_state = {
|
||||
.lock = &audpp_lock,
|
||||
};
|
||||
|
||||
int audpp_send_queue1(void *cmd, unsigned len)
|
||||
{
|
||||
return msm_adsp_write(the_audpp_state.mod,
|
||||
QDSP_uPAudPPCmd1Queue, cmd, len);
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_send_queue1);
|
||||
|
||||
int audpp_send_queue2(void *cmd, unsigned len)
|
||||
{
|
||||
return msm_adsp_write(the_audpp_state.mod,
|
||||
QDSP_uPAudPPCmd2Queue, cmd, len);
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_send_queue2);
|
||||
|
||||
int audpp_send_queue3(void *cmd, unsigned len)
|
||||
{
|
||||
return msm_adsp_write(the_audpp_state.mod,
|
||||
QDSP_uPAudPPCmd3Queue, cmd, len);
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_send_queue3);
|
||||
|
||||
static int audpp_dsp_config(int enable)
|
||||
{
|
||||
audpp_cmd_cfg cmd;
|
||||
|
||||
cmd.cmd_id = AUDPP_CMD_CFG;
|
||||
cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP;
|
||||
|
||||
return audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static void audpp_broadcast(struct audpp_state *audpp, unsigned id,
|
||||
uint16_t *msg)
|
||||
{
|
||||
unsigned n;
|
||||
for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
|
||||
if (audpp->func[n])
|
||||
audpp->func[n] (audpp->private[n], id, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id,
|
||||
unsigned id, uint16_t *msg)
|
||||
{
|
||||
if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id])
|
||||
audpp->func[clnt_id] (audpp->private[clnt_id], id, msg);
|
||||
}
|
||||
|
||||
static void audpp_dsp_event(void *data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
struct audpp_state *audpp = data;
|
||||
uint16_t msg[8];
|
||||
|
||||
if (id == AUDPP_MSG_AVSYNC_MSG) {
|
||||
getevent(audpp->avsync, sizeof(audpp->avsync));
|
||||
|
||||
/* mask off any channels we're not watching to avoid
|
||||
* cases where we might get one last update after
|
||||
* disabling avsync and end up in an odd state when
|
||||
* we next read...
|
||||
*/
|
||||
audpp->avsync[0] &= audpp->avsync_mask;
|
||||
return;
|
||||
}
|
||||
|
||||
getevent(msg, sizeof(msg));
|
||||
|
||||
LOG(EV_EVENT, (id << 16) | msg[0]);
|
||||
LOG(EV_DATA, (msg[1] << 16) | msg[2]);
|
||||
|
||||
switch (id) {
|
||||
case AUDPP_MSG_STATUS_MSG:{
|
||||
unsigned cid = msg[0];
|
||||
pr_info("audpp: status %d %d %d\n", cid, msg[1],
|
||||
msg[2]);
|
||||
if ((cid < 5) && audpp->func[cid])
|
||||
audpp->func[cid] (audpp->private[cid], id, msg);
|
||||
break;
|
||||
}
|
||||
case AUDPP_MSG_HOST_PCM_INTF_MSG:
|
||||
if (audpp->func[5])
|
||||
audpp->func[5] (audpp->private[5], id, msg);
|
||||
break;
|
||||
case AUDPP_MSG_PCMDMAMISSED:
|
||||
pr_err("audpp: DMA missed obj=%x\n", msg[0]);
|
||||
break;
|
||||
case AUDPP_MSG_CFG_MSG:
|
||||
if (msg[0] == AUDPP_MSG_ENA_ENA) {
|
||||
pr_info("audpp: ENABLE\n");
|
||||
audpp->enabled = 1;
|
||||
audpp_broadcast(audpp, id, msg);
|
||||
} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
|
||||
pr_info("audpp: DISABLE\n");
|
||||
audpp->enabled = 0;
|
||||
audpp_broadcast(audpp, id, msg);
|
||||
} else {
|
||||
pr_err("audpp: invalid config msg %d\n", msg[0]);
|
||||
}
|
||||
break;
|
||||
case AUDPP_MSG_ROUTING_ACK:
|
||||
audpp_broadcast(audpp, id, msg);
|
||||
break;
|
||||
case AUDPP_MSG_FLUSH_ACK:
|
||||
audpp_notify_clnt(audpp, msg[0], id, msg);
|
||||
break;
|
||||
default:
|
||||
pr_info("audpp: unhandled msg id %x\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
static struct msm_adsp_ops adsp_ops = {
|
||||
.event = audpp_dsp_event,
|
||||
};
|
||||
|
||||
static void audpp_fake_event(struct audpp_state *audpp, int id,
|
||||
unsigned event, unsigned arg)
|
||||
{
|
||||
uint16_t msg[1];
|
||||
msg[0] = arg;
|
||||
audpp->func[id] (audpp->private[id], event, msg);
|
||||
}
|
||||
|
||||
int audpp_enable(int id, audpp_event_func func, void *private)
|
||||
{
|
||||
struct audpp_state *audpp = &the_audpp_state;
|
||||
int res = 0;
|
||||
|
||||
if (id < -1 || id > 4)
|
||||
return -EINVAL;
|
||||
|
||||
if (id == -1)
|
||||
id = 5;
|
||||
|
||||
mutex_lock(audpp->lock);
|
||||
if (audpp->func[id]) {
|
||||
res = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
audpp->func[id] = func;
|
||||
audpp->private[id] = private;
|
||||
|
||||
LOG(EV_ENABLE, 1);
|
||||
if (audpp->open_count++ == 0) {
|
||||
pr_info("audpp: enable\n");
|
||||
res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp);
|
||||
if (res < 0) {
|
||||
pr_err("audpp: cannot open AUDPPTASK\n");
|
||||
audpp->open_count = 0;
|
||||
audpp->func[id] = NULL;
|
||||
audpp->private[id] = NULL;
|
||||
goto out;
|
||||
}
|
||||
LOG(EV_ENABLE, 2);
|
||||
msm_adsp_enable(audpp->mod);
|
||||
audpp_dsp_config(1);
|
||||
} else {
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
if (audpp->enabled)
|
||||
audpp_fake_event(audpp, id,
|
||||
AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
res = 0;
|
||||
out:
|
||||
mutex_unlock(audpp->lock);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_enable);
|
||||
|
||||
void audpp_disable(int id, void *private)
|
||||
{
|
||||
struct audpp_state *audpp = &the_audpp_state;
|
||||
unsigned long flags;
|
||||
|
||||
if (id < -1 || id > 4)
|
||||
return;
|
||||
|
||||
if (id == -1)
|
||||
id = 5;
|
||||
|
||||
mutex_lock(audpp->lock);
|
||||
LOG(EV_DISABLE, 1);
|
||||
if (!audpp->func[id])
|
||||
goto out;
|
||||
if (audpp->private[id] != private)
|
||||
goto out;
|
||||
|
||||
local_irq_save(flags);
|
||||
audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS);
|
||||
audpp->func[id] = NULL;
|
||||
audpp->private[id] = NULL;
|
||||
local_irq_restore(flags);
|
||||
|
||||
if (--audpp->open_count == 0) {
|
||||
pr_info("audpp: disable\n");
|
||||
LOG(EV_DISABLE, 2);
|
||||
audpp_dsp_config(0);
|
||||
msm_adsp_disable(audpp->mod);
|
||||
msm_adsp_put(audpp->mod);
|
||||
audpp->mod = NULL;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(audpp->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_disable);
|
||||
|
||||
#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT))
|
||||
|
||||
void audpp_avsync(int id, unsigned rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
audpp_cmd_avsync cmd;
|
||||
|
||||
if (BAD_ID(id))
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
if (rate)
|
||||
the_audpp_state.avsync_mask |= (1 << id);
|
||||
else
|
||||
the_audpp_state.avsync_mask &= (~(1 << id));
|
||||
the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask;
|
||||
local_irq_restore(flags);
|
||||
|
||||
cmd.cmd_id = AUDPP_CMD_AVSYNC;
|
||||
cmd.object_number = id;
|
||||
cmd.interrupt_interval_lsw = rate;
|
||||
cmd.interrupt_interval_msw = rate >> 16;
|
||||
audpp_send_queue1(&cmd, sizeof(cmd));
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_avsync);
|
||||
|
||||
unsigned audpp_avsync_sample_count(int id)
|
||||
{
|
||||
uint16_t *avsync = the_audpp_state.avsync;
|
||||
unsigned val;
|
||||
unsigned long flags;
|
||||
unsigned mask;
|
||||
|
||||
if (BAD_ID(id))
|
||||
return 0;
|
||||
|
||||
mask = 1 << id;
|
||||
id = id * AUDPP_AVSYNC_INFO_SIZE + 2;
|
||||
local_irq_save(flags);
|
||||
if (avsync[0] & mask)
|
||||
val = (avsync[id] << 16) | avsync[id + 1];
|
||||
else
|
||||
val = 0;
|
||||
local_irq_restore(flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_avsync_sample_count);
|
||||
|
||||
unsigned audpp_avsync_byte_count(int id)
|
||||
{
|
||||
uint16_t *avsync = the_audpp_state.avsync;
|
||||
unsigned val;
|
||||
unsigned long flags;
|
||||
unsigned mask;
|
||||
|
||||
if (BAD_ID(id))
|
||||
return 0;
|
||||
|
||||
mask = 1 << id;
|
||||
id = id * AUDPP_AVSYNC_INFO_SIZE + 5;
|
||||
local_irq_save(flags);
|
||||
if (avsync[0] & mask)
|
||||
val = (avsync[id] << 16) | avsync[id + 1];
|
||||
else
|
||||
val = 0;
|
||||
local_irq_restore(flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_avsync_byte_count);
|
||||
|
||||
#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
|
||||
#define AUDPP_CMD_VOLUME_PAN 0
|
||||
|
||||
int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan)
|
||||
{
|
||||
/* cmd, obj_cfg[7], cmd_type, volume, pan */
|
||||
uint16_t cmd[11];
|
||||
|
||||
if (id > 6)
|
||||
return -EINVAL;
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS;
|
||||
cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE;
|
||||
cmd[8] = AUDPP_CMD_VOLUME_PAN;
|
||||
cmd[9] = volume;
|
||||
cmd[10] = pan;
|
||||
|
||||
return audpp_send_queue3(cmd, sizeof(cmd));
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_set_volume_and_pan);
|
||||
|
||||
int audpp_pause(unsigned id, int pause)
|
||||
{
|
||||
/* pause 1 = pause 0 = resume */
|
||||
u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
|
||||
|
||||
if (id >= CH_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
memset(pause_cmd, 0, sizeof(pause_cmd));
|
||||
|
||||
pause_cmd[0] = AUDPP_CMD_DEC_CTRL;
|
||||
if (pause == 1)
|
||||
pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V;
|
||||
else if (pause == 0)
|
||||
pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return audpp_send_queue1(pause_cmd, sizeof(pause_cmd));
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_pause);
|
||||
|
||||
int audpp_flush(unsigned id)
|
||||
{
|
||||
u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
|
||||
|
||||
if (id >= CH_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
memset(flush_cmd, 0, sizeof(flush_cmd));
|
||||
|
||||
flush_cmd[0] = AUDPP_CMD_DEC_CTRL;
|
||||
flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V;
|
||||
|
||||
return audpp_send_queue1(flush_cmd, sizeof(flush_cmd));
|
||||
}
|
||||
EXPORT_SYMBOL(audpp_flush);
|
|
@ -1,134 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/evlog.h
|
||||
*
|
||||
* simple event log debugging facility
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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/hrtimer.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#define EV_LOG_ENTRY_NAME(n) n##_entry
|
||||
|
||||
#define DECLARE_LOG(_name, _size, _str) \
|
||||
static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
|
||||
static struct ev_log _name = { \
|
||||
.name = #_name, \
|
||||
.strings = _str, \
|
||||
.num_strings = ARRAY_SIZE(_str), \
|
||||
.entry = EV_LOG_ENTRY_NAME(_name), \
|
||||
.max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
|
||||
}
|
||||
|
||||
struct ev_entry {
|
||||
ktime_t when;
|
||||
uint32_t id;
|
||||
uint32_t arg;
|
||||
};
|
||||
|
||||
struct ev_log {
|
||||
struct ev_entry *entry;
|
||||
unsigned max;
|
||||
unsigned next;
|
||||
unsigned fault;
|
||||
const char **strings;
|
||||
unsigned num_strings;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static char ev_buf[4096];
|
||||
|
||||
static ssize_t ev_log_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ev_log *log = file->private_data;
|
||||
struct ev_entry *entry;
|
||||
unsigned long flags;
|
||||
int size = 0;
|
||||
unsigned n, id, max;
|
||||
ktime_t now, t;
|
||||
|
||||
max = log->max;
|
||||
now = ktime_get();
|
||||
local_irq_save(flags);
|
||||
n = (log->next - 1) & (max - 1);
|
||||
entry = log->entry;
|
||||
while (n != log->next) {
|
||||
t = ktime_sub(now, entry[n].when);
|
||||
id = entry[n].id;
|
||||
if (id) {
|
||||
const char *str;
|
||||
if (id < log->num_strings)
|
||||
str = log->strings[id];
|
||||
else
|
||||
str = "UNKNOWN";
|
||||
size += scnprintf(ev_buf + size, 4096 - size,
|
||||
"%8d.%03d %08x %s\n",
|
||||
t.tv.sec, t.tv.nsec / 1000000,
|
||||
entry[n].arg, str);
|
||||
}
|
||||
n = (n - 1) & (max - 1);
|
||||
}
|
||||
log->fault = 0;
|
||||
local_irq_restore(flags);
|
||||
return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
|
||||
}
|
||||
|
||||
static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
|
||||
{
|
||||
struct ev_entry *entry;
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
|
||||
if (log->fault) {
|
||||
if (log->fault == 1)
|
||||
goto done;
|
||||
log->fault--;
|
||||
}
|
||||
|
||||
entry = log->entry + log->next;
|
||||
entry->when = ktime_get();
|
||||
entry->id = id;
|
||||
entry->arg = arg;
|
||||
log->next = (log->next + 1) & (log->max - 1);
|
||||
done:
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void ev_log_freeze(struct ev_log *log, unsigned count)
|
||||
{
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
log->fault = count;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static int ev_log_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations ev_log_ops = {
|
||||
.read = ev_log_read,
|
||||
.open = ev_log_open,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int ev_log_init(struct ev_log *log)
|
||||
{
|
||||
debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,280 +0,0 @@
|
|||
/* arch/arm/mach-msm/qdsp5/snd.c
|
||||
*
|
||||
* interface to "snd" service on the baseband cpu
|
||||
*
|
||||
* Copyright (C) 2008 HTC 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/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/msm_audio.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
|
||||
struct snd_ctxt {
|
||||
struct mutex lock;
|
||||
int opened;
|
||||
struct msm_rpc_endpoint *ept;
|
||||
struct msm_snd_endpoints *snd_epts;
|
||||
};
|
||||
|
||||
static struct snd_ctxt the_snd;
|
||||
|
||||
#define RPC_SND_PROG 0x30000002
|
||||
#define RPC_SND_CB_PROG 0x31000002
|
||||
#if CONFIG_MSM_AMSS_VERSION == 6210
|
||||
#define RPC_SND_VERS 0x94756085 /* 2490720389 */
|
||||
#elif (CONFIG_MSM_AMSS_VERSION == 6220) || \
|
||||
(CONFIG_MSM_AMSS_VERSION == 6225)
|
||||
#define RPC_SND_VERS 0xaa2b1a44 /* 2854951492 */
|
||||
#elif CONFIG_MSM_AMSS_VERSION == 6350
|
||||
#define RPC_SND_VERS MSM_RPC_VERS(1,0)
|
||||
#endif
|
||||
|
||||
#define SND_SET_DEVICE_PROC 2
|
||||
#define SND_SET_VOLUME_PROC 3
|
||||
|
||||
struct rpc_snd_set_device_args {
|
||||
uint32_t device;
|
||||
uint32_t ear_mute;
|
||||
uint32_t mic_mute;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
struct rpc_snd_set_volume_args {
|
||||
uint32_t device;
|
||||
uint32_t method;
|
||||
uint32_t volume;
|
||||
|
||||
uint32_t cb_func;
|
||||
uint32_t client_data;
|
||||
};
|
||||
|
||||
struct snd_set_device_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
struct rpc_snd_set_device_args args;
|
||||
};
|
||||
|
||||
struct snd_set_volume_msg {
|
||||
struct rpc_request_hdr hdr;
|
||||
struct rpc_snd_set_volume_args args;
|
||||
};
|
||||
|
||||
struct snd_endpoint *get_snd_endpoints(int *size);
|
||||
|
||||
static inline int check_mute(int mute)
|
||||
{
|
||||
return (mute == SND_MUTE_MUTED ||
|
||||
mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int get_endpoint(struct snd_ctxt *snd, unsigned long arg)
|
||||
{
|
||||
int rc = 0, index;
|
||||
struct msm_snd_endpoint ept;
|
||||
|
||||
if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
|
||||
pr_err("snd_ioctl get endpoint: invalid read pointer.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
index = ept.id;
|
||||
if (index < 0 || index >= snd->snd_epts->num) {
|
||||
pr_err("snd_ioctl get endpoint: invalid index!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ept.id = snd->snd_epts->endpoints[index].id;
|
||||
strncpy(ept.name,
|
||||
snd->snd_epts->endpoints[index].name,
|
||||
sizeof(ept.name));
|
||||
|
||||
if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
|
||||
pr_err("snd_ioctl get endpoint: invalid write pointer.\n");
|
||||
rc = -EFAULT;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct snd_set_device_msg dmsg;
|
||||
struct snd_set_volume_msg vmsg;
|
||||
struct msm_snd_device_config dev;
|
||||
struct msm_snd_volume_config vol;
|
||||
struct snd_ctxt *snd = file->private_data;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
switch (cmd) {
|
||||
case SND_SET_DEVICE:
|
||||
if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
|
||||
pr_err("snd_ioctl set device: invalid pointer.\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
dmsg.args.device = cpu_to_be32(dev.device);
|
||||
dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
|
||||
dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
|
||||
if (check_mute(dev.ear_mute) < 0 ||
|
||||
check_mute(dev.mic_mute) < 0) {
|
||||
pr_err("snd_ioctl set device: invalid mute status.\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
dmsg.args.cb_func = -1;
|
||||
dmsg.args.client_data = 0;
|
||||
|
||||
pr_info("snd_set_device %d %d %d\n", dev.device,
|
||||
dev.ear_mute, dev.mic_mute);
|
||||
|
||||
rc = msm_rpc_call(snd->ept,
|
||||
SND_SET_DEVICE_PROC,
|
||||
&dmsg, sizeof(dmsg), 5 * HZ);
|
||||
break;
|
||||
|
||||
case SND_SET_VOLUME:
|
||||
if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
|
||||
pr_err("snd_ioctl set volume: invalid pointer.\n");
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
vmsg.args.device = cpu_to_be32(vol.device);
|
||||
vmsg.args.method = cpu_to_be32(vol.method);
|
||||
if (vol.method != SND_METHOD_VOICE) {
|
||||
pr_err("snd_ioctl set volume: invalid method.\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
vmsg.args.volume = cpu_to_be32(vol.volume);
|
||||
vmsg.args.cb_func = -1;
|
||||
vmsg.args.client_data = 0;
|
||||
|
||||
pr_info("snd_set_volume %d %d %d\n", vol.device,
|
||||
vol.method, vol.volume);
|
||||
|
||||
rc = msm_rpc_call(snd->ept,
|
||||
SND_SET_VOLUME_PROC,
|
||||
&vmsg, sizeof(vmsg), 5 * HZ);
|
||||
break;
|
||||
|
||||
case SND_GET_NUM_ENDPOINTS:
|
||||
if (copy_to_user((void __user *)arg,
|
||||
&snd->snd_epts->num, sizeof(unsigned))) {
|
||||
pr_err("snd_ioctl get endpoint: invalid pointer.\n");
|
||||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_GET_ENDPOINT:
|
||||
rc = get_endpoint(snd, arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("snd_ioctl unknown command.\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&snd->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int snd_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct snd_ctxt *snd = file->private_data;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
snd->opened = 0;
|
||||
mutex_unlock(&snd->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct snd_ctxt *snd = &the_snd;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&snd->lock);
|
||||
if (snd->opened == 0) {
|
||||
if (snd->ept == NULL) {
|
||||
snd->ept = msm_rpc_connect(RPC_SND_PROG, RPC_SND_VERS,
|
||||
MSM_RPC_UNINTERRUPTIBLE);
|
||||
if (IS_ERR(snd->ept)) {
|
||||
rc = PTR_ERR(snd->ept);
|
||||
snd->ept = NULL;
|
||||
pr_err("snd: failed to connect snd svc\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
file->private_data = snd;
|
||||
snd->opened = 1;
|
||||
} else {
|
||||
pr_err("snd already opened.\n");
|
||||
rc = -EBUSY;
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&snd->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct file_operations snd_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = snd_open,
|
||||
.release = snd_release,
|
||||
.unlocked_ioctl = snd_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
struct miscdevice snd_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "msm_snd",
|
||||
.fops = &snd_fops,
|
||||
};
|
||||
|
||||
static int snd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_ctxt *snd = &the_snd;
|
||||
mutex_init(&snd->lock);
|
||||
snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data;
|
||||
return misc_register(&snd_misc);
|
||||
}
|
||||
|
||||
static struct platform_driver snd_plat_driver = {
|
||||
.probe = snd_probe,
|
||||
.driver = {
|
||||
.name = "msm_snd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init snd_init(void)
|
||||
{
|
||||
return platform_driver_register(&snd_plat_driver);
|
||||
}
|
||||
|
||||
module_init(snd_init);
|
|
@ -1,649 +0,0 @@
|
|||
/*
|
||||
* Support for synaptics touchscreen.
|
||||
*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: Arve Hjønnevåg <arve@android.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* http://www.synaptics.com/sites/default/files/511_000099_01F.pdf
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#endif
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "synaptics_i2c_rmi.h"
|
||||
|
||||
static struct workqueue_struct *synaptics_wq;
|
||||
|
||||
struct synaptics_ts_data {
|
||||
u16 addr;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
int use_irq;
|
||||
struct hrtimer timer;
|
||||
struct work_struct work;
|
||||
u16 max[2];
|
||||
int snap_state[2][2];
|
||||
int snap_down_on[2];
|
||||
int snap_down_off[2];
|
||||
int snap_up_on[2];
|
||||
int snap_up_off[2];
|
||||
int snap_down[2];
|
||||
int snap_up[2];
|
||||
u32 flags;
|
||||
int (*power)(int on);
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int i2c_set(struct synaptics_ts_data *ts, u8 reg, u8 val, char *msg)
|
||||
{
|
||||
int ret = i2c_smbus_write_byte_data(ts->client, reg, val);
|
||||
if (ret < 0)
|
||||
pr_err("i2c_smbus_write_byte_data failed (%s)\n", msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_read(struct synaptics_ts_data *ts, u8 reg, char *msg)
|
||||
{
|
||||
int ret = i2c_smbus_read_byte_data(ts->client, reg);
|
||||
if (ret < 0)
|
||||
pr_err("i2c_smbus_read_byte_data failed (%s)\n", msg);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void synaptics_ts_early_suspend(struct early_suspend *h);
|
||||
static void synaptics_ts_late_resume(struct early_suspend *h);
|
||||
#endif
|
||||
|
||||
static int synaptics_init_panel(struct synaptics_ts_data *ts)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_set(ts, 0xff, 0x10, "set page select");
|
||||
if (ret == 0)
|
||||
ret = i2c_set(ts, 0x41, 0x04, "set No Clip Z");
|
||||
|
||||
ret = i2c_set(ts, 0xff, 0x04, "fallback page select");
|
||||
ret = i2c_set(ts, 0xf0, 0x81, "select 80 reports per second");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void decode_report(struct synaptics_ts_data *ts, u8 *buf)
|
||||
{
|
||||
/*
|
||||
* This sensor sends two 6-byte absolute finger reports, an optional
|
||||
* 2-byte relative report followed by a status byte. This function
|
||||
* reads the two finger reports and transforms the coordinates
|
||||
* according the platform data so they can be aligned with the lcd
|
||||
* behind the touchscreen. Typically we flip the y-axis since the
|
||||
* sensor uses the bottom left corner as the origin, but if the sensor
|
||||
* is mounted upside down the platform data will request that the
|
||||
* x-axis should be flipped instead. The snap to inactive edge border
|
||||
* are used to allow tapping the edges of the screen on the G1. The
|
||||
* active area of the touchscreen is smaller than the lcd. When the
|
||||
* finger gets close the edge of the screen we snap it to the
|
||||
* edge. This allows ui elements at the edge of the screen to be hit,
|
||||
* and it prevents hitting ui elements that are not at the edge of the
|
||||
* screen when the finger is touching the edge.
|
||||
*/
|
||||
int pos[2][2];
|
||||
int f, a;
|
||||
int base = 2;
|
||||
int z = buf[1];
|
||||
int finger = buf[0] & 7;
|
||||
|
||||
for (f = 0; f < 2; f++) {
|
||||
u32 flip_flag = SYNAPTICS_FLIP_X;
|
||||
for (a = 0; a < 2; a++) {
|
||||
int p = buf[base + 1];
|
||||
p |= (u16)(buf[base] & 0x1f) << 8;
|
||||
if (ts->flags & flip_flag)
|
||||
p = ts->max[a] - p;
|
||||
if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
|
||||
if (ts->snap_state[f][a]) {
|
||||
if (p <= ts->snap_down_off[a])
|
||||
p = ts->snap_down[a];
|
||||
else if (p >= ts->snap_up_off[a])
|
||||
p = ts->snap_up[a];
|
||||
else
|
||||
ts->snap_state[f][a] = 0;
|
||||
} else {
|
||||
if (p <= ts->snap_down_on[a]) {
|
||||
p = ts->snap_down[a];
|
||||
ts->snap_state[f][a] = 1;
|
||||
} else if (p >= ts->snap_up_on[a]) {
|
||||
p = ts->snap_up[a];
|
||||
ts->snap_state[f][a] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos[f][a] = p;
|
||||
base += 2;
|
||||
flip_flag <<= 1;
|
||||
}
|
||||
base += 2;
|
||||
if (ts->flags & SYNAPTICS_SWAP_XY)
|
||||
swap(pos[f][0], pos[f][1]);
|
||||
}
|
||||
if (z) {
|
||||
input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
|
||||
input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
|
||||
}
|
||||
input_report_abs(ts->input_dev, ABS_PRESSURE, z);
|
||||
input_report_key(ts->input_dev, BTN_TOUCH, finger);
|
||||
input_sync(ts->input_dev);
|
||||
}
|
||||
|
||||
static void synaptics_ts_work_func(struct work_struct *work)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int bad_data = 0;
|
||||
struct i2c_msg msg[2];
|
||||
u8 start_reg = 0;
|
||||
u8 buf[15];
|
||||
struct synaptics_ts_data *ts =
|
||||
container_of(work, struct synaptics_ts_data, work);
|
||||
|
||||
msg[0].addr = ts->client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = &start_reg;
|
||||
msg[1].addr = ts->client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
msg[1].len = sizeof(buf);
|
||||
msg[1].buf = buf;
|
||||
|
||||
for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
|
||||
ret = i2c_transfer(ts->client->adapter, msg, 2);
|
||||
if (ret < 0) {
|
||||
pr_err("ts_work: i2c_transfer failed\n");
|
||||
bad_data = 1;
|
||||
continue;
|
||||
}
|
||||
if ((buf[14] & 0xc0) != 0x40) {
|
||||
pr_warning("synaptics_ts_work_func:"
|
||||
" bad read %x %x %x %x %x %x %x %x %x"
|
||||
" %x %x %x %x %x %x, ret %d\n",
|
||||
buf[0], buf[1], buf[2], buf[3],
|
||||
buf[4], buf[5], buf[6], buf[7],
|
||||
buf[8], buf[9], buf[10], buf[11],
|
||||
buf[12], buf[13], buf[14], ret);
|
||||
if (bad_data)
|
||||
synaptics_init_panel(ts);
|
||||
bad_data = 1;
|
||||
continue;
|
||||
}
|
||||
bad_data = 0;
|
||||
if ((buf[14] & 1) == 0)
|
||||
break;
|
||||
|
||||
decode_report(ts, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
struct synaptics_ts_data *ts =
|
||||
container_of(timer, struct synaptics_ts_data, timer);
|
||||
|
||||
queue_work(synaptics_wq, &ts->work);
|
||||
|
||||
hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct synaptics_ts_data *ts = dev_id;
|
||||
|
||||
synaptics_ts_work_func(&ts->work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int detect(struct synaptics_ts_data *ts, u32 *panel_version)
|
||||
{
|
||||
int ret;
|
||||
int retry = 10;
|
||||
|
||||
ret = i2c_set(ts, 0xf4, 0x01, "reset device");
|
||||
|
||||
while (retry-- > 0) {
|
||||
ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
|
||||
if (ret >= 0)
|
||||
break;
|
||||
msleep(100);
|
||||
}
|
||||
if (ret < 0) {
|
||||
pr_err("i2c_smbus_read_byte_data failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*panel_version = ret << 8;
|
||||
ret = i2c_read(ts, 0xe5, "product minor");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*panel_version |= ret;
|
||||
|
||||
ret = i2c_read(ts, 0xe3, "property");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pr_info("synaptics: version %x, product property %x\n",
|
||||
*panel_version, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void compute_areas(struct synaptics_ts_data *ts,
|
||||
struct synaptics_i2c_rmi_platform_data *pdata,
|
||||
u16 max_x, u16 max_y)
|
||||
{
|
||||
int inactive_area_left;
|
||||
int inactive_area_right;
|
||||
int inactive_area_top;
|
||||
int inactive_area_bottom;
|
||||
int snap_left_on;
|
||||
int snap_left_off;
|
||||
int snap_right_on;
|
||||
int snap_right_off;
|
||||
int snap_top_on;
|
||||
int snap_top_off;
|
||||
int snap_bottom_on;
|
||||
int snap_bottom_off;
|
||||
int fuzz_x;
|
||||
int fuzz_y;
|
||||
int fuzz_p;
|
||||
int fuzz_w;
|
||||
int swapped = !!(ts->flags & SYNAPTICS_SWAP_XY);
|
||||
|
||||
inactive_area_left = pdata->inactive_left;
|
||||
inactive_area_right = pdata->inactive_right;
|
||||
inactive_area_top = pdata->inactive_top;
|
||||
inactive_area_bottom = pdata->inactive_bottom;
|
||||
snap_left_on = pdata->snap_left_on;
|
||||
snap_left_off = pdata->snap_left_off;
|
||||
snap_right_on = pdata->snap_right_on;
|
||||
snap_right_off = pdata->snap_right_off;
|
||||
snap_top_on = pdata->snap_top_on;
|
||||
snap_top_off = pdata->snap_top_off;
|
||||
snap_bottom_on = pdata->snap_bottom_on;
|
||||
snap_bottom_off = pdata->snap_bottom_off;
|
||||
fuzz_x = pdata->fuzz_x;
|
||||
fuzz_y = pdata->fuzz_y;
|
||||
fuzz_p = pdata->fuzz_p;
|
||||
fuzz_w = pdata->fuzz_w;
|
||||
|
||||
inactive_area_left = inactive_area_left * max_x / 0x10000;
|
||||
inactive_area_right = inactive_area_right * max_x / 0x10000;
|
||||
inactive_area_top = inactive_area_top * max_y / 0x10000;
|
||||
inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
|
||||
snap_left_on = snap_left_on * max_x / 0x10000;
|
||||
snap_left_off = snap_left_off * max_x / 0x10000;
|
||||
snap_right_on = snap_right_on * max_x / 0x10000;
|
||||
snap_right_off = snap_right_off * max_x / 0x10000;
|
||||
snap_top_on = snap_top_on * max_y / 0x10000;
|
||||
snap_top_off = snap_top_off * max_y / 0x10000;
|
||||
snap_bottom_on = snap_bottom_on * max_y / 0x10000;
|
||||
snap_bottom_off = snap_bottom_off * max_y / 0x10000;
|
||||
fuzz_x = fuzz_x * max_x / 0x10000;
|
||||
fuzz_y = fuzz_y * max_y / 0x10000;
|
||||
|
||||
|
||||
ts->snap_down[swapped] = -inactive_area_left;
|
||||
ts->snap_up[swapped] = max_x + inactive_area_right;
|
||||
ts->snap_down[!swapped] = -inactive_area_top;
|
||||
ts->snap_up[!swapped] = max_y + inactive_area_bottom;
|
||||
ts->snap_down_on[swapped] = snap_left_on;
|
||||
ts->snap_down_off[swapped] = snap_left_off;
|
||||
ts->snap_up_on[swapped] = max_x - snap_right_on;
|
||||
ts->snap_up_off[swapped] = max_x - snap_right_off;
|
||||
ts->snap_down_on[!swapped] = snap_top_on;
|
||||
ts->snap_down_off[!swapped] = snap_top_off;
|
||||
ts->snap_up_on[!swapped] = max_y - snap_bottom_on;
|
||||
ts->snap_up_off[!swapped] = max_y - snap_bottom_off;
|
||||
pr_info("synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
|
||||
pr_info("synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
|
||||
inactive_area_left, inactive_area_right,
|
||||
inactive_area_top, inactive_area_bottom);
|
||||
pr_info("synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
|
||||
snap_left_on, snap_left_off, snap_right_on, snap_right_off,
|
||||
snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
|
||||
|
||||
input_set_abs_params(ts->input_dev, ABS_X,
|
||||
-inactive_area_left, max_x + inactive_area_right,
|
||||
fuzz_x, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_Y,
|
||||
-inactive_area_top, max_y + inactive_area_bottom,
|
||||
fuzz_y, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
|
||||
}
|
||||
|
||||
static struct synaptics_i2c_rmi_platform_data fake_pdata;
|
||||
|
||||
static int __devinit synaptics_ts_probe(
|
||||
struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct synaptics_ts_data *ts;
|
||||
u8 buf0[4];
|
||||
u8 buf1[8];
|
||||
struct i2c_msg msg[2];
|
||||
int ret = 0;
|
||||
struct synaptics_i2c_rmi_platform_data *pdata;
|
||||
u32 panel_version = 0;
|
||||
u16 max_x, max_y;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
pr_err("synaptics_ts_probe: need I2C_FUNC_I2C\n");
|
||||
ret = -ENODEV;
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
|
||||
ret = -ENODEV;
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
|
||||
ret = -ENODEV;
|
||||
goto err_check_functionality_failed;
|
||||
}
|
||||
|
||||
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
|
||||
if (ts == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_data_failed;
|
||||
}
|
||||
INIT_WORK(&ts->work, synaptics_ts_work_func);
|
||||
ts->client = client;
|
||||
i2c_set_clientdata(client, ts);
|
||||
pdata = client->dev.platform_data;
|
||||
if (pdata)
|
||||
ts->power = pdata->power;
|
||||
else
|
||||
pdata = &fake_pdata;
|
||||
|
||||
if (ts->power) {
|
||||
ret = ts->power(1);
|
||||
if (ret < 0) {
|
||||
pr_err("synaptics_ts_probe power on failed\n");
|
||||
goto err_power_failed;
|
||||
}
|
||||
}
|
||||
|
||||
ret = detect(ts, &panel_version);
|
||||
if (ret)
|
||||
goto err_detect_failed;
|
||||
|
||||
while (pdata->version > panel_version)
|
||||
pdata++;
|
||||
ts->flags = pdata->flags;
|
||||
|
||||
ret = i2c_read(ts, 0xf0, "device control");
|
||||
if (ret < 0)
|
||||
goto err_detect_failed;
|
||||
pr_info("synaptics: device control %x\n", ret);
|
||||
|
||||
ret = i2c_read(ts, 0xf1, "interrupt enable");
|
||||
if (ret < 0)
|
||||
goto err_detect_failed;
|
||||
pr_info("synaptics_ts_probe: interrupt enable %x\n", ret);
|
||||
|
||||
ret = i2c_set(ts, 0xf1, 0, "disable interrupt");
|
||||
if (ret < 0)
|
||||
goto err_detect_failed;
|
||||
|
||||
msg[0].addr = ts->client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = buf0;
|
||||
buf0[0] = 0xe0;
|
||||
msg[1].addr = ts->client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
msg[1].len = 8;
|
||||
msg[1].buf = buf1;
|
||||
ret = i2c_transfer(ts->client->adapter, msg, 2);
|
||||
if (ret < 0) {
|
||||
pr_err("i2c_transfer failed\n");
|
||||
goto err_detect_failed;
|
||||
}
|
||||
pr_info("synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
|
||||
buf1[0], buf1[1], buf1[2], buf1[3],
|
||||
buf1[4], buf1[5], buf1[6], buf1[7]);
|
||||
|
||||
ret = i2c_set(ts, 0xff, 0x10, "page select = 0x10");
|
||||
if (ret < 0)
|
||||
goto err_detect_failed;
|
||||
|
||||
ret = i2c_smbus_read_word_data(ts->client, 0x04);
|
||||
if (ret < 0) {
|
||||
pr_err("i2c_smbus_read_word_data failed\n");
|
||||
goto err_detect_failed;
|
||||
}
|
||||
ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
|
||||
ret = i2c_smbus_read_word_data(ts->client, 0x06);
|
||||
if (ret < 0) {
|
||||
pr_err("i2c_smbus_read_word_data failed\n");
|
||||
goto err_detect_failed;
|
||||
}
|
||||
ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
|
||||
if (ts->flags & SYNAPTICS_SWAP_XY)
|
||||
swap(max_x, max_y);
|
||||
|
||||
/* will also switch back to page 0x04 */
|
||||
ret = synaptics_init_panel(ts);
|
||||
if (ret < 0) {
|
||||
pr_err("synaptics_init_panel failed\n");
|
||||
goto err_detect_failed;
|
||||
}
|
||||
|
||||
ts->input_dev = input_allocate_device();
|
||||
if (ts->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("synaptics: Failed to allocate input device\n");
|
||||
goto err_input_dev_alloc_failed;
|
||||
}
|
||||
ts->input_dev->name = "synaptics-rmi-touchscreen";
|
||||
ts->input_dev->phys = "msm/input0";
|
||||
ts->input_dev->id.bustype = BUS_I2C;
|
||||
|
||||
__set_bit(EV_SYN, ts->input_dev->evbit);
|
||||
__set_bit(EV_KEY, ts->input_dev->evbit);
|
||||
__set_bit(BTN_TOUCH, ts->input_dev->keybit);
|
||||
__set_bit(EV_ABS, ts->input_dev->evbit);
|
||||
|
||||
compute_areas(ts, pdata, max_x, max_y);
|
||||
|
||||
|
||||
ret = input_register_device(ts->input_dev);
|
||||
if (ret) {
|
||||
pr_err("synaptics: Unable to register %s input device\n",
|
||||
ts->input_dev->name);
|
||||
goto err_input_register_device_failed;
|
||||
}
|
||||
if (client->irq) {
|
||||
ret = request_threaded_irq(client->irq, NULL,
|
||||
synaptics_ts_irq_handler,
|
||||
IRQF_TRIGGER_LOW|IRQF_ONESHOT,
|
||||
client->name, ts);
|
||||
if (ret == 0) {
|
||||
ret = i2c_set(ts, 0xf1, 0x01, "enable abs int");
|
||||
if (ret)
|
||||
free_irq(client->irq, ts);
|
||||
}
|
||||
if (ret == 0)
|
||||
ts->use_irq = 1;
|
||||
else
|
||||
dev_err(&client->dev, "request_irq failed\n");
|
||||
}
|
||||
if (!ts->use_irq) {
|
||||
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
ts->timer.function = synaptics_ts_timer_func;
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
}
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
||||
ts->early_suspend.suspend = synaptics_ts_early_suspend;
|
||||
ts->early_suspend.resume = synaptics_ts_late_resume;
|
||||
register_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
|
||||
pr_info("synaptics: Start touchscreen %s in %s mode\n",
|
||||
ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
|
||||
|
||||
return 0;
|
||||
|
||||
err_input_register_device_failed:
|
||||
input_free_device(ts->input_dev);
|
||||
|
||||
err_input_dev_alloc_failed:
|
||||
err_detect_failed:
|
||||
err_power_failed:
|
||||
kfree(ts);
|
||||
err_alloc_data_failed:
|
||||
err_check_functionality_failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int synaptics_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
if (ts->use_irq)
|
||||
free_irq(client->irq, ts);
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
input_unregister_device(ts->input_dev);
|
||||
kfree(ts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
int ret;
|
||||
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
if (ts->use_irq)
|
||||
disable_irq(client->irq);
|
||||
else
|
||||
hrtimer_cancel(&ts->timer);
|
||||
ret = cancel_work_sync(&ts->work);
|
||||
if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
|
||||
enable_irq(client->irq);
|
||||
i2c_set(ts, 0xf1, 0, "disable interrupt");
|
||||
i2c_set(ts, 0xf0, 0x86, "deep sleep");
|
||||
|
||||
if (ts->power) {
|
||||
ret = ts->power(0);
|
||||
if (ret < 0)
|
||||
pr_err("synaptics_ts_suspend power off failed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int synaptics_ts_resume(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
|
||||
|
||||
if (ts->power) {
|
||||
ret = ts->power(1);
|
||||
if (ret < 0)
|
||||
pr_err("synaptics_ts_resume power on failed\n");
|
||||
}
|
||||
|
||||
synaptics_init_panel(ts);
|
||||
|
||||
if (ts->use_irq) {
|
||||
enable_irq(client->irq);
|
||||
i2c_set(ts, 0xf1, 0x01, "enable abs int");
|
||||
} else
|
||||
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void synaptics_ts_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct synaptics_ts_data *ts;
|
||||
ts = container_of(h, struct synaptics_ts_data, early_suspend);
|
||||
synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
|
||||
}
|
||||
|
||||
static void synaptics_ts_late_resume(struct early_suspend *h)
|
||||
{
|
||||
struct synaptics_ts_data *ts;
|
||||
ts = container_of(h, struct synaptics_ts_data, early_suspend);
|
||||
synaptics_ts_resume(ts->client);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#define synaptics_ts_suspend NULL
|
||||
#define synaptics_ts_resume NULL
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static const struct i2c_device_id synaptics_ts_id[] = {
|
||||
{ SYNAPTICS_I2C_RMI_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver synaptics_ts_driver = {
|
||||
.probe = synaptics_ts_probe,
|
||||
.remove = synaptics_ts_remove,
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
.suspend = synaptics_ts_suspend,
|
||||
.resume = synaptics_ts_resume,
|
||||
#endif
|
||||
.id_table = synaptics_ts_id,
|
||||
.driver = {
|
||||
.name = SYNAPTICS_I2C_RMI_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit synaptics_ts_init(void)
|
||||
{
|
||||
synaptics_wq = create_singlethread_workqueue("synaptics_wq");
|
||||
if (!synaptics_wq)
|
||||
return -ENOMEM;
|
||||
return i2c_add_driver(&synaptics_ts_driver);
|
||||
}
|
||||
|
||||
static void __exit synaptics_ts_exit(void)
|
||||
{
|
||||
i2c_del_driver(&synaptics_ts_driver);
|
||||
if (synaptics_wq)
|
||||
destroy_workqueue(synaptics_wq);
|
||||
}
|
||||
|
||||
module_init(synaptics_ts_init);
|
||||
module_exit(synaptics_ts_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Arve Hjønnevåg <arve@android.com>");
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* include/linux/synaptics_i2c_rmi.h - platform data structure for f75375s sensor
|
||||
*
|
||||
* Copyright (C) 2008 Google, 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 _LINUX_SYNAPTICS_I2C_RMI_H
|
||||
#define _LINUX_SYNAPTICS_I2C_RMI_H
|
||||
|
||||
#define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts"
|
||||
|
||||
enum {
|
||||
SYNAPTICS_FLIP_X = 1UL << 0,
|
||||
SYNAPTICS_FLIP_Y = 1UL << 1,
|
||||
SYNAPTICS_SWAP_XY = 1UL << 2,
|
||||
SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3,
|
||||
};
|
||||
|
||||
struct synaptics_i2c_rmi_platform_data {
|
||||
uint32_t version; /* Use this entry for panels with */
|
||||
/* (major << 8 | minor) version or above. */
|
||||
/* If non-zero another array entry follows */
|
||||
int (*power)(int on); /* Only valid in first array entry */
|
||||
uint32_t flags;
|
||||
uint32_t inactive_left; /* 0x10000 = screen width */
|
||||
uint32_t inactive_right; /* 0x10000 = screen width */
|
||||
uint32_t inactive_top; /* 0x10000 = screen height */
|
||||
uint32_t inactive_bottom; /* 0x10000 = screen height */
|
||||
uint32_t snap_left_on; /* 0x10000 = screen width */
|
||||
uint32_t snap_left_off; /* 0x10000 = screen width */
|
||||
uint32_t snap_right_on; /* 0x10000 = screen width */
|
||||
uint32_t snap_right_off; /* 0x10000 = screen width */
|
||||
uint32_t snap_top_on; /* 0x10000 = screen height */
|
||||
uint32_t snap_top_off; /* 0x10000 = screen height */
|
||||
uint32_t snap_bottom_on; /* 0x10000 = screen height */
|
||||
uint32_t snap_bottom_off; /* 0x10000 = screen height */
|
||||
uint32_t fuzz_x; /* 0x10000 = screen width */
|
||||
uint32_t fuzz_y; /* 0x10000 = screen height */
|
||||
int fuzz_p;
|
||||
int fuzz_w;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_SYNAPTICS_I2C_RMI_H */
|
Loading…
Reference in New Issue