622 lines
14 KiB
C
Executable File
622 lines
14 KiB
C
Executable File
/*
|
|
* s2mm003.h - S2MM003 USBPD device driver header
|
|
*
|
|
* Copyright (C) 2015 Samsung Electronics
|
|
*
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
#ifndef __S2MM003_H
|
|
#define __S2MM003_H __FILE__
|
|
|
|
#include <linux/gpio.h>
|
|
#include <linux/of_gpio.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/module.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/firmware.h>
|
|
#include <linux/mutex.h>
|
|
|
|
#if defined(CONFIG_CCIC_NOTIFIER)
|
|
#include <linux/ccic/ccic_notifier.h>
|
|
#endif
|
|
|
|
#define AVAILABLE_VOLTAGE 12000
|
|
#define UNIT_FOR_VOLTAGE 50
|
|
#define UNIT_FOR_CURRENT 10
|
|
//#define CONFIG_SAMSUNG_S2MM003_SYSFS
|
|
|
|
/******************************************************************************/
|
|
/* definitions & structures */
|
|
/******************************************************************************/
|
|
#define USBPD_DEV_NAME "usbpd-s2mm003"
|
|
#define FIRMWARE_PATH "usbpd/USB_PD_FULL_DRIVER.bin"
|
|
|
|
#define OTP_ADD_LOW 0x00
|
|
#define OTP_ADD_HIGH 0x01
|
|
#define OTP_RW 0x02
|
|
#define OTP_BCHK_TEST 0x03
|
|
#define OTP_READ_DATA 0x04
|
|
#define OM 0x05
|
|
#define IF_S_CODE_E 0x05
|
|
#define MON_EN 0x06
|
|
#define BUS_IF_SELECT 0x07
|
|
#define I2C_PIN_SELECT 0x08
|
|
#define I2C_DEV_ADDR 0x09
|
|
#define I2C_DEV16_ADDR 0x0A
|
|
#define I2C_8BIT_SLV_RST 0x0B
|
|
#define OTP_BLK_RST 0x0C
|
|
#define USB_PD_RST 0x0D
|
|
#define IRQ_WR_ADDR 0x0E
|
|
#define IRQ_WR_DATA 0x0F
|
|
#define IRQ_RD_ADDR 0x10
|
|
#define IRQ_RD_DATA 0x11
|
|
#define A_TEST_MUX_SEL 0x12
|
|
#define MON0_SEL 0x13
|
|
#define MON1_SEL 0x14
|
|
#define ANALOG_00 0x15
|
|
#define ANALOG_01 0x16
|
|
#define ANALOG_02 0x17
|
|
#define ANALOG_03 0x18
|
|
#define ANALOG_04 0x19
|
|
#define ANALOG_05 0x1A
|
|
#define ANALOG_06 0x1B
|
|
#define ANALOG_07 0x1C
|
|
#define ANALOG_08 0x1D
|
|
#define ANALOG_09 0x1E
|
|
#define ANALOG_10 0x1F
|
|
#define ANALOG_11 0x20
|
|
#define EXT_VCONN_TIMER 0x21
|
|
#define OCP_CC_TIMER 0x22
|
|
#define SELECTED_EXT_NFET_EN 0x23
|
|
#define REDRVEN1_CC_SEL 0x24
|
|
#define OTP_DUMP_DISABLE 0x30
|
|
#define I2C_SYSREG_SET 0x31
|
|
#define I2C_SRAM_SET 0x32
|
|
|
|
#define INTERRUPT_CLEAR 0xFF
|
|
|
|
#define INTERRUPT_STATUS1 0x1830
|
|
#define INTERRUPT_STATUS2 0x1834
|
|
#define INTERRUPT_STATUS3 0x1838
|
|
#define INTERRUPT_STATUS4 0x183C
|
|
#define INTERRUPT_STATUS5 0x1840
|
|
|
|
#define PLUG_STATE_MONITOR 0x1850
|
|
#define RID_GET_MONITOR 0x1854
|
|
|
|
/* PLUG_STATE_MONITOR : 0x1850 */
|
|
#define S_CC1_VALID_MASK 0x07
|
|
#define S_CC1_VALID_SHIFT 0x00
|
|
#define S_CC2_VALID_MASK 0x38
|
|
#define S_CC2_VALID_SHIFT 0x03
|
|
#define PLUG_RPRD_SEL_MONITOR_MASK 0x40
|
|
#define PLUG_RPRD_SEL_MONITOR_SHIFT 0x06
|
|
#define PLUG_ATTACH_DONE_MASK 0x80
|
|
#define PLUG_ATTACH_DONE_SHIFT 0x07
|
|
|
|
/* From S.LSI */
|
|
#define IND_REG_HOST_CMD_ON 0x05
|
|
#define IND_REG_PD_FUNC_STATE 0x16
|
|
#define IND_REG_INT_NUMBER 0x17
|
|
#define IND_REG_INT_STATUS_3 0x1A
|
|
#define IND_REG_INT_STATUS_5 0x1C
|
|
#define IND_REG_READ_MSG_INDEX 0x4F
|
|
#define IND_REG_MSG_ACCESS_BASE 0x50
|
|
#define MSG_BUF_REQUEST_SIZE 0x8 // 1-Byte Length
|
|
#define MSG_REQUEST_SIZE 0x2 // 4-Byte Length
|
|
|
|
#define IND_REG_PDIC_MODE 0x13 // 2'b00:Factory 2'b01:DFP 2'b10:UFP 2'b11:DRP(Default)
|
|
#define IND_REG_PDIC_PLUG_STATE 0x15 // b7:Attach b6:RpRd_sel b5~b3:CC2(100:Ra 010:Rd 001:Rp) b2~b0:CC1(100:Ra 010:Rd 001:Rp)
|
|
#define IND_REG_PDIC_PD_FUNC_STATE 0x16
|
|
#define IND_REG_PDIC_MAIN_INT_NUM 0x17
|
|
|
|
#define IND_REG_PDIC_1_INT 0x18
|
|
#define IND_REG_PDIC_2_INT 0x19
|
|
#define IND_REG_PDIC_3_INT 0x1A
|
|
#define IND_REG_PDIC_4_INT 0x1B
|
|
#define IND_REG_PDIC_5_INT 0x1C
|
|
|
|
#define IND_REG_PDIC_RID 0x30
|
|
|
|
#define b_RESET_START (1 << 7)
|
|
#define b_Reserved (1 << 6)
|
|
#define b_PD_FUNC_FLAG (1 << 5)
|
|
#define b_INT_5_FLAG (1 << 4)
|
|
#define b_INT_4_FLAG (1 << 3)
|
|
#define b_INT_3_FLAG (1 << 2)
|
|
#define b_INT_2_FLAG (1 << 1)
|
|
#define b_INT_1_FLAG (1 << 0)
|
|
|
|
// Interrupt Status1
|
|
#define b_Cmd_Intial_State 0
|
|
#define b_Cmd_Discover_Identity 0x1
|
|
#define b_Cmd_Discover_SVIDs 0x2
|
|
#define b_Cmd_Discover_Modes 0x4
|
|
#define b_Cmd_Enter_Mode 0x8
|
|
#define b_Cmd_Exit_Mode 0x10
|
|
#define b_Cmd_Attention 0x20
|
|
#define b_Msg_GoodCRC 0x40
|
|
#define b_Msg_Accept 0x80
|
|
|
|
// Interrupt Status2
|
|
#define b_Msg_DR_SWAP 0x40
|
|
#define b_Msg_PR_SWAP 0x80
|
|
|
|
// Interrupt Status3
|
|
#define b_Msg_VCONN_SWAP 0x1
|
|
#define b_Msg_Wait 0x2
|
|
#define b_Msg_SRC_CAP 0x4
|
|
#define b_Msg_SNK_CAP 0x8
|
|
#define b_Msg_Request 0x10
|
|
#define b_msg_soft_reset 0x20
|
|
#define b_RID_Detect_done 0x40
|
|
|
|
// Function Status
|
|
#define FUNCTION_STATUS_INITIAL_DETACH 0
|
|
#define FUNCTION_STATUS_SRC_SEND_CAPABILITY 3
|
|
#define FUNCTION_STATUS_SRC_READY 6
|
|
#define FUNCTION_STATUS_SRC_TIMEOUT 7
|
|
#define FUNCTION_STATUS_SINK_DISCOVERY 17
|
|
#define FUNCTION_STATUS_SINK_READY 21
|
|
#define FUNCTION_STATUS_SINK_TIMEOUT 29
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint16_t Message_Type:4,
|
|
Rsvd2_msg_header:1,
|
|
Port_Data_Role:1,
|
|
Specification_Revision:2,
|
|
Port_Power_Role:1,
|
|
Message_ID:3,
|
|
Number_of_obj:3,
|
|
Rsvd_msg_header:1;
|
|
}BITS;
|
|
} U_MSG_HEADER_Type;
|
|
|
|
/* for alternate mode */
|
|
#if defined(CONFIG_CCIC_ALTERNATE_MODE)
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t VDM_command:5,
|
|
Rsvd2_VDM_header:1,
|
|
VDM_command_type:2,
|
|
Object_Position:3,
|
|
Rsvd_VDM_header:2,
|
|
Structured_VDM_Version:2,
|
|
VDM_Type:1,
|
|
Standard_Vendor_ID:16;
|
|
}BITS;
|
|
}U_DATA_MSG_VDM_HEADER_Type;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t USB_Vendor_ID:16,
|
|
Rsvd_ID_header:10,
|
|
Modal_Operation_Supported:1,
|
|
Product_Type:3,
|
|
Data_Capable_USB_Device:1,
|
|
Data_Capable_USB_Host:1;
|
|
}BITS;
|
|
}U_DATA_MSG_ID_HEADER_Type;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t Cert_TID:20,
|
|
Rsvd_cert_VDOer:12;
|
|
}BITS;
|
|
}U_CERT_STAT_VDO_Type;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t Device_Version:16,
|
|
Product_ID:16;
|
|
}BITS;
|
|
}U_PRODUCT_VDO_Type;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t USB_Superspeed_Signaling_Support:3,
|
|
SOP_contoller_present:1,
|
|
Vbus_through_cable:1,
|
|
Vbus_Current_Handling_Capability:2,
|
|
SSRX2_Directionality_Support:1,
|
|
SSRX1_Directionality_Support:1,
|
|
SSTX2_Directionality_Support:1,
|
|
SSTX1_Directionality_Support:1,
|
|
Cable_Termination_Type:2,
|
|
Cable_Latency:4,
|
|
TypeC_to_Plug_Receptacle:1,
|
|
TypeC_to_ABC:2,
|
|
Rsvd_CABLE_VDO:4,
|
|
Cable_Firmware_Version:4,
|
|
Cable_HW_Version:4;
|
|
}BITS;
|
|
}U_CABLE_VDO_Type;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
struct
|
|
{
|
|
uint32_t SVID_0:16,
|
|
SVID_1:16;
|
|
}BITS;
|
|
}U_VDO1_Type;
|
|
#endif
|
|
typedef enum
|
|
{
|
|
// PDO Message
|
|
MSG_Idx_TX_SRC_CAPA = 1,
|
|
MSG_Idx_TX_SINK_CAPA = 2,
|
|
MSG_Idx_TX_REQUEST = 3,
|
|
|
|
MSG_Idx_RX_SRC_CAPA = 4,
|
|
MSG_Idx_RX_SINK_CAPA = 5,
|
|
MSG_Idx_RX_REQUEST = 6,
|
|
|
|
// VDM User Message
|
|
MSG_Idx_VDM_MSG_REQUEST = 9,
|
|
MSG_Idx_CTRL_MSG = 10,
|
|
|
|
// VDM TX Message
|
|
MSG_Idx_TX_DISC_ID_RESP = 17,
|
|
MSG_Idx_TX_DISC_SVIDs_RESP = 18,
|
|
MSG_Idx_TX_DISC_MODE_RESP = 19,
|
|
MSG_Idx_TX_DISC_ENTER_MODE_RESP = 20,
|
|
MSG_Idx_TX_DISC_EXIT_MODE_RESP = 21,
|
|
MSG_Idx_TX_DISC_ATTENTION_RESP = 22,
|
|
|
|
// VDM RX Message
|
|
MSG_Idx_RX_DISC_ID_CABLE = 25,
|
|
MSG_Idx_RX_DISC_ID_RESP = 26,
|
|
MSG_Idx_RX_DISC_SVIDs_RESP = 27,
|
|
MSG_Idx_RX_DISC_MODE_RESP = 28,
|
|
MSG_Idx_RX_DISC_ENTER_MODE_RESP = 29,
|
|
MSG_Idx_RX_DISC_EXIT_MODE_RESP = 30,
|
|
MSG_Idx_RX_DISC_ATTENTION_RESP = 31
|
|
|
|
} Num_MSG_INDEX;
|
|
|
|
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
|
|
typedef enum
|
|
{
|
|
TYPE_C_DETACH = 0,
|
|
TYPE_C_ATTACH_DFP = 1, // Host
|
|
TYPE_C_ATTACH_UFP = 2, // Device
|
|
TYPE_C_ATTACH_DRP = 3, // Dual role
|
|
} CCIC_OTP_MODE;
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
uint16_t Message_Type:4;
|
|
uint16_t Rsvd2_msg_header:1;
|
|
uint16_t Port_Data_Role:1;
|
|
uint16_t Specification_Revision:2;
|
|
uint16_t Port_Power_Role:1;
|
|
uint16_t Message_ID:3;
|
|
uint16_t Number_of_obj:3;
|
|
uint16_t Rsvd_msg_header:1;
|
|
} MSG_HEADER_Type;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t Maximum_Allow_Power:10;
|
|
uint32_t Minimum_Voltage:10;
|
|
uint32_t Maximum_Voltage:10;
|
|
uint32_t PDO_Parameter:2;
|
|
} SRC_BAT_SUPPLY_Typedef;
|
|
|
|
// ================== Capabilities Message ==============
|
|
// Source Capabilities
|
|
typedef struct
|
|
{
|
|
uint32_t Maximum_Current:10;
|
|
uint32_t Voltage_Unit:10;
|
|
uint32_t Peak_Current:2;
|
|
uint32_t Reserved:3;
|
|
uint32_t Data_Role_Swap:1;
|
|
uint32_t USB_Comm_Capable:1;
|
|
uint32_t Externally_POW:1;
|
|
uint32_t USB_Suspend_Support:1;
|
|
uint32_t Dual_Role_Power:1;
|
|
uint32_t PDO_Parameter:2;
|
|
}SRC_FIXED_SUPPLY_Typedef;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t Maximum_Current:10;
|
|
uint32_t Minimum_Voltage:10;
|
|
uint32_t Maximum_Voltage:10;
|
|
uint32_t PDO_Parameter:2;
|
|
}SRC_VAR_SUPPLY_Typedef;
|
|
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Maximum_Current:10,
|
|
Voltage_Unit:10,
|
|
Peak_Current:2,
|
|
Reserved:3,
|
|
Data_Role_Swap:1,
|
|
USB_Comm_Capable:1,
|
|
Externally_POW:1,
|
|
USB_Suspend_Support:1,
|
|
Dual_Role_Power:1,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SRC_FIXED_SUPPLY_Typedef;
|
|
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Maximum_Current:10,
|
|
Minimum_Voltage:10,
|
|
Maximum_Voltage:10,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SRC_VAR_SUPPLY_Typedef;
|
|
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Maximum_Allow_Power:10,
|
|
Minimum_Voltage:10,
|
|
Maximum_Voltage:10,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SRC_BAT_SUPPLY_Typedef;
|
|
|
|
|
|
// Sink Capabilities
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Maximum_Current:10,
|
|
Voltage_Unit:10,
|
|
Peak_Current:2,
|
|
Reserved:3,
|
|
Data_Role_Swap:1,
|
|
USB_Comm_Capable:1,
|
|
Externally_POW:1,
|
|
Higher_Capability:1,
|
|
Dual_Role_Power:1,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SINK_FIXED_SUPPLY_Typedef;
|
|
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Operational_Current:10,
|
|
Minimum_Voltage:10,
|
|
Maximum_Voltage:10,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SINK_VAR_SUPPLY_Typedef;
|
|
|
|
|
|
typedef union
|
|
{
|
|
uint16_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[2];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Operational_Power:10,
|
|
Minimum_Voltage:10,
|
|
Maximum_Voltage:10,
|
|
PDO_Parameter:2;
|
|
}BITS;
|
|
} U_SINK_BAT_SUPPLY_Typedef;
|
|
|
|
// ================== Request Message ================
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t Maximum_OP_Current:10; // 10mA
|
|
uint32_t OP_Current:10; // 10mA
|
|
uint32_t Reserved_1:4; // Set to Zero
|
|
uint32_t No_USB_Suspend:1;
|
|
uint32_t USB_Comm_Capable:1;
|
|
uint32_t Capa_Mismatch:1;
|
|
uint32_t GiveBack_Flag:1; // GiveBack Support set to 1
|
|
uint32_t Object_Position:3; // 000 is reserved
|
|
uint32_t Reserved_2:1;
|
|
} REQUEST_FIXED_SUPPLY_STRUCT_Typedef;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t DATA;
|
|
|
|
struct
|
|
{
|
|
uint8_t BDATA[4];
|
|
}BYTES;
|
|
|
|
struct
|
|
{
|
|
uint32_t Minimum_OP_Current:10, // 10mA
|
|
OP_Current:10, // 10mA
|
|
Reserved_1:4, // Set to Zero
|
|
No_USB_Suspend:1,
|
|
USB_Comm_Capable:1,
|
|
Capa_Mismatch:1,
|
|
GiveBack_Flag:1, // GiveBack Support set to 1
|
|
Object_Position:3, // 000 is reserved
|
|
Reserved_2:1;
|
|
}BITS;
|
|
}U_REQUEST_FIXED_SUPPLY_STRUCT_Typedef;
|
|
|
|
#define S2MM003_REG_MASK(reg, mask) ((reg & mask##_MASK) >> mask##_SHIFT)
|
|
|
|
|
|
#if defined(CONFIG_SAMSUNG_S2MM003_SYSFS)
|
|
static ssize_t s2mm003_register_show(struct device *dev,
|
|
struct device_attribute *att, char *buf);
|
|
|
|
static DEVICE_ATTR(s2mm003_register, S_IRUGO, s2mm003_register_show, NULL);
|
|
#endif
|
|
|
|
struct s2mm003_data {
|
|
struct device *dev;
|
|
struct i2c_client *i2c;
|
|
int irq_gpio;
|
|
int redriver_en;
|
|
struct mutex i2c_mutex;
|
|
u8 attach;
|
|
u8 vbus_detach;
|
|
|
|
int wq_times;
|
|
int p_prev_rid;
|
|
int prev_rid;
|
|
int cur_rid;
|
|
|
|
u8 firm_ver[4];
|
|
|
|
int func_state;
|
|
|
|
int plug_rprd_sel;
|
|
uint32_t Pdic_usb_state;
|
|
#if defined(CONFIG_CCIC_ALTERNATE_MODE)
|
|
uint32_t Pdic_state_machine;
|
|
uint32_t SVID_0;
|
|
uint32_t SVID_1;
|
|
uint32_t Vendor_ID;
|
|
uint32_t Product_ID;
|
|
int acc_type;
|
|
#endif
|
|
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
|
|
struct dual_role_phy_instance *dual_role;
|
|
struct dual_role_phy_desc *desc;
|
|
struct completion reverse_completion;
|
|
int power_role;
|
|
int try_state_change;
|
|
#endif
|
|
};
|
|
|
|
#define DUAL_ROLE_SET_MODE_WAIT_MS 1500
|
|
|
|
enum S2MM003_POWER {
|
|
S2MM003_CPU_RESET,
|
|
S2MM003_FULL_RESET,
|
|
S2MM003_START,
|
|
};
|
|
|
|
//int irq_times;
|
|
//int wq_times;
|
|
//int p_prev_rid = -1;
|
|
//int prev_rid = -1;
|
|
//int cur_rid = -1;
|
|
#endif /* __S2MM003_H */
|