On 03/14/2013 06:54 PM, Tony Lindgren wrote: > * Roger Quadros <rogerq@xxxxxx> [130314 08:45]: >> >> OK. Let me know how the below patch looks. After that, the board code >> will look like. >> >> static struct usbhs_phy_data phy_data[] = { >> { >> .reset_gpio = 147, >> .vcc_gpio = 148 >> .vcc_polarity = 1, >> .phy_id = "nop_usb_xceiv.2", >> }, >> {}, /* Terminator */ >> }; >> >> usbhs_init_phys(phy_data); > > Great, looks good to me. > >> Patch to implement usbhs_init_phys(); >> >> diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c >> index 5706bdc..b9d6bff 100644 >> --- a/arch/arm/mach-omap2/usb-host.c >> +++ b/arch/arm/mach-omap2/usb-host.c >> @@ -22,8 +22,12 @@ >> #include <linux/platform_device.h> >> #include <linux/slab.h> >> #include <linux/dma-mapping.h> >> +#include <linux/regulator/machine.h> >> +#include <linux/regulator/fixed.h> >> +#include <linux/string.h> >> >> #include <asm/io.h> >> +#include <asm/gpio.h> > > Please change these both to linux/io.h and linux/gpio.h. OK. > >> #include "soc.h" >> #include "omap_device.h" >> @@ -472,6 +476,141 @@ void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) >> } >> } >> >> +static const char *reset_supply = "reset"; >> +static const char *vcc_supply = "vcc"; >> + >> +/* Template for PHY regulators */ >> +static struct regulator_consumer_supply hsusb_reg_supplies[] = { >> + { /* .supply & .dev_name filled later */ }, >> +}; >> + >> +static struct regulator_init_data hsusb_reg_data = { >> + .constraints = { >> + .valid_ops_mask = REGULATOR_CHANGE_STATUS, >> + }, >> + .consumer_supplies = hsusb_reg_supplies, >> + .num_consumer_supplies = ARRAY_SIZE(hsusb_reg_supplies), >> +}; >> + >> +static struct fixed_voltage_config hsusb_reg_config = { >> + /* .supply_name filled later */ >> + .microvolts = 3300000, >> + .gpio = -1, /* updated later */ >> + .startup_delay = 70000, /* 70msec */ >> + .enable_high = 1, /* updated later */ >> + .enabled_at_boot = 0, /* keep in RESET */ >> + /* .init_data filled later */ >> +}; >> + >> +static struct platform_device_info hsusb_reg_pdev_info = { >> + .name = "reg-fixed-voltage", >> + .id = PLATFORM_DEVID_AUTO, >> +}; >> + >> +int __init usbhs_init_phys(struct usbhs_phy_data *phy) >> +{ >> + struct regulator_consumer_supply *supplies; >> + struct regulator_init_data *reg_data; >> + struct fixed_voltage_config *config; >> + char *supply_name; >> + int i; >> + >> + >> + for (i = 1; i <= OMAP3_HS_USB_PORTS; i++) { > > Maybe pass the number of ports to initialize too to the > function? Might be more future proof, although it will only > be needed until we have converted to DT. > OK. I'll add a port index parameter to the usbhs_phy_data structure to indicate which port the data belongs to and a number of ports to usbhs_init_phys() board code can then do static struct usbhs_phy_data phy_data[] = { { .port = 1, /* First USB port */ .reset_gpio = 147, .vcc_gpio = 148 .vcc_polarity = 1, .phy_id = "nop_usb_xceiv.2", }, }; usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); >> + >> + if (!phy->phy_id) /* Terminator ? */ >> + break; >> + >> + if (!gpio_is_valid(phy->reset_gpio)) >> + goto check_vcc; >> + >> + supplies = kmemdup(hsusb_reg_supplies, >> + ARRAY_SIZE(hsusb_reg_supplies) * >> + sizeof(struct regulator_consumer_supply), >> + GFP_KERNEL); >> + if (!supplies) >> + return -ENOMEM; >> + >> + supplies->supply = reset_supply; >> + supplies->dev_name = phy->phy_id; >> + >> + reg_data = kmemdup(&hsusb_reg_data, sizeof(hsusb_reg_data), >> + GFP_KERNEL); >> + if (!reg_data) >> + return -ENOMEM; >> + >> + reg_data->consumer_supplies = supplies; >> + >> + config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config), >> + GFP_KERNEL); >> + if (!config) >> + return -ENOMEM; >> + >> + supply_name = kmalloc(14, GFP_KERNEL); >> + if (!supply_name) >> + return -ENOMEM; >> + >> + scnprintf(supply_name, 13, "hsusb%d_reset", i); >> + config->supply_name = supply_name; >> + config->gpio = phy->reset_gpio; >> + config->init_data = reg_data; >> + >> + hsusb_reg_pdev_info.data = config; >> + hsusb_reg_pdev_info.size_data = sizeof(hsusb_reg_config); >> + platform_device_register_full(&hsusb_reg_pdev_info); >> + >> +check_vcc: >> + if (!gpio_is_valid(phy->vcc_gpio)) >> + goto next; >> + >> + supplies = kmemdup(hsusb_reg_supplies, >> + ARRAY_SIZE(hsusb_reg_supplies) * >> + sizeof(struct regulator_consumer_supply), >> + GFP_KERNEL); >> + if (!supplies) >> + return -ENOMEM; >> + >> + supplies->supply = vcc_supply; >> + supplies->dev_name = phy->phy_id; >> + >> + reg_data = kmemdup(&hsusb_reg_data, sizeof(hsusb_reg_data), >> + GFP_KERNEL); >> + if (!reg_data) >> + return -ENOMEM; >> + >> + reg_data->consumer_supplies = supplies; >> + >> + config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config), >> + GFP_KERNEL); >> + if (!config) >> + return -ENOMEM; >> + >> + supply_name = kmalloc(14, GFP_KERNEL); >> + if (!supply_name) >> + return -ENOMEM; >> + >> + scnprintf(supply_name, 13, "hsusb%d_vcc", i); >> + config->supply_name = supply_name; >> + config->gpio = phy->vcc_gpio; >> + config->enable_high = phy->vcc_polarity; >> + config->init_data = reg_data; >> + >> + hsusb_reg_pdev_info.data = config; >> + hsusb_reg_pdev_info.size_data = sizeof(hsusb_reg_config); >> + platform_device_register_full(&hsusb_reg_pdev_info); >> + >> +next: >> + phy++; >> + } >> + >> + return 0; >> +} >> + >> void __init usbhs_init(struct usbhs_omap_platform_data *pdata) >> { >> struct omap_hwmod *uhh_hwm, *tll_hwm; >> diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h >> index 3319f5c..70a8c63 100644 >> --- a/arch/arm/mach-omap2/usb.h >> +++ b/arch/arm/mach-omap2/usb.h >> @@ -53,8 +53,16 @@ >> #define USBPHY_OTGSESSEND_EN (1 << 20) >> #define USBPHY_DATA_POLARITY (1 << 23) >> >> +struct usbhs_phy_data { >> + int reset_gpio; >> + int vcc_gpio; >> + bool vcc_polarity; /* 1 active high, 0 active low */ >> + char *phy_id; >> +}; >> + >> extern void usb_musb_init(struct omap_musb_board_data *board_data); >> extern void usbhs_init(struct usbhs_omap_platform_data *pdata); >> +extern int usbhs_init_phys(struct usbhs_phy_data *phy); > > Maybe need a static inline version when no EHCI is selected? > Yes. > Otherwise looks good to me, thanks for updating it. > Cool. I'll update all boards and send it to you soon. cheers, -roger -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html