diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-i2c.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-i2c.patch | 3435 |
1 files changed, 0 insertions, 3435 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-i2c.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-i2c.patch deleted file mode 100644 index e6f6f675d..000000000 --- a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-i2c.patch +++ /dev/null @@ -1,3435 +0,0 @@ - - -From: Masayuki Ohtake <masa-korg@dsn.okisemi.com> -Subject: OKI Semiconductor PCH I2C driver - -This driver implements I2C controls for PCH. - -Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com> -Acked-by: Wang Qi <qi.wang@intel.com> - ---- - drivers/i2c/busses/Kconfig | 7 + - drivers/i2c/busses/Makefile | 3 - drivers/i2c/busses/pch_common.h | 146 - drivers/i2c/busses/pch_debug.h | 60 - drivers/i2c/busses/pch_i2c_hal.c | 1930 - drivers/i2c/busses/pch_i2c_hal.h | 337 - drivers/i2c/busses/pch_i2c_main.c | 247 - drivers/i2c/busses/pch_i2c_pci.c | 583 - drivers/i2c/i2c-dev.c | 28 -+++++++++++++++++++++++++++++++ 9 files changed, yy insertions(+) -diff -urN linux-2.6.33.1/drivers/i2c/busses/Kconfig topcliff-2.6.33.1/drivers/i2c/busses/Kconfig ---- linux-2.6.33.1/drivers/i2c/busses/Kconfig 2010-03-16 01:09:39.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/Kconfig 2010-03-23 10:40:18.000000000 +0900 -@@ -7,6 +7,13 @@ - comment "PC SMBus host controller drivers" - depends on PCI - -+config PCH_I2C -+ tristate "PCH I2C" -+ depends on PCI -+ help -+ If you say yes to this option, support will be included for the SMB -+ PCH I2C Host controller. -+ - config I2C_ALI1535 - tristate "ALI 1535" - depends on PCI -diff -urN linux-2.6.33.1/drivers/i2c/busses/Makefile topcliff-2.6.33.1/drivers/i2c/busses/Makefile ---- linux-2.6.33.1/drivers/i2c/busses/Makefile 2010-03-16 01:09:39.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/Makefile 2010-03-23 10:40:18.000000000 +0900 -@@ -75,3 +75,6 @@ - ifeq ($(CONFIG_I2C_DEBUG_BUS),y) - EXTRA_CFLAGS += -DDEBUG - endif -+ -+obj-$(CONFIG_PCH_I2C) += pch_i2c.o -+pch_i2c-objs := pch_i2c_main.o pch_i2c_pci.o pch_i2c_hal.o -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_common.h topcliff-2.6.33.1/drivers/i2c/busses/pch_common.h ---- linux-2.6.33.1/drivers/i2c/busses/pch_common.h 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_common.h 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,146 @@ -+/*! -+ * @file ioh_common.h -+ * @brief Provides the macro definitions used by all files. -+ * @version 1.0.0.0 -+ * @section -+ * 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; version 2 of the License. -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* -+ * History: -+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+ * All rights reserved. -+ * -+ * created: -+ * WIPRO 03/07/2009 -+ * modified: -+ * WIPRO 05/08/2009 -+ * -+ */ -+ -+#ifndef __IOH_COMMON_H__ -+#define __IOH_COMMON_H__ -+ -+/*! @ingroup Global -+@def IOH_WRITE8 -+@brief Macro for writing 8 bit data to an io/mem address -+*/ -+#define IOH_WRITE8(val, addr) iowrite8((val), (void __iomem *)(addr)) -+/*! @ingroup Global -+@def IOH_LOG -+@brief Macro for writing 16 bit data to an io/mem address -+*/ -+#define IOH_WRITE16(val, addr) iowrite16((val), (void __iomem *)(addr)) -+/*! @ingroup Global -+@def IOH_LOG -+@brief Macro for writing 32 bit data to an io/mem address -+*/ -+#define IOH_WRITE32(val, addr) iowrite32((val), (void __iomem *)(addr)) -+ -+/*! @ingroup Global -+@def IOH_READ8 -+@brief Macro for reading 8 bit data from an io/mem address -+*/ -+#define IOH_READ8(addr) ioread8((void __iomem *)(addr)) -+/*! @ingroup Global -+@def IOH_READ16 -+@brief Macro for reading 16 bit data from an io/mem address -+*/ -+#define IOH_READ16(addr) ioread16((void __iomem *)(addr)) -+/*! @ingroup Global -+@def IOH_READ32 -+@brief Macro for reading 32 bit data from an io/mem address -+*/ -+#define IOH_READ32(addr) ioread32((void __iomem *)(addr)) -+/*! @ingroup Global -+@def IOH_WRITE32_F -+@brief Macro for writing 32 bit data to an io/mem address -+*/ -+#define IOH_WRITE32_F(val, addr) do \ -+ { IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0); -+ -+/*! @ingroup Global -+@def IOH_WRITE_BYTE -+@brief Macro for writing 1 byte data to an io/mem address -+*/ -+#define IOH_WRITE_BYTE IOH_WRITE8 -+/*! @ingroup Global -+@def IOH_WRITE_WORD -+@brief Macro for writing 1 word data to an io/mem address -+*/ -+#define IOH_WRITE_WORD IOH_WRITE16 -+/*! @ingroup Global -+@def IOH_WRITE_LONG -+@brief Macro for writing long data to an io/mem address -+*/ -+#define IOH_WRITE_LONG IOH_WRITE32 -+ -+/*! @ingroup Global -+@def IOH_READ_BYTE -+@brief Macro for reading 1 byte data from an io/mem address -+*/ -+#define IOH_READ_BYTE IOH_READ8 -+/*! @ingroup Global -+@def IOH_READ_WORD -+@brief Macro for reading 1 word data from an io/mem address -+*/ -+#define IOH_READ_WORD IOH_READ16 -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief Macro for reading long data from an io/mem address -+*/ -+#define IOH_READ_LONG IOH_READ32 -+ -+/* Bit Manipulation Macros */ -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to set a specified bit(mask) at the -+ specified address -+*/ -+#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\ -+ (bitmask)), (addr)) -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to clear a specified bit(mask) at the specified address -+*/ -+#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\ -+ ~(bitmask)), (addr)) -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to set a specified bitmask for a variable -+*/ -+#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask)) -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to clear a specified bitmask for a variable -+*/ -+#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask))) -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to set a specified bit for a variable -+*/ -+#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit))) -+ -+/*! @ingroup Global -+@def IOH_READ_LONG -+@brief macro to clear a specified bit for a variable -+*/ -+#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit))) -+ -+#endif -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_debug.h topcliff-2.6.33.1/drivers/i2c/busses/pch_debug.h ---- linux-2.6.33.1/drivers/i2c/busses/pch_debug.h 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_debug.h 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,60 @@ -+/*! -+ * @file ioh_debug.h -+ * @brief Provides the macro definitions used for debugging. -+ * @version 1.0.0.0 -+ * @section -+ * 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; version 2 of the License. -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* -+ * History: -+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+ * All rights reserved. -+ * -+ * created: -+ * WIPRO 03/07/2009 -+ * modified: -+ * WIPRO 05/08/2009 -+ * -+ */ -+ -+#ifndef __IOH_DEBUG_H__ -+#define __IOH_DEBUG_H__ -+ -+#ifdef MODULE -+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\ -+ THIS_MODULE->name, ##args) -+#else -+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\ -+ __FILE__, ##args) -+#endif -+ -+ -+#ifdef DEBUG -+ #define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args) -+#else -+ #define IOH_DEBUG(fmt, args...) -+#endif -+ -+#ifdef IOH_TRACE_ENABLED -+ #define IOH_TRACE IOH_DEBUG -+#else -+ #define IOH_TRACE(fmt, args...) -+#endif -+ -+#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__) -+#define IOH_TRACE_EXIT IOH_TRACE("Exit %s", __func__) -+ -+ -+#endif -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.c topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.c ---- linux-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.c 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.c 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,1930 @@ -+/*! -+* @file ioh_i2c_hal.c -+* @brief This file contains definitions of HAL Layer APIs and -+* Internal functions -+* @version 0.95 -+* @section -+* 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; version 2 of the License. -+* -+* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+*/ -+ -+/* -+* History: -+* Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+* All rights reserved. -+* -+* created: -+* WIPRO 02/20/2009 -+* modified: -+* WIPRO 05/21/2009 -+* -+*/ -+ -+/*includes*/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/i2c.h> -+#include <linux/fs.h> -+#include <linux/io.h> -+#include <linux/types.h> -+#include <linux/interrupt.h> -+#include <linux/jiffies.h> -+ -+#include "pch_i2c_hal.h" -+#include "pch_common.h" -+#include "pch_debug.h" -+ -+/** -+ *macro definition -+ */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CSADR -+@brief I2CSADR register offset -+*/ -+#define IOH_I2CSADR (0x00) /* I2C slave address register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CCTL -+@brief I2CCTL register offset -+*/ -+#define IOH_I2CCTL (0x04) /* I2C control register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CSR -+@brief I2CSR register offset -+*/ -+#define IOH_I2CSR (0x08) /* I2C status register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CDR -+@brief I2CDR register offset -+*/ -+#define IOH_I2CDR (0x0C) /* I2C data register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CMON -+@brief I2CMON register offset -+*/ -+#define IOH_I2CMON (0x10) /* I2C bus monitor register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBC -+@brief I2CBC register offset -+*/ -+#define IOH_I2CBC (0x14) /* I2C bus transfer rate setup counter */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CMOD -+@brief I2CMOD register offset -+*/ -+#define IOH_I2CMOD (0x18) /* I2C mode register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFSLV -+@brief I2CBUFSLV register offset -+*/ -+#define IOH_I2CBUFSLV (0x1C) /* I2C buffer mode slave address register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFSUB -+@brief I2CBUFSUB register offset -+*/ -+#define IOH_I2CBUFSUB (0x20) /* I2C buffer mode subaddress register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFFOR -+@brief I2CBUFFOR register offset -+*/ -+#define IOH_I2CBUFFOR (0x24) /* I2C buffer mode format register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFCTL -+@brief I2CBUFCTL register offset -+*/ -+#define IOH_I2CBUFCTL (0x28) /* I2C buffer mode control register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFMSK -+@brief I2CBUFMSK register offset -+*/ -+#define IOH_I2CBUFMSK (0x2C) /* I2C buffer mode interrupt mask register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFSTA -+@brief I2CBUFSTA register offset -+*/ -+#define IOH_I2CBUFSTA (0x30) /* I2C buffer mode status register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CBUFLEV -+@brief I2CBUFLEV register offset -+*/ -+#define IOH_I2CBUFLEV (0x34) /* I2C buffer mode level register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CESRFOR -+@brief I2CESRFOR register offset -+*/ -+#define IOH_I2CESRFOR (0x38) /* EEPROM software reset mode format register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CESRCTL -+@brief I2CESRCTL register offset -+*/ -+#define IOH_I2CESRCTL (0x3C) /* EEPROM software reset mode control register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CESRMSK -+@brief I2CESRMSK register offset -+*/ -+#define IOH_I2CESRMSK (0x40) /* EEPROM software reset mode -+ * interrupt mask register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CESRSTA -+@brief I2CESRSTA register offset -+*/ -+#define IOH_I2CESRSTA (0x44) /* EEPROM software reset mode status register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CTMR -+@brief I2CTMR register offset -+*/ -+#define IOH_I2CTMR (0x48) /* I2C timer register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CSRST -+@brief I2CSRST register offset -+*/ -+#define IOH_I2CSRST (0xFC) /* I2C reset register */ -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CNF -+@brief I2CNF register offset -+*/ -+#define IOH_I2CNF (0xF8) /* I2C noise filter register */ -+ -+/*! @ingroup I2C_HALLayer -+@def BUS_IDLE_TIMEOUT -+@brief Time out value when waiting for Bus Idle -+*/ -+#define BUS_IDLE_TIMEOUT (20) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_I2CCTL_I2CMEN -+@brief Bitmask to enable I2CMEN bit -+*/ -+#define IOH_I2CCTL_I2CMEN (0x0080) -+ -+/*! @ingroup I2C_HALLayer -+@def TEN_BIT_ADDR_DEFAULT -+@brief Default bits to be added for 10 bit addressing -+*/ -+#define TEN_BIT_ADDR_DEFAULT (0xF000) -+ -+/*! @ingroup I2C_HALLayer -+@def TEN_BIT_ADDR_MASK -+@brief 10 bit address mask -+*/ -+#define TEN_BIT_ADDR_MASK (0xF0) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_START -+@brief Set the start bit in Normal mode -+*/ -+#define IOH_START (0x0020) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_ESR_START -+@brief Bitmask to set Start bit in EEPROM Software Reset mode -+*/ -+#define IOH_ESR_START (0x0001) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_BUFF_START -+@brief Bitmask to set Start bit in Buffer mode -+*/ -+#define IOH_BUFF_START (0x1) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_REPSTART -+@brief Bitmask to set repeated start bit -+*/ -+#define IOH_REPSTART (0x0004) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_ACK -+@brief Ack bit position in I2CCTL register -+*/ -+#define IOH_ACK (0x0008) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_GETACK -+@brief Mask to extract the ack bit -+*/ -+#define IOH_GETACK (0x0001) -+ -+/*! @ingroup I2C_HALLayer -+@def CLR_REG -+@brief Mask for register reset -+*/ -+#define CLR_REG (0x0) -+/*! @ingroup I2C_HALLayer -+@def I2C_RD -+@brief Set read bit in I2CDR with slave address -+*/ -+#define I2C_RD (0x1) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMCF_BIT -+@brief Mask for I2CMCF bit -+*/ -+#define I2CMCF_BIT (0x0080) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMIF_BIT -+@brief Mask for I2CMIF bit -+*/ -+#define I2CMIF_BIT (0x0002) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMAL_BIT -+@brief Mask for I2CMAL bit -+*/ -+#define I2CMAL_BIT (0x0010) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMFI_BIT -+@brief Mask for I2CBMFI bit -+*/ -+#define I2CBMFI_BIT (0x0001) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMAL_BIT -+@brief Mask for I2CBMAL bit -+*/ -+#define I2CBMAL_BIT (0x0002) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMNA_BIT -+@brief Mask for I2CBMNA bit -+*/ -+#define I2CBMNA_BIT (0x0004) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMTO_BIT -+@brief Mask for I2CBMTO bit -+*/ -+#define I2CBMTO_BIT (0x0008) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMIS_BIT -+@brief Mask for I2CBMIS bit -+*/ -+#define I2CBMIS_BIT (0x0010) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRFI_BIT -+@brief Mask for I2CESRFI bit -+*/ -+#define I2CESRFI_BIT (0X0001) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRTO_BIT -+@brief Mask for I2CESRTO bit -+*/ -+#define I2CESRTO_BIT (0x0002) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRFIIE_BIT -+@brief Mask for I2CESRFIIE bit -+*/ -+#define I2CESRFIIE_BIT (0x1) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRTOIE_BIT -+@brief Mask for I2CESRTOIE bit -+*/ -+#define I2CESRTOIE_BIT (0x2) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMDZ_BIT -+@brief Mask for I2CBMDZ bit -+*/ -+#define I2CBMDZ_BIT (0x0040) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMAG_BIT -+@brief Mask for I2CBMAG bit -+*/ -+#define I2CBMAG_BIT (0x0020) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMBB_BIT -+@brief Mask for I2CMBB bit -+*/ -+#define I2CMBB_BIT (0x0020) -+ -+/*! @ingroup I2C_HALLayer -+@def BUFFER_MODE_MASK -+@brief Status bit mask in buffer mode -+*/ -+#define BUFFER_MODE_MASK (I2CBMFI_BIT | I2CBMAL_BIT | I2CBMNA_BIT | \ -+ I2CBMTO_BIT | I2CBMIS_BIT) -+ -+/*! @ingroup I2C_HALLayer -+@def I2C_ADDR_MSK -+@brief Mask to get the 8 LSB bits in 10 bit addressing -+*/ -+#define I2C_ADDR_MSK (0xFF) -+ -+/*! @ingroup I2C_HALLayer -+@def I2C_MSB_2B_MSK -+@brief Mask to get the 2 MSB bits in 10 bit addressing -+*/ -+#define I2C_MSB_2B_MSK (0x300) -+ -+/*! @ingroup I2C_HALLayer -+@def FAST_MODE_CLK -+@brief Fast mode clock in KHz -+*/ -+#define FAST_MODE_CLK (400) -+ -+/*! @ingroup I2C_HALLayer -+@def FAST_MODE_EN -+@brief Enable the fast mode -+*/ -+#define FAST_MODE_EN (0x0001) -+ -+/*! @ingroup I2C_HALLayer -+@def SUB_ADDR_LEN_MAX -+@brief Maximum sub address length -+*/ -+#define SUB_ADDR_LEN_MAX (4) -+ -+/*! @ingroup I2C_HALLayer -+@def BUF_LEN_MAX -+@brief Maximum buffer length in buffer mode -+*/ -+#define BUF_LEN_MAX (32) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_BUFFER_MODE -+@brief To enable the buffer mode -+*/ -+#define IOH_BUFFER_MODE (0x1) -+ -+/*! @ingroup I2C_HALLayer -+@def EEPROM_SW_RST_MODE -+@brief Mask to enable the EEPROM Software Reset mode -+*/ -+#define EEPROM_SW_RST_MODE (0x0002) -+ -+/*! @ingroup I2C_HALLayer -+@def NORMAL_INTR_ENBL -+@brief Mask to enable the I2C interrupts in normal mode -+*/ -+#define NORMAL_INTR_ENBL (0x0300) -+ -+/*! @ingroup I2C_HALLayer -+@def EEPROM_RST_INTR_ENBL -+@brief Mask to enable I2CESRFI, I2CESRTO interrupts -+ in EEPROM Software Reset mode -+*/ -+#define EEPROM_RST_INTR_ENBL (I2CESRFIIE_BIT | I2CESRTOIE_BIT) -+ -+/*! @ingroup I2C_HALLayer -+@def EEPROM_RST_INTR_DISBL -+@brief Mask to disable interrupts in EEPROM Software Reset mode -+*/ -+#define EEPROM_RST_INTR_DISBL (0x0) -+ -+/*! @ingroup I2C_HALLayer -+@def BUFFER_MODE_INTR_ENBL -+@brief Mask to enable I2CBMIS,I2CBMTO,I2CBMNA,I2CBMAL,I2CBMFI -+ interrupts in Buffer mode -+*/ -+#define BUFFER_MODE_INTR_ENBL (0x001F) -+ -+/*! @ingroup I2C_HALLayer -+@def BUFFER_MODE_INTR_DISBL -+@brief Mask to disable all interrupts in Buffer mode -+*/ -+#define BUFFER_MODE_INTR_DISBL (0x0) -+ -+/*! @ingroup I2C_HALLayer -+@def NORMAL_MODE -+@brief Specifies Normal mode -+*/ -+#define NORMAL_MODE (0x0) -+ -+/*! @ingroup I2C_HALLayer -+@def BUFFER_MODE -+@brief Specifies Buffer mode -+*/ -+#define BUFFER_MODE (0x1) -+ -+/*! @ingroup I2C_HALLayer -+@def EEPROM_SR_MODE -+@brief Specifies EEPROM software reset mode -+*/ -+#define EEPROM_SR_MODE (0x2) -+ -+/*! @ingroup I2C_HALLayer -+@def I2C_TX_MODE -+@brief Specifies Master transmission mode -+*/ -+#define I2C_TX_MODE (0x0010) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_BUF_TX -+@brief Specifies Buffer transmission mode -+*/ -+#define IOH_BUF_TX (0xFFF7) -+ -+/*! @ingroup I2C_HALLayer -+@def IOH_BUF_RD -+@brief Specifies Buffer reception mode -+*/ -+#define IOH_BUF_RD (0x0008) -+ -+/*! @ingroup I2C_HALLayer -+@def I2C_ERROR_MASK -+@brief Mask for errors in all modes -+*/ -+#define I2C_ERROR_MASK (I2CESRTO_EVENT | I2CBMIS_EVENT | I2CBMTO_EVENT | \ -+ I2CBMNA_EVENT | I2CBMAL_EVENT | I2CMAL_EVENT) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMAL_EVENT -+@brief MAL bit position in event flag -+*/ -+#define I2CMAL_EVENT (0x0001) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CMCF_EVENT -+@brief MCF bit position in event flag -+*/ -+#define I2CMCF_EVENT (0x0002) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMFI_EVENT -+@brief I2CBMFI bit position in event flag -+*/ -+#define I2CBMFI_EVENT (0x0004) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMAL_EVENT -+@brief I2CBMAL bit position in event flag -+*/ -+#define I2CBMAL_EVENT (0x0008) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMNA_EVENT -+@brief I2CBMNA bit position in event flag -+*/ -+#define I2CBMNA_EVENT (0x0010) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMTO_EVENT -+@brief I2CBMTO bit position in event flag -+*/ -+#define I2CBMTO_EVENT (0x0020) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CBMIS_EVENT -+@brief I2CBMIS bit position in event flag -+*/ -+#define I2CBMIS_EVENT (0x0040) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRFI_EVENT -+@brief I2CESRFI bit position in event flag -+*/ -+#define I2CESRFI_EVENT (0x0080) -+ -+/*! @ingroup I2C_HALLayer -+@def I2CESRTO_EVENT -+@brief I2CESRTO bit position in event flag -+*/ -+#define I2CESRTO_EVENT (0x0100) -+ -+/* -+ * wait queue head -+ */ -+ -+/*! @ingroup I2C_UtilitiesAPI -+@var ioh_i2c_event -+@brief Wait queue head -+@remarks This global variable is used to synchronize -+ data handling with interrupts -+@see - ioh_i2c_init -+ - ioh_i2c_cb -+*/ -+static wait_queue_head_t ioh_i2c_event; -+ -+/* Function prototypes */ -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_start(struct i2c_algo_ioh_data * adap) -+@brief Function to generate start condition in normal mode -+*/ -+static void ioh_i2c_start(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_buff_mode_start(struct i2c_algo_ioh_data * adap) -+@brief Function to generate start condition in buffer mode -+*/ -+static void ioh_i2c_buff_mode_start(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_eeprom_swrst_start(struct i2c_algo_ioh_data * adap) -+@brief Function to generate start condition in EEPROM Software -+ Reset mode -+*/ -+static void ioh_i2c_eeprom_swrst_start(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_stop(struct i2c_algo_ioh_data *adap) -+@brief Function to generate stop condition in normal mode -+*/ -+static void ioh_i2c_stop(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_repstart(struct i2c_algo_ioh_data *adap) -+@brief Function to generate repeated start condition in normal mode -+*/ -+static void ioh_i2c_repstart(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_getack(struct i2c_algo_ioh_data *adap) -+@brief Function to confirm ACK/NACK -+*/ -+static s32 ioh_i2c_getack(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_sendack(struct i2c_algo_ioh_data *adap) -+@brief Function to send ACK -+*/ -+static void ioh_i2c_sendack(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_sendnack(struct i2c_algo_ioh_data *adap) -+@brief Function to send NACK -+*/ -+static void ioh_i2c_sendnack(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_wait_for_bus_idle -+ (struct i2c_algo_ioh_data *adap,s32 timeout) -+@brief Function to check the status of bus -+*/ -+static s32 ioh_i2c_wait_for_bus_idle(struct i2c_algo_ioh_data *adap, -+ s32 timeout); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn ioh_i2c_wait_for_xfer_complete(struct i2c_algo_ioh_data *adap) -+@brief Function to wait till transfer complete. -+*/ -+static s32 ioh_i2c_wait_for_xfer_complete(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_init(struct i2c_algo_ioh_data * adap) -+ @remarks Implements the hardware initialization of I2C module. -+ The main tasks performed by this method are: -+ - Clear I2CCTL,I2CMOD,I2CBUFFOR,I2CBUFSLV,I2CBUFSUB,I2CBUFMSK, -+ I2CESRFOR,I2CESRMSK registers. -+ - Set I2CMEN in I2CCTL to 1. -+ - Set bus speed based on module parameter. -+ - Enable required interrupts. -+ - Initialize wait queue head. -+ @note This function always returns @ref IOH_I2C_SUCCESS -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Function returns successfully. -+ @see - ioh_i2c_probe -+ - ioh_i2c_resume -+ <hr> -+ */ -+s32 ioh_i2c_init(struct i2c_algo_ioh_data *adap) -+{ -+ u32 ioh_i2cbc; -+ u32 ioh_i2ctmr; -+ u32 reg_value = 0; -+ -+#ifndef FPGA -+ /*reset I2C controller */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CSRST, 0x1); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CSRST, 0x0); -+#endif -+ /* Initialize I2C registers */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CCTL, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFFOR, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSLV, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSUB, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRFOR, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRMSK, CLR_REG); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CNF, 0x21); -+ IOH_DEBUG -+ ("Cleared the registers IOH_I2CCTL,IOH_I2CMOD,IOH_I2CBUFFOR\n," -+ "IOH_I2CBUFSLV,IOH_I2CBUFSUB,IOH_I2CBUFMSK," -+ "\nIOH_I2CESRFOR,IOH_I2CESRMSK\n"); -+ -+ reg_value |= IOH_I2CCTL_I2CMEN; -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, -+ IOH_I2CCTL_I2CMEN); -+ -+ ioh_i2c_speed = (ioh_i2c_speed == 400) ? 400 : 100; -+ -+ if (ioh_i2c_speed == FAST_MODE_CLK) { -+ reg_value |= FAST_MODE_EN; -+ IOH_DEBUG("Fast mode enabled\n"); -+ } -+ -+ ioh_i2c_clk = (ioh_i2c_clk <= 0 -+ || ioh_i2c_clk > IOH_I2C_MAX_CLK) ? 62500 : ioh_i2c_clk; -+ -+ ioh_i2cbc = ((ioh_i2c_clk) + (ioh_i2c_speed * 4)) / (ioh_i2c_speed * 8); -+ /* Set transfer speed in I2CBC */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBC, ioh_i2cbc); -+ -+ ioh_i2ctmr = (ioh_i2c_clk) / 8; -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CTMR, ioh_i2ctmr); -+ -+ reg_value |= NORMAL_INTR_ENBL; /* Enable interrupts in normal mode */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CCTL, reg_value); -+ -+ IOH_DEBUG("In ioh_i2c_init: I2CCTL =%x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ IOH_DEBUG("In ioh_i2c_init: ioh_i2cbc =%x\n", ioh_i2cbc); -+ IOH_DEBUG("In ioh_i2c_init: ioh_i2ctmr =%x\n", ioh_i2ctmr); -+ -+ IOH_DEBUG("Enable interrupts\n"); -+ init_waitqueue_head(&ioh_i2c_event); -+ return IOH_I2C_SUCCESS; -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_writebytes(struct i2c_adapter *i2c_adap , -+ struct i2c_msg *msgs, u32 last, u32 first) -+ @remarks Function to write data to I2C bus in normal mode. -+ The main tasks performed by this method are: -+ - Enable transmission mode. -+ - Send out the slave address. -+ - Wait for Bus idle and send out Start signal -+ - Perform data write operation. -+ - Send stop or repeat start as necessary, depending on whether -+ the current message is the last message or not. -+ - Return with number of bytes transferred successfully or -+ the error code -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref IN] contains reference to i2c_msg structure -+ @param last [@ref IN] specifies whether last message or not -+ In the case of compound mode it will be -+ 1 for last message, otherwise 0. -+ @param first [@ref IN] specifies whether first message or not -+ 1 for first message otherwise 0. -+ @retval s32 -+ - Number of bytes transferred successfully -+ - @ref IOH_I2C_FAIL @ref ioh_i2c_wait_for_bus_idle, -+ @ref ioh_i2c_wait_for_xfer_complete, -+ @ref ioh_i2c_getack fails -+ - -ERESTARTSYS -+ @ref ioh_i2c_wait_for_xfer_complete was interrupted by a signal -+ @see ioh_i2c_xfer -+ <hr> -+ */ -+s32 ioh_i2c_writebytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, -+ u32 last, u32 first) -+{ -+ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ u8 *buf; -+ u32 length; -+ u32 addr; -+ u32 addr_2_msb; -+ u32 addr_8_lsb; -+ s32 wrcount = IOH_I2C_FAIL; -+ length = msgs->len; -+ buf = msgs->buf; -+ addr = msgs->addr; -+ /* enable master tx */ -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, -+ I2C_TX_MODE); -+ -+ IOH_DEBUG("In ioh_i2c_writebytes : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ IOH_DEBUG("In ioh_i2c_writebytes : msgs->len = %d\n", length); -+ -+ if (first) { -+ if (ioh_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -+ IOH_I2C_FAIL) { -+ return IOH_I2C_FAIL; -+ } -+ } -+ -+ if ((msgs->flags & I2C_M_TEN) != false) { -+ addr_2_msb = ((addr & I2C_MSB_2B_MSK) >> 7); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ (addr_2_msb | TEN_BIT_ADDR_MASK)); -+ -+ if (first) -+ ioh_i2c_start(adap); -+ if ((ioh_i2c_wait_for_xfer_complete(adap) == IOH_I2C_SUCCESS) && -+ (ioh_i2c_getack(adap) == IOH_I2C_SUCCESS)) { -+ addr_8_lsb = (addr & I2C_ADDR_MSK); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ (addr_8_lsb)); -+ -+ } else { -+ ioh_i2c_stop(adap); -+ return IOH_I2C_FAIL; -+ } -+ } else { -+ /* set 7 bit slave address and R/W bit as 0 */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ ((addr) << 1)); -+ if (first) -+ ioh_i2c_start(adap); -+ } -+ -+ if ((ioh_i2c_wait_for_xfer_complete(adap) == IOH_I2C_SUCCESS) && -+ (ioh_i2c_getack(adap) == IOH_I2C_SUCCESS)) { -+ for (wrcount = 0; wrcount < length; ++wrcount) { -+ /* write buffer value to I2C data register */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ buf[wrcount]); -+ IOH_DEBUG -+ ("ioh_i2c_writebytes : writing %x to Data register\n", -+ buf[wrcount]); -+ -+ if (ioh_i2c_wait_for_xfer_complete(adap) != -+ IOH_I2C_SUCCESS) { -+ wrcount = IOH_I2C_FAIL; -+ break; -+ } -+ -+ IOH_DEBUG("ioh_i2c_wait_for_xfer_complete return %d", -+ IOH_I2C_SUCCESS); -+ -+ if (ioh_i2c_getack(adap)) { -+ wrcount = IOH_I2C_FAIL; -+ break; -+ } -+ } -+ -+ /* check if this is the last message */ -+ if (last) -+ ioh_i2c_stop(adap); -+ else -+ ioh_i2c_repstart(adap); -+ } else { -+ ioh_i2c_stop(adap); -+ } -+ -+ IOH_DEBUG(KERN_INFO, "ioh_i2c_writebytes return=%d\n", wrcount); -+ -+ return wrcount; -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_readbytes(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs, u32 last, u32 first) -+ @remarks Function to read data from I2C bus in normal mode. -+ The main tasks performed by this method are: -+ - Enable Reception mode. -+ - Send out the slave address. -+ - Wait for Bus idle and send out Start signal -+ - Perform data reads. -+ - Send stop or repeat start as necessary, depending on whether -+ the current -+ message read is the last message or not -+ - Return with number of bytes read (if successful) or -+ the error code -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref INOUT] contains reference to i2c_msg structure -+ @param last [@ref IN] specifies whether last message or not -+ @param first [@ref IN] specifies whether first message or not -+ @retval s32 - Number of Bytes read successfully -+ - @ref IOH_I2C_FAIL @ref ioh_i2c_wait_for_bus_idle, -+ @ref ioh_i2c_wait_for_xfer_complete, -+ @ref ioh_i2c_getack fails -+ - -ERESTARTSYS -+ @ref ioh_i2c_wait_for_xfer_complete was interrupted by a signal -+ @see ioh_i2c_xfer -+ <hr> -+ */ -+s32 ioh_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, -+ u32 last, u32 first) -+{ -+ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ u8 *buf; -+ u32 count = IOH_I2C_FAIL; -+ u32 length; -+ u32 addr; -+ u32 addr_2_msb; -+ length = msgs->len; -+ buf = msgs->buf; -+ addr = msgs->addr; -+ -+ /* enable master reception */ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, -+ I2C_TX_MODE); -+ -+ if (first) { -+ if (ioh_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -+ IOH_I2C_FAIL) { -+ return IOH_I2C_FAIL; -+ } -+ } -+ -+ if ((msgs->flags & I2C_M_TEN) != false) { -+ addr_2_msb = (((addr & I2C_MSB_2B_MSK) >> 7) | (I2C_RD)); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ (addr_2_msb | TEN_BIT_ADDR_MASK)); -+ -+ } else { -+ /* 7 address bits + R/W bit */ -+ addr = (((addr) << 1) | (I2C_RD)); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, addr); -+ } -+ -+ /* check if it is the first message */ -+ if (first == true) -+ ioh_i2c_start(adap); -+ -+ if ((ioh_i2c_wait_for_xfer_complete(adap) == IOH_I2C_SUCCESS) -+ && (ioh_i2c_getack(adap) == IOH_I2C_SUCCESS)) { -+ IOH_DEBUG("ioh_i2c_wait_for_xfer_complete return %d", -+ IOH_I2C_SUCCESS); -+ -+ if (length == 0) { -+ -+ ioh_i2c_stop(adap); -+ (void)adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CDR); -+ -+ count = length; -+ } else { -+ int read_index = 0; -+ int loop; -+ ioh_i2c_sendack(adap); -+ -+ /* Dummy read */ -+ -+ for (loop = 1; loop < length; loop++) { -+ buf[read_index] = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CDR); -+ -+ if (loop != 1) -+ read_index++; -+ -+ if (ioh_i2c_wait_for_xfer_complete(adap) != -+ IOH_I2C_SUCCESS) { -+ ioh_i2c_stop(adap); -+ return IOH_I2C_FAIL; -+ } -+ -+ } /* end for */ -+ -+ ioh_i2c_sendnack(adap); -+ -+ buf[read_index] = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CDR); -+ -+ if (length != 1) -+ read_index++; -+ -+ if (ioh_i2c_wait_for_xfer_complete(adap) == -+ IOH_I2C_SUCCESS) { -+ if (last) -+ ioh_i2c_stop(adap); -+ else -+ ioh_i2c_repstart(adap); -+ -+ buf[read_index++] = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CDR); -+ count = read_index; -+ } -+ -+ } -+ } else { -+ ioh_i2c_stop(adap); -+ } -+ -+ return count; -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_entcb(s32(*ioh_i2c_ptr)(struct i2c_algo_ioh_data *adap)) -+ @remarks Function to register call back function. -+ The main tasks performed by this method are: -+ - Validate ioh_i2c_ptr -+ - Update the reference of the callback function in the callback -+ function pointer. -+ @param ioh_i2c_ptr [@ref IN] Contains reference to call back function -+ @retval None -+ @see ioh_i2c_probe -+ <hr> -+ */ -+void ioh_i2c_entcb(s32(*ioh_i2c_ptr) (struct i2c_algo_ioh_data *adap)) -+{ -+ if (ioh_i2c_ptr != NULL) { -+ IOH_DEBUG("value in ioh_i2c_ptr = %p", ioh_i2c_ptr); -+ /* set the handler call back function */ -+ ioh_i2c_cbr = ioh_i2c_ptr; -+ IOH_DEBUG("value updated in ioh_i2c_cbr = %p", ioh_i2c_cbr); -+ IOH_DEBUG("Invoked ioh_i2c_entcb successfully"); -+ -+ } -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_handler(int irq,void * pData) -+ @remarks This function implements the interrupt handler for -+ the IOH I2C controller. -+ The main tasks performed by this method are: -+ - Invoke callback function. -+ - Based on return value of callback function, -+ return IRQ_NONE or IRQ_HANDLED -+ @param irq [@ref IN] irq number -+ @param pData [@ref IN] cookie passed back to the handler function -+ @retval irqreturn_t -+ - IRQ_NONE Not our interrupt -+ - IRQ_HANDLED Interrupt serviced -+ @see ioh_i2c_probe -+ <hr> -+ */ -+irqreturn_t ioh_i2c_handler(int irq, void *pData) -+{ -+ s32 ret = 0; -+ u32 i; -+ -+ struct adapter_info *adap_info = (struct adapter_info *)pData; -+ /* invoke the call back */ -+ -+ if (ioh_i2c_cbr != NULL) { -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) -+ ret |= (ioh_i2c_cbr) (&adap_info->ioh_i2c_data[i]); -+ } else { -+ IOH_LOG(KERN_ERR, " Call back pointer null ..."); -+ } -+ -+ IOH_DEBUG("ioh_i2c_cb return = %d\n", ret); -+ -+ if (ret == IOH_I2C_EVENT_SET) -+ IOH_DEBUG(" ioh_i2c_handler return IRQ_HANDLED"); -+ else -+ IOH_DEBUG("ioh_i2c_handler return IRQ_NONE"); -+ -+ return (ret == IOH_I2C_EVENT_SET) ? (IRQ_HANDLED) : (IRQ_NONE); -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_buffer_read -+ (struct i2c_adapter * i2c_adap,struct i2c_msg *msgs) -+ @remarks Function to read data from I2C bus in buffer mode. -+ The main tasks performed by this method are: -+ - Enable Buffer Mode. -+ - Set timeout interval in I2CTMR register. -+ - Enable buffer mode interrupts. -+ - Set the I2C Slave Address in the I2CBUFSLV register. -+ - Set the number of bytes, transmission mode and -+ sub-address length in I2CBUFFOR register. -+ - Perform the data read. -+ - Disable buffer mode interrupts. -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref INOUT] contains reference to i2c_msg structure -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Function returns successfully -+ - @ref IOH_I2C_FAIL @ref ioh_i2c_wait_for_bus_idle, -+ @ref ioh_i2c_wait_for_xfer_complete, -+ @ref ioh_i2c_getack fails -+ - -ERESTARTSYS -+ @ref ioh_i2c_wait_for_xfer_complete was interrupted by a signal -+ @see ioh_i2c_xfer -+ <hr> -+ */ -+s32 ioh_i2c_buffer_read(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs) -+{ -+ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ u32 loop; -+ u32 rdcount = 0; -+ u32 length; -+ u32 i2cbufsub = 0; -+ u32 addr; -+ u32 i2cbufslv_7_lsb; -+ u32 i2cbufslv_10_9_bit; -+ u32 msglen; -+ /* initialize to invalid length, so that no sub address is tx-ed */ -+ u32 subaddrlen = 5; -+ u32 i2cmod_prev; -+ s32 i; -+ u32 time_interval = i2c_adap->timeout; -+ u32 i2ctmr; -+ s32 retvalue = IOH_I2C_FAIL; -+ u8 *buf; -+ -+ length = msgs->len; -+ buf = msgs->buf; -+ addr = msgs->addr; -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, -+ BUFFER_MODE_INTR_ENBL); -+ -+ /* get the current value of I2C mod register */ -+ i2cmod_prev = adap->readreg((adap->ioh_i2c_base_address), IOH_I2CMOD); -+ -+ /* enable buffer mode */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, -+ IOH_BUFFER_MODE); -+ -+ time_interval = (time_interval <= 10) ? (time_interval) : (10); -+ -+ /* value of I2CT = (Timeout interval * PCLK frequency)/ 8 */ -+ i2ctmr = (time_interval * (ioh_i2c_clk)) / 8; -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CTMR, i2ctmr); -+ -+ /* if 10 bit addressing is selected */ -+ -+ if ((msgs->flags & I2C_M_TEN) != false) { -+ /* get the 8 LSBits */ -+ i2cbufslv_7_lsb = (addr & I2C_ADDR_MSK); -+ -+ /* get the 2 MSBits */ -+ i2cbufslv_10_9_bit = ((addr & I2C_MSB_2B_MSK) << 1); -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSLV, -+ (TEN_BIT_ADDR_DEFAULT | i2cbufslv_7_lsb | -+ i2cbufslv_10_9_bit)); -+ } else { -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSLV, -+ ((addr & I2C_ADDR_MSK) << 1)); -+ } -+ -+ /* get sub address length, restrict to 4 bytes max */ -+ subaddrlen = -+ (buf[0] <= SUB_ADDR_LEN_MAX) ? (buf[0]) : (SUB_ADDR_LEN_MAX); -+ -+ for (i = (subaddrlen - 1); i >= 0; i--) { -+ /* frame the sub address based on the length */ -+ i2cbufsub |= (((u32) buf[2 - i]) << (8 * i)); -+ } -+ -+ msglen = length - (subaddrlen + 1); -+ -+ loop = (subaddrlen + 1); -+ -+ /* write the sub address to the reg */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSUB, i2cbufsub); -+ /* clear buffers */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFLEV, CLR_REG); -+ -+ rdcount = (msglen <= BUF_LEN_MAX) ? (msglen) : (BUF_LEN_MAX); -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFFOR, -+ ((rdcount << 4) | (IOH_BUF_RD) | (subaddrlen))); -+ -+ do { -+ if (ioh_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -+ IOH_I2C_FAIL) { -+ break; -+ } -+ -+ ioh_i2c_buff_mode_start(adap); -+ -+ IOH_DEBUG("buffer mode start"); -+ -+ if ((adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CBUFSTA) & I2CBMDZ_BIT) != 0) { -+ IOH_DEBUG("buffer read error 1"); -+ break; -+ } -+ -+ if (ioh_i2c_wait_for_xfer_complete(adap) == IOH_I2C_FAIL) { -+ IOH_DEBUG("buffer read error2"); -+ break; -+ } -+ -+ IOH_DEBUG("ioh_i2c_wait_for_xfer_complete return %d", -+ IOH_I2C_SUCCESS); -+ -+ retvalue = rdcount; -+ -+ for (; rdcount > 0; rdcount--, loop++) { -+ buf[loop] = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CDR); -+ -+ } -+ } while (0); -+ -+ /* disable buffer mode interrupts */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, -+ BUFFER_MODE_INTR_DISBL); -+ /* restore the I2CMOD register */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, i2cmod_prev); -+ -+ return retvalue; -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_buffer_write -+ (struct i2c_adapter * i2c_adap,struct i2c_msg * msgs) -+ @remarks Function to write data to I2C bus in buffer mode. -+ The main tasks performed by this method are: -+ - Enable Buffer Mode. -+ - Set timeout interval in I2CTMR register. -+ - Enable buffer mode interrupts. -+ - Set the I2C Slave Address in the I2CBUFSLV register. -+ - Set the number of bytes, transmission mode and -+ subaddress length in I2CBUFFOR register. -+ - Perform data transfer. -+ - Disable the buffer mode interrupts. -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref INOUT] contains reference to i2c_msg structure -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Function returns successfully -+ - @ref IOH_I2C_FAIL @ref ioh_i2c_wait_for_bus_idle, -+ @ref ioh_i2c_wait_for_xfer_complete, -+ @ref ioh_i2c_getack fails -+ - -ERESTARTSYS -+ @ref ioh_i2c_wait_for_xfer_complete was interrupted by a signal -+ @see ioh_i2c_xfer -+ <hr> -+ */ -+s32 ioh_i2c_buffer_write(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs) -+{ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ u32 loop = 0; -+ u32 wrcount = 0; -+ u32 msglen; -+ u32 i2cbufsub = 0; -+ u32 addr; -+ u32 i2cbufslv_7_lsb; -+ u32 i2cbufslv_10_9_bit; -+ -+ /* initialize to invalid length, so that no sub address is tx-ed */ -+ u32 subaddrlen = 5; -+ u32 i2cmod_prev; -+ s32 i; -+ u32 time_interval = i2c_adap->timeout; -+ u32 i2ctmr; -+ s32 retvalue = IOH_I2C_FAIL; -+ u8 *buf; -+ -+ msglen = msgs->len; -+ buf = msgs->buf; -+ addr = msgs->addr; -+ -+ /* get the current value of I2C mod register */ -+ i2cmod_prev = adap->readreg((adap->ioh_i2c_base_address), IOH_I2CMOD); -+ /* enable buffer mode */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, -+ IOH_BUFFER_MODE); -+ -+ time_interval = (time_interval <= 10) ? (time_interval) : (10); -+ /* value of I2CT = (Timeout interval * PCLK frequency)/ 8 */ -+ i2ctmr = (time_interval * (ioh_i2c_clk)) / 8; -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CTMR, i2ctmr); -+ -+ /* enable buffer mode interrupts */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, -+ BUFFER_MODE_INTR_ENBL); -+ -+ /* if 10 bit addressing is selected */ -+ -+ if ((msgs->flags & I2C_M_TEN) != false) { -+ IOH_DEBUG("ioh_i2c_buffer_write...ten bit addressing"); -+ /* get the 8 LSBits */ -+ i2cbufslv_7_lsb = (addr & I2C_ADDR_MSK); -+ -+ /* get the 2 MSBits */ -+ i2cbufslv_10_9_bit = ((addr & I2C_MSB_2B_MSK) << 1); -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSLV, -+ (TEN_BIT_ADDR_DEFAULT | i2cbufslv_7_lsb | -+ i2cbufslv_10_9_bit)); -+ } else { -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSLV, -+ ((addr & I2C_ADDR_MSK) << 1)); -+ -+ } -+ -+ /* get sub address length, restrict to 4 bytes max */ -+ subaddrlen = -+ (buf[0] <= SUB_ADDR_LEN_MAX) ? (buf[0]) : (SUB_ADDR_LEN_MAX); -+ -+ for (i = (subaddrlen - 1); i >= 0; i--) { -+ /* frame the sub address based on the length */ -+ i2cbufsub |= (((u32) buf[2 - i]) << (8 * i)); -+ } -+ -+ /* subaddrlen bytes + the 1st field */ -+ loop = subaddrlen + 1; -+ -+ msglen = msglen - loop; -+ -+ /* write the sub address to the reg */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFSUB, i2cbufsub); -+ -+ /* clear buffers */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFLEV, CLR_REG); -+ -+ msglen = (msglen < BUF_LEN_MAX) ? (msglen) : (BUF_LEN_MAX); -+ -+ for (wrcount = 0; wrcount < msglen; wrcount++) { -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CDR, -+ buf[loop]); -+ IOH_DEBUG("Buffer mode %x", (buf[loop] & 0xff)); -+ loop++; -+ } -+ -+ /* set the number of bytes, transmission mode and sub address length */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFFOR, -+ ((((wrcount << 4) & (IOH_BUF_TX)) | (subaddrlen)))); -+ -+ do { -+ if ((ioh_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT)) == -+ IOH_I2C_FAIL) { -+ break; -+ } -+ -+ /* issue start bits */ -+ ioh_i2c_buff_mode_start(adap); -+ -+ if (((adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CBUFSTA)) & (I2CBMDZ_BIT | -+ I2CBMAG_BIT)) != false) { -+ break; -+ } -+ -+ if (ioh_i2c_wait_for_xfer_complete(adap) == IOH_I2C_FAIL) -+ break; -+ -+ IOH_DEBUG("ioh_i2c_wait_for_xfer_complete return %d", -+ IOH_I2C_SUCCESS); -+ retvalue = wrcount; -+ } while (0); -+ -+ /* disable buffer mode interrupts */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, -+ BUFFER_MODE_INTR_DISBL); -+ /* restore the I2CMOD register */ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, i2cmod_prev); -+ -+ return retvalue; -+} -+ -+/*! @ingroup I2C_HALLayerAPI -+ @fn ioh_i2c_eeprom_sw_reset -+ (struct i2c_adapter * i2c_adap,struct i2c_msg *msgs) -+ @remarks Function for triggering EEPROM software reset. -+ The main tasks performed by this method are: -+ - Enable EEPROM software reset mode. -+ - Enable the required interrupts. -+ - Update timeout value in I2CTMR register. -+ - Invoke @ref ioh_i2c_eeprom_swrst_start to -+ send software reset pattern. -+ - Disable interrupts. -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref IN] contains reference to i2c_msg structure -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Function returns successfully -+ - i@ref IOH_I2C_FAIL @ref ioh_i2c_wait_for_bus_idle, -+ @ref ioh_i2c_wait_for_xfer_complete, -+ - -ERESTARTSYS -+ @ref ioh_i2c_wait_for_xfer_complete was interrupted by a signal -+ @see ioh_i2c_xfer -+ <hr> -+ */ -+s32 ioh_i2c_eeprom_sw_reset(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs) -+{ -+ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ u32 time_interval = i2c_adap->timeout; -+ u32 i2ctmr; -+ u32 i2cmod_prev; -+ u32 ioh_pattern; -+ -+ s32 ret_val = IOH_I2C_FAIL; /* init return value to error */ -+ -+ /* get the current value of I2C mod register */ -+ i2cmod_prev = adap->readreg((adap->ioh_i2c_base_address), IOH_I2CMOD); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, CLR_REG); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CMOD, -+ EEPROM_SW_RST_MODE); -+ -+ IOH_DEBUG("ioh_i2c_eeprom_sw_reset : I2CMOD %x\n", -+ adap->readreg((adap->ioh_i2c_base_address), IOH_I2CMOD)); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRMSK, -+ EEPROM_RST_INTR_ENBL); -+ -+ time_interval = (time_interval <= 10) ? (time_interval) : (10); -+ -+ /* value of I2CT = (Timeout interval * PCLK frequency)/ 8 */ -+ i2ctmr = (time_interval * (ioh_i2c_clk)) / 8; -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CTMR, i2ctmr); -+ -+ /* get the EEPROM reset pattern */ -+ ioh_pattern = (u32) (*(msgs->buf)); -+ -+ /* mode 1 & 2 are used for buffer mode selection */ -+ ioh_pattern -= 2; -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRFOR, -+ ioh_pattern); -+ -+ IOH_DEBUG("ioh_i2c_eeprom_sw_reset : I2CESRFOR %x\n", -+ adap->readreg((adap->ioh_i2c_base_address), IOH_I2CESRFOR)); -+ -+ if (ioh_i2c_wait_for_bus_idle(adap, BUS_IDLE_TIMEOUT) == -+ IOH_I2C_SUCCESS) { -+ -+ ioh_i2c_eeprom_swrst_start(adap); -+ ret_val = ioh_i2c_wait_for_xfer_complete(adap); -+ -+ IOH_DEBUG("ioh_i2c_wait_for_xfer_complete return =%d\n", -+ ret_val); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CMOD, -+ i2cmod_prev); -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRMSK, -+ EEPROM_RST_INTR_DISBL); -+ } -+ -+ IOH_DEBUG("ioh_i2c_eeprom_sw_reset return=%d\n", ret_val); -+ -+ return ret_val; -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_cb(struct i2c_algo_ioh_data * adap) -+ @remarks Interrupt handler Call back function. -+ The main tasks performed by this method are: -+ - Get the current operation mode. -+ - For the current mode ,check if any of the required interrupt -+ bits are set. -+ - Invoke wake_up_interruptible function to unblock the functions -+ waiting for these events. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval s32 -+ - @ref IOH_I2C_EVENT_SET Valid I2C event recognized and flagged -+ - @ref IOH_I2C_EVENT_NONE No valid I2C event -+ @see ioh_i2c_probe -+ <hr> -+ */ -+s32 ioh_i2c_cb(struct i2c_algo_ioh_data *adap) -+{ -+ u32 reg_val; -+ u32 i2c_mode; -+ u32 i2c_interrupt = false; -+ -+ reg_val = adap->readreg((adap->ioh_i2c_base_address), IOH_I2CMOD); -+ /* get the current mode of operation */ -+ i2c_mode = reg_val & (BUFFER_MODE | EEPROM_SR_MODE); -+ -+ switch (i2c_mode) { -+ -+ case NORMAL_MODE: -+ { -+ reg_val = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CSR); -+ reg_val &= (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT); -+ -+ if (reg_val != 0) { -+ -+ if (I2CMAL_BIT & reg_val) { -+ adap->ioh_i2c_event_flag |= -+ I2CMAL_EVENT; -+ } -+ -+ if (I2CMCF_BIT & reg_val) { -+ adap->ioh_i2c_event_flag |= -+ I2CMCF_EVENT; -+ } -+ -+ /* clear the applicable bits */ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), -+ IOH_I2CSR, reg_val); -+ -+ IOH_DEBUG("ioh_i2c_cb : IOH_I2CSR = %x\n", -+ (adap-> -+ readreg(adap->ioh_i2c_base_address, -+ IOH_I2CSR))); -+ -+ i2c_interrupt = true; -+ } -+ -+ break; -+ } -+ -+ case BUFFER_MODE: -+ { -+ reg_val = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CBUFSTA); -+ reg_val &= BUFFER_MODE_MASK; -+ if (reg_val != 0) { -+ /* there is a co-relation between the buffer -+ * mode interrupt flags' bit */ -+ /* positions and the flag positions in event -+ * flag. for e.g. I2CBMFI is at position */ -+ /* 0 in the I2CBUFSTA register. its position -+ * in the event flag is 2, hence left shifting -+ */ -+ adap->ioh_i2c_event_flag |= ((reg_val) << 2); -+ -+ /* clear the applicable bits */ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), -+ IOH_I2CBUFSTA, reg_val); -+ -+ IOH_DEBUG("ioh_i2c_cb : IOH_I2CBUFSTA = %x\n", -+ (adap-> -+ readreg(adap->ioh_i2c_base_address, -+ IOH_I2CBUFSTA))); -+ -+ i2c_interrupt = true; -+ } -+ -+ break; -+ -+ } -+ -+ case EEPROM_SR_MODE: -+ { -+ reg_val = -+ adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CESRSTA); -+ reg_val &= (I2CESRFI_BIT | I2CESRTO_BIT); -+ if (reg_val != 0) { -+ -+ adap->ioh_i2c_event_flag |= ((reg_val) << 7); -+ -+ /* clear the applicable bits */ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), -+ IOH_I2CESRSTA, reg_val); -+ -+ IOH_DEBUG("ioh_i2c_cb : IOH_I2CESRSTA = %x\n", -+ (adap-> -+ readreg(adap->ioh_i2c_base_address, -+ IOH_I2CESRSTA))); -+ -+ i2c_interrupt = true; -+ } -+ -+ break; -+ } -+ -+ default: -+ { -+ break; -+ } -+ } /* end switch */ -+ -+ if (i2c_interrupt == true) -+ wake_up_interruptible(&ioh_i2c_event); -+ -+ return ((i2c_interrupt == -+ true) ? (IOH_I2C_EVENT_SET) : (IOH_I2C_EVENT_NONE)); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_start(struct i2c_algo_ioh_data * adap) -+ @remarks The main tasks performed by this method are: -+ - Generate I2C start condition in normal mode -+ by setting I2CCTL.I2CMSTA to 1. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ <hr> -+ */ -+static void ioh_i2c_start(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_start : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, IOH_START); -+ IOH_DEBUG(" Invoke ioh_i2c_start successfully \n"); -+ IOH_DEBUG("In ioh_i2c_start : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_buff_mode_start(struct i2c_algo_ioh_data * adap) -+ @remarks The main tasks performed by this method are: -+ - Generate I2C start condition in buffer mode -+ by setting I2CBUFCTL.I2CBMSTA to 1. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see - ioh_i2c_buffer_read -+ - ioh_i2c_buffer_write -+ <hr> -+ */ -+static void ioh_i2c_buff_mode_start(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_buff_mode_start : I2CBUFCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CBUFCTL))); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CBUFCTL, -+ IOH_BUFF_START); -+ -+ IOH_DEBUG(" Invoke ioh_i2c_buff_mode_start successfully \n"); -+ IOH_DEBUG("In ioh_i2c_buff_mode_start : I2CBUFCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CBUFCTL))); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_eeprom_swrst_start(struct i2c_algo_ioh_data * adap) -+ @remarks The main tasks performed by this method are: -+ - Generate I2C start condition in EEPROM sw reset mode -+ by setting I2CESRCTL.I2CSTA to 1. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see ioh_i2c_eeprom_sw_reset -+ <hr> -+ */ -+static void ioh_i2c_eeprom_swrst_start(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_eeprom_swrst_start : I2CESRCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CESRCTL))); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CESRCTL, -+ IOH_ESR_START); -+ -+ IOH_DEBUG(" Invoked ioh_i2c_eeprom_swrst_start successfully\n"); -+ IOH_DEBUG("In ioh_i2c_eeprom_swrst_start : I2CESRCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CESRCTL))); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_stop(struct i2c_algo_ioh_data *adap) -+ @remarks Function to generate stop condition in normal mode. -+ The main tasks performed by this method are: -+ - Generate I2C stop condition by setting I2CCTL.I2CMSTA to 0. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ <hr> -+ */ -+static void ioh_i2c_stop(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_stop : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ /* clear the start bit */ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, IOH_START); -+ IOH_DEBUG(" Invoke ioh_i2c_stop successfully \n"); -+ IOH_DEBUG("In ioh_i2c_stop : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_repstart(struct i2c_algo_ioh_data *adap) -+ @remarks Function to generate repeated start condition in normal mode. -+ The main tasks performed by this method are: -+ - Generate repeated start condition by setting using -+ I2CCTL.I2CRSTA to 1. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ <hr> -+ */ -+static void ioh_i2c_repstart(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_repstart : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, -+ IOH_REPSTART); -+ -+ IOH_DEBUG(" Invoke ioh_i2c_repstart successfully \n"); -+ IOH_DEBUG("In ioh_i2c_repstart : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_getack(struct i2c_algo_ioh_data *adap) -+ @remarks Function to confirm ACK/NACK. -+ The main tasks performed by this method are: -+ - Get the ACK status from I2CSR. -+ - Return success if ACK received or failure otherwise. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Acknowledgement was received. -+ - @ref IOH_I2C_FAIL No acknowledgement received. -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ <hr> -+ */ -+static s32 ioh_i2c_getack(struct i2c_algo_ioh_data *adap) -+{ -+ u32 reg_val; -+ reg_val = -+ (adap->readreg((adap->ioh_i2c_base_address), IOH_I2CSR) & -+ IOH_GETACK); -+ -+ if (reg_val == 0) -+ IOH_DEBUG("ioh_i2c_getack : return%d \n", IOH_I2C_SUCCESS); -+ else -+ IOH_DEBUG("ioh_i2c_getack : return%d \n", IOH_I2C_FAIL); -+ -+ return (((reg_val) == 0) ? (IOH_I2C_SUCCESS) : (IOH_I2C_FAIL)); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_sendack(struct i2c_algo_ioh_data *adap) -+ @remarks Function to send ACK. -+ The main tasks performed by this method are: -+ - Clear the I2C TXAK bit in I2CCTL register . -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see ioh_i2c_readbytes -+ <hr> -+ */ -+static void ioh_i2c_sendack(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_sendack : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, IOH_ACK); -+ -+ IOH_DEBUG("Invoke ioh_i2c_sendack successfully\n"); -+ IOH_DEBUG("In ioh_i2c_sendack : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_sendnack(struct i2c_algo_ioh_data *adap) -+ @remarks Function to send NACK. -+ The main tasks performed by this method are: -+ - Set the I2C TXAK bit in I2CCTL register . -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see ioh_i2c_readbytes -+ <hr> -+ */ -+static void ioh_i2c_sendnack(struct i2c_algo_ioh_data *adap) -+{ -+ IOH_DEBUG("In ioh_i2c_sendnack : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ adap->set_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, IOH_ACK); -+ IOH_DEBUG("Invoke ioh_i2c_sendnack successfully\n"); -+ IOH_DEBUG("In ioh_i2c_sendnack : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_wait_for_bus_idle -+ (struct i2c_algo_ioh_data *adap,s32 timeout) -+ @remarks Function to check the status of bus. -+ The main tasks performed by this method are: -+ - Get the status of Bus Busy. -+ - If bus is busy sleep for 1 msec and again check. -+ - Repeat until bus is free or timeout happens. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @param timeout [@ref IN] waiting time counter (us) -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS The function returns successfully. -+ - @ref IOH_I2C_FAIL The bus is still idle. -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ - ioh_i2c_buffer_read -+ - ioh_i2c_buffer_write -+ - ioh_i2c_eeprom_sw_reset -+ <hr> -+ */ -+static s32 ioh_i2c_wait_for_bus_idle(struct i2c_algo_ioh_data *adap, -+ s32 timeout) -+{ -+ u32 reg_value; -+ -+ /* get the status of bus busy */ -+ reg_value = -+ (adap->readreg((adap->ioh_i2c_base_address), IOH_I2CSR) & -+ (I2CMBB_BIT)); -+ -+ while ((timeout != 0) && (reg_value != 0)) { -+ msleep(1); /* wait for 100 ms */ -+ reg_value = -+ (adap->readreg((adap->ioh_i2c_base_address), -+ IOH_I2CSR) & (I2CMBB_BIT)); -+ timeout--; -+ } -+ -+ IOH_DEBUG("In ioh_i2c_wait_for_bus_idle : I2CSR = %x\n", -+ adap->readreg((adap->ioh_i2c_base_address), IOH_I2CSR)); -+ -+ if (timeout == 0) { -+ IOH_LOG(KERN_ERR, "ioh_i2c_wait_for_bus_idle :return%d\n", -+ IOH_I2C_FAIL); -+ } else { -+ IOH_DEBUG("ioh_i2c_wait_for_bus_idle : return %d\n", -+ IOH_I2C_SUCCESS); -+ } -+ -+ return ((timeout <= 0) ? (IOH_I2C_FAIL) : (IOH_I2C_SUCCESS)); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_wait_for_xfer_complete(struct i2c_algo_ioh_data * adap) -+ @remarks This functions initiates a wait for the transfer complete event -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS Function returns successfully. -+ - @ref IOH_I2C_FAIL Any error occurs. -+ - -ERESTARTSYS wait_event_interruptible_timeout -+ API was interrupted -+ @see - ioh_i2c_readbytes -+ - ioh_i2c_writebytes -+ - ioh_i2c_buffer_read -+ - ioh_i2c_buffer_write -+ - ioh_i2c_eeprom_sw_reset -+ <hr> -+*/ -+static s32 ioh_i2c_wait_for_xfer_complete(struct i2c_algo_ioh_data *adap) -+{ -+ -+ u32 temp_flag; -+ s32 ret = IOH_I2C_FAIL; -+ ret = -+ wait_event_interruptible_timeout(ioh_i2c_event, -+ (adap->ioh_i2c_event_flag != 0), -+ msecs_to_jiffies(50)); -+ -+ IOH_DEBUG -+ ("adap->ioh_i2c_event_flag in ioh_i2c_wait_for_xfer_complete=%x", -+ adap->ioh_i2c_event_flag); -+ temp_flag = adap->ioh_i2c_event_flag; -+ adap->ioh_i2c_event_flag = 0; -+ -+ if (ret == 0) { -+ IOH_LOG(KERN_ERR, "ioh_i2c_wait_for_xfer_complete : Timeout\n"); -+ } else if (ret < 0) { -+ IOH_LOG(KERN_ERR, -+ "ioh_i2c_wait_for_xfer_complete failed : " -+ "Interrupted by other signal\n"); -+ ret = -ERESTARTSYS; -+ } else if ((temp_flag & I2C_ERROR_MASK) == 0) { -+ ret = IOH_I2C_SUCCESS; -+ } else { -+ IOH_LOG(KERN_ERR, -+ "ioh_i2c_wait_for_xfer_complete failed : " -+ "Error in transfer\n"); -+ } -+ -+ IOH_DEBUG(KERN_ERR, "ioh_i2c_wait_for_xfer_complete returns %d\n", ret); -+ -+ return ret; -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_writereg(u32 addr,u32 offset,u32 val) -+ @remarks Function for writing data to register. -+ The main tasks performed by this method are: -+ - Compute the target address by adding the offset to -+ the base address. -+ - Write the specified value to the target address. -+ @param addr [@ref IN] Base address for the I2C channel -+ @param offset [@ref IN] offset for the register -+ @param val [@ref IN] Value to be written -+ @retval None -+ @see ioh_i2c_probe -+ <hr> -+ */ -+void ioh_i2c_writereg(u32 addr, u32 offset, u32 val) -+{ -+ IOH_WRITE_LONG(val, (addr + offset)); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_readreg(u32 addr,u32 offset) -+ @remarks Function for reading data from register. -+ The main tasks performed by this method are: -+ - Compute the target address by adding the offset to -+ the base address. -+ - Read the register value and return the same. -+ @param addr [@ref IN] Base address for the I2C channel -+ @param offset [@ref IN] offset for the register -+ @retval u32 -+ The content of the register that is read. -+ @see ioh_i2c_probe -+ <hr> -+ */ -+u32 ioh_i2c_readreg(u32 addr, u32 offset) -+{ -+ u32 ret; -+ ret = IOH_READ_LONG(addr + offset); -+ return ret; -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_setbit(u32 addr,u32 offset,u32 bitmask) -+ @remarks Function to set particular bit in register. -+ The main tasks performed by this method are: -+ - Compute the target address by adding the offset -+ to the base address. -+ - Read the register value at the target address. -+ - Perform logical OR with bitmask and write back -+ to the target address. -+ @param addr [@ref IN] Base address for the I2C channel -+ @param offset [@ref IN] offset for the register -+ @param bitmask [@ref IN] bit position -+ @retval None -+ @see ioh_i2c_probe -+ <hr> -+ */ -+void ioh_i2c_setbit(u32 addr, u32 offset, u32 bitmask) -+{ -+ IOH_WRITE_LONG(((IOH_READ_LONG(addr + offset)) | (bitmask)), -+ (addr + offset)); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_clrbit(u32 addr,u32 off,u32 bitmask) -+ @remarks Function to reset particular bit in register. -+ The main tasks performed by this method are: -+ - Compute the target address by adding the offset -+ to the base address. -+ - Read the register value at the target address. -+ - Perform logical AND with bitmask and write back -+ to the target address. -+ @param addr [@ref IN] Base address for the I2C channel -+ @param offset [@ref IN] offset for the register -+ @param bitmask [@ref IN] bit position -+ @retval None -+ @see ioh_i2c_probe -+ <hr> -+ */ -+void ioh_i2c_clrbit(u32 addr, u32 offset, u32 bitmask) -+{ -+ IOH_WRITE_LONG(((IOH_READ_LONG(addr + offset)) & (~(bitmask))), -+ (addr + offset)); -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_disbl_int(struct i2c_algo_ioh_data * adap) -+ @remarks Function to disable IOH I2C interrupts. -+ The main tasks performed by this method are: -+ - Disable the following interrupts: -+ MAL,MCF,I2CESRFI,I2CESRTO,I2CBMIS,I2CBMTO,I2CBMNA, -+ I2CBMAL and I2CBMFI. -+ @param adap [@ref IN] Contains reference to struct i2c_algo_ioh_data -+ @retval None -+ @see - ioh_i2c_remove -+ - ioh_i2c_suspend -+ <hr> -+*/ -+void ioh_i2c_disbl_int(struct i2c_algo_ioh_data *adap) -+{ -+ -+ adap->clr_reg_bit((adap->ioh_i2c_base_address), IOH_I2CCTL, -+ NORMAL_INTR_ENBL); -+ -+ IOH_DEBUG("ioh_i2c_disbl_int : I2CCTL = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CCTL))); -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CESRMSK, -+ EEPROM_RST_INTR_DISBL); -+ -+ IOH_DEBUG("ioh_i2c_disbl_int : IOH_I2CESRMSK = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CESRMSK))); -+ -+ adap->writereg((adap->ioh_i2c_base_address), IOH_I2CBUFMSK, -+ BUFFER_MODE_INTR_DISBL); -+ -+ IOH_DEBUG("ioh_i2c_disbl_int : IOH_I2CBUFMSK = %x\n", -+ (adap->readreg(adap->ioh_i2c_base_address, IOH_I2CBUFMSK))); -+ -+} -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.h topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.h ---- linux-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.h 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_hal.h 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,337 @@ -+#ifndef __IOH_I2C_HAL_H__ -+#define __IOH_I2C_HAL_H__ -+/*! -+* @file ioh_i2c_hal.h -+* @brief This file provides the function prototypes and macros to the I2C module. -+* @version 0.95 -+* @section -+* 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; version 2 of the License. -+* -+* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+*/ -+ -+/* -+* History: -+* Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+* All rights reserved. -+* -+* created: -+* WIPRO 02/20/2009 -+* modified: -+* WIPRO 05/21/2009 -+* -+*/ -+ -+/*! @defgroup I2C*/ -+ -+/*! @defgroup I2C_Global -+@ingroup I2C -+@brief This group describes the global entities within -+ the module. -+@remarks This group includes all the global data structures -+ used within the modules. These are mainly used to -+ store the device related information which is used -+ through out the module. -+<hr> -+*/ -+ -+/*! @defgroup I2C_PCILayer -+@ingroup I2C -+@brief This group describes the PCI layer interface -+ functionalities. -+@remarks This group contains the functions and data structures -+ that are used to interface the module with PCI Layer -+ subsystem of the Kernel. -+<hr> -+*/ -+ -+/*! @defgroup I2C_InterfaceLayer -+@ingroup I2C -+@brief This group describes the Driver interface functionalities. -+@remarks This group contains the data structures and functions used -+ to interface the module driver with the kernel subsystem. -+<hr> -+*/ -+ -+/*! @defgroup I2C_HALLayer -+@ingroup I2C -+@brief This group describes the hardware specific functionalities. -+@remarks This group contains the functions and data structures used -+ by the module to communicate with the hardware. These -+ functions are device specific and designed according to the -+ device specifications. -+<hr> -+*/ -+ -+/*! @defgroup I2C_Utilities -+@ingroup I2C -+@brief This group describes the utility functionalities. -+@remarks This group contains the functions and data structures used -+ to assist the other functionalities in their operations. -+<hr> -+*/ -+ -+/*! @defgroup I2C_PCILayerAPI -+@ingroup I2C_PCILayer -+@brief This group contains the API(functions) used as the PCI -+ interface between the Kernel subsystem and the module. -+<hr> -+*/ -+ -+/*! @defgroup I2C_PCILayerFacilitators -+@ingroup I2C_PCILayer -+@brief This group contains the data structures used by the PCI -+ Layer APIs for their functionalities. -+<hr> -+*/ -+ -+/*! @defgroup I2C_InterfaceLayerAPI -+@ingroup I2C_InterfaceLayer -+@brief This group contains the API(functions) used as the Driver -+ interface between the Kernel subsystem and the module. -+<hr> -+*/ -+ -+/*! @defgroup I2C_InterfaceLayerFacilitators -+@ingroup I2C_InterfaceLayer -+@brief This group contains the data structures used by the Driver -+ interface APIs for their functionalities. -+<hr> -+*/ -+ -+/*! @defgroup I2C_HALLayerAPI -+@ingroup I2C_HALLayer -+@brief This group contains the APIs(functions) used to interact with -+ the hardware. These APIs act as an interface between the -+ hardware and the other driver functions. -+<hr> -+*/ -+ -+/*! @defgroup I2C_UtilitiesAPI -+@ingroup I2C_Utilities -+@brief This group contains the APIs(functions) used by other functions. -+<hr> -+*/ -+ -+/*includes*/ -+#include <linux/irqreturn.h> -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_SUCCESS -+@brief Success status code -+*/ -+#define IOH_I2C_SUCCESS (0) -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_FAIL -+@brief Error status code -+*/ -+#define IOH_I2C_FAIL (-1) -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_MAX_CHN -+@brief Maximum I2C channels available -+*/ -+#define IOH_I2C_MAX_CHN (1) -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_EVENT_SET -+@brief I2C Interrupt Event Set Status -+*/ -+#define IOH_I2C_EVENT_SET (0) -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_EVENT_NONE -+@brief I2C Interrupt Event Clear Status -+*/ -+#define IOH_I2C_EVENT_NONE (1) -+ -+/*! @ingroup I2C_Global -+@def IOH_I2C_MAX_CLK -+@brief Maximum peripheral Clock speed supported in MHz -+*/ -+#define IOH_I2C_MAX_CLK (100000) -+ -+ -+/* flag for Buffer mode enable */ -+#define IOH_BUFFER_MODE_ENABLE (0x0002) -+ -+/* flag for EEPROM SW RST enable */ -+#define IOH_EEPROM_SW_RST_MODE_ENABLE (0x0008) -+ -+/* for mode selection */ -+#define I2C_MODE_SEL (0x711) -+ -+/*structures*/ -+/*! @ingroup I2C_HALLayer -+@struct i2c_algo_ioh_data -+@brief This structure contains references to methods implementing -+ I2C driver functionalities. -+@note The concerned details should be provided during -+ the data transfer. -+@see - ioh_i2c_init -+ - ioh_i2c_entcb -+ - ioh_i2c_cb -+ - ioh_i2c_disbl_int -+*/ -+ -+struct i2c_algo_ioh_data { -+ -+ struct adapter_info *p_adapter_info; -+ /**< stores the reference to adapter_info structure*/ -+ -+ struct i2c_adapter ioh_i2c_adapter; -+ /**< stores the reference to i2c_adapter structure*/ -+ -+ u32 ioh_i2c_base_address; /**< specifies the remapped base address*/ -+ int ioh_i2c_buff_mode_en; /**< specifies if buffer mode is enabled*/ -+ u32 ioh_i2c_event_flag; /**< specifies occurrence of interrupt events*/ -+ -+ bool ioh_i2c_xfer_in_progress; -+ /**< specifies whether the transfer is completed */ -+ -+ void (*writereg) (u32 addr, u32 off, u32 val); -+ /**< stores the reference to register write function*/ -+ -+ u32(*readreg) (u32 addr, u32 off); -+ /**< stores the reference to register read function*/ -+ -+ void (*set_reg_bit) (u32 addr, u32 off, u32 bitmsk); -+ /**< stores the reference to register bit setting function*/ -+ -+ void (*clr_reg_bit) (u32 addr, u32 off, u32 bitmsk); -+ /**< stores the reference to register bit clearing function*/ -+}; -+ -+/*! @ingroup I2C_HALLayer -+@struct adapter_info -+@brief This structure holds the adapter information -+ for the IOH i2c controller. -+@note This structure contains instances of struct i2c_algo_ioh_data -+ for the available I2C channels and also a variable for saving -+ the suspend status. -+@see - ioh_i2c_probe -+ - ioh_i2c_remove -+ - ioh_i2c_suspend -+ - ioh_i2c_resume -+*/ -+ -+struct adapter_info { -+ -+ struct i2c_algo_ioh_data ioh_i2c_data[IOH_I2C_MAX_CHN]; -+ /**< stores a list of i2c_algo_ioh_data; -+ there will be as many elements as maximum I2C channels*/ -+ -+ bool ioh_i2c_suspended; -+ /**< specifies whether the system is suspended or not*/ -+}; -+ -+/**global variables*/ -+extern int ioh_i2c_speed; -+extern int ioh_i2c_clk; -+extern s32(*ioh_i2c_cbr) (struct i2c_algo_ioh_data *); -+ -+extern struct i2c_algorithm ioh_i2c_algorithm; -+ -+/* Function prototypes */ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_init(struct i2c_algo_ioh_data *adap) -+@brief Function to initialize IOH I2C hardware -+*/ -+s32 ioh_i2c_init(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_writebytes(struct i2c_adapter *i2c_adap , -+ struct i2c_msg *msgs,u32 last, u32 first) -+@brief Function for data write in normal mode -+*/ -+s32 ioh_i2c_writebytes(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs, u32 last, u32 first); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_readbytes(struct i2c_adapter *i2c_adap , -+ struct i2c_msg *msgs,u32 last, u32 first) -+@brief Function for data read in normal mode -+*/ -+s32 ioh_i2c_readbytes(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs, u32 last, u32 first); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_eeprom_sw_reset(struct i2c_adapter * i2c_adap, -+ struct i2c_msg *msgs) -+@brief Function for triggering EEPROM software reset mode -+*/ -+s32 ioh_i2c_eeprom_sw_reset(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_buffer_write -+ (struct i2c_adapter * i2c_adap,struct i2c_msg *msgs) -+@brief Function for data write in buffer mode -+*/ -+s32 ioh_i2c_buffer_write(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn s32 ioh_i2c_buffer_read -+ (struct i2c_adapter * i2c_adap,struct i2c_msg *msgs) -+@brief Function for data read in buffer mode -+*/ -+s32 ioh_i2c_buffer_read(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn irqreturn_t ioh_i2c_handler(int irq,void *pData) -+@brief Interrupt handler -+*/ -+irqreturn_t ioh_i2c_handler(int irq, void *pData); -+ -+/*! @ingroup I2C_HALLayerAPI -+@fn void ioh_i2c_entcb -+ (s32(*ioh_i2c_ptr)(struct i2c_algo_ioh_data *adap)) -+@brief Function for registering the interrupt handler call back -+*/ -+void ioh_i2c_entcb(s32(*ioh_i2c_ptr) (struct i2c_algo_ioh_data *adap)); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn s32 ioh_i2c_cb(struct i2c_algo_ioh_data * adap) -+@brief Call back function invoked from interrupt handler -+*/ -+s32 ioh_i2c_cb(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn void ioh_i2c_disbl_int(struct i2c_algo_ioh_data *adap) -+@brief Function for disabling the interrupt -+*/ -+void ioh_i2c_disbl_int(struct i2c_algo_ioh_data *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn void ioh_i2c_writereg(u32 addr,u32 off,u32 val) -+@brief Function for writing data to register -+*/ -+void ioh_i2c_writereg(u32 addr, u32 off, u32 val); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn u32 ioh_i2c_readreg(u32 addr,u32 off) -+@brief Function for reading data from register -+*/ -+u32 ioh_i2c_readreg(u32 addr, u32 off); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn void ioh_i2c_setbit(u32 addr,u32 off,u32 bitmsk) -+@brief Function to set a particular bit in a register -+*/ -+void ioh_i2c_setbit(u32 addr, u32 off, u32 bitmsk); -+ -+/*! @ingroup I2C_UtilitiesAPI -+@fn void ioh_i2c_clrbit(u32 addr,u32 off,u32 bitmsk) -+@brief Function to clear a particular bit in a register -+*/ -+void ioh_i2c_clrbit(u32 addr, u32 off, u32 bitmsk); -+#endif -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_i2c_main.c topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_main.c ---- linux-2.6.33.1/drivers/i2c/busses/pch_i2c_main.c 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_main.c 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,247 @@ -+/*! -+ * @file ioh_i2c_main.c -+ * @brief This file contains the definitions -+ * of Interface Layer APIs for IOH I2C driver. -+ * @version 0.95 -+ * @section -+ * 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; version 2 of the License. -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* -+ * History: -+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+ * All rights reserved. -+ * -+ * created: -+ * WIPRO 02/20/2009 -+ * modified: -+ * WIPRO 05/21/2009 -+ * -+ */ -+ -+/*includes*/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/i2c.h> -+#include <linux/pci.h> -+#include <linux/types.h> -+#include <linux/stat.h> -+#include <linux/interrupt.h> -+ -+#include "pch_i2c_hal.h" -+#include "pch_common.h" -+#include "pch_debug.h" -+ -+/* Function prototypes */ -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_func(struct i2c_adapter *adap) -+ @brief This function returns the functionalities supported -+ by I2C driver. -+ */ -+static u32 ioh_i2c_func(struct i2c_adapter *adap); -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_xfer(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs,s32 num) -+ @brief This function handles data transfer through I2C bus -+ */ -+static s32 ioh_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, -+ s32 num); -+ -+/*structures*/ -+ -+/*! @ingroup I2C_Global -+ @struct ioh_i2c_algorithm -+ @brief This an instance of the kernel structure i2c_algorithm structure -+ and it stores the properties of the IOH I2C algorithm driver. -+ @note This structure stores the references of the @ref ioh_i2c_xfer -+ and @ref ioh_i2c_func functions. -+ @see ioh_i2c_probe -+ */ -+ -+struct i2c_algorithm ioh_i2c_algorithm = { -+ .master_xfer = ioh_i2c_xfer, -+ .functionality = ioh_i2c_func -+}; -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_func(struct i2c_adapter *adap) -+ @brief Function return the functionality of the I2C driver -+ @remarks Returns (I2C_FUNC_I2C) | (I2C_FUNC_SMBUS_EMUL) | -+ (I2C_FUNC_10BIT_ADDR) -+ @param adap [@ref IN] Contains reference to i2c_adapter structure -+ @retval u32 -+ - Bitwise OR of the feature status codes supported -+ by this algorithm driver. -+ @see ioh_i2c_algorithm -+ */ -+static u32 ioh_i2c_func(struct i2c_adapter *adap) -+{ -+ u32 ret; -+ ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; -+ return ret; -+} -+ -+/*! @ingroup I2C_UtilitiesAPI -+ @fn ioh_i2c_xfer(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs,s32 num) -+ @brief Function to transfer data through I2C bus -+ @remarks Function to transfer data through I2C bus -+ The main tasks performed by this method are: -+ - Check if system is suspended. -+ - If EEPROM software reset command is received, -+ then invoke function ioh_i2c_eeprom_sw_reset. -+ - If Buffer mode selection command is received, -+ check the value of msgs[0]->buf[0]. If set, -+ enable buffer mode, by setting the variable -+ adap->ioh_i2c_buff_mode_en. Otherwise reset the flag. -+ - If no special command, perform the requested -+ data transfer operation. -+ @note The master transfer function ioh_i2c_xfer -+ is invoked by the Linux I2C core, whenever -+ communication/data transfer with the IOH I2C -+ driver is necessary. The Linux I2C core -+ ensures that the function is called with -+ valid parameters only. -+ @param i2c_adap [@ref IN] contains reference to the struct i2c_adapter -+ @param msgs [@ref IN] contains reference to i2c_msg structure -+ @param num [@ref IN] number of messages -+ @retval s32 -+ - @ref IOH_I2C_SUCCESS -+ Function returns successfully for EEPROM sw reset mode, -+ buffer mode selection commands. -+ - The number of bytes transferred for successful operation -+ of read/write calls. -+ - @ref IOH_I2C_FAIL -+ Any error occurs during the execution of the function. -+ @see ioh_i2c_algorithm -+ <hr> -+ */ -+ -+static s32 ioh_i2c_xfer(struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs, s32 num) -+{ -+ -+ struct i2c_msg *pmsg; -+ u32 i = 0; -+ u32 status; -+ u32 msglen; -+ u32 subaddrlen; -+ s32 ret = IOH_I2C_FAIL; -+ -+ struct i2c_algo_ioh_data *adap = i2c_adap->algo_data; -+ -+ if (adap->p_adapter_info->ioh_i2c_suspended == false) { -+ IOH_DEBUG("ioh_i2c_xfer " -+ "adap->p_adapter_info->ioh_i2c_suspended is %d\n", -+ adap->p_adapter_info->ioh_i2c_suspended); -+ /* transfer not completed */ -+ adap->ioh_i2c_xfer_in_progress = true; -+ IOH_DEBUG(" adap->ioh_i2c_xfer_in_progress is %d\n", -+ adap->ioh_i2c_xfer_in_progress); -+ pmsg = &msgs[0]; -+ status = pmsg->flags; -+ /* special commands for IOH I2C driver */ -+ if ((status & -+ (IOH_EEPROM_SW_RST_MODE_ENABLE | IOH_BUFFER_MODE_ENABLE)) -+ != false) { -+ if ((status & IOH_EEPROM_SW_RST_MODE_ENABLE) != false) { -+ /* check whether EEPROM sw reset is enabled */ -+ IOH_DEBUG("ioh_i2c_xfer invoking " -+ "ioh_i2c_eeprom_sw_reset\n"); -+ IOH_DEBUG("After invoking " -+ "I2C_MODE_SEL :flag= 0x%x\n", status); -+ ret = ioh_i2c_eeprom_sw_reset(i2c_adap, pmsg); -+ } else { -+ adap->ioh_i2c_buff_mode_en = -+ (pmsg->buf[0] == 1) ? -+ (IOH_BUFFER_MODE_ENABLE) : (pmsg->buf[0]); -+ ret = IOH_I2C_SUCCESS; -+ } -+ /* transfer completed */ -+ adap->ioh_i2c_xfer_in_progress = false; -+ IOH_DEBUG("adap->ioh_i2c_xfer_in_progress is %d\n", -+ adap->ioh_i2c_xfer_in_progress); -+ IOH_DEBUG(KERN_INFO, -+ "After mode selection " -+ "ioh_i2c_xfer return = %d\n", ret); -+ return ret; -+ } -+ for (i = 0; i < num; i++) { -+ pmsg = &msgs[i]; -+ pmsg->flags |= adap->ioh_i2c_buff_mode_en; -+ status = pmsg->flags; -+ IOH_DEBUG("After invoking I2C_MODE_SEL :flag= 0x%x\n", -+ status); -+ /* calculate sub address length and message length */ -+ /* these are applicable only for buffer mode */ -+ subaddrlen = pmsg->buf[0]; -+ /* calculate actual message length excluding -+ * the sub address fields */ -+ msglen = (pmsg->len) - (subaddrlen + 1); -+ -+ if (((status & IOH_BUFFER_MODE_ENABLE) != false) -+ && (msglen != 0)) { -+ /* Buffer mode cannot be used for transferring -+ * 0 byte data. Hence when buffer mode is -+ * enabled and 0 byte transfer is requested, -+ * normal mode transfer will be used */ -+ if ((status & (I2C_M_RD)) != false) { -+ IOH_DEBUG(KERN_INFO, -+ "ioh_i2c_xfer invoking " -+ "ioh_i2c_buffer_read\n"); -+ ret = -+ ioh_i2c_buffer_read(i2c_adap, pmsg); -+ } else { -+ IOH_DEBUG(KERN_INFO, -+ "ioh_i2c_xfer invoking " -+ "ioh_i2c_buffer_write\n"); -+ ret = -+ ioh_i2c_buffer_write(i2c_adap, pmsg); -+ } -+ } else { -+ if ((status & (I2C_M_RD)) != false) { -+ IOH_DEBUG(KERN_INFO, -+ "ioh_i2c_xfer invoking " -+ "ioh_i2c_readbytes\n"); -+ ret = -+ ioh_i2c_readbytes(i2c_adap, pmsg, -+ (i + 1 == num), -+ (i == 0)); -+ } else { -+ IOH_DEBUG(KERN_INFO, -+ "ioh_i2c_xfer invoking " -+ "ioh_i2c_writebytes\n"); -+ ret = -+ ioh_i2c_writebytes(i2c_adap, pmsg, -+ (i + 1 == num), -+ (i == 0)); -+ } -+ } -+ -+ } -+ -+ adap->ioh_i2c_xfer_in_progress = false; /* transfer completed */ -+ -+ IOH_DEBUG(" adap->ioh_i2c_xfer_in_progress is %d\n", -+ adap->ioh_i2c_xfer_in_progress); -+ } -+ IOH_DEBUG(KERN_INFO, "ioh_i2c_xfer return:%d\n\n\n\n", ret); -+ -+ return ret; -+} -diff -urN linux-2.6.33.1/drivers/i2c/busses/pch_i2c_pci.c topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_pci.c ---- linux-2.6.33.1/drivers/i2c/busses/pch_i2c_pci.c 1970-01-01 09:00:00.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/busses/pch_i2c_pci.c 2010-03-23 10:40:18.000000000 +0900 -@@ -0,0 +1,583 @@ -+/*! -+* @file ioh_i2c_pci.c -+* @brief This file contains the definitions of I2C_PCILayer APIs. -+* @version 0.95 -+* @section -+* 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; version 2 of the License. -+* -+* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+*/ -+ -+/* -+* History: -+* Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. -+* All rights reserved. -+* -+* created: -+* WIPRO 02/20/2009 -+* modified: -+* WIPRO 05/21/2009 -+* -+*/ -+ -+/*includes*/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/i2c.h> -+#include <linux/pci.h> -+#include <linux/types.h> -+#include <linux/stat.h> -+#include <linux/interrupt.h> -+ -+#include "pch_i2c_hal.h" -+#include "pch_common.h" -+#include "pch_debug.h" -+ -+/** -+ *macro definition -+ */ -+ -+/*! @ingroup I2C_PCILayer -+@def PCI_DEVICE_ID_IOH_I2C -+@brief Device ID of the device supported by IOH I2C -+ driver in GE configuration. -+*/ -+#define PCI_DEVICE_ID_IOH_I2C (0x8817) -+ -+/* -+ * variable declaration -+ */ -+/*! @ingroup I2C_Global -+@var ioh_i2c_speed -+@brief specifies I2C bus speed in Kbps -+@note This parameter is provided as module parameter -+ while loading the driver. If no value is provided, -+ by default the speed is set to 100 kbps. -+@see ioh_i2c_init -+<hr> -+*/ -+int ioh_i2c_speed = 100; -+ -+/*! @ingroup I2C_Global -+@var ioh_i2c_clock -+@brief specifies I2C clock speed in KHz -+@note This parameter is provided as module parameter -+ while inserting the driver. If no value is provided, -+ by default the speed is set to 62500KHz. -+@see ioh_i2c_init -+<hr> -+*/ -+/* int ioh_i2c_clk = 62500; */ -+int ioh_i2c_clk = 50000; -+ -+/*! @ingroup I2C_Global -+@var ioh_i2c_cbr -+@brief I2C_Global function pointer to save reference to -+ callback function -+@see ioh_i2c_entcb -+<hr> -+*/ -+s32(*ioh_i2c_cbr) (struct i2c_algo_ioh_data *); -+ -+/*! @ingroup I2C_Global -+@var MODULE_NAME -+@brief I2C_Global variable storing the name of this driver -+@see ioh_i2c_probe -+<hr> -+*/ -+#define MODULE_NAME "pch_i2c" /* name for the driver */ -+ -+/* Function prototypes */ -+/*! @ingroup I2C_PCILayerAPI -+@fn ioh_i2c_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id) -+@brief This function implements the probe routine -+ for IOH I2C driver module -+*/ -+static int __devinit ioh_i2c_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id); -+ -+/*! @ingroup I2C_PCILayerAPI -+@fn ioh_i2c_remove(struct pci_dev *pdev) -+@brief This function implements the remove routine -+ for IOH I2C driver module. -+*/ -+static void __devexit ioh_i2c_remove(struct pci_dev *pdev); -+ -+/*! @ingroup I2C_PCILayerAPI -+@fn ioh_i2c_suspend(struct pci_dev* pdev,pm_message_t state) -+@brief This function implements the suspend routine -+ for IOH I2C driver module -+*/ -+static int ioh_i2c_suspend(struct pci_dev *pdev, pm_message_t state); -+ -+/*! @ingroup I2C_PCILayerAPI -+@fn ioh_i2c_resume(struct pci_dev* pdev) -+@brief This function implements the resume routine -+ for IOH I2C driver module -+*/ -+static int ioh_i2c_resume(struct pci_dev *pdev); -+ -+/*structures*/ -+/*! @ingroup I2C_PCILayerFacilitators -+@struct ioh_i2c_pcidev_id -+@brief Store information of supported PCI devices -+@note This is an instance of pci_device_id structure and -+ holds information of the PCI devices that are supported -+ by this driver -+@see ioh_i2c_pcidriver -+*/ -+ -+static struct pci_device_id __devinitdata ioh_i2c_pcidev_id[] = { -+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IOH_I2C)}, -+ {0,} -+}; -+ -+/*! @ingroup I2C_PCILayerFacilitators -+@struct ioh_i2c_pcidriver -+@brief Store the references of PCI driver interfaces to kernel -+@note This is an instance of pci_driver and this structure specifies -+ the driver details to be registered with the kernel -+@see - ioh_i2c_pci_init -+ - ioh_i2c_pci_exit -+<hr> -+*/ -+ -+static struct pci_driver ioh_i2c_pcidriver = { -+ .name = "ioh_i2c", -+ .id_table = ioh_i2c_pcidev_id, -+ .probe = ioh_i2c_probe, -+ .remove = __devexit_p(ioh_i2c_remove), -+#ifdef CONFIG_PM -+ .suspend = ioh_i2c_suspend, -+ .resume = ioh_i2c_resume -+#endif -+}; -+ -+/*! @ingroup I2C_PCILayerAPI -+ @fn ioh_i2c_probe(struct pci_dev *pdev, const struct -+ pci_device_id *id) -+ @remarks The main tasks performed by this method are: -+ - Allocate memory for driver private data. -+ - Enable the PCI device. -+ - Reserve the PCI regions. -+ - Map the device address of the IO BAR. -+ - Register the interrupt handler. -+ - Initialize the members in adap_info->ioh_i2c_data. -+ - Register the ioh_i2c_adapter. -+ - Initialize the IOH I2C hardware. -+ @note This function is invoked by the PCI core when a device is -+ found for this driver to control -+ @param pdev [@ref IN] contains reference to -+ PCI device descriptor for the peripheral -+ @param id [@ref IN] contains reference to -+ the pci_device_id table of matching peripheral -+ @retval int -+ - @ref IOH_I2C_SUCCESS Function returns successfully. -+ - -EIO pci_enable_device fails -+ - -EINVAL pci_enable_device/request_irq fails -+ - -EBUSY pci_request_regions/request_irq fails -+ - -ENOMEM i2c_add_adapter/request_irq/pci_iomap/kzalloc fails -+ - -EAGAIN i2c_add_adapter fails -+ - -ENOSYS request_irq fails -+ @see ioh_i2c_pcidriver -+ <hr> -+ */ -+static int __devinit ioh_i2c_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id) -+{ -+ -+ int i; -+ u32 base_addr; -+ s32 ret = IOH_I2C_SUCCESS; -+ -+ IOH_DEBUG("Enterred in i2c_probe\n"); -+ -+ do { -+ struct adapter_info *adap_info = -+ kzalloc((sizeof(struct adapter_info)), GFP_KERNEL); -+ if (adap_info == NULL) { -+ IOH_LOG(KERN_ERR, "Memory allocation failed FAILED"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ IOH_DEBUG -+ ("Function kzalloc invoked successfully " -+ "and adap_info valu = %p\n", -+ adap_info); -+ -+ ret = pci_enable_device(pdev); -+ -+ if (ret) { -+ IOH_LOG(KERN_ERR, "pci_enable_device FAILED"); -+ kfree(adap_info); -+ break; -+ } -+ -+ IOH_DEBUG("pci_enable_device returns %d\n", ret); -+ -+ ret = pci_request_regions(pdev, MODULE_NAME); -+ if (ret) { -+ IOH_LOG(KERN_ERR, "pci_request_regions FAILED"); -+ pci_disable_device(pdev); -+ kfree(adap_info); -+ break; -+ } -+ -+ IOH_DEBUG("pci_request_regions returns %d\n", ret); -+ -+ /* Wipro 1/13/2010 Use Mem BAR */ -+ base_addr = (unsigned long)pci_iomap(pdev, 1, 0); -+ -+ if (base_addr == 0) { -+ IOH_LOG(KERN_ERR, "pci_iomap FAILED"); -+ pci_release_regions(pdev); -+ pci_disable_device(pdev); -+ kfree(adap_info); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ IOH_DEBUG("pci_iomap invoked successfully\n"); -+ -+ ioh_i2c_entcb(ioh_i2c_cb); -+ IOH_DEBUG("ioh_i2c_entcb invoked successfully\n"); -+ -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) { -+ adap_info->ioh_i2c_data[i].p_adapter_info = adap_info; -+ adap_info->ioh_i2c_data[i].writereg = ioh_i2c_writereg; -+ adap_info->ioh_i2c_data[i].readreg = ioh_i2c_readreg; -+ adap_info->ioh_i2c_data[i].set_reg_bit = ioh_i2c_setbit; -+ adap_info->ioh_i2c_data[i].clr_reg_bit = ioh_i2c_clrbit; -+ -+ adap_info->ioh_i2c_data[i].ioh_i2c_adapter.owner = -+ THIS_MODULE; -+ adap_info->ioh_i2c_data[i].ioh_i2c_adapter.class = -+ I2C_CLASS_HWMON; -+ strcpy(adap_info->ioh_i2c_data[i].ioh_i2c_adapter.name, -+ "ioh_i2c"); -+ adap_info->ioh_i2c_data[i].ioh_i2c_adapter.algo = -+ &ioh_i2c_algorithm; -+ adap_info->ioh_i2c_data[i].ioh_i2c_adapter.algo_data = -+ &adap_info->ioh_i2c_data[i]; -+ -+ /* (i * 0x80) + base_addr; */ -+ adap_info->ioh_i2c_data[i].ioh_i2c_base_address = -+ base_addr; -+ -+ adap_info->ioh_i2c_data[i].ioh_i2c_adapter.dev.parent = -+ &pdev->dev; -+ -+ ret = -+ i2c_add_adapter(& -+ (adap_info->ioh_i2c_data[i]. -+ ioh_i2c_adapter)); -+ -+ if (ret) { -+ IOH_LOG(KERN_ERR, "i2c_add_adapter FAILED"); -+ -+ pci_iounmap(pdev, (void *)base_addr); -+ pci_release_regions(pdev); -+ pci_disable_device(pdev); -+ kfree(adap_info); -+ break; -+ } -+ -+ IOH_DEBUG("i2c_add_adapter returns %d for channel-%d\n", -+ ret, i); -+ (void)ioh_i2c_init(&adap_info->ioh_i2c_data[i]); -+ IOH_DEBUG("ioh_i2c_init invoked successfully \n"); -+ -+ } -+ -+ if (ret) -+ break; -+ -+ ret = request_irq(pdev->irq, &ioh_i2c_handler, IRQF_SHARED, -+ MODULE_NAME, (void *)adap_info); -+ -+ if (ret) { -+ IOH_DEBUG("request_irq Failed\n"); -+ -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) { -+ i2c_del_adapter(& -+ (adap_info-> -+ ioh_i2c_data -+ [i].ioh_i2c_adapter)); -+ } -+ -+ pci_iounmap(pdev, (void *)base_addr); -+ -+ pci_release_regions(pdev); -+ pci_disable_device(pdev); -+ kfree(adap_info); -+ break; -+ } -+ -+ IOH_DEBUG("request_irq returns %d\n", ret); -+ -+ IOH_DEBUG("ioh_i2c_probe returns %d\n", IOH_I2C_SUCCESS); -+ pci_set_drvdata(pdev, (void *)adap_info); -+ return IOH_I2C_SUCCESS; -+ } while (0); -+ -+ return ret; -+} -+ -+/*! @ingroup I2C_PCILayerAPI -+ @fn ioh_i2c_remove(struct pci_dev *pdev) -+ @remarks The main tasks performed by this method are: -+ - Disable interrupts. -+ - Unregister interrupt handler. -+ - Unregister i2c_adapter. -+ - Release IO memory. -+ - Release PCI regions. -+ - Disable PCI device. -+ @note This function is invoked when the IOH I2C driver module is -+ unloaded from the system using rmmod command or when the -+ IOH I2C device is removed from the system. -+ @param pdev [@ref INOUT] contains reference to -+ PCI device descriptor for the peripheral -+ @retval None -+ @see ioh_i2c_pcidriver -+ <hr> -+ */ -+ -+static void __devexit ioh_i2c_remove(struct pci_dev *pdev) -+{ -+ int i; -+ -+ struct adapter_info *adap_info = pci_get_drvdata(pdev); -+ -+ IOH_DEBUG(" invoked function pci_get_drvdata successfully\n"); -+ -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) { -+ ioh_i2c_disbl_int(&adap_info->ioh_i2c_data[i]); -+ -+ if (i == (IOH_I2C_MAX_CHN - 1)) { -+ free_irq(pdev->irq, (void *)adap_info); -+ IOH_DEBUG(" free_irq invoked successfully\n"); -+ } -+ -+ i2c_del_adapter(&(adap_info->ioh_i2c_data[i].ioh_i2c_adapter)); -+ -+ IOH_DEBUG(" invoked i2c_del_adapter successfully\n"); -+ -+ } -+ -+ if (adap_info->ioh_i2c_data[0].ioh_i2c_base_address) { -+ pci_iounmap(pdev, -+ (void *)adap_info->ioh_i2c_data[0]. -+ ioh_i2c_base_address); -+ IOH_DEBUG(" pci_iounmap invoked successfully\n"); -+ adap_info->ioh_i2c_data[0].ioh_i2c_base_address = 0; -+ } -+ -+ pci_set_drvdata(pdev, NULL); -+ -+ pci_release_regions(pdev); -+ IOH_DEBUG(" pci_release_regions invoked successfully\n"); -+ -+ pci_disable_device(pdev); -+ kfree(adap_info); -+ IOH_DEBUG(" pci_disable_device invoked successfully\n"); -+ IOH_DEBUG(" ioh_i2c_remove invoked successfully\n"); -+} -+ -+#ifdef CONFIG_PM -+ -+/*! @ingroup I2C_PCILayerAPI -+ @fn ioh_i2c_suspend(struct pci_dev* pdev,pm_message_t state) -+ @remarks The main tasks performed by this method are: -+ - Wait for any transfer in progress to complete. -+ - Disable interrupts. -+ - Save PCI device state. -+ - Disable PM notifications. -+ - Disable the PCI device. -+ - Move the device to D3Hot power state. -+ @note This function is invoked by the kernel when the system is -+ transitioning to low power state. -+ @param pdev [@ref INOUT] -+ contains reference to PCI device descriptor for the peripheral -+ @param state [@ref IN] -+ Represents the low power state the system is transitioning to. -+ @retval int -+ - @ref IOH_I2C_SUCCESS Function returns successfully. -+ - -ENOMEM pci_save_state fails. -+ @see ioh_i2c_pcidriver -+ */ -+static int ioh_i2c_suspend(struct pci_dev *pdev, pm_message_t state) -+{ -+ -+ int i; -+ int ret; -+ -+ struct adapter_info *adap_info = pci_get_drvdata(pdev); -+ -+ IOH_DEBUG(" invoked function pci_get_drvdata successfully\n"); -+ -+ adap_info->ioh_i2c_suspended = true; -+ -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) { -+ while ((adap_info->ioh_i2c_data[i].ioh_i2c_xfer_in_progress == -+ true)) { -+ /* It is assumed that any pending transfer will -+ * be completed after the delay -+ */ -+ msleep(1); -+ } -+ /* Disable the i2c interrupts */ -+ ioh_i2c_disbl_int(&adap_info->ioh_i2c_data[i]); -+ } -+ -+ IOH_DEBUG("I2CSR = %x\n", -+ ioh_i2c_readreg(adap_info-> -+ ioh_i2c_data[0].ioh_i2c_base_address, 0x08)); -+ IOH_DEBUG("I2CBUFSTA = %x\n", -+ ioh_i2c_readreg(adap_info-> -+ ioh_i2c_data[0].ioh_i2c_base_address, 0x30)); -+ IOH_DEBUG("I2CESRSTA = %x\n", -+ ioh_i2c_readreg(adap_info-> -+ ioh_i2c_data[0].ioh_i2c_base_address, 0x44)); -+ -+ IOH_DEBUG(" invoked function ioh_i2c_disbl_int successfully\n"); -+ -+ ret = pci_save_state(pdev); -+ -+ if (ret) { -+ IOH_LOG(KERN_ERR, "pci_save_state failed\n"); -+ return ret; -+ } -+ -+ IOH_DEBUG("Invoked pci_save_state successfully\n"); -+ -+ pci_enable_wake(pdev, PCI_D3hot, 0); -+ IOH_DEBUG("Invoked pci_enable_wake successfully\n"); -+ -+ pci_disable_device(pdev); -+ IOH_DEBUG("Invoked pci_disable_device successfully\n"); -+ -+ pci_set_power_state(pdev, pci_choose_state(pdev, state)); -+ IOH_DEBUG("Invoked pci_set_power_state successfully\n"); -+ IOH_DEBUG("ioh_i2c_suspend returns %d\n", IOH_I2C_SUCCESS); -+ -+ return IOH_I2C_SUCCESS; -+ -+} -+ -+/*! @ingroup I2C_PCILayerAPI -+ @fn ioh_i2c_resume(struct pci_dev* pdev) -+ @remarks The main tasks performed by this method are: -+ - Move device to D0 power state. -+ - Restore PCI device state. -+ - Enable the PCI device state. -+ - Disable PM notifications. -+ - Initialize IOH I2C device. -+ @note This function is invoked by the kernel when the system is -+ transitioning to normal power state from a lower power state. -+ @param pdev [@ref INOUT] -+ contains reference to PCI device descriptor for the peripheral -+ @retval int -+ - @ref IOH_I2C_SUCCESS Function returns successfully. -+ - -EIO pci_enable_device fails. -+ - -EINVAL pci_enable_device fails. -+ @see ioh_i2c_pcidriver -+ <hr> -+ */ -+static int ioh_i2c_resume(struct pci_dev *pdev) -+{ -+ -+ struct adapter_info *adap_info = pci_get_drvdata(pdev); -+ int i; -+ -+ IOH_DEBUG(" invoked function pci_get_drvdata successfully\n"); -+ -+ pci_set_power_state(pdev, PCI_D0); -+ IOH_DEBUG("Invoked pci_set_power_state successfully\n"); -+ -+ pci_restore_state(pdev); -+ IOH_DEBUG("Invoked pci_restore_state successfully\n"); -+ -+ if (pci_enable_device(pdev) < 0) { -+ IOH_LOG(KERN_ERR, -+ "pci_enable_device failed in ioh_i2c_resume\n"); -+ return -EIO; -+ } -+ -+ pci_enable_wake(pdev, PCI_D3hot, 0); -+ -+ IOH_DEBUG("Invoked pci_enable_wake successfully\n"); -+ -+ for (i = 0; i < IOH_I2C_MAX_CHN; i++) -+ (void)ioh_i2c_init(&adap_info->ioh_i2c_data[i]); -+ -+ IOH_DEBUG("Invoked ioh_i2c_init successfully\n"); -+ -+ adap_info->ioh_i2c_suspended = false; -+ -+ IOH_DEBUG("ioh_i2c_resume return %d\n", IOH_I2C_SUCCESS); -+ return IOH_I2C_SUCCESS; -+} -+ -+#endif -+ -+/*! @ingroup I2C_InterfaceLayerAPI -+ @fn ioh_i2c_pci_init(void) -+ @brief This function implements the module entry point. -+ @remarks This function invoked at module insertion -+ The main task performed by this method: -+ - Register the PCI driver with PCI core -+ using pci_register_driver API. -+ @param None -+ @retval int -+ - 0 Function returns successfully. -+ - -EEXIST pci_register_driver fails -+ - -EINVAL pci_register_driver fails -+ - -ENOMEM pci_register_driver fails -+ <hr> -+ */ -+static int __init ioh_i2c_pci_init(void) -+{ -+ -+ IOH_DEBUG -+ ("ioh_i2c_pci_init : Invoked pci_register_driver successfully\n"); -+ return pci_register_driver(&ioh_i2c_pcidriver); -+} -+ -+/*! @ingroup I2C_InterfaceLayerAPI -+ @fn ioh_i2c_pci_exit(void) -+ @brief This function implements the module exit point. -+ @remarks This function is invoked when IOH I2C driver module is being -+ removed from the system. The main task performed by this method: -+ - Unregister the PCI driver with PCI core using -+ the pci_unregister_driver API -+ @param None -+ @retval None -+ */ -+static void __exit ioh_i2c_pci_exit(void) -+{ -+ IOH_DEBUG -+ ("ioh_i2c_pci_exit : Invoked pci_unregister_driver successfully \n "); -+ pci_unregister_driver(&ioh_i2c_pcidriver); -+ -+} -+ -+MODULE_DESCRIPTION("IOH I2C PCI Driver"); -+MODULE_LICENSE("GPL"); -+module_init(ioh_i2c_pci_init); -+module_exit(ioh_i2c_pci_exit); -+module_param(ioh_i2c_speed, int, (S_IRUSR | S_IWUSR)); -+module_param(ioh_i2c_clk, int, (S_IRUSR | S_IWUSR)); -diff -urN linux-2.6.33.1/drivers/i2c/i2c-dev.c topcliff-2.6.33.1/drivers/i2c/i2c-dev.c ---- linux-2.6.33.1/drivers/i2c/i2c-dev.c 2010-03-16 01:09:39.000000000 +0900 -+++ topcliff-2.6.33.1/drivers/i2c/i2c-dev.c 2010-03-24 11:21:29.000000000 +0900 -@@ -36,7 +36,7 @@ - #include <linux/i2c-dev.h> - #include <linux/jiffies.h> - #include <asm/uaccess.h> -- -+#include "busses/pch_i2c_hal.h" - static struct i2c_driver i2cdev_driver; - - /* -@@ -147,6 +147,11 @@ - if (tmp==NULL) - return -ENOMEM; - -+ if (copy_from_user(tmp, buf, count)) { -+ kfree(tmp); -+ return -EFAULT; -+ } -+ - pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n", - iminor(file->f_path.dentry->d_inode), count); - -@@ -372,6 +377,12 @@ - struct i2c_client *client = (struct i2c_client *)file->private_data; - unsigned long funcs; - -+ unsigned long ioh_mode; -+ int ret; -+ -+ struct i2c_msg msg; -+ unsigned char msgbuf[1]; -+ - dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", - cmd, arg); - -@@ -427,6 +438,22 @@ - */ - client->adapter->timeout = msecs_to_jiffies(arg * 10); - break; -+ case I2C_MODE_SEL: -+ ioh_mode = arg; -+ -+ if (ioh_mode <= 4) { -+ msgbuf[0] = ioh_mode; -+ msg.buf = msgbuf; -+ msg.len = 1; -+ msg.flags = (ioh_mode <=1) ? \ -+ (IOH_BUFFER_MODE_ENABLE) : \ -+ (IOH_EEPROM_SW_RST_MODE_ENABLE); -+ ret = i2c_transfer(client->adapter, &msg, 1); -+ } else { -+ printk(KERN_ERR "I2C mode sel:Invalid mode \n"); -+ ret = -EINVAL; -+ } -+ return ret; - default: - /* NOTE: returning a fault code here could cause trouble - * in buggy userspace code. Some old kernel bugs returned |