1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/** \file server/drivers/i2c.c
* OS agnostic functions to access i2c devices.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/ioctl.h>
#ifdef HAVE_DEV_IICBUS_IIC_H
#include <dev/iicbus/iic.h>
#else /* HAVE_LINUX_I2C_DEV_H */
#include <linux/i2c-dev.h>
/* I2C_SLAVE is missing in linux/i2c-dev.h from kernel headers of 2.4.x kernels
*/
#ifndef I2C_SLAVE
#define I2C_SLAVE 0x0703 /* ioctl to change slave address */
#endif
#endif
#define I2C_DEFAULT_DEVICE "/dev/i2c-0"
/** data to access an i2c slave */
typedef struct {
int fd; /**< file descriptor of the i2c device */
#ifdef HAVE_DEV_IICBUS_IIC_H
unsigned int slave; /**< slave address */
#endif
} I2CHandle;
/**
* setup connection to i2c slave
* \param device device file of the i2c bus
* \param addr use this slave address
* \retval NULL Error
* \retval Pointer to handle of the connection
*/
I2CHandle *i2c_open(const char *device, unsigned int addr)
{
I2CHandle *h;
#ifdef HAVE_DEV_IICBUS_IIC_H
struct iiccmd cmd;
bzero(&cmd, sizeof(cmd));
#endif
h = malloc(sizeof(*h));
if(!h)
return NULL;
h->fd = open(device, O_RDWR);
if(h->fd < 0)
goto free;
#ifdef HAVE_DEV_IICBUS_IIC_H
cmd.slave = h->slave = addr << 1;
cmd.last = 0;
cmd.count = 0;
if (ioctl(h->fd, I2CRSTCARD, &cmd) < 0)
goto close;
if (ioctl(h->fd, I2CSTART, &cmd) < 0)
goto close;
#else /* HAVE_LINUX_I2C_DEV_H */
if (ioctl(h->fd, I2C_SLAVE, addr) < 0) {
goto close;
}
#endif
return h;
close:
close(h->fd);
free:
free(h);
return NULL;
}
/**
* close connection to i2c slave
*/
void i2c_close(I2CHandle *h)
{
#ifdef HAVE_DEV_IICBUS_IIC_H
ioctl(h->fd, I2CSTOP);
#endif
close(h->fd);
free(h);
}
/**
* write data to an i2c slave
* \param h Handle of i2c slave
* \param buf Buffer to send to the device
* \param count Number of bytes to write
* \retval >=0 Success.
* \retval <0 Error.
*/
int i2c_write(I2CHandle *h, void *buf, unsigned int count)
{
#ifdef HAVE_DEV_IICBUS_IIC_H
struct iiccmd cmd;
bzero(&cmd, sizeof(cmd));
cmd.slave = h->slave;
cmd.last = 1;
cmd.count = count;
cmd.buf = buf;
return ioctl(h->fd, I2CWRITE, &cmd);
#else /* HAVE_LINUX_I2C_DEV_H */
if (write(h->fd, buf, count) != count)
return -1;
return 0;
#endif
}
|