1
0
Fork 0

otgcontrol: add excton device registration (emulate OTG VID signal -> OTG driver)

pull/10/head
Steinar Bakkemo 2020-10-08 19:25:40 +02:00
parent b686926262
commit fac945efde
7 changed files with 79 additions and 14 deletions

View File

@ -1,17 +1,56 @@
#include "otgcontrol_dr_mode.h"
int otgcontrol_set_dr_mode(struct rm_otgcontrol_data *otgc_dta, int mode)
#include <linux/kernel.h>
#include <linux/slab.h>
static const unsigned int usb_extcon_cable[] = {
EXTCON_USB_HOST,
};
int otgcontrol_init_extcon(struct rm_otgcontrol_data *otgc_data)
{
int ret;
printk("%s: Allocating extcon device\n", __func__);
otgc_data->extcon_dev = devm_extcon_dev_allocate(otgc_data->dev, usb_extcon_cable);
if (IS_ERR(otgc_data->extcon_dev)) {
dev_err(otgc_data->dev, "%s: failed to allocate extcon device\n", __func__);
return -ENOMEM;
}
printk("%s: Registering extcon device\n", __func__);
ret = devm_extcon_dev_register(otgc_data->dev, otgc_data->extcon_dev);
if (ret < 0) {
dev_err(otgc_data->dev, "%s: Failed to register extcon device\n", __func__);
kfree(otgc_data->extcon_dev);
otgc_data->extcon_dev = NULL;
return ret;
}
return 0;
}
void otgcontrol_uninit_extcon(struct rm_otgcontrol_data *otgc_data)
{
if (!IS_ERR(otgc_data->extcon_dev)) {
devm_extcon_dev_unregister(otgc_data->dev, otgc_data->extcon_dev);
kfree(otgc_data->extcon_dev);
otgc_data->extcon_dev = NULL;
}
}
int otgcontrol_set_dr_mode(struct rm_otgcontrol_data *otgc_data, int mode)
{
switch(mode)
{
case OTG1_DR_MODE__DEVICE:
printk("%s: Switching OTG1 DR mode -> DEVICE\n", __func__);
/* Set ID pin emulation to LOW */
return extcon_set_state_sync(otgc_data->extcon_dev, EXTCON_USB_HOST, false);
break;
case OTG1_DR_MODE__HOST:
printk("%s: Switching OTG1 DR mode -> HOST\n", __func__);
/* Set ID pin emulation to HIGH */
return extcon_set_state_sync(otgc_data->extcon_dev, EXTCON_USB_HOST, true);
break;
default:

View File

@ -6,6 +6,8 @@
#define OTG1_DR_MODE__DEVICE 0
#define OTG1_DR_MODE__HOST 1
int otgcontrol_init_extcon(struct rm_otgcontrol_data *otgc_data);
void otgcontrol_uninit_extcon(struct rm_otgcontrol_data *otgc_data);
int otgcontrol_set_dr_mode(struct rm_otgcontrol_data *otgc_dta, int mode);
int otgcontrol_get_dr_mode(struct rm_otgcontrol_data *otgc_data);

View File

@ -34,7 +34,7 @@ int otgcontrol_init_fsm(struct rm_otgcontrol_data *otgc_data)
}
return 0;
}
EXPORT_SYMBOL(otgcontrol_init_fsm);
//EXPORT_SYMBOL(otgcontrol_init_fsm);
int otgcontrol_set_controlmode(struct rm_otgcontrol_data *otgc_data, int mode)
{
@ -70,26 +70,27 @@ int otgcontrol_handleInput(struct rm_otgcontrol_data *otgc_data, int signal, voi
{
case OTG1_EVENT__CHALLENGE_REPLY_RECEIVED:
printk("%s: CHALLENGE REPLY RECEIVED\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS !\n", __func__);
break;
case OTG1_EVENT__MODE_CHANGE_REQUESTED:
printk("%s: MODE CHANGE REQUESTED\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS !\n", __func__);
break;
case OTG1_EVENT__ONEWIRE_GPIO_STATE_CHANGED:
printk("%s: ONEWIRE GPIO STATE CHANGED\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS !\n", __func__);
break;
case OTG1_EVENT__OTG_CHARGERMODE_CHANGE_REQUESTED:
printk("%s: CHARGERMODE CHANGE REQUESTED\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS !\n", __func__);
break;
case OTG1_EVENT__TIMEOUT:
printk("%s: TIMEOUT\n", __func__);
break;
case OTG1_EVENT__VBUS_CHANGED:
printk("%s: VBUS CHANGED\n", __func__);
printk("%s: PLEASE IMPLEMENT SUPPORT FOR THIS !\n", __func__);
break;
default:
@ -104,6 +105,6 @@ static int otgcontrol_start_onewire_authentication(struct rm_otgcontrol_data *ot
{
printk("%s: Enter\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS\n", __func__);
printk("%s: PLEASE IMPLEMENT THIS !\n", __func__);
return 0;
}

View File

@ -12,6 +12,7 @@
#include "otgcontrol_sysfs.h"
#include "otgcontrol_fsm.h"
#include "otgcontrol_dr_mode.h"
/* Required Linux includes */
#include <linux/kernel.h>
@ -53,7 +54,11 @@ static int rm_otgcontrol_init(struct rm_otgcontrol_data *otgc_data)
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);
return ret;
}
@ -148,7 +153,7 @@ static int rm_otgcontrol_probe(struct platform_device *pdev)
printk("[---- SBA ----] %s: Setting otgc_data reference in pdev, and initiating\n", __func__);
ret = rm_otgcontrol_init(otgc_data);
if(ret < 0)
goto error_2;
goto error_3;
platform_set_drvdata(pdev, otgc_data);
return 0;
@ -161,6 +166,13 @@ error_2:
kfree(pdata);
kfree(otgc_data);
return ret;
error_3:
otgcontrol_uninit_sysfs_nodes(otgc_data);
otgcontrol_uninit_extcon(otgc_data);
kfree(pdata);
kfree(otgc_data);
return ret;
}
static int rm_otgcontrol_remove(struct platform_device *pdev)
@ -172,6 +184,9 @@ static int rm_otgcontrol_remove(struct platform_device *pdev)
printk("%s: Un-initializing sysfs nodes\n", __func__);
otgcontrol_uninit_sysfs_nodes(otgc_data);
printk("%s: Un-initializing extcon device\n", __func__);
otgcontrol_uninit_extcon(otgc_data);
printk("%s: Freeing otgc->pdata\n", __func__);
kfree(otgc_data->pdata);

View File

@ -11,6 +11,8 @@ int otgcontrol_init_one_wire_mux_state(struct rm_otgcontrol_data *otgc_data)
printk("%s: Initiating one-wire pinctrl states\n", __func__);
otgc_data->one_wire_pinctrl = devm_pinctrl_get(otgc_data->dev);
if (IS_ERR(otgc_data->one_wire_pinctrl))
return PTR_ERR(otgc_data->one_wire_pinctrl);
otgc_data->one_wire_pinctrl_states[OTG1_ONEWIRE_STATE__GPIO] = pinctrl_lookup_state(otgc_data->one_wire_pinctrl, "one_wire_gpio");
if (IS_ERR(otgc_data->one_wire_pinctrl_states[OTG1_ONEWIRE_STATE__GPIO])) {
@ -89,6 +91,7 @@ int otgcontrol_switch_one_wire_mux_state(struct rm_otgcontrol_data *otgc_data, i
int otgcontrol_get_current_gpio_state(struct rm_otgcontrol_data *otgc_data)
{
printk("%s: Enter\n", __func__);
return 0;
}

View File

@ -166,13 +166,15 @@ int otgcontrol_init_sysfs_nodes(struct rm_otgcontrol_data *otgc_data)
kobject_put(otgc_data->kobject);
return retval;
}
EXPORT_SYMBOL(otgcontrol_init_sysfs_nodes);
//EXPORT_SYMBOL(otgcontrol_init_sysfs_nodes);
void otgcontrol_uninit_sysfs_nodes(struct rm_otgcontrol_data *otgc_data)
{
printk("%s: Enter\n", __func__);
printk("%s: Decrementing kobject refcount\n", __func__);
if(!IS_ERR(otgc_data->kobject))
if(!IS_ERR(otgc_data->kobject)) {
kobject_put(otgc_data->kobject);
otgc_data->kobject = NULL;
}
}
EXPORT_SYMBOL(otgcontrol_uninit_sysfs_nodes);
//EXPORT_SYMBOL(otgcontrol_uninit_sysfs_nodes);

View File

@ -1,8 +1,9 @@
#ifndef __RM_OTGCONTROL_H_
'#ifndef __RM_OTGCONTROL_H_
#define __RM_OTGCONTROL_H_
#include <linux/kobject.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/extcon.h>
struct rm_otgcontrol_platform_data {
struct power_supply *vbus_supply;
@ -12,6 +13,8 @@ struct rm_otgcontrol_data {
struct device *dev;
struct rm_otgcontrol_platform_data *pdata;
struct extcon_dev *extcon_dev;
int otg_controlstate;
int one_wire_state;