Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");