diff options
author | Wolfram Sang <wsa@the-dreams.de> | 2017-05-23 06:27:17 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2017-05-31 15:01:03 -0400 |
commit | 22c78d1cce104072747023d2ae0351bf3f97d725 (patch) | |
tree | 03c552b637a825ce43e838233671a63c74a2de8e | |
parent | e4991ecdc6b8ad2b21f3d6e90ef826b8871103a2 (diff) |
i2c: break out smbus support into separate file
Break out the exported SMBus functions and the emulation layer into a
separate file. This also involved splitting up the tracing header into
an I2C and an SMBus part.
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | Documentation/driver-api/i2c.rst | 3 | ||||
-rw-r--r-- | drivers/i2c/Makefile | 2 | ||||
-rw-r--r-- | drivers/i2c/i2c-core-base.c | 574 | ||||
-rw-r--r-- | drivers/i2c/i2c-core-smbus.c | 594 | ||||
-rw-r--r-- | include/trace/events/i2c.h | 226 | ||||
-rw-r--r-- | include/trace/events/smbus.h | 249 |
6 files changed, 849 insertions, 799 deletions
diff --git a/Documentation/driver-api/i2c.rst b/Documentation/driver-api/i2c.rst index e6d4808ffbab..c215503801f0 100644 --- a/Documentation/driver-api/i2c.rst +++ b/Documentation/driver-api/i2c.rst | |||
@@ -44,3 +44,6 @@ i2c_adapter devices which don't support those I2C operations. | |||
44 | 44 | ||
45 | .. kernel-doc:: drivers/i2c/i2c-core-base.c | 45 | .. kernel-doc:: drivers/i2c/i2c-core-base.c |
46 | :export: | 46 | :export: |
47 | |||
48 | .. kernel-doc:: drivers/i2c/i2c-core-smbus.c | ||
49 | :export: | ||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 6c54716e7f28..a6a90fe2db88 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o | 5 | obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o |
6 | obj-$(CONFIG_I2C) += i2c-core.o | 6 | obj-$(CONFIG_I2C) += i2c-core.o |
7 | i2c-core-objs := i2c-core-base.o | 7 | i2c-core-objs := i2c-core-base.o i2c-core-smbus.o |
8 | i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o | 8 | i2c-core-$(CONFIG_I2C_SLAVE) += i2c-core-slave.o |
9 | 9 | ||
10 | obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o | 10 | obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o |
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 88c0ca664a7b..70fc4624c69c 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c | |||
@@ -14,9 +14,6 @@ | |||
14 | /* ------------------------------------------------------------------------- */ | 14 | /* ------------------------------------------------------------------------- */ |
15 | 15 | ||
16 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. | 16 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. |
17 | All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | ||
18 | SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and | ||
19 | Jean Delvare <jdelvare@suse.de> | ||
20 | Mux support by Rodolfo Giometti <giometti@enneenne.com> and | 17 | Mux support by Rodolfo Giometti <giometti@enneenne.com> and |
21 | Michael Lawnick <michael.lawnick.ext@nsn.com> | 18 | Michael Lawnick <michael.lawnick.ext@nsn.com> |
22 | OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de> | 19 | OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de> |
@@ -3155,577 +3152,6 @@ void i2c_put_adapter(struct i2c_adapter *adap) | |||
3155 | } | 3152 | } |
3156 | EXPORT_SYMBOL(i2c_put_adapter); | 3153 | EXPORT_SYMBOL(i2c_put_adapter); |
3157 | 3154 | ||
3158 | /* The SMBus parts */ | ||
3159 | |||
3160 | #define POLY (0x1070U << 3) | ||
3161 | static u8 crc8(u16 data) | ||
3162 | { | ||
3163 | int i; | ||
3164 | |||
3165 | for (i = 0; i < 8; i++) { | ||
3166 | if (data & 0x8000) | ||
3167 | data = data ^ POLY; | ||
3168 | data = data << 1; | ||
3169 | } | ||
3170 | return (u8)(data >> 8); | ||
3171 | } | ||
3172 | |||
3173 | /* Incremental CRC8 over count bytes in the array pointed to by p */ | ||
3174 | static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) | ||
3175 | { | ||
3176 | int i; | ||
3177 | |||
3178 | for (i = 0; i < count; i++) | ||
3179 | crc = crc8((crc ^ p[i]) << 8); | ||
3180 | return crc; | ||
3181 | } | ||
3182 | |||
3183 | /* Assume a 7-bit address, which is reasonable for SMBus */ | ||
3184 | static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) | ||
3185 | { | ||
3186 | /* The address will be sent first */ | ||
3187 | u8 addr = i2c_8bit_addr_from_msg(msg); | ||
3188 | pec = i2c_smbus_pec(pec, &addr, 1); | ||
3189 | |||
3190 | /* The data buffer follows */ | ||
3191 | return i2c_smbus_pec(pec, msg->buf, msg->len); | ||
3192 | } | ||
3193 | |||
3194 | /* Used for write only transactions */ | ||
3195 | static inline void i2c_smbus_add_pec(struct i2c_msg *msg) | ||
3196 | { | ||
3197 | msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg); | ||
3198 | msg->len++; | ||
3199 | } | ||
3200 | |||
3201 | /* Return <0 on CRC error | ||
3202 | If there was a write before this read (most cases) we need to take the | ||
3203 | partial CRC from the write part into account. | ||
3204 | Note that this function does modify the message (we need to decrease the | ||
3205 | message length to hide the CRC byte from the caller). */ | ||
3206 | static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) | ||
3207 | { | ||
3208 | u8 rpec = msg->buf[--msg->len]; | ||
3209 | cpec = i2c_smbus_msg_pec(cpec, msg); | ||
3210 | |||
3211 | if (rpec != cpec) { | ||
3212 | pr_debug("Bad PEC 0x%02x vs. 0x%02x\n", | ||
3213 | rpec, cpec); | ||
3214 | return -EBADMSG; | ||
3215 | } | ||
3216 | return 0; | ||
3217 | } | ||
3218 | |||
3219 | /** | ||
3220 | * i2c_smbus_read_byte - SMBus "receive byte" protocol | ||
3221 | * @client: Handle to slave device | ||
3222 | * | ||
3223 | * This executes the SMBus "receive byte" protocol, returning negative errno | ||
3224 | * else the byte received from the device. | ||
3225 | */ | ||
3226 | s32 i2c_smbus_read_byte(const struct i2c_client *client) | ||
3227 | { | ||
3228 | union i2c_smbus_data data; | ||
3229 | int status; | ||
3230 | |||
3231 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3232 | I2C_SMBUS_READ, 0, | ||
3233 | I2C_SMBUS_BYTE, &data); | ||
3234 | return (status < 0) ? status : data.byte; | ||
3235 | } | ||
3236 | EXPORT_SYMBOL(i2c_smbus_read_byte); | ||
3237 | |||
3238 | /** | ||
3239 | * i2c_smbus_write_byte - SMBus "send byte" protocol | ||
3240 | * @client: Handle to slave device | ||
3241 | * @value: Byte to be sent | ||
3242 | * | ||
3243 | * This executes the SMBus "send byte" protocol, returning negative errno | ||
3244 | * else zero on success. | ||
3245 | */ | ||
3246 | s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) | ||
3247 | { | ||
3248 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3249 | I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); | ||
3250 | } | ||
3251 | EXPORT_SYMBOL(i2c_smbus_write_byte); | ||
3252 | |||
3253 | /** | ||
3254 | * i2c_smbus_read_byte_data - SMBus "read byte" protocol | ||
3255 | * @client: Handle to slave device | ||
3256 | * @command: Byte interpreted by slave | ||
3257 | * | ||
3258 | * This executes the SMBus "read byte" protocol, returning negative errno | ||
3259 | * else a data byte received from the device. | ||
3260 | */ | ||
3261 | s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) | ||
3262 | { | ||
3263 | union i2c_smbus_data data; | ||
3264 | int status; | ||
3265 | |||
3266 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3267 | I2C_SMBUS_READ, command, | ||
3268 | I2C_SMBUS_BYTE_DATA, &data); | ||
3269 | return (status < 0) ? status : data.byte; | ||
3270 | } | ||
3271 | EXPORT_SYMBOL(i2c_smbus_read_byte_data); | ||
3272 | |||
3273 | /** | ||
3274 | * i2c_smbus_write_byte_data - SMBus "write byte" protocol | ||
3275 | * @client: Handle to slave device | ||
3276 | * @command: Byte interpreted by slave | ||
3277 | * @value: Byte being written | ||
3278 | * | ||
3279 | * This executes the SMBus "write byte" protocol, returning negative errno | ||
3280 | * else zero on success. | ||
3281 | */ | ||
3282 | s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, | ||
3283 | u8 value) | ||
3284 | { | ||
3285 | union i2c_smbus_data data; | ||
3286 | data.byte = value; | ||
3287 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3288 | I2C_SMBUS_WRITE, command, | ||
3289 | I2C_SMBUS_BYTE_DATA, &data); | ||
3290 | } | ||
3291 | EXPORT_SYMBOL(i2c_smbus_write_byte_data); | ||
3292 | |||
3293 | /** | ||
3294 | * i2c_smbus_read_word_data - SMBus "read word" protocol | ||
3295 | * @client: Handle to slave device | ||
3296 | * @command: Byte interpreted by slave | ||
3297 | * | ||
3298 | * This executes the SMBus "read word" protocol, returning negative errno | ||
3299 | * else a 16-bit unsigned "word" received from the device. | ||
3300 | */ | ||
3301 | s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) | ||
3302 | { | ||
3303 | union i2c_smbus_data data; | ||
3304 | int status; | ||
3305 | |||
3306 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3307 | I2C_SMBUS_READ, command, | ||
3308 | I2C_SMBUS_WORD_DATA, &data); | ||
3309 | return (status < 0) ? status : data.word; | ||
3310 | } | ||
3311 | EXPORT_SYMBOL(i2c_smbus_read_word_data); | ||
3312 | |||
3313 | /** | ||
3314 | * i2c_smbus_write_word_data - SMBus "write word" protocol | ||
3315 | * @client: Handle to slave device | ||
3316 | * @command: Byte interpreted by slave | ||
3317 | * @value: 16-bit "word" being written | ||
3318 | * | ||
3319 | * This executes the SMBus "write word" protocol, returning negative errno | ||
3320 | * else zero on success. | ||
3321 | */ | ||
3322 | s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, | ||
3323 | u16 value) | ||
3324 | { | ||
3325 | union i2c_smbus_data data; | ||
3326 | data.word = value; | ||
3327 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3328 | I2C_SMBUS_WRITE, command, | ||
3329 | I2C_SMBUS_WORD_DATA, &data); | ||
3330 | } | ||
3331 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | ||
3332 | |||
3333 | /** | ||
3334 | * i2c_smbus_read_block_data - SMBus "block read" protocol | ||
3335 | * @client: Handle to slave device | ||
3336 | * @command: Byte interpreted by slave | ||
3337 | * @values: Byte array into which data will be read; big enough to hold | ||
3338 | * the data returned by the slave. SMBus allows at most 32 bytes. | ||
3339 | * | ||
3340 | * This executes the SMBus "block read" protocol, returning negative errno | ||
3341 | * else the number of data bytes in the slave's response. | ||
3342 | * | ||
3343 | * Note that using this function requires that the client's adapter support | ||
3344 | * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality. Not all adapter drivers | ||
3345 | * support this; its emulation through I2C messaging relies on a specific | ||
3346 | * mechanism (I2C_M_RECV_LEN) which may not be implemented. | ||
3347 | */ | ||
3348 | s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, | ||
3349 | u8 *values) | ||
3350 | { | ||
3351 | union i2c_smbus_data data; | ||
3352 | int status; | ||
3353 | |||
3354 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3355 | I2C_SMBUS_READ, command, | ||
3356 | I2C_SMBUS_BLOCK_DATA, &data); | ||
3357 | if (status) | ||
3358 | return status; | ||
3359 | |||
3360 | memcpy(values, &data.block[1], data.block[0]); | ||
3361 | return data.block[0]; | ||
3362 | } | ||
3363 | EXPORT_SYMBOL(i2c_smbus_read_block_data); | ||
3364 | |||
3365 | /** | ||
3366 | * i2c_smbus_write_block_data - SMBus "block write" protocol | ||
3367 | * @client: Handle to slave device | ||
3368 | * @command: Byte interpreted by slave | ||
3369 | * @length: Size of data block; SMBus allows at most 32 bytes | ||
3370 | * @values: Byte array which will be written. | ||
3371 | * | ||
3372 | * This executes the SMBus "block write" protocol, returning negative errno | ||
3373 | * else zero on success. | ||
3374 | */ | ||
3375 | s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, | ||
3376 | u8 length, const u8 *values) | ||
3377 | { | ||
3378 | union i2c_smbus_data data; | ||
3379 | |||
3380 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
3381 | length = I2C_SMBUS_BLOCK_MAX; | ||
3382 | data.block[0] = length; | ||
3383 | memcpy(&data.block[1], values, length); | ||
3384 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3385 | I2C_SMBUS_WRITE, command, | ||
3386 | I2C_SMBUS_BLOCK_DATA, &data); | ||
3387 | } | ||
3388 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | ||
3389 | |||
3390 | /* Returns the number of read bytes */ | ||
3391 | s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, | ||
3392 | u8 length, u8 *values) | ||
3393 | { | ||
3394 | union i2c_smbus_data data; | ||
3395 | int status; | ||
3396 | |||
3397 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
3398 | length = I2C_SMBUS_BLOCK_MAX; | ||
3399 | data.block[0] = length; | ||
3400 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3401 | I2C_SMBUS_READ, command, | ||
3402 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
3403 | if (status < 0) | ||
3404 | return status; | ||
3405 | |||
3406 | memcpy(values, &data.block[1], data.block[0]); | ||
3407 | return data.block[0]; | ||
3408 | } | ||
3409 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | ||
3410 | |||
3411 | s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, | ||
3412 | u8 length, const u8 *values) | ||
3413 | { | ||
3414 | union i2c_smbus_data data; | ||
3415 | |||
3416 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
3417 | length = I2C_SMBUS_BLOCK_MAX; | ||
3418 | data.block[0] = length; | ||
3419 | memcpy(data.block + 1, values, length); | ||
3420 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
3421 | I2C_SMBUS_WRITE, command, | ||
3422 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
3423 | } | ||
3424 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | ||
3425 | |||
3426 | /* Simulate a SMBus command using the i2c protocol | ||
3427 | No checking of parameters is done! */ | ||
3428 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, | ||
3429 | unsigned short flags, | ||
3430 | char read_write, u8 command, int size, | ||
3431 | union i2c_smbus_data *data) | ||
3432 | { | ||
3433 | /* So we need to generate a series of msgs. In the case of writing, we | ||
3434 | need to use only one message; when reading, we need two. We initialize | ||
3435 | most things with sane defaults, to keep the code below somewhat | ||
3436 | simpler. */ | ||
3437 | unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; | ||
3438 | unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; | ||
3439 | int num = read_write == I2C_SMBUS_READ ? 2 : 1; | ||
3440 | int i; | ||
3441 | u8 partial_pec = 0; | ||
3442 | int status; | ||
3443 | struct i2c_msg msg[2] = { | ||
3444 | { | ||
3445 | .addr = addr, | ||
3446 | .flags = flags, | ||
3447 | .len = 1, | ||
3448 | .buf = msgbuf0, | ||
3449 | }, { | ||
3450 | .addr = addr, | ||
3451 | .flags = flags | I2C_M_RD, | ||
3452 | .len = 0, | ||
3453 | .buf = msgbuf1, | ||
3454 | }, | ||
3455 | }; | ||
3456 | |||
3457 | msgbuf0[0] = command; | ||
3458 | switch (size) { | ||
3459 | case I2C_SMBUS_QUICK: | ||
3460 | msg[0].len = 0; | ||
3461 | /* Special case: The read/write field is used as data */ | ||
3462 | msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? | ||
3463 | I2C_M_RD : 0); | ||
3464 | num = 1; | ||
3465 | break; | ||
3466 | case I2C_SMBUS_BYTE: | ||
3467 | if (read_write == I2C_SMBUS_READ) { | ||
3468 | /* Special case: only a read! */ | ||
3469 | msg[0].flags = I2C_M_RD | flags; | ||
3470 | num = 1; | ||
3471 | } | ||
3472 | break; | ||
3473 | case I2C_SMBUS_BYTE_DATA: | ||
3474 | if (read_write == I2C_SMBUS_READ) | ||
3475 | msg[1].len = 1; | ||
3476 | else { | ||
3477 | msg[0].len = 2; | ||
3478 | msgbuf0[1] = data->byte; | ||
3479 | } | ||
3480 | break; | ||
3481 | case I2C_SMBUS_WORD_DATA: | ||
3482 | if (read_write == I2C_SMBUS_READ) | ||
3483 | msg[1].len = 2; | ||
3484 | else { | ||
3485 | msg[0].len = 3; | ||
3486 | msgbuf0[1] = data->word & 0xff; | ||
3487 | msgbuf0[2] = data->word >> 8; | ||
3488 | } | ||
3489 | break; | ||
3490 | case I2C_SMBUS_PROC_CALL: | ||
3491 | num = 2; /* Special case */ | ||
3492 | read_write = I2C_SMBUS_READ; | ||
3493 | msg[0].len = 3; | ||
3494 | msg[1].len = 2; | ||
3495 | msgbuf0[1] = data->word & 0xff; | ||
3496 | msgbuf0[2] = data->word >> 8; | ||
3497 | break; | ||
3498 | case I2C_SMBUS_BLOCK_DATA: | ||
3499 | if (read_write == I2C_SMBUS_READ) { | ||
3500 | msg[1].flags |= I2C_M_RECV_LEN; | ||
3501 | msg[1].len = 1; /* block length will be added by | ||
3502 | the underlying bus driver */ | ||
3503 | } else { | ||
3504 | msg[0].len = data->block[0] + 2; | ||
3505 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { | ||
3506 | dev_err(&adapter->dev, | ||
3507 | "Invalid block write size %d\n", | ||
3508 | data->block[0]); | ||
3509 | return -EINVAL; | ||
3510 | } | ||
3511 | for (i = 1; i < msg[0].len; i++) | ||
3512 | msgbuf0[i] = data->block[i-1]; | ||
3513 | } | ||
3514 | break; | ||
3515 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
3516 | num = 2; /* Another special case */ | ||
3517 | read_write = I2C_SMBUS_READ; | ||
3518 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { | ||
3519 | dev_err(&adapter->dev, | ||
3520 | "Invalid block write size %d\n", | ||
3521 | data->block[0]); | ||
3522 | return -EINVAL; | ||
3523 | } | ||
3524 | msg[0].len = data->block[0] + 2; | ||
3525 | for (i = 1; i < msg[0].len; i++) | ||
3526 | msgbuf0[i] = data->block[i-1]; | ||
3527 | msg[1].flags |= I2C_M_RECV_LEN; | ||
3528 | msg[1].len = 1; /* block length will be added by | ||
3529 | the underlying bus driver */ | ||
3530 | break; | ||
3531 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
3532 | if (read_write == I2C_SMBUS_READ) { | ||
3533 | msg[1].len = data->block[0]; | ||
3534 | } else { | ||
3535 | msg[0].len = data->block[0] + 1; | ||
3536 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { | ||
3537 | dev_err(&adapter->dev, | ||
3538 | "Invalid block write size %d\n", | ||
3539 | data->block[0]); | ||
3540 | return -EINVAL; | ||
3541 | } | ||
3542 | for (i = 1; i <= data->block[0]; i++) | ||
3543 | msgbuf0[i] = data->block[i]; | ||
3544 | } | ||
3545 | break; | ||
3546 | default: | ||
3547 | dev_err(&adapter->dev, "Unsupported transaction %d\n", size); | ||
3548 | return -EOPNOTSUPP; | ||
3549 | } | ||
3550 | |||
3551 | i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK | ||
3552 | && size != I2C_SMBUS_I2C_BLOCK_DATA); | ||
3553 | if (i) { | ||
3554 | /* Compute PEC if first message is a write */ | ||
3555 | if (!(msg[0].flags & I2C_M_RD)) { | ||
3556 | if (num == 1) /* Write only */ | ||
3557 | i2c_smbus_add_pec(&msg[0]); | ||
3558 | else /* Write followed by read */ | ||
3559 | partial_pec = i2c_smbus_msg_pec(0, &msg[0]); | ||
3560 | } | ||
3561 | /* Ask for PEC if last message is a read */ | ||
3562 | if (msg[num-1].flags & I2C_M_RD) | ||
3563 | msg[num-1].len++; | ||
3564 | } | ||
3565 | |||
3566 | status = i2c_transfer(adapter, msg, num); | ||
3567 | if (status < 0) | ||
3568 | return status; | ||
3569 | |||
3570 | /* Check PEC if last message is a read */ | ||
3571 | if (i && (msg[num-1].flags & I2C_M_RD)) { | ||
3572 | status = i2c_smbus_check_pec(partial_pec, &msg[num-1]); | ||
3573 | if (status < 0) | ||
3574 | return status; | ||
3575 | } | ||
3576 | |||
3577 | if (read_write == I2C_SMBUS_READ) | ||
3578 | switch (size) { | ||
3579 | case I2C_SMBUS_BYTE: | ||
3580 | data->byte = msgbuf0[0]; | ||
3581 | break; | ||
3582 | case I2C_SMBUS_BYTE_DATA: | ||
3583 | data->byte = msgbuf1[0]; | ||
3584 | break; | ||
3585 | case I2C_SMBUS_WORD_DATA: | ||
3586 | case I2C_SMBUS_PROC_CALL: | ||
3587 | data->word = msgbuf1[0] | (msgbuf1[1] << 8); | ||
3588 | break; | ||
3589 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
3590 | for (i = 0; i < data->block[0]; i++) | ||
3591 | data->block[i+1] = msgbuf1[i]; | ||
3592 | break; | ||
3593 | case I2C_SMBUS_BLOCK_DATA: | ||
3594 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
3595 | for (i = 0; i < msgbuf1[0] + 1; i++) | ||
3596 | data->block[i] = msgbuf1[i]; | ||
3597 | break; | ||
3598 | } | ||
3599 | return 0; | ||
3600 | } | ||
3601 | |||
3602 | /** | ||
3603 | * i2c_smbus_xfer - execute SMBus protocol operations | ||
3604 | * @adapter: Handle to I2C bus | ||
3605 | * @addr: Address of SMBus slave on that bus | ||
3606 | * @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC) | ||
3607 | * @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE | ||
3608 | * @command: Byte interpreted by slave, for protocols which use such bytes | ||
3609 | * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL | ||
3610 | * @data: Data to be read or written | ||
3611 | * | ||
3612 | * This executes an SMBus protocol operation, and returns a negative | ||
3613 | * errno code else zero on success. | ||
3614 | */ | ||
3615 | s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | ||
3616 | char read_write, u8 command, int protocol, | ||
3617 | union i2c_smbus_data *data) | ||
3618 | { | ||
3619 | unsigned long orig_jiffies; | ||
3620 | int try; | ||
3621 | s32 res; | ||
3622 | |||
3623 | /* If enabled, the following two tracepoints are conditional on | ||
3624 | * read_write and protocol. | ||
3625 | */ | ||
3626 | trace_smbus_write(adapter, addr, flags, read_write, | ||
3627 | command, protocol, data); | ||
3628 | trace_smbus_read(adapter, addr, flags, read_write, | ||
3629 | command, protocol); | ||
3630 | |||
3631 | flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; | ||
3632 | |||
3633 | if (adapter->algo->smbus_xfer) { | ||
3634 | i2c_lock_bus(adapter, I2C_LOCK_SEGMENT); | ||
3635 | |||
3636 | /* Retry automatically on arbitration loss */ | ||
3637 | orig_jiffies = jiffies; | ||
3638 | for (res = 0, try = 0; try <= adapter->retries; try++) { | ||
3639 | res = adapter->algo->smbus_xfer(adapter, addr, flags, | ||
3640 | read_write, command, | ||
3641 | protocol, data); | ||
3642 | if (res != -EAGAIN) | ||
3643 | break; | ||
3644 | if (time_after(jiffies, | ||
3645 | orig_jiffies + adapter->timeout)) | ||
3646 | break; | ||
3647 | } | ||
3648 | i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT); | ||
3649 | |||
3650 | if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) | ||
3651 | goto trace; | ||
3652 | /* | ||
3653 | * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't | ||
3654 | * implement native support for the SMBus operation. | ||
3655 | */ | ||
3656 | } | ||
3657 | |||
3658 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | ||
3659 | command, protocol, data); | ||
3660 | |||
3661 | trace: | ||
3662 | /* If enabled, the reply tracepoint is conditional on read_write. */ | ||
3663 | trace_smbus_reply(adapter, addr, flags, read_write, | ||
3664 | command, protocol, data); | ||
3665 | trace_smbus_result(adapter, addr, flags, read_write, | ||
3666 | command, protocol, res); | ||
3667 | |||
3668 | return res; | ||
3669 | } | ||
3670 | EXPORT_SYMBOL(i2c_smbus_xfer); | ||
3671 | |||
3672 | /** | ||
3673 | * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate | ||
3674 | * @client: Handle to slave device | ||
3675 | * @command: Byte interpreted by slave | ||
3676 | * @length: Size of data block; SMBus allows at most I2C_SMBUS_BLOCK_MAX bytes | ||
3677 | * @values: Byte array into which data will be read; big enough to hold | ||
3678 | * the data returned by the slave. SMBus allows at most | ||
3679 | * I2C_SMBUS_BLOCK_MAX bytes. | ||
3680 | * | ||
3681 | * This executes the SMBus "block read" protocol if supported by the adapter. | ||
3682 | * If block read is not supported, it emulates it using either word or byte | ||
3683 | * read protocols depending on availability. | ||
3684 | * | ||
3685 | * The addresses of the I2C slave device that are accessed with this function | ||
3686 | * must be mapped to a linear region, so that a block read will have the same | ||
3687 | * effect as a byte read. Before using this function you must double-check | ||
3688 | * if the I2C slave does support exchanging a block transfer with a byte | ||
3689 | * transfer. | ||
3690 | */ | ||
3691 | s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, | ||
3692 | u8 command, u8 length, u8 *values) | ||
3693 | { | ||
3694 | u8 i = 0; | ||
3695 | int status; | ||
3696 | |||
3697 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
3698 | length = I2C_SMBUS_BLOCK_MAX; | ||
3699 | |||
3700 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) | ||
3701 | return i2c_smbus_read_i2c_block_data(client, command, length, values); | ||
3702 | |||
3703 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) | ||
3704 | return -EOPNOTSUPP; | ||
3705 | |||
3706 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) { | ||
3707 | while ((i + 2) <= length) { | ||
3708 | status = i2c_smbus_read_word_data(client, command + i); | ||
3709 | if (status < 0) | ||
3710 | return status; | ||
3711 | values[i] = status & 0xff; | ||
3712 | values[i + 1] = status >> 8; | ||
3713 | i += 2; | ||
3714 | } | ||
3715 | } | ||
3716 | |||
3717 | while (i < length) { | ||
3718 | status = i2c_smbus_read_byte_data(client, command + i); | ||
3719 | if (status < 0) | ||
3720 | return status; | ||
3721 | values[i] = status; | ||
3722 | i++; | ||
3723 | } | ||
3724 | |||
3725 | return i; | ||
3726 | } | ||
3727 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); | ||
3728 | |||
3729 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | 3155 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
3730 | MODULE_DESCRIPTION("I2C-Bus main module"); | 3156 | MODULE_DESCRIPTION("I2C-Bus main module"); |
3731 | MODULE_LICENSE("GPL"); | 3157 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c new file mode 100644 index 000000000000..10f00a82ec9d --- /dev/null +++ b/drivers/i2c/i2c-core-smbus.c | |||
@@ -0,0 +1,594 @@ | |||
1 | /* | ||
2 | * Linux I2C core SMBus and SMBus emulation code | ||
3 | * | ||
4 | * This file contains the SMBus functions which are always included in the I2C | ||
5 | * core because they can be emulated via I2C. SMBus specific extensions | ||
6 | * (e.g. smbalert) are handled in a seperate i2c-smbus module. | ||
7 | * | ||
8 | * All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | ||
9 | * SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and | ||
10 | * Jean Delvare <jdelvare@suse.de> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the Free | ||
14 | * Software Foundation; either version 2 of the License, or (at your option) | ||
15 | * any later version. | ||
16 | */ | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/i2c.h> | ||
20 | |||
21 | #define CREATE_TRACE_POINTS | ||
22 | #include <trace/events/smbus.h> | ||
23 | |||
24 | |||
25 | /* The SMBus parts */ | ||
26 | |||
27 | #define POLY (0x1070U << 3) | ||
28 | static u8 crc8(u16 data) | ||
29 | { | ||
30 | int i; | ||
31 | |||
32 | for (i = 0; i < 8; i++) { | ||
33 | if (data & 0x8000) | ||
34 | data = data ^ POLY; | ||
35 | data = data << 1; | ||
36 | } | ||
37 | return (u8)(data >> 8); | ||
38 | } | ||
39 | |||
40 | /* Incremental CRC8 over count bytes in the array pointed to by p */ | ||
41 | static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) | ||
42 | { | ||
43 | int i; | ||
44 | |||
45 | for (i = 0; i < count; i++) | ||
46 | crc = crc8((crc ^ p[i]) << 8); | ||
47 | return crc; | ||
48 | } | ||
49 | |||
50 | /* Assume a 7-bit address, which is reasonable for SMBus */ | ||
51 | static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) | ||
52 | { | ||
53 | /* The address will be sent first */ | ||
54 | u8 addr = i2c_8bit_addr_from_msg(msg); | ||
55 | pec = i2c_smbus_pec(pec, &addr, 1); | ||
56 | |||
57 | /* The data buffer follows */ | ||
58 | return i2c_smbus_pec(pec, msg->buf, msg->len); | ||
59 | } | ||
60 | |||
61 | /* Used for write only transactions */ | ||
62 | static inline void i2c_smbus_add_pec(struct i2c_msg *msg) | ||
63 | { | ||
64 | msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg); | ||
65 | msg->len++; | ||
66 | } | ||
67 | |||
68 | /* Return <0 on CRC error | ||
69 | If there was a write before this read (most cases) we need to take the | ||
70 | partial CRC from the write part into account. | ||
71 | Note that this function does modify the message (we need to decrease the | ||
72 | message length to hide the CRC byte from the caller). */ | ||
73 | static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) | ||
74 | { | ||
75 | u8 rpec = msg->buf[--msg->len]; | ||
76 | cpec = i2c_smbus_msg_pec(cpec, msg); | ||
77 | |||
78 | if (rpec != cpec) { | ||
79 | pr_debug("Bad PEC 0x%02x vs. 0x%02x\n", | ||
80 | rpec, cpec); | ||
81 | return -EBADMSG; | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * i2c_smbus_read_byte - SMBus "receive byte" protocol | ||
88 | * @client: Handle to slave device | ||
89 | * | ||
90 | * This executes the SMBus "receive byte" protocol, returning negative errno | ||
91 | * else the byte received from the device. | ||
92 | */ | ||
93 | s32 i2c_smbus_read_byte(const struct i2c_client *client) | ||
94 | { | ||
95 | union i2c_smbus_data data; | ||
96 | int status; | ||
97 | |||
98 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
99 | I2C_SMBUS_READ, 0, | ||
100 | I2C_SMBUS_BYTE, &data); | ||
101 | return (status < 0) ? status : data.byte; | ||
102 | } | ||
103 | EXPORT_SYMBOL(i2c_smbus_read_byte); | ||
104 | |||
105 | /** | ||
106 | * i2c_smbus_write_byte - SMBus "send byte" protocol | ||
107 | * @client: Handle to slave device | ||
108 | * @value: Byte to be sent | ||
109 | * | ||
110 | * This executes the SMBus "send byte" protocol, returning negative errno | ||
111 | * else zero on success. | ||
112 | */ | ||
113 | s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) | ||
114 | { | ||
115 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
116 | I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); | ||
117 | } | ||
118 | EXPORT_SYMBOL(i2c_smbus_write_byte); | ||
119 | |||
120 | /** | ||
121 | * i2c_smbus_read_byte_data - SMBus "read byte" protocol | ||
122 | * @client: Handle to slave device | ||
123 | * @command: Byte interpreted by slave | ||
124 | * | ||
125 | * This executes the SMBus "read byte" protocol, returning negative errno | ||
126 | * else a data byte received from the device. | ||
127 | */ | ||
128 | s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) | ||
129 | { | ||
130 | union i2c_smbus_data data; | ||
131 | int status; | ||
132 | |||
133 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
134 | I2C_SMBUS_READ, command, | ||
135 | I2C_SMBUS_BYTE_DATA, &data); | ||
136 | return (status < 0) ? status : data.byte; | ||
137 | } | ||
138 | EXPORT_SYMBOL(i2c_smbus_read_byte_data); | ||
139 | |||
140 | /** | ||
141 | * i2c_smbus_write_byte_data - SMBus "write byte" protocol | ||
142 | * @client: Handle to slave device | ||
143 | * @command: Byte interpreted by slave | ||
144 | * @value: Byte being written | ||
145 | * | ||
146 | * This executes the SMBus "write byte" protocol, returning negative errno | ||
147 | * else zero on success. | ||
148 | */ | ||
149 | s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, | ||
150 | u8 value) | ||
151 | { | ||
152 | union i2c_smbus_data data; | ||
153 | data.byte = value; | ||
154 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
155 | I2C_SMBUS_WRITE, command, | ||
156 | I2C_SMBUS_BYTE_DATA, &data); | ||
157 | } | ||
158 | EXPORT_SYMBOL(i2c_smbus_write_byte_data); | ||
159 | |||
160 | /** | ||
161 | * i2c_smbus_read_word_data - SMBus "read word" protocol | ||
162 | * @client: Handle to slave device | ||
163 | * @command: Byte interpreted by slave | ||
164 | * | ||
165 | * This executes the SMBus "read word" protocol, returning negative errno | ||
166 | * else a 16-bit unsigned "word" received from the device. | ||
167 | */ | ||
168 | s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) | ||
169 | { | ||
170 | union i2c_smbus_data data; | ||
171 | int status; | ||
172 | |||
173 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
174 | I2C_SMBUS_READ, command, | ||
175 | I2C_SMBUS_WORD_DATA, &data); | ||
176 | return (status < 0) ? status : data.word; | ||
177 | } | ||
178 | EXPORT_SYMBOL(i2c_smbus_read_word_data); | ||
179 | |||
180 | /** | ||
181 | * i2c_smbus_write_word_data - SMBus "write word" protocol | ||
182 | * @client: Handle to slave device | ||
183 | * @command: Byte interpreted by slave | ||
184 | * @value: 16-bit "word" being written | ||
185 | * | ||
186 | * This executes the SMBus "write word" protocol, returning negative errno | ||
187 | * else zero on success. | ||
188 | */ | ||
189 | s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, | ||
190 | u16 value) | ||
191 | { | ||
192 | union i2c_smbus_data data; | ||
193 | data.word = value; | ||
194 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
195 | I2C_SMBUS_WRITE, command, | ||
196 | I2C_SMBUS_WORD_DATA, &data); | ||
197 | } | ||
198 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | ||
199 | |||
200 | /** | ||
201 | * i2c_smbus_read_block_data - SMBus "block read" protocol | ||
202 | * @client: Handle to slave device | ||
203 | * @command: Byte interpreted by slave | ||
204 | * @values: Byte array into which data will be read; big enough to hold | ||
205 | * the data returned by the slave. SMBus allows at most 32 bytes. | ||
206 | * | ||
207 | * This executes the SMBus "block read" protocol, returning negative errno | ||
208 | * else the number of data bytes in the slave's response. | ||
209 | * | ||
210 | * Note that using this function requires that the client's adapter support | ||
211 | * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality. Not all adapter drivers | ||
212 | * support this; its emulation through I2C messaging relies on a specific | ||
213 | * mechanism (I2C_M_RECV_LEN) which may not be implemented. | ||
214 | */ | ||
215 | s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, | ||
216 | u8 *values) | ||
217 | { | ||
218 | union i2c_smbus_data data; | ||
219 | int status; | ||
220 | |||
221 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
222 | I2C_SMBUS_READ, command, | ||
223 | I2C_SMBUS_BLOCK_DATA, &data); | ||
224 | if (status) | ||
225 | return status; | ||
226 | |||
227 | memcpy(values, &data.block[1], data.block[0]); | ||
228 | return data.block[0]; | ||
229 | } | ||
230 | EXPORT_SYMBOL(i2c_smbus_read_block_data); | ||
231 | |||
232 | /** | ||
233 | * i2c_smbus_write_block_data - SMBus "block write" protocol | ||
234 | * @client: Handle to slave device | ||
235 | * @command: Byte interpreted by slave | ||
236 | * @length: Size of data block; SMBus allows at most 32 bytes | ||
237 | * @values: Byte array which will be written. | ||
238 | * | ||
239 | * This executes the SMBus "block write" protocol, returning negative errno | ||
240 | * else zero on success. | ||
241 | */ | ||
242 | s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, | ||
243 | u8 length, const u8 *values) | ||
244 | { | ||
245 | union i2c_smbus_data data; | ||
246 | |||
247 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
248 | length = I2C_SMBUS_BLOCK_MAX; | ||
249 | data.block[0] = length; | ||
250 | memcpy(&data.block[1], values, length); | ||
251 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
252 | I2C_SMBUS_WRITE, command, | ||
253 | I2C_SMBUS_BLOCK_DATA, &data); | ||
254 | } | ||
255 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | ||
256 | |||
257 | /* Returns the number of read bytes */ | ||
258 | s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, | ||
259 | u8 length, u8 *values) | ||
260 | { | ||
261 | union i2c_smbus_data data; | ||
262 | int status; | ||
263 | |||
264 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
265 | length = I2C_SMBUS_BLOCK_MAX; | ||
266 | data.block[0] = length; | ||
267 | status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
268 | I2C_SMBUS_READ, command, | ||
269 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
270 | if (status < 0) | ||
271 | return status; | ||
272 | |||
273 | memcpy(values, &data.block[1], data.block[0]); | ||
274 | return data.block[0]; | ||
275 | } | ||
276 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | ||
277 | |||
278 | s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, | ||
279 | u8 length, const u8 *values) | ||
280 | { | ||
281 | union i2c_smbus_data data; | ||
282 | |||
283 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
284 | length = I2C_SMBUS_BLOCK_MAX; | ||
285 | data.block[0] = length; | ||
286 | memcpy(data.block + 1, values, length); | ||
287 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
288 | I2C_SMBUS_WRITE, command, | ||
289 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
290 | } | ||
291 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | ||
292 | |||
293 | /* Simulate a SMBus command using the i2c protocol | ||
294 | No checking of parameters is done! */ | ||
295 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, | ||
296 | unsigned short flags, | ||
297 | char read_write, u8 command, int size, | ||
298 | union i2c_smbus_data *data) | ||
299 | { | ||
300 | /* So we need to generate a series of msgs. In the case of writing, we | ||
301 | need to use only one message; when reading, we need two. We initialize | ||
302 | most things with sane defaults, to keep the code below somewhat | ||
303 | simpler. */ | ||
304 | unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; | ||
305 | unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; | ||
306 | int num = read_write == I2C_SMBUS_READ ? 2 : 1; | ||
307 | int i; | ||
308 | u8 partial_pec = 0; | ||
309 | int status; | ||
310 | struct i2c_msg msg[2] = { | ||
311 | { | ||
312 | .addr = addr, | ||
313 | .flags = flags, | ||
314 | .len = 1, | ||
315 | .buf = msgbuf0, | ||
316 | }, { | ||
317 | .addr = addr, | ||
318 | .flags = flags | I2C_M_RD, | ||
319 | .len = 0, | ||
320 | .buf = msgbuf1, | ||
321 | }, | ||
322 | }; | ||
323 | |||
324 | msgbuf0[0] = command; | ||
325 | switch (size) { | ||
326 | case I2C_SMBUS_QUICK: | ||
327 | msg[0].len = 0; | ||
328 | /* Special case: The read/write field is used as data */ | ||
329 | msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? | ||
330 | I2C_M_RD : 0); | ||
331 | num = 1; | ||
332 | break; | ||
333 | case I2C_SMBUS_BYTE: | ||
334 | if (read_write == I2C_SMBUS_READ) { | ||
335 | /* Special case: only a read! */ | ||
336 | msg[0].flags = I2C_M_RD | flags; | ||
337 | num = 1; | ||
338 | } | ||
339 | break; | ||
340 | case I2C_SMBUS_BYTE_DATA: | ||
341 | if (read_write == I2C_SMBUS_READ) | ||
342 | msg[1].len = 1; | ||
343 | else { | ||
344 | msg[0].len = 2; | ||
345 | msgbuf0[1] = data->byte; | ||
346 | } | ||
347 | break; | ||
348 | case I2C_SMBUS_WORD_DATA: | ||
349 | if (read_write == I2C_SMBUS_READ) | ||
350 | msg[1].len = 2; | ||
351 | else { | ||
352 | msg[0].len = 3; | ||
353 | msgbuf0[1] = data->word & 0xff; | ||
354 | msgbuf0[2] = data->word >> 8; | ||
355 | } | ||
356 | break; | ||
357 | case I2C_SMBUS_PROC_CALL: | ||
358 | num = 2; /* Special case */ | ||
359 | read_write = I2C_SMBUS_READ; | ||
360 | msg[0].len = 3; | ||
361 | msg[1].len = 2; | ||
362 | msgbuf0[1] = data->word & 0xff; | ||
363 | msgbuf0[2] = data->word >> 8; | ||
364 | break; | ||
365 | case I2C_SMBUS_BLOCK_DATA: | ||
366 | if (read_write == I2C_SMBUS_READ) { | ||
367 | msg[1].flags |= I2C_M_RECV_LEN; | ||
368 | msg[1].len = 1; /* block length will be added by | ||
369 | the underlying bus driver */ | ||
370 | } else { | ||
371 | msg[0].len = data->block[0] + 2; | ||
372 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { | ||
373 | dev_err(&adapter->dev, | ||
374 | "Invalid block write size %d\n", | ||
375 | data->block[0]); | ||
376 | return -EINVAL; | ||
377 | } | ||
378 | for (i = 1; i < msg[0].len; i++) | ||
379 | msgbuf0[i] = data->block[i-1]; | ||
380 | } | ||
381 | break; | ||
382 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
383 | num = 2; /* Another special case */ | ||
384 | read_write = I2C_SMBUS_READ; | ||
385 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { | ||
386 | dev_err(&adapter->dev, | ||
387 | "Invalid block write size %d\n", | ||
388 | data->block[0]); | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | msg[0].len = data->block[0] + 2; | ||
392 | for (i = 1; i < msg[0].len; i++) | ||
393 | msgbuf0[i] = data->block[i-1]; | ||
394 | msg[1].flags |= I2C_M_RECV_LEN; | ||
395 | msg[1].len = 1; /* block length will be added by | ||
396 | the underlying bus driver */ | ||
397 | break; | ||
398 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
399 | if (read_write == I2C_SMBUS_READ) { | ||
400 | msg[1].len = data->block[0]; | ||
401 | } else { | ||
402 | msg[0].len = data->block[0] + 1; | ||
403 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { | ||
404 | dev_err(&adapter->dev, | ||
405 | "Invalid block write size %d\n", | ||
406 | data->block[0]); | ||
407 | return -EINVAL; | ||
408 | } | ||
409 | for (i = 1; i <= data->block[0]; i++) | ||
410 | msgbuf0[i] = data->block[i]; | ||
411 | } | ||
412 | break; | ||
413 | default: | ||
414 | dev_err(&adapter->dev, "Unsupported transaction %d\n", size); | ||
415 | return -EOPNOTSUPP; | ||
416 | } | ||
417 | |||
418 | i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK | ||
419 | && size != I2C_SMBUS_I2C_BLOCK_DATA); | ||
420 | if (i) { | ||
421 | /* Compute PEC if first message is a write */ | ||
422 | if (!(msg[0].flags & I2C_M_RD)) { | ||
423 | if (num == 1) /* Write only */ | ||
424 | i2c_smbus_add_pec(&msg[0]); | ||
425 | else /* Write followed by read */ | ||
426 | partial_pec = i2c_smbus_msg_pec(0, &msg[0]); | ||
427 | } | ||
428 | /* Ask for PEC if last message is a read */ | ||
429 | if (msg[num-1].flags & I2C_M_RD) | ||
430 | msg[num-1].len++; | ||
431 | } | ||
432 | |||
433 | status = i2c_transfer(adapter, msg, num); | ||
434 | if (status < 0) | ||
435 | return status; | ||
436 | |||
437 | /* Check PEC if last message is a read */ | ||
438 | if (i && (msg[num-1].flags & I2C_M_RD)) { | ||
439 | status = i2c_smbus_check_pec(partial_pec, &msg[num-1]); | ||
440 | if (status < 0) | ||
441 | return status; | ||
442 | } | ||
443 | |||
444 | if (read_write == I2C_SMBUS_READ) | ||
445 | switch (size) { | ||
446 | case I2C_SMBUS_BYTE: | ||
447 | data->byte = msgbuf0[0]; | ||
448 | break; | ||
449 | case I2C_SMBUS_BYTE_DATA: | ||
450 | data->byte = msgbuf1[0]; | ||
451 | break; | ||
452 | case I2C_SMBUS_WORD_DATA: | ||
453 | case I2C_SMBUS_PROC_CALL: | ||
454 | data->word = msgbuf1[0] | (msgbuf1[1] << 8); | ||
455 | break; | ||
456 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
457 | for (i = 0; i < data->block[0]; i++) | ||
458 | data->block[i+1] = msgbuf1[i]; | ||
459 | break; | ||
460 | case I2C_SMBUS_BLOCK_DATA: | ||
461 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
462 | for (i = 0; i < msgbuf1[0] + 1; i++) | ||
463 | data->block[i] = msgbuf1[i]; | ||
464 | break; | ||
465 | } | ||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * i2c_smbus_xfer - execute SMBus protocol operations | ||
471 | * @adapter: Handle to I2C bus | ||
472 | * @addr: Address of SMBus slave on that bus | ||
473 | * @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC) | ||
474 | * @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE | ||
475 | * @command: Byte interpreted by slave, for protocols which use such bytes | ||
476 | * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL | ||
477 | * @data: Data to be read or written | ||
478 | * | ||
479 | * This executes an SMBus protocol operation, and returns a negative | ||
480 | * errno code else zero on success. | ||
481 | */ | ||
482 | s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | ||
483 | char read_write, u8 command, int protocol, | ||
484 | union i2c_smbus_data *data) | ||
485 | { | ||
486 | unsigned long orig_jiffies; | ||
487 | int try; | ||
488 | s32 res; | ||
489 | |||
490 | /* If enabled, the following two tracepoints are conditional on | ||
491 | * read_write and protocol. | ||
492 | */ | ||
493 | trace_smbus_write(adapter, addr, flags, read_write, | ||
494 | command, protocol, data); | ||
495 | trace_smbus_read(adapter, addr, flags, read_write, | ||
496 | command, protocol); | ||
497 | |||
498 | flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; | ||
499 | |||
500 | if (adapter->algo->smbus_xfer) { | ||
501 | i2c_lock_bus(adapter, I2C_LOCK_SEGMENT); | ||
502 | |||
503 | /* Retry automatically on arbitration loss */ | ||
504 | orig_jiffies = jiffies; | ||
505 | for (res = 0, try = 0; try <= adapter->retries; try++) { | ||
506 | res = adapter->algo->smbus_xfer(adapter, addr, flags, | ||
507 | read_write, command, | ||
508 | protocol, data); | ||
509 | if (res != -EAGAIN) | ||
510 | break; | ||
511 | if (time_after(jiffies, | ||
512 | orig_jiffies + adapter->timeout)) | ||
513 | break; | ||
514 | } | ||
515 | i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT); | ||
516 | |||
517 | if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) | ||
518 | goto trace; | ||
519 | /* | ||
520 | * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't | ||
521 | * implement native support for the SMBus operation. | ||
522 | */ | ||
523 | } | ||
524 | |||
525 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | ||
526 | command, protocol, data); | ||
527 | |||
528 | trace: | ||
529 | /* If enabled, the reply tracepoint is conditional on read_write. */ | ||
530 | trace_smbus_reply(adapter, addr, flags, read_write, | ||
531 | command, protocol, data); | ||
532 | trace_smbus_result(adapter, addr, flags, read_write, | ||
533 | command, protocol, res); | ||
534 | |||
535 | return res; | ||
536 | } | ||
537 | EXPORT_SYMBOL(i2c_smbus_xfer); | ||
538 | |||
539 | /** | ||
540 | * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate | ||
541 | * @client: Handle to slave device | ||
542 | * @command: Byte interpreted by slave | ||
543 | * @length: Size of data block; SMBus allows at most I2C_SMBUS_BLOCK_MAX bytes | ||
544 | * @values: Byte array into which data will be read; big enough to hold | ||
545 | * the data returned by the slave. SMBus allows at most | ||
546 | * I2C_SMBUS_BLOCK_MAX bytes. | ||
547 | * | ||
548 | * This executes the SMBus "block read" protocol if supported by the adapter. | ||
549 | * If block read is not supported, it emulates it using either word or byte | ||
550 | * read protocols depending on availability. | ||
551 | * | ||
552 | * The addresses of the I2C slave device that are accessed with this function | ||
553 | * must be mapped to a linear region, so that a block read will have the same | ||
554 | * effect as a byte read. Before using this function you must double-check | ||
555 | * if the I2C slave does support exchanging a block transfer with a byte | ||
556 | * transfer. | ||
557 | */ | ||
558 | s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, | ||
559 | u8 command, u8 length, u8 *values) | ||
560 | { | ||
561 | u8 i = 0; | ||
562 | int status; | ||
563 | |||
564 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
565 | length = I2C_SMBUS_BLOCK_MAX; | ||
566 | |||
567 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) | ||
568 | return i2c_smbus_read_i2c_block_data(client, command, length, values); | ||
569 | |||
570 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) | ||
571 | return -EOPNOTSUPP; | ||
572 | |||
573 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) { | ||
574 | while ((i + 2) <= length) { | ||
575 | status = i2c_smbus_read_word_data(client, command + i); | ||
576 | if (status < 0) | ||
577 | return status; | ||
578 | values[i] = status & 0xff; | ||
579 | values[i + 1] = status >> 8; | ||
580 | i += 2; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | while (i < length) { | ||
585 | status = i2c_smbus_read_byte_data(client, command + i); | ||
586 | if (status < 0) | ||
587 | return status; | ||
588 | values[i] = status; | ||
589 | i++; | ||
590 | } | ||
591 | |||
592 | return i; | ||
593 | } | ||
594 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated); | ||
diff --git a/include/trace/events/i2c.h b/include/trace/events/i2c.h index 4abb8eab34d3..86a401190df9 100644 --- a/include/trace/events/i2c.h +++ b/include/trace/events/i2c.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* I2C and SMBUS message transfer tracepoints | 1 | /* I2C message transfer tracepoints |
2 | * | 2 | * |
3 | * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/tracepoint.h> | 18 | #include <linux/tracepoint.h> |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * drivers/i2c/i2c-core.c | 21 | * drivers/i2c/i2c-core-base.c |
22 | */ | 22 | */ |
23 | extern int i2c_transfer_trace_reg(void); | 23 | extern int i2c_transfer_trace_reg(void); |
24 | extern void i2c_transfer_trace_unreg(void); | 24 | extern void i2c_transfer_trace_unreg(void); |
@@ -144,228 +144,6 @@ TRACE_EVENT_FN(i2c_result, | |||
144 | i2c_transfer_trace_reg, | 144 | i2c_transfer_trace_reg, |
145 | i2c_transfer_trace_unreg); | 145 | i2c_transfer_trace_unreg); |
146 | 146 | ||
147 | /* | ||
148 | * i2c_smbus_xfer() write data or procedure call request | ||
149 | */ | ||
150 | TRACE_EVENT_CONDITION(smbus_write, | ||
151 | TP_PROTO(const struct i2c_adapter *adap, | ||
152 | u16 addr, unsigned short flags, | ||
153 | char read_write, u8 command, int protocol, | ||
154 | const union i2c_smbus_data *data), | ||
155 | TP_ARGS(adap, addr, flags, read_write, command, protocol, data), | ||
156 | TP_CONDITION(read_write == I2C_SMBUS_WRITE || | ||
157 | protocol == I2C_SMBUS_PROC_CALL || | ||
158 | protocol == I2C_SMBUS_BLOCK_PROC_CALL), | ||
159 | TP_STRUCT__entry( | ||
160 | __field(int, adapter_nr ) | ||
161 | __field(__u16, addr ) | ||
162 | __field(__u16, flags ) | ||
163 | __field(__u8, command ) | ||
164 | __field(__u8, len ) | ||
165 | __field(__u32, protocol ) | ||
166 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
167 | TP_fast_assign( | ||
168 | __entry->adapter_nr = adap->nr; | ||
169 | __entry->addr = addr; | ||
170 | __entry->flags = flags; | ||
171 | __entry->command = command; | ||
172 | __entry->protocol = protocol; | ||
173 | |||
174 | switch (protocol) { | ||
175 | case I2C_SMBUS_BYTE_DATA: | ||
176 | __entry->len = 1; | ||
177 | goto copy; | ||
178 | case I2C_SMBUS_WORD_DATA: | ||
179 | case I2C_SMBUS_PROC_CALL: | ||
180 | __entry->len = 2; | ||
181 | goto copy; | ||
182 | case I2C_SMBUS_BLOCK_DATA: | ||
183 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
184 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
185 | __entry->len = data->block[0] + 1; | ||
186 | copy: | ||
187 | memcpy(__entry->buf, data->block, __entry->len); | ||
188 | break; | ||
189 | case I2C_SMBUS_QUICK: | ||
190 | case I2C_SMBUS_BYTE: | ||
191 | case I2C_SMBUS_I2C_BLOCK_BROKEN: | ||
192 | default: | ||
193 | __entry->len = 0; | ||
194 | } | ||
195 | ), | ||
196 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", | ||
197 | __entry->adapter_nr, | ||
198 | __entry->addr, | ||
199 | __entry->flags, | ||
200 | __entry->command, | ||
201 | __print_symbolic(__entry->protocol, | ||
202 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
203 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
204 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
205 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
206 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
207 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
208 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
209 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
210 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
211 | __entry->len, | ||
212 | __entry->len, __entry->buf | ||
213 | )); | ||
214 | |||
215 | /* | ||
216 | * i2c_smbus_xfer() read data request | ||
217 | */ | ||
218 | TRACE_EVENT_CONDITION(smbus_read, | ||
219 | TP_PROTO(const struct i2c_adapter *adap, | ||
220 | u16 addr, unsigned short flags, | ||
221 | char read_write, u8 command, int protocol), | ||
222 | TP_ARGS(adap, addr, flags, read_write, command, protocol), | ||
223 | TP_CONDITION(!(read_write == I2C_SMBUS_WRITE || | ||
224 | protocol == I2C_SMBUS_PROC_CALL || | ||
225 | protocol == I2C_SMBUS_BLOCK_PROC_CALL)), | ||
226 | TP_STRUCT__entry( | ||
227 | __field(int, adapter_nr ) | ||
228 | __field(__u16, flags ) | ||
229 | __field(__u16, addr ) | ||
230 | __field(__u8, command ) | ||
231 | __field(__u32, protocol ) | ||
232 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
233 | TP_fast_assign( | ||
234 | __entry->adapter_nr = adap->nr; | ||
235 | __entry->addr = addr; | ||
236 | __entry->flags = flags; | ||
237 | __entry->command = command; | ||
238 | __entry->protocol = protocol; | ||
239 | ), | ||
240 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s", | ||
241 | __entry->adapter_nr, | ||
242 | __entry->addr, | ||
243 | __entry->flags, | ||
244 | __entry->command, | ||
245 | __print_symbolic(__entry->protocol, | ||
246 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
247 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
248 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
249 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
250 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
251 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
252 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
253 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
254 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }) | ||
255 | )); | ||
256 | |||
257 | /* | ||
258 | * i2c_smbus_xfer() read data or procedure call reply | ||
259 | */ | ||
260 | TRACE_EVENT_CONDITION(smbus_reply, | ||
261 | TP_PROTO(const struct i2c_adapter *adap, | ||
262 | u16 addr, unsigned short flags, | ||
263 | char read_write, u8 command, int protocol, | ||
264 | const union i2c_smbus_data *data), | ||
265 | TP_ARGS(adap, addr, flags, read_write, command, protocol, data), | ||
266 | TP_CONDITION(read_write == I2C_SMBUS_READ), | ||
267 | TP_STRUCT__entry( | ||
268 | __field(int, adapter_nr ) | ||
269 | __field(__u16, addr ) | ||
270 | __field(__u16, flags ) | ||
271 | __field(__u8, command ) | ||
272 | __field(__u8, len ) | ||
273 | __field(__u32, protocol ) | ||
274 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
275 | TP_fast_assign( | ||
276 | __entry->adapter_nr = adap->nr; | ||
277 | __entry->addr = addr; | ||
278 | __entry->flags = flags; | ||
279 | __entry->command = command; | ||
280 | __entry->protocol = protocol; | ||
281 | |||
282 | switch (protocol) { | ||
283 | case I2C_SMBUS_BYTE: | ||
284 | case I2C_SMBUS_BYTE_DATA: | ||
285 | __entry->len = 1; | ||
286 | goto copy; | ||
287 | case I2C_SMBUS_WORD_DATA: | ||
288 | case I2C_SMBUS_PROC_CALL: | ||
289 | __entry->len = 2; | ||
290 | goto copy; | ||
291 | case I2C_SMBUS_BLOCK_DATA: | ||
292 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
293 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
294 | __entry->len = data->block[0] + 1; | ||
295 | copy: | ||
296 | memcpy(__entry->buf, data->block, __entry->len); | ||
297 | break; | ||
298 | case I2C_SMBUS_QUICK: | ||
299 | case I2C_SMBUS_I2C_BLOCK_BROKEN: | ||
300 | default: | ||
301 | __entry->len = 0; | ||
302 | } | ||
303 | ), | ||
304 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", | ||
305 | __entry->adapter_nr, | ||
306 | __entry->addr, | ||
307 | __entry->flags, | ||
308 | __entry->command, | ||
309 | __print_symbolic(__entry->protocol, | ||
310 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
311 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
312 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
313 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
314 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
315 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
316 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
317 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
318 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
319 | __entry->len, | ||
320 | __entry->len, __entry->buf | ||
321 | )); | ||
322 | |||
323 | /* | ||
324 | * i2c_smbus_xfer() result | ||
325 | */ | ||
326 | TRACE_EVENT(smbus_result, | ||
327 | TP_PROTO(const struct i2c_adapter *adap, | ||
328 | u16 addr, unsigned short flags, | ||
329 | char read_write, u8 command, int protocol, | ||
330 | int res), | ||
331 | TP_ARGS(adap, addr, flags, read_write, command, protocol, res), | ||
332 | TP_STRUCT__entry( | ||
333 | __field(int, adapter_nr ) | ||
334 | __field(__u16, addr ) | ||
335 | __field(__u16, flags ) | ||
336 | __field(__u8, read_write ) | ||
337 | __field(__u8, command ) | ||
338 | __field(__s16, res ) | ||
339 | __field(__u32, protocol ) | ||
340 | ), | ||
341 | TP_fast_assign( | ||
342 | __entry->adapter_nr = adap->nr; | ||
343 | __entry->addr = addr; | ||
344 | __entry->flags = flags; | ||
345 | __entry->read_write = read_write; | ||
346 | __entry->command = command; | ||
347 | __entry->protocol = protocol; | ||
348 | __entry->res = res; | ||
349 | ), | ||
350 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s %s res=%d", | ||
351 | __entry->adapter_nr, | ||
352 | __entry->addr, | ||
353 | __entry->flags, | ||
354 | __entry->command, | ||
355 | __print_symbolic(__entry->protocol, | ||
356 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
357 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
358 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
359 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
360 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
361 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
362 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
363 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
364 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
365 | __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd", | ||
366 | __entry->res | ||
367 | )); | ||
368 | |||
369 | #endif /* _TRACE_I2C_H */ | 147 | #endif /* _TRACE_I2C_H */ |
370 | 148 | ||
371 | /* This part must be outside protection */ | 149 | /* This part must be outside protection */ |
diff --git a/include/trace/events/smbus.h b/include/trace/events/smbus.h new file mode 100644 index 000000000000..d2fb6e1d3e10 --- /dev/null +++ b/include/trace/events/smbus.h | |||
@@ -0,0 +1,249 @@ | |||
1 | /* SMBUS message transfer tracepoints | ||
2 | * | ||
3 | * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #undef TRACE_SYSTEM | ||
12 | #define TRACE_SYSTEM smbus | ||
13 | |||
14 | #if !defined(_TRACE_SMBUS_H) || defined(TRACE_HEADER_MULTI_READ) | ||
15 | #define _TRACE_SMBUS_H | ||
16 | |||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/tracepoint.h> | ||
19 | |||
20 | /* | ||
21 | * drivers/i2c/i2c-core-smbus.c | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * i2c_smbus_xfer() write data or procedure call request | ||
26 | */ | ||
27 | TRACE_EVENT_CONDITION(smbus_write, | ||
28 | TP_PROTO(const struct i2c_adapter *adap, | ||
29 | u16 addr, unsigned short flags, | ||
30 | char read_write, u8 command, int protocol, | ||
31 | const union i2c_smbus_data *data), | ||
32 | TP_ARGS(adap, addr, flags, read_write, command, protocol, data), | ||
33 | TP_CONDITION(read_write == I2C_SMBUS_WRITE || | ||
34 | protocol == I2C_SMBUS_PROC_CALL || | ||
35 | protocol == I2C_SMBUS_BLOCK_PROC_CALL), | ||
36 | TP_STRUCT__entry( | ||
37 | __field(int, adapter_nr ) | ||
38 | __field(__u16, addr ) | ||
39 | __field(__u16, flags ) | ||
40 | __field(__u8, command ) | ||
41 | __field(__u8, len ) | ||
42 | __field(__u32, protocol ) | ||
43 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
44 | TP_fast_assign( | ||
45 | __entry->adapter_nr = adap->nr; | ||
46 | __entry->addr = addr; | ||
47 | __entry->flags = flags; | ||
48 | __entry->command = command; | ||
49 | __entry->protocol = protocol; | ||
50 | |||
51 | switch (protocol) { | ||
52 | case I2C_SMBUS_BYTE_DATA: | ||
53 | __entry->len = 1; | ||
54 | goto copy; | ||
55 | case I2C_SMBUS_WORD_DATA: | ||
56 | case I2C_SMBUS_PROC_CALL: | ||
57 | __entry->len = 2; | ||
58 | goto copy; | ||
59 | case I2C_SMBUS_BLOCK_DATA: | ||
60 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
61 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
62 | __entry->len = data->block[0] + 1; | ||
63 | copy: | ||
64 | memcpy(__entry->buf, data->block, __entry->len); | ||
65 | break; | ||
66 | case I2C_SMBUS_QUICK: | ||
67 | case I2C_SMBUS_BYTE: | ||
68 | case I2C_SMBUS_I2C_BLOCK_BROKEN: | ||
69 | default: | ||
70 | __entry->len = 0; | ||
71 | } | ||
72 | ), | ||
73 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", | ||
74 | __entry->adapter_nr, | ||
75 | __entry->addr, | ||
76 | __entry->flags, | ||
77 | __entry->command, | ||
78 | __print_symbolic(__entry->protocol, | ||
79 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
80 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
81 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
82 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
83 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
84 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
85 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
86 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
87 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
88 | __entry->len, | ||
89 | __entry->len, __entry->buf | ||
90 | )); | ||
91 | |||
92 | /* | ||
93 | * i2c_smbus_xfer() read data request | ||
94 | */ | ||
95 | TRACE_EVENT_CONDITION(smbus_read, | ||
96 | TP_PROTO(const struct i2c_adapter *adap, | ||
97 | u16 addr, unsigned short flags, | ||
98 | char read_write, u8 command, int protocol), | ||
99 | TP_ARGS(adap, addr, flags, read_write, command, protocol), | ||
100 | TP_CONDITION(!(read_write == I2C_SMBUS_WRITE || | ||
101 | protocol == I2C_SMBUS_PROC_CALL || | ||
102 | protocol == I2C_SMBUS_BLOCK_PROC_CALL)), | ||
103 | TP_STRUCT__entry( | ||
104 | __field(int, adapter_nr ) | ||
105 | __field(__u16, flags ) | ||
106 | __field(__u16, addr ) | ||
107 | __field(__u8, command ) | ||
108 | __field(__u32, protocol ) | ||
109 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
110 | TP_fast_assign( | ||
111 | __entry->adapter_nr = adap->nr; | ||
112 | __entry->addr = addr; | ||
113 | __entry->flags = flags; | ||
114 | __entry->command = command; | ||
115 | __entry->protocol = protocol; | ||
116 | ), | ||
117 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s", | ||
118 | __entry->adapter_nr, | ||
119 | __entry->addr, | ||
120 | __entry->flags, | ||
121 | __entry->command, | ||
122 | __print_symbolic(__entry->protocol, | ||
123 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
124 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
125 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
126 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
127 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
128 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
129 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
130 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
131 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }) | ||
132 | )); | ||
133 | |||
134 | /* | ||
135 | * i2c_smbus_xfer() read data or procedure call reply | ||
136 | */ | ||
137 | TRACE_EVENT_CONDITION(smbus_reply, | ||
138 | TP_PROTO(const struct i2c_adapter *adap, | ||
139 | u16 addr, unsigned short flags, | ||
140 | char read_write, u8 command, int protocol, | ||
141 | const union i2c_smbus_data *data), | ||
142 | TP_ARGS(adap, addr, flags, read_write, command, protocol, data), | ||
143 | TP_CONDITION(read_write == I2C_SMBUS_READ), | ||
144 | TP_STRUCT__entry( | ||
145 | __field(int, adapter_nr ) | ||
146 | __field(__u16, addr ) | ||
147 | __field(__u16, flags ) | ||
148 | __field(__u8, command ) | ||
149 | __field(__u8, len ) | ||
150 | __field(__u32, protocol ) | ||
151 | __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), | ||
152 | TP_fast_assign( | ||
153 | __entry->adapter_nr = adap->nr; | ||
154 | __entry->addr = addr; | ||
155 | __entry->flags = flags; | ||
156 | __entry->command = command; | ||
157 | __entry->protocol = protocol; | ||
158 | |||
159 | switch (protocol) { | ||
160 | case I2C_SMBUS_BYTE: | ||
161 | case I2C_SMBUS_BYTE_DATA: | ||
162 | __entry->len = 1; | ||
163 | goto copy; | ||
164 | case I2C_SMBUS_WORD_DATA: | ||
165 | case I2C_SMBUS_PROC_CALL: | ||
166 | __entry->len = 2; | ||
167 | goto copy; | ||
168 | case I2C_SMBUS_BLOCK_DATA: | ||
169 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
170 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
171 | __entry->len = data->block[0] + 1; | ||
172 | copy: | ||
173 | memcpy(__entry->buf, data->block, __entry->len); | ||
174 | break; | ||
175 | case I2C_SMBUS_QUICK: | ||
176 | case I2C_SMBUS_I2C_BLOCK_BROKEN: | ||
177 | default: | ||
178 | __entry->len = 0; | ||
179 | } | ||
180 | ), | ||
181 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", | ||
182 | __entry->adapter_nr, | ||
183 | __entry->addr, | ||
184 | __entry->flags, | ||
185 | __entry->command, | ||
186 | __print_symbolic(__entry->protocol, | ||
187 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
188 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
189 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
190 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
191 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
192 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
193 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
194 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
195 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
196 | __entry->len, | ||
197 | __entry->len, __entry->buf | ||
198 | )); | ||
199 | |||
200 | /* | ||
201 | * i2c_smbus_xfer() result | ||
202 | */ | ||
203 | TRACE_EVENT(smbus_result, | ||
204 | TP_PROTO(const struct i2c_adapter *adap, | ||
205 | u16 addr, unsigned short flags, | ||
206 | char read_write, u8 command, int protocol, | ||
207 | int res), | ||
208 | TP_ARGS(adap, addr, flags, read_write, command, protocol, res), | ||
209 | TP_STRUCT__entry( | ||
210 | __field(int, adapter_nr ) | ||
211 | __field(__u16, addr ) | ||
212 | __field(__u16, flags ) | ||
213 | __field(__u8, read_write ) | ||
214 | __field(__u8, command ) | ||
215 | __field(__s16, res ) | ||
216 | __field(__u32, protocol ) | ||
217 | ), | ||
218 | TP_fast_assign( | ||
219 | __entry->adapter_nr = adap->nr; | ||
220 | __entry->addr = addr; | ||
221 | __entry->flags = flags; | ||
222 | __entry->read_write = read_write; | ||
223 | __entry->command = command; | ||
224 | __entry->protocol = protocol; | ||
225 | __entry->res = res; | ||
226 | ), | ||
227 | TP_printk("i2c-%d a=%03x f=%04x c=%x %s %s res=%d", | ||
228 | __entry->adapter_nr, | ||
229 | __entry->addr, | ||
230 | __entry->flags, | ||
231 | __entry->command, | ||
232 | __print_symbolic(__entry->protocol, | ||
233 | { I2C_SMBUS_QUICK, "QUICK" }, | ||
234 | { I2C_SMBUS_BYTE, "BYTE" }, | ||
235 | { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, | ||
236 | { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, | ||
237 | { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, | ||
238 | { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, | ||
239 | { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, | ||
240 | { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, | ||
241 | { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), | ||
242 | __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd", | ||
243 | __entry->res | ||
244 | )); | ||
245 | |||
246 | #endif /* _TRACE_SMBUS_H */ | ||
247 | |||
248 | /* This part must be outside protection */ | ||
249 | #include <trace/define_trace.h> | ||