ads1115 analog-to-digital 4-channel added
[i2c-telemetry.git] / smbus.c
1 /*
2     smbus.c - SMBus level access helper functions
3
4     Copyright (C) 1995-97 Simon G. Vogl
5     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
6     Copyright (C) 2012    Jean Delvare <khali@linux-fr.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21     MA 02110-1301 USA.
22 */
23
24 #include <errno.h>
25 #include "smbus.h"      // NB: Path changed!
26 #include <sys/ioctl.h>
27 #include <linux/types.h>
28 #include <linux/i2c.h>
29 #include <linux/i2c-dev.h>
30
31 //NB: Added by John Burns
32 #ifndef NULL
33 #define NULL 0
34 #endif
35
36 /* Compatibility defines */
37 #ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
38 #define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
39 #endif
40 #ifndef I2C_FUNC_SMBUS_PEC
41 #define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
42 #endif
43
44 __s32 i2c_smbus_access(int file, char read_write, __u8 command,
45                        int size, union i2c_smbus_data *data)
46 {
47         struct i2c_smbus_ioctl_data args;
48         __s32 err;
49
50         args.read_write = read_write;
51         args.command = command;
52         args.size = size;
53         args.data = data;
54
55         err = ioctl(file, I2C_SMBUS, &args);
56         if (err == -1)
57                 err = -errno;
58         return err;
59 }
60
61
62 __s32 i2c_smbus_write_quick(int file, __u8 value)
63 {
64         return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
65 }
66
67 __s32 i2c_smbus_read_byte(int file)
68 {
69         union i2c_smbus_data data;
70         int err;
71
72         err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
73         if (err < 0)
74                 return err;
75
76         return 0x0FF & data.byte;
77 }
78
79 __s32 i2c_smbus_write_byte(int file, __u8 value)
80 {
81         return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
82                                 I2C_SMBUS_BYTE, NULL);
83 }
84
85 __s32 i2c_smbus_read_byte_data(int file, __u8 command)
86 {
87         union i2c_smbus_data data;
88         int err;
89
90         err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
91                                I2C_SMBUS_BYTE_DATA, &data);
92         if (err < 0)
93                 return err;
94
95         return 0x0FF & data.byte;
96 }
97
98 __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
99 {
100         union i2c_smbus_data data;
101         data.byte = value;
102         return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
103                                 I2C_SMBUS_BYTE_DATA, &data);
104 }
105
106 __s32 i2c_smbus_read_word_data(int file, __u8 command)
107 {
108         union i2c_smbus_data data;
109         int err;
110
111         err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
112                                I2C_SMBUS_WORD_DATA, &data);
113         if (err < 0)
114                 return err;
115
116         return 0x0FFFF & data.word;
117 }
118
119 __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)
120 {
121         union i2c_smbus_data data;
122         data.word = value;
123         return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
124                                 I2C_SMBUS_WORD_DATA, &data);
125 }
126
127 __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
128 {
129         union i2c_smbus_data data;
130         data.word = value;
131         if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
132                              I2C_SMBUS_PROC_CALL, &data))
133                 return -1;
134         else
135                 return 0x0FFFF & data.word;
136 }
137
138 /* Returns the number of read bytes */
139 __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)
140 {
141         union i2c_smbus_data data;
142         int i, err;
143
144         err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
145                                I2C_SMBUS_BLOCK_DATA, &data);
146         if (err < 0)
147                 return err;
148
149         for (i = 1; i <= data.block[0]; i++)
150                 values[i-1] = data.block[i];
151         return data.block[0];
152 }
153
154 __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
155                                  const __u8 *values)
156 {
157         union i2c_smbus_data data;
158         int i;
159         if (length > I2C_SMBUS_BLOCK_MAX)
160                 length = I2C_SMBUS_BLOCK_MAX;
161         for (i = 1; i <= length; i++)
162                 data.block[i] = values[i-1];
163         data.block[0] = length;
164         return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
165                                 I2C_SMBUS_BLOCK_DATA, &data);
166 }
167
168 /* Returns the number of read bytes */
169 /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
170    ask for less than 32 bytes, your code will only work with kernels
171    2.6.23 and later. */
172 __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
173                                     __u8 *values)
174 {
175         union i2c_smbus_data data;
176         int i, err;
177
178         if (length > I2C_SMBUS_BLOCK_MAX)
179                 length = I2C_SMBUS_BLOCK_MAX;
180         data.block[0] = length;
181
182         err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
183                                length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
184                                 I2C_SMBUS_I2C_BLOCK_DATA, &data);
185         if (err < 0)
186                 return err;
187
188         for (i = 1; i <= data.block[0]; i++)
189                 values[i-1] = data.block[i];
190         return data.block[0];
191 }
192
193 __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
194                                      const __u8 *values)
195 {
196         union i2c_smbus_data data;
197         int i;
198         if (length > I2C_SMBUS_BLOCK_MAX)
199                 length = I2C_SMBUS_BLOCK_MAX;
200         for (i = 1; i <= length; i++)
201                 data.block[i] = values[i-1];
202         data.block[0] = length;
203         return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
204                                 I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
205 }
206
207 /* Returns the number of read bytes */
208 __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
209                                    __u8 *values)
210 {
211         union i2c_smbus_data data;
212         int i, err;
213
214         if (length > I2C_SMBUS_BLOCK_MAX)
215                 length = I2C_SMBUS_BLOCK_MAX;
216         for (i = 1; i <= length; i++)
217                 data.block[i] = values[i-1];
218         data.block[0] = length;
219
220         err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
221                                I2C_SMBUS_BLOCK_PROC_CALL, &data);
222         if (err < 0)
223                 return err;
224
225         for (i = 1; i <= data.block[0]; i++)
226                 values[i-1] = data.block[i];
227         return data.block[0];
228 }