Linux bt gamepad 连接流程

本文介绍了Linux 3.4.x内核下,通过HIDP和UHID连接蓝牙gamepad的流程。当HIDP设备接入时,通过hid_register_driver将蓝牙hidp作为hid driver包装并创建设备节点。在UHID部分,当设备接入时,通过hid_device_probe和uhid_char_write进行探测和初始化。此外,Linux BlueZ通过input plugin支持HID输入设备,但nanoPC-t2上设备成功连接后,input设备未自动创建,可能需要额外的配置或代码修复。
摘要由CSDN通过智能技术生成

Linux bt gamepad 连接流程

3.4.x 内核

HIDP(net/bluetooth/hidp)

此目录下的文件:

— core.c

— sock.c

core.c 中init:

1198static const struct hid_device_id hidp_table[] = {
1199	{ HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) },
1200	{ }
1201};

1203static struct hid_driver hidp_driver = {
1204	.name = "generic-bluetooth",
1205	.id_table = hidp_table,
1206};
1207
1208static int __init hidp_init(void)
1209{
1210	int ret;
1211
1212	BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
1213
1214	ret = hid_register_driver(&hidp_driver);
1215	if (ret)
1216	goto err;
1217
1218	ret = hidp_init_sockets();
1219	if (ret)
1220	goto err_drv;
1221
1222	return 0;
1223err_drv:
1224	hid_unregister_driver(&hidp_driver);
1225err:
1226	return ret;
1227}

注册的hidp_driver 中只有一个id table,没有对应的probe等函数。

按照hid_register_driver() 继续,在include/linux/hid.h 中

723#define hid_register_driver(driver) \
724	__hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
725

定义在/drivers/hid/hid-core.c

2161int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
2162	const char *mod_name)
2163{
2164	int ret;
2165
2166	hdrv->driver.name = hdrv->name;
2167	hdrv->driver.bus = &hid_bus_type;
2168	hdrv->driver.owner = owner;
2169	hdrv->driver.mod_name = mod_name;
2170
2171	INIT_LIST_HEAD(&hdrv->dyn_list);
2172	spin_lock_init(&hdrv->dyn_lock);
2173
2174	ret = driver_register(&hdrv->driver);

bluetooth hidp重新作为hid driver包装,并指定bus类型为hid_bus_type

1778static struct bus_type hid_bus_type = {
1779	.name	= "hid",
1780	.match	= hid_bus_match,
1781	.probe	= hid_device_probe,
1782	.remove	= hid_device_remove,
1783	.uevent	= hid_uevent,
1784};
1785

probe 函数:

1696static int hid_device_probe(struct device *dev)
1697{
    ...
1717	hdev->driver = hdrv;
1718	if (hdrv->probe) {
1719	ret = hdrv->probe(hdev, id);
1720	} else { /* default probe */
1721	ret = hid_parse(hdev);
1722	if (!ret)
1723	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
1724	}
    ...

没有定义probe 函数,因此走hid_parse 和 hid_hw_start(进行connect-add设备节点):
/include/linux/hid.h

834static inline int __must_check hid_hw_start(struct hid_device *hdev,
835	unsigned int connect_mask)
836{
837	int ret = hdev->ll_driver->start(hdev);
838	if (ret || !connect_mask)
839	return ret;
840	ret = hid_connect(hdev, connect_mask);
841	if (ret)
842	hdev->ll_driver->stop(hdev);
843	return ret;
844}
845

/drivers/hid/hid-core.c
经过hid_connect 之后, 设备节点会被创建:

1213int 
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值