#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/interrupt.h>
#include <linux/usb/typec.h>
#include <linux/usb/typec_altmode.h>
#include <linux/usb/role.h>
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include "tps6598x.h"
#include "trace.h"
#define TPS_REG_VID …
#define TPS_REG_MODE …
#define TPS_REG_CMD1 …
#define TPS_REG_DATA1 …
#define TPS_REG_VERSION …
#define TPS_REG_INT_EVENT1 …
#define TPS_REG_INT_EVENT2 …
#define TPS_REG_INT_MASK1 …
#define TPS_REG_INT_MASK2 …
#define TPS_REG_INT_CLEAR1 …
#define TPS_REG_INT_CLEAR2 …
#define TPS_REG_SYSTEM_POWER_STATE …
#define TPS_REG_STATUS …
#define TPS_REG_SYSTEM_CONF …
#define TPS_REG_CTRL_CONF …
#define TPS_REG_BOOT_STATUS …
#define TPS_REG_POWER_STATUS …
#define TPS_REG_PD_STATUS …
#define TPS_REG_RX_IDENTITY_SOP …
#define TPS_REG_DATA_STATUS …
#define TPS_REG_SLEEP_CONF …
#define TPS_SYSCONF_PORTINFO(c) …
#define TPS_BUNDLE_TIMEOUT …
#define TPS_TASK_BPMS_INVALID_BUNDLE_SIZE …
#define TPS_TASK_BPMS_INVALID_SLAVE_ADDR …
#define TPS_TASK_BPMS_INVALID_TIMEOUT …
#define TPS_PBMC_RC …
#define TPS_PBMC_DPCS …
#define TPS_SETUP_MS …
enum { … };
struct tps6598x_rx_identity_reg { … } __packed;
#define TPS_TASK_TIMEOUT …
#define TPS_TASK_REJECTED …
enum { … };
static const char *const modes[] = …;
#define INVALID_CMD(_cmd_) …
struct tps6598x;
struct tipd_data { … };
struct tps6598x { … };
static enum power_supply_property tps6598x_psy_props[] = …;
static const char *tps6598x_psy_name_prefix = …;
#define TPS_MAX_LEN …
static int
tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len)
{ … }
static int tps6598x_block_write(struct tps6598x *tps, u8 reg,
const void *val, size_t len)
{ … }
static inline int tps6598x_read8(struct tps6598x *tps, u8 reg, u8 *val)
{ … }
static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val)
{ … }
static inline int tps6598x_read32(struct tps6598x *tps, u8 reg, u32 *val)
{ … }
static inline int tps6598x_read64(struct tps6598x *tps, u8 reg, u64 *val)
{ … }
static inline int tps6598x_write8(struct tps6598x *tps, u8 reg, u8 val)
{ … }
static inline int tps6598x_write64(struct tps6598x *tps, u8 reg, u64 val)
{ … }
static inline int
tps6598x_write_4cc(struct tps6598x *tps, u8 reg, const char *val)
{ … }
static int tps6598x_read_partner_identity(struct tps6598x *tps)
{ … }
static void tps6598x_set_data_role(struct tps6598x *tps,
enum typec_data_role role, bool connected)
{ … }
static int tps6598x_connect(struct tps6598x *tps, u32 status)
{ … }
static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
{ … }
static int tps6598x_exec_cmd_tmo(struct tps6598x *tps, const char *cmd,
size_t in_len, const u8 *in_data,
size_t out_len, u8 *out_data,
u32 cmd_timeout_ms, u32 res_delay_ms)
{ … }
static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd,
size_t in_len, const u8 *in_data,
size_t out_len, u8 *out_data)
{ … }
static int tps6598x_dr_set(struct typec_port *port, enum typec_data_role role)
{ … }
static int tps6598x_pr_set(struct typec_port *port, enum typec_role role)
{ … }
static const struct typec_operations tps6598x_ops = …;
static bool tps6598x_read_status(struct tps6598x *tps, u32 *status)
{ … }
static bool tps6598x_read_data_status(struct tps6598x *tps)
{ … }
static bool tps6598x_read_power_status(struct tps6598x *tps)
{ … }
static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status)
{ … }
static irqreturn_t cd321x_interrupt(int irq, void *data)
{ … }
static bool tps6598x_has_role_changed(struct tps6598x *tps, u32 status)
{ … }
static irqreturn_t tps25750_interrupt(int irq, void *data)
{ … }
static irqreturn_t tps6598x_interrupt(int irq, void *data)
{ … }
#define POLL_INTERVAL …
static void tps6598x_poll_work(struct work_struct *work)
{ … }
static int tps6598x_check_mode(struct tps6598x *tps)
{ … }
static const struct regmap_config tps6598x_regmap_config = …;
static int tps6598x_psy_get_online(struct tps6598x *tps,
union power_supply_propval *val)
{ … }
static int tps6598x_psy_get_prop(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{ … }
static int cd321x_switch_power_state(struct tps6598x *tps, u8 target_state)
{ … }
static int devm_tps6598_psy_register(struct tps6598x *tps)
{ … }
static int
tps6598x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
{ … }
static int tps_request_firmware(struct tps6598x *tps, const struct firmware **fw,
const char **firmware_name)
{ … }
static int
tps25750_write_firmware(struct tps6598x *tps,
u8 bpms_addr, const u8 *data, size_t len)
{ … }
static int
tps25750_exec_pbms(struct tps6598x *tps, u8 *in_data, size_t in_len)
{ … }
static int tps25750_abort_patch_process(struct tps6598x *tps)
{ … }
static int tps25750_start_patch_burst_mode(struct tps6598x *tps)
{ … }
static int tps25750_complete_patch_process(struct tps6598x *tps)
{ … }
static int tps25750_apply_patch(struct tps6598x *tps)
{
int ret;
unsigned long timeout;
u64 status = 0;
ret = tps6598x_block_read(tps, TPS_REG_BOOT_STATUS, &status, 5);
if (ret)
return ret;
if (status & TPS_BOOT_STATUS_I2C_EEPROM_PRESENT)
goto wait_for_app;
ret = tps25750_start_patch_burst_mode(tps);
if (ret) {
tps25750_abort_patch_process(tps);
return ret;
}
ret = tps25750_complete_patch_process(tps);
if (ret)
return ret;
wait_for_app:
timeout = jiffies + msecs_to_jiffies(1000);
do {
ret = tps6598x_check_mode(tps);
if (ret < 0)
return ret;
if (time_is_before_jiffies(timeout))
return -ETIMEDOUT;
} while (ret != TPS_MODE_APP);
if (status & TPS_BOOT_STATUS_DEAD_BATTERY_FLAG) {
ret = tps6598x_exec_cmd(tps, "DBfg", 0, NULL, 0, NULL);
if (ret) {
dev_err(tps->dev, "failed to clear dead battery %d\n", ret);
return ret;
}
}
dev_info(tps->dev, "controller switched to \"APP\" mode\n");
return 0;
};
static int tps6598x_apply_patch(struct tps6598x *tps)
{ … }
static int cd321x_init(struct tps6598x *tps)
{ … }
static int tps25750_init(struct tps6598x *tps)
{ … }
static int tps6598x_init(struct tps6598x *tps)
{ … }
static int cd321x_reset(struct tps6598x *tps)
{ … }
static int tps25750_reset(struct tps6598x *tps)
{ … }
static int tps6598x_reset(struct tps6598x *tps)
{ … }
static int
tps25750_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
{ … }
static int tps6598x_probe(struct i2c_client *client)
{ … }
static void tps6598x_remove(struct i2c_client *client)
{ … }
static int __maybe_unused tps6598x_suspend(struct device *dev)
{ … }
static int __maybe_unused tps6598x_resume(struct device *dev)
{ … }
static const struct dev_pm_ops tps6598x_pm_ops = …;
static const struct tipd_data cd321x_data = …;
static const struct tipd_data tps6598x_data = …;
static const struct tipd_data tps25750_data = …;
static const struct of_device_id tps6598x_of_match[] = …;
MODULE_DEVICE_TABLE(of, tps6598x_of_match);
static const struct i2c_device_id tps6598x_id[] = …;
MODULE_DEVICE_TABLE(i2c, tps6598x_id);
static struct i2c_driver tps6598x_i2c_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;