Staging: dream: remove dream driver and arch from tree
This code is stalled, with no one working on it anymore, and the main msm code is now going through the proper channels to get merged correctly. So remove it as it contains a number of kernel information leaks and it is doubtful if it even still builds anymore. Acked-by: Pavel Machek <pavel@ucw.cz> Acked-by: Bryan Huntsman <bryanh@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
1e431a9d64
commit
3414df8ca3
|
@ -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 a new issue