/* bq.h: include for BQ gauge interface
 * No #defines or globals are needed for external operation; use only the defined functions
 * 
 */

#ifndef BQ_H_
#define BQ_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#define BQADDR 0x55
#define ADAPTER_NR 2

// i2cfile: contains current handle for i2c file
static int i2cfile;

/* curraddr: contains current slave address we are using
 * This is necessary because the IOCTL_RDWR ioctl requires you to specify the address for each message
 * since this address might change (if we enter ROM mode on the BQ device), we need to keep track of
 * which one we are using.
 */
static unsigned char curraddr;

/*
 * In order to write to the BQ gauge, we must write an additional 8 bit subaddress to read from.
 * Therefore, we cannot use the read() function, and must use the IOCTL_RDWR ioctl.  This requires
 * the following structure:
 */
typedef struct i2c_rdwr_ioctl_data_s {
	struct i2c_msg *msgs;	/* pointers to i2c_msgs */
	__u32 nmsgs;			/* number of i2c_msgs */
} i2c_rdwr_ioctl_data;

/*
 * bq_dataram structure: this structure contains all of the data from the gauge's dataram and should
 * suffice for most purposes.  Note that the structure is in the same order as the addresses on the gauge.
 * This means that we can copy directly from the gauge to the structure without re-ordering the bytes.
 */
typedef struct bq_dataram_s {
	unsigned short Control;
	short AtRate;
	unsigned short AtRateTTE;
	short Temp;
	unsigned short Voltage;
	unsigned short Flags;
	unsigned short NomAvailCap;
	unsigned short FullAvailCap;
	unsigned short RemCap;
	unsigned short FullChgCap;
	short AvgCurr;
	unsigned short TTE;
	unsigned short TTF;
	unsigned short StbyCurr;
	unsigned short StbyTTE;
	unsigned short MaxLoadCurr;
	unsigned short MaxLoadTTE;
	unsigned short AvailEnergy;
	unsigned short AvgPow;
	unsigned short TTEAtConstPow;
	unsigned short CycleCnt;
	unsigned short StateOfChg;
} bq_dataram;

/*
 * Initbq(): Initialize the i2c bus to communicate with the BQ gauge
 * Arguments: None
 * Returns: failure code if failed, otherwise ioctl success value (0)
 */
int initbq();

/*
 * seti2caddr: Sets the I2C address to a custom value
 * Should NOT be neccessary in normal operation.  Only needed if you enter ROM mode to reflash device.
 * Arguments: unsigned char addr: 8 bit address value (lower 7 bits are the address)
 * Returns: ioctl failure code on failure: 0 otherwise
 */
int seti2caddr(unsigned char addr);

/*
 * writebq: write a string of bytes to the BQ gauge
 * Arguments:	unsigned char cmd: subaddress value: this is the address on the gauge that you are writing to
 * 	                    unsigned char * buf: pointer to string of bytes that you will write
 *                     int cnt: number of bytes you will write
 * Returns: write failure code on failure, otherwise number of bytes written 
 */
int writebq(unsigned char cmd, unsigned char* buf, int cnt);

/*
 * readbq: reads bytes from BQ gauge
 * Arguments:	unsigned char cmd: subaddress: this is the address on the gauge that you will read from
 *                     unsigned char* buf: buffer that you will read into
 *                     int cnt: number of bytes to read into buffer
 */
int readbq(unsigned char cmd,unsigned char* buf, int cnt);

/*
 * readbqdataram: Reads entirity of BQ gauge dataram into a bq_dataram structure (defined in bq.h)
 * Arguments:	bq_dataram *dr: pointer to structure
 * Returns: ioctl failure code on fail, otherwise 0
 */
int readbqdataram(bq_dataram *dr);

/*
 * closebq: close the BQ gauge handle
 * Arguments: void
 * Returns: 0
 */
int closebq();

#endif /*BQ_H_*/
