📄 twl4030_usb.c
字号:
/* * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller * * Copyright (C) 2004-2007 Texas Instruments * * FS USB suport is based heavily on the isp1301_omap.c OTG transceiver driver. * Copyright (C) 2004 David Brownell * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Current status: * - FS USB Gadget and Host modes work independently. No OTG support. * - HS USB ULPI mode works. */#include <linux/module.h>#include <linux/kernel_stat.h>#include <linux/init.h>#include <linux/time.h>#include <linux/interrupt.h>#include <linux/i2c.h>#include <linux/slab.h>#include <linux/device.h>#include <linux/usb/ch9.h>#include <linux/usb_gadget.h>#include <linux/usb.h>#include <linux/usb/otg.h>#include <asm/arch/twl4030.h>#include <asm/arch/usb.h>#include <asm/arch/irqs.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/arch/mux.h>#include <asm/arch/io.h>#include <asm/arch/hardware.h>#include <asm/arch/clock.h>#include <asm/arch/resource.h>/* Register defines */#define VENDOR_ID_LO (0x00)#define VENDOR_ID_HI (0x01)#define PRODUCT_ID_LO (0x02)#define PRODUCT_ID_HI (0x03)#define FUNC_CTRL (0x04)#define FUNC_CTRL_SET (0x05)#define FUNC_CTRL_CLR (0x06)# define SUSPENDM (1 << 6)# define RESET (1 << 5)# define OPMODE_MASK (3 << 3) /* bits 3 and 4 */# define OPMODE_NORMAL (0 << 3)# define OPMODE_NONDRIVING (1 << 3)# define OPMODE_DISABLE_BIT_NRZI (2 << 3)# define TERMSELECT (1 << 2)# define XCVRSELECT_MASK (3 << 0) /* bits 0 and 1 */# define XCVRSELECT_HS (0 << 0)# define XCVRSELECT_FS (1 << 0)# define XCVRSELECT_LS (2 << 0)# define XCVRSELECT_FS4LS (3 << 0)#define IFC_CTRL (0x07)#define IFC_CTRL_SET (0x08)#define IFC_CTRL_CLR (0x09)# define INTERFACE_PROTECT_DISABLE (1 << 7)# define AUTORESUME (1 << 4)# define CLOCKSUSPENDM (1 << 3)# define CARKITMODE (1 << 2)# define FSLSSERIALMODE_3PIN (1 << 1)#define OTG_CTRL (0x0A)#define OTG_CTRL_SET (0x0B)#define OTG_CTRL_CLR (0x0C)# define DRVVBUS (1 << 5)# define CHRGVBUS (1 << 4)# define DISCHRGVBUS (1 << 3)# define DMPULLDOWN (1 << 2)# define DPPULLDOWN (1 << 1)# define IDPULLUP (1 << 0)#define USB_INT_EN_RISE (0x0D)#define USB_INT_EN_RISE_SET (0x0E)#define USB_INT_EN_RISE_CLR (0x0F)#define USB_INT_EN_FALL (0x10)#define USB_INT_EN_FALL_SET (0x11)#define USB_INT_EN_FALL_CLR (0x12)#define USB_INT_STS (0x13)#define USB_INT_LATCH (0x14)# define IDGND (1 << 4)# define SESSEND (1 << 3)# define SESSVALID (1 << 2)# define VBUSVALID (1 << 1)# define HOSTDISCONNECT (1 << 0)#define CARKIT_CTRL (0x19)#define CARKIT_CTRL_SET (0x1A)#define CARKIT_CTRL_CLR (0x1B)#define MICEN (1 << 6)#define SPKRIGHTEN (1 << 5)#define SPKLEFTEN (1 << 4)#define RXDEN (1 << 3)#define TXDEN (1 << 2)#define IDGNDDRV (1 << 1)#define CARKITPWR (1 << 0)#define CARKIT_PLS_CTRL (0x22)#define CARKIT_PLS_CTRL_SET (0x23)#define CARKIT_PLS_CTRL_CLR (0x24)# define SPKRRIGHT_BIASEN (1 << 3)# define SPKRLEFT_BIASEN (1 << 2)# define RXPLSEN (1 << 1)# define TXPLSEN (1 << 0)#define MCPC_CTRL (0x30)#define MCPC_CTRL_SET (0x31)#define MCPC_CTRL_CLR (0x32)#define RTSOL (1 << 7)#define EXTSWR (1 << 6)#define EXTSWC (1 << 5)#define VOICESW (1 << 4)#define OUT64K (1 << 3)#define RTSCTSSW (1 << 2)#define HS_UART (1 << 0)#define MCPC_IO_CTRL (0x33)#define MCPC_IO_CTRL_SET (0x34)#define MCPC_IO_CTRL_CLR (0x35)# define MICBIASEN (1<< 5)# define CTS_NPU (1 << 4)# define RXD_PU (1 << 3)# define TXDTYP (1 << 2)# define CTSTYP (1 << 1)# define RTSTYP (1 << 0)#define MCPC_CTRL2 (0x36)#define MCPC_CTRL2_SET (0x37)#define MCPC_CTRL2_CLR (0x38)# define MCPC_CK_EN (1 << 0)#define OTHER_FUNC_CTRL (0x80)#define OTHER_FUNC_CTRL_SET (0x81)#define OTHER_FUNC_CTRL_CLR (0x82)# define BDIS_ACON_EN (1<< 4)# define FIVEWIRE_MODE (1 << 2)#define OTHER_IFC_CTRL (0x83)#define OTHER_IFC_CTRL_SET (0x84)#define OTHER_IFC_CTRL_CLR (0x85)# define OE_INT_EN (1 << 6)# define CEA2011_MODE (1 << 5)# define FSLSSERIALMODE_4PIN (1 << 4)# define HIZ_ULPI_60MHZ_OUT (1 << 3)# define HIZ_ULPI (1 << 2)# define ALT_INT_REROUTE (1 << 0)#define OTHER_INT_EN_RISE (0x86)#define OTHER_INT_EN_RISE_SET (0x87)#define OTHER_INT_EN_RISE_CLR (0x88)#define OTHER_INT_EN_FALL (0x89)#define OTHER_INT_EN_FALL_SET (0x8A)#define OTHER_INT_EN_FALL_CLR (0x8B)#define OTHER_INT_STS (0x8C)#define OTHER_INT_LATCH (0x8D)# define VB_SESS_VLD (1 << 7)# define DM_HI (1 << 6) /* not valid for "latch" reg */# define DP_HI (1 << 5) /* not valid for "latch" reg */# define BDIS_ACON (1 << 3) /* not valid for "fall" regs */# define MANU (1 << 1)# define ABNORMAL_STRESS (1 << 0)#define ID_STATUS (0x96)# define ID_RES_FLOAT (1 << 4)# define ID_RES_440K (1 << 3)# define ID_RES_200K (1 << 2)# define ID_RES_102K (1 << 1)# define ID_RES_GND (1 << 0)#define POWER_CTRL (0xAC)#define POWER_CTRL_SET (0xAD)#define POWER_CTRL_CLR (0xAE)# define OTG_ENAB (1 << 5)#define OTHER_IFC_CTRL2 (0xAF)#define OTHER_IFC_CTRL2_SET (0xB0)#define OTHER_IFC_CTRL2_CLR (0xB1)# define ULPI_STP_LOW (1 << 4)# define ULPI_TXEN_POL (1 << 3)# define ULPI_4PIN_2430 (1 << 2)# define USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */# define USB_INT_OUTSEL_INT1N (0 << 0)# define USB_INT_OUTSEL_INT2N (1 << 0)#define REG_CTRL_EN (0xB2)#define REG_CTRL_EN_SET (0xB3)#define REG_CTRL_EN_CLR (0xB4)#define REG_CTRL_ERROR (0xB5)# define ULPI_I2C_CONFLICT_INTEN (1 << 0)#define OTHER_FUNC_CTRL2 (0xB8)#define OTHER_FUNC_CTRL2_SET (0xB9)#define OTHER_FUNC_CTRL2_CLR (0xBA)# define VBAT_TIMER_EN (1 << 0)/* following registers do not have separate _clr and _set registers */#define VBUS_DEBOUNCE (0xC0)#define ID_DEBOUNCE (0xC1)#define VBAT_TIMER (0xD3)#define PHY_PWR_CTRL (0xFD)# define PHYPWD (1 << 0)#define PHY_CLK_CTRL (0xFE)# define CLOCKGATING_EN (1 << 2)# define CLK32K_EN (1 << 1)# define REQ_PHY_DPLL_CLK (1 << 0)#define PHY_CLK_CTRL_STS (0xFF)# define PHY_DPLL_CLK (1 << 0)/* In module TWL4030_MODULE_PM_MASTER */#define PROTECT_KEY (0x0E)/* In module TWL4030_MODULE_PM_RECIEVER */#define VUSB_DEDICATED1 (0x7D)#define VUSB_DEDICATED2 (0x7E)#define VUSB1V5_DEV_GRP (0x71)#define VUSB1V5_TYPE (0x72)#define VUSB1V5_REMAP (0x73)#define VUSB1V8_DEV_GRP (0x74)#define VUSB1V8_TYPE (0x75)#define VUSB1V8_REMAP (0x76)#define VUSB3V1_DEV_GRP (0x77)#define VUSB3V1_TYPE (0x78)#define VUSB3V1_REMAP (0x79)#define ID_STATUS (0x96)#define ID_RES_FLOAT (1 << 4) /* mini-B */#define ID_RES_440K (1 << 3) /* type 2 charger */#define ID_RES_200K (1 << 2) /* 5-wire carkit or type 1 charger */#define ID_RES_102K (1 << 1) /* phone */#define ID_RES_GND (1 << 0) /* mini-A *//* In module TWL4030_MODULE_INTBR */#define PMBR1 (0x0D)# define GPIO_USB_4PIN_ULPI_2430C (3 << 0)/* In module TWL4030_MODULE_INT */#define REG_PWR_ISR1 (0x00)#define REG_PWR_IMR1 (0x01)#define USB_PRES (1 << 2)#define REG_PWR_EDR1 (0x05)#define USB_PRES_FALLING (1 << 4)#define USB_PRES_RISING (1 << 5)#define REG_PWR_SIH_CTRL (0x07)# define COR (1 << 2)/*-------------------------------------------------------------------------*/#define twl4030_i2c_read_u8_verify(module, data, address) \do { \ if (twl4030_i2c_read_u8(module, data, address) < 0) { \ printk(KERN_ERR "twl4030_usb: i2c read failed, \ line %d\n", __LINE__); \ goto i2c_failed; \ } \} while (0)#define twl4030_i2c_write_u8_verify(module, data, address) \do { \ u8 check; \ if (!((twl4030_i2c_write_u8((module), (data), (address)) >= 0) && \ (twl4030_i2c_read_u8((module), &check, (address)) >= 0) && \ (check == data)) && \ !((twl4030_i2c_write_u8((module), (data), (address)) >= 0) && \ (twl4030_i2c_read_u8((module), &check, (address)) >= 0) && \ (check == (data)))) { \ printk(KERN_ERR "twl4030_usb: i2c write failed, \ line %d\n", __LINE__); \ goto i2c_failed; \ } \} while (0)#define twl4030_usb_write_verify(address, data) \ twl4030_i2c_write_u8_verify(TWL4030_MODULE_USB, (data), (address))static inline int twl4030_usb_write(u8 address, u8 data){ int ret = 0; ret = twl4030_i2c_write_u8(TWL4030_MODULE_USB, data, address); if (ret >= 0) { } else { printk(KERN_WARNING "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); } return ret;}static inline int twl4030_usb_read(u8 address){ u8 data; int ret = 0; ret = twl4030_i2c_read_u8(TWL4030_MODULE_USB, &data, address); if (ret >= 0) { ret = data; } else { printk(KERN_WARNING "TWL4030:USB:Read[0x%x] Error %d\n", address, ret); } return ret;}/*-------------------------------------------------------------------------*/struct twl4030_usb { struct otg_transceiver otg; int irq; u8 usb_mode; /* pin configuration */# define T2_USB_MODE_ULPI 1# define T2_USB_MODE_CEA2011_3PIN 2 u8 asleep; struct constraint_handle *usb_power_constraint;};static struct constraint_id cnstr_id = { .type = RES_LATENCY_CO, .data = (void *)"latency",};static struct twl4030_usb *the_transceiver;/*-------------------------------------------------------------------------*/static inline inttwl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits){ return twl4030_usb_write(reg + 1, bits);}static inline inttwl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits){ return twl4030_usb_write(reg + 2, bits);}/*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/static void twl4030_cea2011_3_pin_FS_setup(struct twl4030_usb *twl){ u8 pmbr1; /* Important! - choose bet GPIO or USB */ twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &pmbr1, PMBR1); twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, pmbr1 | GPIO_USB_4PIN_ULPI_2430C, PMBR1); /* Mux between UART and USB ULPI lines */ twl4030_usb_clear_bits(twl, MCPC_CTRL2, MCPC_CK_EN); twl4030_usb_clear_bits(twl, CARKIT_CTRL, CARKITPWR | TXDEN | RXDEN | SPKLEFTEN | MICEN); twl4030_usb_clear_bits(twl, CARKIT_PLS_CTRL, TXPLSEN | RXPLSEN |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -