/*
    i2c-dev.h - i2c-bus driver, char device interface

    Copyright (C) 1995-97 Simon G. Vogl
    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/* $Id: i2c-dev.h,v 1.3 1999/12/21 23:45:58 frodo Exp $ */

#ifndef I2C_DEV_H
#define I2C_DEV_H


#include <linux/types.h>
#include <linux/i2c.h>

/* Some IOCTL commands are defined in <linux/i2c.h> */
/* Note: 10-bit addresses are NOT supported! */

/* This is the structure as used in the I2C_SMBUS ioctl call */
struct i2c_smbus_ioctl_data {
  char read_write;
  __u8 command;
  int size;
  union i2c_smbus_data *data;
};

#ifndef __KERNEL__

#include <sys/ioctl.h>

extern inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, 
                                     int size, union i2c_smbus_data *data)
{
  struct i2c_smbus_ioctl_data args;

  args.read_write = read_write;
  args.command = command;
  args.size = size;
  args.data = data;
  return ioctl(file,I2C_SMBUS,&args);
}


extern inline __s32 i2c_smbus_write_quick(int file, __u8 value)
{
  return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
}

extern inline __s32 i2c_smbus_read_byte(int file)
{
  union i2c_smbus_data data;
  if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
    return -1;
  else
    return 0x0FF & data.byte;
}

extern inline __s32 i2c_smbus_write_byte(int file, __u8 value)
{
  return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,NULL);
}

extern inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
  union i2c_smbus_data data;
  if (i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_BYTE_DATA,&data))
    return -1;
  else
    return 0x0FF & data.byte;
}

extern inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, 
                                              __u8 value)
{
  union i2c_smbus_data data;
  data.byte = value;
  return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,I2C_SMBUS_BYTE_DATA,
                          &data);
}

extern inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
{
  union i2c_smbus_data data;
  if (i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_WORD_DATA,&data))
    return -1;
  else
    return 0x0FFFF & data.word;
}

extern inline __s32 i2c_smbus_write_word_data(int file, __u8 command, 
                                              __u16 value)
{
  union i2c_smbus_data data;
  data.word = value;
  return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,I2C_SMBUS_WORD_DATA, 
                          &data);
}

extern inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
{
  union i2c_smbus_data data;
  data.word = value;
  if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,I2C_SMBUS_PROC_CALL,&data))
    return -1;
  else
    return 0x0FFFF & data.word;
}


/* Returns the number of read bytes */
extern inline __s32 i2c_smbus_read_block_data(int file, __u8 command, 
                                              __u8 *values)
{
  union i2c_smbus_data data;
  int i;
  if (i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_BLOCK_DATA,&data))
    return -1;
  else {
    for (i = 1; i <= data.block[0]; i++)
      values[i-1] = data.block[i];
    return data.block[0];
  }
}

extern inline __s32 i2c_smbus_write_block_data(int file, __u8 command, 
                                               __u8 length, __u8 *values)
{
  union i2c_smbus_data data;
  int i;
  if (length > 32)
    length = 32;
  for (i = 1; i <= length; i++)
    data.block[i] = values[i-1];
  data.block[0] = length;
  return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,I2C_SMBUS_BLOCK_DATA,
                          &data);
}

#endif /* ndef __KERNEL__ */

#endif
