otgcontrol: implement initial FSM
Complete disabling of authenticated USB device connection in all modes Code cleanup - Spaces -> tabs - Cleaner initiation sequencepull/10/head
parent
e05abcf7da
commit
2833df5aa4
|
@ -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:
|
||||
|
|
|
@ -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
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue