0001
0002
0003
0004 #include <linux/err.h>
0005 #include <linux/i2c.h>
0006 #include <linux/init.h>
0007 #include <linux/jiffies.h>
0008 #include <linux/kernel.h>
0009 #include <linux/mutex.h>
0010 #include <linux/module.h>
0011 #include <linux/mod_devicetable.h>
0012 #include <linux/slab.h>
0013
0014 #include "cmd.h"
0015 #include "core.h"
0016 #include "i2c.h"
0017 #include "resources.h"
0018
0019 #define MLXSW_I2C_CIR2_BASE 0x72000
0020 #define MLXSW_I2C_CIR_STATUS_OFF 0x18
0021 #define MLXSW_I2C_CIR2_OFF_STATUS (MLXSW_I2C_CIR2_BASE + \
0022 MLXSW_I2C_CIR_STATUS_OFF)
0023 #define MLXSW_I2C_OPMOD_SHIFT 12
0024 #define MLXSW_I2C_EVENT_BIT_SHIFT 22
0025 #define MLXSW_I2C_GO_BIT_SHIFT 23
0026 #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24
0027 #define MLXSW_I2C_EVENT_BIT BIT(MLXSW_I2C_EVENT_BIT_SHIFT)
0028 #define MLXSW_I2C_GO_BIT BIT(MLXSW_I2C_GO_BIT_SHIFT)
0029 #define MLXSW_I2C_GO_OPMODE BIT(MLXSW_I2C_OPMOD_SHIFT)
0030 #define MLXSW_I2C_SET_IMM_CMD (MLXSW_I2C_GO_OPMODE | \
0031 MLXSW_CMD_OPCODE_QUERY_FW)
0032 #define MLXSW_I2C_PUSH_IMM_CMD (MLXSW_I2C_GO_BIT | \
0033 MLXSW_I2C_SET_IMM_CMD)
0034 #define MLXSW_I2C_SET_CMD (MLXSW_CMD_OPCODE_ACCESS_REG)
0035 #define MLXSW_I2C_PUSH_CMD (MLXSW_I2C_GO_BIT | MLXSW_I2C_SET_CMD)
0036 #define MLXSW_I2C_TLV_HDR_SIZE 0x10
0037 #define MLXSW_I2C_ADDR_WIDTH 4
0038 #define MLXSW_I2C_PUSH_CMD_SIZE (MLXSW_I2C_ADDR_WIDTH + 4)
0039 #define MLXSW_I2C_SET_EVENT_CMD (MLXSW_I2C_EVENT_BIT)
0040 #define MLXSW_I2C_PUSH_EVENT_CMD (MLXSW_I2C_GO_BIT | \
0041 MLXSW_I2C_SET_EVENT_CMD)
0042 #define MLXSW_I2C_READ_SEMA_SIZE 4
0043 #define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
0044 #define MLXSW_I2C_MBOX_SIZE 20
0045 #define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
0046 #define MLXSW_I2C_MBOX_OFFSET_BITS 20
0047 #define MLXSW_I2C_MBOX_SIZE_BITS 12
0048 #define MLXSW_I2C_ADDR_BUF_SIZE 4
0049 #define MLXSW_I2C_BLK_DEF 32
0050 #define MLXSW_I2C_RETRY 5
0051 #define MLXSW_I2C_TIMEOUT_MSECS 5000
0052 #define MLXSW_I2C_MAX_DATA_SIZE 256
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 struct mlxsw_i2c {
0068 struct {
0069 u32 mb_size_in;
0070 u32 mb_off_in;
0071 u32 mb_size_out;
0072 u32 mb_off_out;
0073 struct mutex lock;
0074 } cmd;
0075 struct device *dev;
0076 struct mlxsw_core *core;
0077 struct mlxsw_bus_info bus_info;
0078 u16 block_size;
0079 };
0080
0081 #define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
0082 { .addr = (_client)->addr, \
0083 .buf = (_addr_buf), \
0084 .len = MLXSW_I2C_ADDR_BUF_SIZE, \
0085 .flags = 0 }, \
0086 { .addr = (_client)->addr, \
0087 .buf = (_buf), \
0088 .len = (_len), \
0089 .flags = I2C_M_RD } }
0090
0091 #define MLXSW_I2C_WRITE_MSG(_client, _buf, _len) \
0092 { .addr = (_client)->addr, \
0093 .buf = (u8 *)(_buf), \
0094 .len = (_len), \
0095 .flags = 0 }
0096
0097
0098 static inline void
0099 mlxsw_i2c_convert_mbox(struct mlxsw_i2c *mlxsw_i2c, u8 *buf)
0100 {
0101 u32 tmp;
0102
0103
0104 tmp = be32_to_cpup((__be32 *) buf);
0105 mlxsw_i2c->cmd.mb_off_in = tmp &
0106 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
0107 mlxsw_i2c->cmd.mb_size_in = (tmp & GENMASK(31,
0108 MLXSW_I2C_MBOX_OFFSET_BITS)) >>
0109 MLXSW_I2C_MBOX_OFFSET_BITS;
0110
0111 tmp = be32_to_cpup((__be32 *) (buf + MLXSW_I2C_ADDR_WIDTH));
0112 mlxsw_i2c->cmd.mb_off_out = tmp &
0113 GENMASK(MLXSW_I2C_MBOX_OFFSET_BITS - 1, 0);
0114 mlxsw_i2c->cmd.mb_size_out = (tmp & GENMASK(31,
0115 MLXSW_I2C_MBOX_OFFSET_BITS)) >>
0116 MLXSW_I2C_MBOX_OFFSET_BITS;
0117 }
0118
0119
0120 static inline int mlxsw_i2c_get_reg_size(u8 *in_mbox)
0121 {
0122 u16 tmp = be16_to_cpup((__be16 *) (in_mbox + MLXSW_I2C_TLV_HDR_SIZE));
0123
0124 return (tmp & 0x7ff) * 4 + MLXSW_I2C_TLV_HDR_SIZE;
0125 }
0126
0127
0128 static inline void mlxsw_i2c_set_slave_addr(u8 *buf, u32 off)
0129 {
0130 __be32 *val = (__be32 *) buf;
0131
0132 *val = htonl(off);
0133 }
0134
0135
0136 static int mlxsw_i2c_wait_go_bit(struct i2c_client *client,
0137 struct mlxsw_i2c *mlxsw_i2c, u8 *p_status)
0138 {
0139 u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0140 u8 buf[MLXSW_I2C_READ_SEMA_SIZE];
0141 int len = MLXSW_I2C_READ_SEMA_SIZE;
0142 struct i2c_msg read_sema[] =
0143 MLXSW_I2C_READ_MSG(client, addr_buf, buf, len);
0144 bool wait_done = false;
0145 unsigned long end;
0146 int i = 0, err;
0147
0148 mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_OFF_STATUS);
0149
0150 end = jiffies + msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0151 do {
0152 u32 ctrl;
0153
0154 err = i2c_transfer(client->adapter, read_sema,
0155 ARRAY_SIZE(read_sema));
0156
0157 ctrl = be32_to_cpu(*(__be32 *) buf);
0158 if (err == ARRAY_SIZE(read_sema)) {
0159 if (!(ctrl & MLXSW_I2C_GO_BIT)) {
0160 wait_done = true;
0161 *p_status = ctrl >>
0162 MLXSW_I2C_CIR_CTRL_STATUS_SHIFT;
0163 break;
0164 }
0165 }
0166 cond_resched();
0167 } while ((time_before(jiffies, end)) || (i++ < MLXSW_I2C_RETRY));
0168
0169 if (wait_done) {
0170 if (*p_status)
0171 err = -EIO;
0172 } else {
0173 return -ETIMEDOUT;
0174 }
0175
0176 return err > 0 ? 0 : err;
0177 }
0178
0179
0180 static int mlxsw_i2c_write_cmd(struct i2c_client *client,
0181 struct mlxsw_i2c *mlxsw_i2c,
0182 int immediate)
0183 {
0184 __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
0185 0, cpu_to_be32(MLXSW_I2C_PUSH_IMM_CMD)
0186 };
0187 __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
0188 0, 0, 0, 0, 0, 0,
0189 cpu_to_be32(client->adapter->nr & 0xffff),
0190 cpu_to_be32(MLXSW_I2C_SET_IMM_CMD)
0191 };
0192 struct i2c_msg push_cmd =
0193 MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
0194 MLXSW_I2C_PUSH_CMD_SIZE);
0195 struct i2c_msg prep_cmd =
0196 MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
0197 int err;
0198
0199 if (!immediate) {
0200 push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_CMD);
0201 prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_SET_CMD);
0202 }
0203 mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
0204 MLXSW_I2C_CIR2_BASE);
0205 mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
0206 MLXSW_I2C_CIR2_OFF_STATUS);
0207
0208
0209 err = i2c_transfer(client->adapter, &prep_cmd, 1);
0210 if (err < 0)
0211 return err;
0212 else if (err != 1)
0213 return -EIO;
0214
0215
0216 err = i2c_transfer(client->adapter, &push_cmd, 1);
0217 if (err < 0)
0218 return err;
0219 else if (err != 1)
0220 return -EIO;
0221
0222 return 0;
0223 }
0224
0225
0226 static int
0227 mlxsw_i2c_write_init_cmd(struct i2c_client *client,
0228 struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod)
0229 {
0230 __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = {
0231 0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD)
0232 };
0233 __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = {
0234 0, 0, 0, 0, 0, 0,
0235 cpu_to_be32(client->adapter->nr & 0xffff),
0236 cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD)
0237 };
0238 struct i2c_msg push_cmd =
0239 MLXSW_I2C_WRITE_MSG(client, push_cmd_buf,
0240 MLXSW_I2C_PUSH_CMD_SIZE);
0241 struct i2c_msg prep_cmd =
0242 MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE);
0243 u8 status;
0244 int err;
0245
0246 push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode);
0247 prep_cmd_buf[3] = cpu_to_be32(in_mod);
0248 prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode);
0249 mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf,
0250 MLXSW_I2C_CIR2_BASE);
0251 mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf,
0252 MLXSW_I2C_CIR2_OFF_STATUS);
0253
0254
0255 err = i2c_transfer(client->adapter, &prep_cmd, 1);
0256 if (err < 0)
0257 return err;
0258 else if (err != 1)
0259 return -EIO;
0260
0261
0262 err = i2c_transfer(client->adapter, &push_cmd, 1);
0263 if (err < 0)
0264 return err;
0265 else if (err != 1)
0266 return -EIO;
0267
0268
0269 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
0270 if (err) {
0271 dev_err(&client->dev, "HW semaphore is not released");
0272 return err;
0273 }
0274
0275
0276 if (status) {
0277 dev_err(&client->dev, "Bad transaction completion status %x\n",
0278 status);
0279 return -EIO;
0280 }
0281
0282 return 0;
0283 }
0284
0285
0286 static int mlxsw_i2c_get_mbox(struct i2c_client *client,
0287 struct mlxsw_i2c *mlxsw_i2c)
0288 {
0289 u8 addr_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0290 u8 buf[MLXSW_I2C_MBOX_SIZE];
0291 struct i2c_msg mbox_cmd[] =
0292 MLXSW_I2C_READ_MSG(client, addr_buf, buf, MLXSW_I2C_MBOX_SIZE);
0293 int err;
0294
0295
0296 mlxsw_i2c_set_slave_addr(addr_buf, MLXSW_I2C_CIR2_BASE);
0297 err = i2c_transfer(client->adapter, mbox_cmd, 2);
0298 if (err != 2) {
0299 dev_err(&client->dev, "Could not obtain mail boxes\n");
0300 if (!err)
0301 return -EIO;
0302 else
0303 return err;
0304 }
0305
0306
0307 mlxsw_i2c_convert_mbox(mlxsw_i2c, &buf[MLXSW_I2C_MBOX_OUT_PARAM_OFF]);
0308
0309 return err;
0310 }
0311
0312
0313 static int
0314 mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
0315 u8 *p_status)
0316 {
0317 struct i2c_client *client = to_i2c_client(dev);
0318 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0319 unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0320 int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
0321 unsigned long end;
0322 u8 *tran_buf;
0323 struct i2c_msg write_tran =
0324 MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);
0325 int err;
0326
0327 tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,
0328 GFP_KERNEL);
0329 if (!tran_buf)
0330 return -ENOMEM;
0331
0332 write_tran.buf = tran_buf;
0333 for (i = 0; i < num; i++) {
0334 chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?
0335 mlxsw_i2c->block_size : in_mbox_size;
0336 write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
0337 mlxsw_i2c_set_slave_addr(tran_buf, off);
0338 memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
0339 mlxsw_i2c->block_size * i, chunk_size);
0340
0341 j = 0;
0342 end = jiffies + timeout;
0343 do {
0344 err = i2c_transfer(client->adapter, &write_tran, 1);
0345 if (err == 1)
0346 break;
0347
0348 cond_resched();
0349 } while ((time_before(jiffies, end)) ||
0350 (j++ < MLXSW_I2C_RETRY));
0351
0352 if (err != 1) {
0353 if (!err) {
0354 err = -EIO;
0355 goto mlxsw_i2c_write_exit;
0356 }
0357 }
0358
0359 off += chunk_size;
0360 in_mbox_size -= chunk_size;
0361 }
0362
0363
0364 err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
0365 if (err) {
0366 dev_err(&client->dev, "Could not start transaction");
0367 err = -EIO;
0368 goto mlxsw_i2c_write_exit;
0369 }
0370
0371
0372 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
0373 if (err) {
0374 dev_err(&client->dev, "HW semaphore is not released");
0375 goto mlxsw_i2c_write_exit;
0376 }
0377
0378
0379 if (*p_status) {
0380 dev_err(&client->dev, "Bad transaction completion status %x\n",
0381 *p_status);
0382 err = -EIO;
0383 }
0384
0385 mlxsw_i2c_write_exit:
0386 kfree(tran_buf);
0387 return err;
0388 }
0389
0390
0391 static int
0392 mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
0393 u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status)
0394 {
0395 struct i2c_client *client = to_i2c_client(dev);
0396 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0397 unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
0398 u8 tran_buf[MLXSW_I2C_ADDR_BUF_SIZE];
0399 int num, chunk_size, reg_size, i, j;
0400 int off = mlxsw_i2c->cmd.mb_off_out;
0401 unsigned long end;
0402 struct i2c_msg read_tran[] =
0403 MLXSW_I2C_READ_MSG(client, tran_buf, NULL, 0);
0404 int err;
0405
0406 WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
0407
0408 if (in_mbox) {
0409 reg_size = mlxsw_i2c_get_reg_size(in_mbox);
0410 num = reg_size / mlxsw_i2c->block_size;
0411 if (reg_size % mlxsw_i2c->block_size)
0412 num++;
0413
0414 if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
0415 dev_err(&client->dev, "Could not acquire lock");
0416 return -EINVAL;
0417 }
0418
0419 err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
0420 if (err)
0421 goto cmd_fail;
0422
0423
0424 if (!out_mbox) {
0425 mutex_unlock(&mlxsw_i2c->cmd.lock);
0426 return 0;
0427 }
0428 } else {
0429
0430 reg_size = MLXSW_I2C_MAX_DATA_SIZE;
0431 num = reg_size / mlxsw_i2c->block_size;
0432
0433 if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
0434 dev_err(&client->dev, "Could not acquire lock");
0435 return -EINVAL;
0436 }
0437
0438 err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,
0439 in_mod);
0440 if (err)
0441 goto cmd_fail;
0442 }
0443
0444
0445 read_tran[1].buf = out_mbox;
0446 for (i = 0; i < num; i++) {
0447 chunk_size = (reg_size > mlxsw_i2c->block_size) ?
0448 mlxsw_i2c->block_size : reg_size;
0449 read_tran[1].len = chunk_size;
0450 mlxsw_i2c_set_slave_addr(tran_buf, off);
0451
0452 j = 0;
0453 end = jiffies + timeout;
0454 do {
0455 err = i2c_transfer(client->adapter, read_tran,
0456 ARRAY_SIZE(read_tran));
0457 if (err == ARRAY_SIZE(read_tran))
0458 break;
0459
0460 cond_resched();
0461 } while ((time_before(jiffies, end)) ||
0462 (j++ < MLXSW_I2C_RETRY));
0463
0464 if (err != ARRAY_SIZE(read_tran)) {
0465 if (!err)
0466 err = -EIO;
0467
0468 goto cmd_fail;
0469 }
0470
0471 off += chunk_size;
0472 reg_size -= chunk_size;
0473 read_tran[1].buf += chunk_size;
0474 }
0475
0476 mutex_unlock(&mlxsw_i2c->cmd.lock);
0477
0478 return 0;
0479
0480 cmd_fail:
0481 mutex_unlock(&mlxsw_i2c->cmd.lock);
0482 return err;
0483 }
0484
0485 static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
0486 u32 in_mod, bool out_mbox_direct,
0487 char *in_mbox, size_t in_mbox_size,
0488 char *out_mbox, size_t out_mbox_size,
0489 u8 *status)
0490 {
0491 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0492
0493 return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size,
0494 in_mbox, out_mbox_size, out_mbox, status);
0495 }
0496
0497 static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv,
0498 const struct mlxsw_tx_info *tx_info)
0499 {
0500 return false;
0501 }
0502
0503 static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
0504 const struct mlxsw_tx_info *tx_info)
0505 {
0506 return 0;
0507 }
0508
0509 static int
0510 mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
0511 const struct mlxsw_config_profile *profile,
0512 struct mlxsw_res *res)
0513 {
0514 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0515 char *mbox;
0516 int err;
0517
0518 mlxsw_i2c->core = mlxsw_core;
0519
0520 mbox = mlxsw_cmd_mbox_alloc();
0521 if (!mbox)
0522 return -ENOMEM;
0523
0524 err = mlxsw_cmd_query_fw(mlxsw_core, mbox);
0525 if (err)
0526 goto mbox_put;
0527
0528 mlxsw_i2c->bus_info.fw_rev.major =
0529 mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox);
0530 mlxsw_i2c->bus_info.fw_rev.minor =
0531 mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox);
0532 mlxsw_i2c->bus_info.fw_rev.subminor =
0533 mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox);
0534
0535 err = mlxsw_core_resources_query(mlxsw_core, mbox, res);
0536
0537 mbox_put:
0538 mlxsw_cmd_mbox_free(mbox);
0539 return err;
0540 }
0541
0542 static void mlxsw_i2c_fini(void *bus_priv)
0543 {
0544 struct mlxsw_i2c *mlxsw_i2c = bus_priv;
0545
0546 mlxsw_i2c->core = NULL;
0547 }
0548
0549 static const struct mlxsw_bus mlxsw_i2c_bus = {
0550 .kind = "i2c",
0551 .init = mlxsw_i2c_init,
0552 .fini = mlxsw_i2c_fini,
0553 .skb_transmit_busy = mlxsw_i2c_skb_transmit_busy,
0554 .skb_transmit = mlxsw_i2c_skb_transmit,
0555 .cmd_exec = mlxsw_i2c_cmd_exec,
0556 };
0557
0558 static int mlxsw_i2c_probe(struct i2c_client *client,
0559 const struct i2c_device_id *id)
0560 {
0561 const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
0562 struct mlxsw_i2c *mlxsw_i2c;
0563 u8 status;
0564 int err;
0565
0566 mlxsw_i2c = devm_kzalloc(&client->dev, sizeof(*mlxsw_i2c), GFP_KERNEL);
0567 if (!mlxsw_i2c)
0568 return -ENOMEM;
0569
0570 if (quirks) {
0571 if ((quirks->max_read_len &&
0572 quirks->max_read_len < MLXSW_I2C_BLK_DEF) ||
0573 (quirks->max_write_len &&
0574 quirks->max_write_len < MLXSW_I2C_BLK_DEF)) {
0575 dev_err(&client->dev, "Insufficient transaction buffer length\n");
0576 return -EOPNOTSUPP;
0577 }
0578
0579 mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
0580 min_t(u16, quirks->max_read_len,
0581 quirks->max_write_len));
0582 } else {
0583 mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;
0584 }
0585
0586 i2c_set_clientdata(client, mlxsw_i2c);
0587 mutex_init(&mlxsw_i2c->cmd.lock);
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602 err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 1);
0603 if (err) {
0604 dev_err(&client->dev, "Could not start transaction");
0605 goto errout;
0606 }
0607
0608
0609 err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
0610 if (err) {
0611 dev_err(&client->dev, "HW semaphore is not released");
0612 goto errout;
0613 }
0614
0615
0616 if (status) {
0617 dev_err(&client->dev, "Bad transaction completion status %x\n",
0618 status);
0619 err = -EIO;
0620 goto errout;
0621 }
0622
0623
0624 err = mlxsw_i2c_get_mbox(client, mlxsw_i2c);
0625 if (err < 0) {
0626 dev_err(&client->dev, "Fail to get mailboxes\n");
0627 goto errout;
0628 }
0629
0630 dev_info(&client->dev, "%s mb size=%x off=0x%08x out mb size=%x off=0x%08x\n",
0631 id->name, mlxsw_i2c->cmd.mb_size_in,
0632 mlxsw_i2c->cmd.mb_off_in, mlxsw_i2c->cmd.mb_size_out,
0633 mlxsw_i2c->cmd.mb_off_out);
0634
0635
0636 mlxsw_i2c->bus_info.device_kind = id->name;
0637 mlxsw_i2c->bus_info.device_name = client->name;
0638 mlxsw_i2c->bus_info.dev = &client->dev;
0639 mlxsw_i2c->bus_info.low_frequency = true;
0640 mlxsw_i2c->dev = &client->dev;
0641
0642 err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
0643 &mlxsw_i2c_bus, mlxsw_i2c, false,
0644 NULL, NULL);
0645 if (err) {
0646 dev_err(&client->dev, "Fail to register core bus\n");
0647 return err;
0648 }
0649
0650 return 0;
0651
0652 errout:
0653 mutex_destroy(&mlxsw_i2c->cmd.lock);
0654 i2c_set_clientdata(client, NULL);
0655
0656 return err;
0657 }
0658
0659 static int mlxsw_i2c_remove(struct i2c_client *client)
0660 {
0661 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
0662
0663 mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
0664 mutex_destroy(&mlxsw_i2c->cmd.lock);
0665
0666 return 0;
0667 }
0668
0669 int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
0670 {
0671 i2c_driver->probe = mlxsw_i2c_probe;
0672 i2c_driver->remove = mlxsw_i2c_remove;
0673 return i2c_add_driver(i2c_driver);
0674 }
0675 EXPORT_SYMBOL(mlxsw_i2c_driver_register);
0676
0677 void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
0678 {
0679 i2c_del_driver(i2c_driver);
0680 }
0681 EXPORT_SYMBOL(mlxsw_i2c_driver_unregister);
0682
0683 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
0684 MODULE_DESCRIPTION("Mellanox switch I2C interface driver");
0685 MODULE_LICENSE("Dual BSD/GPL");