blob: d686f15e0caa80c9eb7b33f435f806a549d0eff9 [file] [log] [blame]
/*
* include/aml_i2c.h
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __AML_I2C_H__
#define __AML_I2C_H__
#include <common.h>
#include <linux/compiler.h>
#include <asm/arch/i2c.h>
#define AML_I2C_MAX_TOKENS 8
/*I2C_CONTROL_REG 0x2140/0x2148*/
struct aml_i2c_reg_ctrl {
unsigned int start:1; /*[0] Set to 1 to start list processing*/
/*Setting this bit to 0 while the list processor is operating causes the list
processor to abort the current I2C operation and generate an I2C STOP
command on the I2C bus. Normally this bit is set to 1 and left high
until processing is complete. To re-start the list processor with a
new list (after a previous list has been exhausted), simply set this
bit to zero then to one.*/
unsigned int ack_ignore:1; /*[1] Set to 1 to disable I2C ACK detection.*/
/*The I2C bus uses an ACK signal after every byte transfer to detect
problems during the transfer. Current Software implementations of the
I2C bus ignore this ACK. This bit is for compatibility with the current
Amlogic software. This bit should be set to 0 to allow NACK
operations to abort I2C bus transactions. If a NACK occurs, the ERROR
bit above will be set. */
unsigned int status:1; /*[2] the status of the List processor*/
#define I2C_IDLE 0
#define I2C_RUNNING 1
/* 0: IDLE
1: Running. The list processor will enter this state on the clock cycle
after the START bit is set. The software can poll the status register to
determine when processing is complete.
*/
unsigned int error:1; /*[3] */
/*This read only bit is set if the I2C device generates a NACK during writing.
This bit is cleared at on the clock cycle after the START bit is set to 1
indicating the start of list processing. Errors can be ignored by setting
the ACK_IGNORE bit below. Errors will be generated on Writes to
devices that return NACK instead of ACK. A NACK is returned by a
device if it is unable to accept any more data (for example because it
is processing some other real-time function). In the event of an
ERROR, the I2C module will automatically generate a STOP condition
on the bus.*/
unsigned int cur_token:4; /*[7:4] the current token being processed*/
unsigned int rd_data_cnt:4;/*[11:8] number of bytes READ over the I2C bus*/
/*If this value is zero, then no data has been read. If this value is 1, then
bits [7:0] in TOKEN_RDATA_REG0 contains valid data. The software can
read this register after an I2C transaction to get the number of bytes to
read from the I2C device*/
unsigned int clk_delay:10; /*[21:12] Quarter clock delay*/
/*This value corresponds to period of the SCL clock divided by 4
Quarter Clock Delay = * System Clock Frequency
For example, if the system clock is 133Mhz, and the I2C clock period
is 10uS (100khz), then
Quarter Clock Delay = * 133 Mhz = 332
*/
unsigned int manual_en:1; /*[22] enable manual mode. */
/*Manual I2C mode is controlled by bits 12,13,14 and 15 above.*/
unsigned int wrscl:1; /*[23] Sets the level of the SCL line */
/*if manual mode is enabled. If this bit is '0', then the SCL line is
pulled low. If this bit is '1' then the SCL line is tri-stated.*/
unsigned int wrsda:1; /*[24] Sets the level of the SDA line */
/*if manual mode is enabled. If this bit is '0', then the SDA line is
pulled low. If this bit is '1' then the SDA line is tri-stated.*/
unsigned int rdscl:1; /*[25] Read back level of the SCL line*/
unsigned int rdsda:1; /*[26] Read back level of the SDA line*/
#if 1
unsigned int unused:1; /*[27]*/
unsigned int clk_delay_ext:2; /*[29:28]*/
unsigned int unused2:2; /*[31:30]*/
#else
unsigned int unused:5; /*[31:27]*/
#endif
};
struct aml_i2c_reg_slave_addr {
unsigned int slave_addr:8; /*[7:0] SLAVE ADDRESS.*/
/*This is a 7-bit value for a 7-bit I2C device, or (0xF0 | {A9,A8}) for a
10 bit I2C device. By convention, the slave address is typically
stored in by first left shifting it so that it's MSB is D7 (The I2C bus
assumes the 7-bit address is left shifted one). Additionally, since
the SLAVE address is always an 7-bit value, D0 is always 0.
NOTE: The I2C always transfers 8-bits even for address. The I2C
hardware will use D0 to dictate the direction of the bus. Therefore,
D0 should always be '0' when this register is set.
*/
unsigned int sda_filter:3; /*[10:8] SDA FILTER*/
/*A filter was added in the SCL input path to allow for filtering of slow
rise times. 0 = no filtering, 7 = max filtering*/
unsigned int scl_filter:3; /*[13:11] SCL FILTER*/
/*A filter was added in the SCL input path to allow for filtering of slow
rise times. 0 = no filtering, 7 = max filtering*/
#if 1
unsigned int unused:2; /*[15:14]*/
unsigned int clk_low_delay:12; /*[27:16]*/
unsigned int clk_low_delay_en:1; /*[28]*/
unsigned int unused2:3; /*[31:29]*/
#else
unsigned int unused:18; /*[31:14]*/
#endif
};
/*Write data associated with the DATA token should be placed into the
I2C_TOKEN_WDATA_REG0 or I2C_TOKEN_WDATA_REG1 registers.
Read data associated with the DATA or DATA-LAST token can be read from
the I2C_TOKEN_RDATA_REG0 or I2C_TOKEN_RDATA_REG1 registers*/
enum aml_i2c_token {
TOKEN_END,
TOKEN_START,
TOKEN_SLAVE_ADDR_WRITE,
TOKEN_SLAVE_ADDR_READ,
TOKEN_DATA,
TOKEN_DATA_LAST,
TOKEN_STOP
};
struct aml_i2c_reg_master {
volatile unsigned int i2c_ctrl;
volatile unsigned int i2c_slave_addr;
volatile unsigned int i2c_token_list_0;
volatile unsigned int i2c_token_list_1;
volatile unsigned int i2c_token_wdata_0;
volatile unsigned int i2c_token_wdata_1;
volatile unsigned int i2c_token_rdata_0;
volatile unsigned int i2c_token_rdata_1;
};
struct aml_i2c_reg_slave_ctrl {
unsigned int samp_rate:7; /*[6:0] sampling rate*/
/*Defined as MPEG system clock / (value + 1). The SDA and SCL inputs into
the slave module are sampled as a way of filtering the inputs. A
rising or falling edge is determined by when 3 successive samples are
either high or low respectively*/
unsigned int enable:1; /*[7] A '1' enables the I2C slave state machine*/
unsigned int hold_time:8; /*[15:8]*/
/*Data hold time after the falling edge of SCL.
Hold time = (MPEG system clock period) * (value + 1).
*/
unsigned int slave_addr:8; /*[23-16]*/
/*Bits [7:1] are used to identify the device.
Bit [0] is ignored since this corresponds to the R/W bit.*/
unsigned int ack_always:1; /*[24]*/
/*Typically the ACK of a slave I2C device is dependent upon the
availability of data (if reading) and room to store data (when we are
being written). Our I2C module has a status register that can be read
continuously. This bit can be set if the I2C master wants to
continually read the status register. */
unsigned int irq_en:1; /*[25]*/
/*If this bit is set, then an interrupt will be sent to the ARC whenever 4
bytes have been read or 4 bytes have been written to the I2C slave
module.*/
unsigned int busy:1; /*[26] */
/*Read only status bit. '1' indicates that the I2C slave module is sending
or receiving data.*/
unsigned int rx_rdy:1; /*[27] */
/*This bit is set to '1' by the ARC to indicate to the slave machine that
the I2C slave module is ready to receive data. This bit is cleared by
the I2C module when it has received 4 bytes from the I2C master.
This bit is also available in the status register that can be read by
the I2C master. The I2C master can read the status register to see
when the I2C slave module is ready to receive data.*/
unsigned int tx_rdy:1; /*[28] */
/*This bit is set to '1' by the ARC to indicate to the slave machine that
the I2C slave module is ready to send data. This bit is cleared by
the I2C module when it has sent 4 bytes to the I2C master. This bit
is also available in the status register that can be read by the I2C
master. The I2C master can read the status register to see when the
I2C slave module has data to send.*/
unsigned int reg_ptr:3; /*[31:29] */
/*There are 5 internal registers inside the I2C slave module. The I2C
Master sets this value using the byte that follows the address byte
in the I2C data stream. Register 4 (numbered 0,1,¡­4) is the
status register.*/
};
struct aml_i2c_reg_slave{
unsigned int i2c_slave_ctrl;
unsigned int i2c_slave_tx_data;
unsigned int i2c_slave_rx_data;
};
struct aml_i2c {
unsigned int i2c_debug;
unsigned int cur_slave_addr;
unsigned int wait_count;
unsigned int wait_ack_interval;
unsigned int wait_read_interval;
unsigned int wait_xfer_interval;
unsigned int master_no;/*master a:0 master b:1*/
#define I2C_MASTER_AO 0
#define I2C_MASTER_A 1
#define I2C_MASTER_B 2
#define I2C_MASTER_C 3
#define I2C_MASTER_D 4
unsigned char token_tag[AML_I2C_MAX_TOKENS];
unsigned int msg_flags;
struct aml_i2c_ops* ops;
struct aml_i2c_reg_master __iomem* master_regs;
//#ifdef CONFIG_I2C_AML_SLAVE
struct aml_i2c_reg_slave __iomem* slave_regs;
struct aml_pinmux_reg_bit slave_pinmux;
unsigned int slave_dev_addr;
//#endif
void __iomem *reg_base;
struct aml_pinmux_reg_bit master_pinmux;
int irq;
unsigned int use_pio;/*0: hardware i2c, 1: pio i2c*/
unsigned int master_i2c_speed;
};
struct aml_i2c_ops {
void (*xfer_prepare)(struct aml_i2c *i2c);
int (*do_address)(struct aml_i2c *i2c, unsigned int addr);
ssize_t (*read)(struct aml_i2c *i2c, unsigned char *buf, size_t len);
ssize_t (*write)(struct aml_i2c *i2c, unsigned char *buf, size_t len);
void (*stop)(struct aml_i2c *i2c);
};
int aml_i2c_init(void);
void i2c_plat_init(void);
int aml_i2c_xfer(struct i2c_msg *msgs, int num);
/*General i2c master transfer,it can Send to a specific master control*/
int aml_i2c_transfer(int adap_num , struct i2c_msg *msgs , int num);
enum aml_i2c_id{
SOFT_I2C = 0,
HARD_I2C,
};
struct i2c_board_info {
char type[64];
int i2c_id;
unsigned short addr;
void (*device_init)(void);
void (*device_uninit)(void);
};
#define I2C_BOARD_INFO(dev_type, dev_addr) \
.type = dev_type, .addr = (dev_addr)
struct aml_i2c_device {
struct i2c_borad_info *aml_i2c_boards;
unsigned dev_num;
};
#ifdef AML_MESON_BOARD_8726M_2010_11_18_V11
//Please refer board schematic for detail pin connection
//@AML8726-M_ARM_DEV_BOARD_2DDR_V1R1.pdf
//port27-> Red (0x7F)
//port26-> Green (0xBF)
//port25-> Blue (0xDF)
#define I2C_LED_RED (0x7F)
#define I2C_LED_GREEN (0xBF)
#define I2C_LED_BLUE (0xDF)
//To set onboard LEDs on/off
void board_i2c_led_set(unsigned char byLED, unsigned char byOn);
#endif //AML_MESON_BOARD_8726M_2010_11_18_V11
#endif //__AML_I2C_H__