在SC60上打算实现usb device和otg的软切换,即通过软件设置实现usb device和otg的切换。
原理图上可以设计一个GPIO来控制USB ID和数据线的切换。VBUS的供电方面,otg使用外供电,可以不用考虑;作device时vbus用来检测插入即可。
参考原理图如下:

图中使用GPIO_96作为控制切换的管脚,它输出0时,USB_ID脚为高,s脚为高,usb切换开关选择的是HSD1:USB_DP_EXT和USB_DM_EXT,此时模块作为device;
GPIO_96输出1时,USB_ID脚为低,usb切换开关选择的是HSD2:USB_DP_COM和USB_DM_COM,此时模块作为host,外部连接otg设备。

参考驱动:

#include <linux/device.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/semaphore.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/gpio.h>#define SC60_GPIO_SET_MAJOR    198
#define SC60_DO1            0x1
#define SC60_DO2            0x2u32 gpio_num[]={96,
};struct SC60_gpio_dev{struct cdev cdev;
};struct SC60_gpio_dev *SC60_gpio_devp;static int SC60_gpio_major = SC60_GPIO_SET_MAJOR;int SC60_gpio_open(struct inode *inode, struct file *filp)
{//printk(KERN_ERR "###sc60### SC60_gpio open in\n");filp->private_data = SC60_gpio_devp;return 0;
}int SC60_gpio_release(struct inode *inode, struct file *filp)
{//printk(KERN_ERR "###sc60### SC60_gpio release in\n");return 0;
}static ssize_t SC60_gpio_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{__attribute__((__unused__)) struct SC60_gpio_dev *dev = filp->private_data;//copy_to_user//printk(KERN_ERR "###sc60### SC60_gpio read in\n");return 0;
}static ssize_t SC60_gpio_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{__attribute__((__unused__)) struct SC60_gpio_dev *dev = filp->private_data;//copy_from_user//printk(KERN_ERR "###sc60### SC60_gpio write in\n");return -1;
}static loff_t SC60_gpio_llseek(struct file *filp, loff_t offset, int orig)
{//printk(KERN_ERR "###sc60### SC60_gpio llseek in\n");//filp->f_posswitch(orig){case 0:break;case 1:break;default:break;}return 0;
}static long SC60_gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{__attribute__((__unused__)) struct SC60_gpio_dev *dev = filp->private_data;//printk(KERN_ERR "###sc60### SC60_gpio ioctl in\n");switch(cmd){case SC60_DO1:break;case SC60_DO2:default:break;}return 0;
}static const struct file_operations SC60_gpio_fops = {.owner = THIS_MODULE,.llseek = SC60_gpio_llseek,.read = SC60_gpio_read,.write = SC60_gpio_write,.unlocked_ioctl = SC60_gpio_ioctl,.open = SC60_gpio_open,.release = SC60_gpio_release,
};struct class *SC60_gpio_class;static void SC60_gpio_setup_cdev(struct SC60_gpio_dev *dev, int index)
{int err, devno;devno = MKDEV(SC60_gpio_major, index);printk(KERN_ERR "###sc60### SC60_gpio SC60_gpio_setup_cdev\n");cdev_init(&dev->cdev, &SC60_gpio_fops);dev->cdev.owner = THIS_MODULE;err = cdev_add(&dev->cdev, devno, 1);if(err){printk(KERN_ERR "###sc60### %d add SC60_gpio %d\n", err, index);}SC60_gpio_class = class_create(THIS_MODULE, "sc60_otg_set");//stone comment//这里的名字是/dev/下面的名字// create device in /dev/sc60_otg_set//实际在/sys/class/sc60_otg_set// but the real device is /sys/bus/platform/devices/SC60_otg_controldevice_create(SC60_gpio_class, NULL, devno, NULL, "sc60_otg_set");
}static bool gpio_flag = 0;static ssize_t SC60_gpio_get(struct device *dev, struct device_attribute *attr, char *buf)
{int ret = 0;if(gpio_flag)//print chars to buf//ret = snprintf(buf, PAGE_SIZE, "%d\n", SC60_adc1_to_vol());ret = snprintf(buf, PAGE_SIZE, "--otg set--\n");elseret = snprintf(buf, PAGE_SIZE, "--host set--\n");return ret;
}static ssize_t SC60_gpio_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{int stat;//char to intstat = buf[0] - '0';printk(KERN_ERR "set gpio status :%d \n", stat);gpio_free(gpio_num[0]);gpio_request(gpio_num[0], NULL);if(stat == 0){gpio_direction_output(gpio_num[0], 0);gpio_flag = stat;}if(stat == 1){gpio_direction_output(gpio_num[0], 1);gpio_flag = stat;}return count;
}
static DEVICE_ATTR(SC60_gpio, 0664, SC60_gpio_get, SC60_gpio_set);static int __init SC60_gpio_probe(struct platform_device *pdev)
{int result;dev_t devno = MKDEV(SC60_gpio_major, 0);printk(KERN_ERR "###sc60### SC60_gpio_probe in\n");if(SC60_gpio_major){//这里是分配设备号//cat proc/devices 看到198 SC60_gpio_controlresult = register_chrdev_region(devno, 1, "SC60_gpio_control");}else{result = alloc_chrdev_region(&devno, 0, 1, "SC60_gpio_control");SC60_gpio_major = MAJOR(devno);}if(result < 0){return result;}SC60_gpio_devp = kmalloc(sizeof(struct SC60_gpio_dev), GFP_KERNEL);if(!SC60_gpio_devp){result = -ENOMEM;goto fail_malloc;}memset(SC60_gpio_devp, 0, sizeof(struct SC60_gpio_dev));SC60_gpio_setup_cdev(SC60_gpio_devp, 0);//这里创建的节点是在/sys/bus/platform/devices/SC60_otg_control下//SC60_otg_control这个名字是由SC60_gpio_device和SC60_gpio_device_driver的名字决定的device_create_file(&pdev->dev, &dev_attr_sc60_gpio);printk(KERN_ERR "###sc60### SC60_gpio_probe out\n");return 0;fail_malloc:unregister_chrdev_region(devno, 1);return result;
}static int __exit SC60_gpio_remove(struct platform_device *pdev)
{cdev_del(&SC60_gpio_devp->cdev);kfree(SC60_gpio_devp);device_destroy(SC60_gpio_class, MKDEV(SC60_gpio_major, 0));class_destroy(SC60_gpio_class);unregister_chrdev_region(MKDEV(SC60_gpio_major, 0), 1);return 0;
}static struct platform_driver SC60_gpio_device_driver = {.probe   = SC60_gpio_probe,.remove  = SC60_gpio_remove,.driver  = {.name = "SC60_otg_control",.owner = THIS_MODULE,},
};static struct platform_device SC60_gpio_device = {.name    = "SC60_otg_control",.id      = -1,
};static int __init SC60_gpio_init(void)
{platform_device_register(&SC60_gpio_device);return platform_driver_register(&SC60_gpio_device_driver);
}static void __exit SC60_codec_exit(void)
{platform_driver_unregister(&SC60_gpio_device_driver);platform_device_unregister(&SC60_gpio_device);
}module_init(SC60_gpio_init);
module_exit(SC60_codec_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("stone");
MODULE_DESCRIPTION("stone for SC60 gpio-set CTRL");

这样就可以使用节点控制usb状态了。
读取otg状态:
cat /sys/bus/platform/devices/sc60_otg_control/sc60_gpio
设置otg状态:
echo 1 > /sys/bus/platform/devices/sc60_otg_control/sc60_gpio
设置USB状态:
echo 0 > /sys/bus/platform/devices/sc60_otg_control/sc60_gpio

玩转移远SC60 Android开发板------(4)USB和otg切换相关推荐

  1. 玩转移远SC60 Android开发板------(1)LCD

    最近拿到了一块移远的SC60开发板,先上图: SC60 是一款基于高通MSM8953平台.工业级高性能.可运行安卓操作系统的4G 智能模块,其综合特征如下: ⚫ 支持LTE-FDD.LTE-TDD.D ...

  2. 玩转移远SC60 Android开发板------(3)SPI转CAN总线

    SC60开发板默认是不支持CAN接口的,需要外接转换芯片,选取MICROCHIP的MCP25625这一款. 芯片特点如下: • Stand-Alone CAN 2.0B Controller with ...

  3. 玩转移远SC60 Android开发板------(5)充电和电池管理

      SC60 模块可编程开关模式锂电池充电功能,可以给单节锂电池和聚合物电池充电.其充电过程包括涓流充电.预充电.恒流充电.恒压充电等状态.  ◆ 涓流充电:电池电压低于2.1V 时,系统处于涓流充电 ...

  4. Android开发板

    由于公司要做智能自助设备,因此需要在Android开发板上开发,记录一下经验 一.Android开发板应用 Android开发板应用: 商业应用:机顶盒.广告机,自助机,售卖机,多媒体教学,人脸识别, ...

  5. Android开发板 MTK 4g/5g 安卓开发板定制

    厂商:深圳新移科技 公司介绍:专业提供 4G.5G 安卓核心板 / 开发板.物联网方案.整机定制开发生产 一.Android 开发板应用: 商业应用:安防监控,图像识别设备,4G 音视频传输,智能手持 ...

  6. 【测评】迅为4418/6818开发板安卓Android开发板

    拿到开发板暂时按手册测试了以下功能,性能确实不错,没有卡顿现象,更多功能有待测试... Android开发板 Android开发板基本功能介绍 1.开机 开发板接通电源,并按下电源开关,系统即启动,在 ...

  7. android开发板只有网口和串口如何使用android studio进行调试

    android开发板只有网口和串口如何使用android studio进行调试 1.要先准备一条串口线,或者串口转usb的线,用于在pc端与开发板端建立连接. 2.要下载一个在pc端运行的超级终端,我 ...

  8. Android开发板开发总结

    ADB常见命令 adb connect ip[:port]:连接Android开发板(要求开发板开启ADB服务) adb disconnect ip:断开与Android开发板的连接 adb shel ...

  9. Android开发板串口(SerialPort)通信

    Android开发板串口(SerialPort)通信 Roy88关注 22017.09.07 18:01:22字数 1,618阅读 28,511 前言: 最近在总是看见有人在群里面问一些串口通信相关的 ...

最新文章

  1. PHP 接入(第三方登录)QQ 登录 OAuth2.0 过程中遇到的坑
  2. 数组子数组求最大值1
  3. SSH框架搭建 笔记 (含spring注解驱动)
  4. ArcGIS Engine 中的多线程使用
  5. jspider java运行_Web Spider 网络蜘蛛爬虫
  6. 服务器的防火墙禁止了对指定通讯端口的访问,使用iptables限制访问网站指定端口...
  7. django 1.8 官方文档翻译:6-3 Django异常
  8. logrotate 切割 nginx php mysql 日志
  9. r语言 回归分析 分类变量_R语言进阶之广义线性回归
  10. neo4j入门(一)概述
  11. 全国省市县无刷新级联菜单
  12. python吃显卡还是内存条_用游戏本打游戏是显卡重要还是内存重要?
  13. jQuery .tmpl(), .template()学习资料小结
  14. 谈谈以前那位研发总监错在哪里
  15. 计算机械公差什么软件好,Tolerance机械公差查询工具
  16. Win8.1的IE缓存文件夹哪里去了?细说系统安装分区里那些带箭头的文件夹
  17. 130个实用网站集合
  18. 放射组学常用到的一些工具(软件)
  19. Impala 4.0 启用 LZO
  20. Zero-Shot Learing与Attention Machinism

热门文章

  1. 整数规划之分枝定界法
  2. 浅谈分辨率带宽RBW
  3. 盘点游戏中那些“欺骗玩家眼睛的技巧”
  4. 【containerd 源码分析】containerd cri PodRunSandbox 源码分析之二
  5. 4路RS485继电器模块 电脑控制开关 PC智能控制器 工控板
  6. 上海招聘java程序员有哪些要求
  7. 中国防火墙行业创新战略及十四五投资规划分析报告2022-2027年
  8. 计算机一级销售额怎么计算,excel如何计算每个销售组的月销售额和该月的累计销售额?...
  9. 上海医保系统的三重保障
  10. 如何以正确的顺序重新安装驱动程序 | Dell 中国