Re: [PATCH v6] USB: serial: cp210x: Add support for GPIOs on CP2108

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Pho,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb-serial/usb-next]
[also build test WARNING on usb/usb-testing tty/tty-testing v5.12-rc6 next-20210401]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Pho-Tran/USB-serial-cp210x-Add-support-for-GPIOs-on-CP2108/20210405-141927
base:   https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git usb-next
config: x86_64-randconfig-s022-20210405 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-279-g6d5d9b42-dirty
        # https://github.com/0day-ci/linux/commit/a4658078c55d4396be894b30d3b94fd86b770f45
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Pho-Tran/USB-serial-cp210x-Add-support-for-GPIOs-on-CP2108/20210405-141927
        git checkout a4658078c55d4396be894b30d3b94fd86b770f45
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>


sparse warnings: (new ones prefixed by >>)
>> drivers/usb/serial/cp210x.c:1540:13: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [addressable] [usertype] buf @@     got unsigned short [usertype] @@
   drivers/usb/serial/cp210x.c:1540:13: sparse:     expected restricted __le16 [addressable] [usertype] buf
   drivers/usb/serial/cp210x.c:1540:13: sparse:     got unsigned short [usertype]
>> drivers/usb/serial/cp210x.c:1542:19: sparse: sparse: restricted __le16 degrades to integer
>> drivers/usb/serial/cp210x.c:1581:24: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] wIndex @@     got int @@
   drivers/usb/serial/cp210x.c:1581:24: sparse:     expected restricted __le16 [usertype] wIndex
   drivers/usb/serial/cp210x.c:1581:24: sparse:     got int
>> drivers/usb/serial/cp210x.c:1587:57: sparse: sparse: incorrect type in argument 6 (different base types) @@     expected unsigned short [usertype] index @@     got restricted __le16 [usertype] wIndex @@
   drivers/usb/serial/cp210x.c:1587:57: sparse:     expected unsigned short [usertype] index
   drivers/usb/serial/cp210x.c:1587:57: sparse:     got restricted __le16 [usertype] wIndex
>> drivers/usb/serial/cp210x.c:1676:14: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] temp @@     got unsigned short [usertype] @@
   drivers/usb/serial/cp210x.c:1676:14: sparse:     expected restricted __le16 [usertype] temp
   drivers/usb/serial/cp210x.c:1676:14: sparse:     got unsigned short [usertype]
   drivers/usb/serial/cp210x.c:1677:32: sparse: sparse: restricted __le16 degrades to integer
   drivers/usb/serial/cp210x.c:1678:14: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] temp @@     got unsigned short [usertype] @@
   drivers/usb/serial/cp210x.c:1678:14: sparse:     expected restricted __le16 [usertype] temp
   drivers/usb/serial/cp210x.c:1678:14: sparse:     got unsigned short [usertype]
   drivers/usb/serial/cp210x.c:1679:23: sparse: sparse: restricted __le16 degrades to integer
>> drivers/usb/serial/cp210x.c:1679:20: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] gpio_latch @@     got unsigned long @@
   drivers/usb/serial/cp210x.c:1679:20: sparse:     expected restricted __le16 [usertype] gpio_latch
   drivers/usb/serial/cp210x.c:1679:20: sparse:     got unsigned long
   drivers/usb/serial/cp210x.c:1721:57: sparse: sparse: restricted __le16 degrades to integer

vim +1540 drivers/usb/serial/cp210x.c

  1496	
  1497	static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
  1498	{
  1499		struct usb_serial *serial = gpiochip_get_data(gc);
  1500		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1501		u8 req_type = REQTYPE_DEVICE_TO_HOST;
  1502		int result;
  1503		__le16 buf;
  1504	
  1505		result = usb_autopm_get_interface(serial->interface);
  1506		if (result)
  1507			return result;
  1508	/*
  1509	 * This function will be read latch value of gpio and storage to buf(16bit)
  1510	 * where bit 0 is GPIO0, bit 1 is GPIO1, etc. Up to GPIOn where n is
  1511	 * total number of GPIO pins the interface supports.
  1512	 * Interfaces on CP2102N supports 7 GPIOs
  1513	 * Interfaces on CP2103 amd CP2104 supports 4 GPIOs
  1514	 * Enhanced interfaces on CP2105 support 3 GPIOs
  1515	 * Standard interfaces on CP2105 support 4 GPIOs
  1516	 * Interfaces on CP2108 supports 16 GPIOs
  1517	 */
  1518		switch (priv->partnum) {
  1519		/*
  1520		 * Request type to Read_Latch of CP2105 and Cp2108
  1521		 * is 0xc1 <REQTYPE_INTERFACE_TO_HOST>
  1522		 */
  1523		case CP210X_PARTNUM_CP2108:
  1524			req_type = REQTYPE_INTERFACE_TO_HOST;
  1525			result = cp210x_read_vendor_block(serial, req_type,
  1526							CP210X_READ_LATCH, &buf, sizeof(__le16));
  1527			break;
  1528		case CP210X_PARTNUM_CP2105:
  1529			req_type = REQTYPE_INTERFACE_TO_HOST;
  1530			result = cp210x_read_vendor_block(serial, req_type,
  1531							CP210X_READ_LATCH, &buf, sizeof(u8));
  1532			break;
  1533		default:
  1534			result = cp210x_read_vendor_block(serial, req_type,
  1535							CP210X_READ_LATCH, &buf, sizeof(u8));
  1536			break;
  1537		}
  1538		if (result < 0)
  1539			return result;
> 1540		buf = le16_to_cpu(buf);
  1541		usb_autopm_put_interface(serial->interface);
> 1542		return !!(buf & BIT(gpio));
  1543	}
  1544	
  1545	static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
  1546	{
  1547		struct usb_serial *serial = gpiochip_get_data(gc);
  1548		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1549		struct cp210x_gpio_write buf;
  1550		__le16 wIndex;
  1551		int result;
  1552	
  1553		if (value == 1) {
  1554			buf.cp210x_8gpios.state = BIT(gpio);
  1555			buf.cp210x_16gpios.state = cpu_to_le16(BIT(gpio));
  1556		} else {
  1557			buf.cp210x_8gpios.state = 0;
  1558			buf.cp210x_16gpios.state = 0;
  1559		}
  1560		buf.cp210x_8gpios.mask = BIT(gpio);
  1561		buf.cp210x_16gpios.mask = cpu_to_le16(BIT(gpio));
  1562	
  1563		result = usb_autopm_get_interface(serial->interface);
  1564		if (result)
  1565			goto out;
  1566	
  1567		switch (priv->partnum) {
  1568		case CP210X_PARTNUM_CP2108:
  1569			result = cp210x_write_vendor_block(serial,
  1570								REQTYPE_HOST_TO_INTERFACE,
  1571								CP210X_WRITE_LATCH, &buf.cp210x_16gpios,
  1572								sizeof(buf.cp210x_16gpios));
  1573			break;
  1574		case CP210X_PARTNUM_CP2105:
  1575			result = cp210x_write_vendor_block(serial,
  1576								REQTYPE_HOST_TO_INTERFACE,
  1577								CP210X_WRITE_LATCH, &buf.cp210x_8gpios,
  1578								sizeof(buf.cp210x_8gpios));
  1579			break;
  1580		default:
> 1581			wIndex = buf.cp210x_8gpios.state << 8 | buf.cp210x_8gpios.mask;
  1582			result = usb_control_msg(serial->dev,
  1583								usb_sndctrlpipe(serial->dev, 0),
  1584								CP210X_VENDOR_SPECIFIC,
  1585								REQTYPE_HOST_TO_DEVICE,
  1586								CP210X_WRITE_LATCH,
> 1587								wIndex,
  1588								NULL, 0, USB_CTRL_SET_TIMEOUT);
  1589			break;
  1590		}
  1591		usb_autopm_put_interface(serial->interface);
  1592	
  1593	out:
  1594		if (result < 0) {
  1595			dev_err(&serial->interface->dev, "failed to set GPIO value: %d\n",
  1596					result);
  1597		}
  1598	}
  1599	
  1600	static int cp210x_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio)
  1601	{
  1602		struct usb_serial *serial = gpiochip_get_data(gc);
  1603		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1604	
  1605		return priv->gpio_input & BIT(gpio);
  1606	}
  1607	
  1608	static int cp210x_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
  1609	{
  1610		struct usb_serial *serial = gpiochip_get_data(gc);
  1611		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1612	
  1613		if (priv->partnum == CP210X_PARTNUM_CP2105) {
  1614			/* hardware does not support an input mode */
  1615			return -ENOTSUPP;
  1616		}
  1617	
  1618		/* push-pull pins cannot be changed to be inputs */
  1619		if (priv->gpio_pushpull & BIT(gpio))
  1620			return -EINVAL;
  1621	
  1622		/* make sure to release pin if it is being driven low */
  1623		cp210x_gpio_set(gc, gpio, 1);
  1624	
  1625		priv->gpio_input |= BIT(gpio);
  1626	
  1627		return 0;
  1628	}
  1629	
  1630	static int cp210x_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
  1631						int value)
  1632	{
  1633		struct usb_serial *serial = gpiochip_get_data(gc);
  1634		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1635	
  1636		priv->gpio_input &= ~BIT(gpio);
  1637		cp210x_gpio_set(gc, gpio, value);
  1638	
  1639		return 0;
  1640	}
  1641	
  1642	static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
  1643					  unsigned long config)
  1644	{
  1645		struct usb_serial *serial = gpiochip_get_data(gc);
  1646		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1647		enum pin_config_param param = pinconf_to_config_param(config);
  1648	
  1649		/* Succeed only if in correct mode (this can't be set at runtime) */
  1650		if ((param == PIN_CONFIG_DRIVE_PUSH_PULL) &&
  1651		    (priv->gpio_pushpull & BIT(gpio)))
  1652			return 0;
  1653	
  1654		if ((param == PIN_CONFIG_DRIVE_OPEN_DRAIN) &&
  1655		    !(priv->gpio_pushpull & BIT(gpio)))
  1656			return 0;
  1657	
  1658		return -ENOTSUPP;
  1659	}
  1660	
  1661	static int cp2108_gpio_init(struct usb_serial *serial)
  1662	{
  1663		struct cp210x_serial_private *priv = usb_get_serial_data(serial);
  1664		struct cp210x_quad_port_config config;
  1665		__le16 gpio_latch;
  1666		__le16 temp;
  1667		int result;
  1668		u8 i;
  1669	
  1670		result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
  1671						  CP210X_GET_PORTCONFIG, &config,
  1672						  sizeof(config));
  1673		if (result < 0)
  1674			return result;
  1675		priv->gc.ngpio = 16;
> 1676		temp = le16_to_cpu(config.reset_state.gpio_mode_PB1);
  1677		priv->gpio_pushpull = (temp & CP2108_GPIO_MODE_MASK) >> CP2108_GPIO_MODE_OFFSET;
  1678		temp = le16_to_cpu(config.reset_state.gpio_latch_PB1);
> 1679		gpio_latch = (temp & CP2108_GPIO_MODE_MASK) >> CP2108_GPIO_MODE_OFFSET;
  1680		/*
  1681		 * Mark all pins which are not in GPIO mode
  1682		 * Refer to table 9.1: GPIO Mode alternate Functions on CP2108 datasheet:
  1683		 * https://www.silabs.com/documents/public/data-sheets/cp2108-datasheet.pdf
  1684		 * Alternate Functions of GPIO0 to GPIO3 is determine by enhancedfxn_IFC[0]
  1685		 * and the same for other pins, enhancedfxn_IFC[1]: GPIO4 to GPIO7,
  1686		 * enhancedfxn_IFC[2]: GPIO8 to GPIO11, enhancedfxn_IFC[3]: GPIO12 to GPIO15.
  1687		 */
  1688		for (i = 0; i < 4; i++) {
  1689			switch (config.enhancedfxn_IFC[i]) {
  1690			case EF_IFC_GPIO_TXLED:
  1691				priv->gpio_altfunc |= BIT(i * 4);
  1692				break;
  1693			case EF_IFC_GPIO_RXLED:
  1694				priv->gpio_altfunc |= BIT((i * 4) + 1);
  1695				break;
  1696			case EF_IFC_GPIO_RS485_LOGIC:
  1697			case EF_IFC_GPIO_RS485:
  1698				priv->gpio_altfunc |= BIT((i * 4) + 2);
  1699				break;
  1700			case EF_IFC_GPIO_CLOCK:
  1701				priv->gpio_altfunc |= BIT((i * 4) + 3);
  1702				break;
  1703			case EF_IFC_DYNAMIC_SUSPEND:
  1704				priv->gpio_altfunc |= BIT(i * 4);
  1705				priv->gpio_altfunc |= BIT((i * 4) + 1);
  1706				priv->gpio_altfunc |= BIT((i * 4) + 2);
  1707				priv->gpio_altfunc |= BIT((i * 4) + 3);
  1708				break;
  1709			}
  1710		}
  1711		/*
  1712		 * Like CP2102N, CP2108 has also no strict input and output pin
  1713		 * modes.
  1714		 * Do the same input mode emulation as CP2102N.
  1715		 */
  1716		for (i = 0; i < priv->gc.ngpio; ++i) {
  1717			/*
  1718			 * Set direction to "input" iff pin is open-drain and reset
  1719			 * value is 1.
  1720			 */
  1721			if (!(priv->gpio_pushpull & BIT(i)) && (gpio_latch & BIT(i)))
  1722				priv->gpio_input |= BIT(i);
  1723		}
  1724	
  1725		return 0;
  1726	}
  1727	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux