Add samsung specific changes

This commit is contained in:
2025-08-11 14:29:00 +02:00
parent c66122e619
commit 4d134a1294
2688 changed files with 1127995 additions and 11475 deletions

View File

@@ -0,0 +1,107 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2011, 2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_USB_CCID_DESC_H
#define __LINUX_USB_CCID_DESC_H
#include <linux/types.h>
/*CCID specification version 1.10*/
#define CCID1_10 0x0110
#define SMART_CARD_DEVICE_CLASS 0x0B
/* Smart Card Device Class Descriptor Type */
#define CCID_DECRIPTOR_TYPE 0x21
/* Table 5.3-1 Summary of CCID Class Specific Request */
#define CCIDGENERICREQ_ABORT 0x01
#define CCIDGENERICREQ_GET_CLOCK_FREQUENCIES 0x02
#define CCIDGENERICREQ_GET_DATA_RATES 0x03
/* 6.1 Command Pipe, Bulk-OUT Messages */
#define PC_TO_RDR_ICCPOWERON 0x62
#define PC_TO_RDR_ICCPOWEROFF 0x63
#define PC_TO_RDR_GETSLOTSTATUS 0x65
#define PC_TO_RDR_XFRBLOCK 0x6F
#define PC_TO_RDR_GETPARAMETERS 0x6C
#define PC_TO_RDR_RESETPARAMETERS 0x6D
#define PC_TO_RDR_SETPARAMETERS 0x61
#define PC_TO_RDR_ESCAPE 0x6B
#define PC_TO_RDR_ICCCLOCK 0x6E
#define PC_TO_RDR_T0APDU 0x6A
#define PC_TO_RDR_SECURE 0x69
#define PC_TO_RDR_MECHANICAL 0x71
#define PC_TO_RDR_ABORT 0x72
#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73
/* 6.2 Response Pipe, Bulk-IN Messages */
#define RDR_TO_PC_DATABLOCK 0x80
#define RDR_TO_PC_SLOTSTATUS 0x81
#define RDR_TO_PC_PARAMETERS 0x82
#define RDR_TO_PC_ESCAPE 0x83
#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84
/* 6.3 Interrupt-IN Messages */
#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50
#define RDR_TO_PC_HARDWAREERROR 0x51
/* Table 6.2-2 Slot error register when bmCommandStatus = 1 */
#define CMD_ABORTED 0xFF
#define ICC_MUTE 0xFE
#define XFR_PARITY_ERROR 0xFD
#define XFR_OVERRUN 0xFC
#define HW_ERROR 0xFB
#define BAD_ATR_TS 0xF8
#define BAD_ATR_TCK 0xF7
#define ICC_PROTOCOL_NOT_SUPPORTED 0xF6
#define ICC_CLASS_NOT_SUPPORTED 0xF5
#define PROCEDURE_BYTE_CONFLICT 0xF4
#define DEACTIVATED_PROTOCOL 0xF3
#define BUSY_WITH_AUTO_SEQUENCE 0xF2
#define PIN_TIMEOUT 0xF0
#define PIN_CANCELLED 0xEF
#define CMD_SLOT_BUSY 0xE0
/* CCID rev 1.1, p.27 */
#define VOLTS_AUTO 0x00
#define VOLTS_5_0 0x01
#define VOLTS_3_0 0x02
#define VOLTS_1_8 0x03
/* 6.3.1 RDR_to_PC_NotifySlotChange */
#define ICC_NOT_PRESENT 0x00
#define ICC_PRESENT 0x01
#define ICC_CHANGE 0x02
#define ICC_INSERTED_EVENT (ICC_PRESENT+ICC_CHANGE)
/* Identifies the length of type of subordinate descriptors of a CCID device
* Table 5.1-1 Smart Card Device Class descriptors
*/
struct usb_ccid_class_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdCCID;
__u8 bMaxSlotIndex;
__u8 bVoltageSupport;
__u32 dwProtocols;
__u32 dwDefaultClock;
__u32 dwMaximumClock;
__u8 bNumClockSupported;
__u32 dwDataRate;
__u32 dwMaxDataRate;
__u8 bNumDataRatesSupported;
__u32 dwMaxIFSD;
__u32 dwSynchProtocols;
__u32 dwMechanical;
__u32 dwFeatures;
__u32 dwMaxCCIDMessageLength;
__u8 bClassGetResponse;
__u8 bClassEnvelope;
__u16 wLcdLayout;
__u8 bPINSupport;
__u8 bMaxCCIDBusySlots;
} __packed;
#endif

View File

@@ -0,0 +1,336 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_USB_DWC3_MSM_H
#define __LINUX_USB_DWC3_MSM_H
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <linux/usb/gadget.h>
/* used for struct usb_phy flags */
#define PHY_HOST_MODE BIT(0)
#define DEVICE_IN_SS_MODE BIT(1)
#define PHY_LANE_A BIT(2)
#define PHY_LANE_B BIT(3)
#define PHY_HSFS_MODE BIT(4)
#define PHY_LS_MODE BIT(5)
#define EUD_SPOOF_DISCONNECT BIT(6)
#define EUD_SPOOF_CONNECT BIT(7)
#define PHY_SUS_OVERRIDE BIT(8)
#define PHY_DP_MODE BIT(9)
#define PHY_USB_DP_CONCURRENT_MODE BIT(10)
/*
* The following are bit fields describing the USB BAM options.
* These bit fields are set by function drivers that wish to queue
* usb_requests with sps/bam parameters.
*/
#define MSM_TX_PIPE_ID_OFS (16)
#define MSM_SPS_MODE BIT(5)
#define MSM_IS_FINITE_TRANSFER BIT(6)
#define MSM_PRODUCER BIT(7)
#define MSM_DISABLE_WB BIT(8)
#define MSM_ETD_IOC BIT(9)
#define MSM_INTERNAL_MEM BIT(10)
#define MSM_VENDOR_ID BIT(16)
/* EBC TRB parameters */
#define EBC_TRB_SIZE 16384
/* Operations codes for GSI enabled EPs */
enum gsi_ep_op {
GSI_EP_OP_CONFIG = 0,
GSI_EP_OP_STARTXFER,
GSI_EP_OP_STORE_DBL_INFO,
GSI_EP_OP_ENABLE_GSI,
GSI_EP_OP_UPDATEXFER,
GSI_EP_OP_RING_DB,
GSI_EP_OP_ENDXFER,
GSI_EP_OP_GET_CH_INFO,
GSI_EP_OP_GET_XFER_IDX,
GSI_EP_OP_PREPARE_TRBS,
GSI_EP_OP_FREE_TRBS,
GSI_EP_OP_SET_CLR_BLOCK_DBL,
GSI_EP_OP_CHECK_FOR_SUSPEND,
GSI_EP_OP_DISABLE,
};
enum usb_hw_ep_mode {
USB_EP_NONE,
USB_EP_BAM,
USB_EP_GSI,
USB_EP_EBC,
};
enum dwc3_notify_event {
DWC3_CONTROLLER_ERROR_EVENT,
DWC3_CONTROLLER_RESET_EVENT,
DWC3_CONTROLLER_POST_RESET_EVENT,
DWC3_CORE_PM_SUSPEND_EVENT,
DWC3_CORE_PM_RESUME_EVENT,
DWC3_CONTROLLER_CONNDONE_EVENT,
DWC3_CONTROLLER_NOTIFY_OTG_EVENT,
DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER,
DWC3_CONTROLLER_PULLUP_ENTER,
DWC3_CONTROLLER_PULLUP_EXIT,
/* USB GSI event buffer related notification */
DWC3_GSI_EVT_BUF_ALLOC,
DWC3_GSI_EVT_BUF_SETUP,
DWC3_GSI_EVT_BUF_CLEANUP,
DWC3_GSI_EVT_BUF_CLEAR,
DWC3_GSI_EVT_BUF_FREE,
DWC3_CONTROLLER_NOTIFY_CLEAR_DB,
DWC3_IMEM_UPDATE_PID,
};
/*
* @buf_base_addr: Base pointer to buffer allocated for each GSI enabled EP.
* TRBs point to buffers that are split from this pool. The size of the
* buffer is num_bufs times buf_len. num_bufs and buf_len are determined
based on desired performance and aggregation size.
* @dma: DMA address corresponding to buf_base_addr.
* @num_bufs: Number of buffers associated with the GSI enabled EP. This
* corresponds to the number of non-zlp TRBs allocated for the EP.
* The value is determined based on desired performance for the EP.
* @buf_len: Size of each individual buffer is determined based on aggregation
* negotiated as per the protocol. In case of no aggregation supported by
* the protocol, we use default values.
* @db_reg_phs_addr_lsb: IPA channel doorbell register's physical address LSB
* @mapped_db_reg_phs_addr_lsb: doorbell LSB IOVA address mapped with IOMMU
* @db_reg_phs_addr_msb: IPA channel doorbell register's physical address MSB
* @ep_intr_num: Interrupter number for EP.
*/
struct usb_gsi_request {
void *buf_base_addr;
dma_addr_t dma;
size_t num_bufs;
size_t buf_len;
u32 db_reg_phs_addr_lsb;
dma_addr_t mapped_db_reg_phs_addr_lsb;
u32 db_reg_phs_addr_msb;
u8 ep_intr_num;
struct sg_table sgt_trb_xfer_ring;
struct sg_table sgt_data_buff;
};
/*
* @last_trb_addr: Address (LSB - based on alignment restrictions) of
* last TRB in queue. Used to identify rollover case.
* @const_buffer_size: TRB buffer size in KB (similar to IPA aggregation
* configuration). Must be aligned to Max USB Packet Size.
* Should be 1 <= const_buffer_size <= 31.
* @depcmd_low_addr: Used by GSI hardware to write "Update Transfer" cmd
* @depcmd_hi_addr: Used to write "Update Transfer" command.
* @gevntcount_low_addr: GEVNCOUNT low address for GSI hardware to read and
* clear processed events.
* @gevntcount_hi_addr: GEVNCOUNT high address.
* @xfer_ring_len: length of transfer ring in bytes (must be integral
* multiple of TRB size - 16B for xDCI).
* @xfer_ring_base_addr: physical base address of transfer ring. Address must
* be aligned to xfer_ring_len rounded to power of two.
* @ch_req: Used to pass request specific info for certain operations on GSI EP
*/
struct gsi_channel_info {
u16 last_trb_addr;
u8 const_buffer_size;
u32 depcmd_low_addr;
u8 depcmd_hi_addr;
u32 gevntcount_low_addr;
u8 gevntcount_hi_addr;
u16 xfer_ring_len;
u64 xfer_ring_base_addr;
struct usb_gsi_request *ch_req;
};
struct dwc3;
extern void *dwc_trace_ipc_log_ctxt;
/**
* usb_gadget_autopm_get - increment PM-usage counter of usb gadget's parent
* device.
* @gadget: usb gadget whose parent device counter is incremented
*
* This routine should be called by function driver when it wants to use
* gadget's parent device and needs to guarantee that it is not suspended. In
* addition, the routine prevents subsequent autosuspends of gadget's parent
* device. However if the autoresume fails then the counter is re-decremented.
*
* This routine can run only in process context.
*/
static inline int usb_gadget_autopm_get(struct usb_gadget *gadget)
{
int status = -ENODEV;
if (!gadget || !gadget->dev.parent)
return status;
status = pm_runtime_get_sync(gadget->dev.parent);
if (status < 0)
pm_runtime_put_sync(gadget->dev.parent);
if (status > 0)
status = 0;
return status;
}
/**
* usb_gadget_autopm_get_async - increment PM-usage counter of usb gadget's
* parent device.
* @gadget: usb gadget whose parent device counter is incremented
*
* This routine increments @gadget parent device PM usage counter and queue an
* autoresume request if the device is suspended. It does not autoresume device
* directly (it only queues a request). After a successful call, the device may
* not yet be resumed.
*
* This routine can run in atomic context.
*/
static inline int usb_gadget_autopm_get_async(struct usb_gadget *gadget)
{
int status = -ENODEV;
if (!gadget || !gadget->dev.parent)
return status;
status = pm_runtime_get(gadget->dev.parent);
if (status < 0 && status != -EINPROGRESS)
pm_runtime_put_noidle(gadget->dev.parent);
if (status > 0 || status == -EINPROGRESS)
status = 0;
return status;
}
/**
* usb_gadget_autopm_get_noresume - increment PM-usage counter of usb gadget's
* parent device.
* @gadget: usb gadget whose parent device counter is incremented
*
* This routine increments PM-usage count of @gadget parent device but does not
* carry out an autoresume.
*
* This routine can run in atomic context.
*/
static inline void usb_gadget_autopm_get_noresume(struct usb_gadget *gadget)
{
if (gadget && gadget->dev.parent)
pm_runtime_get_noresume(gadget->dev.parent);
}
/**
* usb_gadget_autopm_put - decrement PM-usage counter of usb gadget's parent
* device.
* @gadget: usb gadget whose parent device counter is decremented.
*
* This routine should be called by function driver when it is finished using
* @gadget parent device and wants to allow it to autosuspend. It decrements
* PM-usage counter of @gadget parent device, when the counter reaches 0, a
* delayed autosuspend request is attempted.
*
* This routine can run only in process context.
*/
static inline void usb_gadget_autopm_put(struct usb_gadget *gadget)
{
if (gadget && gadget->dev.parent)
pm_runtime_put_sync(gadget->dev.parent);
}
/**
* usb_gadget_autopm_put_async - decrement PM-usage counter of usb gadget's
* parent device.
* @gadget: usb gadget whose parent device counter is decremented.
*
* This routine decrements PM-usage counter of @gadget parent device and
* schedules a delayed autosuspend request if the counter is <= 0.
*
* This routine can run in atomic context.
*/
static inline void usb_gadget_autopm_put_async(struct usb_gadget *gadget)
{
if (gadget && gadget->dev.parent)
pm_runtime_put(gadget->dev.parent);
}
/**
* usb_gadget_autopm_put_no_suspend - decrement PM-usage counter of usb gadget
's
* parent device.
* @gadget: usb gadget whose parent device counter is decremented.
*
* This routine decrements PM-usage counter of @gadget parent device but does
* not carry out an autosuspend.
*
* This routine can run in atomic context.
*/
static inline void usb_gadget_autopm_put_no_suspend(struct usb_gadget *gadget)
{
if (gadget && gadget->dev.parent)
pm_runtime_put_noidle(gadget->dev.parent);
}
#if IS_ENABLED(CONFIG_USB_DWC3_MSM)
void dwc3_msm_notify_event(struct dwc3 *dwc,
enum dwc3_notify_event event, unsigned int value);
int usb_gsi_ep_op(struct usb_ep *ep, void *op_data, enum gsi_ep_op op);
int msm_ep_config(struct usb_ep *ep, struct usb_request *request, u32 bam_opts);
int msm_ep_unconfig(struct usb_ep *ep);
void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable);
int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size,
u8 dst_pipe_idx);
int msm_dwc3_reset_dbm_ep(struct usb_ep *ep);
int dwc3_msm_set_dp_mode(struct device *dev, bool connected, int lanes);
int dwc3_msm_release_ss_lane(struct device *dev);
int msm_ep_update_ops(struct usb_ep *ep);
int msm_ep_clear_ops(struct usb_ep *ep);
int msm_ep_set_mode(struct usb_ep *ep, enum usb_hw_ep_mode mode);
int dwc3_core_stop_hw_active_transfers(struct dwc3 *dwc);
#else
void dwc3_msm_notify_event(struct dwc3 *dwc,
enum dwc3_notify_event event, unsigned int value)
{ }
static inline int usb_gsi_ep_op(struct usb_ep *ep, void *op_data,
enum gsi_ep_op op)
{ return 0; }
static inline int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr,
u32 size, u8 dst_pipe_idx)
{ return -ENODEV; }
static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
u32 bam_opts)
{ return -ENODEV; }
static inline int msm_ep_unconfig(struct usb_ep *ep)
{ return -ENODEV; }
static inline void dwc3_tx_fifo_resize_request(struct usb_ep *ep,
bool qdss_enable)
{ }
static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget)
{ return false; }
static inline int dwc3_msm_set_dp_mode(struct device *dev, bool connected, int lanes)
{ return -ENODEV; }
static inline int dwc3_msm_release_ss_lane(struct device *dev)
{ return -ENODEV; }
int msm_ep_update_ops(struct usb_ep *ep)
{ return -ENODEV; }
int msm_ep_clear_ops(struct usb_ep *ep)
{ return -ENODEV; }
int msm_ep_set_mode(struct usb_ep *ep, enum usb_hw_ep_mode mode)
{ return -ENODEV; }
inline int dwc3_core_stop_hw_active_transfers(struct dwc3 *dwc)
{ return 0; }
#endif
#ifdef CONFIG_ARM64
int dwc3_msm_kretprobe_init(void);
void dwc3_msm_kretprobe_exit(void);
#else
int dwc3_msm_kretprobe_init(void)
{ return 0; }
void dwc3_msm_kretprobe_exit(void)
{ }
#endif
#endif /* __LINUX_USB_DWC3_MSM_H */

View File

@@ -0,0 +1,24 @@
/*
* Gadget Function Driver for Android USB accessories
*
* Copyright (C) 2021 samsung.com.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#ifndef _F_SS_MON_GADGHET_H_
#define _F_SS_MON_GADGHET_H_
#include <linux/usb/gadget.h>
extern void usb_reset_notify(struct usb_gadget *gadget);
extern void vbus_session_notify(struct usb_gadget *gadget, int is_active, int ret);
extern void make_suspend_current_event(void);
#endif

View File

@@ -0,0 +1,109 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_USB_REDRIVER_H
#define __LINUX_USB_REDRIVER_H
#include <linux/list.h>
#include <linux/device.h>
#include <linux/of.h>
/*
* design rules,
* [a] assume pullup operation happen in kretprobe.
* in kretprobe function, mutex lock is not allowed;
* in kretprobe function, schedule_work() is allowed;
* [b] this is core driver which service lower redriver and upper user.
* [c] redriver must probe early than user, or not user will defer probe.
* [d] redriver can rmmod only when there is no user bind to it.
* [e] if user rmmod, redirver will change to default state.
* [f] if redriver module insmod after new change and build,
* user module also need insmod to work.
* [g] when a redriver probe, set to disable state, all control from user.
* as ssphy have no eud function which don't need to keep working.
* [h] user should be ssphy, but current user is dwc3,
* as seem some redriver have termination issue,
* it need to do pullup operation from controller driver.
*/
#define ORIENTATION_CC1 0
#define ORIENTATION_CC2 1
/**
* struct usb_redriver - present a redriver chip
* @list: link all redriver chips
* @of_node: redriver chip device tree node
* @release_usb_lanes: put redriver into 2/4 lanes display mode
* @notify_connect: cable connect
* @notify_disconnect: cable disconnect
* @gadget_pullup_enter: operation when enter gadget pullup function
* @gadget_pullup_exit: operation when exit gadget pullup function
* @host_powercycle: workaround for host otg case
* @unbind, change to default state when user unbind it
* @bounded, bound to user or not
*/
struct usb_redriver {
struct list_head list;
struct device_node *of_node;
int (*release_usb_lanes)(struct usb_redriver *ur, int ort, int num);
int (*notify_connect)(struct usb_redriver *ur, int ort);
int (*notify_disconnect)(struct usb_redriver *ur);
int (*gadget_pullup_enter)(struct usb_redriver *ur, int is_on);
int (*gadget_pullup_exit)(struct usb_redriver *ur, int is_on);
int (*host_powercycle)(struct usb_redriver *ur);
void (*unbind)(struct usb_redriver *ur);
bool bounded;
};
#if IS_ENABLED(CONFIG_USB_REDRIVER)
int usb_add_redriver(struct usb_redriver *ur);
int usb_remove_redriver(struct usb_redriver *ur);
struct usb_redriver *usb_get_redriver_by_phandle(
const struct device_node *np,
const char *phandle_name, int index);
void usb_put_redriver(struct usb_redriver *ur);
void usb_redriver_release_lanes(struct usb_redriver *ur, int ort, int num);
void usb_redriver_notify_connect(struct usb_redriver *ur, int ort);
void usb_redriver_notify_disconnect(struct usb_redriver *ur);
void usb_redriver_gadget_pullup_enter(struct usb_redriver *ur, int is_on);
void usb_redriver_gadget_pullup_exit(struct usb_redriver *ur, int is_on);
void usb_redriver_host_powercycle(struct usb_redriver *ur);
#else
static inline int usb_add_redriver(struct usb_redriver *ur)
{
return 0;
}
static inline struct usb_redriver *usb_get_redriver_by_phandle(
const struct device_node *np,
const char *phandle_name, int index)
{
return NULL;
}
static inline int usb_remove_redriver(struct usb_redriver *ur)
{
return 0;
}
#define usb_put_redriver(ur) do {} while (0)
#define usb_redriver_release_lanes(ur, ort, num) do {} while (0)
#define usb_redriver_notify_connect(ur, ort) do {} while (0)
#define usb_redriver_notify_disconnect(ur) do {} while (0)
#define usb_redriver_gadget_pullup_enter(ur, is_on) do {} while (0)
#define usb_redriver_gadget_pullup_exit(ur, is_on) do {} while (0)
#define usb_redriver_host_powercycle(ur) do {} while (0)
#endif
#endif /*__LINUX_USB_REDRIVER_H */

View File

@@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_USB_REPEATER_H
#define __LINUX_USB_REPEATER_H
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/types.h>
#if IS_ENABLED(CONFIG_I2C_EUSB2_REPEATER)
#define UR_AUTO_RESUME_SUPPORTED BIT(0)
#endif
struct usb_repeater {
struct device *dev;
const char *label;
unsigned int flags;
#if IS_ENABLED(CONFIG_USB_PHY_SETTING_QCOM)
bool is_host;
#endif
struct list_head head;
int (*reset)(struct usb_repeater *x, bool bring_out_of_reset);
int (*init)(struct usb_repeater *x);
int (*suspend)(struct usb_repeater *r, int suspend);
int (*powerup)(struct usb_repeater *r);
int (*powerdown)(struct usb_repeater *r);
int (*get_version)(struct usb_repeater *r);
};
#if IS_ENABLED(CONFIG_USB_REPEATER)
struct usb_repeater *devm_usb_get_repeater_by_phandle(struct device *dev,
const char *phandle, u8 index);
struct usb_repeater *devm_usb_get_repeater_by_node(struct device *dev,
struct device_node *node);
struct usb_repeater *usb_get_repeater_by_phandle(struct device *dev,
const char *phandle, u8 index);
struct usb_repeater *usb_get_repeater_by_node(struct device_node *node);
void usb_put_repeater(struct usb_repeater *r);
int usb_add_repeater_dev(struct usb_repeater *r);
void usb_remove_repeater_dev(struct usb_repeater *r);
#else
static inline struct usb_repeater *devm_usb_get_repeater_by_phandle(
struct device *d, const char *phandle, u8 index)
{ return ERR_PTR(-ENXIO); }
static inline struct usb_repeater *devm_usb_get_repeater_by_node(
struct device *dev, struct device_node *node)
{ return ERR_PTR(-ENXIO); }
static inline struct usb_repeater *usb_get_repeater_by_phandle(
struct device *d, const char *phandle, u8 index)
{ return ERR_PTR(-ENXIO); }
static inline struct usb_repeater *usb_get_repeater_by_node(
struct device_node *node)
{ return ERR_PTR(-ENXIO); }
static inline void usb_put_repeater(struct usb_repeater *r)
{ }
static inline int usb_add_repeater_dev(struct usb_repeater *r)
{ return 0; }
static inline void usb_remove_repeater_dev(struct usb_repeater *r)
{ }
#endif
static inline int usb_repeater_reset(struct usb_repeater *r,
bool bring_out_of_reset)
{
if (r && r->reset != NULL)
return r->reset(r, bring_out_of_reset);
else
return 0;
}
static inline int usb_repeater_init(struct usb_repeater *r)
{
if (r && r->init != NULL)
return r->init(r);
else
return 0;
}
static inline int usb_repeater_suspend(struct usb_repeater *r, int suspend)
{
if (r && r->suspend != NULL)
return r->suspend(r, suspend);
else
return 0;
}
static inline int usb_repeater_powerup(struct usb_repeater *r)
{
if (r && r->powerup != NULL)
return r->powerup(r);
else
return 0;
}
static inline int usb_repeater_powerdown(struct usb_repeater *r)
{
if (r && r->powerdown != NULL)
return r->powerdown(r);
else
return 0;
}
static inline int usb_repeater_get_version(struct usb_repeater *r)
{
if (r && r->get_version != NULL)
return r->get_version(r);
else
return -EINVAL;
}
#endif /* __LINUX_USB_REPEATER_H */

View File

@@ -0,0 +1,345 @@
/*
*
* Copyright (C) 2017-2020 Samsung Electronics
*
* Author:Wookwang Lee. <wookwang.lee@samsung.com>,
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LINUX_PDIC_CORE_H__
#define __LINUX_PDIC_CORE_H__
/* PDIC Dock Observer Callback parameter */
enum {
PDIC_DOCK_DETACHED = 0,
PDIC_DOCK_HMT = 105, /* Samsung Gear VR */
PDIC_DOCK_ABNORMAL = 106,
PDIC_DOCK_MPA = 109, /* Samsung Multi Port Adaptor */
PDIC_DOCK_DEX = 110, /* Samsung Dex */
PDIC_DOCK_HDMI = 111, /* Samsung HDMI Dongle */
PDIC_DOCK_T_VR = 112,
PDIC_DOCK_UVDM = 113,
PDIC_DOCK_DEXPAD = 114,
PDIC_DOCK_UNSUPPORTED_AUDIO = 115, /* Ra/Ra TypeC Analog Earphone*/
PDIC_DOCK_NEW = 200, /* For New uevent */
};
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 */
TYPE_C_ATTACH_SRC = 4, /* SRC */
TYPE_C_ATTACH_SNK = 5, /* SNK */
TYPE_C_RR_SWAP = 6,
TYPE_C_DR_SWAP = 7,
} PDIC_OTP_MODE;
#if defined(CONFIG_TYPEC)
typedef enum {
TRY_ROLE_SWAP_NONE = 0,
TRY_ROLE_SWAP_PR = 1, /* pr_swap */
TRY_ROLE_SWAP_DR = 2, /* dr_swap */
TRY_ROLE_SWAP_TYPE = 3, /* type */
TRY_ROLE_SWAP_VC = 4, /* vconn swap */
} PDIC_ROLE_SWAP_MODE;
#define TRY_ROLE_SWAP_WAIT_MS 5000
#endif
#define DUAL_ROLE_SET_MODE_WAIT_MS 2000
#define GEAR_VR_DETACH_WAIT_MS 1000
#define SAMSUNG_PRODUCT_ID 0x6860
#define SAMSUNG_PRODUCT_TYPE 0x2
/* Samsung Acc VID */
#define SAMSUNG_VENDOR_ID 0x04E8
#define SAMSUNG_MPA_VENDOR_ID 0x04B4
#define TypeC_DP_SUPPORT (0xFF01)
/* Samsung Acc PID */
#define GEARVR_PRODUCT_ID 0xA500
#define GEARVR_PRODUCT_ID_1 0xA501
#define GEARVR_PRODUCT_ID_2 0xA502
#define GEARVR_PRODUCT_ID_3 0xA503
#define GEARVR_PRODUCT_ID_4 0xA504
#define GEARVR_PRODUCT_ID_5 0xA505
#define DEXDOCK_PRODUCT_ID 0xA020
#define HDMI_PRODUCT_ID 0xA025
#define MPA2_PRODUCT_ID 0xA027
#define UVDM_PROTOCOL_ID 0xA028
#define DEXPAD_PRODUCT_ID 0xA029
#define MPA_PRODUCT_ID 0x2122
#define FRIENDS_PRODUCT_ID 0xB002
/* Samsung UVDM structure */
#define SEC_UVDM_SHORT_DATA 0x0
#define SEC_UVDM_LONG_DATA 0x1
#define SEC_UVDM_ININIATOR 0x0
#define SEC_UVDM_RESPONDER_INIT 0x0
#define SEC_UVDM_RESPONDER_ACK 0x1
#define SEC_UVDM_RESPONDER_NAK 0x2
#define SEC_UVDM_RESPONDER_BUSY 0x3
#define SEC_UVDM_RX_HEADER_BUSY 0x2
#define SEC_UVDM_UNSTRUCTURED_VDM 0x4
#define SEC_UVDM_RX_HEADER_ACK 0x0
#define SEC_UVDM_RX_HEADER_NAK 0x1
#define SEC_UVDM_ALIGN (4)
#define SEC_UVDM_MAXDATA_FIRST (12)
#define SEC_UVDM_MAXDATA_NORMAL (16)
#define SEC_UVDM_CHECKSUM_COUNT (20)
/*For DP Pin Assignment */
#define DP_PIN_ASSIGNMENT_NODE 0x00000000
#define DP_PIN_ASSIGNMENT_A 0x00000001 /* ( 1 << 0 ) */
#define DP_PIN_ASSIGNMENT_B 0x00000002 /* ( 1 << 1 ) */
#define DP_PIN_ASSIGNMENT_C 0x00000004 /* ( 1 << 2 ) */
#define DP_PIN_ASSIGNMENT_D 0x00000008 /* ( 1 << 3 ) */
#define DP_PIN_ASSIGNMENT_E 0x00000010 /* ( 1 << 4 ) */
#define DP_PIN_ASSIGNMENT_F 0x00000020 /* ( 1 << 5 ) */
#define MAX_BUF_DATA 256
typedef union {
u16 word;
u8 byte[2];
struct {
unsigned msg_type:5;
unsigned port_data_role:1;
unsigned spec_revision:2;
unsigned port_power_role:1;
unsigned msg_id:3;
unsigned num_data_objs:3;
unsigned extended:1;
};
} msg_header_type;
typedef union {
u32 object;
u16 word[2];
u8 byte[4];
struct {
unsigned vendor_defined:15;
unsigned vdm_type:1;
unsigned vendor_id:16;
};
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;
} uvdm_header;
typedef union {
u32 object;
u16 word[2];
u8 byte[4];
struct{
unsigned data:8;
unsigned total_set_num:4;
unsigned direction:1;
unsigned cmd_type:2;
unsigned data_type:1;
unsigned pid:16;
};
} s_uvdm_header;
typedef union {
u32 object;
u16 word[2];
u8 byte[4];
struct{
unsigned cur_size:8;
unsigned total_size:8;
unsigned reserved:12;
unsigned order_cur_set:4;
};
} s_tx_header;
typedef union {
u32 object;
u16 word[2];
u8 byte[4];
struct{
unsigned checksum:16;
unsigned reserved:16;
};
} s_tx_tailer;
typedef union {
u32 object;
u16 word[2];
u8 byte[4];
struct{
unsigned reserved:18;
unsigned result_value:2;
unsigned rcv_data_size:8;
unsigned order_cur_set:4;
};
} s_rx_header;
enum usbpd_port_data_role {
USBPD_UFP,
USBPD_DFP,
};
enum usbpd_port_power_role {
USBPD_SINK,
USBPD_SOURCE,
USBPD_DRP,
};
enum usbpd_port_vconn_role {
USBPD_VCONN_OFF,
USBPD_VCONN_ON,
};
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
struct pdic_state_work {
struct work_struct pdic_work;
int dest;
int id;
int attach;
int event;
int sub;
};
typedef enum {
CLIENT_OFF = 0,
CLIENT_ON = 1,
} PDIC_DEVICE_REASON;
typedef enum {
HOST_OFF = 0,
HOST_ON = 1,
} PDIC_HOST_REASON;
#endif
enum uvdm_data_type {
TYPE_SHORT = 0,
TYPE_LONG,
};
enum uvdm_direction_type {
DIR_OUT = 0,
DIR_IN,
};
struct uvdm_data {
unsigned short pid; /* Product ID */
char type; /* uvdm_data_type */
char dir; /* uvdm_direction_type */
unsigned int size; /* data size */
void __user *pData; /* data pointer */
};
#ifdef CONFIG_COMPAT
struct uvdm_data_32 {
unsigned short pid; /* Product ID */
char type; /* uvdm_data_type */
char dir; /* uvdm_direction_type */
unsigned int size; /* data size */
compat_uptr_t pData; /* data pointer */
};
#endif
struct pdic_misc_dev {
struct uvdm_data u_data;
#ifdef CONFIG_COMPAT
struct uvdm_data_32 u_data_32;
#endif
atomic_t open_excl;
atomic_t ioctl_excl;
int (*uvdm_write)(void *data, int size);
int (*uvdm_read)(void *data);
int (*uvdm_ready)(void);
void (*uvdm_close)(void);
bool (*pps_control)(int en);
};
struct pdic_misc_data {
void *fw_buf;
size_t offset;
size_t fw_buf_size;
int is_error;
};
struct pdic_data {
int (*firmware_update)(void *data,
void *fw_bin, size_t fw_size);
size_t (*get_prev_fw_size)(void *data);
void *data;
};
struct pdic_fwupdate_data {
struct pdic_misc_data *misc_data;
struct pdic_data *ic_data;
atomic_t opened;
};
struct pdic_misc_core {
struct pdic_misc_dev c_dev;
struct pdic_fwupdate_data fw_data;
};
typedef struct _pdic_data_t {
const char *name;
void *pdic_sysfs_prop;
void *drv_data;
void (*set_enable_alternate_mode)(int);
struct pdic_misc_dev *misc_dev;
struct pdic_data fw_data;
} pdic_data_t, *ppdic_data_t;
/* ----------------------------------
* pdic_core.c functions
*-----------------------------------
*/
int pdic_core_init(void);
int pdic_core_register_chip(ppdic_data_t ppdic_data);
void pdic_core_unregister_chip(void);
int pdic_register_switch_device(int mode);
void pdic_send_dock_intent(int type);
void pdic_send_dock_uevent(u32 vid, u32 pid, int state);
void *pdic_core_get_drvdata(void);
/* ----------------------------------
* pdic_misc.c functions
*-----------------------------------
*/
int pdic_misc_init(ppdic_data_t ppdic_data);
void pdic_misc_exit(void);
/* SEC UVDM Utility function */
int get_checksum(const char *data, int start_addr, int size);
int get_data_size(bool is_first_data, int data_size);
int set_endian(const char *src, char *dest, int size);
int set_uvdmset_count(int size);
void set_msg_header(void *data, int msg_type, int obj_num);
void set_uvdm_header(void *data, int vid, int vdm_type);
void set_sec_uvdm_header(void *data, int pid, bool data_type, int cmd_type,
bool dir, int total_set_num, uint8_t received_data);
void set_sec_uvdm_tx_header(void *data, int first_set, int cur_set, int total_size,
int remained_size);
void set_sec_uvdm_tx_tailer(void *data);
void set_sec_uvdm_rx_header(void *data, int cur_num, int cur_set, int ack);
struct device *get_pdic_device(void);
#endif

View File

@@ -0,0 +1,281 @@
/*
* Copyrights (C) 2019 Samsung Electronics, 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.
*
* 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.
*/
#ifndef __PDIC_NOTIFIER_H__
#define __PDIC_NOTIFIER_H__
/* PDIC notifier call sequence,
* largest priority number device will be called first.
* refer Team Docs > ETC > 1. USB Type C >
* code managing > pdic_notifier, pdic_notifier
*/
typedef enum {
PDIC_NOTIFY_DEV_INITIAL = 0,
PDIC_NOTIFY_DEV_USB = 1,
PDIC_NOTIFY_DEV_BATT = 2,
PDIC_NOTIFY_DEV_PDIC = 3,
PDIC_NOTIFY_DEV_MUIC = 4,
PDIC_NOTIFY_DEV_CCIC = 5,
PDIC_NOTIFY_DEV_MANAGER = 6,
PDIC_NOTIFY_DEV_DP = 7,
PDIC_NOTIFY_DEV_USB_DP = 8,
PDIC_NOTIFY_DEV_SUB_BATTERY = 9,
PDIC_NOTIFY_DEV_SECOND_MUIC = 10,
PDIC_NOTIFY_DEV_DEDICATED_MUIC = 11,
PDIC_NOTIFY_DEV_ALL = 12,
} pdic_notifier_device;
typedef enum {
PDIC_NOTIFY_ID_INITIAL = 0,
PDIC_NOTIFY_ID_ATTACH = 1,
PDIC_NOTIFY_ID_RID = 2,
PDIC_NOTIFY_ID_USB = 3,
PDIC_NOTIFY_ID_POWER_STATUS = 4,
PDIC_NOTIFY_ID_WATER = 5,
PDIC_NOTIFY_ID_VCONN = 6,
PDIC_NOTIFY_ID_OTG = 7,
PDIC_NOTIFY_ID_TA = 8,
PDIC_NOTIFY_ID_DP_CONNECT = 9,
PDIC_NOTIFY_ID_DP_HPD = 10,
PDIC_NOTIFY_ID_DP_LINK_CONF = 11,
PDIC_NOTIFY_ID_USB_DP = 12,
PDIC_NOTIFY_ID_ROLE_SWAP = 13,
PDIC_NOTIFY_ID_FAC = 14,
PDIC_NOTIFY_ID_CC_PIN_STATUS = 15,
PDIC_NOTIFY_ID_WATER_CABLE = 16,
PDIC_NOTIFY_ID_POFF_WATER = 17,
PDIC_NOTIFY_ID_DEVICE_INFO = 18,
PDIC_NOTIFY_ID_SVID_INFO = 19,
PDIC_NOTIFY_ID_CLEAR_INFO = 20,
#if IS_ENABLED(CONFIG_MUIC_POGO)
PDIC_NOTIFY_ID_POGO = 21,
#endif
PDIC_NOTIFY_ID_RPLEVEL = 22,
} pdic_notifier_id_t;
typedef enum {
RID_UNDEFINED = 0,
RID_000K = 1,
RID_001K = 2,
RID_255K = 3,
RID_301K = 4,
RID_523K = 5,
RID_619K = 6,
RID_OPEN = 7,
RID_056K = 8,
} pdic_notifier_rid_t;
typedef enum {
USB_STATUS_NOTIFY_DETACH = 0,
USB_STATUS_NOTIFY_ATTACH_DFP = 1,
USB_STATUS_NOTIFY_ATTACH_UFP = 2,
USB_STATUS_NOTIFY_ATTACH_DRP = 3,
} USB_STATUS;
typedef enum {
PDIC_NOTIFY_PIN_STATUS_NO_DETERMINATION = 0,
PDIC_NOTIFY_PIN_STATUS_CC1_ACTIVE = 1,
PDIC_NOTIFY_PIN_STATUS_CC2_ACTIVE = 2,
PDIC_NOTIFY_PIN_STATUS_AUDIO_ACCESSORY = 3,
PDIC_NOTIFY_PIN_STATUS_DEBUG_ACCESSORY = 4,
PDIC_NOTIFY_PIN_STATUS_PDIC_ERROR = 5,
PDIC_NOTIFY_PIN_STATUS_DISABLED = 6,
PDIC_NOTIFY_PIN_STATUS_RFU = 7,
PDIC_NOTIFY_PIN_STATUS_NOCC_USB_ACTIVE = 8,
} pdic_notifier_pin_status_t;
typedef enum {
PDIC_NOTIFY_DP_PIN_UNKNOWN = 0,
PDIC_NOTIFY_DP_PIN_A = 1,
PDIC_NOTIFY_DP_PIN_B = 2,
PDIC_NOTIFY_DP_PIN_C = 3,
PDIC_NOTIFY_DP_PIN_D = 4,
PDIC_NOTIFY_DP_PIN_E = 5,
PDIC_NOTIFY_DP_PIN_F = 6,
} pdic_notifier_dp_pinconf_t;
typedef enum {
PDIC_NOTIFY_DETACH = 0,
PDIC_NOTIFY_ATTACH = 1,
} pdic_notifier_attach_t;
typedef enum {
PDIC_NOTIFY_DEVICE = 0,
PDIC_NOTIFY_HOST = 1,
} pdic_notifier_attach_rprd_t;
typedef enum {
PDIC_NOTIFY_LOW = 0,
PDIC_NOTIFY_HIGH = 1,
PDIC_NOTIFY_IRQ = 2,
} pdic_notifier_dp_hpd_t;
typedef enum {
PDIC_NOTIFY_PD_EVENT_DETACH = 0,
PDIC_NOTIFY_PD_EVENT_CCIC_ATTACH,
PDIC_NOTIFY_PD_EVENT_SINK,
PDIC_NOTIFY_PD_EVENT_SOURCE,
PDIC_NOTIFY_PD_EVENT_SINK_CAP,
PDIC_NOTIFY_PD_EVENT_PRSWAP_SNKTOSRC,
} pdic_notifier_pd_event_t;
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t sub1:16;
uint64_t sub2:16;
uint64_t sub3:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_TYPEDEF;
/* ID = 1 : Attach */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t attach:16;
uint64_t rprd:16;
uint64_t cable_type:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_ATTACH_TYPEDEF;
/* ID = 2 : RID */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t rid:16;
uint64_t sub2:16;
uint64_t sub3:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_RID_TYPEDEF;
/* ID = 3 : USB status */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t attach:16;
uint64_t drp:16;
uint64_t sub3:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_USB_STATUS_TYPEDEF;
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t is_connect:16;
uint64_t hs_connect:16;
uint64_t reserved:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} USB_DP_NOTI_TYPEDEF;
/* ID = 4 : POWER STATUS */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t attach:16;
uint64_t event:16;
uint64_t data:16;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_POWER_STATUS_TYPEDEF;
/* ID = 18 : Device Info */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t vendor_id:16;
uint64_t product_id:16;
uint64_t version:8;
uint64_t ifpmic_index:8;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_DEVICE_INFO_TYPEDEF;
/* ID = 19 : Standard Vendor ID Info */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t standard_vendor_id:16;
uint64_t reserved:32;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_SVID_INFO_TYPEDEF;
/* ID = 20 : Clear ID Info */
typedef struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t clear_id:16;
uint64_t reserved:32;
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
void *pd;
#endif
} PD_NOTI_CLEAR_INFO_TYPEDEF;
struct pdic_notifier_data {
PD_NOTI_TYPEDEF pdic_template;
struct blocking_notifier_head notifier_call_chain;
struct mutex notify_mutex;
};
#define PDIC_NOTIFIER_BLOCK(name) \
struct notifier_block (name)
#define SET_PDIC_NOTIFIER_BLOCK(nb, fn, dev) do { \
(nb)->notifier_call = (fn); \
(nb)->priority = (dev); \
} while (0)
#define DESTROY_PDIC_NOTIFIER_BLOCK(nb) \
SET_PDIC_NOTIFIER_BLOCK(nb, NULL, -1)
extern int pdic_notifier_notify(PD_NOTI_TYPEDEF *noti, void *pd,
int pdic_attach);
extern int pdic_notifier_register(struct notifier_block *nb,
notifier_fn_t notifier, pdic_notifier_device listener);
extern int pdic_notifier_unregister(struct notifier_block *nb);
extern void pdic_uevent_work(int id, int state);
const char *pdic_event_src_string(pdic_notifier_device src);
const char *pdic_event_dest_string(pdic_notifier_device dest);
const char *pdic_event_id_string(pdic_notifier_id_t id);
const char *pdic_rid_string(pdic_notifier_rid_t rid);
const char *pdic_usbstatus_string(USB_STATUS usbstatus);
#ifndef MODULE
extern int pdic_notifier_init(void);
#endif
#endif /* __PDIC_NOTIFIER_H__ */

View File

@@ -0,0 +1,50 @@
/*
*
* Copyright (C) 2021 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LINUX_PDIC_PARAM_H__
#define __LINUX_PDIC_PARAM_H__
enum pdic_param_usbmode {
PDIC_PARAM_MODE_NO,
PDIC_PARAM_MODE_OB,
PDIC_PARAM_MODE_IB,
PDIC_PARAM_MODE_DL,
PDIC_PARAM_MODE_LC,
};
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
extern int check_factory_mode_boot(void);
extern int get_usb_factory_mode(void);
extern int is_lpcharge_pdic_param(void);
extern int is_factory_mode_pdic_param(void);
extern int is_recovery_mode_pdic_param(void);
#else
static inline int check_factory_mode_boot(void)
{return 0; }
static inline int get_usb_factory_mode(void)
{return PDIC_PARAM_MODE_NO;}
static inline int is_lpcharge_pdic_param(void)
{return 0; }
static inline int is_factory_mode_pdic_param(void)
{return 0; }
static inline int is_recovery_mode_pdic_param(void)
{return 0; }
#endif
#endif /* __LINUX_PDIC_PARAM_H__ */

View File

@@ -0,0 +1,145 @@
/*
*
* Copyright (C) 2021 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LINUX_PDIC_POLICY_H__
#define __LINUX_PDIC_POLICY_H__
#include <linux/usb/typec.h>
#include <linux/usb/typec/common/pdic_notifier.h>
enum pdic_message {
MSG_INITIAL,
MSG_SRC,
MSG_SNK,
MSG_VBUSON,
MSG_VBUSOFF,
MSG_RP56K,
MSG_RP22K,
MSG_RP10K,
MSG_UFP,
MSG_DFP,
MSG_AUDIO,
MSG_DEBUG,
MSG_CC1,
MSG_CC2,
MSG_NOCC_WAKE,
MSG_CC_SHORT,
MSG_SBU_SHORT,
MSG_WATER,
MSG_DRY,
MSG_ROPEN,
MSG_R301K,
MSG_R255K,
MSG_R523K,
MSG_R619K,
MSG_UOPEN,
MSG_U301K,
MSG_U255K,
MSG_U523K,
MSG_U619K,
MSG_FAC_ERR,
MSG_EX_CNT,
MSG_KILLER,
MSG_DCOVER,
MSG_DP_CONN,
MSG_DP_DISCONN,
MSG_DP_LINK_CONF,
MSG_DP_HPD,
MSG_DEVICE_INFO,
MSG_SVID_INFO,
MSG_SELECT_PDO,
MSG_CURRENT_PDO,
MSG_PD_POWER_STATUS,
MSG_FAC_MODE_NOTI_TO_MUIC,
MSG_GET_ROLESWAP_CHECK,
MSG_GET_ACC,
MSG_MUIC_SET_BC12,
MSG_SHUTDOWN,
MSG_CCOFF,
MSG_MAX,
};
enum pdic_status {
PP_STATUS_CC_ON,
PP_STATUS_CC_STATE,
PP_STATUS_CC_DIRECTION,
PP_STATUS_CC_RP_CURRENT,
PP_STATUS_POWER_ROLE,
PP_STATUS_DATA_ROLE,
PP_STATUS_VBUS_BOOSTER,
PP_STATUS_RID,
PP_STATUS_UID,
PP_STATUS_WATER,
PP_STATUS_CC_SHORT,
PP_STATUS_SBU_SHORT,
PP_STATUS_EXPLICIT_CONTRACT,
};
struct pdic_alt_info {
u16 vendor_id;
u16 product_id;
u16 bcd_device;
u16 svid[12];
int dp_device;
int dp_pin_assignment;
int dp_selected_pin;
int hpd_state;
int hpd_irq;
};
struct pdic_ops {
int (*dr_set)(void *data, enum typec_data_role role);
int (*pr_set)(void *data, enum typec_role role);
int (*vconn_set)(void *data, enum typec_role role);
int (*port_type_set)(void *data, enum typec_port_type type);
int (*get_alt_info)(void *data, struct pdic_alt_info *alt_info);
void (*set_alt_mode)(int);
void (*dp_info_clear)(void *data);
int (*usbpd_sbu_test_read)(void *data);
void (*cc_control_command)(void *data, int is_off);
void (*alt_info_clear)(void *data);
};
struct pp_ic_data {
struct device *dev;
const struct pdic_ops *p_ops;
struct pdic_notifier_struct *pd_noti;
int support_pd;
int vbus_dischar_gpio;
void *pp_data;
void *drv_data;
int typec_implemented;
};
#ifdef CONFIG_PDIC_POLICY
extern int pdic_policy_update_pdo_list(void *data, int max_v, int min_v,
int max_icl, int cnt, int num);
extern int pdic_policy_send_msg(void *data, int msg, int param1, int param2);
extern void *pdic_policy_init(struct pp_ic_data *ic_data);
extern void pdic_policy_deinit(struct pp_ic_data *ic_data);
#else
static inline int pdic_policy_update_pdo_list(void *data, int max_v, int min_v,
int max_icl, int cnt, int num) {return 0; }
static inline int pdic_policy_send_msg(void *data, int msg,
int param1, int param2) {return 0; }
static inline void *pdic_policy_init(struct pp_ic_data *ic_data) {return NULL; }
static inline void pdic_policy_deinit(struct pp_ic_data *ic_data) {}
#endif
#endif /* __LINUX_PDIC_POLICY_H__ */

View File

@@ -0,0 +1,268 @@
/*
*
*
*
* Copyright (C) 2021 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 __PDIC_SPEC_DEF_H__
#define __PDIC_SPEC_DEF_H__
#define DP_SVID (0xFF01)
#define SAMSUNG_SVID (0x04E8)
#define PD_SID (0xFF00)
typedef enum {
S_DISCOVER_IDENTIFY = 0x1,
S_DISCOVER_SVIDS,
S_DISCOVER_MODES,
S_ENTER_MODE,
S_EXIT_MODE,
S_ATTENTION,
S_DISPLAYPORT_STATUS_UPDATE = 0x10,
S_DISPLAYPORT_CONFIGURE = 0x11,
} S_VDM_HEADER_COMMAND;
typedef enum {
S_TYPE_REQ = 0,
S_TYPE_ACK,
S_TYPE_NAK,
S_TYPE_BUSY,
} S_VDM_HEADER_COMMAND_TYPE;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Number_of_obj:3,
MSG_ID:3,
Port_Power_Role:1,
Specification_Rev:2,
Port_Data_Role:1,
Reserved:1,
MSG_Type:4;
} BITS;
} S_MSG_HEADER;
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;
} S_VDM_HEADER;
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;
} S_ID_HEADER_VDO;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Cert_TID:20,
Rsvd_cert_VDOer:12;
} BITS;
} S_CERT_STAT_VDO;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Device_Version:16,
Product_ID:16;
} BITS;
} S_PRODUCT_VDO;
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;
} S_CABLE_VDO;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t SVID_1:16,
SVID_0:16;
} BITS;
} S_SVID_VDO;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
S_ID_HEADER_VDO id_header;
S_CERT_STAT_VDO cert_stat;
S_PRODUCT_VDO product;
} DISCOVER_IDENTITY_RESPONSE;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
S_SVID_VDO svid_vdo[6];
} DISCOVER_SVID_RESPONSE;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
} ENTER_MODE_RESPONSE;
/*
*
* Display port defines
*
*/
/* For DP VDM Modes VDO Port_Capability */
typedef enum
{
S_RESERVED = 0,
S_UFP_D_CAPABLE = 1,
S_DFP_D_CAPABLE = 2,
S_DFP_D_AND_UFP_D_CAPABLE = 3
} S_DP_CAPABILITIES_VDO_PORT_CAPABILITY;
/* For DP VDM Modes VDO Receptacle_Indication */
typedef enum
{
S_USB_TYPE_C_PLUG = 0,
S_USB_TYPE_C_RECEPTACLE = 1
} S_DP_CAPABILITIES_VDO_RECEPTACLE_INDICATION;
/* For DP_Status_Update Port_Connected */
typedef enum
{
S_ADAPTOR_DISABLE = 0,
S_CONNECT_DFP_D = 1,
S_CONNECT_UFP_D = 2,
S_CONNECT_DFP_D_and_UFP_D = 3
} S_DP_STATUS_UPDATE_VDO_CONNECTED;
/* For DP_Configure Select_Configuration */
typedef enum
{
S_CFG_FOR_USB = 0,
S_CFG_UFP_U_AS_DFP_D = 1,
S_CFG_UFP_U_AS_UFP_D = 2,
S_CFG_RESERVED = 3
} S_DP_STATUS_UPDATE_VDO_SELECT_CONFIGUTATION;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Port_Capability:2,
Signalling_DP:4,
Receptacle_Indication:1,
USB_2p0_Not_Used:1,
DFP_D_Pin_Assignments:8,
UFP_D_Pin_Assignments:8,
DP_MODE_VDO_Reserved:8;
} BITS;
} S_DP_CAPABILITIES_VDO;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Port_Connected:2,
Power_Low:1,
Enabled:1,
Multi_Function_Preference:1,
USB_Configuration_Req:1,
Exit_DP_Mode_Req:1,
HPD_State:1,
HPD_Interrupt:1,
Reserved:23;
} BITS;
} S_DP_STATUS_UPDATE_VDO;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
S_DP_CAPABILITIES_VDO dp_mode_vdo;
} DP_DISCOVER_MODE_RESPONSE;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
S_DP_STATUS_UPDATE_VDO dp_status_update_vdo;
} DP_STATUS_RESPONSE;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
} DP_CONFIGURATION_RESPONSE;
typedef struct {
S_MSG_HEADER msg_header;
S_VDM_HEADER vdm_header;
S_DP_STATUS_UPDATE_VDO dp_status_update_vdo;
} DP_ATTENTION_REQUEST;
#endif /* __PDIC_SPEC_DEF_H__ */

View File

@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0
/*
*
* Copyright (C) 2017-2021 Samsung Electronics
*
* Author:Wookwang Lee. <wookwang.lee@samsung.com>,
* 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __PDIC_SYSFS__
#define __PDIC_SYSFS__
extern const struct attribute_group pdic_sysfs_group;
enum {
BUILT_IN = 0,
UMS = 1,
SPU = 2,
SPU_VERIFICATION = 3,
FWUP_CMD_MAX = 4,
};
static const int RO_PERM = 0444;
static const int WO_PERM = 0200;
static const int RW_PERM = 0644;
enum pdic_sysfs_property {
PDIC_SYSFS_PROP_CHIP_NAME = 0,
PDIC_SYSFS_PROP_CUR_VERSION,
PDIC_SYSFS_PROP_SRC_VERSION,
PDIC_SYSFS_PROP_LPM_MODE,
PDIC_SYSFS_PROP_STATE,
PDIC_SYSFS_PROP_RID,
PDIC_SYSFS_PROP_CTRL_OPTION,
PDIC_SYSFS_PROP_BOOTING_DRY,
PDIC_SYSFS_PROP_FW_UPDATE,
PDIC_SYSFS_PROP_FW_UPDATE_STATUS,
PDIC_SYSFS_PROP_FW_WATER,
PDIC_SYSFS_PROP_DEX_FAN_UVDM,
PDIC_SYSFS_PROP_ACC_DEVICE_VERSION,
PDIC_SYSFS_PROP_DEBUG_OPCODE,
PDIC_SYSFS_PROP_CONTROL_GPIO,
PDIC_SYSFS_PROP_USBPD_IDS,
PDIC_SYSFS_PROP_USBPD_TYPE, /* for SWITCH_STATE */
PDIC_SYSFS_PROP_CC_PIN_STATUS,
PDIC_SYSFS_PROP_RAM_TEST,
PDIC_SYSFS_PROP_SBU_ADC,
PDIC_SYSFS_PROP_CC_ADC,
PDIC_SYSFS_PROP_VSAFE0V_STATUS,
PDIC_SYSFS_PROP_OVP_IC_SHUTDOWN,
PDIC_SYSFS_PROP_HMD_POWER,
PDIC_SYSFS_PROP_SET_WATER_THRESHOLD,
PDIC_SYSFS_PROP_USBPD_WATER_CHECK,
PDIC_SYSFS_PROP_15MODE_WATERTEST_TYPE,
PDIC_SYSFS_PROP_VBUS_ADC,
PDIC_SYSFS_PROP_USB_BOOT_MODE,
PDIC_SYSFS_PROP_DP_SBU_SW_SEL,
PDIC_SYSFS_PROP_NOVBUS_RP22K,
PDIC_SYSFS_PROP_CABLE_CONNECT_CTRL,
PDIC_SYSFS_PROP_MAX_COUNT,
};
struct _pdic_data_t;
typedef struct _pdic_sysfs_property_t {
enum pdic_sysfs_property *properties;
size_t num_properties;
int (*get_property)(struct _pdic_data_t *ppdic_data,
enum pdic_sysfs_property prop,
char *buf);
ssize_t (*set_property)(struct _pdic_data_t *ppdic_data,
enum pdic_sysfs_property prop,
const char *buf,
size_t size);
/* Decides whether userspace can change a specific property */
int (*property_is_writeable)(struct _pdic_data_t *ppdic_data,
enum pdic_sysfs_property prop);
int (*property_is_writeonly)(struct _pdic_data_t *ppdic_data,
enum pdic_sysfs_property prop);
} pdic_sysfs_property_t, *ppdic_sysfs_property_t;
void pdic_sysfs_init_attrs(void);
#endif

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2018-2019 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.
*
*
*/
#ifndef __IF_CB_MANAGER_H__
#define __IF_CB_MANAGER_H__
enum sbu_switch_status {
UNDEFINED = -1,
OPEN_SBU = 0,
CLOSE_SBU_CC1_ACTIVE = 1,
CLOSE_SBU_CC2_ACTIVE = 2,
};
struct usb_ops {
void (*usb_set_vbus_current)(void *data, int state);
int (*usb_restart_host_mode)(void *data, int lanes);
};
struct muic_ops {
int (*muic_check_usb_killer)(void *data);
void (*muic_set_bypass)(void *data, int enable);
void (*muic_set_bc12)(void *data, int enable);
};
struct usbpd_ops {
int (*usbpd_sbu_test_read)(void *data);
void (*usbpd_set_host_on)(void *data, int mode);
void (*usbpd_cc_control_command)(void *data, int is_off);
void (*usbpd_wait_entermode)(void *data, int on);
void (*usbpd_water_pd_ta_notify)(void *data);
void (*usbpd_sbu_switch_control)(void *data, int on);
};
struct lvs_ops {
int (*lvs_cc_attach)(void *data, int on);
};
struct usb_dev {
const struct usb_ops *ops;
void *data;
};
struct muic_dev {
const struct muic_ops *ops;
void *data;
};
struct usbpd_dev {
const struct usbpd_ops *ops;
void *data;
};
struct lvs_dev {
const struct lvs_ops *ops;
void *data;
};
struct if_cb_manager {
struct usb_dev *usb_d;
struct muic_dev *muic_d;
struct usbpd_dev *usbpd_d;
struct lvs_dev *lvs_d;
};
extern struct if_cb_manager *register_usb(struct usb_dev *usb);
extern struct if_cb_manager *register_muic(struct muic_dev *muic);
extern struct if_cb_manager *register_usbpd(struct usbpd_dev *usbpd);
extern struct if_cb_manager *register_lvs(struct lvs_dev *lvs);
extern void usb_set_vbus_current(struct if_cb_manager *man_core, int state);
extern int usb_restart_host_mode(struct if_cb_manager *man_core, int lanes);
extern int muic_check_usb_killer(struct if_cb_manager *man_core);
extern void muic_set_bypass(struct if_cb_manager *man_core, int enable);
extern void muic_set_bc12(struct if_cb_manager *man_core, int enable);
extern int usbpd_sbu_test_read(struct if_cb_manager *man_core);
extern void usbpd_set_host_on(struct if_cb_manager *man_core, int mode);
extern void usbpd_cc_control_command(struct if_cb_manager *man_core, int is_off);
extern void usbpd_wait_entermode(struct if_cb_manager *man_core, int on);
extern void usbpd_water_pd_ta_notify(struct if_cb_manager *man_core);
extern void usbpd_sbu_switch_control(int on);
#endif /* __IF_CB_MANAGER_H__ */

View File

@@ -0,0 +1,31 @@
/*
* header file supporting USB Type-C Manager hwpram call chain information
*
* Copyright (C) 2020 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 __USB_TYPEC_MANAGER_HWPARAM_H__
#define __USB_TYPEC_MANAGER_HWPARAM_H__
void water_dry_time_update(int mode);
void wVbus_time_update(int status);
unsigned long manager_hw_param_update(int param);
void manager_hw_param_init(void);
void usb_enum_hw_param_data_update(int speed);
#endif /* __USB_TYPEC_MANAGER_HWPARAM_H__ */

View File

@@ -0,0 +1,277 @@
/*
* header file supporting USB Type-C Manager notifier call chain information
*
* Copyright (C) 2020 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 __USB_TYPEC_MANAGER_NOTIFIER_H__
#define __USB_TYPEC_MANAGER_NOTIFIER_H__
#include <linux/muic/common/muic.h>
#include <linux/muic/common/muic_notifier.h>
#if IS_ENABLED(CONFIG_VBUS_NOTIFIER)
#include <linux/vbus_notifier.h>
#endif
#include <linux/usb/typec/common/pdic_notifier.h>
#define TYPEC_MANAGER_MAJ_VERSION 2
#define TYPEC_MANAGER_MIN_VERSION 3
/* USB TypeC Manager notifier call sequence,
* largest priority number device will be called first. */
typedef enum {
/* MUIC */
MANAGER_NOTIFY_MUIC_NONE = 0,
MANAGER_NOTIFY_MUIC_USB,
MANAGER_NOTIFY_MUIC_OTG,
MANAGER_NOTIFY_MUIC_CHARGER,
MANAGER_NOTIFY_MUIC_TIMEOUT_OPEN_DEVICE,
MANAGER_NOTIFY_MUIC_UART,
/* PDIC */
MANAGER_NOTIFY_PDIC_INITIAL = 20,
MANAGER_NOTIFY_PDIC_WACOM, /* Low Priority */
MANAGER_NOTIFY_PDIC_SENSORHUB,
MANAGER_NOTIFY_PDIC_USBDP,
MANAGER_NOTIFY_PDIC_DP,
MANAGER_NOTIFY_PDIC_SUB_BATTERY,
MANAGER_NOTIFY_PDIC_BATTERY,
MANAGER_NOTIFY_PDIC_USB,
MANAGER_NOTIFY_PDIC_MUIC, /* High Priority */
MANAGER_NOTIFY_PDIC_DELAY_DONE,
} manager_notifier_device_t;
typedef enum {
PD_USB_TYPE,
PD_TA_TYPE,
PD_NONE_TYPE,
} pd_usb_state_t;
typedef enum
{
VBUS_NOTIFIER = 1 << 0,
PDIC_NOTIFIER = 1 << 1,
MUIC_NOTIFIER = 1 << 2,
ALL_NOTIFIER = VBUS_NOTIFIER | PDIC_NOTIFIER | MUIC_NOTIFIER
}notifier_register;
typedef struct
{
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t sub1:16;
uint64_t sub2:16;
uint64_t sub3:16;
void *pd;
} MANAGER_NOTI_TYPEDEF;
struct typec_manager_event_work
{
struct work_struct typec_manager_work;
MANAGER_NOTI_TYPEDEF event;
};
struct manager_dwork {
struct delayed_work dwork;
bool pending;
};
struct manager_usb_dwork {
struct delayed_work dwork;
int data;
bool pending;
};
struct manager_dp {
int is_support;
int attach_state;
int cable_type;
int hpd_state;
int is_connect;
int hs_connect;
int check_done;
};
struct manager_water {
int detected;
int detOnPowerOff;
int wVbus_det;
int report_type;
};
struct typec_manager_muic {
int attach_state;
int cable_type;
};
struct typec_manager_usb {
int dr;
int notified_dr;
int enum_state;
bool enable_state;
u64 event_time_stamp;
};
typedef struct _manager_data_t
{
struct blocking_notifier_head manager_muic_notifier;
struct blocking_notifier_head manager_notifier;
struct notifier_block pdic_nb;
struct notifier_block muic_nb;
#if IS_ENABLED(CONFIG_VBUS_NOTIFIER)
struct notifier_block vbus_nb;
#endif
#if defined(CONFIG_CABLE_TYPE_NOTIFIER)
struct notifier_block cable_type_nb;
#endif
int confirm_notifier_register;
int notifier_register_try_count;
struct delayed_work manager_init_work;
struct workqueue_struct *manager_noti_wq;
struct workqueue_struct *manager_muic_noti_wq;
struct manager_dwork usb_enum_check;
struct manager_dwork usb_event_by_vbus;
#if IS_ENABLED(CONFIG_MUIC_POGO)
struct manager_dwork usb_event_by_pogo;
#endif
struct manager_usb_dwork manager_usb_event_delayed_work;
struct mutex mo_lock;
int vbus_state;
#if IS_ENABLED(CONFIG_MUIC_POGO)
int is_muic_pogo;
#endif
int classified_cable_type;
int pdic_attach_state;
int pdic_rid_state;
int alt_is_support;
int usb_factory;
u64 otg_stamp;
int vbus_by_otg_detection;
int pd_con_state;
int svid_info;
void *pd;
char fac_control[16];
struct typec_manager_usb usb;
struct typec_manager_muic muic;
#ifdef CONFIG_USE_SECOND_MUIC
struct typec_manager_muic second_muic;
#endif
struct manager_water water;
struct manager_dp dp;
struct notifier_block manager_external_notifier_nb;
struct typec_manager_gadget_ops *gadget_ops;
}manager_data_t;
struct typec_manager_gadget_ops {
void *driver_data;
int (*get_cmply_link_state)(void *dev);
};
typedef union {
struct {
uint64_t src:4;
uint64_t dest:4;
uint64_t id:8;
uint64_t sub1:16;
uint64_t sub2:16;
uint64_t sub3:16;
};
uint64_t noti_event;
} MANAGER_NOTI_TYPEDEF_REF;
#define PDIC_BATTERY (1<<0)
#define PDIC_USB (1<<1)
#define PDIC_DP (1<<2)
#define PDIC_DELAY_DONE (1<<3)
/* Timeout to check for USB enumeration */
#define CANCEL_USB_DWORK 0
#define MAX_USB_DWORK_TIME 120000
#define MIN_USB_DWORK_TIME 2000
#ifdef CONFIG_USB_CONFIGFS_F_MBIM
#define BOOT_USB_DWORK_TIME 9000
#else
#define BOOT_USB_DWORK_TIME 18000
#endif
/* Timeout for USB off when Vbus is in LOW state */
#define VBUS_USB_OFF_TIMEOUT 1000
/* Time to check whether it is VBUS by OTG to prevent moisture popup error */
#define OTG_VBUS_CHECK_TIME 300
/* Time to retry when Notifier registration fails */
#define NOTIFIER_REG_RETRY_TIME 2000
#define NOTIFIER_REG_RETRY_COUNT 5
#define USB_EVENT_INTERVAL_CHECK_TIME 300
#define MANAGER_NOTIFIER_BLOCK(name) \
struct notifier_block (name)
#define SET_MANAGER_NOTIFIER_BLOCK(nb, fn, dev) do { \
(nb)->notifier_call = (fn); \
(nb)->priority = (dev); \
} while (0)
#define DESTROY_MANAGER_NOTIFIER_BLOCK(nb) \
SET_MANAGER_NOTIFIER_BLOCK(nb, NULL, -1)
/* pdic notifier register/unregister API
* for used any where want to receive pdic attached device attach/detach. */
int manager_notifier_register(struct notifier_block *nb,
notifier_fn_t notifier, manager_notifier_device_t listener);
int manager_notifier_unregister(struct notifier_block *nb);
void manager_notifier_usbdp_support(void);
void set_usb_enumeration_state(int state);
void set_usb_enable_state(void);
void probe_typec_manager_gadget_ops (struct typec_manager_gadget_ops *ops);
#ifdef CONFIG_USB_USING_ADVANCED_USBLOG
#define utmanager_info(fmt, ...) \
({ \
pr_info(fmt, ##__VA_ARGS__); \
printk_usb(NOTIFY_PRINTK_USB_NORMAL, fmt, ##__VA_ARGS__); \
})
#define utmanager_err(fmt, ...) \
({ \
pr_err(fmt, ##__VA_ARGS__); \
printk_usb(NOTIFY_PRINTK_USB_NORMAL, fmt, ##__VA_ARGS__); \
})
#else
#define utmanager_info(fmt, ...) \
({ \
pr_info(fmt, ##__VA_ARGS__); \
})
#define utmanager_err(fmt, ...) \
({ \
pr_err(fmt, ##__VA_ARGS__); \
})
#endif
#endif /* __USB_TYPEC_MANAGER_NOTIFIER_H__ */

View File

@@ -0,0 +1,399 @@
/*
* max77775-muic.h - MUIC for the Maxim 77775
*
* Copyright (C) 2015 Samsung Electrnoics
* Insun Choi <insun77.choi@samsung.com>
*
* 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, see <http://www.gnu.org/licenses/>.
*
* This driver is based on max14577-muic.h
*
*/
#ifndef __MAX77775_MUIC_H__
#define __MAX77775_MUIC_H__
#include <linux/workqueue.h>
#include <linux/muic/common/muic.h>
#if IS_ENABLED(CONFIG_IF_CB_MANAGER)
#include <linux/usb/typec/manager/if_cb_manager.h>
#endif
#include "max77775.h"
#define MUIC_DEV_NAME "muic-max77775"
#define MUIC_IRQ_INIT_DETECT (-1)
#define MUIC_IRQ_PDIC_HANDLER (-2)
#define MUIC_IRQ_POGO_ADC (-4)
enum max77775_adc {
MAX77775_UIADC_GND = 0x00,
MAX77775_UIADC_255K = 0x03,
MAX77775_UIADC_301K = 0x04,
MAX77775_UIADC_523K = 0x05,
MAX77775_UIADC_619K = 0x06,
MAX77775_UIADC_OPEN = 0x07,
MAX77775_UIADC_DONTCARE = 0xfe, /* ADC don't care for MHL */
MAX77775_UIADC_ERROR = 0xff, /* ADC value read error */
};
enum max77775_vbadc {
MAX77775_VBADC_3_8V_UNDER = 0x0,
MAX77775_VBADC_3_8V_TO_4_5V = 0x1,
MAX77775_VBADC_4_5V_TO_5_5V = 0x2,
MAX77775_VBADC_5_5V_TO_6_5V = 0x3,
MAX77775_VBADC_6_5V_TO_7_5V = 0x4,
MAX77775_VBADC_7_5V_TO_8_5V = 0x5,
MAX77775_VBADC_8_5V_TO_9_5V = 0x6,
MAX77775_VBADC_9_5V_TO_10_5V = 0x7,
MAX77775_VBADC_10_5V_TO_11_5V = 0x8,
MAX77775_VBADC_11_5V_TO_12_5V = 0x9,
MAX77775_VBADC_12_5V_OVER = 0xa,
};
enum max77775_muic_command_opcode {
COMMAND_BC_CTRL1_READ = OPCODE_BCCTRL1_R,
COMMAND_BC_CTRL2_READ = OPCODE_BCCTRL2_R,
COMMAND_BC_CTRL2_WRITE = OPCODE_BCCTRL2_W,
COMMAND_CONTROL1_READ = OPCODE_CTRL1_R,
COMMAND_CONTROL1_WRITE = OPCODE_CTRL1_W,
/* AFC */
COMMAND_HV_CONTROL_WRITE = OPCODE_FCCTRL1_W,
COMMAND_AFC_RESULT_READ = OPCODE_AFC_HV_RESULT_W,
COMMAND_QC_2_0_SET = OPCODE_AFC_QC_2_0_SET,
COMMAND_NONE = 0xFF,
};
#if IS_ENABLED(CONFIG_HV_MUIC_MAX77775_AFC)
enum max77775_afc_status_type {
MAX77775_MUIC_AFC_STATUS_CLEAR = (0x0),
MAX77775_MUIC_AFC_DISABLE_CHANGE_DURING_WORK = (0x1 << 0),
MAX77775_MUIC_AFC_DISABLE_CHANGE_DURING_WORK_END = ~(0x1 << 0),
MAX77775_MUIC_AFC_SET_VOLTAGE_CHANGE_DURING_WORK = (0x1 << 1),
MAX77775_MUIC_AFC_SET_VOLTAGE_CHANGE_DURING_WORK_END = ~(0x1 << 1),
MAX77775_MUIC_AFC_WORK_PROCESS = (0x1 << 2),
MAX77775_MUIC_AFC_WORK_PROCESS_END = ~(0x1 << 2)
};
#endif /* CONFIG_HV_MUIC_MAX77775_AFC */
#define AFC_OP_OUT_LEN 11 /* OPCODE(1) + Result(1) + VBADC(1) + RX Data(8) */
#if defined(CONFIG_HICCUP_CHARGER)
enum MUIC_HICCUP_MODE {
MUIC_HICCUP_MODE_OFF = 0,
MUIC_HICCUP_MODE_ON,
};
#endif
#define MUIC_PDIC_NOTI_ATTACH (1)
#define MUIC_PDIC_NOTI_DETACH (-1)
#define MUIC_PDIC_NOTI_UNDEFINED (0)
struct max77775_muic_ccic_evt {
int ccic_evt_attached; /* 1: attached, -1: detached, 0: undefined */
int ccic_evt_rid; /* the last rid */
int ccic_evt_rprd; /*rprd */
int ccic_evt_roleswap; /* check rprd role swap event */
int ccic_evt_dcdcnt; /* count dcd timeout */
};
/* muic chip specific internal data structure */
struct max77775_muic_data {
struct device *dev;
struct i2c_client *i2c; /* i2c addr: 0x4A; MUIC */
struct mutex muic_mutex;
struct wakeup_source *muic_ws;
#if IS_ENABLED(CONFIG_MUIC_AFC_RETRY)
struct wakeup_source *afc_retry_ws;
#endif
/* model dependent mfd platform data */
struct max77775_platform_data *mfd_pdata;
struct max77775_usbc_platform_data *usbc_pdata;
int irq_uiadc;
int irq_chgtyp;
int irq_spr;
int irq_dcdtmo;
int irq_vbadc;
int irq_vbusdet;
/* model dependent muic platform data */
struct muic_platform_data *pdata;
/* muic current attached device */
muic_attached_dev_t attached_dev;
void *attached_func;
bool is_muic_ready;
bool is_muic_reset;
u8 adcmode;
u8 switch_val;
/* check is otg test */
bool is_otg_test;
/* muic HV charger */
bool is_factory_start;
bool is_check_hv;
bool is_charger_ready;
bool is_afc_reset;
bool is_skip_bigdata;
bool is_charger_mode;
bool is_usb_fail;
u8 is_boot_dpdnvden;
struct delayed_work afc_work;
struct work_struct afc_handle_work;
struct mutex afc_lock;
unsigned char afc_op_dataout[AFC_OP_OUT_LEN];
int hv_voltage;
int reserve_hv_voltage;
int afc_retry;
int dcdtmo_retry;
int bc1p2_retry_count;
/* hiccup mode flag */
int is_hiccup_mode;
/* muic status value */
u8 status1;
u8 status2;
u8 status3;
u8 status4;
u8 status5;
u8 status6;
struct delayed_work debug_work;
struct delayed_work stuck_check_work;
/* Fake vbus flag */
int fake_chgtyp;
#if defined(CONFIG_USB_EXTERNAL_NOTIFY)
/* USB Notifier */
struct notifier_block usb_nb;
#endif
struct max77775_muic_ccic_evt ccic_info_data;
struct work_struct ccic_info_data_work;
bool afc_water_disable;
int ccic_evt_id;
/* PDIC Notifier */
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
struct notifier_block manager_nb;
#else
struct notifier_block ccic_nb;
#endif
#if IS_ENABLED(CONFIG_MUIC_POGO)
int pogo_adc;
#endif /* CONFIG_MUIC_POGO */
#if IS_ENABLED(CONFIG_IF_CB_MANAGER)
struct muic_dev muic_d;
struct if_cb_manager *man;
#endif
};
/* max77775 muic register read/write related information defines. */
#define REG_NONE 0xff
/* MAX77775 REGISTER ENABLE or DISABLE bit */
enum max77775_reg_bit_control {
MAX77775_DISABLE_BIT = 0,
MAX77775_ENABLE_BIT,
};
/* MAX77775 STATUS1 register */
#define USBC_STATUS1_UIADC_SHIFT 0
#define USBC_STATUS1_VBADC_SHIFT 4
#define USBC_STATUS1_UIADC_MASK (0x7 << USBC_STATUS1_UIADC_SHIFT)
#define USBC_STATUS1_VBADC_MASK (0xf << USBC_STATUS1_VBADC_SHIFT)
/* MAX77775 BC STATUS register */
#define BC_STATUS_CHGTYP_SHIFT 0
#define BC_STATUS_DCDTMO_SHIFT 2
#define BC_STATUS_PRCHGTYP_SHIFT 3
#define BC_STATUS_VBUSDET_SHIFT 7
#define BC_STATUS_CHGTYP_MASK (0x3 << BC_STATUS_CHGTYP_SHIFT)
#define BC_STATUS_DCDTMO_MASK (0x1 << BC_STATUS_DCDTMO_SHIFT)
#define BC_STATUS_PRCHGTYP_MASK (0x7 << BC_STATUS_PRCHGTYP_SHIFT)
#define BC_STATUS_VBUSDET_MASK (0x1 << BC_STATUS_VBUSDET_SHIFT)
/* MAX77775 USBC_STATUS2 register - include ERROR message. */
#define USBC_STATUS2_SYSMSG_SHIFT 0
#define USBC_STATUS2_SYSMSG_MASK (0xff << USBC_STATUS2_SYSMSG_SHIFT)
/* MAX77775 DAT_IN register */
#define DAT_IN_SHIFT 0
#define DAT_IN_MASK (0xff << DAT_IN_SHIFT)
/* MAX77775 DAT_OUT register */
#define DAT_OUT_SHIFT 0
#define DAT_OUT_MASK (0xff << DAT_OUT_SHIFT)
/* MAX77775 BC_CTRL1 */
#define BC_CTRL1_DCDCpl_SHIFT 7
#define BC_CTRL1_3ADCPDet_SHIFT 4
#define BC_CTRL1_CHGDetMan_SHIFT 1
#define BC_CTRL1_CHGDetEn_SHIFT 0
#define BC_CTRL1_DCDCpl_MASK (0x1 << BC_CTRL1_DCDCpl_SHIFT)
#define BC_CTRL1_3ADCPDet_MASK (0x1 << BC_CTRL1_3ADCPDet_SHIFT)
#define BC_CTRL1_CHGDetMan_MASK (0x1 << BC_CTRL1_CHGDetMan_SHIFT)
#define BC_CTRL1_CHGDetEn_MASK (0x1 << BC_CTRL1_CHGDetEn_SHIFT)
/* MAX77775 BC_CTRL2 */
#define BC_CTRL2_DNMonEn_SHIFT 5
#define BC_CTRL2_DPDNMan_SHIFT 4
#define BC_CTRL2_DPDrv_SHIFT 2
#define BC_CTRL2_DNDrv_SHIFT 0
#define BC_CTRL2_DNMonEn_MASK (0x1 << BC_CTRL2_DNMonEn_SHIFT)
#define BC_CTRL2_DPDNMan_MASK (0x1 << BC_CTRL2_DPDNMan_SHIFT)
#define BC_CTRL2_DPDrv_MASK (0x3 << BC_CTRL2_DPDrv_SHIFT)
#define BC_CTRL2_DNDrv_MASK (0x3 << BC_CTRL2_DNDrv_SHIFT)
/* MAX77775 SWITCH COMMAND */
#define COMN1SW_SHIFT 0
#define COMP2SW_SHIFT 3
#define USBAUTODET_SHIFT 6
#define NOBCCOMP_SHIFT 7
#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
#define USBAUTODET_MASK (0x1 << USBAUTODET_SHIFT)
#define NOBCCOMP_MASK (0x1 << NOBCCOMP_SHIFT)
#define NOBCCOMP_USBAUTODET_MASK (NOBCCOMP_MASK | USBAUTODET_MASK)
#define COMSW_MASK (COMN1SW_MASK | COMP2SW_MASK)
enum {
VB_LOW = 0x00,
VB_HIGH = (0x1 << BC_STATUS_VBUSDET_SHIFT),
VB_DONTCARE = 0xff,
};
/* MAX77775 MUIC Charger Type Detection Output Value */
enum {
/* No Valid voltage at VB (Vvb < Vvbdet) */
CHGTYP_NO_VOLTAGE = 0x00,
/* Unknown (D+/D- does not present a valid USB charger signature) */
CHGTYP_USB = 0x01,
/* Charging Downstream Port */
CHGTYP_CDP = 0x02,
/* Dedicated Charger (D+/D- shorted) */
CHGTYP_DEDICATED_CHARGER = 0x03,
/* Hiccup mode, Set D+/D- to GND */
CHGTYP_HICCUP_MODE = 0xfa,
/* DCD Timeout, Open D+/D- */
CHGTYP_TIMEOUT_OPEN = 0xfb,
/* Any charger w/o USB */
CHGTYP_UNOFFICIAL_CHARGER = 0xfc,
/* Any charger type */
CHGTYP_ANY = 0xfd,
/* Don't care charger type */
CHGTYP_DONTCARE = 0xfe,
CHGTYP_MAX,
CHGTYP_INIT,
CHGTYP_MIN = CHGTYP_NO_VOLTAGE
};
/* MAX77775 MUIC Special Charger Type Detection Output value (BC_STATUS.PrChgTyp) */
enum {
PRCHGTYP_UNKNOWN = 0x00,
PRCHGTYP_SAMSUNG_2A = 0x01,
PRCHGTYP_APPLE_500MA = 0x02,
PRCHGTYP_APPLE_1A = 0x03,
PRCHGTYP_APPLE_2A = 0x04,
PRCHGTYP_APPLE_12W = 0x05,
PRCHGTYP_3A_DCP = 0x06,
PRCHGTYP_RFU = 0x07,
};
enum {
PROCESS_ATTACH = 0,
PROCESS_LOGICALLY_DETACH,
PROCESS_NONE,
};
/* muic register value for COMN1, COMN2 in Switch command */
/*
* MAX77775 Switch values
* NoBCComp [7] / USBAutoDet [6] / D+ [5:3] / D- [2:0]
* 0: Compare with BC1.2 / 1: Ignore BC1.2, Manual control
* 0: Disable / 1: Enable
* 000: Open / 001, 100: USB / 011, 101: UART
*/
enum max77775_switch_val {
MAX77775_MUIC_NOBCCOMP_DIS = 0x0,
MAX77775_MUIC_NOBCCOMP_EN = 0x1,
MAX77775_MUIC_USBAUTODET_DIS = 0x0,
MAX77775_MUIC_USBAUTODET_EN = 0x1,
MAX77775_MUIC_USBAUTODET_VAL = MAX77775_MUIC_USBAUTODET_DIS,
MAX77775_MUIC_COM_OPEN = 0x00,
MAX77775_MUIC_COM_USB = 0x01,
MAX77775_MUIC_COM_UART = 0x02,
MAX77775_MUIC_COM_UART_CP = 0x03,
};
enum {
COM_OPEN = (MAX77775_MUIC_NOBCCOMP_DIS << NOBCCOMP_SHIFT) |
(MAX77775_MUIC_USBAUTODET_VAL << USBAUTODET_SHIFT) |
(MAX77775_MUIC_COM_OPEN << COMP2SW_SHIFT) |
(MAX77775_MUIC_COM_OPEN << COMN1SW_SHIFT),
COM_USB = (MAX77775_MUIC_NOBCCOMP_DIS << NOBCCOMP_SHIFT) |
(MAX77775_MUIC_USBAUTODET_VAL << USBAUTODET_SHIFT) |
(MAX77775_MUIC_COM_USB << COMP2SW_SHIFT) |
(MAX77775_MUIC_COM_USB << COMN1SW_SHIFT),
COM_UART = (MAX77775_MUIC_NOBCCOMP_EN << NOBCCOMP_SHIFT) |
(MAX77775_MUIC_USBAUTODET_VAL << USBAUTODET_SHIFT) |
(MAX77775_MUIC_COM_UART << COMP2SW_SHIFT) |
(MAX77775_MUIC_COM_UART << COMN1SW_SHIFT),
COM_UART_CP = (MAX77775_MUIC_NOBCCOMP_EN << NOBCCOMP_SHIFT) |
(MAX77775_MUIC_USBAUTODET_VAL << USBAUTODET_SHIFT) |
(MAX77775_MUIC_COM_UART_CP << COMP2SW_SHIFT) |
(MAX77775_MUIC_COM_UART_CP << COMN1SW_SHIFT),
};
extern struct muic_platform_data muic_pdata;
extern struct device *switch_device;
extern int max77775_muic_probe(struct max77775_usbc_platform_data *usbc_data);
extern int max77775_muic_remove(struct max77775_usbc_platform_data *usbc_data);
extern void max77775_muic_shutdown(struct max77775_usbc_platform_data *usbc_data);
extern int max77775_muic_suspend(struct max77775_usbc_platform_data *usbc_data);
extern int max77775_muic_resume(struct max77775_usbc_platform_data *usbc_data);
#if IS_ENABLED(CONFIG_HV_MUIC_MAX77775_AFC)
extern bool max77775_muic_check_is_enable_afc(struct max77775_muic_data *muic_data, muic_attached_dev_t new_dev);
extern void max77775_muic_check_afc_disabled(struct max77775_muic_data *muic_data);
extern void max77775_muic_clear_hv_control(struct max77775_muic_data *muic_data);
extern int max77775_muic_afc_hv_set(struct max77775_muic_data *muic_data, int voltage);
extern int max77775_muic_qc_hv_set(struct max77775_muic_data *muic_data, int voltage);
extern void max77775_muic_handle_detect_dev_afc(struct max77775_muic_data *muic_data, unsigned char *data);
extern void max77775_muic_handle_detect_dev_qc(struct max77775_muic_data *muic_data, unsigned char *data);
extern void max77775_muic_handle_detect_dev_hv(struct max77775_muic_data *muic_data, unsigned char *data);
extern int __max77775_muic_afc_set_voltage(struct max77775_muic_data *muic_data, int voltage);
#endif /* CONFIG_HV_MUIC_MAX77775_AFC */
extern void max77775_muic_register_ccic_notifier(struct max77775_muic_data *muic_data);
extern void max77775_muic_unregister_ccic_notifier(struct max77775_muic_data *muic_data);
#if defined(CONFIG_USB_EXTERNAL_NOTIFY)
extern void muic_send_dock_intent(int type);
#endif /* CONFIG_USB_EXTERNAL_NOTIFY */
extern void max77775_muic_enable_detecting_short(struct max77775_muic_data *muic_data);
#endif /* __MAX77775_MUIC_H__ */

View File

@@ -0,0 +1,610 @@
/*
* Copyrights (C) 2017 Samsung Electronics, Inc.
* Copyrights (C) 2017 Maxim Integrated Products, 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.
*
* 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.
*/
#ifndef __LINUX_MFD_MAX77775_H
#define __LINUX_MFD_MAX77775_H
#define MAX77775_CCPD_NAME "MAX77775"
#undef __CONST_FFS
#define __CONST_FFS(_x) \
((_x) & 0x0F ? \
((_x) & 0x03 ? ((_x) & 0x01 ? 0 : 1) : ((_x) & 0x04 ? 2 : 3)) : \
((_x) & 0x30 ? ((_x) & 0x10 ? 4 : 5) : ((_x) & 0x40 ? 6 : 7)))
#undef FFS
#define FFS(_x) \
((_x) ? __CONST_FFS(_x) : 0)
#undef BIT_RSVD
#define BIT_RSVD 0
#undef BITS
#define BITS(_end, _start) \
((BIT(_end) - BIT(_start)) + BIT(_end))
#undef __BITS_GET
#define __BITS_GET(_word, _mask, _shift) \
(((_word) & (_mask)) >> (_shift))
#undef BITS_GET
#define BITS_GET(_word, _bit) \
__BITS_GET(_word, _bit, FFS(_bit))
#undef __BITS_SET
#define __BITS_SET(_word, _mask, _shift, _val) \
(((_word) & ~(_mask)) | (((_val) << (_shift)) & (_mask)))
#undef BITS_SET
#define BITS_SET(_word, _bit, _val) \
__BITS_SET(_word, _bit, FFS(_bit), _val)
#undef BITS_MATCH
#define BITS_MATCH(_word, _bit) \
(((_word) & (_bit)) == (_bit))
/*
* Register address
*/
#define REG_PRODUCT_ID 0x10 /* replaced address */
#define REG_UIC_FW_REV 0x01
#define REG_UIC_INT 0x02
#define REG_CC_INT 0x03
#define REG_PD_INT 0x04
#define REG_VDM_INT 0x05
#define REG_SPARE_INT 0x06
#define REG_USBC_STATUS1 0x08
#define REG_USBC_STATUS2 0x09
#define REG_BC_STATUS 0x0A
#define REG_UIC_FW_REV2 0x0B
#define REG_CC_STATUS1 0x0C
#define REG_CC_STATUS2 0x0D
#define REG_PD_STATUS1 0x0E
#define REG_PD_STATUS2 0x0F
#define REG_UIC_INT_M 0x12
#define REG_CC_INT_M 0x13
#define REG_PD_INT_M 0x14
#define REG_VDM_INT_M 0x15
#define REG_SPARE_INT_M 0x16
#define REG_OPCODE 0x21
#define REG_OPCODE_DATA 0x22
#define REG_OPCDE_RES 0x51
#define REG_END_DATA 0x41
/*
* REG_INT_M Initial values
*/
#define REG_UIC_INT_M_INIT 0x04
#define REG_CC_INT_M_INIT 0x20
#define REG_PD_INT_M_INIT 0x00
#define REG_VDM_INT_M_INIT 0xF0
#if defined(CONFIG_MAX77775_CCOPEN_AFTER_WATERCABLE)
#define REG_SPARE_INT_M_INIT 0x3F
#else
#define REG_SPARE_INT_M_INIT 0x7F
#endif
/*
* REG_UIC_INT Interrupts
*/
#define BIT_APCmdResI BIT(7)
#define BIT_SYSMsgI BIT(6)
#define BIT_VBUSDetI BIT(5)
#define BIT_VbADCI BIT(4)
#define BIT_DCDTmoI BIT(3)
#define BIT_CHGTypI BIT(1)
#define BIT_UIDADCI BIT(0)
/*
* REG_CC_INT Interrupts
*/
#define BIT_VCONNOCPI BIT(7)
#define BIT_VSAFE0VI BIT(6)
#define BIT_DETABRTI BIT(5)
#define BIT_VCONNSCI BIT(4)
#define BIT_CCPinStatI BIT(3)
#define BIT_CCIStatI BIT(2)
#define BIT_CCVcnStatI BIT(1)
#define BIT_CCStatI BIT(0)
/*
* REG_PD_INT Interrupts
*/
#define BIT_PDMsgI BIT(7)
#define BIT_DataRole BIT(5)
#define BIT_SSAccI BIT(1)
#define BIT_FCTIDI BIT(0)
/*
* REG_SPARE_INT Interrupts
*/
#define BIT_USBID BIT(7)
#define BIT_TACONNI BIT(6)
/*
* REG_USBC_STATUS1
*/
#define BIT_VBADC BITS(7, 4)
#define BIT_UIDADC BITS(2, 0)
/*
* REG_USBC_STATUS2
*/
#define BIT_SYSMsg BITS(7, 0)
/*
* REG_BC_STATUS
*/
#define BIT_VBUSDet BIT(7)
#define BIT_PrChgTyp BITS(5, 3)
#define BIT_DCDTmo BIT(2)
#define BIT_ChgTyp BITS(1, 0)
/*
* REG_CC_STATUS1
*/
#define BIT_CCPinStat BITS(7, 6)
#define BIT_CCIStat BITS(5, 4)
#define BIT_CCVcnStat BIT(3)
#define BIT_CCStat BITS(2, 0)
/*
* REG_CC_STATUS2
*/
#define BIT_CCSBUSHORT BITS(7, 6)
#define BIT_VCONNOCP BIT(5)
#define BIT_VCONNSC BIT(4)
#define BIT_VSAFE0V BIT(3)
#define BIT_DETABRT BIT(2)
#define BIT_ConnStat BIT(1)
#define BIT_Altmode BIT(0)
/*
* REG_PD_STATUS1
*/
#define BIT_PDMsg BITS(7, 0)
/*
* REG_PD_STATUS2
*/
#define BIT_PD_DataRole BIT(7)
#define BIT_PD_STOP_MODE BIT(6)
#define BIT_PD_ENTER_MODE BIT(5)
#define BIT_PD_PSRDY BIT(4)
#define BIT_FCT_ID BITS(3, 0)
/*
* REG_SPARE_STATUS
*/
#define BIT_SPARE_CC_OPEN BIT(1)
#define BIT_SPARE_TA_CONNECT BIT(0)
/** opcode reg **/
/*
* CC Control1 Write
*/
#define BIT_CCVcnEn BIT(7)
#define BIT_CCTrySnkEn BIT(6)
#define BIT_CCSrcDbgEn BIT(4)
#define BIT_CCSnkDbgEn BIT(3)
#define BIT_CCAudEn BIT(2)
#define BIT_CCSrcSnk BIT(1) // CCSrcEn
#define BIT_CCSnkSrc BIT(0) // CCSnkEn
/*
* max77766 role
*/
enum max77775_data_role {
UFP = 0,
DFP,
};
enum max77775_power_role {
SNK = 0,
SRC,
};
enum max77775_vcon_role {
OFF = 0,
ON
};
/*
* F/W update
*/
#define FW_CMD_READ 0x3
#define FW_CMD_READ_SIZE 6 /* cmd(1) + len(1) + data(4) */
#define FW_CMD_WRITE 0x1
#define FW_CMD_WRITE_SIZE 36 /* cmd(1) + len(1) + data(34) */
#define FW_CMD_END 0x0
#define FW_HEADER_SIZE 8
#define FW_VERIFY_DATA_SIZE 3
#define FW_VERIFY_TRY_COUNT 10
#define FW_SECURE_MODE_TRY_COUNT 10
#define FW_ERR_CODE_TRY_COUNT 32
#define FW_WAIT_TIMEOUT (1000 * 5) /* 5 sec */
#define I2C_SMBUS_BLOCK_HALF (I2C_SMBUS_BLOCK_MAX / 2)
#define GET_CCCTRL4_LOCK_ERROR_EN(_x) ((_x & (0x1 << 4)) >> 1)
enum {
NO_DETERMINATION = 0,
CC1_ACTIVE,
CC2_ACTVIE,
AUDIO_ACCESSORY,
DEBUG_ACCESSORY,
ERROR,
DISABLED,
DEBUG_SNK,
};
enum {
NOT_IN_UFP_MODE = 0,
CCI_500mA,
CCI_1_5A,
CCI_3_0A,
CCI_SHORT,
};
/*
* All type of Interrupts
*/
enum {
AP_Command_respond = 7,
USBC_System_message = 6,
CHGIN_Voltage = 5,
CHGIN_Voltage_ADC = 4,
DCD_Timer = 3,
Charge_Type = 1,
UID_ADC = 0,
};
enum max77775_chg_type {
CHGTYP_NOTHING = 0,
CHGTYP_USB_SDP,
CHGTYP_CDP_T,
CHGTYP_DCP,
};
enum max77775_pr_chg_type {
Unknown = 0,
Samsung_2A,
Apple_05A,
Apple_1A,
Apple_2A,
Apple_12W,
DCP_3A,
RFU_CHG,
};
enum max77775_ccpd_device {
DEV_NONE = 0,
DEV_OTG,
DEV_USB,
DEV_CDP,
DEV_DCP,
DEV_APPLE500MA,
DEV_APPLE1A,
DEV_APPLE2A,
DEV_APPLE12W,
DEV_DCP3A,
DEV_HVDCP,
DEV_QC,
DEV_FCT_GND,
DEV_FCT_1K,
DEV_FCT_56K,
DEV_FCT_255K,
DEV_FCT_301K,
DEV_FCT_523K,
DEV_FCT_619K,
DEV_FCT_OPEN,
DEV_PD_TA,
DEV_PD_AMA,
DEV_UNKNOWN,
};
enum max77775_uidadc {
UID_GND = 0,
UID_100Kohm = 1,
UID_255Kohm = 3,
UID_301Kohm = 4,
UID_523Kohm = 5,
UID_619Kohm = 6,
UID_Open = 7,
};
enum max77775_fctid {
FCT_GND = 1,
FCT_56Kohm = 2,
FCT_255Kohm = 3,
FCT_301Kohm = 4,
FCT_523Kohm = 5,
FCT_619Kohm = 6,
FCT_OPEN = 7,
};
enum max77775_cc_pin_state {
cc_No_Connection = 0,
cc_SINK,
cc_SOURCE,
cc_Audio_Accessory,
cc_Debug_Accessory,
cc_Error,
cc_Disabled,
cc_Debug_Sink,
};
enum max77775_usbc_SYSMsg {
SYSERROR_NONE = 0x00,
/*Reserved = 0x01,*/
/*Reserved = 0x02,*/
SYSERROR_BOOT_WDT = 0x03,
SYSERROR_BOOT_SWRSTREQ = 0x04,
SYSMSG_BOOT_POR = 0x05,
SYSERROR_HV_NOVBUS = 0x10,
SYSERROR_HV_FMETHOD_RXPERR = 0x11,
SYSERROR_HV_FMETHOD_RXBUFOW = 0x12,
SYSERROR_HV_FMETHOD_RXTFR = 0x13,
SYSERROR_HV_FMETHOD_MPNACK = 0x14,
SYSERROR_HV_FMETHOD_RESET_FAIL = 0x15,
SYSMsg_AFC_Done = 0x20,
SYSERROR_SYSPOS = 0x30,
SYSERROR_APCMD_UNKNOWN = 0x31,
SYSERROR_APCMD_INPROGRESS = 0x32,
SYSERROR_APCMD_FAIL = 0x33,
SYSMSG_CCx_5V_AFC_SHORT = 0x61,
SYSMSG_SBUx_GND_SHORT = 0x62,
SYSMSG_CCx_5V_SHORT = 0x65,
SYSMSG_SBUx_5V_SHORT = 0x66,
SYSERROR_FACTORY_RID0 = 0x70,
SYSERROR_POWER_NEGO = 0x80,
SYSERROR_CCRP_HIGH = 0x90, /* PD Charger Connected while Water state */
SYSERROR_CCRP_LOW = 0x91, /* PD Charger Disconnected while Water state */
SYSMSG_RELEASE_CC1_SHORT = 0xB3,
SYSMSG_RELEASE_CC2_SHORT = 0xB4,
SYSMSG_ABNORMAL_TA = 0xC1,
};
enum max77775_pdmsg {
Nothing_happened = 0x00,
Sink_PD_PSRdy_received = 0x01,
Sink_PD_Error_Recovery = 0x02,
Sink_PD_SenderResponseTimer_Timeout = 0x03,
Source_PD_PSRdy_Sent = 0x04,
Source_PD_Error_Recovery = 0x05,
Source_PD_SenderResponseTimer_Timeout = 0x06,
PD_DR_Swap_Request_Received = 0x07,
PD_PR_Swap_Request_Received = 0x08,
PD_VCONN_Swap_Request_Received = 0x09,
Received_PD_Message_in_illegal_state = 0x0A,
SRC_CAP_RECEIVED = 0x0B,
Samsung_Accessory_is_attached = 0x10,
VDM_Attention_message_Received = 0x11,
Rejcet_Received = 0x12,
Not_Supported_Received = 0x13,
Prswap_Snktosrc_Sent = 0x14,
Prswap_Srctosnk_Sent = 0x15,
HARDRESET_RECEIVED = 0x16,
Get_Vbus_turn_on = 0x17,
Get_Vbus_turn_off = 0x18,
HARDRESET_SENT = 0x19,
PRSWAP_SRCTOSWAP = 0x1A,
PRSWAP_SWAPTOSNK = 0X1B,
PRSWAP_SNKTOSWAP = 0x1C,
PRSWAP_SWAPTOSRC = 0x1D,
Sink_PD_Disabled = 0x20,
Source_PD_Disabled = 0x21,
Current_Cable_Connected = 0x22,
Get_Source_Capabilities_Extended_Received = 0x30,
Get_Status_Received = 0x31,
Get_Battery_Cap_Received = 0x32,
Get_Battery_Status_Received = 0x33,
Get_Manufacturer_Info_Received = 0x34,
Source_Capabilities_Extended_Received = 0x35,
Status_Received = 0x36,
Battery_Capabilities_Received = 0x37,
Batery_Status_Received = 0x38,
Manufacturer_Info_Received = 0x39,
Alert_Message = 0x3e,
VDM_NAK_Recevied = 0x40,
VDM_BUSY_Recevied = 0x41,
VDM_ACK_Recevied = 0x42,
VDM_REQ_Recevied = 0x43,
AFC_Sink_PD_Capabilities_Received = 0x50,
AFC_Sink_PD_PSRdy_Received = 0x51,
AFC_VDM_ResponseTimer_Timout = 0x52,
PDMSG_DP_DISCOVER_IDENTITY = 0x61,
PDMSG_DP_DISCOVER_SVID = 0x62,
PDMSG_DP_DISCOVER_MODES = 0x63,
PDMSG_DP_ENTER_MODE = 0x64,
PDMSG_DP_EXIT_MODE = 0x65,
PDMSG_DP_STATUS = 0x66,
PDMSG_DP_CONFIGURE = 0x67,
PDMSG_DP_ATTENTION = 0x68,
PDMSG_SRC_ACCEPT = 0x70,
};
enum max77775_connstat {
DRY = 0x00,
WATER = 0x01,
};
/*
* External type definition
*/
#define MAX77775_AUTOIBUS_FW_AT_OFF 3
#define MAX77775_AUTOIBUS_FW_OFF 2
#define MAX77775_AUTOIBUS_AT_OFF 1
#define MAX77775_AUTOIBUS_ON 0
#define OPCODE_WAIT_TIMEOUT (3000) /* 3000ms */
#define OPCODE_WRITE_COMMAND 0x21
#define OPCODE_READ_COMMAND 0x51
#define OPCODE_SIZE 1
#define OPCODE_HEADER_SIZE 1
#define OPCODE_DATA_LENGTH 32
#define OPCODE_MAX_LENGTH (OPCODE_DATA_LENGTH + OPCODE_SIZE)
#define OPCODE_WRITE 0x21
#define OPCODE_DATAOUT1 0x22
#define OPCODE_WRITE_END 0x41
#define OPCODE_READ 0x51
#define OPCODE_WRITE_SEQ 0x1
#define OPCODE_READ_SEQ 0x2
#define OPCODE_RW_SEQ 0x3
#define OPCODE_PUSH_SEQ 0x4
#define OPCODE_UPDATE_SEQ 0x5
typedef enum {
OPCODE_BCCTRL1_R = 0x01,
OPCODE_BCCTRL1_W,
OPCODE_BCCTRL2_R,
OPCODE_BCCTRL2_W,
OPCODE_CTRL1_R = 0x05,
OPCODE_CTRL1_W,
OPCODE_CCCTRL1_R = 0x0B,
OPCODE_CCCTRL1_W,
OPCODE_CCCTRL2_R,
OPCODE_CCCTRL2_W,
OPCODE_CCCTRL3_R,
OPCODE_CCCTRL3_W,
OPCODE_CCCTRL4_R = 0x11,
OPCODE_CCCTRL4_W,
OPCODE_VCONN_ILIM_R = 0x13,
OPCODE_VCONN_ILIM_W,
OPCODE_CCCTRL5_W = 0x16,
OPCODE_AFC_HV_W = 0x20,
OPCODE_AFC_HV_RESULT_W = 0x21,
OPCODE_AFC_QC_2_0_SET = 0x22,
OPCODE_CHGIN_ILIM_R = 0x25,
OPCODE_CHGIN_ILIM_W,
OPCODE_USB_ID_SET = 0x27,
OPCODE_READ_SBU = 0x28,
OPCODE_CONTROL_JIG_R = 0x29,
OPCODE_CONTROL_JIG_W = 0x2A,
OPCODE_ICURR_AUTOIBUS_ON = 0x2C,
OPCODE_SET_SNKCAP = 0x2E,
OPCODE_READ_CC = 0x2D,
OPCODE_CURRENT_SRCCAP = 0x30,
OPCODE_GET_SRCCAP = 0x31,
OPCODE_SRCCAP_REQUEST = 0x32,
OPCODE_SET_SRCCAP = 0x33,
OPCODE_SEND_GET_REQUEST = 0x34,
OPCODE_READ_RESPONSE_FOR_GET_REQUEST = 0x35,
OPCODE_SWAP_REQUEST = 0x37,
OPCODE_APDO_SRCCAP_REQUEST = 0x3A,
OPCODE_SET_PPS = 0x3C,
OPCODE_VDM_DISCOVER_SET_VDM_REQ = 0x48,
OPCODE_VDM_DISCOVER_GET_VDM_RESP = 0x4B,
OPCODE_SAMSUNG_FACTORY_TEST = 0x54,
OPCODE_SET_ALTERNATEMODE = 0x55,
OPCODE_SAMSUNG_CCSBU_SHORT = 0x56,
OPCODE_SAMSUNG_FW_AUTOIBUS = 0x57,
OPCODE_SAMSUNG_READ_MESSAGE = 0x5D,
OPCODE_SNK_SELECTED_PDO = 0x65,
OPCODE_FW_OPCODE_CLEAR = 0x70,
OPCODE_CHG_CONTROL1_R = 0x7F,
OPCODE_SBU_CTRL1_R = 0x85,
OPCODE_SBU_CTRL1_W = 0x86,
OPCODE_FCCTRL1_W = 0x88,
OPCODE_MOISTURE_CC_OPEN = 0x9C,
OPCODE_ACTIVE_DISCHARGE = 0x91,
OPCODE_HICCUP_ENABLE = 0x92,
OPCODE_AUTO_SHIPMODE = 0x97,
OPCODE_BYPASS_MTN = 0x98,
OPCODE_CHGRCV_RAMP = 0x9F,
OPCODE_NONE = 0xff,
} max77775_opcode_list;
typedef enum{
OPCODE_ID_VDM_DISCOVER_IDENTITY = 0x1,
OPCODE_ID_VDM_DISCOVER_SVIDS = 0x2,
OPCODE_ID_VDM_DISCOVER_MODES = 0x3,
OPCODE_ID_VDM_ENTER_MODE = 0x4,
OPCODE_ID_VDM_EXIT_MODE = 0x5,
OPCODE_ID_VDM_ATTENTION = 0x6,
OPCODE_ID_VDM_SVID_DP_STATUS = 0x10,
OPCODE_ID_VDM_SVID_DP_CONFIGURE = 0x11,
} max77775_vdm_list;
enum{
OPCODE_GET_SRC_CAP_EXT = 0,
OPCODE_GET_STATUS,
OPCODE_GET_BAT_CAP,
OPCODE_GET_BAT_STS,
OPCODE_GET_MANUFACTURE_INFO,
};
typedef enum {
OPCODE_WAIT_START = 0,
OPCODE_WAIT_END,
} max77775_opcode_wait_type;
typedef enum {
OPCODE_NOTI_START = 0x0,
OPCODE_NOTI_NONE = 0xff,
} max77775_opcode_noti_cmd;
/* SAMSUNG OPCODE */
#define REG_NONE 0xff
#define CCIC_IRQ_INIT_DETECT (-1)
//#define MINOR_VERSION_MASK 0b00000111
/* PRODUCT ID */
#define FW_PRODUCT_ID_REG 3
//#define STAR_PRODUCT_ID 0b0000
//#define Lykan_PRODUCT_ID 0b0001
//#define BEYOND_PRODUCT_ID 0b0010
#endif

View File

@@ -0,0 +1,628 @@
/*
* Copyrights (C) 2017 Samsung Electronics, Inc.
* Copyrights (C) 2017 Maxim Integrated Products, 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.
*
* 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.
*/
#ifndef __LINUX_MAXIM_CCIC_ALTERNATE_MODE_H__
#define __LINUX_MAXIM_CCIC_ALTERNATE_MODE_H__
#if defined(CONFIG_MAX77775_CCIC_ALTERNATE_MODE)
typedef union { /* new defined union for MD05 Op Code Command Data */
uint8_t DATA;
struct {
uint8_t BDATA[1];
} BYTES;
struct {
uint8_t Num_Of_VDO:3,
Cmd_Type:2,
Reserved:3;
} BITS;
} SEND_VDM_BYTE_DATA;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Number_of_obj:3,
MSG_ID:3,
Port_Power_Role:1,
Specification_Rev:2,
Port_Data_Role:1,
Reserved:1,
MSG_Type:4;
} BITS;
} UND_DATA_MSG_HEADER_Type;
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;
} UND_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;
} UND_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;
} UND_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;
} UND_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;
} UND_CABLE_VDO_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t SVID_1:16,
SVID_0:16;
} BITS;
} UND_VDO1_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t VENDOR_DEFINED_MESSAGE:15,
VDM_TYPE:1,
USB_Vendor_ID:16;
} BITS;
} UND_UNSTRUCTURED_VDM_HEADER_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t DATA:8,
TOTAL_NUMBER_OF_UVDM_SET:4,
RESERVED:1,
COMMAND_TYPE:2,
DATA_TYPE:1,
PID:16;
} BITS;
} UND_SEC_UNSTRUCTURED_VDM_HEADER_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t VENDOR_DEFINED_MESSAGE:15,
VDM_TYPE:1,
USB_Vendor_ID:16;
} BITS;
} UND_SEC_DATA_HEADER_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t VENDOR_DEFINED_MESSAGE:15,
VDM_TYPE:1,
USB_Vendor_ID:16;
} BITS;
} UND_SEC_DATA_TAILER_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t ORDER_OF_CURRENT_UVDM_SET:4,
RESERVED:9,
COMMAND_TYPE:2,
DATA_TYPE:1,
PID:16;
} BITS;
} UND_SEC_UNSTRUCTURED_VDM_RESPONSE_HEADER_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t VENDOR_DEFINED_MESSAGE:15,
VDM_TYPE:1,
USB_Vendor_ID:16;
} BITS;
} UND_SEC_DATA_RESPONSE_HEADER_Type;
typedef struct {
uint32_t VDO[7];
} VDO_MESSAGE_Type;
/* For DP */
#define TypeC_POWER_SINK_INPUT 0
#define TypeC_POWER_SOURCE_OUTPUT 1
#define TypeC_DP_SUPPORT (0xFF01)
/* For Dex */
#define TypeC_Dex_SUPPORT (0x04E8)
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
/* For DP VDM Modes VDO Port_Capability */
typedef enum {
num_Reserved_Capable = 0,
num_UFP_D_Capable = 1,
num_DFP_D_Capable = 2,
num_DFP_D_and_UFP_D_Capable = 3
} Num_DP_Port_Capability_Type;
/* For DP VDM Modes VDO Receptacle_Indication */
typedef enum {
num_USB_TYPE_C_PLUG = 0,
num_USB_TYPE_C_Receptacle = 1
} Num_DP_Receptacle_Indication_Type;
/* For DP_Status_Update Port_Connected */
typedef enum {
num_Adaptor_Disable = 0,
num_Connect_DFP_D = 1,
num_Connect_UFP_D = 2,
num_Connect_DFP_D_and_UFP_D = 3
} Num_DP_Port_Connected_Type;
/* For DP_Configure Select_Configuration */
typedef enum {
num_Cfg_for_USB = 0,
num_Cfg_UFP_U_as_DFP_D = 1,
num_Cfg_UFP_U_as_UFP_D = 2,
num_Cfg_Reserved = 3
} Num_DP_Sel_Configuration_Type;
typedef enum { /* There is another Macro definitions which are similiar to this */
REQ = 0,
ACK = 1,
NAK = 2,
BUSY = 3
} VDM_CMD_TYPE;
typedef enum {
Reserved = 0,
Discover_Identity = 1,
Discover_SVIDs = 2,
Discover_Modes = 3,
Enter_Mode = 4,
Exit_Mode = 5,
Attention = 6,
Configure = 17
} VDM_HEADER_COMMAND;
typedef enum {
Version_1_0 = 0,
Version_2_0 = 1,
Reserved1 = 2,
Reserved2 = 3
} STRUCTURED_VDM_VERSION;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Port_Capability:2,
Signalling_DP:4,
Receptacle_Indication:1,
USB_2p0_Not_Used:1,
DFP_D_Pin_Assignments:8,
UFP_D_Pin_Assignments:8,
DP_MODE_VDO_Reserved:8;
} BITS;
} UND_VDO_MODE_DP_CAPABILITY_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t Port_Connected:2,
Power_Low:1,
Enabled:1,
Multi_Function_Preference:1,
USB_Configuration_Req:1,
Exit_DP_Mode_Req:1,
HPD_State:1,
HPD_Interrupt:1,
Reserved:23;
} BITS;
} UND_VDO_DP_STATUS_UPDATES_Type;
typedef union {
uint32_t DATA;
struct {
uint8_t BDATA[4];
} BYTES;
struct {
uint32_t SEL_Configuration:2,
Select_DP_V1p3:1,
Select_USB_Gen2:1,
Select_Reserved_1:2,
Select_Reserved_2:2,
DFP_D_PIN_Assign_A:1,
DFP_D_PIN_Assign_B:1,
DFP_D_PIN_Assign_C:1,
DFP_D_PIN_Assign_D:1,
DFP_D_PIN_Assign_E:1,
DFP_D_PIN_Assign_F:1,
DFP_D_PIN_Reserved:2,
UFP_D_PIN_Assign_A:1,
UFP_D_PIN_Assign_B:1,
UFP_D_PIN_Assign_C:1,
UFP_D_PIN_Assign_D:1,
UFP_D_PIN_Assign_E:1,
UFP_D_PIN_Assign_F:1,
UFP_D_PIN_Reserved:2,
DP_MODE_Reserved:8;
} BITS;
} UND_DP_CONFIG_UPDATE_Type;
typedef struct {
UND_DATA_MSG_HEADER_Type MSG_HEADER;
UND_DATA_MSG_VDM_HEADER_Type DATA_MSG_VDM_HEADER;
UND_VDO_MODE_DP_CAPABILITY_Type DATA_MSG_MODE_VDO_DP;
} DIS_MODE_DP_CAPA_Type;
typedef struct {
UND_DATA_MSG_HEADER_Type MSG_HEADER;
UND_DATA_MSG_VDM_HEADER_Type DATA_MSG_VDM_HEADER;
UND_VDO_DP_STATUS_UPDATES_Type DATA_DP_STATUS_UPDATE;
} DP_STATUS_UPDATE_Type;
typedef struct {
UND_DATA_MSG_HEADER_Type MSG_HEADER;
UND_DATA_MSG_VDM_HEADER_Type DATA_MSG_VDM_HEADER;
UND_VDO_DP_STATUS_UPDATES_Type DATA_MSG_DP_STATUS;
} DIS_ATTENTION_MESSAGE_DP_STATUS_Type;
enum VDM_MSG_IRQ_State {
VDM_DISCOVER_ID = (1 << 0),
VDM_DISCOVER_SVIDS = (1 << 1),
VDM_DISCOVER_MODES = (1 << 2),
VDM_ENTER_MODE = (1 << 3),
VDM_EXIT_MODE = (1 << 4),
VDM_ATTENTION = (1 << 5),
VDM_DP_STATUS_UPDATE = (1 << 6),
VDM_DP_CONFIGURE = (1 << 7),
};
#define ALTERNATE_MODE_NOT_READY (1 << 0)
#define ALTERNATE_MODE_READY (1 << 1)
#define ALTERNATE_MODE_STOP (1 << 2)
#define ALTERNATE_MODE_START (1 << 3)
#define ALTERNATE_MODE_RESET (1 << 4)
/* VMD Message Register I2C address by S.LSI */
#define REG_VDM_MSG_REQ 0x02C0
#define REG_SSM_MSG_READ 0x0340
#define REG_SSM_MSG_SEND 0x0360
#define REG_TX_DIS_ID_RESPONSE 0x0400
#define REG_TX_DIS_SVID_RESPONSE 0x0420
#define REG_TX_DIS_MODE_RESPONSE 0x0440
#define REG_TX_ENTER_MODE_RESPONSE 0x0460
#define REG_TX_EXIT_MODE_RESPONSE 0x0480
#define REG_TX_DIS_ATTENTION_RESPONSE 0x04A0
#define REG_RX_DIS_ID_CABLE 0x0500
#define REG_RX_DIS_ID 0x0520
#define REG_RX_DIS_SVID 0x0540
#define REG_RX_MODE 0x0560
#define REG_RX_ENTER_MODE 0x0580
#define REG_RX_EXIT_MODE 0x05A0
#define REG_RX_DIS_ATTENTION 0x05C0
#define REG_RX_DIS_DP_STATUS_UPDATE 0x0600
#define REG_RX_DIS_DP_CONFIGURE 0x0620
#define MODE_INT_CLEAR 0x01
#define PD_NEXT_STATE 0x02
#define MODE_INTERFACE 0x03
#define SVID_SELECT 0x07
#define REQ_PR_SWAP 0x10
#define REQ_DR_SWAP 0x11
#define SEL_SSM_MSG_REQ 0x20
#define DP_ALT_MODE_REQ 0x30
/* Samsung Acc VID */
#define SAMSUNG_VENDOR_ID 0x04E8
#define SAMSUNG_MPA_VENDOR_ID 0x04B4
/* Samsung Acc PID */
#define GEARVR_PRODUCT_ID 0xA500
#define GEARVR_PRODUCT_ID_1 0xA501
#define GEARVR_PRODUCT_ID_2 0xA502
#define GEARVR_PRODUCT_ID_3 0xA503
#define GEARVR_PRODUCT_ID_4 0xA504
#define GEARVR_PRODUCT_ID_5 0xA505
#define DEXDOCK_PRODUCT_ID 0xA020
#define HDMI_PRODUCT_ID 0xA025
#define MPA2_PRODUCT_ID 0xA027
#define UVDM_PROTOCOL_ID 0xA028
#define DEXPAD_PRODUCT_ID 0xA029
#define MPA_PRODUCT_ID 0x2122
/* Samsung UVDM structure */
#define SEC_UVDM_SHORT_DATA 0x0
#define SEC_UVDM_LONG_DATA 0x1
#define SEC_UVDM_ININIATOR 0x0
#define SEC_UVDM_RESPONDER_ACK 0x1
#define SEC_UVDM_RESPONDER_NAK 0x2
#define SEC_UVDM_RESPONDER_BUSY 0x3
#define UNSTRUCTURED_VDM 0x0
#define STRUCTURED_VDM 1
/*For DP Pin Assignment */
#define DP_PIN_ASSIGNMENT_NODE 0x00000000
#define DP_PIN_ASSIGNMENT_A 0x00000001 /* ( 1 << 0 ) */
#define DP_PIN_ASSIGNMENT_B 0x00000002 /* ( 1 << 1 ) */
#define DP_PIN_ASSIGNMENT_C 0x00000004 /* ( 1 << 2 ) */
#define DP_PIN_ASSIGNMENT_D 0x00000008 /* ( 1 << 3 ) */
#define DP_PIN_ASSIGNMENT_E 0x00000010 /* ( 1 << 4 ) */
#define DP_PIN_ASSIGNMENT_F 0x00000020 /* ( 1 << 5 ) */
#define DISCOVER_IDENTITY_RESPONSE_SIZE 31
#define DISCOVER_SVIDS_RESPONSE_SIZE 31
#define DISCOVER_MODES_RESPONSE_SIZE 11
#define ENTER_MODE_RESPONSE_SIZE 7
#define ATTENTION_RESPONSE_SIZE 11
#define DP_STATUS_RESPONSE_SIZE 11
#define DP_CONFIGURE_RESPONSE_SIZE 11
#define SAMSUNGUVDM_DEXFAN_RESPONSE_SIZE 31
#define SAMSUNGUVDM_MAX_LONGPACKET_SIZE (236)
#define SAMSUNGUVDM_MAX_SHORTPACKET_SIZE (1)
#define SAMSUNGUVDM_WAIT_MS (2000)
#define SAMSUNGUVDM_ALIGN (4)
#define SAMSUNGUVDM_UVDM_HEADER_OFFSET (4)
#define SAMSUNGUVDM_MAXDATA_FIRST_UVDMSET (12)
#define SAMSUNGUVDM_MAXDATA_NORMAL_UVDMSET (16)
#define SAMSUNGUVDM_CHECKSUM_DATA_COUNT (20)
#define MSG_HEADER_OFFSET (0)
#define VDM_HEADER_OFFSET (2)
#define VDO1_OFFSET (6)
#define VDO2_OFFSET (10)
enum uvdm_rx_type {
RX_ACK = 0,
RX_NAK,
RX_BUSY,
};
typedef union sec_uvdm_header {
uint32_t data;
struct {
uint8_t bdata[4];
} BYTES;
struct {
uint32_t data:8,
total_number_of_uvdm_set:4,
direction:1,
command_type:2,
data_type:1,
pid:16;
} BITS;
} U_SEC_UVDM_HEADER;
typedef U_SEC_UVDM_HEADER U_SEC_UVDM_RESPONSE_HEADER;
typedef union sec_tx_data_header {
uint32_t data;
struct {
uint8_t bdata[4];
} BYTES;
struct {
uint32_t data_size_of_current_set:8,
total_data_size:8,
reserved:12,
order_of_current_uvdm_set:4;
} BITS;
} U_SEC_TX_DATA_HEADER;
typedef union sec_data_tx_tailer {
uint32_t data;
struct {
uint8_t bdata[4];
} BYTES;
struct {
uint32_t checksum:16,
reserved:16;
} BITS;
} U_SEC_TX_DATA_TAILER;
typedef union sec_data_rx_header {
uint32_t data;
struct {
uint8_t bdata[4];
} BYTES;
struct {
uint32_t reserved:18,
result_value:2,
received_data_size_of_current_set:8,
order_of_current_uvdm_set:4;
} BITS;
} U_SEC_RX_DATA_HEADER;
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;
#define SEC_UVDM_LONGPACKET_WAIT_MS (6000)
#define SEC_UVDM_RX_HEADER_ACK 0x0
#define SEC_UVDM_RX_HEADER_NAK 0x1
#define MAXIM_ENABLE_ALTERNATE_SRCCAP 0x1
#define MAXIM_ENABLE_ALTERNATE_VDM 0x2
#define MAXIM_ENABLE_ALTERNATE_SRC_VDM 0x3
#define MAXIM_DISABLE_ALTERNATE_SRC_VDM 0x0
typedef union {
uint32_t DATA;
uint8_t BYTES[4];
struct {
uint32_t Vdm_Flag_Reserve_b0:1, /* b0 */
Vdm_Flag_Discover_ID:1, /* b1 */
Vdm_Flag_Discover_SVIDs:1, /* b2 */
Vdm_Flag_Discover_MODEs:1, /* b3 */
Vdm_Flag_Enter_Mode:1, /* b4 */
Vdm_Flag_Exit_Mode:1, /* b5 */
Vdm_Flag_Attention:1, /* b6 */
Vdm_Flag_Reserved:9, /* b7 - b15 */
Vdm_Flag_DP_Status_Update:1, /* b16 */
Vdm_Flag_DP_Configure:1, /* b17 */
Vdm_Flag_Reserved2:14; /* b18 - b31 */
} BITS;
} MAX77775_VDM_MSG_IRQ_STATUS_Type;
struct DP_DP_DISCOVER_IDENTITY { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
} __attribute__((aligned(1), packed));
struct DP_DP_DISCOVER_ENTER_MODE { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
} __attribute__((aligned(1), packed));
struct DP_DP_STATUS { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
UND_VDO_DP_STATUS_UPDATES_Type vdo_status;
} __attribute__((aligned(1), packed));
struct DP_DP_CONFIGURE { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
UND_DP_CONFIG_UPDATE_Type vdo_config;
} __attribute__((aligned(1), packed));
struct SS_DEX_DISCOVER_MODE { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
} __attribute__((aligned(1), packed));
struct SS_DEX_ENTER_MODE { /* struct type definition */
SEND_VDM_BYTE_DATA byte_data;
UND_DATA_MSG_VDM_HEADER_Type vdm_header;
} __attribute__((aligned(1), packed));
struct SS_UNSTRUCTURED_VDM_MSG{
SEND_VDM_BYTE_DATA byte_data;
VDO_MESSAGE_Type VDO_MSG;
} __attribute__((aligned(1), packed));
void max77775_receive_alternate_message(struct max77775_usbc_platform_data *data,
MAX77775_VDM_MSG_IRQ_STATUS_Type *VDM_MSG_IRQ_State);
void max77775_vdm_message_handler(struct max77775_usbc_platform_data *usbpd_data,
char *opcode_data, int len);
void max77775_uvdm_opcode_response_handler(struct max77775_usbc_platform_data *usbpd_data,
char *opcode_data, int len);
void max77775_send_dex_fan_unstructured_vdm_message(void *data, int cmd);
void max77775_set_enable_alternate_mode(int mode);
int max77775_process_check_accessory(void *data);
extern void max77775_set_discover_identity(void *data);
extern void max77775_set_dp_configure(void *data, uint8_t w_data);
extern void max77775_set_dex_enter_mode(void *data);
extern int max77775_sec_uvdm_in_request_message(void *data);
extern int max77775_sec_uvdm_out_request_message(void *data, int size);
extern int max77775_sec_uvdm_ready(void);
extern void max77775_sec_uvdm_close(void);
#endif
#endif

View File

@@ -0,0 +1,70 @@
/*
* Copyrights (C) 2017 Samsung Electronics, Inc.
* Copyrights (C) 2017 Maxim Integrated Products, 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.
*
* 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.
*/
#ifndef __LINUX_MFD_MAX77775_CC_H
#define __LINUX_MFD_MAX77775_CC_H
#include <linux/pm_wakeup.h>
#define MAX77775_CC_NAME "max77775_CC"
#define MAX77865_IRQSRC_CHG (1 << 0)
#define MAX77865_IRQSRC_FG (1 << 2)
struct max77775_cc_data {
/* interrupt pin */
int irq_vconncop;
int irq_vsafe0v;
int irq_detabrt;
int irq_vconnsc;
int irq_ccpinstat;
int irq_ccistat;
int irq_ccvcnstat;
int irq_ccstat;
u8 usbc_status1;
u8 usbc_status2;
u8 bc_status;
u8 cc_status1;
u8 cc_status2;
u8 pd_status1;
u8 pd_status2;
u8 opcode_res;
/* VCONN Over Current Detection */
u8 vconnocp;
/* VCONN Over Short Circuit Detection */
u8 vconnsc;
/* Status of VBUS Detection */
u8 vsafe0v;
/* Charger Detection Abort Status */
u8 detabrt;
/* Output of active CC pin */
u8 ccpinstat;
/* CC Pin Detected Allowed VBUS Current in UFP mode */
u8 ccistat;
/* Status of Vconn Output */
u8 ccvcnstat;
/* CC Pin State Machine Detection */
u8 ccstat;
enum max77775_vcon_role current_vcon;
enum max77775_vcon_role previous_vcon;
enum max77775_power_role current_pr;
enum max77775_power_role previous_pr;
struct wakeup_source ccstat_ws;
};
#endif

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __MAX77775_KUNIT_H__
#define __MAX77775_KUNIT_H__
#if IS_ENABLED(CONFIG_SEC_KUNIT)
#include <kunit/mock.h>
#endif
#ifndef __mockable
#define __mockable
#endif
#ifndef __visible_for_testing
#define __visible_for_testing static
#endif
#ifndef EXPORT_SYMBOL_KUNIT
#define EXPORT_SYMBOL_KUNIT(sym) /* nothing */
#endif
#endif /* __MAX77775_KUNIT_H__ */

View File

@@ -0,0 +1,144 @@
/*
* Copyrights (C) 2017 Samsung Electronics, Inc.
* Copyrights (C) 2017 Maxim Integrated Products, 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.
*
* 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.
*/
#ifndef __LINUX_MFD_MAX77775_PD_H
#define __LINUX_MFD_MAX77775_PD_H
#include "max77775.h"
#if IS_ENABLED(CONFIG_BATTERY_SAMSUNG)
#include <linux/battery/sec_pd.h>
#endif
#define MAX77775_PD_NAME "MAX77775_PD"
enum {
CC_SNK = 0,
CC_SRC,
CC_NO_CONN,
};
enum {
D2D_NONE = 0,
D2D_SNKONLY,
D2D_SRCSNK,
};
typedef enum {
PDO_TYPE_FIXED = 0,
PDO_TYPE_BATTERY,
PDO_TYPE_VARIABLE,
PDO_TYPE_APDO
} pdo_supply_type_t;
typedef union sec_pdo_object {
uint32_t data;
struct {
uint8_t bdata[4];
} BYTES;
struct {
uint32_t reserved:30,
type:2;
} BITS_supply;
struct {
uint32_t max_current:10, /* 10mA units */
voltage:10, /* 50mV units */
peak_current:2,
reserved:2,
unchuncked_extended_messages_supported:1,
data_role_data:1,
usb_communications_capable:1,
unconstrained_power:1,
usb_suspend_supported:1,
dual_role_power:1,
supply:2; /* Fixed supply : 00b */
} BITS_pdo_fixed;
struct {
uint32_t max_current:10, /* 10mA units */
min_voltage:10, /* 50mV units */
max_voltage:10, /* 50mV units */
supply:2; /* Variable Supply (non-Battery) : 10b */
} BITS_pdo_variable;
struct {
uint32_t max_allowable_power:10, /* 250mW units */
min_voltage:10, /* 50mV units */
max_voltage:10, /* 50mV units */
supply:2; /* Battery : 01b */
} BITS_pdo_battery;
struct {
uint32_t max_current:7, /* 50mA units */
reserved1:1,
min_voltage:8, /* 100mV units */
reserved2:1,
max_voltage:8, /* 100mV units */
reserved3:2,
pps_power_limited:1,
pps_supply:2,
supply:2; /* APDO : 11b */
} BITS_pdo_programmable;
} U_SEC_PDO_OBJECT;
struct max77775_pd_data {
/* interrupt pin */
int irq_pdmsg;
int irq_psrdy;
int irq_datarole;
int irq_ssacc;
int irq_fct_id;
u8 usbc_status1;
u8 usbc_status2;
u8 bc_status;
u8 cc_status1;
u8 cc_status2;
u8 pd_status1;
u8 pd_status2;
u8 opcode_res;
/* PD Message */
u8 pdsmg;
/* Data Role */
enum max77775_data_role current_dr;
enum max77775_data_role previous_dr;
/* SSacc */
u8 ssacc;
/* FCT cable */
u8 fct_id;
enum max77775_ccpd_device device;
#if IS_ENABLED(CONFIG_BATTERY_SAMSUNG)
struct pdic_notifier_struct pd_noti;
#endif
bool pdo_list;
bool psrdy_received;
bool cc_sbu_short;
bool bPPS_on;
bool sent_chg_info;
struct workqueue_struct *wqueue;
struct delayed_work retry_work;
struct delayed_work d2d_work;
struct delayed_work abnormal_pdo_work;
int cc_status;
int src_cap_done;
int auth_type;
int d2d_type;
int req_pdo_type;
bool psrdy_sent;
};
#endif

View File

@@ -0,0 +1,391 @@
/*
* Copyrights (C) 2017 Samsung Electronics, Inc.
* Copyrights (C) 2017 Maxim Integrated Products, 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.
*
* 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.
*/
#ifndef __LINUX_MFD_MAX77775_UIC_H
#define __LINUX_MFD_MAX77775_UIC_H
#if IS_ENABLED(CONFIG_BATTERY_SAMSUNG)
#include <linux/battery/sec_pd.h>
#endif
#include <linux/usb/typec.h>
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
#include <linux/usb/typec/common/pdic_core.h>
#endif
#if IS_ENABLED(CONFIG_IF_CB_MANAGER)
#include <linux/usb/typec/manager/if_cb_manager.h>
#endif
#include <linux/usb/typec/maxim/max77775_kunit.h>
#include "max77775_pd.h"
#include "max77775_cc.h"
#define MAX77775_SYS_FW_UPDATE
#define MAX77775_MAX_APDCMD_TIME (7*HZ)
struct max77775_opcode {
unsigned char opcode;
unsigned char data[OPCODE_DATA_LENGTH];
int read_length;
int write_length;
};
typedef struct max77775_usbc_command_data {
u8 opcode;
u8 prev_opcode;
u8 response;
u8 read_data[OPCODE_DATA_LENGTH];
u8 write_data[OPCODE_DATA_LENGTH];
int read_length;
int write_length;
u8 reg;
u8 val;
u8 mask;
u8 seq;
int noti_cmd;
u8 is_uvdm;
} usbc_cmd_data;
typedef struct max77775_usbc_command_node {
usbc_cmd_data cmd_data;
struct max77775_usbc_command_node *next;
} usbc_cmd_node;
typedef struct max77775_usbc_command_node *usbc_cmd_node_p;
typedef struct max77775_usbc_command_queue {
struct mutex command_mutex;
usbc_cmd_node *front;
usbc_cmd_node *rear;
usbc_cmd_node tmp_cmd_node;
} usbc_cmd_queue_t;
#if defined(CONFIG_SEC_FACTORY)
#define FAC_ABNORMAL_REPEAT_STATE 12
#define FAC_ABNORMAL_REPEAT_RID 5
#define FAC_ABNORMAL_REPEAT_RID0 3
struct AP_REQ_GET_STATUS_Type {
uint32_t FAC_Abnormal_Repeat_State;
uint32_t FAC_Abnormal_Repeat_RID;
uint32_t FAC_Abnormal_RID0;
};
#endif
#define NAME_LEN_HMD 14
#define MAX_NUM_HMD 32
#define TAG_HMD "HMD"
#define MAX_NVCN_CNT 30 /* No vbus & connection */
#define MAX_CHK_TIME 30
struct max77775_hmd_power_dev {
uint vid;
uint pid;
char hmd_name[NAME_LEN_HMD];
};
struct max77775_usb_mock {
int (*opcode_write)(void *usbc_data,
usbc_cmd_data *write_op);
int (*opcode_read)(void *usbc_data,
usbc_cmd_data *read_op);
int (*opcode_push)(void *usbc_data,
usbc_cmd_data *read_op);
int (*opcode_update)(void *usbc_data,
usbc_cmd_data *update_op);
int (*opcode_rw)(void *usbc_data,
usbc_cmd_data *opcode_r, usbc_cmd_data *opcode_w);
void (*ccic_event_work)(void *data, int dest,
int id, int attach, int event, int sub);
int (*check_accessory)(void *data);
};
struct max77775_usbc_platform_data {
struct max77775_dev *max77775;
struct device *dev;
struct i2c_client *i2c; /*0xCC */
struct i2c_client *muic; /*0x4A */
struct i2c_client *charger; /*0x2A; Charger */
int irq_base;
/* interrupt pin */
int irq_apcmd;
int irq_sysmsg;
/* VDM pin */
int irq_vdm0;
int irq_vdm1;
int irq_vdm2;
int irq_vdm3;
int irq_vdm4;
int irq_vdm5;
int irq_vdm6;
int irq_vdm7;
int irq_vir0;
/* USBID pin */
int irq_usbid;
#if defined(CONFIG_MAX77775_CCOPEN_AFTER_WATERCABLE)
/* TA Connect pin */
int irq_taconn;
u8 ta_conn_status;
struct delayed_work set_ccopen_for_watercable_work;
#endif
/* register information */
u8 usbc_status1;
u8 usbc_status2;
u8 bc_status;
u8 cc_status1;
u8 cc_status2;
u8 pd_status1;
u8 pd_status2;
/* opcode register information */
u8 op_ctrl1_w;
int watchdog_count;
int por_count;
int opcode_fail_count;
int stuck_suppose;
u8 opcode_res;
/* USBC System message interrupt */
u8 sysmsg;
u8 pd_msg;
/* F/W state */
u8 HW_Revision;
u8 FW_Revision;
u8 FW_Minor_Revision;
u8 plug_attach_done;
int op_code_done;
enum max77775_connstat prev_connstat;
enum max77775_connstat current_connstat;
/* F/W opcode Thread */
struct work_struct op_wait_work;
struct work_struct op_send_work;
struct work_struct cc_open_req_work;
struct work_struct dp_configure_work;
#ifdef MAX77775_SYS_FW_UPDATE
struct work_struct fw_update_work;
#endif
struct workqueue_struct *op_wait_queue;
struct workqueue_struct *op_send_queue;
struct completion op_completion;
int op_code;
int is_first_booting;
usbc_cmd_data last_opcode;
unsigned long opcode_stamp;
struct mutex op_lock;
/* F/W opcode command data */
usbc_cmd_queue_t usbc_cmd_queue;
uint32_t alternate_state;
uint32_t acc_type;
uint32_t Vendor_ID;
uint32_t Product_ID;
uint32_t Device_Version;
uint32_t SVID_0;
uint32_t SVID_1;
uint32_t SVID_DP;
struct delayed_work acc_detach_work;
uint32_t dp_is_connect;
uint32_t dp_hs_connect;
uint32_t dp_selected_pin;
u8 pin_assignment;
uint32_t is_sent_pin_configuration;
wait_queue_head_t host_turn_on_wait_q;
wait_queue_head_t device_add_wait_q;
int host_turn_on_event;
int host_turn_on_wait_time;
int device_add;
int is_samsung_accessory_enter_mode;
int send_enter_mode_req;
u8 sbu[2];
u8 cc[2];
struct completion ccic_sysfs_completion;
struct completion psrdy_wait;
struct max77775_muic_data *muic_data;
struct max77775_pd_data *pd_data;
struct max77775_cc_data *cc_data;
struct max77775_platform_data *max77775_data;
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
ppdic_data_t ppdic_data;
struct workqueue_struct *ccic_wq;
int manual_lpm_mode;
int fac_water_enable;
int cur_rid;
int pd_state;
u8 vconn_test;
u8 vconn_en;
u8 fw_update;
int is_host;
int is_client;
bool auto_vbus_en;
u8 cc_pin_status;
int ccrp_state;
int vsafe0v_status;
#endif
struct typec_port *port;
struct typec_partner *partner;
struct usb_pd_identity partner_identity;
struct typec_capability typec_cap;
struct completion typec_reverse_completion;
int typec_power_role;
int typec_data_role;
int typec_try_state_change;
int pwr_opmode;
bool pd_support;
struct delayed_work usb_external_notifier_register_work;
struct notifier_block usb_external_notifier_nb;
int mpsm_mode;
bool mdm_block;
int vbus_enable;
int pd_pr_swap;
int shut_down;
struct delayed_work vbus_hard_reset_work;
uint8_t ReadMSG[32];
int ram_test_enable;
int ram_test_retry;
int ram_test_result;
struct completion uvdm_longpacket_out_wait;
struct completion uvdm_longpacket_in_wait;
int is_in_first_sec_uvdm_req;
int is_in_sec_uvdm_out;
bool pn_flag;
int uvdm_error;
#if defined(CONFIG_SEC_FACTORY)
struct AP_REQ_GET_STATUS_Type factory_mode;
struct delayed_work factory_state_work;
struct delayed_work factory_rid_work;
#endif
struct completion cc_open_work_completion;
int detach_done_wait;
int set_altmode;
int set_altmode_error;
#if IS_ENABLED(CONFIG_IF_CB_MANAGER)
struct usbpd_dev *usbpd_d;
struct if_cb_manager *man;
int sbu_switch_status;
#endif
u8 ccctrl4_reg;
int cc_open_req;
bool recover_opcode_list[OPCODE_NONE];
int need_recover;
bool srcccap_request_retry;
int ovp_gpio;
struct mutex hmd_power_lock;
struct max77775_hmd_power_dev *hmd_list;
#if defined(CONFIG_SUPPORT_SHIP_MODE)
int ship_mode_en;
u8 ship_mode_data;
#endif
bool rid_check;
int lapse_idx;
u64 time_lapse[MAX_NVCN_CNT];
int wait_entermode;
struct max77775_usb_mock usb_mock;
};
/* Function Status from s2mm005 definition */
typedef enum {
max77775_State_PE_Initial_detach = 0,
max77775_State_PE_SRC_Send_Capabilities = 3,
max77775_State_PE_SNK_Wait_for_Capabilities = 17,
} max77775_pd_state_t;
typedef enum {
MPSM_OFF = 0,
MPSM_ON = 1,
} CCIC_DEVICE_MPSM;
#define DATA_ROLE_SWAP 1
#define POWER_ROLE_SWAP 2
#define VCONN_ROLE_SWAP 3
#define MANUAL_ROLE_SWAP 4
#define ROLE_ACCEPT 0x1
#define ROLE_REJECT 0x2
#define ROLE_BUSY 0x3
int max77775_pd_init(struct max77775_usbc_platform_data *usbc_data);
int max77775_cc_init(struct max77775_usbc_platform_data *usbc_data);
int max77775_muic_init(struct max77775_usbc_platform_data *usbc_data);
int max77775_i2c_opcode_read(struct max77775_usbc_platform_data *usbc_data,
u8 opcode, u8 length, u8 *values);
void init_usbc_cmd_data(usbc_cmd_data *cmd_data);
void max77775_usbc_clear_queue(struct max77775_usbc_platform_data *usbc_data);
int max77775_usbc_opcode_rw(struct max77775_usbc_platform_data *usbc_data,
usbc_cmd_data *opcode_r, usbc_cmd_data *opcode_w);
int max77775_usbc_opcode_write(struct max77775_usbc_platform_data *usbc_data,
usbc_cmd_data *write_op);
int max77775_usbc_opcode_read(struct max77775_usbc_platform_data *usbc_data,
usbc_cmd_data *read_op);
int max77775_usbc_opcode_push(struct max77775_usbc_platform_data *usbc_data,
usbc_cmd_data *read_op);
int max77775_usbc_opcode_update(struct max77775_usbc_platform_data *usbc_data,
usbc_cmd_data *read_op);
void max77775_ccic_event_work(void *data, int dest, int id,
int attach, int event, int sub);
void max77775_notify_dr_status(struct max77775_usbc_platform_data *usbpd_data,
uint8_t attach);
void max77775_pdo_list(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_response_pdo_request(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_response_apdo_request(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_response_set_pps(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_send_new_src_cap_push(struct max77775_usbc_platform_data *pusbpd, int auth, int d2d_type);
void max77775_response_req_pdo(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_current_pdo(struct max77775_usbc_platform_data *usbc_data,
unsigned char *data);
void max77775_check_pdo(struct max77775_usbc_platform_data *usbc_data);
void max77775_detach_pd(struct max77775_usbc_platform_data *usbc_data);
void max77775_notify_rp_current_level(struct max77775_usbc_platform_data *usbc_data);
extern void max77775_set_jig_on(struct max77775_usbc_platform_data *usbpd_data, int mode);
extern void max77775_vbus_turn_on_ctrl(struct max77775_usbc_platform_data *usbc_data, bool enable, bool swaped);
extern void max77775_dp_detach(void *data);
void max77775_usbc_disable_auto_vbus(struct max77775_usbc_platform_data *usbc_data);
extern void max77775_pdic_manual_ccopen_request(int is_on);
int max77775_get_pd_support(struct max77775_usbc_platform_data *usbc_data);
bool max77775_sec_pps_control(int en);
bool max77775_check_hmd_dev(struct max77775_usbc_platform_data *usbpd_data);
void max77775_request_response(struct max77775_usbc_platform_data *usbc_data);
#if defined(CONFIG_SEC_FACTORY)
void factory_execute_monitor(int);
#endif
bool max77775_need_check_stuck(struct max77775_usbc_platform_data *usbc_data);
void max77775_send_check_stuck_opcode(struct max77775_usbc_platform_data *usbpd_data);
bool is_empty_usbc_cmd_queue(usbc_cmd_queue_t *usbc_cmd_queue);
extern void max77775_chg_check_stuck(int chgin_dtls);
#endif

View File

@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __UCSI_GLINK_H__
#define __UCSI_GLINK_H__
#include <linux/errno.h>
#include <linux/usb/typec.h>
struct ucsi_glink_constat_info {
enum typec_accessory acc;
};
struct notifier_block;
#if IS_ENABLED(CONFIG_UCSI_QTI_GLINK)
int register_ucsi_glink_notifier(struct notifier_block *nb);
int unregister_ucsi_glink_notifier(struct notifier_block *nb);
#else
static inline int register_ucsi_glink_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
static inline int unregister_ucsi_glink_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2013, 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_USB_QDSS_H
#define __LINUX_USB_QDSS_H
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
#define USB_QDSS_CH_EBC "qdss_ebc"
#define USB_QDSS_CH_MDM "qdss_mdm"
#define USB_QDSS_CH_SW "qdss_sw"
struct qdss_request {
char *buf;
int length;
int actual;
int status;
void *context;
struct scatterlist *sg;
unsigned int num_sgs;
};
struct usb_qdss_ch;
enum qdss_state {
USB_QDSS_CONNECT,
USB_QDSS_DISCONNECT,
USB_QDSS_CTRL_READ_DONE,
USB_QDSS_DATA_WRITE_DONE,
};
#if IS_ENABLED(CONFIG_USB_F_QDSS)
struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv,
void (*notify)(void *priv, unsigned int event,
struct qdss_request *d_req, struct usb_qdss_ch *ch));
void usb_qdss_close(struct usb_qdss_ch *ch);
int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write);
void usb_qdss_free_req(struct usb_qdss_ch *ch);
int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req);
#else
static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv,
void (*n)(void *, unsigned int event,
struct qdss_request *d, struct usb_qdss_ch *c))
{
return ERR_PTR(-ENODEV);
}
static inline int usb_qdss_write(struct usb_qdss_ch *c, struct qdss_request *d)
{
return -ENODEV;
}
static inline int usb_qdss_alloc_req(struct usb_qdss_ch *c, int n_wr, int n_rd)
{
return -ENODEV;
}
static inline void usb_qdss_close(struct usb_qdss_ch *ch) { }
static inline void usb_qdss_free_req(struct usb_qdss_ch *ch) { }
#endif /* CONFIG_USB_F_QDSS */
#endif