summaryrefslogtreecommitdiff
path: root/drivers/media/video/wmt_v4l2/sensors/nmi5625
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/media/video/wmt_v4l2/sensors/nmi5625
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/media/video/wmt_v4l2/sensors/nmi5625')
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/Makefile4
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.c158
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.h219
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_custom_wmt.h70
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.c484
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.h14
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.c435
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.h42
8 files changed, 1426 insertions, 0 deletions
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/Makefile b/drivers/media/video/wmt_v4l2/sensors/nmi5625/Makefile
new file mode 100755
index 00000000..f77cbbad
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/Makefile
@@ -0,0 +1,4 @@
+# obj-y += nmidrv_i2c.o
+nmidrv-objs += nmidrv_kernel.o
+obj-y += nmidrv.o
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.c b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.c
new file mode 100755
index 00000000..646d3cfb
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.c
@@ -0,0 +1,158 @@
+
+#include "../cmos-subdev.h"
+#include "../../wmt-vid.h"
+#include "nmidrv_cmos.h"
+
+#define sensor_write_array(sd, arr, sz)
+#define sensor_read(sd, reg)
+#define sensor_write(sd, reg, val)
+
+struct cmos_win_size {
+ char *name;
+ int width;
+ int height;
+ uint8_t *regs;
+ size_t size;
+};
+
+#define CMOS_WIN_SIZE(n, w, h, r) \
+ {.name = n, .width = w , .height = h, .regs = r, .size = ARRAY_SIZE(r) }
+
+#define FILP_REG_INIT_VALUE 0x10
+#define DELAY_INTERVAL 50
+#define RETRY_TIMES 10
+
+static const struct cmos_win_size cmos_supported_win_sizes[] = {
+ CMOS_WIN_SIZE("QVGA", 320, 240, nmi_320_240_regs),
+// CMOS_WIN_SIZE("VGA", 640, 480, nmi_640_480_regs),
+};
+
+static const struct cmos_win_size *cmos_select_win(u32 *width, u32 *height)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cmos_supported_win_sizes); i++) {
+ if (cmos_supported_win_sizes[i].width == *width &&
+ cmos_supported_win_sizes[i].height == *height) {
+ *width = cmos_supported_win_sizes[i].width;
+ *height = cmos_supported_win_sizes[i].height;
+ return &cmos_supported_win_sizes[i];
+ }
+ }
+ return NULL;
+}
+
+static int sensor_queryctrl(struct cmos_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ return -EINVAL;
+}
+
+static int sensor_s_ctrl(struct cmos_subdev *sd, struct v4l2_control *ctrl)
+{
+ return -EINVAL;
+}
+
+static int sensor_g_mbus_fmt(struct cmos_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ return -EINVAL;
+}
+
+static int sensor_s_mbus_fmt(struct cmos_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ const struct cmos_win_size *win;
+
+ win = cmos_select_win(&mf->width, &mf->height);
+ if (!win) {
+ pr_err("%s, s_mbus_fmt failed, width %d, height %d\n",
+ sd->name, mf->width, mf->height);
+ return -EINVAL;
+ }
+
+ sensor_write_array(sd, win->regs, win->size);
+ return 0;
+}
+
+static int sensor_try_mbus_fmt(struct cmos_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ return 0;
+}
+
+static int sensor_enum_framesizes(struct cmos_subdev *sd,
+ struct v4l2_frmsizeenum *fsize)
+{
+ int i;
+ int num_valid = -1;
+ __u32 index = fsize->index;
+
+ for (i = 0; i < ARRAY_SIZE(cmos_supported_win_sizes); i++) {
+ const struct cmos_win_size *win = &cmos_supported_win_sizes[index];
+ if (index == ++num_valid) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = win->width;
+ fsize->discrete.height = win->height;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int sensor_identify(struct cmos_subdev *sd)
+{
+ extern int nmi_running(void);
+ return nmi_running() ? 0 : -EINVAL;
+}
+
+static int sensor_init(struct cmos_subdev *sd)
+{
+ if (sensor_identify(sd)) {
+ return -1;
+ }
+
+ sensor_write_array(sd, nmi_default_regs_init,
+ ARRAY_SIZE(nmi_default_regs_init));
+ return 0;
+}
+
+static int sensor_exit(struct cmos_subdev *sd)
+{
+ sensor_write_array(sd, nmi_default_regs_exit,
+ ARRAY_SIZE(nmi_default_regs_exit));
+ return 0;
+}
+
+static struct cmos_subdev_ops nmi_ops = {
+ .identify = sensor_identify,
+ .init = sensor_init,
+ .exit = sensor_exit,
+ .queryctrl = sensor_queryctrl,
+ .s_ctrl = sensor_s_ctrl,
+ .s_mbus_fmt = sensor_s_mbus_fmt,
+ .g_mbus_fmt = sensor_g_mbus_fmt,
+ .try_mbus_fmt = sensor_try_mbus_fmt,
+ .enum_framesizes = sensor_enum_framesizes,
+};
+
+struct cmos_subdev nmi = {
+ .name = "nmi",
+ .i2c_addr = 0xff,
+ .id = 0xff,
+ .max_width = 320,
+ .max_height = 240,
+ .ops = &nmi_ops,
+};
+
+#if 0
+int nmi_cmos_init(void)
+{
+ return cmos_register_sudbdev(&nmi);
+}
+
+void nmi_cmos_exit(void)
+{
+ return cmos_unregister_subdev(&nmi);
+}
+#endif
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.h b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.h
new file mode 100755
index 00000000..4b24659c
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_cmos.h
@@ -0,0 +1,219 @@
+
+#ifndef __NMI_H_
+#define __NMI_H_
+
+// Scene Mode
+uint8_t nmi_scene_mode_auto[] = {
+};
+
+uint8_t nmi_scene_mode_night[] = {
+};
+
+
+// White Balance
+uint8_t nmi_wb_auto [] = {
+};
+
+uint8_t nmi_wb_incandescent [] = {
+};
+
+uint8_t nmi_wb_fluorescent [] = {
+};
+
+uint8_t nmi_wb_daylight [] = {
+};
+
+uint8_t nmi_wb_cloudy [] = {
+};
+
+uint8_t nmi_wb_tungsten [] = {
+};
+
+
+// Exposure
+uint8_t nmi_exposure_neg6[] = {
+};
+
+uint8_t nmi_exposure_neg3[] = {
+};
+
+uint8_t nmi_exposure_zero[] = {
+};
+
+uint8_t nmi_exposure_pos3[] = {
+};
+
+uint8_t nmi_exposure_pos6[] = {
+};
+
+
+// Color Effect
+uint8_t nmi_colorfx_none[] = {
+};
+
+uint8_t nmi_colorfx_bw[] = {
+};
+
+uint8_t nmi_colorfx_sepia[] = {
+};
+
+uint8_t nmi_colorfx_negative[] = {
+};
+
+uint8_t nmi_colorfx_emboss[] = {
+};
+
+uint8_t nmi_colorfx_sketch[] = {
+};
+
+uint8_t nmi_colorfx_sky_blue[] = {
+};
+
+uint8_t nmi_colorfx_grass_green[] = {
+};
+
+uint8_t nmi_colorfx_skin_whiten[] = {
+};
+
+uint8_t nmi_colorfx_vivid[] = {
+};
+
+// Brightness
+uint8_t nmi_brightness_neg4[] = {
+};
+
+uint8_t nmi_brightness_neg3[] = {
+};
+
+uint8_t nmi_brightness_neg2[] = {
+};
+
+uint8_t nmi_brightness_neg1[] = {
+};
+
+uint8_t nmi_brightness_zero[] = {
+};
+
+uint8_t nmi_brightness_pos1[] = {
+};
+
+uint8_t nmi_brightness_pos2[] = {
+};
+
+uint8_t nmi_brightness_pos3[] = {
+};
+
+uint8_t nmi_brightness_pos4[] = {
+};
+
+// Contrast
+uint8_t nmi_contrast_neg4[] = {
+};
+
+uint8_t nmi_contrast_neg3[] = {
+};
+
+uint8_t nmi_contrast_neg2[] = {
+};
+
+uint8_t nmi_contrast_neg1[] = {
+};
+
+uint8_t nmi_contrast_zero[] = {
+};
+
+uint8_t nmi_contrast_pos1[] = {
+};
+
+uint8_t nmi_contrast_pos2[] = {
+};
+
+uint8_t nmi_contrast_pos3[] = {
+};
+
+uint8_t nmi_contrast_pos4[] = {
+};
+
+// Saturation
+uint8_t nmi_saturation_neg4[] = {
+};
+
+uint8_t nmi_saturation_neg3[] = {
+};
+
+uint8_t nmi_saturation_neg2[] = {
+};
+
+uint8_t nmi_saturation_neg1[] = {
+};
+
+uint8_t nmi_saturation_zero[] = {
+};
+
+uint8_t nmi_saturation_pos1[] = {
+};
+
+uint8_t nmi_saturation_pos2[] = {
+};
+
+uint8_t nmi_saturation_pos3[] = {
+};
+
+uint8_t nmi_saturation_pos4[] = {
+};
+
+
+// Resolution
+
+// QCIF
+uint8_t nmi_176_144_regs[]={
+};
+
+// QVGA
+uint8_t nmi_320_240_regs[]={
+};
+
+// CIF
+uint8_t nmi_352_288_regs[]={
+};
+
+// VGA
+uint8_t nmi_640_480_regs[]={
+};
+
+// SVGA
+uint8_t nmi_800_600_regs[]={
+};
+
+// XGA
+uint8_t nmi_1024_768_regs[]={
+};
+
+// 720p
+uint8_t nmi_1280_720_regs[]={
+};
+
+// UXGA
+uint8_t nmi_1600_1200_regs[]={
+};
+
+// 1080p
+uint8_t nmi_1920_1080_regs[]={
+};
+
+// QXGA
+uint8_t nmi_2048_1536_regs[]={
+};
+
+uint8_t nmi_2592_1944_regs[]={
+};
+
+// Initiliztion
+uint8_t nmi_default_regs_init[] = {
+};
+
+// Exit
+uint8_t nmi_default_regs_exit[] = {
+};
+
+#endif /* #ifndef __NMI_H_ */
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_custom_wmt.h b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_custom_wmt.h
new file mode 100755
index 00000000..0832f3a5
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_custom_wmt.h
@@ -0,0 +1,70 @@
+
+#ifndef _NMIDRV_CUSTOM_H_
+#define _NMIDRV_CUSTOM_H_
+/******************************************************************************
+**
+** Copyright (c) Newport Media Inc. All rights reserved.
+**
+** Module Name: nmidrv_custom.h
+**
+** This module implements the porting interface for the NMI ATV driver.
+** It can be used as an example for the driver porting.
+**
+**
+*******************************************************************************/
+
+#include <mach/wmt_iomux.h>
+
+//if pin is unuse,please define it as 0xff
+#define NMI_PIN_UNUSE 0xFF
+
+//step 1: configure NMI600 power pin and reset pin .
+//if VDDIO and VCORE use each pin, define NMI_POWER_VDDIO_PIN & NMI_POWER_VCORE_PIN
+//if VDDIO and VCORE use same pin, only define NMI_POWER_VDDIO_PIN,
+//and define NMI_POWER_VCORE_PIN as 0xff !!!
+#define NMI_POWER_VDDIO_PIN NMI_PIN_UNUSE
+#define NMI_POWER_VCORE_PIN WMT_PIN_GP0_GPIO2
+
+#define NMI_RESET_PIN WMT_PIN_GP62_SUSGPIO0
+
+
+// step 2: configure NMI600 i2c bus .
+//if use hardware I2C , please define NMI_HW_I2C
+#define NMI_HW_I2C
+#define NMI_HW_I2C_PORT 4
+#define NMI_I2C_RW_LENGTH 256
+
+//if use gpio i2c , please modify the defination below
+// note: when nmi600 power off, nmi600 iic sda and scl will be set to input mode.
+// so if other devices share iic with nmi600, maybe i2c needs initilize again.
+#define NMI_SCL_PIN NMI_PIN_UNUSE
+#define NMI_SDA_PIN NMI_PIN_UNUSE
+
+/******************************************************************************
+**
+** (B) Nmi Function Prototype (for porting on MTK 65XX)
+**
+*******************************************************************************/
+#define NMI_SET_GPIO_MODE_ENABLE(PIN) if(PIN!=NMI_PIN_UNUSE) \
+ gpio_request(PIN, "ATV,DTV")
+
+#define NMI_SET_GPIO_DIR(PIN,DIR) \
+do { \
+ if (PIN!=NMI_PIN_UNUSE) { \
+ if (DIR) \
+ gpio_direction_output(PIN, 1); \
+ else \
+ gpio_direction_input(PIN); \
+ } \
+} while (0)
+
+#define NMI_SET_GPIO_PULL_DISABLE(PIN) if(PIN!=NMI_PIN_UNUSE) \
+ wmt_gpio_setpull(PIN, WMT_GPIO_PULL_NONE)
+#define NMI_SET_GPIO_PULL_ENABLE(PIN) if(PIN!=NMI_PIN_UNUSE) \
+ wmt_gpio_setpull(PIN, WMT_GPIO_PULL_UP)
+#define NMI_SET_GPIO_LEVEL(PIN,LEVEL) if(PIN!=NMI_PIN_UNUSE) \
+ gpio_set_value(PIN, LEVEL)
+#define NMI_GET_GPIO_LEVEL(PIN) gpio_get_value(PIN)
+
+
+#endif /*_NMIDRV_CUSTOM_H_*/
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.c b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.c
new file mode 100755
index 00000000..55df9fdd
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.c
@@ -0,0 +1,484 @@
+/******************************************************************************
+**
+** Copyright (c) Newport Media Inc. All rights reserved.
+**
+** Module Name: nmidrv_i2c.c
+**
+** This module implements the i2c interface NMI ATV/DTV
+**
+**
+*******************************************************************************/
+#include "nmidrv_i2c.h"
+#include "nmidrv_kernel.h"
+#include "nmidrv_custom_mtk.h"
+
+#ifndef NMI_HW_I2C
+
+#include "mach/mt6516_gpio.h"
+#include <linux/delay.h>
+
+/******************************************************************************
+**
+** I2c Defines
+**
+*******************************************************************************/
+#undef _DRIVE_ //this mode is nmi600 Recommend mode. please don't change it.
+
+#define I2C_DELAY_UNIT 2
+
+#define set_sda_output() NMI_SET_GPIO_DIR(NMI_SDA_PIN,1); \
+ NMI_SET_GPIO_LEVEL(NMI_SDA_PIN,0)
+#define set_sda_input() NMI_SET_GPIO_DIR(NMI_SDA_PIN,0)
+#define set_scl_output() NMI_SET_GPIO_DIR(NMI_SCL_PIN,1); \
+ NMI_SET_GPIO_LEVEL(NMI_SCL_PIN,0)
+#define set_scl_input() NMI_SET_GPIO_DIR(NMI_SCL_PIN,0)
+
+#ifdef _DRIVE_
+#define set_i2c_scl_PIN NMI_SET_GPIO_LEVEL(NMI_SCL_PIN,1)
+#define clr_i2c_scl_PIN NMI_SET_GPIO_LEVEL(NMI_SCL_PIN,0)
+#define set_i2c_sda_PIN NMI_SET_GPIO_LEVEL(NMI_SDA_PIN,1)
+#define clr_i2c_sda_PIN NMI_SET_GPIO_LEVEL(NMI_SDA_PIN,0)
+#else
+#define set_i2c_scl_PIN NMI_SET_GPIO_LEVEL(NMI_SCL_PIN,1)
+#define clr_i2c_scl_PIN NMI_SET_GPIO_LEVEL(NMI_SCL_PIN,0)
+#define set_i2c_sda_PIN NMI_SET_GPIO_DIR(NMI_SDA_PIN,0)
+#define clr_i2c_sda_PIN NMI_SET_GPIO_DIR(NMI_SDA_PIN,1)
+#endif
+
+#define get_i2c_sda_PIN NMI_GET_GPIO_LEVEL(NMI_SDA_PIN)
+#define get_i2c_scl_PIN NMI_GET_GPIO_LEVEL(NMI_SCL_PIN)
+
+
+
+
+/******************************************************************************
+**
+** I2c Platform Functions
+**
+*******************************************************************************/
+
+static void i2c_delay(unsigned int time)
+{
+#if 0
+ while(time--) {
+ ;
+ }
+#else
+ udelay(time);
+#endif
+}
+
+static void i2c_begin(void)
+{
+#ifdef _DRIVE_
+
+ /* set SDA to high */
+ set_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL to high */
+ set_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SDA to low */
+ clr_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL to low */
+ clr_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+#else
+
+ /* set SDA to high */
+ set_sda_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL to high */
+ set_scl_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SDA to low */
+ set_sda_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL to low */
+ set_scl_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+#endif
+
+}
+
+static void i2c_end(void)
+{
+#ifdef _DRIVE_
+ /* set SDA to low */
+ clr_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 2);
+
+ /* set SCL to high */
+ set_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SDA to high */
+ set_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+#else
+ set_sda_output();
+ i2c_delay(I2C_DELAY_UNIT << 2);
+ set_scl_input();
+ i2c_delay(I2C_DELAY_UNIT << 3);
+ set_sda_input();
+ i2c_delay(I2C_DELAY_UNIT << 4);
+#endif
+}
+
+static void i2c_write_ask(unsigned char flag)
+{
+#ifdef _DRIVE_
+ /* set SDA to high to ack */
+ if(flag)
+ set_i2c_sda_PIN;
+ else
+ clr_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* toggle clock */
+ set_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ clr_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SDA to 1 */
+ set_i2c_sda_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+#else
+
+ //set_sda_output();
+
+ if(flag)
+ set_sda_input();
+ //else
+ //set_sda_output();
+
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ set_scl_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ set_scl_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ set_sda_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+#endif
+}
+
+static unsigned char i2c_read_ack(void)
+{
+ unsigned char ret;
+
+#ifdef _DRIVE_
+ /* set SDA to input */
+ set_sda_input();
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* read */
+ if (!get_i2c_sda_PIN) {
+ ret = 1;
+ } else {
+ ret = 0;
+ dPrint(N_ERR,"[MTKI2C] 1. i2c_read_ack (Error.. No Ack received)\n");
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ if (!get_i2c_sda_PIN) {
+ ret = 1;
+ dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Correct after additional delay.)\n");
+ } else {
+ ret = 0;
+ dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Error.. No Ack received)\n");
+ }
+ }
+
+ /* set SCL high */
+ set_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL low */
+ clr_i2c_scl_PIN;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SDA back to output */
+ set_sda_output();
+
+#else
+
+ set_sda_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ if (!get_i2c_sda_PIN) {
+ ret = 1;
+ } else {
+ ret = 0;
+ dPrint(N_ERR,"[MTKI2C] 1. i2c_read_ack (Error.. No Ack received)\n");
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ if (!get_i2c_sda_PIN) {
+ ret = 1;
+ dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Correct after additional delay.)\n");
+ } else {
+ ret = 0;
+ dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Error.. No Ack received)\n");
+ }
+ }
+
+ set_scl_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ set_scl_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+#endif
+ return ret;
+}
+
+static unsigned char i2c_read_byte(void)
+{
+ unsigned char i;
+ unsigned char ret = 0;
+
+#ifdef _DRIVE_
+
+ /* set SDA input */
+ set_sda_input();
+
+ /* loop */
+ for (i = 0; i < 8; i++) {
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL high */
+ set_i2c_scl_PIN;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* read SDA */
+ ret = ret<<1;
+ if (get_i2c_sda_PIN)
+ ret |= 1;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL low */
+ clr_i2c_scl_PIN;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* if end, set SDA output */
+ if (i == 7) {
+ set_sda_output();
+ }
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ }
+
+#else
+ int retry,retry_val = 10000000;
+
+ ret = 0;
+
+ set_sda_input();
+ for (i = 0; i < 8; i++) {
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ set_scl_input();
+
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ ret = ret<<1;
+ if (get_i2c_sda_PIN)
+ ret |= 1;
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ retry = retry_val;
+ while (retry >= 0)
+ {
+ if (get_i2c_scl_PIN)
+ break;
+ else
+ {
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ retry--;
+ }
+ }
+
+ //if (retry != retry_val)
+ if (retry < (retry_val-10000))
+ {
+ //NMI_ERROR("[MTKI2C] i2c_read_byte: retry = %d\n",retry);
+ }
+
+ set_scl_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ if (i==7){
+ set_sda_output();
+ }
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ }
+
+#endif
+
+ return ret;
+}
+
+static unsigned char i2c_write_byte(unsigned char data)
+{
+ unsigned char i;
+
+#ifdef _DRIVE_
+ /* loop */
+ for (i = 0; i < 8; i++) {
+ /* set SDA high or low depend on the data bit */
+ if (data & 0x80)
+ set_i2c_sda_PIN;
+ else
+ clr_i2c_sda_PIN;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ data <<= 1;
+
+ /* set SCL high */
+ set_i2c_scl_PIN;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+
+ /* set SCL low */
+ clr_i2c_scl_PIN;
+ /* delay */
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ }
+#else
+ int retry, retry_val = 10000000;
+
+ //set_sda_output();
+
+ for (i = 0; i < 8; i++) {
+ if (data & 0x80)
+ set_sda_input();
+ else
+ set_sda_output();
+
+ data <<= 1;
+
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ set_scl_input();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ retry = retry_val;
+ while (retry >= 0)
+ {
+ if (get_i2c_scl_PIN)
+ break;
+ else
+ {
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ retry--;
+ }
+ }
+
+ //if (retry != retry_val)
+ if (retry < (retry_val-10000))
+ {
+ dPrint(N_TRACE,"i2c write_byte: retry = %d\n",retry);
+ }
+ set_scl_output();
+ i2c_delay(I2C_DELAY_UNIT << 0);
+ }
+
+#endif
+
+ return i2c_read_ack();
+}
+
+/******************************************************************************
+**
+** I2c Global Functions
+**
+*******************************************************************************/
+
+int nmi_i2c_init(void)
+{
+ dPrint(N_TRACE,"nmi_i2c_init: enter...\n");
+
+ //disable all inside pull( pullup & pulldown)
+ NMI_SET_GPIO_PULL_DISABLE(NMI_SDA_PIN);
+ NMI_SET_GPIO_PULL_DISABLE(NMI_SCL_PIN);
+ //set gpio mode
+ NMI_SET_GPIO_MODE_ENABLE(NMI_SDA_PIN);
+ NMI_SET_GPIO_MODE_ENABLE(NMI_SCL_PIN);
+
+#ifdef _DRIVE_
+ //set output mode
+ NMI_SET_GPIO_DIR( NMI_SDA_PIN,1);
+ NMI_SET_GPIO_DIR( NMI_SCL_PIN,1);
+ //set gpio high
+ NMI_SET_GPIO_LEVEL( NMI_SDA_PIN,1);
+ NMI_SET_GPIO_LEVEL( NMI_SCL_PIN,1);
+#else
+ //set input mode
+ NMI_SET_GPIO_DIR( NMI_SDA_PIN,0);
+ NMI_SET_GPIO_DIR( NMI_SCL_PIN,0);
+#endif
+
+ dPrint(N_TRACE,"nmi_i2c_init: exit...\n");
+
+ return 1;
+}
+
+void nmi_i2c_deinit(void)
+{
+ dPrint(N_TRACE,"nmi_i2c_deinit: enter...\n");
+
+ NMI_SET_GPIO_MODE_ENABLE(NMI_SDA_PIN);
+ NMI_SET_GPIO_MODE_ENABLE(NMI_SCL_PIN);
+
+ //set as input
+ NMI_SET_GPIO_DIR( NMI_SDA_PIN,0);
+ NMI_SET_GPIO_DIR( NMI_SCL_PIN,0);
+
+ dPrint(N_TRACE,"nmi_i2c_deinit: exit...\n");
+
+}
+
+int nmi_i2c_read(unsigned char adr, unsigned char *b, unsigned long sz)
+{
+ int i;
+
+ i2c_begin();
+ i2c_write_byte((adr << 1)|0x1);
+
+ for(i = 0; i < sz; i++) {
+ b[i] = i2c_read_byte();
+
+ if(i == sz-1)
+ i2c_write_ask(1);
+ else
+ i2c_write_ask(0);
+ }
+
+ i2c_end();
+ return 1;
+}
+
+int nmi_i2c_write(unsigned char adr, unsigned char *b, unsigned long sz)
+{
+ int i;
+
+ i2c_begin();
+
+ i2c_write_byte((adr << 1));
+ for(i = 0; i < sz; i++) {
+ i2c_write_byte(b[i]);
+ }
+
+ i2c_end();
+ return 1;
+}
+#endif
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.h b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.h
new file mode 100755
index 00000000..5640295b
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_i2c.h
@@ -0,0 +1,14 @@
+
+#ifndef _NMIDRV_I2C_H_
+#define _NMIDRV_I2C_H_
+
+#include "nmidrv_custom_mtk.h"
+
+//enternal interface
+#ifndef NMI_HW_I2C
+int nmi_i2c_init(void);
+void nmi_i2c_deinit(void);
+int nmi_i2c_read(unsigned char, unsigned char *, unsigned long);
+int nmi_i2c_write(unsigned char, unsigned char *, unsigned long);
+#endif
+#endif
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.c b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.c
new file mode 100755
index 00000000..601c2072
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.c
@@ -0,0 +1,435 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <asm/uaccess.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <mach/wmt_env.h>
+
+#include "nmidrv_kernel.h"
+#include "nmidrv_custom_wmt.h"
+
+extern int nmi_cmos_init(void);
+extern void nmi_cmos_exit(void);
+
+struct nmi_5625_dev {
+ struct i2c_client *i2c_client_atv;
+
+ struct mutex mu;
+ struct class *tv_class;
+ dev_t devn;
+ struct cdev cdv;
+};
+
+static int already_init = 0;
+static struct nmi_5625_dev nd;
+static u8 i2cBuf[32];
+
+static bool g_bIsAtvStart = false;
+
+int nmi_running(void)
+{
+ return g_bIsAtvStart;
+}
+EXPORT_SYMBOL(nmi_running);
+
+/**************************************************************
+
+ file operation:
+
+ **************************************************************/
+
+static int nmi5625_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+
+ func_enter();
+ if (!already_init) {
+ ret = -ENODEV;
+ goto _fail_;
+ }
+
+ /***************************************
+ initialize 2.8V 1.2V RESET GPIO mode for reference
+ ****************************************/
+
+ //PWR Enable
+ NMI_SET_GPIO_MODE_ENABLE(NMI_POWER_VDDIO_PIN);
+ NMI_SET_GPIO_DIR(NMI_POWER_VDDIO_PIN, 1);
+ NMI_SET_GPIO_PULL_DISABLE(NMI_POWER_VDDIO_PIN);
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VDDIO_PIN, 0);
+
+ //LDO_Enable
+ NMI_SET_GPIO_MODE_ENABLE(NMI_POWER_VCORE_PIN);
+ NMI_SET_GPIO_DIR(NMI_POWER_VCORE_PIN, 1);
+ NMI_SET_GPIO_PULL_DISABLE(NMI_POWER_VCORE_PIN);
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VCORE_PIN, 0);
+
+ //Reset
+ NMI_SET_GPIO_MODE_ENABLE(NMI_RESET_PIN);
+ NMI_SET_GPIO_DIR(NMI_RESET_PIN, 1);
+ NMI_SET_GPIO_PULL_DISABLE(NMI_RESET_PIN);
+ NMI_SET_GPIO_LEVEL(NMI_RESET_PIN, 0);
+
+#ifndef NMI_HW_I2C
+ nmi_i2c_init();
+#endif
+ file->private_data = (void *)&nd;
+
+_fail_:
+
+ func_exit();
+ return ret;
+}
+
+static int nmi5625_release(struct inode * inode, struct file * file)
+{
+ int ret = 0;
+ //struct nmi_5625_dev *d = file->private_data;
+
+ /**
+ nothing to do
+ **/
+ func_enter();
+
+#ifndef NMI_HW_I2C
+ nmi_i2c_deinit();
+#endif
+ func_exit();
+ return ret;
+}
+
+static long nmi5625_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct nmi_5625_dev *d = file->private_data;
+ int ret = 0;
+
+ //func_enter();
+
+ switch ((cmd&0xffff0000)) {
+
+ case NMI_POWER_VDDIO_CTL:
+ dPrint(N_TRACE,"NM5625_PWR_2P8_CTL, power %s\n", (arg==1)?"on":"off");
+ if (arg == 1){ /* on */
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VDDIO_PIN, 1);
+ }
+ else{
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VDDIO_PIN, 0);
+ }
+ break;
+
+ case NMI_POWER_VCORE_CTL:
+ dPrint(N_TRACE,"NM5625_PWR_1P2_CTL, power %s\n", (arg==1)?"on":"off");
+ if (arg == 1){ /* on */
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VCORE_PIN, 1);
+ g_bIsAtvStart = 1;
+ }
+ else{
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VCORE_PIN, 0);
+ g_bIsAtvStart = 0;
+ }
+ break;
+
+ case NMI_FM_POWER_VCORE_CTL:
+ dPrint(N_TRACE,"NMI_FM_POWER_VCORE_CTL, power %s\n", (arg==1)?"on":"off");
+ if (arg == 1){ /* on */
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VCORE_PIN, 1);
+ //g_bIsAtvStart = 1;
+ }
+ else{
+ NMI_SET_GPIO_LEVEL(NMI_POWER_VCORE_PIN, 0);
+ //g_bIsAtvStart = 0;
+ }
+ break;
+ case NMI_RESET_CTL:
+ dPrint(N_TRACE,"NM5625_ATV_RESET_CTL, reset %s\n", (arg==1)?"high":"low");
+ if (arg == 1) {
+ NMI_SET_GPIO_LEVEL(NMI_RESET_PIN, 1);
+ }
+ else {
+ NMI_SET_GPIO_LEVEL(NMI_RESET_PIN, 0);
+ }
+ break;
+ case NMI_I2C_READ:
+ {
+ u8 *kbuf = &i2cBuf[0];
+ int size = cmd&0xffff; /* Note: I used the lower 16 bits for size */
+ int len = size;
+
+ dPrint(N_TRACE,"NM5625_ATV_I2C_READ\n");
+ mutex_lock(&d->mu);
+
+#ifdef NMI_HW_I2C
+
+ while(len) {
+ int sz;
+ if (len > NMI_I2C_RW_LENGTH)
+ sz = NMI_I2C_RW_LENGTH;
+ else
+ sz = len;
+ ret = i2c_master_recv(d->i2c_client_atv, kbuf, sz);
+ if (ret < 0) {
+ dPrint(N_ERR, "nmi: failed i2c read...(%d)\n", ret);
+ //kfree(kbuf);
+ mutex_unlock(&d->mu);
+ goto _fail_;
+ }
+ kbuf += NMI_I2C_RW_LENGTH;
+ len -= sz;
+ }
+
+#else
+ ret = nmi_i2c_read(0x60,kbuf,size);
+#endif
+ dPrint(N_TRACE,"kernel:nmi_i2c_read buf is (%p), size is (%d)\n",kbuf,size);
+
+ if (copy_to_user((void *)arg, i2cBuf, size) ) {
+ dPrint(N_ERR, "nmi: failed copy to user...\n");
+ ret = -EFAULT;
+ //kfree(kbuf);
+ mutex_unlock(&d->mu);
+ goto _fail_;
+ }
+ //kfree(kbuf);
+ mutex_unlock(&d->mu);
+ }
+ break;
+ case NMI_I2C_WRITE:
+ {
+ u8 *kbuf = &i2cBuf[0];
+ int size = cmd&0xffff; /* Note: I used the lower 16 bits for size */
+ int len = size;
+ dPrint(N_TRACE,"NM5625_ATV_I2C_WRITE\n");
+ if (copy_from_user((void *)kbuf, (void *)arg, size)) {
+ dPrint(N_ERR, "nmi: failed copy from user...\n");
+ ret = -EFAULT;
+ goto _fail_;
+ }
+ mutex_lock(&d->mu);
+
+#ifdef NMI_HW_I2C
+
+ while (len) {
+ int sz;
+ if (len > NMI_I2C_RW_LENGTH)
+ sz = NMI_I2C_RW_LENGTH;
+ else
+ sz = len;
+
+ ret = i2c_master_send(d->i2c_client_atv, kbuf, sz);
+
+ if (ret < 0) {
+ dPrint(N_ERR, "nmi: failed i2c write...(%d)\n", ret);
+ //kfree(kbuf);
+ mutex_unlock(&d->mu);
+ goto _fail_;
+ }
+ kbuf += NMI_I2C_RW_LENGTH;
+ len -= sz;
+ }
+
+#else
+ ret = nmi_i2c_write(0x60,kbuf,size);
+#endif
+ dPrint(N_TRACE,"kernel:nmi_i2c_write buf is (%p), size is (%d)\n",kbuf,size);
+
+ mutex_unlock(&d->mu);
+ }
+ break;
+ default:
+ break;
+ }
+
+_fail_:
+ //func_exit();
+ dPrint(N_TRACE, "nmi_ioctl return value...(%d)\n", ret);
+ return ret;
+}
+
+static const struct file_operations nmi5625_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = nmi5625_ioctl,
+ .open = nmi5625_open,
+ .release = nmi5625_release,
+};
+
+/**************************************************************
+
+i2c:
+
+ **************************************************************/
+
+static int nmi5625_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static int nmi5625_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
+{
+ strcpy(info->type, "nmiatv");
+ return 0;
+}
+
+static int nmi5625_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct device *dev;
+ func_enter();
+
+ if (!already_init) {
+ memset(&nd, 0, sizeof(struct nmi_5625_dev));
+
+ /**
+ initialize mutex
+ **/
+ mutex_init(&nd.mu);
+
+ /**
+ register our driver
+ **/
+ if ((ret = alloc_chrdev_region (&nd.devn, 0, 1, "nmi")) < 0) {
+ dPrint(N_ERR, "nmi: failed unable to get major...%d\n", ret);
+ goto _fail_;
+ }
+ dPrint(N_INFO, "nmi:dynamic major(%d),minor(%d)\n", MAJOR(nd.devn), MINOR(nd.devn));
+
+ cdev_init(&nd.cdv, &nmi5625_fops);
+ nd.cdv.owner = THIS_MODULE;
+ ret = cdev_add(&nd.cdv, nd.devn, 1);
+ if (ret) {
+ dPrint(N_ERR, "nmi: failed to add device...%d\n", ret);
+ goto _fail_;
+ }
+
+
+ nd.tv_class = class_create(THIS_MODULE, "atv");
+ if (IS_ERR(nd.tv_class)) {
+ dPrint(N_ERR, "nmi: failed to create the atv class\n");
+ }
+
+ dev = device_create(nd.tv_class, NULL, nd.devn, NULL, "nmi");
+ if (IS_ERR(dev)) {
+ dPrint(N_ERR, "nmi: failed to create device\n");
+ }
+ /*User interface end */
+
+ already_init = 1;
+ }
+
+ nd.i2c_client_atv = client;
+
+_fail_:
+
+ func_exit();
+ return ret;
+}
+
+static const struct i2c_device_id nmi5625_id[] = {
+ {"nmiatv", 0},
+ {},
+};
+
+//static unsigned short force[] = {2, 0xc0, I2C_CLIENT_END, I2C_CLIENT_END};
+//static const unsigned short * const forces[] = { force, NULL };
+//static struct i2c_client_address_data addr_data = { .forces = forces,};
+
+static struct i2c_driver nmi5625_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "nmiatv",
+ },
+ .probe = nmi5625_probe,
+ .detect = nmi5625_detect,
+ .remove = nmi5625_remove,
+ .id_table = nmi5625_id,
+ // .address_data =&addr_data,
+};
+
+static struct i2c_board_info nmi5625_i2c_dev = {
+ I2C_BOARD_INFO("nmiatv", 0x60),
+};
+
+/**************************************************************
+
+Module:
+
+ **************************************************************/
+
+static int parse_nmi_param(void)
+{
+ char env[] = "wmt.nmi.param";
+ char buf[64];
+ size_t l = sizeof(buf);
+ int nr = -EINVAL;
+
+ if (wmt_getsyspara(env, buf, &l) == 0) {
+ sscanf(buf, "i2c-%d", &nr);
+ pr_info("nmi5625 i2c adapter %d\n", nr);
+ }
+
+ return nr;
+}
+
+static __init int nmi5625_init(void)
+{
+ int ret;
+ struct i2c_adapter *adapter;
+ struct i2c_client *client;
+ int nr;
+ func_enter();
+
+ nr = parse_nmi_param();
+ if (nr < 0)
+ return nr;
+
+ adapter = i2c_get_adapter(nr);
+ client = i2c_new_device(adapter, &nmi5625_i2c_dev);
+ i2c_put_adapter(adapter);
+ if (!client) {
+ printk("nmi i2c_new_device failed\n");
+ return -EINVAL;
+ }
+
+ ret = i2c_add_driver(&nmi5625_i2c_driver);
+ if (ret < 0) {
+ dPrint(N_ERR, "nmi: failed register i2c driver...(%d)\n", ret);
+ }
+
+ func_exit();
+
+ return ret;
+}
+
+static __exit void nmi5625_clean(void)
+{
+ func_enter();
+
+ i2c_del_driver(&nmi5625_i2c_driver);
+
+ if (already_init) {
+ device_destroy(nd.tv_class, nd.devn);
+ class_destroy(nd.tv_class);
+ cdev_del(&nd.cdv);
+ unregister_chrdev_region(nd.devn, 1);
+ already_init = 0;
+ i2c_unregister_device(nd.i2c_client_atv);
+ nd.i2c_client_atv = NULL;
+ }
+
+ func_exit();
+}
+
+module_init(nmi5625_init);
+module_exit(nmi5625_clean);
+
+MODULE_AUTHOR("nmi");
+MODULE_DESCRIPTION("nmi TV 5625 driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.h b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.h
new file mode 100755
index 00000000..1b9f116a
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/nmi5625/nmidrv_kernel.h
@@ -0,0 +1,42 @@
+#ifndef _NMIDRV_KERNEL_H_
+#define _NMIDRV_KERNEL_H_
+
+/**************************************************************
+ IO Control Command defination:
+**************************************************************/
+#define NMI_POWER_VDDIO_CTL 0x10000000
+#define NMI_POWER_VCORE_CTL 0x20000000
+#define NMI_RESET_CTL 0x30000000
+#define NMI_I2C_READ 0x40000000
+#define NMI_I2C_WRITE 0x50000000
+#define NMI_FM_POWER_VCORE_CTL 0x60000000
+
+/**************************************************************
+ Debug Trace Defination:
+**************************************************************/
+
+#define DEBUG
+
+#define N_INIT 0x00000001
+#define N_ERR 0x00000002
+#define N_FUNC 0x00000004
+#define N_TRACE 0x00000008
+#define N_INFO 0x00000010
+
+static unsigned int dflag = N_INIT|N_ERR|N_FUNC|N_INFO;
+
+#ifdef DEBUG
+#define dPrint(f, str...) if (dflag & f) printk (str)
+#else
+#define dPrint(f, str...) /* nothing */
+#endif
+
+#define func_enter() dPrint (N_TRACE, "nmi: %s...enter\n", __func__)
+#define func_exit() dPrint(N_TRACE, "nmi: %s...exit\n", __func__)
+
+
+#ifdef NMI_HW_I2C
+#define NMI_I2C_RW_LENGTH 256
+#endif
+
+#endif