File: i2c.c

package info (click to toggle)
lcdproc 0.5.9-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,088 kB
  • sloc: ansic: 59,645; sh: 1,740; perl: 681; makefile: 417
file content (120 lines) | stat: -rw-r--r-- 2,341 bytes parent folder | download | duplicates (4)
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
}