1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel La Jolla Cove Adapter USB-I2C driver 4 * 5 * Copyright (c) 2023, Intel Corporation. 6 */ 7 8 #include <linux/acpi.h> 9 #include <linux/auxiliary_bus.h> 10 #include <linux/bitfield.h> 11 #include <linux/bits.h> 12 #include <linux/dev_printk.h> 13 #include <linux/i2c.h> 14 #include <linux/module.h> 15 #include <linux/usb/ljca.h> 16 17 /* I2C init flags */ 18 #define LJCA_I2C_INIT_FLAG_MODE BIT(0) 19 #define LJCA_I2C_INIT_FLAG_MODE_POLLING FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 0) 20 #define LJCA_I2C_INIT_FLAG_MODE_INTERRUPT FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 1) 21 22 #define LJCA_I2C_INIT_FLAG_ADDR_16BIT BIT(0) 23 24 #define LJCA_I2C_INIT_FLAG_FREQ GENMASK(2, 1) 25 #define LJCA_I2C_INIT_FLAG_FREQ_100K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 0) 26 #define LJCA_I2C_INIT_FLAG_FREQ_400K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 1) 27 #define LJCA_I2C_INIT_FLAG_FREQ_1M FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 2) 28 29 #define LJCA_I2C_BUF_SIZE 60u 30 #define LJCA_I2C_MAX_XFER_SIZE (LJCA_I2C_BUF_SIZE - sizeof(struct ljca_i2c_rw_packet)) 31 32 /* I2C commands */ 33 enum ljca_i2c_cmd { 34 LJCA_I2C_INIT = 1, 35 LJCA_I2C_XFER, 36 LJCA_I2C_START, 37 LJCA_I2C_STOP, 38 LJCA_I2C_READ, 39 LJCA_I2C_WRITE, 40 }; 41 42 enum ljca_xfer_type { 43 LJCA_I2C_WRITE_XFER_TYPE, 44 LJCA_I2C_READ_XFER_TYPE, 45 }; 46 47 /* I2C raw commands: Init/Start/Read/Write/Stop */ 48 struct ljca_i2c_rw_packet { 49 u8 id; 50 __le16 len; 51 u8 data[] __counted_by(len); 52 } __packed; 53 54 struct ljca_i2c_dev { 55 struct ljca_client *ljca; 56 struct ljca_i2c_info *i2c_info; 57 struct i2c_adapter adap; 58 59 u8 obuf[LJCA_I2C_BUF_SIZE]; 60 u8 ibuf[LJCA_I2C_BUF_SIZE]; 61 }; 62 63 static int ljca_i2c_init(struct ljca_i2c_dev *ljca_i2c, u8 id) 64 { 65 struct ljca_i2c_rw_packet *w_packet = 66 (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; 67 int ret; 68 69 w_packet->id = id; 70 w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); 71 w_packet->data[0] = LJCA_I2C_INIT_FLAG_FREQ_400K; 72 73 ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_INIT, (u8 *)w_packet, 74 struct_size(w_packet, data, 1), NULL, 0); 75 76 return ret < 0 ? ret : 0; 77 } 78 79 static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 target_addr, 80 enum ljca_xfer_type type) 81 { 82 struct ljca_i2c_rw_packet *w_packet = 83 (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; 84 struct ljca_i2c_rw_packet *r_packet = 85 (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; 86 s16 rp_len; 87 int ret; 88 89 w_packet->id = ljca_i2c->i2c_info->id; 90 w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); 91 w_packet->data[0] = (target_addr << 1) | type; 92 93 ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_START, (u8 *)w_packet, 94 struct_size(w_packet, data, 1), (u8 *)r_packet, 95 LJCA_I2C_BUF_SIZE); 96 if (ret < 0 || ret < sizeof(*r_packet)) 97 return ret < 0 ? ret : -EIO; 98 99 rp_len = le16_to_cpu(r_packet->len); 100 if (rp_len < 0 || r_packet->id != w_packet->id) { 101 dev_dbg(&ljca_i2c->adap.dev, 102 "i2c start failed len: %d id: %d %d\n", 103 rp_len, r_packet->id, w_packet->id); 104 return -EIO; 105 } 106 107 return 0; 108 } 109 110 static void ljca_i2c_stop(struct ljca_i2c_dev *ljca_i2c) 111 { 112 struct ljca_i2c_rw_packet *w_packet = 113 (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; 114 struct ljca_i2c_rw_packet *r_packet = 115 (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; 116 s16 rp_len; 117 int ret; 118 119 w_packet->id = ljca_i2c->i2c_info->id; 120 w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); 121 w_packet->data[0] = 0; 122 123 ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_STOP, (u8 *)w_packet, 124 struct_size(w_packet, data, 1), (u8 *)r_packet, 125 LJCA_I2C_BUF_SIZE); 126 if (ret < 0 || ret < sizeof(*r_packet)) { 127 dev_dbg(&ljca_i2c->adap.dev, 128 "i2c stop failed ret: %d id: %d\n", 129 ret, w_packet->id); 130 return; 131 } 132 133 rp_len = le16_to_cpu(r_packet->len); 134 if (rp_len < 0 || r_packet->id != w_packet->id) 135 dev_dbg(&ljca_i2c->adap.dev, 136 "i2c stop failed len: %d id: %d %d\n", 137 rp_len, r_packet->id, w_packet->id); 138 } 139 140 static int ljca_i2c_pure_read(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len) 141 { 142 struct ljca_i2c_rw_packet *w_packet = 143 (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; 144 struct ljca_i2c_rw_packet *r_packet = 145 (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; 146 s16 rp_len; 147 int ret; 148 149 w_packet->id = ljca_i2c->i2c_info->id; 150 w_packet->len = cpu_to_le16(len); 151 w_packet->data[0] = 0; 152 153 ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_READ, (u8 *)w_packet, 154 struct_size(w_packet, data, 1), (u8 *)r_packet, 155 LJCA_I2C_BUF_SIZE); 156 if (ret < 0 || ret < sizeof(*r_packet)) 157 return ret < 0 ? ret : -EIO; 158 159 rp_len = le16_to_cpu(r_packet->len); 160 if (rp_len != len || r_packet->id != w_packet->id) { 161 dev_dbg(&ljca_i2c->adap.dev, 162 "i2c raw read failed len: %d id: %d %d\n", 163 rp_len, r_packet->id, w_packet->id); 164 return -EIO; 165 } 166 167 memcpy(data, r_packet->data, len); 168 169 return 0; 170 } 171 172 static int ljca_i2c_read(struct ljca_i2c_dev *ljca_i2c, u8 target_addr, u8 *data, 173 u8 len) 174 { 175 int ret; 176 177 ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_READ_XFER_TYPE); 178 if (!ret) 179 ret = ljca_i2c_pure_read(ljca_i2c, data, len); 180 181 ljca_i2c_stop(ljca_i2c); 182 183 return ret; 184 } 185 186 static int ljca_i2c_pure_write(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len) 187 { 188 struct ljca_i2c_rw_packet *w_packet = 189 (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; 190 struct ljca_i2c_rw_packet *r_packet = 191 (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; 192 s16 rplen; 193 int ret; 194 195 w_packet->id = ljca_i2c->i2c_info->id; 196 w_packet->len = cpu_to_le16(len); 197 memcpy(w_packet->data, data, len); 198 199 ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_WRITE, (u8 *)w_packet, 200 struct_size(w_packet, data, len), (u8 *)r_packet, 201 LJCA_I2C_BUF_SIZE); 202 if (ret < 0 || ret < sizeof(*r_packet)) 203 return ret < 0 ? ret : -EIO; 204 205 rplen = le16_to_cpu(r_packet->len); 206 if (rplen != len || r_packet->id != w_packet->id) { 207 dev_dbg(&ljca_i2c->adap.dev, 208 "i2c write failed len: %d id: %d/%d\n", 209 rplen, r_packet->id, w_packet->id); 210 return -EIO; 211 } 212 213 return 0; 214 } 215 216 static int ljca_i2c_write(struct ljca_i2c_dev *ljca_i2c, u8 target_addr, 217 u8 *data, u8 len) 218 { 219 int ret; 220 221 ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_WRITE_XFER_TYPE); 222 if (!ret) 223 ret = ljca_i2c_pure_write(ljca_i2c, data, len); 224 225 ljca_i2c_stop(ljca_i2c); 226 227 return ret; 228 } 229 230 static int ljca_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, 231 int num) 232 { 233 struct ljca_i2c_dev *ljca_i2c; 234 struct i2c_msg *cur_msg; 235 int i, ret; 236 237 ljca_i2c = i2c_get_adapdata(adapter); 238 if (!ljca_i2c) 239 return -EINVAL; 240 241 for (i = 0; i < num; i++) { 242 cur_msg = &msg[i]; 243 if (cur_msg->flags & I2C_M_RD) 244 ret = ljca_i2c_read(ljca_i2c, cur_msg->addr, 245 cur_msg->buf, cur_msg->len); 246 else 247 ret = ljca_i2c_write(ljca_i2c, cur_msg->addr, 248 cur_msg->buf, cur_msg->len); 249 250 if (ret) 251 return ret; 252 } 253 254 return num; 255 } 256 257 static u32 ljca_i2c_func(struct i2c_adapter *adap) 258 { 259 return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); 260 } 261 262 static const struct i2c_adapter_quirks ljca_i2c_quirks = { 263 .flags = I2C_AQ_NO_ZERO_LEN, 264 .max_read_len = LJCA_I2C_MAX_XFER_SIZE, 265 .max_write_len = LJCA_I2C_MAX_XFER_SIZE, 266 }; 267 268 static const struct i2c_algorithm ljca_i2c_algo = { 269 .xfer = ljca_i2c_xfer, 270 .functionality = ljca_i2c_func, 271 }; 272 273 static int ljca_i2c_probe(struct auxiliary_device *auxdev, 274 const struct auxiliary_device_id *aux_dev_id) 275 { 276 struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); 277 struct ljca_i2c_dev *ljca_i2c; 278 int ret; 279 280 ljca_i2c = devm_kzalloc(&auxdev->dev, sizeof(*ljca_i2c), GFP_KERNEL); 281 if (!ljca_i2c) 282 return -ENOMEM; 283 284 ljca_i2c->ljca = ljca; 285 ljca_i2c->i2c_info = dev_get_platdata(&auxdev->dev); 286 287 ljca_i2c->adap.owner = THIS_MODULE; 288 ljca_i2c->adap.class = I2C_CLASS_HWMON; 289 ljca_i2c->adap.algo = &ljca_i2c_algo; 290 ljca_i2c->adap.quirks = &ljca_i2c_quirks; 291 ljca_i2c->adap.dev.parent = &auxdev->dev; 292 293 snprintf(ljca_i2c->adap.name, sizeof(ljca_i2c->adap.name), "%s-%s-%d", 294 dev_name(&auxdev->dev), dev_name(auxdev->dev.parent), 295 ljca_i2c->i2c_info->id); 296 297 device_set_node(&ljca_i2c->adap.dev, dev_fwnode(&auxdev->dev)); 298 299 i2c_set_adapdata(&ljca_i2c->adap, ljca_i2c); 300 auxiliary_set_drvdata(auxdev, ljca_i2c); 301 302 ret = ljca_i2c_init(ljca_i2c, ljca_i2c->i2c_info->id); 303 if (ret) 304 return dev_err_probe(&auxdev->dev, -EIO, 305 "i2c init failed id: %d\n", 306 ljca_i2c->i2c_info->id); 307 308 ret = devm_i2c_add_adapter(&auxdev->dev, &ljca_i2c->adap); 309 if (ret) 310 return ret; 311 312 if (has_acpi_companion(&ljca_i2c->adap.dev)) 313 acpi_dev_clear_dependencies(ACPI_COMPANION(&ljca_i2c->adap.dev)); 314 315 return 0; 316 } 317 318 static void ljca_i2c_remove(struct auxiliary_device *auxdev) 319 { 320 struct ljca_i2c_dev *ljca_i2c = auxiliary_get_drvdata(auxdev); 321 322 i2c_del_adapter(&ljca_i2c->adap); 323 } 324 325 static const struct auxiliary_device_id ljca_i2c_id_table[] = { 326 { "usb_ljca.ljca-i2c", 0 }, 327 { /* sentinel */ } 328 }; 329 MODULE_DEVICE_TABLE(auxiliary, ljca_i2c_id_table); 330 331 static struct auxiliary_driver ljca_i2c_driver = { 332 .probe = ljca_i2c_probe, 333 .remove = ljca_i2c_remove, 334 .id_table = ljca_i2c_id_table, 335 }; 336 module_auxiliary_driver(ljca_i2c_driver); 337 338 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>"); 339 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>"); 340 MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>"); 341 MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-I2C driver"); 342 MODULE_LICENSE("GPL"); 343 MODULE_IMPORT_NS(LJCA); 344