Linux usb【3】- gadget驱动介绍

本文基于新思的dwc3 usb控制器,介绍usb的gadget驱动,kernel版本为5.15。

probe刚开始和前面介绍的host驱动是一样的,只不过在dwc3_core_init_mode函数中会选择gadget初始化dwc3_gadget_init。

1214  static int dwc3_core_init_mode(struct dwc3 *dwc)
1215  {
1216  	struct device *dev = dwc->dev;
1217  	int ret;
1218  
1219  	switch (dwc->dr_mode) {
1220  	case USB_DR_MODE_PERIPHERAL:
1221  		dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
1222  
1223  		if (dwc->usb2_phy)
1224  			otg_set_vbus(dwc->usb2_phy->otg, false);
1225  		phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE);
1226  		phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE);
1227  
1228  		ret = dwc3_gadget_init(dwc);
1229  		if (ret)
1230  			return dev_err_probe(dev, ret, "failed to initialize gadget\n");
1231  		break;
1232  	case USB_DR_MODE_HOST:
1233  		dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
1234  
1235  		if (dwc->usb2_phy)
1236  			otg_set_vbus(dwc->usb2_phy->otg, true);
1237  		phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
1238  		phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST);
1239  
1240  		ret = dwc3_host_init(dwc);
1241  		if (ret)
1242  			return dev_err_probe(dev, ret, "failed to initialize host\n");
1243  		break;
1244  	case USB_DR_MODE_OTG:
1245  		INIT_WORK(&dwc->drd_work, __dwc3_set_mode);
1246  		ret = dwc3_drd_init(dwc);
1247  		if (ret)
1248  			return dev_err_probe(dev, ret, "failed to initialize dual-role\n");
1249  		break;
1250  	default:
1251  		dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
1252  		return -EINVAL;
1253  	}
1254  
1255  	return 0;
1256  }

在dwc3_gadget_init中主要就是调用dwc3_gadget_init_endpoints初始化ep, 并且申请了usb_gadget数据结构,并初始化里面的usb_gadget_ops回调函数, 然后调用usb_add_gadget。

4303  /**
4304   * dwc3_gadget_init - initializes gadget related registers
4305   * @dwc: pointer to our controller context structure
4306   *
4307   * Returns 0 on success otherwise negative errno.
4308   */
4309  int dwc3_gadget_init(struct dwc3 *dwc)
4310  {
4311  	int ret;
4312  	int irq;
4313  	struct device *dev;
4314  
4315  #ifdef CONFIG_USB_DWC3_AXERA
4316  	axera_usb_device_init(dwc);
4317  #endif
4318  
4319  	irq = dwc3_gadget_get_irq(dwc);
4320  	if (irq < 0) {
4321  		ret = irq;
4322  		goto err0;
4323  	}
4324  
4325  	dwc->irq_gadget = irq;
4326  
4327  	dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev,
4328  					  sizeof(*dwc->ep0_trb) * 2,
4329  					  &dwc->ep0_trb_addr, GFP_KERNEL);
4330  	if (!dwc->ep0_trb) {
4331  		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
4332  		ret = -ENOMEM;
4333  		goto err0;
4334  	}
4335  
4336  	dwc->setup_buf = kzalloc(DWC3_EP0_SETUP_SIZE, GFP_KERNEL);
4337  	if (!dwc->setup_buf) {
4338  		ret = -ENOMEM;
4339  		goto err1;
4340  	}
4341  
4342  	dwc->bounce = dma_alloc_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE,
4343  			&dwc->bounce_addr, GFP_KERNEL);
4344  	if (!dwc->bounce) {
4345  		ret = -ENOMEM;
4346  		goto err2;
4347  	}
4348  
4349  	init_completion(&dwc->ep0_in_setup);
4350  	dwc->gadget = kzalloc(sizeof(struct usb_gadget), GFP_KERNEL);
4351  	if (!dwc->gadget) {
4352  		ret = -ENOMEM;
4353  		goto err3;
4354  	}
4355  
4356  
4357  	usb_initialize_gadget(dwc->dev, dwc->gadget, dwc_gadget_release);
4358  	dev				= &dwc->gadget->dev;
4359  	dev->platform_data		= dwc;
4360  	dwc->gadget->ops		= &dwc3_gadget_ops;
4361  	dwc->gadget->speed		= USB_SPEED_UNKNOWN;
4362  	dwc->gadget->ssp_rate		= USB_SSP_GEN_UNKNOWN;
4363  	dwc->gadget->sg_supported	= false;
4364  	dwc->gadget->name		= "dwc3-gadget";
4365  	dwc->gadget->lpm_capable	= !dwc->usb2_gadget_lpm_disable;
4366  
4367  	/*
4368 &nbs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值