diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/media/video/wmt_v4l2/sensors/nmi5625 | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-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')
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 |