Lines Matching +full:gpio +full:- +full:7 +full:- +full:segment
1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for Microchip USB251xB USB 2.0 Hi-Speed Hub Controller
9 * a not-accepted patch by Fabien Lahoudere, see:
14 #include <linux/gpio/consumer.h>
15 #include <linux/gpio/driver.h>
95 #define USB251XB_DEF_PORT_MAP_34 0x00 /* USB251{3B/i,4B/i,7/i} only */
110 #define DRIVER_DESC "Microchip USB 2.0 Hi-Speed Hub Controller"
217 .port_cnt = 7,
225 .port_cnt = 7,
234 if (dev->type == &i2c_adapter_type) { in usb251xb_check_dev_children()
244 struct gpio_chip *gc = gpiod_to_chip(hub->gpio_reset); in usb251x_check_gpio_chip()
245 struct i2c_adapter *adap = hub->i2c->adapter; in usb251x_check_gpio_chip()
248 if (!hub->gpio_reset) in usb251x_check_gpio_chip()
252 return -EINVAL; in usb251x_check_gpio_chip()
254 ret = usb251xb_check_dev_children(&adap->dev, gc->parent); in usb251x_check_gpio_chip()
256 dev_err(hub->dev, "Reset GPIO chip is at the same i2c-bus\n"); in usb251x_check_gpio_chip()
257 return -EINVAL; in usb251x_check_gpio_chip()
271 if (!hub->gpio_reset) in usb251xb_reset()
274 i2c_lock_bus(hub->i2c->adapter, I2C_LOCK_SEGMENT); in usb251xb_reset()
276 gpiod_set_value_cansleep(hub->gpio_reset, 1); in usb251xb_reset()
278 gpiod_set_value_cansleep(hub->gpio_reset, 0); in usb251xb_reset()
283 i2c_unlock_bus(hub->i2c->adapter, I2C_LOCK_SEGMENT); in usb251xb_reset()
288 struct device *dev = hub->dev; in usb251xb_connect()
294 if (hub->skip_config) { in usb251xb_connect()
301 err = i2c_smbus_write_i2c_block_data(hub->i2c, in usb251xb_connect()
310 i2c_wb[USB251XB_ADDR_VENDOR_ID_MSB] = (hub->vendor_id >> 8) & 0xFF; in usb251xb_connect()
311 i2c_wb[USB251XB_ADDR_VENDOR_ID_LSB] = hub->vendor_id & 0xFF; in usb251xb_connect()
312 i2c_wb[USB251XB_ADDR_PRODUCT_ID_MSB] = (hub->product_id >> 8) & 0xFF; in usb251xb_connect()
313 i2c_wb[USB251XB_ADDR_PRODUCT_ID_LSB] = hub->product_id & 0xFF; in usb251xb_connect()
314 i2c_wb[USB251XB_ADDR_DEVICE_ID_MSB] = (hub->device_id >> 8) & 0xFF; in usb251xb_connect()
315 i2c_wb[USB251XB_ADDR_DEVICE_ID_LSB] = hub->device_id & 0xFF; in usb251xb_connect()
316 i2c_wb[USB251XB_ADDR_CONFIG_DATA_1] = hub->conf_data1; in usb251xb_connect()
317 i2c_wb[USB251XB_ADDR_CONFIG_DATA_2] = hub->conf_data2; in usb251xb_connect()
318 i2c_wb[USB251XB_ADDR_CONFIG_DATA_3] = hub->conf_data3; in usb251xb_connect()
319 i2c_wb[USB251XB_ADDR_NON_REMOVABLE_DEVICES] = hub->non_rem_dev; in usb251xb_connect()
320 i2c_wb[USB251XB_ADDR_PORT_DISABLE_SELF] = hub->port_disable_sp; in usb251xb_connect()
321 i2c_wb[USB251XB_ADDR_PORT_DISABLE_BUS] = hub->port_disable_bp; in usb251xb_connect()
322 i2c_wb[USB251XB_ADDR_MAX_POWER_SELF] = hub->max_power_sp; in usb251xb_connect()
323 i2c_wb[USB251XB_ADDR_MAX_POWER_BUS] = hub->max_power_bp; in usb251xb_connect()
324 i2c_wb[USB251XB_ADDR_MAX_CURRENT_SELF] = hub->max_current_sp; in usb251xb_connect()
325 i2c_wb[USB251XB_ADDR_MAX_CURRENT_BUS] = hub->max_current_bp; in usb251xb_connect()
326 i2c_wb[USB251XB_ADDR_POWER_ON_TIME] = hub->power_on_time; in usb251xb_connect()
327 i2c_wb[USB251XB_ADDR_LANGUAGE_ID_HIGH] = (hub->lang_id >> 8) & 0xFF; in usb251xb_connect()
328 i2c_wb[USB251XB_ADDR_LANGUAGE_ID_LOW] = hub->lang_id & 0xFF; in usb251xb_connect()
329 i2c_wb[USB251XB_ADDR_MANUFACTURER_STRING_LEN] = hub->manufacturer_len; in usb251xb_connect()
330 i2c_wb[USB251XB_ADDR_PRODUCT_STRING_LEN] = hub->product_len; in usb251xb_connect()
331 i2c_wb[USB251XB_ADDR_SERIAL_STRING_LEN] = hub->serial_len; in usb251xb_connect()
332 memcpy(&i2c_wb[USB251XB_ADDR_MANUFACTURER_STRING], hub->manufacturer, in usb251xb_connect()
334 memcpy(&i2c_wb[USB251XB_ADDR_SERIAL_STRING], hub->serial, in usb251xb_connect()
336 memcpy(&i2c_wb[USB251XB_ADDR_PRODUCT_STRING], hub->product, in usb251xb_connect()
338 i2c_wb[USB251XB_ADDR_BATTERY_CHARGING_ENABLE] = hub->bat_charge_en; in usb251xb_connect()
339 i2c_wb[USB251XB_ADDR_BOOST_UP] = hub->boost_up; in usb251xb_connect()
340 i2c_wb[USB251XB_ADDR_BOOST_57] = hub->boost_57; in usb251xb_connect()
341 i2c_wb[USB251XB_ADDR_BOOST_14] = hub->boost_14; in usb251xb_connect()
342 i2c_wb[USB251XB_ADDR_PORT_SWAP] = hub->port_swap; in usb251xb_connect()
343 i2c_wb[USB251XB_ADDR_PORT_MAP_12] = hub->port_map12; in usb251xb_connect()
344 i2c_wb[USB251XB_ADDR_PORT_MAP_34] = hub->port_map34; in usb251xb_connect()
345 i2c_wb[USB251XB_ADDR_PORT_MAP_56] = hub->port_map56; in usb251xb_connect()
346 i2c_wb[USB251XB_ADDR_PORT_MAP_7] = hub->port_map7; in usb251xb_connect()
365 err = i2c_smbus_write_i2c_block_data(hub->i2c, offset, in usb251xb_connect()
384 struct device *dev = hub->dev; in usb251xb_get_ports_field()
387 of_property_for_each_u32(dev->of_node, prop_name, port) { in usb251xb_get_ports_field()
398 struct device *dev = hub->dev; in usb251xb_get_ofdata()
399 struct device_node *np = dev->of_node; in usb251xb_get_ofdata()
407 return -ENODEV; in usb251xb_get_ofdata()
410 hub->skip_config = of_property_read_bool(np, "skip-config"); in usb251xb_get_ofdata()
412 hub->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in usb251xb_get_ofdata()
413 if (IS_ERR(hub->gpio_reset)) in usb251xb_get_ofdata()
414 return dev_err_probe(dev, PTR_ERR(hub->gpio_reset), in usb251xb_get_ofdata()
415 "unable to request GPIO reset pin\n"); in usb251xb_get_ofdata()
417 if (of_property_read_u16(np, "vendor-id", &hub->vendor_id)) in usb251xb_get_ofdata()
418 hub->vendor_id = USB251XB_DEF_VENDOR_ID; in usb251xb_get_ofdata()
420 if (of_property_read_u16(np, "product-id", &hub->product_id)) in usb251xb_get_ofdata()
421 hub->product_id = data->product_id; in usb251xb_get_ofdata()
423 if (of_property_read_u16(np, "device-id", &hub->device_id)) in usb251xb_get_ofdata()
424 hub->device_id = USB251XB_DEF_DEVICE_ID; in usb251xb_get_ofdata()
426 hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1; in usb251xb_get_ofdata()
427 if (of_property_read_bool(np, "self-powered")) { in usb251xb_get_ofdata()
428 hub->conf_data1 |= BIT(7); in usb251xb_get_ofdata()
430 /* Configure Over-Current sens when self-powered */ in usb251xb_get_ofdata()
431 hub->conf_data1 &= ~BIT(2); in usb251xb_get_ofdata()
432 if (of_property_read_bool(np, "ganged-sensing")) in usb251xb_get_ofdata()
433 hub->conf_data1 &= ~BIT(1); in usb251xb_get_ofdata()
434 else if (of_property_read_bool(np, "individual-sensing")) in usb251xb_get_ofdata()
435 hub->conf_data1 |= BIT(1); in usb251xb_get_ofdata()
436 } else if (of_property_read_bool(np, "bus-powered")) { in usb251xb_get_ofdata()
437 hub->conf_data1 &= ~BIT(7); in usb251xb_get_ofdata()
439 /* Disable Over-Current sense when bus-powered */ in usb251xb_get_ofdata()
440 hub->conf_data1 |= BIT(2); in usb251xb_get_ofdata()
443 if (of_property_read_bool(np, "disable-hi-speed")) in usb251xb_get_ofdata()
444 hub->conf_data1 |= BIT(5); in usb251xb_get_ofdata()
446 if (of_property_read_bool(np, "multi-tt")) in usb251xb_get_ofdata()
447 hub->conf_data1 |= BIT(4); in usb251xb_get_ofdata()
448 else if (of_property_read_bool(np, "single-tt")) in usb251xb_get_ofdata()
449 hub->conf_data1 &= ~BIT(4); in usb251xb_get_ofdata()
451 if (of_property_read_bool(np, "disable-eop")) in usb251xb_get_ofdata()
452 hub->conf_data1 |= BIT(3); in usb251xb_get_ofdata()
454 if (of_property_read_bool(np, "individual-port-switching")) in usb251xb_get_ofdata()
455 hub->conf_data1 |= BIT(0); in usb251xb_get_ofdata()
456 else if (of_property_read_bool(np, "ganged-port-switching")) in usb251xb_get_ofdata()
457 hub->conf_data1 &= ~BIT(0); in usb251xb_get_ofdata()
459 hub->conf_data2 = USB251XB_DEF_CONFIG_DATA_2; in usb251xb_get_ofdata()
460 if (of_property_read_bool(np, "dynamic-power-switching")) in usb251xb_get_ofdata()
461 hub->conf_data2 |= BIT(7); in usb251xb_get_ofdata()
463 if (!of_property_read_u32(np, "oc-delay-us", &property_u32)) { in usb251xb_get_ofdata()
466 hub->conf_data2 &= ~BIT(5); in usb251xb_get_ofdata()
467 hub->conf_data2 &= ~BIT(4); in usb251xb_get_ofdata()
470 hub->conf_data2 &= ~BIT(5); in usb251xb_get_ofdata()
471 hub->conf_data2 |= BIT(4); in usb251xb_get_ofdata()
474 hub->conf_data2 |= BIT(5); in usb251xb_get_ofdata()
475 hub->conf_data2 |= BIT(4); in usb251xb_get_ofdata()
478 hub->conf_data2 |= BIT(5); in usb251xb_get_ofdata()
479 hub->conf_data2 &= ~BIT(4); in usb251xb_get_ofdata()
483 if (of_property_read_bool(np, "compound-device")) in usb251xb_get_ofdata()
484 hub->conf_data2 |= BIT(3); in usb251xb_get_ofdata()
486 hub->conf_data3 = USB251XB_DEF_CONFIG_DATA_3; in usb251xb_get_ofdata()
487 if (of_property_read_bool(np, "port-mapping-mode")) in usb251xb_get_ofdata()
488 hub->conf_data3 |= BIT(3); in usb251xb_get_ofdata()
490 if (data->led_support && of_get_property(np, "led-usb-mode", NULL)) in usb251xb_get_ofdata()
491 hub->conf_data3 &= ~BIT(1); in usb251xb_get_ofdata()
493 if (of_property_read_bool(np, "string-support")) in usb251xb_get_ofdata()
494 hub->conf_data3 |= BIT(0); in usb251xb_get_ofdata()
496 hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES; in usb251xb_get_ofdata()
497 usb251xb_get_ports_field(hub, "non-removable-ports", data->port_cnt, in usb251xb_get_ofdata()
498 true, &hub->non_rem_dev); in usb251xb_get_ofdata()
500 hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF; in usb251xb_get_ofdata()
501 usb251xb_get_ports_field(hub, "sp-disabled-ports", data->port_cnt, in usb251xb_get_ofdata()
502 true, &hub->port_disable_sp); in usb251xb_get_ofdata()
504 hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS; in usb251xb_get_ofdata()
505 usb251xb_get_ports_field(hub, "bp-disabled-ports", data->port_cnt, in usb251xb_get_ofdata()
506 true, &hub->port_disable_bp); in usb251xb_get_ofdata()
508 hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF; in usb251xb_get_ofdata()
509 if (!of_property_read_u32(np, "sp-max-total-current-microamp", in usb251xb_get_ofdata()
511 hub->max_power_sp = min_t(u8, property_u32 / 2000, 50); in usb251xb_get_ofdata()
513 hub->max_power_bp = USB251XB_DEF_MAX_POWER_BUS; in usb251xb_get_ofdata()
514 if (!of_property_read_u32(np, "bp-max-total-current-microamp", in usb251xb_get_ofdata()
516 hub->max_power_bp = min_t(u8, property_u32 / 2000, 255); in usb251xb_get_ofdata()
518 hub->max_current_sp = USB251XB_DEF_MAX_CURRENT_SELF; in usb251xb_get_ofdata()
519 if (!of_property_read_u32(np, "sp-max-removable-current-microamp", in usb251xb_get_ofdata()
521 hub->max_current_sp = min_t(u8, property_u32 / 2000, 50); in usb251xb_get_ofdata()
523 hub->max_current_bp = USB251XB_DEF_MAX_CURRENT_BUS; in usb251xb_get_ofdata()
524 if (!of_property_read_u32(np, "bp-max-removable-current-microamp", in usb251xb_get_ofdata()
526 hub->max_current_bp = min_t(u8, property_u32 / 2000, 255); in usb251xb_get_ofdata()
528 hub->power_on_time = USB251XB_DEF_POWER_ON_TIME; in usb251xb_get_ofdata()
529 if (!of_property_read_u32(np, "power-on-time-ms", &property_u32)) in usb251xb_get_ofdata()
530 hub->power_on_time = min_t(u8, property_u32 / 2, 255); in usb251xb_get_ofdata()
532 if (of_property_read_u16(np, "language-id", &hub->lang_id)) in usb251xb_get_ofdata()
533 hub->lang_id = USB251XB_DEF_LANGUAGE_ID; in usb251xb_get_ofdata()
535 if (of_property_read_u8(np, "boost-up", &hub->boost_up)) in usb251xb_get_ofdata()
536 hub->boost_up = USB251XB_DEF_BOOST_UP; in usb251xb_get_ofdata()
541 hub->manufacturer_len = strlen(str) & 0xFF; in usb251xb_get_ofdata()
542 memset(hub->manufacturer, 0, USB251XB_STRING_BUFSIZE); in usb251xb_get_ofdata()
545 (wchar_t *)hub->manufacturer, in usb251xb_get_ofdata()
549 strscpy(str, cproperty_char ? : data->product_str, sizeof(str)); in usb251xb_get_ofdata()
550 hub->product_len = strlen(str) & 0xFF; in usb251xb_get_ofdata()
551 memset(hub->product, 0, USB251XB_STRING_BUFSIZE); in usb251xb_get_ofdata()
554 (wchar_t *)hub->product, in usb251xb_get_ofdata()
560 hub->serial_len = strlen(str) & 0xFF; in usb251xb_get_ofdata()
561 memset(hub->serial, 0, USB251XB_STRING_BUFSIZE); in usb251xb_get_ofdata()
564 (wchar_t *)hub->serial, in usb251xb_get_ofdata()
571 hub->port_swap = USB251XB_DEF_PORT_SWAP; in usb251xb_get_ofdata()
572 usb251xb_get_ports_field(hub, "swap-dx-lanes", data->port_cnt, in usb251xb_get_ofdata()
573 false, &hub->port_swap); in usb251xb_get_ofdata()
578 hub->bat_charge_en = USB251XB_DEF_BATTERY_CHARGING_ENABLE; in usb251xb_get_ofdata()
579 hub->boost_57 = USB251XB_DEF_BOOST_57; in usb251xb_get_ofdata()
580 hub->boost_14 = USB251XB_DEF_BOOST_14; in usb251xb_get_ofdata()
581 hub->port_map12 = USB251XB_DEF_PORT_MAP_12; in usb251xb_get_ofdata()
582 hub->port_map34 = USB251XB_DEF_PORT_MAP_34; in usb251xb_get_ofdata()
583 hub->port_map56 = USB251XB_DEF_PORT_MAP_56; in usb251xb_get_ofdata()
584 hub->port_map7 = USB251XB_DEF_PORT_MAP_7; in usb251xb_get_ofdata()
627 regulator_disable(hub->vdd); in usb251xb_regulator_disable_action()
632 struct device *dev = hub->dev; in usb251xb_probe()
633 struct device_node *np = dev->of_node; in usb251xb_probe()
646 * usb251x SMBus-slave SCL lane is muxed with CFG_SEL0 pin. So if anyone in usb251xb_probe()
650 * value without SMBus-slave interface activation. If the hub in usb251xb_probe()
651 * accidentally gets this mode, this will cause the driver SMBus- in usb251xb_probe()
652 * functions failure. Normally we could just lock the SMBus-segment the in usb251xb_probe()
653 * hub i2c-interface resides for the device-specific reset timing. But in usb251xb_probe()
654 * the GPIO controller, which is used to handle the hub reset, might be in usb251xb_probe()
655 * placed at the same i2c-bus segment. In this case an error should be in usb251xb_probe()
656 * returned since we can't safely use the GPIO controller to clear the in usb251xb_probe()
658 * the i2c-bus segment (it will cause a deadlock). in usb251xb_probe()
664 hub->vdd = devm_regulator_get(dev, "vdd"); in usb251xb_probe()
665 if (IS_ERR(hub->vdd)) in usb251xb_probe()
666 return PTR_ERR(hub->vdd); in usb251xb_probe()
668 err = regulator_enable(hub->vdd); in usb251xb_probe()
692 hub = devm_kzalloc(&i2c->dev, sizeof(struct usb251xb), GFP_KERNEL); in usb251xb_i2c_probe()
694 return -ENOMEM; in usb251xb_i2c_probe()
697 hub->dev = &i2c->dev; in usb251xb_i2c_probe()
698 hub->i2c = i2c; in usb251xb_i2c_probe()
708 return regulator_disable(hub->vdd); in usb251xb_suspend()
717 err = regulator_enable(hub->vdd); in usb251xb_resume()