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 i2c-tiny-usb adapter - 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * http://www.harbaum.org/till/i2c_tiny_usb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /* include interfaces to usb layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* include interface to i2c layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /* commands via USB, must match command ids in the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define CMD_ECHO		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define CMD_GET_FUNC		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define CMD_SET_DELAY		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define CMD_GET_STATUS		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define CMD_I2C_IO		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define CMD_I2C_IO_BEGIN	(1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define CMD_I2C_IO_END		(1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* i2c bit delay, default is 10us -> 100kHz max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)    (in practice, due to additional delays in the i2c bitbanging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)    code this results in a i2c clock of about 50kHz) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static unsigned short delay = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) module_param(delay, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) MODULE_PARM_DESC(delay, "bit delay in microseconds "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		 "(default is 10us for 100kHz max)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static int usb_read(struct i2c_adapter *adapter, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		    int value, int index, void *data, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int usb_write(struct i2c_adapter *adapter, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		     int value, int index, void *data, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* ----- begin of i2c layer ---------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define STATUS_IDLE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define STATUS_ADDRESS_ACK	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define STATUS_ADDRESS_NAK	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned char *pstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct i2c_msg *pmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	pstatus = kmalloc(sizeof(*pstatus), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (!pstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	for (i = 0 ; i < num ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		int cmd = CMD_I2C_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			cmd |= CMD_I2C_IO_BEGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		if (i == num-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			cmd |= CMD_I2C_IO_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		pmsg = &msgs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			"  %d: %s (flags %d) %d bytes to 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			i, pmsg->flags & I2C_M_RD ? "read" : "write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			pmsg->flags, pmsg->len, pmsg->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		/* and directly send the message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		if (pmsg->flags & I2C_M_RD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			/* read data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			if (usb_read(adapter, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				     pmsg->flags, pmsg->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				     pmsg->buf, pmsg->len) != pmsg->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				dev_err(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 					"failure reading data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			/* write data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			if (usb_write(adapter, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 				      pmsg->flags, pmsg->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				      pmsg->buf, pmsg->len) != pmsg->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				dev_err(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 					"failure writing data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		/* read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		if (usb_read(adapter, CMD_GET_STATUS, 0, 0, pstatus, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			dev_err(&adapter->dev, "failure reading status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		dev_dbg(&adapter->dev, "  status = %d\n", *pstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (*pstatus == STATUS_ADDRESS_NAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	ret = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	kfree(pstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static u32 usb_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	__le32 *pfunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	pfunc = kmalloc(sizeof(*pfunc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/* get functionality from adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (!pfunc || usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			       sizeof(*pfunc)) != sizeof(*pfunc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		dev_err(&adapter->dev, "failure reading functionality\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ret = le32_to_cpup(pfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	kfree(pfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* This is the actual algorithm we define */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const struct i2c_algorithm usb_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	.master_xfer	= usb_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	.functionality	= usb_func,
^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) /* ----- end of i2c layer ------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* ----- begin of usb layer ---------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  * Initially the usb i2c interface uses a vid/pid pair donated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * Future Technology Devices International Ltd., later a pair was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * bought from EZPrototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static const struct usb_device_id i2c_tiny_usb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ USB_DEVICE(0x0403, 0xc631) },   /* FTDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	{ }                               /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Structure to hold all of our device specific stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct i2c_tiny_usb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct usb_device *usb_dev; /* the usb device for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	struct usb_interface *interface; /* the interface for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	struct i2c_adapter adapter; /* i2c related things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int usb_read(struct i2c_adapter *adapter, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		    int value, int index, void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	void *dmadata = kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (!dmadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/* do control transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			       USB_DIR_IN, value, index, dmadata, len, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	memcpy(data, dmadata, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	kfree(dmadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return ret;
^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) static int usb_write(struct i2c_adapter *adapter, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		     int value, int index, void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	void *dmadata = kmemdup(data, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (!dmadata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* do control transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			       value, index, dmadata, len, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	kfree(dmadata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	usb_put_dev(dev->usb_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int i2c_tiny_usb_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			      const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	struct i2c_tiny_usb *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	int retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	u16 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	dev_dbg(&interface->dev, "probing usb device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	/* allocate memory for our device state and initialize it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		dev_err(&interface->dev, "Out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	dev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	/* save our data pointer in this interface device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	usb_set_intfdata(interface, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	version = le16_to_cpu(dev->usb_dev->descriptor.bcdDevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	dev_info(&interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		 "version %x.%02x found at bus %03d address %03d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		 version >> 8, version & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/* setup i2c adapter description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	dev->adapter.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	dev->adapter.class = I2C_CLASS_HWMON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	dev->adapter.algo = &usb_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	dev->adapter.algo_data = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	snprintf(dev->adapter.name, sizeof(dev->adapter.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		 "i2c-tiny-usb at bus %03d device %03d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		dev_err(&dev->adapter.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			"failure setting delay to %dus\n", delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		goto error;
^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) 	dev->adapter.dev.parent = &dev->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	/* and finally attach to i2c layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	i2c_add_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	/* inform user about successful attachment to i2c layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	dev_info(&dev->adapter.dev, "connected i2c-tiny-usb device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		i2c_tiny_usb_free(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void i2c_tiny_usb_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct i2c_tiny_usb *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	i2c_del_adapter(&dev->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	i2c_tiny_usb_free(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	dev_dbg(&interface->dev, "disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static struct usb_driver i2c_tiny_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	.name		= "i2c-tiny-usb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	.probe		= i2c_tiny_usb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	.disconnect	= i2c_tiny_usb_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	.id_table	= i2c_tiny_usb_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) module_usb_driver(i2c_tiny_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* ----- end of usb layer ------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) MODULE_AUTHOR("Till Harbaum <Till@Harbaum.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) MODULE_LICENSE("GPL");