162306a36Sopenharmony_ci==================================== 262306a36Sopenharmony_ciSamsung USB 2.0 PHY adaptation layer 362306a36Sopenharmony_ci==================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci1. Description 662306a36Sopenharmony_ci-------------- 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciThe architecture of the USB 2.0 PHY module in Samsung SoCs is similar 962306a36Sopenharmony_ciamong many SoCs. In spite of the similarities it proved difficult to 1062306a36Sopenharmony_cicreate a one driver that would fit all these PHY controllers. Often 1162306a36Sopenharmony_cithe differences were minor and were found in particular bits of the 1262306a36Sopenharmony_ciregisters of the PHY. In some rare cases the order of register writes or 1362306a36Sopenharmony_cithe PHY powering up process had to be altered. This adaptation layer is 1462306a36Sopenharmony_cia compromise between having separate drivers and having a single driver 1562306a36Sopenharmony_ciwith added support for many special cases. 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci2. Files description 1862306a36Sopenharmony_ci-------------------- 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci- phy-samsung-usb2.c 2162306a36Sopenharmony_ci This is the main file of the adaptation layer. This file contains 2262306a36Sopenharmony_ci the probe function and provides two callbacks to the Generic PHY 2362306a36Sopenharmony_ci Framework. This two callbacks are used to power on and power off the 2462306a36Sopenharmony_ci phy. They carry out the common work that has to be done on all version 2562306a36Sopenharmony_ci of the PHY module. Depending on which SoC was chosen they execute SoC 2662306a36Sopenharmony_ci specific callbacks. The specific SoC version is selected by choosing 2762306a36Sopenharmony_ci the appropriate compatible string. In addition, this file contains 2862306a36Sopenharmony_ci struct of_device_id definitions for particular SoCs. 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci- phy-samsung-usb2.h 3162306a36Sopenharmony_ci This is the include file. It declares the structures used by this 3262306a36Sopenharmony_ci driver. In addition it should contain extern declarations for 3362306a36Sopenharmony_ci structures that describe particular SoCs. 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci3. Supporting SoCs 3662306a36Sopenharmony_ci------------------ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ciTo support a new SoC a new file should be added to the drivers/phy 3962306a36Sopenharmony_cidirectory. Each SoC's configuration is stored in an instance of the 4062306a36Sopenharmony_cistruct samsung_usb2_phy_config:: 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci struct samsung_usb2_phy_config { 4362306a36Sopenharmony_ci const struct samsung_usb2_common_phy *phys; 4462306a36Sopenharmony_ci int (*rate_to_clk)(unsigned long, u32 *); 4562306a36Sopenharmony_ci unsigned int num_phys; 4662306a36Sopenharmony_ci bool has_mode_switch; 4762306a36Sopenharmony_ci }; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciThe num_phys is the number of phys handled by the driver. `*phys` is an 5062306a36Sopenharmony_ciarray that contains the configuration for each phy. The has_mode_switch 5162306a36Sopenharmony_ciproperty is a boolean flag that determines whether the SoC has USB host 5262306a36Sopenharmony_ciand device on a single pair of pins. If so, a special register has to 5362306a36Sopenharmony_cibe modified to change the internal routing of these pins between a USB 5462306a36Sopenharmony_cidevice or host module. 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciFor example the configuration for Exynos 4210 is following:: 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = { 5962306a36Sopenharmony_ci .has_mode_switch = 0, 6062306a36Sopenharmony_ci .num_phys = EXYNOS4210_NUM_PHYS, 6162306a36Sopenharmony_ci .phys = exynos4210_phys, 6262306a36Sopenharmony_ci .rate_to_clk = exynos4210_rate_to_clk, 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci- `int (*rate_to_clk)(unsigned long, u32 *)` 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci The rate_to_clk callback is to convert the rate of the clock 6862306a36Sopenharmony_ci used as the reference clock for the PHY module to the value 6962306a36Sopenharmony_ci that should be written in the hardware register. 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ciThe exynos4210_phys configuration array is as follows:: 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci static const struct samsung_usb2_common_phy exynos4210_phys[] = { 7462306a36Sopenharmony_ci { 7562306a36Sopenharmony_ci .label = "device", 7662306a36Sopenharmony_ci .id = EXYNOS4210_DEVICE, 7762306a36Sopenharmony_ci .power_on = exynos4210_power_on, 7862306a36Sopenharmony_ci .power_off = exynos4210_power_off, 7962306a36Sopenharmony_ci }, 8062306a36Sopenharmony_ci { 8162306a36Sopenharmony_ci .label = "host", 8262306a36Sopenharmony_ci .id = EXYNOS4210_HOST, 8362306a36Sopenharmony_ci .power_on = exynos4210_power_on, 8462306a36Sopenharmony_ci .power_off = exynos4210_power_off, 8562306a36Sopenharmony_ci }, 8662306a36Sopenharmony_ci { 8762306a36Sopenharmony_ci .label = "hsic0", 8862306a36Sopenharmony_ci .id = EXYNOS4210_HSIC0, 8962306a36Sopenharmony_ci .power_on = exynos4210_power_on, 9062306a36Sopenharmony_ci .power_off = exynos4210_power_off, 9162306a36Sopenharmony_ci }, 9262306a36Sopenharmony_ci { 9362306a36Sopenharmony_ci .label = "hsic1", 9462306a36Sopenharmony_ci .id = EXYNOS4210_HSIC1, 9562306a36Sopenharmony_ci .power_on = exynos4210_power_on, 9662306a36Sopenharmony_ci .power_off = exynos4210_power_off, 9762306a36Sopenharmony_ci }, 9862306a36Sopenharmony_ci {}, 9962306a36Sopenharmony_ci }; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci- `int (*power_on)(struct samsung_usb2_phy_instance *);` 10262306a36Sopenharmony_ci `int (*power_off)(struct samsung_usb2_phy_instance *);` 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci These two callbacks are used to power on and power off the phy 10562306a36Sopenharmony_ci by modifying appropriate registers. 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ciFinal change to the driver is adding appropriate compatible value to the 10862306a36Sopenharmony_ciphy-samsung-usb2.c file. In case of Exynos 4210 the following lines were 10962306a36Sopenharmony_ciadded to the struct of_device_id samsung_usb2_phy_of_match[] array:: 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci #ifdef CONFIG_PHY_EXYNOS4210_USB2 11262306a36Sopenharmony_ci { 11362306a36Sopenharmony_ci .compatible = "samsung,exynos4210-usb2-phy", 11462306a36Sopenharmony_ci .data = &exynos4210_usb2_phy_config, 11562306a36Sopenharmony_ci }, 11662306a36Sopenharmony_ci #endif 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciTo add further flexibility to the driver the Kconfig file enables to 11962306a36Sopenharmony_ciinclude support for selected SoCs in the compiled driver. The Kconfig 12062306a36Sopenharmony_cientry for Exynos 4210 is following:: 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci config PHY_EXYNOS4210_USB2 12362306a36Sopenharmony_ci bool "Support for Exynos 4210" 12462306a36Sopenharmony_ci depends on PHY_SAMSUNG_USB2 12562306a36Sopenharmony_ci depends on CPU_EXYNOS4210 12662306a36Sopenharmony_ci help 12762306a36Sopenharmony_ci Enable USB PHY support for Exynos 4210. This option requires that 12862306a36Sopenharmony_ci Samsung USB 2.0 PHY driver is enabled and means that support for this 12962306a36Sopenharmony_ci particular SoC is compiled in the driver. In case of Exynos 4210 four 13062306a36Sopenharmony_ci phys are available - device, host, HSCI0 and HSCI1. 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ciThe newly created file that supports the new SoC has to be also added to the 13362306a36Sopenharmony_ciMakefile. In case of Exynos 4210 the added line is following:: 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ciAfter completing these steps the support for the new SoC should be ready. 138