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