@@ -224,9 +224,10 @@ MODULE_DEVICE_TABLE(usb, id_table);
224224struct cp210x_serial_private {
225225#ifdef CONFIG_GPIOLIB
226226 struct gpio_chip gc ;
227- u8 config ;
228- u8 gpio_mode ;
229227 bool gpio_registered ;
228+ u8 gpio_pushpull ;
229+ u8 gpio_altfunc ;
230+ u8 gpio_input ;
230231#endif
231232 u8 partnum ;
232233 speed_t max_speed ;
@@ -343,6 +344,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
343344#define CONTROL_WRITE_RTS 0x0200
344345
345346/* CP210X_VENDOR_SPECIFIC values */
347+ #define CP210X_READ_2NCONFIG 0x000E
346348#define CP210X_READ_LATCH 0x00C2
347349#define CP210X_GET_PARTNUM 0x370B
348350#define CP210X_GET_PORTCONFIG 0x370C
@@ -452,6 +454,12 @@ struct cp210x_config {
452454#define CP2105_GPIO1_RXLED_MODE BIT(1)
453455#define CP2105_GPIO1_RS485_MODE BIT(2)
454456
457+ /* CP2102N configuration array indices */
458+ #define CP210X_2NCONFIG_CONFIG_VERSION_IDX 2
459+ #define CP210X_2NCONFIG_GPIO_MODE_IDX 581
460+ #define CP210X_2NCONFIG_GPIO_RSTLATCH_IDX 587
461+ #define CP210X_2NCONFIG_GPIO_CONTROL_IDX 600
462+
455463/* CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH call writes these 0x2 bytes. */
456464struct cp210x_gpio_write {
457465 u8 mask ;
@@ -1313,28 +1321,24 @@ static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset)
13131321 struct usb_serial * serial = gpiochip_get_data (gc );
13141322 struct cp210x_serial_private * priv = usb_get_serial_data (serial );
13151323
1316- switch (offset ) {
1317- case 0 :
1318- if (priv -> config & CP2105_GPIO0_TXLED_MODE )
1319- return - ENODEV ;
1320- break ;
1321- case 1 :
1322- if (priv -> config & (CP2105_GPIO1_RXLED_MODE |
1323- CP2105_GPIO1_RS485_MODE ))
1324- return - ENODEV ;
1325- break ;
1326- }
1324+ if (priv -> gpio_altfunc & BIT (offset ))
1325+ return - ENODEV ;
13271326
13281327 return 0 ;
13291328}
13301329
13311330static int cp210x_gpio_get (struct gpio_chip * gc , unsigned int gpio )
13321331{
13331332 struct usb_serial * serial = gpiochip_get_data (gc );
1333+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1334+ u8 req_type = REQTYPE_DEVICE_TO_HOST ;
13341335 int result ;
13351336 u8 buf ;
13361337
1337- result = cp210x_read_vendor_block (serial , REQTYPE_INTERFACE_TO_HOST ,
1338+ if (priv -> partnum == CP210X_PARTNUM_CP2105 )
1339+ req_type = REQTYPE_INTERFACE_TO_HOST ;
1340+
1341+ result = cp210x_read_vendor_block (serial , req_type ,
13381342 CP210X_READ_LATCH , & buf , sizeof (buf ));
13391343 if (result < 0 )
13401344 return result ;
@@ -1345,7 +1349,9 @@ static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
13451349static void cp210x_gpio_set (struct gpio_chip * gc , unsigned int gpio , int value )
13461350{
13471351 struct usb_serial * serial = gpiochip_get_data (gc );
1352+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
13481353 struct cp210x_gpio_write buf ;
1354+ int result ;
13491355
13501356 if (value == 1 )
13511357 buf .state = BIT (gpio );
@@ -1354,25 +1360,68 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
13541360
13551361 buf .mask = BIT (gpio );
13561362
1357- cp210x_write_vendor_block (serial , REQTYPE_HOST_TO_INTERFACE ,
1358- CP210X_WRITE_LATCH , & buf , sizeof (buf ));
1363+ if (priv -> partnum == CP210X_PARTNUM_CP2105 ) {
1364+ result = cp210x_write_vendor_block (serial ,
1365+ REQTYPE_HOST_TO_INTERFACE ,
1366+ CP210X_WRITE_LATCH , & buf ,
1367+ sizeof (buf ));
1368+ } else {
1369+ u16 wIndex = buf .state << 8 | buf .mask ;
1370+
1371+ result = usb_control_msg (serial -> dev ,
1372+ usb_sndctrlpipe (serial -> dev , 0 ),
1373+ CP210X_VENDOR_SPECIFIC ,
1374+ REQTYPE_HOST_TO_DEVICE ,
1375+ CP210X_WRITE_LATCH ,
1376+ wIndex ,
1377+ NULL , 0 , USB_CTRL_SET_TIMEOUT );
1378+ }
1379+
1380+ if (result < 0 ) {
1381+ dev_err (& serial -> interface -> dev , "failed to set GPIO value: %d\n" ,
1382+ result );
1383+ }
13591384}
13601385
13611386static int cp210x_gpio_direction_get (struct gpio_chip * gc , unsigned int gpio )
13621387{
1363- /* Hardware does not support an input mode */
1364- return 0 ;
1388+ struct usb_serial * serial = gpiochip_get_data (gc );
1389+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1390+
1391+ return priv -> gpio_input & BIT (gpio );
13651392}
13661393
13671394static int cp210x_gpio_direction_input (struct gpio_chip * gc , unsigned int gpio )
13681395{
1369- /* Hardware does not support an input mode */
1370- return - ENOTSUPP ;
1396+ struct usb_serial * serial = gpiochip_get_data (gc );
1397+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1398+
1399+ if (priv -> partnum == CP210X_PARTNUM_CP2105 ) {
1400+ /* hardware does not support an input mode */
1401+ return - ENOTSUPP ;
1402+ }
1403+
1404+ /* push-pull pins cannot be changed to be inputs */
1405+ if (priv -> gpio_pushpull & BIT (gpio ))
1406+ return - EINVAL ;
1407+
1408+ /* make sure to release pin if it is being driven low */
1409+ cp210x_gpio_set (gc , gpio , 1 );
1410+
1411+ priv -> gpio_input |= BIT (gpio );
1412+
1413+ return 0 ;
13711414}
13721415
13731416static int cp210x_gpio_direction_output (struct gpio_chip * gc , unsigned int gpio ,
13741417 int value )
13751418{
1419+ struct usb_serial * serial = gpiochip_get_data (gc );
1420+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1421+
1422+ priv -> gpio_input &= ~BIT (gpio );
1423+ cp210x_gpio_set (gc , gpio , value );
1424+
13761425 return 0 ;
13771426}
13781427
@@ -1385,11 +1434,11 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
13851434
13861435 /* Succeed only if in correct mode (this can't be set at runtime) */
13871436 if ((param == PIN_CONFIG_DRIVE_PUSH_PULL ) &&
1388- (priv -> gpio_mode & BIT (gpio )))
1437+ (priv -> gpio_pushpull & BIT (gpio )))
13891438 return 0 ;
13901439
13911440 if ((param == PIN_CONFIG_DRIVE_OPEN_DRAIN ) &&
1392- !(priv -> gpio_mode & BIT (gpio )))
1441+ !(priv -> gpio_pushpull & BIT (gpio )))
13931442 return 0 ;
13941443
13951444 return - ENOTSUPP ;
@@ -1402,12 +1451,13 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
14021451 * this driver that provide GPIO do so in a way that does not impact other
14031452 * signals and are thus expected to have very different initialisation.
14041453 */
1405- static int cp2105_shared_gpio_init (struct usb_serial * serial )
1454+ static int cp2105_gpioconf_init (struct usb_serial * serial )
14061455{
14071456 struct cp210x_serial_private * priv = usb_get_serial_data (serial );
14081457 struct cp210x_pin_mode mode ;
14091458 struct cp210x_config config ;
14101459 u8 intf_num = cp210x_interface_num (serial );
1460+ u8 iface_config ;
14111461 int result ;
14121462
14131463 result = cp210x_read_vendor_block (serial , REQTYPE_DEVICE_TO_HOST ,
@@ -1424,27 +1474,152 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial)
14241474
14251475 /* 2 banks of GPIO - One for the pins taken from each serial port */
14261476 if (intf_num == 0 ) {
1427- if (mode .eci == CP210X_PIN_MODE_MODEM )
1477+ if (mode .eci == CP210X_PIN_MODE_MODEM ) {
1478+ /* mark all GPIOs of this interface as reserved */
1479+ priv -> gpio_altfunc = 0xff ;
14281480 return 0 ;
1481+ }
14291482
1430- priv -> config = config .eci_cfg ;
1431- priv -> gpio_mode = (u8 )((le16_to_cpu (config .gpio_mode ) &
1483+ iface_config = config .eci_cfg ;
1484+ priv -> gpio_pushpull = (u8 )((le16_to_cpu (config .gpio_mode ) &
14321485 CP210X_ECI_GPIO_MODE_MASK ) >>
14331486 CP210X_ECI_GPIO_MODE_OFFSET );
14341487 priv -> gc .ngpio = 2 ;
14351488 } else if (intf_num == 1 ) {
1436- if (mode .sci == CP210X_PIN_MODE_MODEM )
1489+ if (mode .sci == CP210X_PIN_MODE_MODEM ) {
1490+ /* mark all GPIOs of this interface as reserved */
1491+ priv -> gpio_altfunc = 0xff ;
14371492 return 0 ;
1493+ }
14381494
1439- priv -> config = config .sci_cfg ;
1440- priv -> gpio_mode = (u8 )((le16_to_cpu (config .gpio_mode ) &
1495+ iface_config = config .sci_cfg ;
1496+ priv -> gpio_pushpull = (u8 )((le16_to_cpu (config .gpio_mode ) &
14411497 CP210X_SCI_GPIO_MODE_MASK ) >>
14421498 CP210X_SCI_GPIO_MODE_OFFSET );
14431499 priv -> gc .ngpio = 3 ;
14441500 } else {
14451501 return - ENODEV ;
14461502 }
14471503
1504+ /* mark all pins which are not in GPIO mode */
1505+ if (iface_config & CP2105_GPIO0_TXLED_MODE ) /* GPIO 0 */
1506+ priv -> gpio_altfunc |= BIT (0 );
1507+ if (iface_config & (CP2105_GPIO1_RXLED_MODE | /* GPIO 1 */
1508+ CP2105_GPIO1_RS485_MODE ))
1509+ priv -> gpio_altfunc |= BIT (1 );
1510+
1511+ /* driver implementation for CP2105 only supports outputs */
1512+ priv -> gpio_input = 0 ;
1513+
1514+ return 0 ;
1515+ }
1516+
1517+ static int cp2102n_gpioconf_init (struct usb_serial * serial )
1518+ {
1519+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1520+ const u16 config_size = 0x02a6 ;
1521+ u8 gpio_rst_latch ;
1522+ u8 config_version ;
1523+ u8 gpio_pushpull ;
1524+ u8 * config_buf ;
1525+ u8 gpio_latch ;
1526+ u8 gpio_ctrl ;
1527+ int result ;
1528+ u8 i ;
1529+
1530+ /*
1531+ * Retrieve device configuration from the device.
1532+ * The array received contains all customization settings done at the
1533+ * factory/manufacturer. Format of the array is documented at the
1534+ * time of writing at:
1535+ * https://www.silabs.com/community/interface/knowledge-base.entry.html/2017/03/31/cp2102n_setconfig-xsfa
1536+ */
1537+ config_buf = kmalloc (config_size , GFP_KERNEL );
1538+ if (!config_buf )
1539+ return - ENOMEM ;
1540+
1541+ result = cp210x_read_vendor_block (serial ,
1542+ REQTYPE_DEVICE_TO_HOST ,
1543+ CP210X_READ_2NCONFIG ,
1544+ config_buf ,
1545+ config_size );
1546+ if (result < 0 ) {
1547+ kfree (config_buf );
1548+ return result ;
1549+ }
1550+
1551+ config_version = config_buf [CP210X_2NCONFIG_CONFIG_VERSION_IDX ];
1552+ gpio_pushpull = config_buf [CP210X_2NCONFIG_GPIO_MODE_IDX ];
1553+ gpio_ctrl = config_buf [CP210X_2NCONFIG_GPIO_CONTROL_IDX ];
1554+ gpio_rst_latch = config_buf [CP210X_2NCONFIG_GPIO_RSTLATCH_IDX ];
1555+
1556+ kfree (config_buf );
1557+
1558+ /* Make sure this is a config format we understand. */
1559+ if (config_version != 0x01 )
1560+ return - ENOTSUPP ;
1561+
1562+ /*
1563+ * We only support 4 GPIOs even on the QFN28 package, because
1564+ * config locations of GPIOs 4-6 determined using reverse
1565+ * engineering revealed conflicting offsets with other
1566+ * documented functions. So we'll just play it safe for now.
1567+ */
1568+ priv -> gc .ngpio = 4 ;
1569+
1570+ /*
1571+ * Get default pin states after reset. Needed so we can determine
1572+ * the direction of an open-drain pin.
1573+ */
1574+ gpio_latch = (gpio_rst_latch >> 3 ) & 0x0f ;
1575+
1576+ /* 0 indicates open-drain mode, 1 is push-pull */
1577+ priv -> gpio_pushpull = (gpio_pushpull >> 3 ) & 0x0f ;
1578+
1579+ /* 0 indicates GPIO mode, 1 is alternate function */
1580+ priv -> gpio_altfunc = (gpio_ctrl >> 2 ) & 0x0f ;
1581+
1582+ /*
1583+ * The CP2102N does not strictly has input and output pin modes,
1584+ * it only knows open-drain and push-pull modes which is set at
1585+ * factory. An open-drain pin can function both as an
1586+ * input or an output. We emulate input mode for open-drain pins
1587+ * by making sure they are not driven low, and we do not allow
1588+ * push-pull pins to be set as an input.
1589+ */
1590+ for (i = 0 ; i < priv -> gc .ngpio ; ++ i ) {
1591+ /*
1592+ * Set direction to "input" iff pin is open-drain and reset
1593+ * value is 1.
1594+ */
1595+ if (!(priv -> gpio_pushpull & BIT (i )) && (gpio_latch & BIT (i )))
1596+ priv -> gpio_input |= BIT (i );
1597+ }
1598+
1599+ return 0 ;
1600+ }
1601+
1602+ static int cp210x_gpio_init (struct usb_serial * serial )
1603+ {
1604+ struct cp210x_serial_private * priv = usb_get_serial_data (serial );
1605+ int result ;
1606+
1607+ switch (priv -> partnum ) {
1608+ case CP210X_PARTNUM_CP2105 :
1609+ result = cp2105_gpioconf_init (serial );
1610+ break ;
1611+ case CP210X_PARTNUM_CP2102N_QFN28 :
1612+ case CP210X_PARTNUM_CP2102N_QFN24 :
1613+ case CP210X_PARTNUM_CP2102N_QFN20 :
1614+ result = cp2102n_gpioconf_init (serial );
1615+ break ;
1616+ default :
1617+ return 0 ;
1618+ }
1619+
1620+ if (result < 0 )
1621+ return result ;
1622+
14481623 priv -> gc .label = "cp210x" ;
14491624 priv -> gc .request = cp210x_gpio_request ;
14501625 priv -> gc .get_direction = cp210x_gpio_direction_get ;
@@ -1477,7 +1652,7 @@ static void cp210x_gpio_remove(struct usb_serial *serial)
14771652
14781653#else
14791654
1480- static int cp2105_shared_gpio_init (struct usb_serial * serial )
1655+ static int cp210x_gpio_init (struct usb_serial * serial )
14811656{
14821657 return 0 ;
14831658}
@@ -1588,12 +1763,10 @@ static int cp210x_attach(struct usb_serial *serial)
15881763
15891764 cp210x_init_max_speed (serial );
15901765
1591- if (priv -> partnum == CP210X_PARTNUM_CP2105 ) {
1592- result = cp2105_shared_gpio_init (serial );
1593- if (result < 0 ) {
1594- dev_err (& serial -> interface -> dev ,
1595- "GPIO initialisation failed, continuing without GPIO support\n" );
1596- }
1766+ result = cp210x_gpio_init (serial );
1767+ if (result < 0 ) {
1768+ dev_err (& serial -> interface -> dev , "GPIO initialisation failed: %d\n" ,
1769+ result );
15971770 }
15981771
15991772 return 0 ;
0 commit comments