/*
 * include/linux/fsl_devices.h
 *
 * Definitions for any platform device related flags or structures for
 * Freescale processor devices
 *
 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
 *
 * Copyright 2004-2013 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#ifndef _FSL_DEVICE_H_
#define _FSL_DEVICE_H_

/*
 * Some conventions on how we handle peripherals on Freescale chips
 *
 * unique device: a platform_device entry in fsl_plat_devs[] plus
 * associated device information in its platform_data structure.
 *
 * A chip is described by a set of unique devices.
 *
 * Each sub-arch has its own master list of unique devices and
 * enumerates them by enum fsl_devices in a sub-arch specific header
 *
 * The platform data structure is broken into two parts.  The
 * first is device specific information that help identify any
 * unique features of a peripheral.  The second is any
 * information that may be defined by the board or how the device
 * is connected externally of the chip.
 *
 * naming conventions:
 * - platform data structures: <driver>_platform_data
 * - platform data device flags: FSL_<driver>_DEV_<FLAG>
 * - platform data board flags: FSL_<driver>_BRD_<FLAG>
 *
 */

enum fsl_usb2_operating_modes {
	FSL_USB2_MPH_HOST,
	FSL_USB2_DR_HOST,
	FSL_USB2_DR_DEVICE,
	FSL_USB2_DR_OTG,
};

/* this used for usb port type */
enum fsl_usb2_modes {
	FSL_USB_DR_HOST,
	FSL_USB_DR_DEVICE,
	FSL_USB_MPH_HOST1,
	FSL_USB_MPH_HOST2,
	FSL_USB_UNKNOWN, /* unkonwn status */
};

enum fsl_usb2_phy_modes {
	FSL_USB2_PHY_NONE,
	FSL_USB2_PHY_ULPI,
	FSL_USB2_PHY_UTMI,
	FSL_USB2_PHY_UTMI_WIDE,
	FSL_USB2_PHY_SERIAL,
	FSL_USB2_PHY_HSIC,
};

enum usb_wakeup_event {
	WAKEUP_EVENT_INVALID,
	WAKEUP_EVENT_VBUS,
	WAKEUP_EVENT_ID,
	WAKEUP_EVENT_DPDM, /* for remote wakeup */
};

struct clk;
struct platform_device;
struct fsl_usb2_wakeup_platform_data;

struct fsl_usb2_platform_data {
	/* board specific information */
	enum fsl_usb2_operating_modes	operating_mode;
	enum fsl_usb2_phy_modes		phy_mode;
	unsigned int			port_enables;
	unsigned int			workaround;

	int		(*init)(struct fsl_usb2_platform_data *);
	void		(*exit)(struct fsl_usb2_platform_data *);
	void __iomem	*regs;		/* ioremap'd register base */
	struct clk	*clk;
	unsigned	power_budget;	/* hcd->power_budget */
	unsigned	big_endian_mmio:1;
	unsigned	big_endian_desc:1;
	unsigned	es:1;		/* need USBMODE:ES */
	unsigned	le_setup_buf:1;
	unsigned	have_sysif_regs:1;
	unsigned	invert_drvvbus:1;
	unsigned	invert_pwr_fault:1;

	unsigned	suspended:1;
	unsigned	already_suspended:1;

	/* Freescale private */
	char		*name;
	u32		phy_regs;	/* usb phy register base */
	u32 		xcvr_type;	/* PORTSC_PTS_* */
	char 		*transceiver;	/* transceiver name */
	u32		id_gpio;

	struct fsl_xcvr_ops *xcvr_ops;
	struct fsl_xcvr_power *xcvr_pwr;
	int (*gpio_usb_active) (void);
	void (*gpio_usb_inactive) (void);
	void (*usb_clock_for_pm) (bool);
	void (*platform_suspend)(struct fsl_usb2_platform_data *);
	void (*platform_resume)(struct fsl_usb2_platform_data *);
	void (*wake_up_enable)(struct fsl_usb2_platform_data *, bool);
	void (*phy_lowpower_suspend)(struct fsl_usb2_platform_data *, bool);
	void (*platform_driver_vbus)(bool on); /* for vbus shutdown/open */
	enum usb_wakeup_event (*is_wakeup_event)(struct fsl_usb2_platform_data *);
	void (*wakeup_handler)(struct fsl_usb2_platform_data *);
	void (*hsic_post_ops)(void);
	void (*hsic_device_connected)(void);
	/*
	 * Some platforms, like i.mx6x needs to discharge dp/dm at device mode
	 * or there is wakeup interrupt caused by dp/dm change when the cable
	 * is disconnected with Host.
	 */
	void (*dr_discharge_line) (bool);
	/* only set it when vbus lower very slow during OTG switch */
	bool need_discharge_vbus;
	void (*platform_rh_suspend)(struct fsl_usb2_platform_data *);
	void (*platform_rh_resume)(struct fsl_usb2_platform_data *);
	void (*platform_set_disconnect_det)(struct fsl_usb2_platform_data *, bool);
	void (*platform_phy_power_on)(void);

	struct fsl_usb2_wakeup_platform_data *wakeup_pdata;
	unsigned	change_ahb_burst:1;
	unsigned	ahb_burst_mode:3;
	unsigned	lowpower:1;
	unsigned	irq_delay:1;
	enum usb_wakeup_event	wakeup_event;
	u32		pmflags;	/* PM from otg or system */

	void __iomem *charger_base_addr; /* used for i.mx6 usb charger detect */

	/* register save area for suspend/resume */
	u32		pm_command;
	u32		pm_status;
	u32		pm_intr_enable;
	u32		pm_frame_index;
	u32		pm_segment;
	u32		pm_frame_list;
	u32		pm_async_next;
	u32		pm_configured_flag;
	u32		pm_portsc;
	u32		pm_usbgenctrl;
};

struct fsl_usb2_wakeup_platform_data {
	char *name;
	void (*usb_clock_for_pm) (bool);
	void (*usb_wakeup_exhandle) (void);
	struct fsl_usb2_platform_data *usb_pdata[3];
	/* This flag is used to indicate the "usb_wakeup thread" is finished during
	 * usb wakeup routine.
	 */
	bool usb_wakeup_is_pending;
};

#endif /* _FSL_DEVICE_H_ */
