1
0
Fork 0

otgcontrol: implement initial FSM

Complete disabling of authenticated USB device connection in all modes

Code cleanup
- Spaces -> tabs
- Cleaner initiation sequence
pull/10/head
Steinar Bakkemo 2020-10-08 19:46:24 +02:00
parent e05abcf7da
commit 2833df5aa4
10 changed files with 1526 additions and 740 deletions

View File

@ -6,6 +6,7 @@
int otgcontrol_change_otg_charge_mode(struct rm_otgcontrol_data *otgc_data, int mode)
{
int ret;
union power_supply_propval property_val;
printk("%s: Enter\n", __func__);
@ -15,25 +16,43 @@ int otgcontrol_change_otg_charge_mode(struct rm_otgcontrol_data *otgc_data, int
case OTG1_CHARGERMODE_CHARGE:
printk("%s: Setting OTG1 chargermode (CHARGE)\n", __func__);
property_val.intval = POWER_SUPPLY_MODE_CHARGER;
power_supply_set_property(otgc_data->pdata->vbus_supply,
ret = power_supply_set_property(otgc_data->pdata->vbus_supply,
POWER_SUPPLY_PROP_CHARGER_MODE,
&property_val);
if (ret < 0) {
printk("%s: Failed to set charger mode\n", __func__);
return ret;
}
property_val.intval = 1;
power_supply_set_property(otgc_data->pdata->vbus_supply,
ret = power_supply_set_property(otgc_data->pdata->vbus_supply,
POWER_SUPPLY_PROP_ONLINE,
&property_val);
if (ret < 0) {
printk("%s: Failed to enable charging after changing charger mode\n", __func__);
return ret;
}
break;
case OTG1_CHARGERMODE_OTG:
printk("%s: Setting OTG1 chargermode (OTG)\n", __func__);
property_val.intval = POWER_SUPPLY_MODE_OTG_SUPPLY;
power_supply_set_property(otgc_data->pdata->vbus_supply,
ret = power_supply_set_property(otgc_data->pdata->vbus_supply,
POWER_SUPPLY_PROP_CHARGER_MODE,
&property_val);
if (ret < 0) {
printk("%s: Failed to set charger mode\n", __func__);
return ret;
}
property_val.intval = 1;
power_supply_set_property(otgc_data->pdata->vbus_supply,
ret = power_supply_set_property(otgc_data->pdata->vbus_supply,
POWER_SUPPLY_PROP_ONLINE,
&property_val);
if (ret < 0) {
printk("%s: Failed to enable charging after changing charger mode\n", __func__);
return ret;
}
break;
default:

View File

@ -6,6 +6,7 @@
#define OTG1_CHARGERMODE_CHARGE 0
#define OTG1_CHARGERMODE_OTG 1
int otgcontrol_change_otg_charge_mode(struct rm_otgcontrol_data *otgc_data, int mode);
int otgcontrol_change_otg_charge_mode(struct rm_otgcontrol_data *otgc_data,
int mode);
#endif /* __OTGCONTROL_CHARGING_CTRL_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -4,29 +4,30 @@
#include <linux/rm-otgcontrol.h>
int otgcontrol_init_fsm(struct rm_otgcontrol_data *otgc_data);
int otgcontrol_set_controlmode(struct rm_otgcontrol_data *otgc_data, int mode);
int otgcontrol_handleInput(struct rm_otgcontrol_data *otgc_data, int signal, void *param);
static int otgcontrol_start_onewire_authentication(struct rm_otgcontrol_data *otgc_data);
#define OTG_MODE__MANUAL_CONTROL 0
#define OTG_MODE__ONEWIRE_AUTH 1
#define OTG_MODE__USB_NO_AUTH 2
#define OTG1_STATE__MANUAL_CONTROL 0
#define OTG1_STATE__ONEWIRE_NOT_CONNECTED 1
#define OTG1_STATE__ONEWIRE_WAIT_HANDSHAKE_RESPONS 2
#define OTG1_STATE__ONEWIRE_DEVICE_CONNECTED 3
#define OTG1_STATE__USB_NOT_CONNECTED 4
#define OTG1_STATE__USB_DEVICE_CONNECTED 5
#define OTG1_STATE__HOST_CONNECTED 6
#define OTG1_STATE__ONEWIRE_AUTH_NOT_CONNECTED 1
#define OTG1_STATE__ONEWIRE_AUTH_WAIT_HANDSHAKE_RESPONS 2
#define OTG1_STATE__ONEWIRE_AUTH_DEVICE_CONNECTED 3
#define OTG1_STATE__USB_NO_AUTH_WAITING_CHALLENGE_RESPONSE 4
#define OTG1_STATE__USB_NO_AUTH_NOT_CONNECTED 5
#define OTG1_STATE__USB_NO_AUTH_DEVICE_CONNECTED 6
#define OTG1_STATE__HOST_CONNECTED 7
#define OTG1_EVENT__VBUS_CHANGED 0
#define OTG1_EVENT__ONEWIRE_GPIO_STATE_CHANGED 1
#define OTG1_EVENT__CHALLENGE_REPLY_RECEIVED 2
#define OTG1_EVENT__TIMEOUT 3
#define OTG1_EVENT__MODE_CHANGE_REQUESTED 4
#define OTG1_EVENT__OTG_CHARGERMODE_CHANGE_REQUESTED 5
#define OTG1_STATE__OTG_ID_STATE_CHANGE_REQUESTED 6
#define OTG1_EVENT__CHARGER_CONNECTED 0
#define OTG1_EVENT__CHARGER_DISCONNECTED 1
#define OTG1_EVENT__DEVICE_CONNECTED 2
#define OTG1_EVENT__DEVICE_DISCONNECTED 3
#define OTG1_EVENT__CHALLENGE_REPLY_RECEIVED 4
#define OTG1_EVENT__TIMEOUT 5
#define OTG1_EVENT__MODE_CHANGE_REQUESTED 6
#define OTG1_EVENT__MODE_CHANGE_CHALLENGE_REPLY 7
#define OTG1_EVENT__OTG_CHARGERMODE_CHANGE_REQUESTED 8
#define OTG1_EVENT__OTG_DR_MODE_CHANGE_REQUESTED 9
#endif /* __OTGCONTROL_FSM_H__ */

View File

@ -55,11 +55,6 @@ static int rm_otgcontrol_init(struct rm_otgcontrol_data *otgc_data)
if (ret < 0)
return ret;
printk("%s: Initiating default ONEWIRE_AUTH state\n", __func__);
ret = otgcontrol_init_fsm(otgc_data);
if (ret < 0)
return ret;
printk("%s: Initiating extcon device to control USB OTG dr mode\n", __func__);
ret = otgcontrol_init_extcon(otgc_data);
if (ret < 0) {
@ -67,8 +62,20 @@ static int rm_otgcontrol_init(struct rm_otgcontrol_data *otgc_data)
return ret;
}
printk("%s: Initiating onewire state and setting to default state (GPIO)\n", __func__);
ret = otgcontrol_init_one_wire_mux_state(otgc_data);
if (ret < 0) {
printk("%s: Failed to initiate onewire pincontrol configuration\n", __func__);
return ret;
}
printk("%s: Initiating one-wire gpio irq\n", __func__);
ret = otgcontrol_init_gpio_irq(otgc_data);
if (ret < 0)
return ret;
printk("%s: Initiating fsm to start in AUTHORIZED MODE !!\n", __func__);
ret = otgcontrol_init_fsm(otgc_data);
return ret;
}
@ -79,7 +86,7 @@ static int rm_otgcontrol_parse_dt(struct rm_otgcontrol_data *otgc_data)
struct device_node *np = dev->of_node;
struct rm_otgcontrol_platform_data *pdata = otgc_data->pdata;
const char *vbus_supply_name;
int ret = 0, gpio_num;
int ret = 0;
printk("[---- SBA ----] %s: Enter\n", __func__);
@ -112,7 +119,7 @@ static int rm_otgcontrol_parse_dt(struct rm_otgcontrol_data *otgc_data)
if (of_find_property(np, "one-wire-tty-name", NULL)) {
printk("[---- SBA ----] %s: Found one-wire-tty-name property, trying to read it\n", __func__);
ret = of_property_read_string(np, "one-wire-tty-name", otgc_data->one_wire_tty_name);
ret = of_property_read_string(np, "one-wire-tty-name", &otgc_data->one_wire_tty_name);
if (ret) {
printk("[---- SBA ----] %s: Failed to read property one-wire-tty-name (code %d)\n", __func__, ret);
return ret;
@ -123,25 +130,18 @@ static int rm_otgcontrol_parse_dt(struct rm_otgcontrol_data *otgc_data)
return -EINVAL;
}
//if (of_find_property(np, "one-wire-gpios", NULL)) {
//printk("[---- SBA ----] %s: Found one-wire-gpio property, trying to read it\n", __func__);
// gpio_num = of_get_named_gpio(np, "one-wire-gpio", 0);
// if (gpio_num < 0) {
// printk("%s: Failed to read property one-wire-gpio (code %ld)\n", __func__, gpio_num);
// return gpio_num;
// }
// otgc_data->one_wire_gpio = gpio_to_desc(gpio_num);
if (of_find_property(np, "one-wire-gpios", NULL)) {
printk("[---- SBA ----] %s: Found one-wire-gpio property, trying to read it\n", __func__);
otgc_data->one_wire_gpio = devm_gpiod_get(otgc_data->dev, "one-wire", GPIOD_IN);
if (IS_ERR(otgc_data->one_wire_gpio)) {
printk("%s: Failed to read property one-wire-gpio (code %ld)\n", __func__, PTR_ERR(otgc_data->one_wire_gpio));
return PTR_ERR(otgc_data->one_wire_gpio);
}
//}
//else {
// printk("%s: required property one-wire-gpio not given !\n", __func__);
// return -EINVAL;
//}
}
else {
printk("%s: required property one-wire-gpio not given !\n", __func__);
return -EINVAL;
}
return 0;
}

View File

@ -9,6 +9,8 @@
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define ONE_WIRE_GPIO_DEBOUNCE_MS 200 /* ms */
@ -62,7 +64,6 @@ void otgcontrol_uninit_onw_wire_mux_state(struct rm_otgcontrol_data *otgc_data)
int otgcontrol_switch_one_wire_mux_state(struct rm_otgcontrol_data *otgc_data, int state)
{
int ret;
printk("%s: Enter\n", __func__);
switch(state)
{
@ -142,20 +143,25 @@ int otgcontrol_init_gpio_irq(struct rm_otgcontrol_data *otgc_data)
desc_to_gpio(otgc_data->one_wire_gpio));
return ret;
}
otgc_data->one_wire_gpio_irq_is_active = true;
return 0;
}
void otgcontrol_activate_gpio_irq(struct rm_otgcontrol_data *otgc_data)
{
printk("%s: Enter\n", __func__);
if (!otgc_data->one_wire_gpio_irq_is_active) {
enable_irq(otgc_data->one_wire_gpio_irq);
otgc_data->one_wire_gpio_irq_is_active = true;
}
}
void otgcontrol_deactivate_gpio_irq(struct rm_otgcontrol_data *otgc_data)
{
printk("%s: Enter\n", __func__);
if (otgc_data->one_wire_gpio_irq_is_active) {
disable_irq(otgc_data->one_wire_gpio_irq);
otgc_data->one_wire_gpio_irq_is_active = false;
}
}
static irqreturn_t otgcontrol_gpio_irq_handler(int irq, void *data)
@ -183,8 +189,114 @@ static void otgcontrol_gpio_irq_work(struct work_struct *work)
printk("%s: GPIO state changed -> %s\n", __func__, cur_gpio_state ? "HIGH" : "LOW");
otgc_data->one_wire_state = cur_gpio_state;
otgcontrol_handleInput(otgc_data, OTG1_EVENT__ONEWIRE_GPIO_STATE_CHANGED, (void*)&otgc_data->one_wire_state);
if (otgc_data->one_wire_state == 0)
otgcontrol_handleInput(otgc_data, OTG1_EVENT__DEVICE_CONNECTED, NULL);
else
otgcontrol_handleInput(otgc_data, OTG1_EVENT__DEVICE_DISCONNECTED, NULL);
}
/* otgcontrol_activate_gpio_irq(otgc_data); */
}
int otgcontrol_onewire_write_tty(char *device_name, char *text_to_send)
{
// Create variables
struct file *f;
char buf[128];
mm_segment_t fs;
int i;
// Init the buffer with 0
for(i = 0;i < 128;i++)
buf[i] = 0;
printk("%s: Trying to open %s\n", __func__, device_name);
f = filp_open(device_name, O_RDWR, 0);
if(f == NULL) {
printk("%s: filp_open error!!.\n", __func__);
return -1;
}
else {
// Get current segment descriptor
printk("%s: Getting current segment descriptor\n", __func__);
fs = get_fs();
// Set segment descriptor associated to kernel space
printk("%s: Setting segment descriptor\n", __func__);
set_fs(get_ds());
//Write to the file
printk("%s: Writing '%s' to file\n", __func__, text_to_send);
kernel_write(f, text_to_send, strlen(text_to_send), &f->f_pos);
// f->f_op->write(f, text_to_send, strlen(text_to_send), &f->f_pos);
// Restore segment descriptor
printk("%s: Restoring segment descriptor\n", __func__);
set_fs(fs);
printk("%s: Closing file\n", __func__);
filp_close(f,NULL);
return 0;
}
}
int otgcontrol_onewire_read_until_cr(char *device_name, char *buf, int maxlen)
{
// Create variables
struct file *f;
mm_segment_t fs;
char newchar;
int pos;
f = filp_open(device_name, O_RDONLY, 0);
if(f == NULL) {
printk("%s: filp_open error!!.\n", __func__);
return -1;
}
else {
// Get current segment descriptor
printk("%s: Getting current segment descriptor\n", __func__);
fs = get_fs();
// Set segment descriptor associated to kernel space
printk("%s: Setting segment descriptor\n", __func__);
set_fs(get_ds());
pos = 0;
int state = 0;
printk("%s: Starting read loop\n", __func__);
do {
// Read the file
// f->f_op->read(f, &newchar, 1, &f->f_pos);
kernel_read(f, &newchar, 1, &f->f_pos);
printk("%s: <-%c (0x%02x)\n", __func__, newchar, newchar);
switch(state)
{
case 0:
// Wait :
if (newchar == ':') {
printk("%s: SOF\n", __func__);
state = 1;
}
break;
default:
// Reading chars
if (newchar != '#') {
buf[pos++] = newchar;
}
}
}while((newchar != '#') && (pos < maxlen));
printk("%s: Done\n", __func__);
// Restore segment descriptor
printk("%s: Restoring segment descriptor\n", __func__);
set_fs(fs);
printk("%s: Closing file\n", __func__);
filp_close(f,NULL);
printk("%s: Returning %d bytes read\n", __func__, pos);
return pos;
}
}

View File

@ -20,5 +20,7 @@ void otgcontrol_activate_gpio_irq(struct rm_otgcontrol_data *otgc_data);
void otgcontrol_deactivate_gpio_irq(struct rm_otgcontrol_data *otgc_data);
static irqreturn_t otgcontrol_gpio_irq_handler(int irq, void *data);
static void otgcontrol_gpio_irq_work(struct work_struct *work);
int otgcontrol_onewire_read_until_cr(char *device_name, char *buf, int maxlen);
int otgcontrol_onewire_write_tty(char *device_name, char *text_to_send);
#endif /* __OTGCONTROL_ONE_WIRE_H__ */

View File

@ -180,7 +180,6 @@ int otgcontrol_init_sysfs_nodes(struct rm_otgcontrol_data *otgc_data)
kobject_put(otgc_data->kobject);
return retval;
}
//EXPORT_SYMBOL(otgcontrol_init_sysfs_nodes);
void otgcontrol_uninit_sysfs_nodes(struct rm_otgcontrol_data *otgc_data)
{
@ -191,4 +190,3 @@ void otgcontrol_uninit_sysfs_nodes(struct rm_otgcontrol_data *otgc_data)
otgc_data->kobject = NULL;
}
}
//EXPORT_SYMBOL(otgcontrol_uninit_sysfs_nodes);

View File

@ -1,4 +1,4 @@
'#ifndef __RM_OTGCONTROL_H_
#ifndef __RM_OTGCONTROL_H_
#define __RM_OTGCONTROL_H_
#include <linux/kobject.h>
@ -15,19 +15,19 @@ struct rm_otgcontrol_data {
struct extcon_dev *extcon_dev;
int otg_controlstate;
const char *one_wire_tty_name[10]; /* Name of the tty device connected to the one-wire interface pin */
struct gpio_desc *one_wire_gpio; /* GPIO descriptor for GPIO connected to the one-wire-interface pin */
int one_wire_gpio_irq; /* IRQ num for the GPIO num connected to the one-wire-interface pin */
unsigned long one_wire_gpio_debounce_jiffies; /* Amount of jiffies corresponding to the defined debounce interval for the GPIO irq */
struct delayed_work one_wire_gpio_irq_work_queue; /* Work queue used to do IRQ handling async/somewhat delayed/debounced */
const char *one_wire_tty_name;
struct gpio_desc *one_wire_gpio;
int one_wire_gpio_irq;
unsigned long one_wire_gpio_debounce_jiffies;
struct delayed_work one_wire_gpio_irq_work_queue;
bool one_wire_gpio_irq_is_active;
int otg_controlstate;
int mode_requested;
int one_wire_state; /* The last read state of the one-wire GPIO input */
struct pinctrl* one_wire_pinctrl; /* Pinctrl object controlling the pin mux config for the one-wire pin */
struct pinctrl_state* one_wire_pinctrl_states[3]; /* The three pin mux definitions (pinmux states) to choose from */
int one_wire_state;
struct pinctrl* one_wire_pinctrl;
struct pinctrl_state* one_wire_pinctrl_states[3];
struct kobject* kobject;
struct kobj_attribute otg1_device_connected_attribute;
@ -42,7 +42,7 @@ struct rm_otgcontrol_data {
struct kobj_attribute otg1_controllermode_attribute;
int otg1_controllermode;
struct kobj_attribute otg1_pinctrlstate_attribute; /* Read/write property, read current overall control mode or change mode (MANULAL_CONTROL, ONEWIRE_AUTH, USB_NO_AUTH) */
struct kobj_attribute otg1_pinctrlstate_attribute;
int otg1_pinctrlstate;
};