0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/errno.h>
0016 #include <linux/i2c.h>
0017 #include <linux/slab.h>
0018 #include <linux/usb.h>
0019
0020 #define OSIFI2C_READ 20
0021 #define OSIFI2C_WRITE 21
0022 #define OSIFI2C_STOP 22
0023 #define OSIFI2C_STATUS 23
0024 #define OSIFI2C_SET_BIT_RATE 24
0025
0026 #define STATUS_ADDRESS_ACK 0
0027 #define STATUS_ADDRESS_NAK 2
0028
0029 struct osif_priv {
0030 struct usb_device *usb_dev;
0031 struct usb_interface *interface;
0032 struct i2c_adapter adapter;
0033 unsigned char status;
0034 };
0035
0036 static int osif_usb_read(struct i2c_adapter *adapter, int cmd,
0037 int value, int index, void *data, int len)
0038 {
0039 struct osif_priv *priv = adapter->algo_data;
0040
0041 return usb_control_msg(priv->usb_dev, usb_rcvctrlpipe(priv->usb_dev, 0),
0042 cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
0043 USB_DIR_IN, value, index, data, len, 2000);
0044 }
0045
0046 static int osif_usb_write(struct i2c_adapter *adapter, int cmd,
0047 int value, int index, void *data, int len)
0048 {
0049
0050 struct osif_priv *priv = adapter->algo_data;
0051
0052 return usb_control_msg(priv->usb_dev, usb_sndctrlpipe(priv->usb_dev, 0),
0053 cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0054 value, index, data, len, 2000);
0055 }
0056
0057 static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
0058 int num)
0059 {
0060 struct osif_priv *priv = adapter->algo_data;
0061 struct i2c_msg *pmsg;
0062 int ret;
0063 int i;
0064
0065 for (i = 0; i < num; i++) {
0066 pmsg = &msgs[i];
0067
0068 if (pmsg->flags & I2C_M_RD) {
0069 ret = osif_usb_read(adapter, OSIFI2C_READ,
0070 pmsg->flags, pmsg->addr,
0071 pmsg->buf, pmsg->len);
0072 if (ret != pmsg->len) {
0073 dev_err(&adapter->dev, "failure reading data\n");
0074 return -EREMOTEIO;
0075 }
0076 } else {
0077 ret = osif_usb_write(adapter, OSIFI2C_WRITE,
0078 pmsg->flags, pmsg->addr,
0079 pmsg->buf, pmsg->len);
0080 if (ret != pmsg->len) {
0081 dev_err(&adapter->dev, "failure writing data\n");
0082 return -EREMOTEIO;
0083 }
0084 }
0085
0086 ret = osif_usb_write(adapter, OSIFI2C_STOP, 0, 0, NULL, 0);
0087 if (ret) {
0088 dev_err(&adapter->dev, "failure sending STOP\n");
0089 return -EREMOTEIO;
0090 }
0091
0092
0093 ret = osif_usb_read(adapter, OSIFI2C_STATUS, 0, 0,
0094 &priv->status, 1);
0095 if (ret != 1) {
0096 dev_err(&adapter->dev, "failure reading status\n");
0097 return -EREMOTEIO;
0098 }
0099
0100 if (priv->status != STATUS_ADDRESS_ACK) {
0101 dev_dbg(&adapter->dev, "status = %d\n", priv->status);
0102 return -EREMOTEIO;
0103 }
0104 }
0105
0106 return i;
0107 }
0108
0109 static u32 osif_func(struct i2c_adapter *adapter)
0110 {
0111 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0112 }
0113
0114 static const struct i2c_algorithm osif_algorithm = {
0115 .master_xfer = osif_xfer,
0116 .functionality = osif_func,
0117 };
0118
0119 #define USB_OSIF_VENDOR_ID 0x1964
0120 #define USB_OSIF_PRODUCT_ID 0x0001
0121
0122 static const struct usb_device_id osif_table[] = {
0123 { USB_DEVICE(USB_OSIF_VENDOR_ID, USB_OSIF_PRODUCT_ID) },
0124 { }
0125 };
0126 MODULE_DEVICE_TABLE(usb, osif_table);
0127
0128 static int osif_probe(struct usb_interface *interface,
0129 const struct usb_device_id *id)
0130 {
0131 int ret;
0132 struct osif_priv *priv;
0133 u16 version;
0134
0135 priv = devm_kzalloc(&interface->dev, sizeof(*priv), GFP_KERNEL);
0136 if (!priv)
0137 return -ENOMEM;
0138
0139 priv->usb_dev = usb_get_dev(interface_to_usbdev(interface));
0140 priv->interface = interface;
0141
0142 usb_set_intfdata(interface, priv);
0143
0144 priv->adapter.owner = THIS_MODULE;
0145 priv->adapter.class = I2C_CLASS_HWMON;
0146 priv->adapter.algo = &osif_algorithm;
0147 priv->adapter.algo_data = priv;
0148 snprintf(priv->adapter.name, sizeof(priv->adapter.name),
0149 "OSIF at bus %03d device %03d",
0150 priv->usb_dev->bus->busnum, priv->usb_dev->devnum);
0151
0152
0153
0154
0155
0156 ret = osif_usb_write(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0,
0157 NULL, 0);
0158 if (ret) {
0159 dev_err(&interface->dev, "failure sending bit rate");
0160 usb_put_dev(priv->usb_dev);
0161 return ret;
0162 }
0163
0164 i2c_add_adapter(&(priv->adapter));
0165
0166 version = le16_to_cpu(priv->usb_dev->descriptor.bcdDevice);
0167 dev_info(&interface->dev,
0168 "version %x.%02x found at bus %03d address %03d",
0169 version >> 8, version & 0xff,
0170 priv->usb_dev->bus->busnum, priv->usb_dev->devnum);
0171
0172 return 0;
0173 }
0174
0175 static void osif_disconnect(struct usb_interface *interface)
0176 {
0177 struct osif_priv *priv = usb_get_intfdata(interface);
0178
0179 i2c_del_adapter(&(priv->adapter));
0180 usb_set_intfdata(interface, NULL);
0181 usb_put_dev(priv->usb_dev);
0182 }
0183
0184 static struct usb_driver osif_driver = {
0185 .name = "RobotFuzz Open Source InterFace, OSIF",
0186 .probe = osif_probe,
0187 .disconnect = osif_disconnect,
0188 .id_table = osif_table,
0189 };
0190
0191 module_usb_driver(osif_driver);
0192
0193 MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
0194 MODULE_AUTHOR("Barry Carter <barry.carter@robotfuzz.com>");
0195 MODULE_DESCRIPTION("RobotFuzz OSIF driver");
0196 MODULE_LICENSE("GPL v2");