1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for the Diolan DLN-2 USB-I2C adapter 4 * 5 * Copyright (c) 2014 Intel Corporation 6 * 7 * Derived from: 8 * i2c-diolan-u2c.c 9 * Copyright (c) 2010-2011 Ericsson AB 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/types.h> 15 #include <linux/slab.h> 16 #include <linux/i2c.h> 17 #include <linux/platform_device.h> 18 #include <linux/mfd/dln2.h> 19 #include <linux/acpi.h> 20 21 #define DLN2_I2C_MODULE_ID 0x03 22 #define DLN2_I2C_CMD(cmd) DLN2_CMD(cmd, DLN2_I2C_MODULE_ID) 23 24 /* I2C commands */ 25 #define DLN2_I2C_GET_PORT_COUNT DLN2_I2C_CMD(0x00) 26 #define DLN2_I2C_ENABLE DLN2_I2C_CMD(0x01) 27 #define DLN2_I2C_DISABLE DLN2_I2C_CMD(0x02) 28 #define DLN2_I2C_IS_ENABLED DLN2_I2C_CMD(0x03) 29 #define DLN2_I2C_WRITE DLN2_I2C_CMD(0x06) 30 #define DLN2_I2C_READ DLN2_I2C_CMD(0x07) 31 #define DLN2_I2C_SCAN_DEVICES DLN2_I2C_CMD(0x08) 32 #define DLN2_I2C_PULLUP_ENABLE DLN2_I2C_CMD(0x09) 33 #define DLN2_I2C_PULLUP_DISABLE DLN2_I2C_CMD(0x0A) 34 #define DLN2_I2C_PULLUP_IS_ENABLED DLN2_I2C_CMD(0x0B) 35 #define DLN2_I2C_TRANSFER DLN2_I2C_CMD(0x0C) 36 #define DLN2_I2C_SET_MAX_REPLY_COUNT DLN2_I2C_CMD(0x0D) 37 #define DLN2_I2C_GET_MAX_REPLY_COUNT DLN2_I2C_CMD(0x0E) 38 39 #define DLN2_I2C_MAX_XFER_SIZE 256 40 #define DLN2_I2C_BUF_SIZE (DLN2_I2C_MAX_XFER_SIZE + 16) 41 42 struct dln2_i2c { 43 struct platform_device *pdev; 44 struct i2c_adapter adapter; 45 u8 port; 46 /* 47 * Buffer to hold the packet for read or write transfers. One is enough 48 * since we can't have multiple transfers in parallel on the i2c bus. 49 */ 50 void *buf; 51 }; 52 53 static int dln2_i2c_enable(struct dln2_i2c *dln2, bool enable) 54 { 55 u16 cmd; 56 struct { 57 u8 port; 58 } tx; 59 60 tx.port = dln2->port; 61 62 if (enable) 63 cmd = DLN2_I2C_ENABLE; 64 else 65 cmd = DLN2_I2C_DISABLE; 66 67 return dln2_transfer_tx(dln2->pdev, cmd, &tx, sizeof(tx)); 68 } 69 70 static int dln2_i2c_write(struct dln2_i2c *dln2, u8 addr, 71 u8 *data, u16 data_len) 72 { 73 int ret; 74 struct { 75 u8 port; 76 u8 addr; 77 u8 mem_addr_len; 78 __le32 mem_addr; 79 __le16 buf_len; 80 u8 buf[DLN2_I2C_MAX_XFER_SIZE]; 81 } __packed *tx = dln2->buf; 82 unsigned len; 83 84 BUILD_BUG_ON(sizeof(*tx) > DLN2_I2C_BUF_SIZE); 85 86 tx->port = dln2->port; 87 tx->addr = addr; 88 tx->mem_addr_len = 0; 89 tx->mem_addr = 0; 90 tx->buf_len = cpu_to_le16(data_len); 91 memcpy(tx->buf, data, data_len); 92 93 len = sizeof(*tx) + data_len - DLN2_I2C_MAX_XFER_SIZE; 94 ret = dln2_transfer_tx(dln2->pdev, DLN2_I2C_WRITE, tx, len); 95 if (ret < 0) 96 return ret; 97 98 return data_len; 99 } 100 101 static int dln2_i2c_read(struct dln2_i2c *dln2, u16 addr, u8 *data, 102 u16 data_len) 103 { 104 int ret; 105 struct { 106 u8 port; 107 u8 addr; 108 u8 mem_addr_len; 109 __le32 mem_addr; 110 __le16 buf_len; 111 } __packed tx; 112 struct { 113 __le16 buf_len; 114 u8 buf[DLN2_I2C_MAX_XFER_SIZE]; 115 } __packed *rx = dln2->buf; 116 unsigned rx_len = sizeof(*rx); 117 118 BUILD_BUG_ON(sizeof(*rx) > DLN2_I2C_BUF_SIZE); 119 120 tx.port = dln2->port; 121 tx.addr = addr; 122 tx.mem_addr_len = 0; 123 tx.mem_addr = 0; 124 tx.buf_len = cpu_to_le16(data_len); 125 126 ret = dln2_transfer(dln2->pdev, DLN2_I2C_READ, &tx, sizeof(tx), 127 rx, &rx_len); 128 if (ret < 0) 129 return ret; 130 if (rx_len < sizeof(rx->buf_len) + data_len) 131 return -EPROTO; 132 if (le16_to_cpu(rx->buf_len) != data_len) 133 return -EPROTO; 134 135 memcpy(data, rx->buf, data_len); 136 137 return data_len; 138 } 139 140 static int dln2_i2c_xfer(struct i2c_adapter *adapter, 141 struct i2c_msg *msgs, int num) 142 { 143 struct dln2_i2c *dln2 = i2c_get_adapdata(adapter); 144 struct i2c_msg *pmsg; 145 int i; 146 147 for (i = 0; i < num; i++) { 148 int ret; 149 150 pmsg = &msgs[i]; 151 152 if (pmsg->flags & I2C_M_RD) { 153 ret = dln2_i2c_read(dln2, pmsg->addr, pmsg->buf, 154 pmsg->len); 155 if (ret < 0) 156 return ret; 157 158 pmsg->len = ret; 159 } else { 160 ret = dln2_i2c_write(dln2, pmsg->addr, pmsg->buf, 161 pmsg->len); 162 if (ret != pmsg->len) 163 return -EPROTO; 164 } 165 } 166 167 return num; 168 } 169 170 static u32 dln2_i2c_func(struct i2c_adapter *a) 171 { 172 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | 173 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 174 I2C_FUNC_SMBUS_I2C_BLOCK; 175 } 176 177 static const struct i2c_algorithm dln2_i2c_usb_algorithm = { 178 .master_xfer = dln2_i2c_xfer, 179 .functionality = dln2_i2c_func, 180 }; 181 182 static const struct i2c_adapter_quirks dln2_i2c_quirks = { 183 .max_read_len = DLN2_I2C_MAX_XFER_SIZE, 184 .max_write_len = DLN2_I2C_MAX_XFER_SIZE, 185 }; 186 187 static int dln2_i2c_probe(struct platform_device *pdev) 188 { 189 int ret; 190 struct dln2_i2c *dln2; 191 struct device *dev = &pdev->dev; 192 struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev); 193 194 dln2 = devm_kzalloc(dev, sizeof(*dln2), GFP_KERNEL); 195 if (!dln2) 196 return -ENOMEM; 197 198 dln2->buf = devm_kmalloc(dev, DLN2_I2C_BUF_SIZE, GFP_KERNEL); 199 if (!dln2->buf) 200 return -ENOMEM; 201 202 dln2->pdev = pdev; 203 dln2->port = pdata->port; 204 205 /* setup i2c adapter description */ 206 dln2->adapter.owner = THIS_MODULE; 207 dln2->adapter.class = I2C_CLASS_HWMON; 208 dln2->adapter.algo = &dln2_i2c_usb_algorithm; 209 dln2->adapter.quirks = &dln2_i2c_quirks; 210 dln2->adapter.dev.parent = dev; 211 ACPI_COMPANION_SET(&dln2->adapter.dev, ACPI_COMPANION(&pdev->dev)); 212 dln2->adapter.dev.of_node = dev->of_node; 213 i2c_set_adapdata(&dln2->adapter, dln2); 214 snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d", 215 "dln2-i2c", dev_name(pdev->dev.parent), dln2->port); 216 217 platform_set_drvdata(pdev, dln2); 218 219 /* initialize the i2c interface */ 220 ret = dln2_i2c_enable(dln2, true); 221 if (ret < 0) 222 return dev_err_probe(dev, ret, "failed to initialize adapter\n"); 223 224 /* and finally attach to i2c layer */ 225 ret = i2c_add_adapter(&dln2->adapter); 226 if (ret < 0) 227 goto out_disable; 228 229 return 0; 230 231 out_disable: 232 dln2_i2c_enable(dln2, false); 233 234 return ret; 235 } 236 237 static void dln2_i2c_remove(struct platform_device *pdev) 238 { 239 struct dln2_i2c *dln2 = platform_get_drvdata(pdev); 240 241 i2c_del_adapter(&dln2->adapter); 242 dln2_i2c_enable(dln2, false); 243 } 244 245 static struct platform_driver dln2_i2c_driver = { 246 .driver.name = "dln2-i2c", 247 .probe = dln2_i2c_probe, 248 .remove_new = dln2_i2c_remove, 249 }; 250 251 module_platform_driver(dln2_i2c_driver); 252 253 MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>"); 254 MODULE_DESCRIPTION("Driver for the Diolan DLN2 I2C master interface"); 255 MODULE_LICENSE("GPL v2"); 256 MODULE_ALIAS("platform:dln2-i2c"); 257