Re: [PATCH Ver 1.0 3/7] Subscribes for USB resources for TI-DM646x EVM

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Swaminathan S <swami.iyer@xxxxxx> writes:

> This patch implments the support for USB VBUS, PHY control, DM646x
> USB memory map, IRQ, USB Mode. It initializes for a single instance
> of MUSB controller.
>
> Signed-off-by: Ravi B <ravibabu@xxxxxx>

Same comments made on dm644x, some others below...

> ---
>  arch/arm/mach-davinci/board-dm646x-evm.c    |   72 +++++++++++++++++++++
>  arch/arm/mach-davinci/dm646x.c              |   91 +++++++++++++++++++++++++++
>  arch/arm/mach-davinci/include/mach/dm646x.h |    3 +
>  arch/arm/mach-davinci/include/mach/usb.h    |    3 +
>  4 files changed, 169 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
> index 24e0e13..49103a6 100644
> --- a/arch/arm/mach-davinci/board-dm646x-evm.c
> +++ b/arch/arm/mach-davinci/board-dm646x-evm.c
> @@ -33,6 +33,7 @@
>  #include <linux/i2c/at24.h>
>  #include <linux/i2c/pcf857x.h>
>  #include <linux/etherdevice.h>
> +#include <linux/usb/musb.h>
>  
>  #include <media/tvp514x.h>
>  
> @@ -60,6 +61,7 @@
>  /* CPLD Register 0 bits to control ATA */
>  #define DM646X_EVM_ATA_RST		BIT(0)
>  #define DM646X_EVM_ATA_PWD		BIT(1)
> +#define DM646X_EVM_USB_VBUS		BIT(7)
>  
>  #define DM646X_EVM_PHY_MASK		(0x2)
>  #define DM646X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
> @@ -88,14 +90,33 @@ static void __iomem *vpif_vsclkdis_reg;
>  /* spin lock for updating above registers */
>  static spinlock_t vpif_reg_lock;
>  
> +static int dm646x_evm_set_vbus(struct device *dev, int is_on);
> +static struct musb_hdrc_platform_data usb_evm_data[] = {
> +	{
> +#if defined(CONFIG_USB_MUSB_OTG)
> +		.mode = MUSB_OTG,
> +#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
> +		.mode =  MUSB_PERIPHERAL,
> +#elif defined(CONFIG_USB_MUSB_HOST)
> +		.mode = MUSB_HOST,
> +#endif
> +		.power = 255,
> +		.potpgt = 8,
> +		.set_vbus = dm646x_evm_set_vbus,
> +	}
> +};
> +
>  static struct davinci_uart_config uart_config __initdata = {
>  	.enabled_uarts = (1 << 0),
>  };
>  
> +struct i2c_client *cpld_reg0_client;
>  /* CPLD Register 0 Client: used for I/O Control */
>  static int cpld_reg0_probe(struct i2c_client *client,
>  			   const struct i2c_device_id *id)
>  {
> +	cpld_reg0_client = client;
> +
>  	if (HAS_ATA) {
>  		u8 data;
>  		struct i2c_msg msg[2] = {
> @@ -652,6 +673,8 @@ static __init void evm_init(void)
>  
>  	soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
>  	soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
> +
> +	dm646x_usb_configure(usb_evm_data, ARRAY_SIZE(usb_evm_data));
>  }
>  
>  static __init void davinci_dm646x_evm_irq_init(void)
> @@ -659,6 +682,55 @@ static __init void davinci_dm646x_evm_irq_init(void)
>  	davinci_irq_init();
>  }
>  
> +/* Initiate the I2C command to the expander to turn on/off the VBUS line */
> +static int vbus_state = -1;
> +static void evm_deferred_drvvbus(struct work_struct *ignored)
> +{
> +	u8 data;
> +
> +	struct i2c_msg msg[2] = {
> +		{
> +			.addr = cpld_reg0_client->addr,
> +			.flags = I2C_M_RD,
> +			.len = 1,
> +			.buf = &data,
> +		},
> +		{
> +			.addr = cpld_reg0_client->addr,
> +			.flags = 0,
> +			.len = 1,
> +			.buf = &data,
> +		},
> +	};
> +
> +	i2c_transfer(cpld_reg0_client->adapter, msg, 1);
> +	if (vbus_state)
> +		data |= DM646X_EVM_USB_VBUS;
> +	else
> +		data &= ~DM646X_EVM_USB_VBUS;
> +
> +	i2c_transfer(cpld_reg0_client->adapter, msg + 1, 1);
> +	vbus_state = !vbus_state;
> +}
> +
> +/*
> + * DM644x EVM USB VBUS handler.  On TI DM644x EVM USB VBUS is controller

dm644x?  copy/paste problem.

> + * through I2C expander (0x3A) lines.  Tthis function schedules a
> + * work thread to handle the actual VBUS on/off operations.
> + */

When adding function documentation, please use kerneldoc style
Please see: Documentation/kernel-doc-nano-HOWTO.txt.

That being said, I'm not sure what this comment adds that is
not quickly obvious from the code.

> +static int dm646x_evm_set_vbus(struct device *dev, int is_on)
> +{
> +	static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
> +
> +	is_on = is_on ? 1 : 0;

is_on should be a bool, then you wouldn't need this.

Also, I know you're just copying the name from the old code, but I've
never been to thrilled with the 'is_on' name.  IMHO, a 'bool enabled'
be a little better.

> +	if (vbus_state == is_on)
> +		return 0;
> +
> +	vbus_state = !is_on;
> +	schedule_work(&evm_vbus_work);
> +	return 0;
> +}
> +
>  MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
>  	.phys_io      = IO_PHYS,
>  	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
> diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
> index 36e4fb4..bede7fe 100644
> --- a/arch/arm/mach-davinci/dm646x.c
> +++ b/arch/arm/mach-davinci/dm646x.c
> @@ -28,6 +28,8 @@
>  #include <mach/serial.h>
>  #include <mach/common.h>
>  #include <mach/asp.h>
> +#include <mach/usb.h>
> +#include <mach/usb_musb.h>
>  
>  #include "clock.h"
>  #include "mux.h"
> @@ -315,6 +317,12 @@ static struct clk vpif1_clk = {
>  	.flags = ALWAYS_ENABLED,
>  };
>  
> +static struct clk usb_clk = {
> +	.name = "usb",
> +	.parent = &pll1_sysclk3,
> +	.lpsc = DAVINCI_LPSC_USB,
> +};
> +

Minor nit... rather than add at the end, can you group this with the
other clocks sourced by pll1_sysclk3.

>  struct davinci_clk dm646x_clks[] = {
>  	CLK(NULL, "ref", &ref_clk),
>  	CLK(NULL, "aux", &aux_clkin),
> @@ -355,6 +363,7 @@ struct davinci_clk dm646x_clks[] = {
>  	CLK("palm_bk3710", NULL, &ide_clk),
>  	CLK(NULL, "vpif0", &vpif0_clk),
>  	CLK(NULL, "vpif1", &vpif1_clk),
> +	CLK(NULL, "usb", &usb_clk),

ditto

>  	CLK(NULL, NULL, NULL),
>  };
>  
> @@ -930,6 +939,87 @@ void __init dm646x_init(void)
>  	davinci_common_init(&davinci_soc_info_dm646x);
>  }
>  
> +/*
> + * Configure the USB PHY for DM644x platforms.
> + */
> +static int dm646x_usb_phy_config(struct device *dev, u8 mode, int is_on)
> +{
> +	u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
> +
> +	if (is_on) {
> +		/* power everything up; start the on-chip PHY and its PLL */
> +		phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN);
> +		phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON;
> +		phy_ctrl |= USBPHY_NDATAPOL | USBPHY_SESSION_VBUS;
> +		switch (mode) {
> +		case MUSB_PERIPHERAL:
> +			phy_ctrl |= USBPHY_PERI_USBID;
> +			break;
> +		case MUSB_HOST:
> +			phy_ctrl &= ~USBPHY_VBDTCTEN;
> +			break;
> +		}
> +
> +	} else {
> +		/* powerdown the on-chip PHY, its PLL, and the OTG block */
> +		phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN |
> +				USBPHY_PHYPLLON);
> +		phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN;
> +	}
> +
> +	__raw_writel(phy_ctrl, USB_PHY_CTRL);
> +
> +	if (is_on) {
> +		/* wait for PLL to lock before proceeding */
> +		while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
> +			cpu_relax();
> +	}

braces not needed

> +	return 0;
> +}
> +
> +static struct resource usb_resources[] = {
> +	{
> +		.start  = DAVINCI_USB_OTG_BASE,
> +		.end    = DAVINCI_USB_OTG_BASE + 0x5ff,
> +		.flags  = IORESOURCE_MEM,
> +	},
> +	{
> +		.start  = IRQ_DM646X_USBINT,
> +		.flags  = IORESOURCE_IRQ,
> +	},
> +	{
> +		.start  = IRQ_DM646X_USBDMAINT,
> +		.flags  = IORESOURCE_IRQ,
> +	},
> +};
> +
> +static struct plat_res_data dm646x_usb_res;
> +static struct usb_plat_data dm646x_usb_plat_data;
> +/*
> + * Initialize DM644x related USB information such as Memory maps, IRQ etc.
> + * Since DM644x supprot a single MUSB controller initialize the instance
> + * value to 1.
> + */

s/dm644x/dm646x/  and kerneldoc

> +void dm646x_usb_configure(struct musb_hdrc_platform_data *pdata, u8 num_inst)
> +{
> +	pdata->phy_config = dm646x_usb_phy_config;
> +
> +	dm646x_usb_res.plat_data = pdata;
> +	dm646x_usb_res.res_data = usb_resources;
> +	dm646x_usb_res.num_res = ARRAY_SIZE(usb_resources);
> +
> +	dm646x_usb_plat_data.prdata = &dm646x_usb_res;
> +	dm646x_usb_plat_data.num_inst = num_inst;
> +
> +	/* Call the generic platform register function.  The USB
> +	 * configuration w.r.t no. of ep's, capabalities etc. are common
> +	 * across DaVinci platforms and hence allow the generic handler
> +	 * to populate the information.
> +	 */

See "The preferred style for long (multi-line) comments" in Documentation/CodingStyle

> +	setup_usb(&dm646x_usb_plat_data);
> +}
> +
>  static int __init dm646x_init_devices(void)
>  {
>  	if (!cpu_is_davinci_dm646x())
> @@ -940,3 +1030,4 @@ static int __init dm646x_init_devices(void)
>  	return 0;
>  }
>  postcore_initcall(dm646x_init_devices);
> +

stray whitespace change

> diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
> index 8cec746..3c49bfa 100644
> --- a/arch/arm/mach-davinci/include/mach/dm646x.h
> +++ b/arch/arm/mach-davinci/include/mach/dm646x.h
> @@ -16,6 +16,7 @@
>  #include <mach/asp.h>
>  #include <linux/i2c.h>
>  #include <linux/videodev2.h>
> +#include <linux/usb/musb.h>
>  
>  #define DM646X_EMAC_BASE		(0x01C80000)
>  #define DM646X_EMAC_CNTRL_OFFSET	(0x0000)
> @@ -30,6 +31,8 @@ void __init dm646x_init(void);
>  void __init dm646x_init_ide(void);
>  void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
>  void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
> +extern void dm646x_usb_configure(struct musb_hdrc_platform_data *pdata,
> +					u8 num_inst);
>  
>  void dm646x_video_init(void);
>  
> diff --git a/arch/arm/mach-davinci/include/mach/usb.h b/arch/arm/mach-davinci/include/mach/usb.h
> index 96a60b1..6fb9620 100644
> --- a/arch/arm/mach-davinci/include/mach/usb.h
> +++ b/arch/arm/mach-davinci/include/mach/usb.h
> @@ -40,6 +40,9 @@
>  #define USBPHY_CTL_PADDR	(DAVINCI_SYSTEM_MODULE_BASE + 0x34)
>  #define USB_PHY_CTRL		IO_ADDRESS(USBPHY_CTL_PADDR)
>  
> +#define USBPHY_NDATAPOL		BIT(18)
> +#define USBPHY_SESSION_VBUS	BIT(17)
> +#define USBPHY_PERI_USBID	BIT(16)
>  #define USBPHY_PHYCLKGD		BIT(8)
>  #define USBPHY_SESNDEN		BIT(7)  /* v(sess_end) comparator */
>  #define USBPHY_VBDTCTEN		BIT(6)  /* v(bus) comparator */

Kevin
--
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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux