1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * I2C slave mode testunit 4 * 5 * Copyright (C) 2020 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> 6 * Copyright (C) 2020 by Renesas Electronics Corporation 7 */ 8 9 #include <generated/utsrelease.h> 10 #include <linux/bitops.h> 11 #include <linux/completion.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/i2c.h> 14 #include <linux/init.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/slab.h> 18 #include <linux/workqueue.h> /* FIXME: is system_long_wq the best choice? */ 19 20 #define TU_VERSION_MAX_LENGTH 128 21 22 enum testunit_cmds { 23 TU_CMD_READ_BYTES = 1, /* save 0 for ABORT, RESET or similar */ 24 TU_CMD_SMBUS_HOST_NOTIFY, 25 TU_CMD_SMBUS_BLOCK_PROC_CALL, 26 TU_CMD_GET_VERSION_WITH_REP_START, 27 TU_CMD_SMBUS_ALERT_REQUEST, 28 TU_NUM_CMDS 29 }; 30 31 enum testunit_regs { 32 TU_REG_CMD, 33 TU_REG_DATAL, 34 TU_REG_DATAH, 35 TU_REG_DELAY, 36 TU_NUM_REGS 37 }; 38 39 enum testunit_flags { 40 TU_FLAG_IN_PROCESS, 41 TU_FLAG_NACK, 42 }; 43 44 struct testunit_data { 45 unsigned long flags; 46 u8 regs[TU_NUM_REGS]; 47 u8 reg_idx; 48 u8 read_idx; 49 struct i2c_client *client; 50 struct delayed_work worker; 51 struct gpio_desc *gpio; 52 struct completion alert_done; 53 }; 54 55 static char tu_version_info[] = "v" UTS_RELEASE "\n\0"; 56 57 static int i2c_slave_testunit_smbalert_cb(struct i2c_client *client, 58 enum i2c_slave_event event, u8 *val) 59 { 60 struct testunit_data *tu = i2c_get_clientdata(client); 61 62 switch (event) { 63 case I2C_SLAVE_READ_PROCESSED: 64 gpiod_set_value(tu->gpio, 0); 65 fallthrough; 66 case I2C_SLAVE_READ_REQUESTED: 67 *val = tu->regs[TU_REG_DATAL]; 68 break; 69 70 case I2C_SLAVE_STOP: 71 complete(&tu->alert_done); 72 break; 73 74 case I2C_SLAVE_WRITE_REQUESTED: 75 case I2C_SLAVE_WRITE_RECEIVED: 76 return -EOPNOTSUPP; 77 } 78 79 return 0; 80 } 81 82 static int i2c_slave_testunit_slave_cb(struct i2c_client *client, 83 enum i2c_slave_event event, u8 *val) 84 { 85 struct testunit_data *tu = i2c_get_clientdata(client); 86 bool is_proc_call = tu->reg_idx == 3 && tu->regs[TU_REG_DATAL] == 1 && 87 tu->regs[TU_REG_CMD] == TU_CMD_SMBUS_BLOCK_PROC_CALL; 88 bool is_get_version = tu->reg_idx == 3 && 89 tu->regs[TU_REG_CMD] == TU_CMD_GET_VERSION_WITH_REP_START; 90 int ret = 0; 91 92 switch (event) { 93 case I2C_SLAVE_WRITE_REQUESTED: 94 if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) { 95 ret = -EBUSY; 96 break; 97 } 98 99 memset(tu->regs, 0, TU_NUM_REGS); 100 tu->reg_idx = 0; 101 tu->read_idx = 0; 102 break; 103 104 case I2C_SLAVE_WRITE_RECEIVED: 105 if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) { 106 ret = -EBUSY; 107 break; 108 } 109 110 if (tu->reg_idx < TU_NUM_REGS) 111 tu->regs[tu->reg_idx] = *val; 112 else 113 ret = -EMSGSIZE; 114 115 if (tu->reg_idx <= TU_NUM_REGS) 116 tu->reg_idx++; 117 118 /* TU_REG_CMD always written at this point */ 119 if (tu->regs[TU_REG_CMD] >= TU_NUM_CMDS) 120 ret = -EINVAL; 121 122 break; 123 124 case I2C_SLAVE_STOP: 125 if (tu->reg_idx == TU_NUM_REGS) { 126 set_bit(TU_FLAG_IN_PROCESS, &tu->flags); 127 queue_delayed_work(system_long_wq, &tu->worker, 128 msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY])); 129 } 130 131 /* 132 * Reset reg_idx to avoid that work gets queued again in case of 133 * STOP after a following read message. But do not clear TU regs 134 * here because we still need them in the workqueue! 135 */ 136 tu->reg_idx = 0; 137 138 clear_bit(TU_FLAG_NACK, &tu->flags); 139 break; 140 141 case I2C_SLAVE_READ_PROCESSED: 142 /* Advance until we reach the NUL character */ 143 if (is_get_version && tu_version_info[tu->read_idx] != 0) 144 tu->read_idx++; 145 else if (is_proc_call && tu->regs[TU_REG_DATAH]) 146 tu->regs[TU_REG_DATAH]--; 147 148 fallthrough; 149 150 case I2C_SLAVE_READ_REQUESTED: 151 if (is_get_version) 152 *val = tu_version_info[tu->read_idx]; 153 else if (is_proc_call) 154 *val = tu->regs[TU_REG_DATAH]; 155 else 156 *val = test_bit(TU_FLAG_IN_PROCESS, &tu->flags) ? 157 tu->regs[TU_REG_CMD] : 0; 158 break; 159 } 160 161 /* If an error occurred somewhen, we NACK everything until next STOP */ 162 if (ret) 163 set_bit(TU_FLAG_NACK, &tu->flags); 164 165 return ret; 166 } 167 168 static void i2c_slave_testunit_work(struct work_struct *work) 169 { 170 struct testunit_data *tu = container_of(work, struct testunit_data, worker.work); 171 unsigned long time_left; 172 struct i2c_msg msg; 173 u8 msgbuf[256]; 174 u16 orig_addr; 175 int ret = 0; 176 177 msg.addr = I2C_CLIENT_END; 178 msg.buf = msgbuf; 179 180 switch (tu->regs[TU_REG_CMD]) { 181 case TU_CMD_READ_BYTES: 182 msg.addr = tu->regs[TU_REG_DATAL]; 183 msg.flags = I2C_M_RD; 184 msg.len = tu->regs[TU_REG_DATAH]; 185 break; 186 187 case TU_CMD_SMBUS_HOST_NOTIFY: 188 msg.addr = 0x08; 189 msg.flags = 0; 190 msg.len = 3; 191 msgbuf[0] = tu->client->addr; 192 msgbuf[1] = tu->regs[TU_REG_DATAL]; 193 msgbuf[2] = tu->regs[TU_REG_DATAH]; 194 break; 195 196 case TU_CMD_SMBUS_ALERT_REQUEST: 197 if (!tu->gpio) { 198 ret = -ENOENT; 199 break; 200 } 201 i2c_slave_unregister(tu->client); 202 orig_addr = tu->client->addr; 203 tu->client->addr = 0x0c; 204 ret = i2c_slave_register(tu->client, i2c_slave_testunit_smbalert_cb); 205 if (ret) 206 goto out_smbalert; 207 208 reinit_completion(&tu->alert_done); 209 gpiod_set_value(tu->gpio, 1); 210 time_left = wait_for_completion_timeout(&tu->alert_done, HZ); 211 if (!time_left) 212 ret = -ETIMEDOUT; 213 214 i2c_slave_unregister(tu->client); 215 out_smbalert: 216 tu->client->addr = orig_addr; 217 i2c_slave_register(tu->client, i2c_slave_testunit_slave_cb); 218 break; 219 220 default: 221 break; 222 } 223 224 if (msg.addr != I2C_CLIENT_END) { 225 ret = i2c_transfer(tu->client->adapter, &msg, 1); 226 /* convert '0 msgs transferred' to errno */ 227 ret = (ret == 0) ? -EIO : ret; 228 } 229 230 if (ret < 0) 231 dev_err(&tu->client->dev, "CMD%02X failed (%d)\n", tu->regs[TU_REG_CMD], ret); 232 233 clear_bit(TU_FLAG_IN_PROCESS, &tu->flags); 234 } 235 236 static int i2c_slave_testunit_probe(struct i2c_client *client) 237 { 238 struct testunit_data *tu; 239 240 tu = devm_kzalloc(&client->dev, sizeof(struct testunit_data), GFP_KERNEL); 241 if (!tu) 242 return -ENOMEM; 243 244 tu->client = client; 245 i2c_set_clientdata(client, tu); 246 init_completion(&tu->alert_done); 247 INIT_DELAYED_WORK(&tu->worker, i2c_slave_testunit_work); 248 249 tu->gpio = devm_gpiod_get_index_optional(&client->dev, NULL, 0, GPIOD_OUT_LOW); 250 if (IS_ERR(tu->gpio)) 251 return PTR_ERR(tu->gpio); 252 253 if (gpiod_cansleep(tu->gpio)) { 254 dev_err(&client->dev, "GPIO access which may sleep is not allowed\n"); 255 return -EDEADLK; 256 } 257 258 if (sizeof(tu_version_info) > TU_VERSION_MAX_LENGTH) 259 tu_version_info[TU_VERSION_MAX_LENGTH - 1] = 0; 260 261 return i2c_slave_register(client, i2c_slave_testunit_slave_cb); 262 }; 263 264 static void i2c_slave_testunit_remove(struct i2c_client *client) 265 { 266 struct testunit_data *tu = i2c_get_clientdata(client); 267 268 cancel_delayed_work_sync(&tu->worker); 269 i2c_slave_unregister(client); 270 } 271 272 static const struct i2c_device_id i2c_slave_testunit_id[] = { 273 { "slave-testunit" }, 274 { } 275 }; 276 MODULE_DEVICE_TABLE(i2c, i2c_slave_testunit_id); 277 278 static struct i2c_driver i2c_slave_testunit_driver = { 279 .driver = { 280 .name = "i2c-slave-testunit", 281 }, 282 .probe = i2c_slave_testunit_probe, 283 .remove = i2c_slave_testunit_remove, 284 .id_table = i2c_slave_testunit_id, 285 }; 286 module_i2c_driver(i2c_slave_testunit_driver); 287 288 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); 289 MODULE_DESCRIPTION("I2C slave mode test unit"); 290 MODULE_LICENSE("GPL v2"); 291