This commit is contained in:
tmakin committed 2026-09-12 01:04:02 -05:00
1 parent f9b2980f86
commit 366514a4be
1 file changed
+28 -10
+28 -10
View File
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#define DEBUG 1
/* /*
* Driver for Rohm BM92TXX USB Type-C and Power Delivery controller * Driver for Rohm BM92TXX USB Type-C and Power Delivery controller
* *
@@ -29,6 +31,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/extcon-provider.h> #include <linux/extcon-provider.h>
#include <linux/mutex.h>
#include <linux/usb/role.h> #include <linux/usb/role.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
@@ -394,23 +397,23 @@ enum bm92t_state_type {
DOCK_CONFIG_HANDLED DOCK_CONFIG_HANDLED
}; };
struct __packed pd_object { struct pd_object {
unsigned int amp:10; unsigned int amp:10;
unsigned int volt:10; unsigned int volt:10;
unsigned int info:10; unsigned int info:10;
unsigned int type:2; unsigned int type:2;
}; } __packed;
struct __packed rd_object { struct rd_object {
unsigned int max_amp:10; unsigned int max_amp:10;
unsigned int op_amp:10; unsigned int op_amp:10;
unsigned int info:6; unsigned int info:6;
unsigned int usb_comms:1; unsigned int usb_comms:1;
unsigned int mismatch:1; unsigned int mismatch:1;
unsigned int obj_no:4; unsigned int obj_no:4;
}; } __packed;
struct __packed vd_object { struct vd_object {
unsigned int vid:16; unsigned int vid:16;
unsigned int rsvd:10; unsigned int rsvd:10;
unsigned int modal:1; unsigned int modal:1;
@@ -465,6 +468,7 @@ struct bm92t_info {
struct extcon_dev *edev; struct extcon_dev *edev;
struct delayed_work oneshot_work; struct delayed_work oneshot_work;
struct delayed_work power_work; struct delayed_work power_work;
struct mutex lock;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root; struct dentry *debugfs_root;
@@ -1053,7 +1057,7 @@ static void bm92t_extcon_cable_set_init_state(struct work_struct *work)
struct bm92t_info *info = container_of(to_delayed_work(work), struct bm92t_info *info = container_of(to_delayed_work(work),
struct bm92t_info, oneshot_work); struct bm92t_info, oneshot_work);
disable_irq(info->i2c_client->irq); mutex_lock(&info->lock);
bm92t_set_vbus_enable(info, false); bm92t_set_vbus_enable(info, false);
@@ -1078,7 +1082,10 @@ static void bm92t_extcon_cable_set_init_state(struct work_struct *work)
"extcon cable is set to init state\n"); "extcon cable is set to init state\n");
msleep(100); /* Wait a bit */ msleep(100); /* Wait a bit */
queue_work(info->event_wq, &info->work); //queue_work(info->event_wq, &info->work);
enable_irq(info->i2c_client->irq);
mutex_unlock(&info->lock);
} }
static bool bm92t_check_pdo(struct bm92t_info *info) static bool bm92t_check_pdo(struct bm92t_info *info)
@@ -1330,6 +1337,8 @@ static void bm92t_event_handler(struct work_struct *work)
info = container_of(work, struct bm92t_info, work); info = container_of(work, struct bm92t_info, work);
dev = &info->i2c_client->dev; dev = &info->i2c_client->dev;
mutex_lock(&info->lock);
/* Read status registers at 02h, 03h and 04h */ /* Read status registers at 02h, 03h and 04h */
err = bm92t_read_reg(info, ALERT_STATUS_REG, err = bm92t_read_reg(info, ALERT_STATUS_REG,
(unsigned char *) &alert_data, (unsigned char *) &alert_data,
@@ -1929,6 +1938,7 @@ init_contract_out:
ret: ret:
enable_irq(info->i2c_client->irq); enable_irq(info->i2c_client->irq);
mutex_unlock(&info->lock);
} }
static irqreturn_t bm92t_interrupt_handler(int irq, void *handle) static irqreturn_t bm92t_interrupt_handler(int irq, void *handle)
@@ -2177,7 +2187,7 @@ static ssize_t bm92t_cmd_write(struct file *file,
ret = kstrtouint(buf, 0, &val); ret = kstrtouint(buf, 0, &val);
if (ret == 1) { if (!ret) {
cmd = val; cmd = val;
bm92t_send_cmd(info, &cmd); bm92t_send_cmd(info, &cmd);
} else { } else {
@@ -2209,7 +2219,7 @@ static ssize_t bm92t_usbhub_dp_sleep_write(struct file *file,
ret = kstrtouint(buf, 0, &val); ret = kstrtouint(buf, 0, &val);
if (ret == 1) { if (!ret) {
bm92t_usbhub_dp_sleep(info, val ? true : false); bm92t_usbhub_dp_sleep(info, val ? true : false);
} else { } else {
dev_err(&info->i2c_client->dev, "Syntax is: 0 or number\n"); dev_err(&info->i2c_client->dev, "Syntax is: 0 or number\n");
@@ -2489,6 +2499,8 @@ static int bm92t_probe(struct i2c_client *client)
/* Disable Source mode at boot */ /* Disable Source mode at boot */
bm92t_set_source_mode(info, SPDSRC12_OFF); bm92t_set_source_mode(info, SPDSRC12_OFF);
mutex_init(&info->lock);
INIT_WORK(&info->work, bm92t_event_handler); INIT_WORK(&info->work, bm92t_event_handler);
INIT_DELAYED_WORK(&info->oneshot_work, INIT_DELAYED_WORK(&info->oneshot_work,
bm92t_extcon_cable_set_init_state); bm92t_extcon_cable_set_init_state);
@@ -2506,7 +2518,7 @@ static int bm92t_probe(struct i2c_client *client)
*/ */
if (request_threaded_irq(client->irq, NULL, if (request_threaded_irq(client->irq, NULL,
bm92t_interrupt_handler, bm92t_interrupt_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT, "bm92t", IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN, "bm92t",
info)) { info)) {
dev_err(&client->dev, "Request irq failed\n"); dev_err(&client->dev, "Request irq failed\n");
destroy_workqueue(info->event_wq); destroy_workqueue(info->event_wq);
@@ -2535,6 +2547,8 @@ static int bm92t_probe(struct i2c_client *client)
schedule_delayed_work(&info->oneshot_work, msecs_to_jiffies(100)); schedule_delayed_work(&info->oneshot_work, msecs_to_jiffies(100));
// enable_irq(client->irq);
dev_info(&client->dev, "init done\n"); dev_info(&client->dev, "init done\n");
return 0; return 0;
@@ -2595,6 +2609,8 @@ static int bm92t_pm_resume(struct device *dev)
disable_irq_wake(client->irq); disable_irq_wake(client->irq);
} }
mutex_lock(&info->lock);
/* /*
* Toggle DP signal * Toggle DP signal
* Do a toggle on resume instead of disable in suspend * Do a toggle on resume instead of disable in suspend
@@ -2610,6 +2626,8 @@ static int bm92t_pm_resume(struct device *dev)
if (enable_led) if (enable_led)
bm92t_usbhub_led_cfg_wait(info, 128, 0, 0, 64); bm92t_usbhub_led_cfg_wait(info, 128, 0, 0, 64);
mutex_unlock(&info->lock);
return 0; return 0;
} }