-
nmi_gpio_i2c.h
-
-
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);
-
-
nmi_gpio_i2c.c
-
/******************************************************************************
-
-
**
-
-
** Copyright (c) Newport Media Inc. All rights reserved.
-
-
**
-
-
** Module Name: nmidrv_i2c.c
-
-
**
-
-
** This module implements the i2c interface NMI ATV
-
-
**
-
-
**
-
-
*******************************************************************************/
-
-
#include <linux/kernel.h>
-
-
#include <linux/init.h>
-
-
//#include <linux/android_pmem.h>
-
-
#include <mach/hardware.h>
-
-
#include <asm/mach-types.h>
-
-
#include <asm/mach/arch.h>
-
-
#include <asm/mach/map.h>
-
-
#include <mach/board.h>
-
-
#include <mach/hardware.h>
-
-
#include <asm/io.h>
-
-
#include <asm/delay.h>
-
-
#include <mach/gpio.h>
-
-
#include <linux/clk.h>
-
-
#include <mach/mfp.h>
-
-
#include <linux/i2c.h>
-
-
#include <linux/i2c-gpio.h>
-
-
#include "nmi_gpio_i2c.h"
-
-
#include "nm5625_kernel.h"
-
-
#include <linux/delay.h>
-
-
-
-
-
-
-
-
#define NMI_SDA_PIN 81
-
-
#define NMI_SCL_PIN 80
-
-
-
-
static unsigned long I2C_func_cfg[] /*__initdata*/ = {
-
-
MFP_CFG_X(SDA, GPIO, DS3, F_PULL_UP, F_PULL_UP, IO_OE),
-
-
MFP_CFG_X(SCL, GPIO, DS3, F_PULL_UP, F_PULL_UP, IO_OE),
-
-
};
-
-
-
-
static unsigned long I2C_std_func_cfg[] = {
-
MFP_CFG_X(SDA, AF0, DS3, F_PULL_UP, F_PULL_UP, IO_NONE),
-
-
MFP_CFG_X(SCL, AF0, DS3, F_PULL_UP, F_PULL_UP, IO_NONE),
-
};
-
-
-
-
/******************************************************************************
-
-
**
-
-
** I2c Defines
-
-
**
-
-
*******************************************************************************/
-
-
//#undef _DRIVE_ //this mode is nmi600 Recommend mode. please don't change it.
-
-
#define _DRIVE_
-
-
#define I2C_DELAY_UNIT 2
-
-
-
-
/*#define set_sda_output() mt_set_gpio_dir(NMI_SDA_PIN,1); \
-
-
mt_set_gpio_out(NMI_SDA_PIN,0)
-
-
#define set_sda_input() mt_set_gpio_dir(NMI_SDA_PIN,0)
-
-
#define set_scl_output() mt_set_gpio_dir(NMI_SCL_PIN,1); \
-
-
mt_set_gpio_out(NMI_SCL_PIN,0)
-
-
#define set_scl_input() mt_set_gpio_dir(NMI_SCL_PIN,0)*/
-
-
-
-
#define set_sda_output() gpio_direction_output(NMI_SDA_PIN,0)
-
-
#define set_sda_input() gpio_direction_input(NMI_SDA_PIN)
-
-
#define set_scl_output() gpio_direction_output(NMI_SCL_PIN,0)
-
-
#define set_scl_input() gpio_direction_input(NMI_SCL_PIN)
-
-
-
-
#ifdef _DRIVE_
-
-
#define set_i2c_scl_PIN gpio_direction_output(NMI_SCL_PIN,1)
-
-
#define clr_i2c_scl_PIN gpio_direction_output(NMI_SCL_PIN,0)
-
-
#define set_i2c_sda_PIN gpio_direction_output(NMI_SDA_PIN,1)
-
-
#define clr_i2c_sda_PIN gpio_direction_output(NMI_SDA_PIN,0)
-
-
#else
-
-
/*#define set_i2c_scl_PIN mt_set_gpio_out(NMI_SCL_PIN,1)
-
-
#define clr_i2c_scl_PIN mt_set_gpio_out(NMI_SCL_PIN,0)
-
-
#define set_i2c_sda_PIN mt_set_gpio_out(NMI_SDA_PIN,0)
-
-
#define clr_i2c_sda_PIN mt_set_gpio_out(NMI_SDA_PIN,1)*/
-
-
#endif
-
-
-
-
//#define get_i2c_sda_PIN gpio_direction_input(NMI_SDA_PIN);gpio_get_value(NMI_SDA_PIN)
-
-
//#define get_i2c_scl_PIN gpio_direction_input(NMI_SCL_PIN);gpio_get_value(NMI_SCL_PIN)
-
-
#define get_i2c_sda_PIN gpio_get_value(NMI_SDA_PIN)
-
-
#define get_i2c_scl_PIN gpio_get_value(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 */
-
-
//gpio_direction_input(NMI_SDA_PIN);
-
-
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);
-
-
-
-
//gpio_direction_input(NMI_SDA_PIN);
-
-
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;
-
-
//gpio_direction_input(NMI_SDA_PIN);
-
-
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");
-
-
-
-
sprd_mfp_config(I2C_func_cfg, ARRAY_SIZE(I2C_func_cfg));
-
-
gpio_request(NMI_SCL_PIN,"scl");
-
-
gpio_request(NMI_SDA_PIN,"sda");
-
-
gpio_direction_output(NMI_SCL_PIN,1);
-
-
gpio_direction_output(NMI_SDA_PIN,1);
-
-
/*#if 0
-
-
//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
-
-
#else
-
-
//config scl
-
-
mt_set_gpio_mode(NMI_SCL_PIN,GPIO_MODE_00);
-
-
mt_set_gpio_dir(NMI_SCL_PIN, GPIO_DIR_OUT);
-
-
mt_set_gpio_pull_enable(NMI_SCL_PIN,true);
-
-
mt_set_gpio_pull_select(NMI_SCL_PIN, GPIO_PULL_UP);
-
-
mt_set_gpio_out(NMI_SCL_PIN, GPIO_OUT_ONE);
-
-
-
-
//config sda
-
-
mt_set_gpio_mode(NMI_SDA_PIN, GPIO_MODE_00);
-
-
mt_set_gpio_dir(NMI_SDA_PIN, GPIO_DIR_OUT);
-
-
mt_set_gpio_pull_enable(NMI_SDA_PIN,true);
-
-
mt_set_gpio_pull_select(NMI_SDA_PIN, GPIO_PULL_UP);
-
-
mt_set_gpio_out(NMI_SDA_PIN, GPIO_OUT_ONE);
-
-
#endif*/
-
-
dPrint(N_TRACE,"nmi_i2c_init: exit...\n");
-
-
-
-
return 1;
-
-
}
-
-
-
-
void nmi_i2c_deinit(void)
-
-
{
-
-
dPrint(N_TRACE,"nmi_i2c_deinit: enter...\n");
-
-
-
-
gpio_free(NMI_SDA_PIN);
-
-
gpio_free(NMI_SCL_PIN);
-
sprd_mfp_config(I2C_std_func_cfg, ARRAY_SIZE(I2C_std_func_cfg));
-
-
#if 0
-
-
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);
-
-
#endif
-
-
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;
-
-
}