+++ /dev/null
-/*
-  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
-  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions are met:
-
-  * Redistributions of source code must retain the above copyright notice,
-    this list of conditions and the following disclaimer.
-  * Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-       and/or other materials provided with the distribution.
-  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
-    nor the names of its contributors may be used to endorse or promote
-       products derived from this software without specific prior written
-       permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-  POSSIBILITY OF SUCH DAMAGE.
-
-  DESCRIPTION:
-  Part of DRX driver.
-  Data access protocol: Fast Access Sequential Interface (fasi)
-  Fast access, because of short addressing format (16 instead of 32 bits addr)
-  Sequential, because of I2C.
-  These functions know how the chip's memory and registers are to be accessed,
-  but nothing more.
-
-  These functions should not need adapting to a new platform.
-*/
-
-#include "drx_dap_fasi.h"
-#include "drx39xxj.h"
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-
-
-/*============================================================================*/
-
-/*============================================================================*/
-
-/* Functions not supported by protocol*/
-
-static int drxdap_fasi_write_reg8(struct i2c_device_addr *dev_addr,    /* address of I2C device        */
-                                        u32 addr,      /* address of register          */
-                                        u8 data,       /* data to write                */
-                                        u32 flags)
-{                              /* special device flags         */
-       return -EIO;
-}
-
-static int drxdap_fasi_read_reg8(struct i2c_device_addr *dev_addr,     /* address of I2C device        */
-                                       u32 addr,       /* address of register          */
-                                       u8 *data,       /* buffer to receive data       */
-                                       u32 flags)
-{                              /* special device flags         */
-       return -EIO;
-}
-
-static int drxdap_fasi_read_modify_write_reg8(struct i2c_device_addr *dev_addr,        /* address of I2C device        */
-                                                  u32 waddr,   /* address of register          */
-                                                  u32 raddr,   /* address to read back from    */
-                                                  u8 datain,   /* data to send                 */
-                                                  u8 *dataout)
-{                              /* data to receive back         */
-       return -EIO;
-}
-
-static int drxdap_fasi_read_modify_write_reg32(struct i2c_device_addr *dev_addr,       /* address of I2C device        */
-                                                   u32 waddr,  /* address of register          */
-                                                   u32 raddr,  /* address to read back from    */
-                                                   u32 datain, /* data to send                 */
-                                                   u32 *dataout)
-{                              /* data to receive back         */
-       return -EIO;
-}
-
-
-int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
-                                u16 w_count,
-                                u8 *wData,
-                                struct i2c_device_addr *r_dev_addr,
-                                u16 r_count, u8 *r_data)
-{
-       struct drx39xxj_state *state;
-       struct i2c_msg msg[2];
-       unsigned int num_msgs;
-
-       if (w_dev_addr == NULL) {
-               /* Read only */
-               state = r_dev_addr->user_data;
-               msg[0].addr = r_dev_addr->i2c_addr >> 1;
-               msg[0].flags = I2C_M_RD;
-               msg[0].buf = r_data;
-               msg[0].len = r_count;
-               num_msgs = 1;
-       } else if (r_dev_addr == NULL) {
-               /* Write only */
-               state = w_dev_addr->user_data;
-               msg[0].addr = w_dev_addr->i2c_addr >> 1;
-               msg[0].flags = 0;
-               msg[0].buf = wData;
-               msg[0].len = w_count;
-               num_msgs = 1;
-       } else {
-               /* Both write and read */
-               state = w_dev_addr->user_data;
-               msg[0].addr = w_dev_addr->i2c_addr >> 1;
-               msg[0].flags = 0;
-               msg[0].buf = wData;
-               msg[0].len = w_count;
-               msg[1].addr = r_dev_addr->i2c_addr >> 1;
-               msg[1].flags = I2C_M_RD;
-               msg[1].buf = r_data;
-               msg[1].len = r_count;
-               num_msgs = 2;
-       }
-
-       if (state->i2c == NULL) {
-               pr_err("i2c was zero, aborting\n");
-               return 0;
-       }
-       if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
-               pr_warn("drx3933: I2C write/read failed\n");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-
-#ifdef DJH_DEBUG
-       struct drx39xxj_state *state = w_dev_addr->user_data;
-
-       struct i2c_msg msg[2] = {
-               {.addr = w_dev_addr->i2c_addr,
-                .flags = 0, .buf = wData, .len = w_count},
-               {.addr = r_dev_addr->i2c_addr,
-                .flags = I2C_M_RD, .buf = r_data, .len = r_count},
-       };
-
-       pr_dbg("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
-              w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
-
-       if (i2c_transfer(state->i2c, msg, 2) != 2) {
-               pr_warn("drx3933: I2C write/read failed\n");
-               return -EREMOTEIO;
-       }
-#endif
-       return 0;
-}
-
-/*============================================================================*/
-
-/******************************
-*
-* int drxdap_fasi_read_block (
-*      struct i2c_device_addr *dev_addr,      -- address of I2C device
-*      u32 addr,         -- address of chip register/memory
-*      u16            datasize,     -- number of bytes to read
-*      u8 *data,         -- data to receive
-*      u32 flags)        -- special device flags
-*
-* Read block data from chip address. Because the chip is word oriented,
-* the number of bytes to read must be even.
-*
-* Make sure that the buffer to receive the data is large enough.
-*
-* Although this function expects an even number of bytes, it is still byte
-* oriented, and the data read back is NOT translated to the endianness of
-* the target platform.
-*
-* Output:
-* - 0     if reading was successful
-*                  in that case: data read is in *data.
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
-                                        u32 addr,
-                                        u16 datasize,
-                                        u8 *data, u32 flags)
-{
-       u8 buf[4];
-       u16 bufx;
-       int rc;
-       u16 overhead_size = 0;
-
-       /* Check parameters ******************************************************* */
-       if (dev_addr == NULL)
-               return -EINVAL;
-
-       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
-           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
-
-       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
-           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
-            DRXDAP_FASI_LONG_FORMAT(addr)) ||
-           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
-           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
-               return -EINVAL;
-       }
-
-       /* ReadModifyWrite & mode flag bits are not allowed */
-       flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
-#if DRXDAP_SINGLE_MASTER
-       flags |= DRXDAP_FASI_SINGLE_MASTER;
-#endif
-
-       /* Read block from I2C **************************************************** */
-       do {
-               u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
-                             datasize : DRXDAP_MAX_RCHUNKSIZE);
-
-               bufx = 0;
-
-               addr &= ~DRXDAP_FASI_FLAGS;
-               addr |= flags;
-
-#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
-               /* short format address preferred but long format otherwise */
-               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
-#endif
-#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
-                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
-                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
-                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
-                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
-#endif
-#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
-               } else {
-#endif
-#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
-                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
-                       buf[bufx++] =
-                           (u8) (((addr >> 16) & 0x0F) |
-                                   ((addr >> 18) & 0xF0));
-#endif
-#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
-               }
-#endif
-
-#if DRXDAP_SINGLE_MASTER
-               /*
-                * In single master mode, split the read and write actions.
-                * No special action is needed for write chunks here.
-                */
-               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, 0, 0, 0);
-               if (rc == 0)
-                       rc = drxbsp_i2c_write_read(0, 0, 0, dev_addr, todo, data);
-#else
-               /* In multi master mode, do everything in one RW action */
-               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
-                                         data);
-#endif
-               data += todo;
-               addr += (todo >> 1);
-               datasize -= todo;
-       } while (datasize && rc == 0);
-
-       return rc;
-}
-
-
-/******************************
-*
-* int drxdap_fasi_read_reg16 (
-*     struct i2c_device_addr *dev_addr, -- address of I2C device
-*     u32 addr,    -- address of chip register/memory
-*     u16 *data,    -- data to receive
-*     u32 flags)   -- special device flags
-*
-* Read one 16-bit register or memory location. The data received back is
-* converted back to the target platform's endianness.
-*
-* Output:
-* - 0     if reading was successful
-*                  in that case: read data is at *data
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
-                                        u32 addr,
-                                        u16 *data, u32 flags)
-{
-       u8 buf[sizeof(*data)];
-       int rc;
-
-       if (!data)
-               return -EINVAL;
-
-       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
-       *data = buf[0] + (((u16) buf[1]) << 8);
-       return rc;
-}
-
-/******************************
-*
-* int drxdap_fasi_read_reg32 (
-*     struct i2c_device_addr *dev_addr, -- address of I2C device
-*     u32 addr,    -- address of chip register/memory
-*     u32 *data,    -- data to receive
-*     u32 flags)   -- special device flags
-*
-* Read one 32-bit register or memory location. The data received back is
-* converted back to the target platform's endianness.
-*
-* Output:
-* - 0     if reading was successful
-*                  in that case: read data is at *data
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
-                                        u32 addr,
-                                        u32 *data, u32 flags)
-{
-       u8 buf[sizeof(*data)];
-       int rc;
-
-       if (!data)
-               return -EINVAL;
-
-       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
-       *data = (((u32) buf[0]) << 0) +
-           (((u32) buf[1]) << 8) +
-           (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
-       return rc;
-}
-
-/******************************
-*
-* int drxdap_fasi_write_block (
-*      struct i2c_device_addr *dev_addr,    -- address of I2C device
-*      u32 addr,       -- address of chip register/memory
-*      u16            datasize,   -- number of bytes to read
-*      u8 *data,       -- data to receive
-*      u32 flags)      -- special device flags
-*
-* Write block data to chip address. Because the chip is word oriented,
-* the number of bytes to write must be even.
-*
-* Although this function expects an even number of bytes, it is still byte
-* oriented, and the data being written is NOT translated from the endianness of
-* the target platform.
-*
-* Output:
-* - 0     if writing was successful
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
-                                         u32 addr,
-                                         u16 datasize,
-                                         u8 *data, u32 flags)
-{
-       u8 buf[DRXDAP_MAX_WCHUNKSIZE];
-       int st = -EIO;
-       int first_err = 0;
-       u16 overhead_size = 0;
-       u16 block_size = 0;
-
-       /* Check parameters ******************************************************* */
-       if (dev_addr == NULL)
-               return -EINVAL;
-
-       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
-           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
-
-       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
-           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
-            DRXDAP_FASI_LONG_FORMAT(addr)) ||
-           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
-           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
-               return -EINVAL;
-
-       flags &= DRXDAP_FASI_FLAGS;
-       flags &= ~DRXDAP_FASI_MODEFLAGS;
-#if DRXDAP_SINGLE_MASTER
-       flags |= DRXDAP_FASI_SINGLE_MASTER;
-#endif
-
-       /* Write block to I2C ***************************************************** */
-       block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
-       do {
-               u16 todo = 0;
-               u16 bufx = 0;
-
-               /* Buffer device address */
-               addr &= ~DRXDAP_FASI_FLAGS;
-               addr |= flags;
-#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
-               /* short format address preferred but long format otherwise */
-               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
-#endif
-#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
-                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
-                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
-                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
-                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
-#endif
-#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
-               } else {
-#endif
-#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
-                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
-                       buf[bufx++] =
-                           (u8) (((addr >> 16) & 0x0F) |
-                                   ((addr >> 18) & 0xF0));
-#endif
-#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
-               }
-#endif
-
-               /*
-                  In single master mode block_size can be 0. In such a case this I2C
-                  sequense will be visible: (1) write address {i2c addr,
-                  4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
-                  (3) write address (4) write data etc...
-                  Addres must be rewriten because HI is reset after data transport and
-                  expects an address.
-                */
-               todo = (block_size < datasize ? block_size : datasize);
-               if (todo == 0) {
-                       u16 overhead_size_i2c_addr = 0;
-                       u16 data_block_size = 0;
-
-                       overhead_size_i2c_addr =
-                           (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
-                       data_block_size =
-                           (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
-
-                       /* write device address */
-                       st = drxbsp_i2c_write_read(dev_addr,
-                                                 (u16) (bufx),
-                                                 buf,
-                                                 (struct i2c_device_addr *)(NULL),
-                                                 0, (u8 *)(NULL));
-
-                       if ((st != 0) && (first_err == 0)) {
-                               /* at the end, return the first error encountered */
-                               first_err = st;
-                       }
-                       bufx = 0;
-                       todo =
-                           (data_block_size <
-                            datasize ? data_block_size : datasize);
-               }
-               memcpy(&buf[bufx], data, todo);
-               /* write (address if can do and) data */
-               st = drxbsp_i2c_write_read(dev_addr,
-                                         (u16) (bufx + todo),
-                                         buf,
-                                         (struct i2c_device_addr *)(NULL),
-                                         0, (u8 *)(NULL));
-
-               if ((st != 0) && (first_err == 0)) {
-                       /* at the end, return the first error encountered */
-                       first_err = st;
-               }
-               datasize -= todo;
-               data += todo;
-               addr += (todo >> 1);
-       } while (datasize);
-
-       return first_err;
-}
-
-/******************************
-*
-* int drxdap_fasi_write_reg16 (
-*     struct i2c_device_addr *dev_addr, -- address of I2C device
-*     u32 addr,    -- address of chip register/memory
-*     u16            data,    -- data to send
-*     u32 flags)   -- special device flags
-*
-* Write one 16-bit register or memory location. The data being written is
-* converted from the target platform's endianness to little endian.
-*
-* Output:
-* - 0     if writing was successful
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
-                                         u32 addr,
-                                         u16 data, u32 flags)
-{
-       u8 buf[sizeof(data)];
-
-       buf[0] = (u8) ((data >> 0) & 0xFF);
-       buf[1] = (u8) ((data >> 8) & 0xFF);
-
-       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
-}
-
-/******************************
-*
-* int drxdap_fasi_read_modify_write_reg16 (
-*      struct i2c_device_addr *dev_addr,   -- address of I2C device
-*      u32 waddr,     -- address of chip register/memory
-*      u32 raddr,     -- chip address to read back from
-*      u16            wdata,     -- data to send
-*      u16 *rdata)     -- data to receive back
-*
-* Write 16-bit data, then read back the original contents of that location.
-* Requires long addressing format to be allowed.
-*
-* Before sending data, the data is converted to little endian. The
-* data received back is converted back to the target platform's endianness.
-*
-* WARNING: This function is only guaranteed to work if there is one
-* master on the I2C bus.
-*
-* Output:
-* - 0     if reading was successful
-*                  in that case: read back data is at *rdata
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
-                                                   u32 waddr,
-                                                   u32 raddr,
-                                                   u16 wdata, u16 *rdata)
-{
-       int rc = -EIO;
-
-#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
-       if (rdata == NULL)
-               return -EINVAL;
-
-       rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
-       if (rc == 0)
-               rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
-#endif
-
-       return rc;
-}
-
-/******************************
-*
-* int drxdap_fasi_write_reg32 (
-*     struct i2c_device_addr *dev_addr, -- address of I2C device
-*     u32 addr,    -- address of chip register/memory
-*     u32            data,    -- data to send
-*     u32 flags)   -- special device flags
-*
-* Write one 32-bit register or memory location. The data being written is
-* converted from the target platform's endianness to little endian.
-*
-* Output:
-* - 0     if writing was successful
-* - -EIO  if anything went wrong
-*
-******************************/
-
-static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
-                                         u32 addr,
-                                         u32 data, u32 flags)
-{
-       u8 buf[sizeof(data)];
-
-       buf[0] = (u8) ((data >> 0) & 0xFF);
-       buf[1] = (u8) ((data >> 8) & 0xFF);
-       buf[2] = (u8) ((data >> 16) & 0xFF);
-       buf[3] = (u8) ((data >> 24) & 0xFF);
-
-       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
-}
-
-/* The structure containing the protocol interface */
-struct drx_access_func drx_dap_fasi_funct_g = {
-       drxdap_fasi_write_block,        /* Supported */
-       drxdap_fasi_read_block, /* Supported */
-       drxdap_fasi_write_reg8, /* Not supported */
-       drxdap_fasi_read_reg8,  /* Not supported */
-       drxdap_fasi_read_modify_write_reg8,     /* Not supported */
-       drxdap_fasi_write_reg16,        /* Supported */
-       drxdap_fasi_read_reg16, /* Supported */
-       drxdap_fasi_read_modify_write_reg16,    /* Supported */
-       drxdap_fasi_write_reg32,        /* Supported */
-       drxdap_fasi_read_reg32, /* Supported */
-       drxdap_fasi_read_modify_write_reg32     /* Not supported */
-};
 
 
 /*============================================================================*/
 
+/* Functions not supported by protocol*/
+
+static int drxdap_fasi_write_reg8(struct i2c_device_addr *dev_addr,    /* address of I2C device        */
+                                        u32 addr,      /* address of register          */
+                                        u8 data,       /* data to write                */
+                                        u32 flags)
+{                              /* special device flags         */
+       return -EIO;
+}
+
+static int drxdap_fasi_read_reg8(struct i2c_device_addr *dev_addr,     /* address of I2C device        */
+                                       u32 addr,       /* address of register          */
+                                       u8 *data,       /* buffer to receive data       */
+                                       u32 flags)
+{                              /* special device flags         */
+       return -EIO;
+}
+
+static int drxdap_fasi_read_modify_write_reg8(struct i2c_device_addr *dev_addr,        /* address of I2C device        */
+                                                  u32 waddr,   /* address of register          */
+                                                  u32 raddr,   /* address to read back from    */
+                                                  u8 datain,   /* data to send                 */
+                                                  u8 *dataout)
+{                              /* data to receive back         */
+       return -EIO;
+}
+
+static int drxdap_fasi_read_modify_write_reg32(struct i2c_device_addr *dev_addr,       /* address of I2C device        */
+                                                   u32 waddr,  /* address of register          */
+                                                   u32 raddr,  /* address to read back from    */
+                                                   u32 datain, /* data to send                 */
+                                                   u32 *dataout)
+{                              /* data to receive back         */
+       return -EIO;
+}
+
+
+int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
+                                u16 w_count,
+                                u8 *wData,
+                                struct i2c_device_addr *r_dev_addr,
+                                u16 r_count, u8 *r_data)
+{
+       struct drx39xxj_state *state;
+       struct i2c_msg msg[2];
+       unsigned int num_msgs;
+
+       if (w_dev_addr == NULL) {
+               /* Read only */
+               state = r_dev_addr->user_data;
+               msg[0].addr = r_dev_addr->i2c_addr >> 1;
+               msg[0].flags = I2C_M_RD;
+               msg[0].buf = r_data;
+               msg[0].len = r_count;
+               num_msgs = 1;
+       } else if (r_dev_addr == NULL) {
+               /* Write only */
+               state = w_dev_addr->user_data;
+               msg[0].addr = w_dev_addr->i2c_addr >> 1;
+               msg[0].flags = 0;
+               msg[0].buf = wData;
+               msg[0].len = w_count;
+               num_msgs = 1;
+       } else {
+               /* Both write and read */
+               state = w_dev_addr->user_data;
+               msg[0].addr = w_dev_addr->i2c_addr >> 1;
+               msg[0].flags = 0;
+               msg[0].buf = wData;
+               msg[0].len = w_count;
+               msg[1].addr = r_dev_addr->i2c_addr >> 1;
+               msg[1].flags = I2C_M_RD;
+               msg[1].buf = r_data;
+               msg[1].len = r_count;
+               num_msgs = 2;
+       }
+
+       if (state->i2c == NULL) {
+               pr_err("i2c was zero, aborting\n");
+               return 0;
+       }
+       if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
+               pr_warn("drx3933: I2C write/read failed\n");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+
+#ifdef DJH_DEBUG
+       struct drx39xxj_state *state = w_dev_addr->user_data;
+
+       struct i2c_msg msg[2] = {
+               {.addr = w_dev_addr->i2c_addr,
+                .flags = 0, .buf = wData, .len = w_count},
+               {.addr = r_dev_addr->i2c_addr,
+                .flags = I2C_M_RD, .buf = r_data, .len = r_count},
+       };
+
+       pr_dbg("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
+              w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               pr_warn("drx3933: I2C write/read failed\n");
+               return -EREMOTEIO;
+       }
+#endif
+       return 0;
+}
+
+/*============================================================================*/
+
+/******************************
+*
+* int drxdap_fasi_read_block (
+*      struct i2c_device_addr *dev_addr,      -- address of I2C device
+*      u32 addr,         -- address of chip register/memory
+*      u16            datasize,     -- number of bytes to read
+*      u8 *data,         -- data to receive
+*      u32 flags)        -- special device flags
+*
+* Read block data from chip address. Because the chip is word oriented,
+* the number of bytes to read must be even.
+*
+* Make sure that the buffer to receive the data is large enough.
+*
+* Although this function expects an even number of bytes, it is still byte
+* oriented, and the data read back is NOT translated to the endianness of
+* the target platform.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: data read is in *data.
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u16 datasize,
+                                        u8 *data, u32 flags)
+{
+       u8 buf[4];
+       u16 bufx;
+       int rc;
+       u16 overhead_size = 0;
+
+       /* Check parameters ******************************************************* */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
+           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
+
+       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
+           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
+            DRXDAP_FASI_LONG_FORMAT(addr)) ||
+           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
+           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
+               return -EINVAL;
+       }
+
+       /* ReadModifyWrite & mode flag bits are not allowed */
+       flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
+#if DRXDAP_SINGLE_MASTER
+       flags |= DRXDAP_FASI_SINGLE_MASTER;
+#endif
+
+       /* Read block from I2C **************************************************** */
+       do {
+               u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
+                             datasize : DRXDAP_MAX_RCHUNKSIZE);
+
+               bufx = 0;
+
+               addr &= ~DRXDAP_FASI_FLAGS;
+               addr |= flags;
+
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               /* short format address preferred but long format otherwise */
+               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
+#endif
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
+                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
+                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               } else {
+#endif
+#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
+                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
+                       buf[bufx++] =
+                           (u8) (((addr >> 16) & 0x0F) |
+                                   ((addr >> 18) & 0xF0));
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               }
+#endif
+
+#if DRXDAP_SINGLE_MASTER
+               /*
+                * In single master mode, split the read and write actions.
+                * No special action is needed for write chunks here.
+                */
+               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, 0, 0, 0);
+               if (rc == 0)
+                       rc = drxbsp_i2c_write_read(0, 0, 0, dev_addr, todo, data);
+#else
+               /* In multi master mode, do everything in one RW action */
+               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
+                                         data);
+#endif
+               data += todo;
+               addr += (todo >> 1);
+               datasize -= todo;
+       } while (datasize && rc == 0);
+
+       return rc;
+}
+
+
+/******************************
+*
+* int drxdap_fasi_read_reg16 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u16 *data,    -- data to receive
+*     u32 flags)   -- special device flags
+*
+* Read one 16-bit register or memory location. The data received back is
+* converted back to the target platform's endianness.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read data is at *data
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u16 *data, u32 flags)
+{
+       u8 buf[sizeof(*data)];
+       int rc;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
+       *data = buf[0] + (((u16) buf[1]) << 8);
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_read_reg32 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u32 *data,    -- data to receive
+*     u32 flags)   -- special device flags
+*
+* Read one 32-bit register or memory location. The data received back is
+* converted back to the target platform's endianness.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read data is at *data
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u32 *data, u32 flags)
+{
+       u8 buf[sizeof(*data)];
+       int rc;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
+       *data = (((u32) buf[0]) << 0) +
+           (((u32) buf[1]) << 8) +
+           (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_block (
+*      struct i2c_device_addr *dev_addr,    -- address of I2C device
+*      u32 addr,       -- address of chip register/memory
+*      u16            datasize,   -- number of bytes to read
+*      u8 *data,       -- data to receive
+*      u32 flags)      -- special device flags
+*
+* Write block data to chip address. Because the chip is word oriented,
+* the number of bytes to write must be even.
+*
+* Although this function expects an even number of bytes, it is still byte
+* oriented, and the data being written is NOT translated from the endianness of
+* the target platform.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 datasize,
+                                         u8 *data, u32 flags)
+{
+       u8 buf[DRXDAP_MAX_WCHUNKSIZE];
+       int st = -EIO;
+       int first_err = 0;
+       u16 overhead_size = 0;
+       u16 block_size = 0;
+
+       /* Check parameters ******************************************************* */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
+           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
+
+       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
+           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
+            DRXDAP_FASI_LONG_FORMAT(addr)) ||
+           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
+           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
+               return -EINVAL;
+
+       flags &= DRXDAP_FASI_FLAGS;
+       flags &= ~DRXDAP_FASI_MODEFLAGS;
+#if DRXDAP_SINGLE_MASTER
+       flags |= DRXDAP_FASI_SINGLE_MASTER;
+#endif
+
+       /* Write block to I2C ***************************************************** */
+       block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
+       do {
+               u16 todo = 0;
+               u16 bufx = 0;
+
+               /* Buffer device address */
+               addr &= ~DRXDAP_FASI_FLAGS;
+               addr |= flags;
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               /* short format address preferred but long format otherwise */
+               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
+                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
+                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
+#endif
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               } else {
+#endif
+#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
+                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
+                       buf[bufx++] =
+                           (u8) (((addr >> 16) & 0x0F) |
+                                   ((addr >> 18) & 0xF0));
+#endif
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               }
+#endif
+
+               /*
+                  In single master mode block_size can be 0. In such a case this I2C
+                  sequense will be visible: (1) write address {i2c addr,
+                  4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
+                  (3) write address (4) write data etc...
+                  Addres must be rewriten because HI is reset after data transport and
+                  expects an address.
+                */
+               todo = (block_size < datasize ? block_size : datasize);
+               if (todo == 0) {
+                       u16 overhead_size_i2c_addr = 0;
+                       u16 data_block_size = 0;
+
+                       overhead_size_i2c_addr =
+                           (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
+                       data_block_size =
+                           (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
+
+                       /* write device address */
+                       st = drxbsp_i2c_write_read(dev_addr,
+                                                 (u16) (bufx),
+                                                 buf,
+                                                 (struct i2c_device_addr *)(NULL),
+                                                 0, (u8 *)(NULL));
+
+                       if ((st != 0) && (first_err == 0)) {
+                               /* at the end, return the first error encountered */
+                               first_err = st;
+                       }
+                       bufx = 0;
+                       todo =
+                           (data_block_size <
+                            datasize ? data_block_size : datasize);
+               }
+               memcpy(&buf[bufx], data, todo);
+               /* write (address if can do and) data */
+               st = drxbsp_i2c_write_read(dev_addr,
+                                         (u16) (bufx + todo),
+                                         buf,
+                                         (struct i2c_device_addr *)(NULL),
+                                         0, (u8 *)(NULL));
+
+               if ((st != 0) && (first_err == 0)) {
+                       /* at the end, return the first error encountered */
+                       first_err = st;
+               }
+               datasize -= todo;
+               data += todo;
+               addr += (todo >> 1);
+       } while (datasize);
+
+       return first_err;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_reg16 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u16            data,    -- data to send
+*     u32 flags)   -- special device flags
+*
+* Write one 16-bit register or memory location. The data being written is
+* converted from the target platform's endianness to little endian.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 data, u32 flags)
+{
+       u8 buf[sizeof(data)];
+
+       buf[0] = (u8) ((data >> 0) & 0xFF);
+       buf[1] = (u8) ((data >> 8) & 0xFF);
+
+       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
+}
+
+/******************************
+*
+* int drxdap_fasi_read_modify_write_reg16 (
+*      struct i2c_device_addr *dev_addr,   -- address of I2C device
+*      u32 waddr,     -- address of chip register/memory
+*      u32 raddr,     -- chip address to read back from
+*      u16            wdata,     -- data to send
+*      u16 *rdata)     -- data to receive back
+*
+* Write 16-bit data, then read back the original contents of that location.
+* Requires long addressing format to be allowed.
+*
+* Before sending data, the data is converted to little endian. The
+* data received back is converted back to the target platform's endianness.
+*
+* WARNING: This function is only guaranteed to work if there is one
+* master on the I2C bus.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read back data is at *rdata
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
+                                                   u32 waddr,
+                                                   u32 raddr,
+                                                   u16 wdata, u16 *rdata)
+{
+       int rc = -EIO;
+
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
+       if (rdata == NULL)
+               return -EINVAL;
+
+       rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
+       if (rc == 0)
+               rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
+#endif
+
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_reg32 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u32            data,    -- data to send
+*     u32 flags)   -- special device flags
+*
+* Write one 32-bit register or memory location. The data being written is
+* converted from the target platform's endianness to little endian.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u32 data, u32 flags)
+{
+       u8 buf[sizeof(data)];
+
+       buf[0] = (u8) ((data >> 0) & 0xFF);
+       buf[1] = (u8) ((data >> 8) & 0xFF);
+       buf[2] = (u8) ((data >> 16) & 0xFF);
+       buf[3] = (u8) ((data >> 24) & 0xFF);
+
+       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
+}
+
+/* The structure containing the protocol interface */
+struct drx_access_func drx_dap_fasi_funct_g = {
+       drxdap_fasi_write_block,        /* Supported */
+       drxdap_fasi_read_block, /* Supported */
+       drxdap_fasi_write_reg8, /* Not supported */
+       drxdap_fasi_read_reg8,  /* Not supported */
+       drxdap_fasi_read_modify_write_reg8,     /* Not supported */
+       drxdap_fasi_write_reg16,        /* Supported */
+       drxdap_fasi_read_reg16, /* Supported */
+       drxdap_fasi_read_modify_write_reg16,    /* Supported */
+       drxdap_fasi_write_reg32,        /* Supported */
+       drxdap_fasi_read_reg32, /* Supported */
+       drxdap_fasi_read_modify_write_reg32     /* Not supported */
+};
+
 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
                                      u32 addr,
                                      u16 datasize,