2011-02-21 04:14:21 +03:00
/*
* drivers / i2c / busses / i2c - tegra . c
*
* Copyright ( C ) 2010 Google , Inc .
* Author : Colin Cross < ccross @ 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/kernel.h>
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/i2c.h>
# include <linux/io.h>
# include <linux/interrupt.h>
# include <linux/delay.h>
# include <linux/slab.h>
# include <linux/i2c-tegra.h>
2011-06-22 20:16:56 +04:00
# include <linux/of_i2c.h>
2012-08-18 23:17:46 +04:00
# include <linux/of_device.h>
2011-07-30 08:14:30 +04:00
# include <linux/module.h>
2011-02-21 04:14:21 +03:00
# include <asm/unaligned.h>
# include <mach/clk.h>
# define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000))
# define BYTES_PER_FIFO_WORD 4
# define I2C_CNFG 0x000
2011-04-26 01:32:27 +04:00
# define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12
2011-02-21 04:14:21 +03:00
# define I2C_CNFG_PACKET_MODE_EN (1<<10)
# define I2C_CNFG_NEW_MASTER_FSM (1<<11)
2011-04-26 01:32:25 +04:00
# define I2C_STATUS 0x01C
2011-02-21 04:14:21 +03:00
# define I2C_SL_CNFG 0x020
i2c: tegra: Assign unused slave address
On Tegra, we should always use the "new" I2C slave controller, to avoid
issues with the old controller. This was implemented in commit 65a1a0a
"i2c: tegra: Enable new slave mode."
There is currently no driver for the Tegra I2C slave controller upstream.
Additionally, the controller cannot be completely disabled. Instead, we
need to:
a) Set I2C_SL_CNFG_NACK to make the controller automatically NACK any
incoming transactions.
b) The controller's definition of NACK isn't identical to the I2C
protocol's definition. Specifically, it will perform a standard NACK, but
*also* continue to hold the clock line low in expectation of receiving
more data. This can hang the bus, or at least cause transaction timeouts,
if something starts a transaction that matches the controller's slave
address. Since the default address is 0x00, the general call address,
this does occur in practice.
To avoid this, we explicitly program a slave address that is reserved for
future expansion. For current boards, this guarantees the address will
never be used. If a future board ever needs to use this address, we can
add platform data to determine a board-specific safe address. 0xfc is
picked by this patch.
This patch is based on a change previously posted by: Wei Ni <wni@nvidia.com>
http://www.spinics.net/lists/linux-i2c/msg05437.html
In turned based on internal changes by: Bharat Nihalani <bnihalani@nvidia.com>
A semantically equivalent change has been contained in the various
ChromeOS kernels for a while.
I tested this change on top of 3.0-rc2 on Harmony, and interacted with
the WM8903 I2C-based audio codec.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
2011-06-06 21:25:19 +04:00
# define I2C_SL_CNFG_NACK (1<<1)
2011-02-21 04:14:21 +03:00
# define I2C_SL_CNFG_NEWSL (1<<2)
# define I2C_SL_ADDR1 0x02c
i2c: tegra: Assign unused slave address
On Tegra, we should always use the "new" I2C slave controller, to avoid
issues with the old controller. This was implemented in commit 65a1a0a
"i2c: tegra: Enable new slave mode."
There is currently no driver for the Tegra I2C slave controller upstream.
Additionally, the controller cannot be completely disabled. Instead, we
need to:
a) Set I2C_SL_CNFG_NACK to make the controller automatically NACK any
incoming transactions.
b) The controller's definition of NACK isn't identical to the I2C
protocol's definition. Specifically, it will perform a standard NACK, but
*also* continue to hold the clock line low in expectation of receiving
more data. This can hang the bus, or at least cause transaction timeouts,
if something starts a transaction that matches the controller's slave
address. Since the default address is 0x00, the general call address,
this does occur in practice.
To avoid this, we explicitly program a slave address that is reserved for
future expansion. For current boards, this guarantees the address will
never be used. If a future board ever needs to use this address, we can
add platform data to determine a board-specific safe address. 0xfc is
picked by this patch.
This patch is based on a change previously posted by: Wei Ni <wni@nvidia.com>
http://www.spinics.net/lists/linux-i2c/msg05437.html
In turned based on internal changes by: Bharat Nihalani <bnihalani@nvidia.com>
A semantically equivalent change has been contained in the various
ChromeOS kernels for a while.
I tested this change on top of 3.0-rc2 on Harmony, and interacted with
the WM8903 I2C-based audio codec.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
2011-06-06 21:25:19 +04:00
# define I2C_SL_ADDR2 0x030
2011-02-21 04:14:21 +03:00
# define I2C_TX_FIFO 0x050
# define I2C_RX_FIFO 0x054
# define I2C_PACKET_TRANSFER_STATUS 0x058
# define I2C_FIFO_CONTROL 0x05c
# define I2C_FIFO_CONTROL_TX_FLUSH (1<<1)
# define I2C_FIFO_CONTROL_RX_FLUSH (1<<0)
# define I2C_FIFO_CONTROL_TX_TRIG_SHIFT 5
# define I2C_FIFO_CONTROL_RX_TRIG_SHIFT 2
# define I2C_FIFO_STATUS 0x060
# define I2C_FIFO_STATUS_TX_MASK 0xF0
# define I2C_FIFO_STATUS_TX_SHIFT 4
# define I2C_FIFO_STATUS_RX_MASK 0x0F
# define I2C_FIFO_STATUS_RX_SHIFT 0
# define I2C_INT_MASK 0x064
# define I2C_INT_STATUS 0x068
# define I2C_INT_PACKET_XFER_COMPLETE (1<<7)
# define I2C_INT_ALL_PACKETS_XFER_COMPLETE (1<<6)
# define I2C_INT_TX_FIFO_OVERFLOW (1<<5)
# define I2C_INT_RX_FIFO_UNDERFLOW (1<<4)
# define I2C_INT_NO_ACK (1<<3)
# define I2C_INT_ARBITRATION_LOST (1<<2)
# define I2C_INT_TX_FIFO_DATA_REQ (1<<1)
# define I2C_INT_RX_FIFO_DATA_REQ (1<<0)
# define I2C_CLK_DIVISOR 0x06c
# define DVC_CTRL_REG1 0x000
# define DVC_CTRL_REG1_INTR_EN (1<<10)
# define DVC_CTRL_REG2 0x004
# define DVC_CTRL_REG3 0x008
# define DVC_CTRL_REG3_SW_PROG (1<<26)
# define DVC_CTRL_REG3_I2C_DONE_INTR_EN (1<<30)
# define DVC_STATUS 0x00c
# define DVC_STATUS_I2C_DONE_INTR (1<<30)
# define I2C_ERR_NONE 0x00
# define I2C_ERR_NO_ACK 0x01
# define I2C_ERR_ARBITRATION_LOST 0x02
2011-04-26 01:32:25 +04:00
# define I2C_ERR_UNKNOWN_INTERRUPT 0x04
2011-02-21 04:14:21 +03:00
# define PACKET_HEADER0_HEADER_SIZE_SHIFT 28
# define PACKET_HEADER0_PACKET_ID_SHIFT 16
# define PACKET_HEADER0_CONT_ID_SHIFT 12
# define PACKET_HEADER0_PROTOCOL_I2C (1<<4)
# define I2C_HEADER_HIGHSPEED_MODE (1<<22)
# define I2C_HEADER_CONT_ON_NAK (1<<21)
# define I2C_HEADER_SEND_START_BYTE (1<<20)
# define I2C_HEADER_READ (1<<19)
# define I2C_HEADER_10BIT_ADDR (1<<18)
# define I2C_HEADER_IE_ENABLE (1<<17)
# define I2C_HEADER_REPEAT_START (1<<16)
2012-06-13 14:12:38 +04:00
# define I2C_HEADER_CONTINUE_XFER (1<<15)
2011-02-21 04:14:21 +03:00
# define I2C_HEADER_MASTER_ADDR_SHIFT 12
# define I2C_HEADER_SLAVE_ADDR_SHIFT 1
2012-06-13 14:12:38 +04:00
/*
* msg_end_type : The bus control which need to be send at end of transfer .
* @ MSG_END_STOP : Send stop pulse at end of transfer .
* @ MSG_END_REPEAT_START : Send repeat start at end of transfer .
* @ MSG_END_CONTINUE : The following on message is coming and so do not send
* stop or repeat start .
*/
enum msg_end_type {
MSG_END_STOP ,
MSG_END_REPEAT_START ,
MSG_END_CONTINUE ,
} ;
2011-02-21 04:14:21 +03:00
2012-08-18 23:17:46 +04:00
/**
* struct tegra_i2c_hw_feature : Different HW support on Tegra
* @ has_continue_xfer_support : Continue transfer supports .
*/
struct tegra_i2c_hw_feature {
bool has_continue_xfer_support ;
} ;
2011-02-21 04:14:21 +03:00
/**
* struct tegra_i2c_dev - per device i2c context
* @ dev : device reference for power management
2012-08-18 23:17:46 +04:00
* @ hw : Tegra i2c hw feature .
2011-02-21 04:14:21 +03:00
* @ adapter : core i2c layer adapter information
2012-08-08 11:51:32 +04:00
* @ div_clk : clock reference for div clock of i2c controller .
* @ fast_clk : clock reference for fast clock of i2c controller .
2011-02-21 04:14:21 +03:00
* @ base : ioremapped registers cookie
* @ cont_id : i2c controller id , used for for packet header
* @ irq : irq number of transfer complete interrupt
* @ is_dvc : identifies the DVC i2c controller , has a different register layout
* @ msg_complete : transfer completion notifier
* @ msg_err : error code for completed message
* @ msg_buf : pointer to current message data
* @ msg_buf_remaining : size of unsent data in the message buffer
* @ msg_read : identifies read transfers
* @ bus_clk_rate : current i2c bus clock rate
* @ is_suspended : prevents i2c controller accesses after suspend is called
*/
struct tegra_i2c_dev {
struct device * dev ;
2012-08-18 23:17:46 +04:00
const struct tegra_i2c_hw_feature * hw ;
2011-02-21 04:14:21 +03:00
struct i2c_adapter adapter ;
2012-08-08 11:51:32 +04:00
struct clk * div_clk ;
struct clk * fast_clk ;
2011-02-21 04:14:21 +03:00
void __iomem * base ;
int cont_id ;
int irq ;
2011-04-26 01:32:25 +04:00
bool irq_disabled ;
2011-02-21 04:14:21 +03:00
int is_dvc ;
struct completion msg_complete ;
int msg_err ;
u8 * msg_buf ;
size_t msg_buf_remaining ;
int msg_read ;
unsigned long bus_clk_rate ;
bool is_suspended ;
} ;
static void dvc_writel ( struct tegra_i2c_dev * i2c_dev , u32 val , unsigned long reg )
{
writel ( val , i2c_dev - > base + reg ) ;
}
static u32 dvc_readl ( struct tegra_i2c_dev * i2c_dev , unsigned long reg )
{
return readl ( i2c_dev - > base + reg ) ;
}
/*
* i2c_writel and i2c_readl will offset the register if necessary to talk
* to the I2C block inside the DVC block
*/
static unsigned long tegra_i2c_reg_addr ( struct tegra_i2c_dev * i2c_dev ,
unsigned long reg )
{
if ( i2c_dev - > is_dvc )
reg + = ( reg > = I2C_TX_FIFO ) ? 0x10 : 0x40 ;
return reg ;
}
static void i2c_writel ( struct tegra_i2c_dev * i2c_dev , u32 val ,
unsigned long reg )
{
writel ( val , i2c_dev - > base + tegra_i2c_reg_addr ( i2c_dev , reg ) ) ;
2012-06-13 14:12:36 +04:00
/* Read back register to make sure that register writes completed */
if ( reg ! = I2C_TX_FIFO )
readl ( i2c_dev - > base + tegra_i2c_reg_addr ( i2c_dev , reg ) ) ;
2011-02-21 04:14:21 +03:00
}
static u32 i2c_readl ( struct tegra_i2c_dev * i2c_dev , unsigned long reg )
{
return readl ( i2c_dev - > base + tegra_i2c_reg_addr ( i2c_dev , reg ) ) ;
}
static void i2c_writesl ( struct tegra_i2c_dev * i2c_dev , void * data ,
unsigned long reg , int len )
{
writesl ( i2c_dev - > base + tegra_i2c_reg_addr ( i2c_dev , reg ) , data , len ) ;
}
static void i2c_readsl ( struct tegra_i2c_dev * i2c_dev , void * data ,
unsigned long reg , int len )
{
readsl ( i2c_dev - > base + tegra_i2c_reg_addr ( i2c_dev , reg ) , data , len ) ;
}
static void tegra_i2c_mask_irq ( struct tegra_i2c_dev * i2c_dev , u32 mask )
{
u32 int_mask = i2c_readl ( i2c_dev , I2C_INT_MASK ) ;
int_mask & = ~ mask ;
i2c_writel ( i2c_dev , int_mask , I2C_INT_MASK ) ;
}
static void tegra_i2c_unmask_irq ( struct tegra_i2c_dev * i2c_dev , u32 mask )
{
u32 int_mask = i2c_readl ( i2c_dev , I2C_INT_MASK ) ;
int_mask | = mask ;
i2c_writel ( i2c_dev , int_mask , I2C_INT_MASK ) ;
}
static int tegra_i2c_flush_fifos ( struct tegra_i2c_dev * i2c_dev )
{
unsigned long timeout = jiffies + HZ ;
u32 val = i2c_readl ( i2c_dev , I2C_FIFO_CONTROL ) ;
val | = I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH ;
i2c_writel ( i2c_dev , val , I2C_FIFO_CONTROL ) ;
while ( i2c_readl ( i2c_dev , I2C_FIFO_CONTROL ) &
( I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH ) ) {
if ( time_after ( jiffies , timeout ) ) {
dev_warn ( i2c_dev - > dev , " timeout waiting for fifo flush \n " ) ;
return - ETIMEDOUT ;
}
msleep ( 1 ) ;
}
return 0 ;
}
static int tegra_i2c_empty_rx_fifo ( struct tegra_i2c_dev * i2c_dev )
{
u32 val ;
int rx_fifo_avail ;
u8 * buf = i2c_dev - > msg_buf ;
size_t buf_remaining = i2c_dev - > msg_buf_remaining ;
int words_to_transfer ;
val = i2c_readl ( i2c_dev , I2C_FIFO_STATUS ) ;
rx_fifo_avail = ( val & I2C_FIFO_STATUS_RX_MASK ) > >
I2C_FIFO_STATUS_RX_SHIFT ;
/* Rounds down to not include partial word at the end of buf */
words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD ;
if ( words_to_transfer > rx_fifo_avail )
words_to_transfer = rx_fifo_avail ;
i2c_readsl ( i2c_dev , buf , I2C_RX_FIFO , words_to_transfer ) ;
buf + = words_to_transfer * BYTES_PER_FIFO_WORD ;
buf_remaining - = words_to_transfer * BYTES_PER_FIFO_WORD ;
rx_fifo_avail - = words_to_transfer ;
/*
* If there is a partial word at the end of buf , handle it manually to
* prevent overwriting past the end of buf
*/
if ( rx_fifo_avail > 0 & & buf_remaining > 0 ) {
BUG_ON ( buf_remaining > 3 ) ;
val = i2c_readl ( i2c_dev , I2C_RX_FIFO ) ;
memcpy ( buf , & val , buf_remaining ) ;
buf_remaining = 0 ;
rx_fifo_avail - - ;
}
BUG_ON ( rx_fifo_avail > 0 & & buf_remaining > 0 ) ;
i2c_dev - > msg_buf_remaining = buf_remaining ;
i2c_dev - > msg_buf = buf ;
return 0 ;
}
static int tegra_i2c_fill_tx_fifo ( struct tegra_i2c_dev * i2c_dev )
{
u32 val ;
int tx_fifo_avail ;
u8 * buf = i2c_dev - > msg_buf ;
size_t buf_remaining = i2c_dev - > msg_buf_remaining ;
int words_to_transfer ;
val = i2c_readl ( i2c_dev , I2C_FIFO_STATUS ) ;
tx_fifo_avail = ( val & I2C_FIFO_STATUS_TX_MASK ) > >
I2C_FIFO_STATUS_TX_SHIFT ;
/* Rounds down to not include partial word at the end of buf */
words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD ;
2011-08-30 21:46:10 +04:00
/* It's very common to have < 4 bytes, so optimize that case. */
if ( words_to_transfer ) {
if ( words_to_transfer > tx_fifo_avail )
words_to_transfer = tx_fifo_avail ;
/*
* Update state before writing to FIFO . If this casues us
* to finish writing all bytes ( AKA buf_remaining goes to 0 ) we
* have a potential for an interrupt ( PACKET_XFER_COMPLETE is
* not maskable ) . We need to make sure that the isr sees
* buf_remaining as 0 and doesn ' t call us back re - entrantly .
*/
buf_remaining - = words_to_transfer * BYTES_PER_FIFO_WORD ;
tx_fifo_avail - = words_to_transfer ;
i2c_dev - > msg_buf_remaining = buf_remaining ;
i2c_dev - > msg_buf = buf +
words_to_transfer * BYTES_PER_FIFO_WORD ;
barrier ( ) ;
i2c_writesl ( i2c_dev , buf , I2C_TX_FIFO , words_to_transfer ) ;
buf + = words_to_transfer * BYTES_PER_FIFO_WORD ;
}
2011-02-21 04:14:21 +03:00
/*
* If there is a partial word at the end of buf , handle it manually to
* prevent reading past the end of buf , which could cross a page
* boundary and fault .
*/
if ( tx_fifo_avail > 0 & & buf_remaining > 0 ) {
BUG_ON ( buf_remaining > 3 ) ;
memcpy ( & val , buf , buf_remaining ) ;
2011-08-30 21:46:10 +04:00
/* Again update before writing to FIFO to make sure isr sees. */
i2c_dev - > msg_buf_remaining = 0 ;
i2c_dev - > msg_buf = NULL ;
barrier ( ) ;
2011-02-21 04:14:21 +03:00
i2c_writel ( i2c_dev , val , I2C_TX_FIFO ) ;
}
return 0 ;
}
/*
* One of the Tegra I2C blocks is inside the DVC ( Digital Voltage Controller )
* block . This block is identical to the rest of the I2C blocks , except that
* it only supports master mode , it has registers moved around , and it needs
* some extra init to get it into I2C mode . The register moves are handled
* by i2c_readl and i2c_writel
*/
static void tegra_dvc_init ( struct tegra_i2c_dev * i2c_dev )
{
u32 val = 0 ;
val = dvc_readl ( i2c_dev , DVC_CTRL_REG3 ) ;
val | = DVC_CTRL_REG3_SW_PROG ;
val | = DVC_CTRL_REG3_I2C_DONE_INTR_EN ;
dvc_writel ( i2c_dev , val , DVC_CTRL_REG3 ) ;
val = dvc_readl ( i2c_dev , DVC_CTRL_REG1 ) ;
val | = DVC_CTRL_REG1_INTR_EN ;
dvc_writel ( i2c_dev , val , DVC_CTRL_REG1 ) ;
}
2012-08-18 23:17:47 +04:00
static inline int tegra_i2c_clock_enable ( struct tegra_i2c_dev * i2c_dev )
{
int ret ;
ret = clk_prepare_enable ( i2c_dev - > fast_clk ) ;
if ( ret < 0 ) {
dev_err ( i2c_dev - > dev ,
" Enabling fast clk failed, err %d \n " , ret ) ;
return ret ;
}
ret = clk_prepare_enable ( i2c_dev - > div_clk ) ;
if ( ret < 0 ) {
dev_err ( i2c_dev - > dev ,
" Enabling div clk failed, err %d \n " , ret ) ;
clk_disable_unprepare ( i2c_dev - > fast_clk ) ;
}
return ret ;
}
static inline void tegra_i2c_clock_disable ( struct tegra_i2c_dev * i2c_dev )
{
clk_disable_unprepare ( i2c_dev - > div_clk ) ;
clk_disable_unprepare ( i2c_dev - > fast_clk ) ;
}
2011-02-21 04:14:21 +03:00
static int tegra_i2c_init ( struct tegra_i2c_dev * i2c_dev )
{
u32 val ;
int err = 0 ;
2012-08-18 23:17:47 +04:00
tegra_i2c_clock_enable ( i2c_dev ) ;
2011-02-21 04:14:21 +03:00
2012-08-08 11:51:32 +04:00
tegra_periph_reset_assert ( i2c_dev - > div_clk ) ;
2011-02-21 04:14:21 +03:00
udelay ( 2 ) ;
2012-08-08 11:51:32 +04:00
tegra_periph_reset_deassert ( i2c_dev - > div_clk ) ;
2011-02-21 04:14:21 +03:00
if ( i2c_dev - > is_dvc )
tegra_dvc_init ( i2c_dev ) ;
2011-04-26 01:32:27 +04:00
val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
( 0x2 < < I2C_CNFG_DEBOUNCE_CNT_SHIFT ) ;
2011-02-21 04:14:21 +03:00
i2c_writel ( i2c_dev , val , I2C_CNFG ) ;
i2c_writel ( i2c_dev , 0 , I2C_INT_MASK ) ;
2012-08-08 11:51:32 +04:00
clk_set_rate ( i2c_dev - > div_clk , i2c_dev - > bus_clk_rate * 8 ) ;
2011-02-21 04:14:21 +03:00
2011-04-25 22:29:54 +04:00
if ( ! i2c_dev - > is_dvc ) {
u32 sl_cfg = i2c_readl ( i2c_dev , I2C_SL_CNFG ) ;
i2c: tegra: Assign unused slave address
On Tegra, we should always use the "new" I2C slave controller, to avoid
issues with the old controller. This was implemented in commit 65a1a0a
"i2c: tegra: Enable new slave mode."
There is currently no driver for the Tegra I2C slave controller upstream.
Additionally, the controller cannot be completely disabled. Instead, we
need to:
a) Set I2C_SL_CNFG_NACK to make the controller automatically NACK any
incoming transactions.
b) The controller's definition of NACK isn't identical to the I2C
protocol's definition. Specifically, it will perform a standard NACK, but
*also* continue to hold the clock line low in expectation of receiving
more data. This can hang the bus, or at least cause transaction timeouts,
if something starts a transaction that matches the controller's slave
address. Since the default address is 0x00, the general call address,
this does occur in practice.
To avoid this, we explicitly program a slave address that is reserved for
future expansion. For current boards, this guarantees the address will
never be used. If a future board ever needs to use this address, we can
add platform data to determine a board-specific safe address. 0xfc is
picked by this patch.
This patch is based on a change previously posted by: Wei Ni <wni@nvidia.com>
http://www.spinics.net/lists/linux-i2c/msg05437.html
In turned based on internal changes by: Bharat Nihalani <bnihalani@nvidia.com>
A semantically equivalent change has been contained in the various
ChromeOS kernels for a while.
I tested this change on top of 3.0-rc2 on Harmony, and interacted with
the WM8903 I2C-based audio codec.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
2011-06-06 21:25:19 +04:00
sl_cfg | = I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL ;
i2c_writel ( i2c_dev , sl_cfg , I2C_SL_CNFG ) ;
i2c_writel ( i2c_dev , 0xfc , I2C_SL_ADDR1 ) ;
i2c_writel ( i2c_dev , 0x00 , I2C_SL_ADDR2 ) ;
2011-04-25 22:29:54 +04:00
}
2011-02-21 04:14:21 +03:00
val = 7 < < I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
0 < < I2C_FIFO_CONTROL_RX_TRIG_SHIFT ;
i2c_writel ( i2c_dev , val , I2C_FIFO_CONTROL ) ;
if ( tegra_i2c_flush_fifos ( i2c_dev ) )
err = - ETIMEDOUT ;
2012-08-18 23:17:47 +04:00
tegra_i2c_clock_disable ( i2c_dev ) ;
2011-04-26 01:32:25 +04:00
if ( i2c_dev - > irq_disabled ) {
i2c_dev - > irq_disabled = 0 ;
enable_irq ( i2c_dev - > irq ) ;
}
2011-02-21 04:14:21 +03:00
return err ;
}
static irqreturn_t tegra_i2c_isr ( int irq , void * dev_id )
{
u32 status ;
const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST ;
struct tegra_i2c_dev * i2c_dev = dev_id ;
status = i2c_readl ( i2c_dev , I2C_INT_STATUS ) ;
if ( status = = 0 ) {
2011-04-26 01:32:25 +04:00
dev_warn ( i2c_dev - > dev , " irq status 0 %08x %08x %08x \n " ,
i2c_readl ( i2c_dev , I2C_PACKET_TRANSFER_STATUS ) ,
i2c_readl ( i2c_dev , I2C_STATUS ) ,
i2c_readl ( i2c_dev , I2C_CNFG ) ) ;
i2c_dev - > msg_err | = I2C_ERR_UNKNOWN_INTERRUPT ;
if ( ! i2c_dev - > irq_disabled ) {
disable_irq_nosync ( i2c_dev - > irq ) ;
i2c_dev - > irq_disabled = 1 ;
}
goto err ;
2011-02-21 04:14:21 +03:00
}
if ( unlikely ( status & status_err ) ) {
if ( status & I2C_INT_NO_ACK )
i2c_dev - > msg_err | = I2C_ERR_NO_ACK ;
if ( status & I2C_INT_ARBITRATION_LOST )
i2c_dev - > msg_err | = I2C_ERR_ARBITRATION_LOST ;
goto err ;
}
if ( i2c_dev - > msg_read & & ( status & I2C_INT_RX_FIFO_DATA_REQ ) ) {
if ( i2c_dev - > msg_buf_remaining )
tegra_i2c_empty_rx_fifo ( i2c_dev ) ;
else
BUG ( ) ;
}
if ( ! i2c_dev - > msg_read & & ( status & I2C_INT_TX_FIFO_DATA_REQ ) ) {
if ( i2c_dev - > msg_buf_remaining )
tegra_i2c_fill_tx_fifo ( i2c_dev ) ;
else
tegra_i2c_mask_irq ( i2c_dev , I2C_INT_TX_FIFO_DATA_REQ ) ;
}
2012-05-07 10:46:19 +04:00
i2c_writel ( i2c_dev , status , I2C_INT_STATUS ) ;
if ( i2c_dev - > is_dvc )
dvc_writel ( i2c_dev , DVC_STATUS_I2C_DONE_INTR , DVC_STATUS ) ;
2011-08-30 21:46:10 +04:00
if ( status & I2C_INT_PACKET_XFER_COMPLETE ) {
BUG_ON ( i2c_dev - > msg_buf_remaining ) ;
2011-02-21 04:14:21 +03:00
complete ( & i2c_dev - > msg_complete ) ;
2011-08-30 21:46:10 +04:00
}
2011-02-21 04:14:21 +03:00
return IRQ_HANDLED ;
err :
2011-03-31 05:57:33 +04:00
/* An error occurred, mask all interrupts */
2011-02-21 04:14:21 +03:00
tegra_i2c_mask_irq ( i2c_dev , I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
I2C_INT_RX_FIFO_DATA_REQ ) ;
i2c_writel ( i2c_dev , status , I2C_INT_STATUS ) ;
2011-04-26 01:32:25 +04:00
if ( i2c_dev - > is_dvc )
dvc_writel ( i2c_dev , DVC_STATUS_I2C_DONE_INTR , DVC_STATUS ) ;
2012-05-07 10:46:19 +04:00
complete ( & i2c_dev - > msg_complete ) ;
2011-02-21 04:14:21 +03:00
return IRQ_HANDLED ;
}
static int tegra_i2c_xfer_msg ( struct tegra_i2c_dev * i2c_dev ,
2012-06-13 14:12:38 +04:00
struct i2c_msg * msg , enum msg_end_type end_state )
2011-02-21 04:14:21 +03:00
{
u32 packet_header ;
u32 int_mask ;
int ret ;
tegra_i2c_flush_fifos ( i2c_dev ) ;
if ( msg - > len = = 0 )
return - EINVAL ;
i2c_dev - > msg_buf = msg - > buf ;
i2c_dev - > msg_buf_remaining = msg - > len ;
i2c_dev - > msg_err = I2C_ERR_NONE ;
i2c_dev - > msg_read = ( msg - > flags & I2C_M_RD ) ;
INIT_COMPLETION ( i2c_dev - > msg_complete ) ;
packet_header = ( 0 < < PACKET_HEADER0_HEADER_SIZE_SHIFT ) |
PACKET_HEADER0_PROTOCOL_I2C |
( i2c_dev - > cont_id < < PACKET_HEADER0_CONT_ID_SHIFT ) |
( 1 < < PACKET_HEADER0_PACKET_ID_SHIFT ) ;
i2c_writel ( i2c_dev , packet_header , I2C_TX_FIFO ) ;
packet_header = msg - > len - 1 ;
i2c_writel ( i2c_dev , packet_header , I2C_TX_FIFO ) ;
2012-04-24 11:19:35 +04:00
packet_header = I2C_HEADER_IE_ENABLE ;
2012-06-13 14:12:38 +04:00
if ( end_state = = MSG_END_CONTINUE )
packet_header | = I2C_HEADER_CONTINUE_XFER ;
else if ( end_state = = MSG_END_REPEAT_START )
2011-04-26 01:32:26 +04:00
packet_header | = I2C_HEADER_REPEAT_START ;
2012-04-24 11:19:35 +04:00
if ( msg - > flags & I2C_M_TEN ) {
packet_header | = msg - > addr ;
2011-02-21 04:14:21 +03:00
packet_header | = I2C_HEADER_10BIT_ADDR ;
2012-04-24 11:19:35 +04:00
} else {
packet_header | = msg - > addr < < I2C_HEADER_SLAVE_ADDR_SHIFT ;
}
2011-02-21 04:14:21 +03:00
if ( msg - > flags & I2C_M_IGNORE_NAK )
packet_header | = I2C_HEADER_CONT_ON_NAK ;
if ( msg - > flags & I2C_M_RD )
packet_header | = I2C_HEADER_READ ;
i2c_writel ( i2c_dev , packet_header , I2C_TX_FIFO ) ;
if ( ! ( msg - > flags & I2C_M_RD ) )
tegra_i2c_fill_tx_fifo ( i2c_dev ) ;
int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST ;
if ( msg - > flags & I2C_M_RD )
int_mask | = I2C_INT_RX_FIFO_DATA_REQ ;
else if ( i2c_dev - > msg_buf_remaining )
int_mask | = I2C_INT_TX_FIFO_DATA_REQ ;
tegra_i2c_unmask_irq ( i2c_dev , int_mask ) ;
dev_dbg ( i2c_dev - > dev , " unmasked irq: %02x \n " ,
i2c_readl ( i2c_dev , I2C_INT_MASK ) ) ;
ret = wait_for_completion_timeout ( & i2c_dev - > msg_complete , TEGRA_I2C_TIMEOUT ) ;
tegra_i2c_mask_irq ( i2c_dev , int_mask ) ;
if ( WARN_ON ( ret = = 0 ) ) {
dev_err ( i2c_dev - > dev , " i2c transfer timed out \n " ) ;
tegra_i2c_init ( i2c_dev ) ;
return - ETIMEDOUT ;
}
dev_dbg ( i2c_dev - > dev , " transfer complete: %d %d %d \n " ,
ret , completion_done ( & i2c_dev - > msg_complete ) , i2c_dev - > msg_err ) ;
if ( likely ( i2c_dev - > msg_err = = I2C_ERR_NONE ) )
return 0 ;
2012-04-02 09:53:02 +04:00
/*
* NACK interrupt is generated before the I2C controller generates the
* STOP condition on the bus . So wait for 2 clock periods before resetting
* the controller so that STOP condition has been delivered properly .
*/
if ( i2c_dev - > msg_err = = I2C_ERR_NO_ACK )
udelay ( DIV_ROUND_UP ( 2 * 1000000 , i2c_dev - > bus_clk_rate ) ) ;
2011-02-21 04:14:21 +03:00
tegra_i2c_init ( i2c_dev ) ;
if ( i2c_dev - > msg_err = = I2C_ERR_NO_ACK ) {
if ( msg - > flags & I2C_M_IGNORE_NAK )
return 0 ;
return - EREMOTEIO ;
}
return - EIO ;
}
static int tegra_i2c_xfer ( struct i2c_adapter * adap , struct i2c_msg msgs [ ] ,
int num )
{
struct tegra_i2c_dev * i2c_dev = i2c_get_adapdata ( adap ) ;
int i ;
int ret = 0 ;
if ( i2c_dev - > is_suspended )
return - EBUSY ;
2012-08-18 23:17:47 +04:00
tegra_i2c_clock_enable ( i2c_dev ) ;
2011-02-21 04:14:21 +03:00
for ( i = 0 ; i < num ; i + + ) {
2012-06-13 14:12:38 +04:00
enum msg_end_type end_type = MSG_END_STOP ;
if ( i < ( num - 1 ) ) {
if ( msgs [ i + 1 ] . flags & I2C_M_NOSTART )
end_type = MSG_END_CONTINUE ;
else
end_type = MSG_END_REPEAT_START ;
}
ret = tegra_i2c_xfer_msg ( i2c_dev , & msgs [ i ] , end_type ) ;
2011-02-21 04:14:21 +03:00
if ( ret )
break ;
}
2012-08-18 23:17:47 +04:00
tegra_i2c_clock_disable ( i2c_dev ) ;
2011-02-21 04:14:21 +03:00
return ret ? : i ;
}
static u32 tegra_i2c_func ( struct i2c_adapter * adap )
{
2012-08-18 23:17:46 +04:00
struct tegra_i2c_dev * i2c_dev = i2c_get_adapdata ( adap ) ;
u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
I2C_FUNC_PROTOCOL_MANGLING ;
if ( i2c_dev - > hw - > has_continue_xfer_support )
ret | = I2C_FUNC_NOSTART ;
return ret ;
2011-02-21 04:14:21 +03:00
}
static const struct i2c_algorithm tegra_i2c_algo = {
. master_xfer = tegra_i2c_xfer ,
. functionality = tegra_i2c_func ,
} ;
2012-08-18 23:17:46 +04:00
static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
. has_continue_xfer_support = false ,
} ;
static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
. has_continue_xfer_support = true ,
} ;
# if defined(CONFIG_OF)
/* Match table for of_platform binding */
static const struct of_device_id tegra_i2c_of_match [ ] __devinitconst = {
{ . compatible = " nvidia,tegra30-i2c " , . data = & tegra30_i2c_hw , } ,
{ . compatible = " nvidia,tegra20-i2c " , . data = & tegra20_i2c_hw , } ,
{ . compatible = " nvidia,tegra20-i2c-dvc " , . data = & tegra20_i2c_hw , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , tegra_i2c_of_match ) ;
# endif
2011-12-18 10:29:29 +04:00
static int __devinit tegra_i2c_probe ( struct platform_device * pdev )
2011-02-21 04:14:21 +03:00
{
struct tegra_i2c_dev * i2c_dev ;
struct tegra_i2c_platform_data * pdata = pdev - > dev . platform_data ;
struct resource * res ;
2012-08-08 11:51:32 +04:00
struct clk * div_clk ;
struct clk * fast_clk ;
2011-06-22 20:16:56 +04:00
const unsigned int * prop ;
2011-10-13 04:33:00 +04:00
void __iomem * base ;
2011-02-21 04:14:21 +03:00
int irq ;
int ret = 0 ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
if ( ! res ) {
dev_err ( & pdev - > dev , " no mem resource \n " ) ;
return - EINVAL ;
}
2012-06-13 14:12:39 +04:00
base = devm_request_and_ioremap ( & pdev - > dev , res ) ;
2011-02-21 04:14:21 +03:00
if ( ! base ) {
2012-06-13 14:12:39 +04:00
dev_err ( & pdev - > dev , " Cannot request/ioremap I2C registers \n " ) ;
return - EADDRNOTAVAIL ;
2011-02-21 04:14:21 +03:00
}
res = platform_get_resource ( pdev , IORESOURCE_IRQ , 0 ) ;
if ( ! res ) {
dev_err ( & pdev - > dev , " no irq resource \n " ) ;
2012-06-13 14:12:39 +04:00
return - EINVAL ;
2011-02-21 04:14:21 +03:00
}
irq = res - > start ;
2012-08-08 11:51:32 +04:00
div_clk = devm_clk_get ( & pdev - > dev , " div-clk " ) ;
if ( IS_ERR ( div_clk ) ) {
2011-02-21 04:14:21 +03:00
dev_err ( & pdev - > dev , " missing controller clock " ) ;
2012-08-08 11:51:32 +04:00
return PTR_ERR ( div_clk ) ;
2011-02-21 04:14:21 +03:00
}
2012-08-08 11:51:32 +04:00
fast_clk = devm_clk_get ( & pdev - > dev , " fast-clk " ) ;
if ( IS_ERR ( fast_clk ) ) {
2011-02-21 04:14:21 +03:00
dev_err ( & pdev - > dev , " missing bus clock " ) ;
2012-08-08 11:51:32 +04:00
return PTR_ERR ( fast_clk ) ;
2011-02-21 04:14:21 +03:00
}
2012-06-13 14:12:39 +04:00
i2c_dev = devm_kzalloc ( & pdev - > dev , sizeof ( * i2c_dev ) , GFP_KERNEL ) ;
2011-02-21 04:14:21 +03:00
if ( ! i2c_dev ) {
2012-06-13 14:12:39 +04:00
dev_err ( & pdev - > dev , " Could not allocate struct tegra_i2c_dev " ) ;
return - ENOMEM ;
2011-02-21 04:14:21 +03:00
}
i2c_dev - > base = base ;
2012-08-08 11:51:32 +04:00
i2c_dev - > div_clk = div_clk ;
i2c_dev - > fast_clk = fast_clk ;
2011-02-21 04:14:21 +03:00
i2c_dev - > adapter . algo = & tegra_i2c_algo ;
i2c_dev - > irq = irq ;
i2c_dev - > cont_id = pdev - > id ;
i2c_dev - > dev = & pdev - > dev ;
2011-06-22 20:16:56 +04:00
i2c_dev - > bus_clk_rate = 100000 ; /* default clock rate */
if ( pdata ) {
i2c_dev - > bus_clk_rate = pdata - > bus_clk_rate ;
} else if ( i2c_dev - > dev - > of_node ) { /* if there is a device tree node ... */
prop = of_get_property ( i2c_dev - > dev - > of_node ,
" clock-frequency " , NULL ) ;
if ( prop )
i2c_dev - > bus_clk_rate = be32_to_cpup ( prop ) ;
}
2011-02-21 04:14:21 +03:00
2012-08-18 23:17:46 +04:00
i2c_dev - > hw = & tegra20_i2c_hw ;
if ( pdev - > dev . of_node ) {
const struct of_device_id * match ;
match = of_match_device ( of_match_ptr ( tegra_i2c_of_match ) ,
& pdev - > dev ) ;
i2c_dev - > hw = match - > data ;
2011-12-18 10:29:30 +04:00
i2c_dev - > is_dvc = of_device_is_compatible ( pdev - > dev . of_node ,
" nvidia,tegra20-i2c-dvc " ) ;
2012-08-18 23:17:46 +04:00
} else if ( pdev - > id = = 3 ) {
2011-02-21 04:14:21 +03:00
i2c_dev - > is_dvc = 1 ;
2012-08-18 23:17:46 +04:00
}
2011-02-21 04:14:21 +03:00
init_completion ( & i2c_dev - > msg_complete ) ;
platform_set_drvdata ( pdev , i2c_dev ) ;
ret = tegra_i2c_init ( i2c_dev ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to initialize i2c controller " ) ;
2012-06-13 14:12:39 +04:00
return ret ;
2011-02-21 04:14:21 +03:00
}
2012-06-13 14:12:39 +04:00
ret = devm_request_irq ( & pdev - > dev , i2c_dev - > irq ,
2012-11-01 20:38:14 +04:00
tegra_i2c_isr , 0 , dev_name ( & pdev - > dev ) , i2c_dev ) ;
2011-02-21 04:14:21 +03:00
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to request irq %i \n " , i2c_dev - > irq ) ;
2012-06-13 14:12:39 +04:00
return ret ;
2011-02-21 04:14:21 +03:00
}
i2c_set_adapdata ( & i2c_dev - > adapter , i2c_dev ) ;
i2c_dev - > adapter . owner = THIS_MODULE ;
i2c_dev - > adapter . class = I2C_CLASS_HWMON ;
strlcpy ( i2c_dev - > adapter . name , " Tegra I2C adapter " ,
sizeof ( i2c_dev - > adapter . name ) ) ;
i2c_dev - > adapter . algo = & tegra_i2c_algo ;
i2c_dev - > adapter . dev . parent = & pdev - > dev ;
i2c_dev - > adapter . nr = pdev - > id ;
2011-06-22 20:16:56 +04:00
i2c_dev - > adapter . dev . of_node = pdev - > dev . of_node ;
2011-02-21 04:14:21 +03:00
ret = i2c_add_numbered_adapter ( & i2c_dev - > adapter ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to add I2C adapter \n " ) ;
2012-06-13 14:12:39 +04:00
return ret ;
2011-02-21 04:14:21 +03:00
}
2011-06-22 20:16:56 +04:00
of_i2c_register_devices ( & i2c_dev - > adapter ) ;
2011-02-21 04:14:21 +03:00
return 0 ;
}
2011-12-18 10:29:29 +04:00
static int __devexit tegra_i2c_remove ( struct platform_device * pdev )
2011-02-21 04:14:21 +03:00
{
struct tegra_i2c_dev * i2c_dev = platform_get_drvdata ( pdev ) ;
i2c_del_adapter ( & i2c_dev - > adapter ) ;
return 0 ;
}
2012-08-18 16:19:58 +04:00
# ifdef CONFIG_PM_SLEEP
2012-07-24 19:32:45 +04:00
static int tegra_i2c_suspend ( struct device * dev )
2011-02-21 04:14:21 +03:00
{
2012-07-11 23:27:30 +04:00
struct tegra_i2c_dev * i2c_dev = dev_get_drvdata ( dev ) ;
2011-02-21 04:14:21 +03:00
i2c_lock_adapter ( & i2c_dev - > adapter ) ;
i2c_dev - > is_suspended = true ;
i2c_unlock_adapter ( & i2c_dev - > adapter ) ;
return 0 ;
}
2012-07-24 19:32:45 +04:00
static int tegra_i2c_resume ( struct device * dev )
2011-02-21 04:14:21 +03:00
{
2012-07-11 23:27:30 +04:00
struct tegra_i2c_dev * i2c_dev = dev_get_drvdata ( dev ) ;
2011-02-21 04:14:21 +03:00
int ret ;
i2c_lock_adapter ( & i2c_dev - > adapter ) ;
ret = tegra_i2c_init ( i2c_dev ) ;
if ( ret ) {
i2c_unlock_adapter ( & i2c_dev - > adapter ) ;
return ret ;
}
i2c_dev - > is_suspended = false ;
i2c_unlock_adapter ( & i2c_dev - > adapter ) ;
return 0 ;
}
2012-07-11 23:27:30 +04:00
2012-07-24 19:32:45 +04:00
static SIMPLE_DEV_PM_OPS ( tegra_i2c_pm , tegra_i2c_suspend , tegra_i2c_resume ) ;
2012-07-11 23:27:30 +04:00
# define TEGRA_I2C_PM (&tegra_i2c_pm)
# else
# define TEGRA_I2C_PM NULL
2011-02-21 04:14:21 +03:00
# endif
static struct platform_driver tegra_i2c_driver = {
. probe = tegra_i2c_probe ,
2011-12-20 10:15:08 +04:00
. remove = __devexit_p ( tegra_i2c_remove ) ,
2011-02-21 04:14:21 +03:00
. driver = {
. name = " tegra-i2c " ,
. owner = THIS_MODULE ,
2012-07-10 15:20:42 +04:00
. of_match_table = of_match_ptr ( tegra_i2c_of_match ) ,
2012-07-11 23:27:30 +04:00
. pm = TEGRA_I2C_PM ,
2011-02-21 04:14:21 +03:00
} ,
} ;
static int __init tegra_i2c_init_driver ( void )
{
return platform_driver_register ( & tegra_i2c_driver ) ;
}
static void __exit tegra_i2c_exit_driver ( void )
{
platform_driver_unregister ( & tegra_i2c_driver ) ;
}
subsys_initcall ( tegra_i2c_init_driver ) ;
module_exit ( tegra_i2c_exit_driver ) ;
MODULE_DESCRIPTION ( " nVidia Tegra2 I2C Bus Controller driver " ) ;
MODULE_AUTHOR ( " Colin Cross " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;