1*4745dc8aSMauro Carvalho Chehab==================================== 2*4745dc8aSMauro Carvalho ChehabSamsung USB 2.0 PHY adaptation layer 3*4745dc8aSMauro Carvalho Chehab==================================== 4*4745dc8aSMauro Carvalho Chehab 5*4745dc8aSMauro Carvalho Chehab1. Description 6*4745dc8aSMauro Carvalho Chehab-------------- 7*4745dc8aSMauro Carvalho Chehab 8*4745dc8aSMauro Carvalho ChehabThe architecture of the USB 2.0 PHY module in Samsung SoCs is similar 9*4745dc8aSMauro Carvalho Chehabamong many SoCs. In spite of the similarities it proved difficult to 10*4745dc8aSMauro Carvalho Chehabcreate a one driver that would fit all these PHY controllers. Often 11*4745dc8aSMauro Carvalho Chehabthe differences were minor and were found in particular bits of the 12*4745dc8aSMauro Carvalho Chehabregisters of the PHY. In some rare cases the order of register writes or 13*4745dc8aSMauro Carvalho Chehabthe PHY powering up process had to be altered. This adaptation layer is 14*4745dc8aSMauro Carvalho Chehaba compromise between having separate drivers and having a single driver 15*4745dc8aSMauro Carvalho Chehabwith added support for many special cases. 16*4745dc8aSMauro Carvalho Chehab 17*4745dc8aSMauro Carvalho Chehab2. Files description 18*4745dc8aSMauro Carvalho Chehab-------------------- 19*4745dc8aSMauro Carvalho Chehab 20*4745dc8aSMauro Carvalho Chehab- phy-samsung-usb2.c 21*4745dc8aSMauro Carvalho Chehab This is the main file of the adaptation layer. This file contains 22*4745dc8aSMauro Carvalho Chehab the probe function and provides two callbacks to the Generic PHY 23*4745dc8aSMauro Carvalho Chehab Framework. This two callbacks are used to power on and power off the 24*4745dc8aSMauro Carvalho Chehab phy. They carry out the common work that has to be done on all version 25*4745dc8aSMauro Carvalho Chehab of the PHY module. Depending on which SoC was chosen they execute SoC 26*4745dc8aSMauro Carvalho Chehab specific callbacks. The specific SoC version is selected by choosing 27*4745dc8aSMauro Carvalho Chehab the appropriate compatible string. In addition, this file contains 28*4745dc8aSMauro Carvalho Chehab struct of_device_id definitions for particular SoCs. 29*4745dc8aSMauro Carvalho Chehab 30*4745dc8aSMauro Carvalho Chehab- phy-samsung-usb2.h 31*4745dc8aSMauro Carvalho Chehab This is the include file. It declares the structures used by this 32*4745dc8aSMauro Carvalho Chehab driver. In addition it should contain extern declarations for 33*4745dc8aSMauro Carvalho Chehab structures that describe particular SoCs. 34*4745dc8aSMauro Carvalho Chehab 35*4745dc8aSMauro Carvalho Chehab3. Supporting SoCs 36*4745dc8aSMauro Carvalho Chehab------------------ 37*4745dc8aSMauro Carvalho Chehab 38*4745dc8aSMauro Carvalho ChehabTo support a new SoC a new file should be added to the drivers/phy 39*4745dc8aSMauro Carvalho Chehabdirectory. Each SoC's configuration is stored in an instance of the 40*4745dc8aSMauro Carvalho Chehabstruct samsung_usb2_phy_config:: 41*4745dc8aSMauro Carvalho Chehab 42*4745dc8aSMauro Carvalho Chehab struct samsung_usb2_phy_config { 43*4745dc8aSMauro Carvalho Chehab const struct samsung_usb2_common_phy *phys; 44*4745dc8aSMauro Carvalho Chehab int (*rate_to_clk)(unsigned long, u32 *); 45*4745dc8aSMauro Carvalho Chehab unsigned int num_phys; 46*4745dc8aSMauro Carvalho Chehab bool has_mode_switch; 47*4745dc8aSMauro Carvalho Chehab }; 48*4745dc8aSMauro Carvalho Chehab 49*4745dc8aSMauro Carvalho ChehabThe num_phys is the number of phys handled by the driver. `*phys` is an 50*4745dc8aSMauro Carvalho Chehabarray that contains the configuration for each phy. The has_mode_switch 51*4745dc8aSMauro Carvalho Chehabproperty is a boolean flag that determines whether the SoC has USB host 52*4745dc8aSMauro Carvalho Chehaband device on a single pair of pins. If so, a special register has to 53*4745dc8aSMauro Carvalho Chehabbe modified to change the internal routing of these pins between a USB 54*4745dc8aSMauro Carvalho Chehabdevice or host module. 55*4745dc8aSMauro Carvalho Chehab 56*4745dc8aSMauro Carvalho ChehabFor example the configuration for Exynos 4210 is following:: 57*4745dc8aSMauro Carvalho Chehab 58*4745dc8aSMauro Carvalho Chehab const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = { 59*4745dc8aSMauro Carvalho Chehab .has_mode_switch = 0, 60*4745dc8aSMauro Carvalho Chehab .num_phys = EXYNOS4210_NUM_PHYS, 61*4745dc8aSMauro Carvalho Chehab .phys = exynos4210_phys, 62*4745dc8aSMauro Carvalho Chehab .rate_to_clk = exynos4210_rate_to_clk, 63*4745dc8aSMauro Carvalho Chehab } 64*4745dc8aSMauro Carvalho Chehab 65*4745dc8aSMauro Carvalho Chehab- `int (*rate_to_clk)(unsigned long, u32 *)` 66*4745dc8aSMauro Carvalho Chehab 67*4745dc8aSMauro Carvalho Chehab The rate_to_clk callback is to convert the rate of the clock 68*4745dc8aSMauro Carvalho Chehab used as the reference clock for the PHY module to the value 69*4745dc8aSMauro Carvalho Chehab that should be written in the hardware register. 70*4745dc8aSMauro Carvalho Chehab 71*4745dc8aSMauro Carvalho ChehabThe exynos4210_phys configuration array is as follows:: 72*4745dc8aSMauro Carvalho Chehab 73*4745dc8aSMauro Carvalho Chehab static const struct samsung_usb2_common_phy exynos4210_phys[] = { 74*4745dc8aSMauro Carvalho Chehab { 75*4745dc8aSMauro Carvalho Chehab .label = "device", 76*4745dc8aSMauro Carvalho Chehab .id = EXYNOS4210_DEVICE, 77*4745dc8aSMauro Carvalho Chehab .power_on = exynos4210_power_on, 78*4745dc8aSMauro Carvalho Chehab .power_off = exynos4210_power_off, 79*4745dc8aSMauro Carvalho Chehab }, 80*4745dc8aSMauro Carvalho Chehab { 81*4745dc8aSMauro Carvalho Chehab .label = "host", 82*4745dc8aSMauro Carvalho Chehab .id = EXYNOS4210_HOST, 83*4745dc8aSMauro Carvalho Chehab .power_on = exynos4210_power_on, 84*4745dc8aSMauro Carvalho Chehab .power_off = exynos4210_power_off, 85*4745dc8aSMauro Carvalho Chehab }, 86*4745dc8aSMauro Carvalho Chehab { 87*4745dc8aSMauro Carvalho Chehab .label = "hsic0", 88*4745dc8aSMauro Carvalho Chehab .id = EXYNOS4210_HSIC0, 89*4745dc8aSMauro Carvalho Chehab .power_on = exynos4210_power_on, 90*4745dc8aSMauro Carvalho Chehab .power_off = exynos4210_power_off, 91*4745dc8aSMauro Carvalho Chehab }, 92*4745dc8aSMauro Carvalho Chehab { 93*4745dc8aSMauro Carvalho Chehab .label = "hsic1", 94*4745dc8aSMauro Carvalho Chehab .id = EXYNOS4210_HSIC1, 95*4745dc8aSMauro Carvalho Chehab .power_on = exynos4210_power_on, 96*4745dc8aSMauro Carvalho Chehab .power_off = exynos4210_power_off, 97*4745dc8aSMauro Carvalho Chehab }, 98*4745dc8aSMauro Carvalho Chehab {}, 99*4745dc8aSMauro Carvalho Chehab }; 100*4745dc8aSMauro Carvalho Chehab 101*4745dc8aSMauro Carvalho Chehab- `int (*power_on)(struct samsung_usb2_phy_instance *);` 102*4745dc8aSMauro Carvalho Chehab `int (*power_off)(struct samsung_usb2_phy_instance *);` 103*4745dc8aSMauro Carvalho Chehab 104*4745dc8aSMauro Carvalho Chehab These two callbacks are used to power on and power off the phy 105*4745dc8aSMauro Carvalho Chehab by modifying appropriate registers. 106*4745dc8aSMauro Carvalho Chehab 107*4745dc8aSMauro Carvalho ChehabFinal change to the driver is adding appropriate compatible value to the 108*4745dc8aSMauro Carvalho Chehabphy-samsung-usb2.c file. In case of Exynos 4210 the following lines were 109*4745dc8aSMauro Carvalho Chehabadded to the struct of_device_id samsung_usb2_phy_of_match[] array:: 110*4745dc8aSMauro Carvalho Chehab 111*4745dc8aSMauro Carvalho Chehab #ifdef CONFIG_PHY_EXYNOS4210_USB2 112*4745dc8aSMauro Carvalho Chehab { 113*4745dc8aSMauro Carvalho Chehab .compatible = "samsung,exynos4210-usb2-phy", 114*4745dc8aSMauro Carvalho Chehab .data = &exynos4210_usb2_phy_config, 115*4745dc8aSMauro Carvalho Chehab }, 116*4745dc8aSMauro Carvalho Chehab #endif 117*4745dc8aSMauro Carvalho Chehab 118*4745dc8aSMauro Carvalho ChehabTo add further flexibility to the driver the Kconfig file enables to 119*4745dc8aSMauro Carvalho Chehabinclude support for selected SoCs in the compiled driver. The Kconfig 120*4745dc8aSMauro Carvalho Chehabentry for Exynos 4210 is following:: 121*4745dc8aSMauro Carvalho Chehab 122*4745dc8aSMauro Carvalho Chehab config PHY_EXYNOS4210_USB2 123*4745dc8aSMauro Carvalho Chehab bool "Support for Exynos 4210" 124*4745dc8aSMauro Carvalho Chehab depends on PHY_SAMSUNG_USB2 125*4745dc8aSMauro Carvalho Chehab depends on CPU_EXYNOS4210 126*4745dc8aSMauro Carvalho Chehab help 127*4745dc8aSMauro Carvalho Chehab Enable USB PHY support for Exynos 4210. This option requires that 128*4745dc8aSMauro Carvalho Chehab Samsung USB 2.0 PHY driver is enabled and means that support for this 129*4745dc8aSMauro Carvalho Chehab particular SoC is compiled in the driver. In case of Exynos 4210 four 130*4745dc8aSMauro Carvalho Chehab phys are available - device, host, HSCI0 and HSCI1. 131*4745dc8aSMauro Carvalho Chehab 132*4745dc8aSMauro Carvalho ChehabThe newly created file that supports the new SoC has to be also added to the 133*4745dc8aSMauro Carvalho ChehabMakefile. In case of Exynos 4210 the added line is following:: 134*4745dc8aSMauro Carvalho Chehab 135*4745dc8aSMauro Carvalho Chehab obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o 136*4745dc8aSMauro Carvalho Chehab 137*4745dc8aSMauro Carvalho ChehabAfter completing these steps the support for the new SoC should be ready. 138