| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 2 | /* | 
|---|
| 3 | * Linux I2C core SMBus and SMBus emulation code | 
|---|
| 4 | * | 
|---|
| 5 | * This file contains the SMBus functions which are always included in the I2C | 
|---|
| 6 | * core because they can be emulated via I2C. SMBus specific extensions | 
|---|
| 7 | * (e.g. smbalert) are handled in a separate i2c-smbus module. | 
|---|
| 8 | * | 
|---|
| 9 | * All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | 
|---|
| 10 | * SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and | 
|---|
| 11 | * Jean Delvare <jdelvare@suse.de> | 
|---|
| 12 | */ | 
|---|
| 13 | #include <linux/device.h> | 
|---|
| 14 | #include <linux/err.h> | 
|---|
| 15 | #include <linux/i2c.h> | 
|---|
| 16 | #include <linux/i2c-smbus.h> | 
|---|
| 17 | #include <linux/property.h> | 
|---|
| 18 | #include <linux/slab.h> | 
|---|
| 19 | #include <linux/string_choices.h> | 
|---|
| 20 |  | 
|---|
| 21 | #include "i2c-core.h" | 
|---|
| 22 |  | 
|---|
| 23 | #define CREATE_TRACE_POINTS | 
|---|
| 24 | #include <trace/events/smbus.h> | 
|---|
| 25 |  | 
|---|
| 26 |  | 
|---|
| 27 | /* The SMBus parts */ | 
|---|
| 28 |  | 
|---|
| 29 | #define POLY    (0x1070U << 3) | 
|---|
| 30 | static u8 crc8(u16 data) | 
|---|
| 31 | { | 
|---|
| 32 | int i; | 
|---|
| 33 |  | 
|---|
| 34 | for (i = 0; i < 8; i++) { | 
|---|
| 35 | if (data & 0x8000) | 
|---|
| 36 | data = data ^ POLY; | 
|---|
| 37 | data = data << 1; | 
|---|
| 38 | } | 
|---|
| 39 | return (u8)(data >> 8); | 
|---|
| 40 | } | 
|---|
| 41 |  | 
|---|
| 42 | /** | 
|---|
| 43 | * i2c_smbus_pec - Incremental CRC8 over the given input data array | 
|---|
| 44 | * @crc: previous return crc8 value | 
|---|
| 45 | * @p: pointer to data buffer. | 
|---|
| 46 | * @count: number of bytes in data buffer. | 
|---|
| 47 | * | 
|---|
| 48 | * Incremental CRC8 over count bytes in the array pointed to by p | 
|---|
| 49 | */ | 
|---|
| 50 | u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) | 
|---|
| 51 | { | 
|---|
| 52 | int i; | 
|---|
| 53 |  | 
|---|
| 54 | for (i = 0; i < count; i++) | 
|---|
| 55 | crc = crc8(data: (crc ^ p[i]) << 8); | 
|---|
| 56 | return crc; | 
|---|
| 57 | } | 
|---|
| 58 | EXPORT_SYMBOL(i2c_smbus_pec); | 
|---|
| 59 |  | 
|---|
| 60 | /* Assume a 7-bit address, which is reasonable for SMBus */ | 
|---|
| 61 | static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) | 
|---|
| 62 | { | 
|---|
| 63 | /* The address will be sent first */ | 
|---|
| 64 | u8 addr = i2c_8bit_addr_from_msg(msg); | 
|---|
| 65 | pec = i2c_smbus_pec(pec, &addr, 1); | 
|---|
| 66 |  | 
|---|
| 67 | /* The data buffer follows */ | 
|---|
| 68 | return i2c_smbus_pec(pec, msg->buf, msg->len); | 
|---|
| 69 | } | 
|---|
| 70 |  | 
|---|
| 71 | /* Used for write only transactions */ | 
|---|
| 72 | static inline void i2c_smbus_add_pec(struct i2c_msg *msg) | 
|---|
| 73 | { | 
|---|
| 74 | msg->buf[msg->len] = i2c_smbus_msg_pec(pec: 0, msg); | 
|---|
| 75 | msg->len++; | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|
| 78 | /* Return <0 on CRC error | 
|---|
| 79 | If there was a write before this read (most cases) we need to take the | 
|---|
| 80 | partial CRC from the write part into account. | 
|---|
| 81 | Note that this function does modify the message (we need to decrease the | 
|---|
| 82 | message length to hide the CRC byte from the caller). */ | 
|---|
| 83 | static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) | 
|---|
| 84 | { | 
|---|
| 85 | u8 rpec = msg->buf[--msg->len]; | 
|---|
| 86 | cpec = i2c_smbus_msg_pec(pec: cpec, msg); | 
|---|
| 87 |  | 
|---|
| 88 | if (rpec != cpec) { | 
|---|
| 89 | pr_debug( "Bad PEC 0x%02x vs. 0x%02x\n", | 
|---|
| 90 | rpec, cpec); | 
|---|
| 91 | return -EBADMSG; | 
|---|
| 92 | } | 
|---|
| 93 | return 0; | 
|---|
| 94 | } | 
|---|
| 95 |  | 
|---|
| 96 | /** | 
|---|
| 97 | * i2c_smbus_read_byte - SMBus "receive byte" protocol | 
|---|
| 98 | * @client: Handle to slave device | 
|---|
| 99 | * | 
|---|
| 100 | * This executes the SMBus "receive byte" protocol, returning negative errno | 
|---|
| 101 | * else the byte received from the device. | 
|---|
| 102 | */ | 
|---|
| 103 | s32 i2c_smbus_read_byte(const struct i2c_client *client) | 
|---|
| 104 | { | 
|---|
| 105 | union i2c_smbus_data data; | 
|---|
| 106 | int status; | 
|---|
| 107 |  | 
|---|
| 108 | status = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 109 | I2C_SMBUS_READ, command: 0, | 
|---|
| 110 | I2C_SMBUS_BYTE, data: &data); | 
|---|
| 111 | return (status < 0) ? status : data.byte; | 
|---|
| 112 | } | 
|---|
| 113 | EXPORT_SYMBOL(i2c_smbus_read_byte); | 
|---|
| 114 |  | 
|---|
| 115 | /** | 
|---|
| 116 | * i2c_smbus_write_byte - SMBus "send byte" protocol | 
|---|
| 117 | * @client: Handle to slave device | 
|---|
| 118 | * @value: Byte to be sent | 
|---|
| 119 | * | 
|---|
| 120 | * This executes the SMBus "send byte" protocol, returning negative errno | 
|---|
| 121 | * else zero on success. | 
|---|
| 122 | */ | 
|---|
| 123 | s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) | 
|---|
| 124 | { | 
|---|
| 125 | return i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 126 | I2C_SMBUS_WRITE, command: value, I2C_SMBUS_BYTE, NULL); | 
|---|
| 127 | } | 
|---|
| 128 | EXPORT_SYMBOL(i2c_smbus_write_byte); | 
|---|
| 129 |  | 
|---|
| 130 | /** | 
|---|
| 131 | * i2c_smbus_read_byte_data - SMBus "read byte" protocol | 
|---|
| 132 | * @client: Handle to slave device | 
|---|
| 133 | * @command: Byte interpreted by slave | 
|---|
| 134 | * | 
|---|
| 135 | * This executes the SMBus "read byte" protocol, returning negative errno | 
|---|
| 136 | * else a data byte received from the device. | 
|---|
| 137 | */ | 
|---|
| 138 | s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) | 
|---|
| 139 | { | 
|---|
| 140 | union i2c_smbus_data data; | 
|---|
| 141 | int status; | 
|---|
| 142 |  | 
|---|
| 143 | status = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 144 | I2C_SMBUS_READ, command, | 
|---|
| 145 | I2C_SMBUS_BYTE_DATA, data: &data); | 
|---|
| 146 | return (status < 0) ? status : data.byte; | 
|---|
| 147 | } | 
|---|
| 148 | EXPORT_SYMBOL(i2c_smbus_read_byte_data); | 
|---|
| 149 |  | 
|---|
| 150 | /** | 
|---|
| 151 | * i2c_smbus_write_byte_data - SMBus "write byte" protocol | 
|---|
| 152 | * @client: Handle to slave device | 
|---|
| 153 | * @command: Byte interpreted by slave | 
|---|
| 154 | * @value: Byte being written | 
|---|
| 155 | * | 
|---|
| 156 | * This executes the SMBus "write byte" protocol, returning negative errno | 
|---|
| 157 | * else zero on success. | 
|---|
| 158 | */ | 
|---|
| 159 | s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, | 
|---|
| 160 | u8 value) | 
|---|
| 161 | { | 
|---|
| 162 | union i2c_smbus_data data; | 
|---|
| 163 | data.byte = value; | 
|---|
| 164 | return i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 165 | I2C_SMBUS_WRITE, command, | 
|---|
| 166 | I2C_SMBUS_BYTE_DATA, data: &data); | 
|---|
| 167 | } | 
|---|
| 168 | EXPORT_SYMBOL(i2c_smbus_write_byte_data); | 
|---|
| 169 |  | 
|---|
| 170 | /** | 
|---|
| 171 | * i2c_smbus_read_word_data - SMBus "read word" protocol | 
|---|
| 172 | * @client: Handle to slave device | 
|---|
| 173 | * @command: Byte interpreted by slave | 
|---|
| 174 | * | 
|---|
| 175 | * This executes the SMBus "read word" protocol, returning negative errno | 
|---|
| 176 | * else a 16-bit unsigned "word" received from the device. | 
|---|
| 177 | */ | 
|---|
| 178 | s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) | 
|---|
| 179 | { | 
|---|
| 180 | union i2c_smbus_data data; | 
|---|
| 181 | int status; | 
|---|
| 182 |  | 
|---|
| 183 | status = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 184 | I2C_SMBUS_READ, command, | 
|---|
| 185 | I2C_SMBUS_WORD_DATA, data: &data); | 
|---|
| 186 | return (status < 0) ? status : data.word; | 
|---|
| 187 | } | 
|---|
| 188 | EXPORT_SYMBOL(i2c_smbus_read_word_data); | 
|---|
| 189 |  | 
|---|
| 190 | /** | 
|---|
| 191 | * i2c_smbus_write_word_data - SMBus "write word" protocol | 
|---|
| 192 | * @client: Handle to slave device | 
|---|
| 193 | * @command: Byte interpreted by slave | 
|---|
| 194 | * @value: 16-bit "word" being written | 
|---|
| 195 | * | 
|---|
| 196 | * This executes the SMBus "write word" protocol, returning negative errno | 
|---|
| 197 | * else zero on success. | 
|---|
| 198 | */ | 
|---|
| 199 | s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, | 
|---|
| 200 | u16 value) | 
|---|
| 201 | { | 
|---|
| 202 | union i2c_smbus_data data; | 
|---|
| 203 | data.word = value; | 
|---|
| 204 | return i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 205 | I2C_SMBUS_WRITE, command, | 
|---|
| 206 | I2C_SMBUS_WORD_DATA, data: &data); | 
|---|
| 207 | } | 
|---|
| 208 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | 
|---|
| 209 |  | 
|---|
| 210 | /** | 
|---|
| 211 | * i2c_smbus_read_block_data - SMBus "block read" protocol | 
|---|
| 212 | * @client: Handle to slave device | 
|---|
| 213 | * @command: Byte interpreted by slave | 
|---|
| 214 | * @values: Byte array into which data will be read; big enough to hold | 
|---|
| 215 | *	the data returned by the slave.  SMBus allows at most 32 bytes. | 
|---|
| 216 | * | 
|---|
| 217 | * This executes the SMBus "block read" protocol, returning negative errno | 
|---|
| 218 | * else the number of data bytes in the slave's response. | 
|---|
| 219 | * | 
|---|
| 220 | * Note that using this function requires that the client's adapter support | 
|---|
| 221 | * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality.  Not all adapter drivers | 
|---|
| 222 | * support this; its emulation through I2C messaging relies on a specific | 
|---|
| 223 | * mechanism (I2C_M_RECV_LEN) which may not be implemented. | 
|---|
| 224 | */ | 
|---|
| 225 | s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, | 
|---|
| 226 | u8 *values) | 
|---|
| 227 | { | 
|---|
| 228 | union i2c_smbus_data data; | 
|---|
| 229 | int status; | 
|---|
| 230 |  | 
|---|
| 231 | status = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 232 | I2C_SMBUS_READ, command, | 
|---|
| 233 | I2C_SMBUS_BLOCK_DATA, data: &data); | 
|---|
| 234 | if (status) | 
|---|
| 235 | return status; | 
|---|
| 236 |  | 
|---|
| 237 | memcpy(to: values, from: &data.block[1], len: data.block[0]); | 
|---|
| 238 | return data.block[0]; | 
|---|
| 239 | } | 
|---|
| 240 | EXPORT_SYMBOL(i2c_smbus_read_block_data); | 
|---|
| 241 |  | 
|---|
| 242 | /** | 
|---|
| 243 | * i2c_smbus_write_block_data - SMBus "block write" protocol | 
|---|
| 244 | * @client: Handle to slave device | 
|---|
| 245 | * @command: Byte interpreted by slave | 
|---|
| 246 | * @length: Size of data block; SMBus allows at most 32 bytes | 
|---|
| 247 | * @values: Byte array which will be written. | 
|---|
| 248 | * | 
|---|
| 249 | * This executes the SMBus "block write" protocol, returning negative errno | 
|---|
| 250 | * else zero on success. | 
|---|
| 251 | */ | 
|---|
| 252 | s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, | 
|---|
| 253 | u8 length, const u8 *values) | 
|---|
| 254 | { | 
|---|
| 255 | union i2c_smbus_data data; | 
|---|
| 256 |  | 
|---|
| 257 | if (length > I2C_SMBUS_BLOCK_MAX) | 
|---|
| 258 | length = I2C_SMBUS_BLOCK_MAX; | 
|---|
| 259 | data.block[0] = length; | 
|---|
| 260 | memcpy(to: &data.block[1], from: values, len: length); | 
|---|
| 261 | return i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 262 | I2C_SMBUS_WRITE, command, | 
|---|
| 263 | I2C_SMBUS_BLOCK_DATA, data: &data); | 
|---|
| 264 | } | 
|---|
| 265 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | 
|---|
| 266 |  | 
|---|
| 267 | /* Returns the number of read bytes */ | 
|---|
| 268 | s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, | 
|---|
| 269 | u8 length, u8 *values) | 
|---|
| 270 | { | 
|---|
| 271 | union i2c_smbus_data data; | 
|---|
| 272 | int status; | 
|---|
| 273 |  | 
|---|
| 274 | if (length > I2C_SMBUS_BLOCK_MAX) | 
|---|
| 275 | length = I2C_SMBUS_BLOCK_MAX; | 
|---|
| 276 | data.block[0] = length; | 
|---|
| 277 | status = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 278 | I2C_SMBUS_READ, command, | 
|---|
| 279 | I2C_SMBUS_I2C_BLOCK_DATA, data: &data); | 
|---|
| 280 | if (status < 0) | 
|---|
| 281 | return status; | 
|---|
| 282 |  | 
|---|
| 283 | memcpy(to: values, from: &data.block[1], len: data.block[0]); | 
|---|
| 284 | return data.block[0]; | 
|---|
| 285 | } | 
|---|
| 286 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | 
|---|
| 287 |  | 
|---|
| 288 | s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, | 
|---|
| 289 | u8 length, const u8 *values) | 
|---|
| 290 | { | 
|---|
| 291 | union i2c_smbus_data data; | 
|---|
| 292 |  | 
|---|
| 293 | if (length > I2C_SMBUS_BLOCK_MAX) | 
|---|
| 294 | length = I2C_SMBUS_BLOCK_MAX; | 
|---|
| 295 | data.block[0] = length; | 
|---|
| 296 | memcpy(to: data.block + 1, from: values, len: length); | 
|---|
| 297 | return i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, | 
|---|
| 298 | I2C_SMBUS_WRITE, command, | 
|---|
| 299 | I2C_SMBUS_I2C_BLOCK_DATA, data: &data); | 
|---|
| 300 | } | 
|---|
| 301 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | 
|---|
| 302 |  | 
|---|
| 303 | static void i2c_smbus_try_get_dmabuf(struct i2c_msg *msg, u8 init_val) | 
|---|
| 304 | { | 
|---|
| 305 | bool is_read = msg->flags & I2C_M_RD; | 
|---|
| 306 | unsigned char *dma_buf; | 
|---|
| 307 |  | 
|---|
| 308 | dma_buf = kzalloc(I2C_SMBUS_BLOCK_MAX + (is_read ? 2 : 3), GFP_KERNEL); | 
|---|
| 309 | if (!dma_buf) | 
|---|
| 310 | return; | 
|---|
| 311 |  | 
|---|
| 312 | msg->buf = dma_buf; | 
|---|
| 313 | msg->flags |= I2C_M_DMA_SAFE; | 
|---|
| 314 |  | 
|---|
| 315 | if (init_val) | 
|---|
| 316 | msg->buf[0] = init_val; | 
|---|
| 317 | } | 
|---|
| 318 |  | 
|---|
| 319 | /* | 
|---|
| 320 | * Simulate a SMBus command using the I2C protocol. | 
|---|
| 321 | * No checking of parameters is done! | 
|---|
| 322 | */ | 
|---|
| 323 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, | 
|---|
| 324 | unsigned short flags, | 
|---|
| 325 | char read_write, u8 command, int size, | 
|---|
| 326 | union i2c_smbus_data *data) | 
|---|
| 327 | { | 
|---|
| 328 | /* | 
|---|
| 329 | * So we need to generate a series of msgs. In the case of writing, we | 
|---|
| 330 | * need to use only one message; when reading, we need two. We | 
|---|
| 331 | * initialize most things with sane defaults, to keep the code below | 
|---|
| 332 | * somewhat simpler. | 
|---|
| 333 | */ | 
|---|
| 334 | unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; | 
|---|
| 335 | unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; | 
|---|
| 336 | int nmsgs = read_write == I2C_SMBUS_READ ? 2 : 1; | 
|---|
| 337 | u8 partial_pec = 0; | 
|---|
| 338 | int status; | 
|---|
| 339 | struct i2c_msg msg[2] = { | 
|---|
| 340 | { | 
|---|
| 341 | .addr = addr, | 
|---|
| 342 | .flags = flags, | 
|---|
| 343 | .len = 1, | 
|---|
| 344 | .buf = msgbuf0, | 
|---|
| 345 | }, { | 
|---|
| 346 | .addr = addr, | 
|---|
| 347 | .flags = flags | I2C_M_RD, | 
|---|
| 348 | .len = 0, | 
|---|
| 349 | .buf = msgbuf1, | 
|---|
| 350 | }, | 
|---|
| 351 | }; | 
|---|
| 352 | bool wants_pec = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK | 
|---|
| 353 | && size != I2C_SMBUS_I2C_BLOCK_DATA); | 
|---|
| 354 |  | 
|---|
| 355 | msgbuf0[0] = command; | 
|---|
| 356 | switch (size) { | 
|---|
| 357 | case I2C_SMBUS_QUICK: | 
|---|
| 358 | msg[0].len = 0; | 
|---|
| 359 | /* Special case: The read/write field is used as data */ | 
|---|
| 360 | msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? | 
|---|
| 361 | I2C_M_RD : 0); | 
|---|
| 362 | nmsgs = 1; | 
|---|
| 363 | break; | 
|---|
| 364 | case I2C_SMBUS_BYTE: | 
|---|
| 365 | if (read_write == I2C_SMBUS_READ) { | 
|---|
| 366 | /* Special case: only a read! */ | 
|---|
| 367 | msg[0].flags = I2C_M_RD | flags; | 
|---|
| 368 | nmsgs = 1; | 
|---|
| 369 | } | 
|---|
| 370 | break; | 
|---|
| 371 | case I2C_SMBUS_BYTE_DATA: | 
|---|
| 372 | if (read_write == I2C_SMBUS_READ) | 
|---|
| 373 | msg[1].len = 1; | 
|---|
| 374 | else { | 
|---|
| 375 | msg[0].len = 2; | 
|---|
| 376 | msgbuf0[1] = data->byte; | 
|---|
| 377 | } | 
|---|
| 378 | break; | 
|---|
| 379 | case I2C_SMBUS_WORD_DATA: | 
|---|
| 380 | if (read_write == I2C_SMBUS_READ) | 
|---|
| 381 | msg[1].len = 2; | 
|---|
| 382 | else { | 
|---|
| 383 | msg[0].len = 3; | 
|---|
| 384 | msgbuf0[1] = data->word & 0xff; | 
|---|
| 385 | msgbuf0[2] = data->word >> 8; | 
|---|
| 386 | } | 
|---|
| 387 | break; | 
|---|
| 388 | case I2C_SMBUS_PROC_CALL: | 
|---|
| 389 | nmsgs = 2; /* Special case */ | 
|---|
| 390 | read_write = I2C_SMBUS_READ; | 
|---|
| 391 | msg[0].len = 3; | 
|---|
| 392 | msg[1].len = 2; | 
|---|
| 393 | msgbuf0[1] = data->word & 0xff; | 
|---|
| 394 | msgbuf0[2] = data->word >> 8; | 
|---|
| 395 | break; | 
|---|
| 396 | case I2C_SMBUS_BLOCK_DATA: | 
|---|
| 397 | if (read_write == I2C_SMBUS_READ) { | 
|---|
| 398 | msg[1].flags |= I2C_M_RECV_LEN; | 
|---|
| 399 | msg[1].len = 1; /* block length will be added by | 
|---|
| 400 | the underlying bus driver */ | 
|---|
| 401 | i2c_smbus_try_get_dmabuf(msg: &msg[1], init_val: 0); | 
|---|
| 402 | } else { | 
|---|
| 403 | msg[0].len = data->block[0] + 2; | 
|---|
| 404 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { | 
|---|
| 405 | dev_err(&adapter->dev, | 
|---|
| 406 | "Invalid block write size %d\n", | 
|---|
| 407 | data->block[0]); | 
|---|
| 408 | return -EINVAL; | 
|---|
| 409 | } | 
|---|
| 410 |  | 
|---|
| 411 | i2c_smbus_try_get_dmabuf(msg: &msg[0], init_val: command); | 
|---|
| 412 | memcpy(to: msg[0].buf + 1, from: data->block, len: msg[0].len - 1); | 
|---|
| 413 | } | 
|---|
| 414 | break; | 
|---|
| 415 | case I2C_SMBUS_BLOCK_PROC_CALL: | 
|---|
| 416 | nmsgs = 2; /* Another special case */ | 
|---|
| 417 | read_write = I2C_SMBUS_READ; | 
|---|
| 418 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { | 
|---|
| 419 | dev_err(&adapter->dev, | 
|---|
| 420 | "Invalid block write size %d\n", | 
|---|
| 421 | data->block[0]); | 
|---|
| 422 | return -EINVAL; | 
|---|
| 423 | } | 
|---|
| 424 |  | 
|---|
| 425 | msg[0].len = data->block[0] + 2; | 
|---|
| 426 | i2c_smbus_try_get_dmabuf(msg: &msg[0], init_val: command); | 
|---|
| 427 | memcpy(to: msg[0].buf + 1, from: data->block, len: msg[0].len - 1); | 
|---|
| 428 |  | 
|---|
| 429 | msg[1].flags |= I2C_M_RECV_LEN; | 
|---|
| 430 | msg[1].len = 1; /* block length will be added by | 
|---|
| 431 | the underlying bus driver */ | 
|---|
| 432 | i2c_smbus_try_get_dmabuf(msg: &msg[1], init_val: 0); | 
|---|
| 433 | break; | 
|---|
| 434 | case I2C_SMBUS_I2C_BLOCK_DATA: | 
|---|
| 435 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { | 
|---|
| 436 | dev_err(&adapter->dev, "Invalid block %s size %d\n", | 
|---|
| 437 | str_read_write(read_write == I2C_SMBUS_READ), | 
|---|
| 438 | data->block[0]); | 
|---|
| 439 | return -EINVAL; | 
|---|
| 440 | } | 
|---|
| 441 |  | 
|---|
| 442 | if (read_write == I2C_SMBUS_READ) { | 
|---|
| 443 | msg[1].len = data->block[0]; | 
|---|
| 444 | i2c_smbus_try_get_dmabuf(msg: &msg[1], init_val: 0); | 
|---|
| 445 | } else { | 
|---|
| 446 | msg[0].len = data->block[0] + 1; | 
|---|
| 447 |  | 
|---|
| 448 | i2c_smbus_try_get_dmabuf(msg: &msg[0], init_val: command); | 
|---|
| 449 | memcpy(to: msg[0].buf + 1, from: data->block + 1, len: data->block[0]); | 
|---|
| 450 | } | 
|---|
| 451 | break; | 
|---|
| 452 | default: | 
|---|
| 453 | dev_err(&adapter->dev, "Unsupported transaction %d\n", size); | 
|---|
| 454 | return -EOPNOTSUPP; | 
|---|
| 455 | } | 
|---|
| 456 |  | 
|---|
| 457 | if (wants_pec) { | 
|---|
| 458 | /* Compute PEC if first message is a write */ | 
|---|
| 459 | if (!(msg[0].flags & I2C_M_RD)) { | 
|---|
| 460 | if (nmsgs == 1) /* Write only */ | 
|---|
| 461 | i2c_smbus_add_pec(msg: &msg[0]); | 
|---|
| 462 | else /* Write followed by read */ | 
|---|
| 463 | partial_pec = i2c_smbus_msg_pec(pec: 0, msg: &msg[0]); | 
|---|
| 464 | } | 
|---|
| 465 | /* Ask for PEC if last message is a read */ | 
|---|
| 466 | if (msg[nmsgs - 1].flags & I2C_M_RD) | 
|---|
| 467 | msg[nmsgs - 1].len++; | 
|---|
| 468 | } | 
|---|
| 469 |  | 
|---|
| 470 | status = __i2c_transfer(adap: adapter, msgs: msg, num: nmsgs); | 
|---|
| 471 | if (status < 0) | 
|---|
| 472 | goto cleanup; | 
|---|
| 473 | if (status != nmsgs) { | 
|---|
| 474 | status = -EIO; | 
|---|
| 475 | goto cleanup; | 
|---|
| 476 | } | 
|---|
| 477 | status = 0; | 
|---|
| 478 |  | 
|---|
| 479 | /* Check PEC if last message is a read */ | 
|---|
| 480 | if (wants_pec && (msg[nmsgs - 1].flags & I2C_M_RD)) { | 
|---|
| 481 | status = i2c_smbus_check_pec(cpec: partial_pec, msg: &msg[nmsgs - 1]); | 
|---|
| 482 | if (status < 0) | 
|---|
| 483 | goto cleanup; | 
|---|
| 484 | } | 
|---|
| 485 |  | 
|---|
| 486 | if (read_write == I2C_SMBUS_READ) | 
|---|
| 487 | switch (size) { | 
|---|
| 488 | case I2C_SMBUS_BYTE: | 
|---|
| 489 | data->byte = msgbuf0[0]; | 
|---|
| 490 | break; | 
|---|
| 491 | case I2C_SMBUS_BYTE_DATA: | 
|---|
| 492 | data->byte = msgbuf1[0]; | 
|---|
| 493 | break; | 
|---|
| 494 | case I2C_SMBUS_WORD_DATA: | 
|---|
| 495 | case I2C_SMBUS_PROC_CALL: | 
|---|
| 496 | data->word = msgbuf1[0] | (msgbuf1[1] << 8); | 
|---|
| 497 | break; | 
|---|
| 498 | case I2C_SMBUS_I2C_BLOCK_DATA: | 
|---|
| 499 | memcpy(to: data->block + 1, from: msg[1].buf, len: data->block[0]); | 
|---|
| 500 | break; | 
|---|
| 501 | case I2C_SMBUS_BLOCK_DATA: | 
|---|
| 502 | case I2C_SMBUS_BLOCK_PROC_CALL: | 
|---|
| 503 | if (msg[1].buf[0] > I2C_SMBUS_BLOCK_MAX) { | 
|---|
| 504 | dev_err(&adapter->dev, | 
|---|
| 505 | "Invalid block size returned: %d\n", | 
|---|
| 506 | msg[1].buf[0]); | 
|---|
| 507 | status = -EPROTO; | 
|---|
| 508 | goto cleanup; | 
|---|
| 509 | } | 
|---|
| 510 | memcpy(to: data->block, from: msg[1].buf, len: msg[1].buf[0] + 1); | 
|---|
| 511 | break; | 
|---|
| 512 | } | 
|---|
| 513 |  | 
|---|
| 514 | cleanup: | 
|---|
| 515 | if (msg[0].flags & I2C_M_DMA_SAFE) | 
|---|
| 516 | kfree(objp: msg[0].buf); | 
|---|
| 517 | if (msg[1].flags & I2C_M_DMA_SAFE) | 
|---|
| 518 | kfree(objp: msg[1].buf); | 
|---|
| 519 |  | 
|---|
| 520 | return status; | 
|---|
| 521 | } | 
|---|
| 522 |  | 
|---|
| 523 | /** | 
|---|
| 524 | * i2c_smbus_xfer - execute SMBus protocol operations | 
|---|
| 525 | * @adapter: Handle to I2C bus | 
|---|
| 526 | * @addr: Address of SMBus slave on that bus | 
|---|
| 527 | * @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC) | 
|---|
| 528 | * @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE | 
|---|
| 529 | * @command: Byte interpreted by slave, for protocols which use such bytes | 
|---|
| 530 | * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL | 
|---|
| 531 | * @data: Data to be read or written | 
|---|
| 532 | * | 
|---|
| 533 | * This executes an SMBus protocol operation, and returns a negative | 
|---|
| 534 | * errno code else zero on success. | 
|---|
| 535 | */ | 
|---|
| 536 | s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, | 
|---|
| 537 | unsigned short flags, char read_write, | 
|---|
| 538 | u8 command, int protocol, union i2c_smbus_data *data) | 
|---|
| 539 | { | 
|---|
| 540 | s32 res; | 
|---|
| 541 |  | 
|---|
| 542 | res = __i2c_lock_bus_helper(adap: adapter); | 
|---|
| 543 | if (res) | 
|---|
| 544 | return res; | 
|---|
| 545 |  | 
|---|
| 546 | res = __i2c_smbus_xfer(adapter, addr, flags, read_write, | 
|---|
| 547 | command, protocol, data); | 
|---|
| 548 | i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT); | 
|---|
| 549 |  | 
|---|
| 550 | return res; | 
|---|
| 551 | } | 
|---|
| 552 | EXPORT_SYMBOL(i2c_smbus_xfer); | 
|---|
| 553 |  | 
|---|
| 554 | s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, | 
|---|
| 555 | unsigned short flags, char read_write, | 
|---|
| 556 | u8 command, int protocol, union i2c_smbus_data *data) | 
|---|
| 557 | { | 
|---|
| 558 | int (*xfer_func)(struct i2c_adapter *adap, u16 addr, | 
|---|
| 559 | unsigned short flags, char read_write, | 
|---|
| 560 | u8 command, int size, union i2c_smbus_data *data); | 
|---|
| 561 | unsigned long orig_jiffies; | 
|---|
| 562 | int try; | 
|---|
| 563 | s32 res; | 
|---|
| 564 |  | 
|---|
| 565 | res = __i2c_check_suspended(adap: adapter); | 
|---|
| 566 | if (res) | 
|---|
| 567 | return res; | 
|---|
| 568 |  | 
|---|
| 569 | /* If enabled, the following two tracepoints are conditional on | 
|---|
| 570 | * read_write and protocol. | 
|---|
| 571 | */ | 
|---|
| 572 | trace_smbus_write(adap: adapter, addr, flags, read_write, | 
|---|
| 573 | command, protocol, data); | 
|---|
| 574 | trace_smbus_read(adap: adapter, addr, flags, read_write, | 
|---|
| 575 | command, protocol); | 
|---|
| 576 |  | 
|---|
| 577 | flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; | 
|---|
| 578 |  | 
|---|
| 579 | xfer_func = adapter->algo->smbus_xfer; | 
|---|
| 580 | if (i2c_in_atomic_xfer_mode()) { | 
|---|
| 581 | if (adapter->algo->smbus_xfer_atomic) | 
|---|
| 582 | xfer_func = adapter->algo->smbus_xfer_atomic; | 
|---|
| 583 | else if (adapter->algo->master_xfer_atomic) | 
|---|
| 584 | xfer_func = NULL; /* fallback to I2C emulation */ | 
|---|
| 585 | } | 
|---|
| 586 |  | 
|---|
| 587 | if (xfer_func) { | 
|---|
| 588 | /* Retry automatically on arbitration loss */ | 
|---|
| 589 | orig_jiffies = jiffies; | 
|---|
| 590 | for (res = 0, try = 0; try <= adapter->retries; try++) { | 
|---|
| 591 | res = xfer_func(adapter, addr, flags, read_write, | 
|---|
| 592 | command, protocol, data); | 
|---|
| 593 | if (res != -EAGAIN) | 
|---|
| 594 | break; | 
|---|
| 595 | if (time_after(jiffies, | 
|---|
| 596 | orig_jiffies + adapter->timeout)) | 
|---|
| 597 | break; | 
|---|
| 598 | } | 
|---|
| 599 |  | 
|---|
| 600 | if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) | 
|---|
| 601 | goto trace; | 
|---|
| 602 | /* | 
|---|
| 603 | * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't | 
|---|
| 604 | * implement native support for the SMBus operation. | 
|---|
| 605 | */ | 
|---|
| 606 | } | 
|---|
| 607 |  | 
|---|
| 608 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | 
|---|
| 609 | command, size: protocol, data); | 
|---|
| 610 |  | 
|---|
| 611 | trace: | 
|---|
| 612 | /* If enabled, the reply tracepoint is conditional on read_write. */ | 
|---|
| 613 | trace_smbus_reply(adap: adapter, addr, flags, read_write, | 
|---|
| 614 | command, protocol, data, res); | 
|---|
| 615 | trace_smbus_result(adap: adapter, addr, flags, read_write, | 
|---|
| 616 | command, protocol, res); | 
|---|
| 617 |  | 
|---|
| 618 | return res; | 
|---|
| 619 | } | 
|---|
| 620 | EXPORT_SYMBOL(__i2c_smbus_xfer); | 
|---|
| 621 |  | 
|---|
| 622 | /** | 
|---|
| 623 | * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate | 
|---|
| 624 | * @client: Handle to slave device | 
|---|
| 625 | * @command: Byte interpreted by slave | 
|---|
| 626 | * @length: Size of data block; SMBus allows at most I2C_SMBUS_BLOCK_MAX bytes | 
|---|
| 627 | * @values: Byte array into which data will be read; big enough to hold | 
|---|
| 628 | *	the data returned by the slave.  SMBus allows at most | 
|---|
| 629 | *	I2C_SMBUS_BLOCK_MAX bytes. | 
|---|
| 630 | * | 
|---|
| 631 | * This executes the SMBus "block read" protocol if supported by the adapter. | 
|---|
| 632 | * If block read is not supported, it emulates it using either word or byte | 
|---|
| 633 | * read protocols depending on availability. | 
|---|
| 634 | * | 
|---|
| 635 | * The addresses of the I2C slave device that are accessed with this function | 
|---|
| 636 | * must be mapped to a linear region, so that a block read will have the same | 
|---|
| 637 | * effect as a byte read. Before using this function you must double-check | 
|---|
| 638 | * if the I2C slave does support exchanging a block transfer with a byte | 
|---|
| 639 | * transfer. | 
|---|
| 640 | */ | 
|---|
| 641 | s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, | 
|---|
| 642 | u8 command, u8 length, u8 *values) | 
|---|
| 643 | { | 
|---|
| 644 | u8 i = 0; | 
|---|
| 645 | int status; | 
|---|
| 646 |  | 
|---|
| 647 | if (length > I2C_SMBUS_BLOCK_MAX) | 
|---|
| 648 | length = I2C_SMBUS_BLOCK_MAX; | 
|---|
| 649 |  | 
|---|
| 650 | if (i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) | 
|---|
| 651 | return i2c_smbus_read_i2c_block_data(client, command, length, values); | 
|---|
| 652 |  | 
|---|
| 653 | if (!i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) | 
|---|
| 654 | return -EOPNOTSUPP; | 
|---|
| 655 |  | 
|---|
| 656 | if (i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) { | 
|---|
| 657 | while ((i + 2) <= length) { | 
|---|
| 658 | status = i2c_smbus_read_word_data(client, command + i); | 
|---|
| 659 | if (status < 0) | 
|---|
| 660 | return status; | 
|---|
| 661 | values[i] = status & 0xff; | 
|---|
| 662 | values[i + 1] = status >> 8; | 
|---|
| 663 | i += 2; | 
|---|
| 664 | } | 
|---|
| 665 | } | 
|---|
| 666 |  | 
|---|
| 667 | while (i < length) { | 
|---|
| 668 | status = i2c_smbus_read_byte_data(client, command + i); | 
|---|
| 669 | if (status < 0) | 
|---|
| 670 | return status; | 
|---|
| 671 | values[i] = status; | 
|---|
| 672 | i++; | 
|---|
| 673 | } | 
|---|
| 674 |  | 
|---|
| 675 | return i; | 
|---|
| 676 | } | 
|---|
| 677 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); | 
|---|
| 678 |  | 
|---|
| 679 | /** | 
|---|
| 680 | * i2c_new_smbus_alert_device - get ara client for SMBus alert support | 
|---|
| 681 | * @adapter: the target adapter | 
|---|
| 682 | * @setup: setup data for the SMBus alert handler | 
|---|
| 683 | * Context: can sleep | 
|---|
| 684 | * | 
|---|
| 685 | * Setup handling of the SMBus alert protocol on a given I2C bus segment. | 
|---|
| 686 | * | 
|---|
| 687 | * Handling can be done either through our IRQ handler, or by the | 
|---|
| 688 | * adapter (from its handler, periodic polling, or whatever). | 
|---|
| 689 | * | 
|---|
| 690 | * This returns the ara client, which should be saved for later use with | 
|---|
| 691 | * i2c_handle_smbus_alert() and ultimately i2c_unregister_device(); or an | 
|---|
| 692 | * ERRPTR to indicate an error. | 
|---|
| 693 | */ | 
|---|
| 694 | struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter, | 
|---|
| 695 | struct i2c_smbus_alert_setup *setup) | 
|---|
| 696 | { | 
|---|
| 697 | struct i2c_board_info ara_board_info = { | 
|---|
| 698 | I2C_BOARD_INFO( "smbus_alert", 0x0c), | 
|---|
| 699 | .platform_data = setup, | 
|---|
| 700 | }; | 
|---|
| 701 |  | 
|---|
| 702 | return i2c_new_client_device(adap: adapter, info: &ara_board_info); | 
|---|
| 703 | } | 
|---|
| 704 | EXPORT_SYMBOL_GPL(i2c_new_smbus_alert_device); | 
|---|
| 705 |  | 
|---|
| 706 | #if IS_ENABLED(CONFIG_I2C_SMBUS) | 
|---|
| 707 | int i2c_setup_smbus_alert(struct i2c_adapter *adapter) | 
|---|
| 708 | { | 
|---|
| 709 | struct device *parent = adapter->dev.parent; | 
|---|
| 710 | int irq; | 
|---|
| 711 |  | 
|---|
| 712 | /* Adapter instantiated without parent, skip the SMBus alert setup */ | 
|---|
| 713 | if (!parent) | 
|---|
| 714 | return 0; | 
|---|
| 715 |  | 
|---|
| 716 | /* Report serious errors */ | 
|---|
| 717 | irq = device_property_match_string(dev: parent, propname: "interrupt-names", string: "smbus_alert"); | 
|---|
| 718 | if (irq < 0 && irq != -EINVAL && irq != -ENODATA) | 
|---|
| 719 | return irq; | 
|---|
| 720 |  | 
|---|
| 721 | /* Skip setup when no irq was found */ | 
|---|
| 722 | if (irq < 0 && !device_property_present(dev: parent, propname: "smbalert-gpios")) | 
|---|
| 723 | return 0; | 
|---|
| 724 |  | 
|---|
| 725 | return PTR_ERR_OR_ZERO(ptr: i2c_new_smbus_alert_device(adapter, NULL)); | 
|---|
| 726 | } | 
|---|
| 727 | #endif | 
|---|
| 728 |  | 
|---|