^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the Diolan u2c-12 USB-I2C adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010-2011 Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Derived from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * i2c-tiny-usb.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DRIVER_NAME "i2c-diolan-u2c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define USB_VENDOR_ID_DIOLAN 0x0abf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define USB_DEVICE_ID_DIOLAN_U2C 0x3370
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* commands via USB, must match command ids in the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CMD_I2C_READ 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CMD_I2C_WRITE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CMD_I2C_SCAN 0x03 /* Returns list of detected devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CMD_I2C_RELEASE_SDA 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CMD_I2C_RELEASE_SCL 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CMD_I2C_DROP_SDA 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CMD_I2C_DROP_SCL 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CMD_I2C_READ_SDA 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CMD_I2C_READ_SCL 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CMD_GET_FW_VERSION 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CMD_GET_SERIAL 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CMD_I2C_START 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CMD_I2C_STOP 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CMD_I2C_REPEATED_START 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CMD_I2C_PUT_BYTE 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CMD_I2C_GET_BYTE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CMD_I2C_PUT_ACK 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CMD_I2C_GET_ACK 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define CMD_I2C_PUT_BYTE_ACK 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define CMD_I2C_GET_BYTE_ACK 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CMD_I2C_SET_SPEED 0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CMD_I2C_GET_SPEED 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CMD_I2C_SET_CLK_SYNC 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CMD_I2C_GET_CLK_SYNC 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define CMD_I2C_SET_CLK_SYNC_TO 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CMD_I2C_GET_CLK_SYNC_TO 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define RESP_OK 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define RESP_FAILED 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define RESP_BAD_MEMADDR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define RESP_DATA_ERR 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define RESP_NOT_IMPLEMENTED 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define RESP_NACK 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define RESP_TIMEOUT 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define U2C_I2C_SPEED_FAST 0 /* 400 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define U2C_I2C_SPEED_STD 1 /* 100 kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define U2C_I2C_SPEED_2KHZ 242 /* 2 kHz, minimum speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define U2C_I2C_SPEED(f) ((DIV_ROUND_UP(1000000, (f)) - 10) / 2 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define U2C_I2C_FREQ(s) (1000000 / (2 * (s - 1) + 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define DIOLAN_USB_TIMEOUT 100 /* in ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define DIOLAN_SYNC_TIMEOUT 20 /* in ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define DIOLAN_OUTBUF_LEN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define DIOLAN_FLUSH_LEN (DIOLAN_OUTBUF_LEN - 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define DIOLAN_INBUF_LEN 256 /* Maximum supported receive length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Structure to hold all of our device specific stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct i2c_diolan_u2c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u8 obuffer[DIOLAN_OUTBUF_LEN]; /* output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 ibuffer[DIOLAN_INBUF_LEN]; /* input buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int ep_in, ep_out; /* Endpoints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct usb_device *usb_dev; /* the usb device for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct usb_interface *interface;/* the interface for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct i2c_adapter adapter; /* i2c related things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int olen; /* Output buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ocount; /* Number of enqueued messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static uint frequency = I2C_MAX_STANDARD_MODE_FREQ; /* I2C clock frequency in Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) module_param(frequency, uint, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* usb layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Send command to device, and get response. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int actual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!dev->olen || !dev->ocount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = usb_bulk_msg(dev->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) usb_sndbulkpipe(dev->usb_dev, dev->ep_out),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dev->obuffer, dev->olen, &actual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) DIOLAN_USB_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for (i = 0; i < dev->ocount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int tmpret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tmpret = usb_bulk_msg(dev->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) usb_rcvbulkpipe(dev->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) dev->ep_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) dev->ibuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) sizeof(dev->ibuffer), &actual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) DIOLAN_USB_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Stop command processing if a previous command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * returned an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Note that we still need to retrieve all messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = tmpret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret == 0 && actual > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) switch (dev->ibuffer[actual - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case RESP_NACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Return ENXIO if NACK was received as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * response to the address phase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * EIO otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret = i == 1 ? -ENXIO : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case RESP_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case RESP_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* strip off return code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ret = actual - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev->olen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dev->ocount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int diolan_write_cmd(struct i2c_diolan_u2c *dev, bool flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (flush || dev->olen >= DIOLAN_FLUSH_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return diolan_usb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Send command (no data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int diolan_usb_cmd(struct i2c_diolan_u2c *dev, u8 command, bool flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev->obuffer[dev->olen++] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dev->ocount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return diolan_write_cmd(dev, flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Send command with one byte of data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int diolan_usb_cmd_data(struct i2c_diolan_u2c *dev, u8 command, u8 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bool flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev->obuffer[dev->olen++] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev->obuffer[dev->olen++] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev->ocount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return diolan_write_cmd(dev, flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Send command with two bytes of data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int diolan_usb_cmd_data2(struct i2c_diolan_u2c *dev, u8 command, u8 d1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 d2, bool flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev->obuffer[dev->olen++] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev->obuffer[dev->olen++] = d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dev->obuffer[dev->olen++] = d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev->ocount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return diolan_write_cmd(dev, flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Flush input queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * If we don't do this at startup and the controller has queued up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * messages which were not retrieved, it will stop responding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * at some point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void diolan_flush_input(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int actual = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = usb_bulk_msg(dev->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev->ibuffer, sizeof(dev->ibuffer), &actual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) DIOLAN_USB_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret < 0 || actual == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (i == 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev_err(&dev->interface->dev, "Failed to flush input buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int diolan_i2c_start(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return diolan_usb_cmd(dev, CMD_I2C_START, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int diolan_i2c_repeated_start(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return diolan_usb_cmd(dev, CMD_I2C_REPEATED_START, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int diolan_i2c_stop(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return diolan_usb_cmd(dev, CMD_I2C_STOP, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int diolan_i2c_get_byte_ack(struct i2c_diolan_u2c *dev, bool ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u8 *byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = diolan_usb_cmd_data(dev, CMD_I2C_GET_BYTE_ACK, ack, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *byte = dev->ibuffer[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) else if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int diolan_i2c_put_byte_ack(struct i2c_diolan_u2c *dev, u8 byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return diolan_usb_cmd_data(dev, CMD_I2C_PUT_BYTE_ACK, byte, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int diolan_set_speed(struct i2c_diolan_u2c *dev, u8 speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return diolan_usb_cmd_data(dev, CMD_I2C_SET_SPEED, speed, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Enable or disable clock synchronization (stretching) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int diolan_set_clock_synch(struct i2c_diolan_u2c *dev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return diolan_usb_cmd_data(dev, CMD_I2C_SET_CLK_SYNC, enable, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Set clock synchronization timeout in ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int diolan_set_clock_synch_timeout(struct i2c_diolan_u2c *dev, int ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int to_val = ms * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return diolan_usb_cmd_data2(dev, CMD_I2C_SET_CLK_SYNC_TO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) to_val & 0xff, (to_val >> 8) & 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void diolan_fw_version(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = diolan_usb_cmd(dev, CMD_GET_FW_VERSION, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dev_info(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) "Diolan U2C firmware version %u.%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) (unsigned int)dev->ibuffer[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) (unsigned int)dev->ibuffer[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void diolan_get_serial(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = diolan_usb_cmd(dev, CMD_GET_SERIAL, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (ret >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) serial = le32_to_cpu(*(u32 *)dev->ibuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dev_info(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) "Diolan U2C serial number %u\n", serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int diolan_init(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int speed, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (frequency >= 2 * I2C_MAX_STANDARD_MODE_FREQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) speed = U2C_I2C_SPEED_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) frequency = I2C_MAX_FAST_MODE_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) } else if (frequency >= I2C_MAX_STANDARD_MODE_FREQ || frequency == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) speed = U2C_I2C_SPEED_STD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) frequency = I2C_MAX_STANDARD_MODE_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) speed = U2C_I2C_SPEED(frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (speed > U2C_I2C_SPEED_2KHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) speed = U2C_I2C_SPEED_2KHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) frequency = U2C_I2C_FREQ(speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_info(&dev->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) "Diolan U2C at USB bus %03d address %03d speed %d Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) diolan_flush_input(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) diolan_fw_version(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) diolan_get_serial(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* Set I2C speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = diolan_set_speed(dev, speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* Configure I2C clock synchronization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = diolan_set_clock_synch(dev, speed != U2C_I2C_SPEED_FAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (speed != U2C_I2C_SPEED_FAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ret = diolan_set_clock_synch_timeout(dev, DIOLAN_SYNC_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* i2c layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct i2c_diolan_u2c *dev = i2c_get_adapdata(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct i2c_msg *pmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int ret, sret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = diolan_i2c_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) pmsg = &msgs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = diolan_i2c_repeated_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = diolan_i2c_put_byte_ack(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) i2c_8bit_addr_from_msg(pmsg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (pmsg->flags & I2C_M_RD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) for (j = 0; j < pmsg->len; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u8 byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) bool ack = j < pmsg->len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * Don't send NACK if this is the first byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * of a SMBUS_BLOCK message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ack = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = diolan_i2c_get_byte_ack(dev, ack, &byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Adjust count if first received byte is length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (byte == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) || byte > I2C_SMBUS_BLOCK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) pmsg->len += byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pmsg->buf[j] = byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (j = 0; j < pmsg->len; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = diolan_i2c_put_byte_ack(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pmsg->buf[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) sret = diolan_i2c_stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (sret < 0 && ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ret = sret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * Return list of supported functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static u32 diolan_usb_func(struct i2c_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static const struct i2c_algorithm diolan_usb_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .master_xfer = diolan_usb_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .functionality = diolan_usb_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* device layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static const struct usb_device_id diolan_u2c_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) { USB_DEVICE(USB_VENDOR_ID_DIOLAN, USB_DEVICE_ID_DIOLAN_U2C) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) MODULE_DEVICE_TABLE(usb, diolan_u2c_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static void diolan_u2c_free(struct i2c_diolan_u2c *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) usb_put_dev(dev->usb_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int diolan_u2c_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct usb_host_interface *hostif = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct i2c_diolan_u2c *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (hostif->desc.bInterfaceNumber != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) || hostif->desc.bNumEndpoints < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* allocate memory for our device state and initialize it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dev->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* save our data pointer in this interface device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) usb_set_intfdata(interface, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* setup i2c adapter description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev->adapter.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev->adapter.class = I2C_CLASS_HWMON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dev->adapter.algo = &diolan_usb_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) i2c_set_adapdata(&dev->adapter, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) snprintf(dev->adapter.name, sizeof(dev->adapter.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) DRIVER_NAME " at bus %03d device %03d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dev->adapter.dev.parent = &dev->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* initialize diolan i2c interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = diolan_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev_err(&interface->dev, "failed to initialize adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* and finally attach to i2c layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = i2c_add_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) goto error_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dev_dbg(&interface->dev, "connected " DRIVER_NAME "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) error_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) diolan_u2c_free(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static void diolan_u2c_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct i2c_diolan_u2c *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) i2c_del_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) diolan_u2c_free(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dev_dbg(&interface->dev, "disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static struct usb_driver diolan_u2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .name = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .probe = diolan_u2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .disconnect = diolan_u2c_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .id_table = diolan_u2c_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) module_usb_driver(diolan_u2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) MODULE_DESCRIPTION(DRIVER_NAME " driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) MODULE_LICENSE("GPL");