From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/usb/gadget/udc/pch_udc.c | 146 +++++++++++++++++++++++++++++------------------- 1 files changed, 89 insertions(+), 57 deletions(-) diff --git a/kernel/drivers/usb/gadget/udc/pch_udc.c b/kernel/drivers/usb/gadget/udc/pch_udc.c index 14e9990..fd3656d 100644 --- a/kernel/drivers/usb/gadget/udc/pch_udc.c +++ b/kernel/drivers/usb/gadget/udc/pch_udc.c @@ -7,16 +7,15 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <linux/errno.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/machine.h> #include <linux/list.h> #include <linux/interrupt.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <linux/gpio.h> #include <linux/irq.h> - -/* GPIO port for VBUS detecting */ -static int vbus_gpio_port = -1; /* GPIO port number (-1:Not used) */ #define PCH_VBUS_PERIOD 3000 /* VBUS polling period (msec) */ #define PCH_VBUS_INTERVAL 10 /* VBUS polling interval (msec) */ @@ -229,8 +228,7 @@ * for control data * @status: Status * @reserved: Reserved - * @data12: First setup word - * @data34: Second setup word + * @request: Control Request */ struct pch_udc_stp_dma_desc { u32 status; @@ -302,13 +300,13 @@ /** * struct pch_vbus_gpio_data - Structure holding GPIO informaton * for detecting VBUS - * @port: gpio port number + * @port: gpio descriptor for the VBUS GPIO * @intr: gpio interrupt number - * @irq_work_fall Structure for WorkQueue - * @irq_work_rise Structure for WorkQueue + * @irq_work_fall: Structure for WorkQueue + * @irq_work_rise: Structure for WorkQueue */ struct pch_vbus_gpio_data { - int port; + struct gpio_desc *port; int intr; struct work_struct irq_work_fall; struct work_struct irq_work_rise; @@ -475,7 +473,7 @@ * pch_udc_write_csr() - Write the command and status registers. * @dev: Reference to pch_udc_dev structure * @val: value to be written to CSR register - * @addr: address of CSR register + * @ep: end-point number */ static void pch_udc_write_csr(struct pch_udc_dev *dev, unsigned long val, unsigned int ep) @@ -490,7 +488,7 @@ /** * pch_udc_read_csr() - Read the command and status registers. * @dev: Reference to pch_udc_dev structure - * @addr: address of CSR register + * @ep: end-point number * * Return codes: content of CSR register */ @@ -660,6 +658,7 @@ * pch_udc_ep_set_bufsz() - Set the maximum packet size for the endpoint * @ep: Reference to structure of type pch_udc_ep_regs * @buf_size: The buffer word size + * @ep_in: EP is IN */ static void pch_udc_ep_set_bufsz(struct pch_udc_ep *ep, u32 buf_size, u32 ep_in) @@ -972,7 +971,8 @@ /** * pch_udc_ep_enable() - This api enables endpoint - * @regs: Reference to structure pch_udc_ep_regs + * @ep: reference to structure of type pch_udc_ep_regs + * @cfg: current configuration information * @desc: endpoint descriptor */ static void pch_udc_ep_enable(struct pch_udc_ep *ep, @@ -1008,7 +1008,7 @@ /** * pch_udc_ep_disable() - This api disables endpoint - * @regs: Reference to structure pch_udc_ep_regs + * @ep: reference to structure of type pch_udc_ep_regs */ static void pch_udc_ep_disable(struct pch_udc_ep *ep) { @@ -1028,7 +1028,7 @@ /** * pch_udc_wait_ep_stall() - Wait EP stall. - * @dev: Reference to pch_udc_dev structure + * @ep: reference to structure of type pch_udc_ep_regs */ static void pch_udc_wait_ep_stall(struct pch_udc_ep *ep) { @@ -1262,7 +1262,7 @@ int vbus = 0; if (dev->vbus_gpio.port) - vbus = gpio_get_value(dev->vbus_gpio.port) ? 1 : 0; + vbus = gpiod_get_value(dev->vbus_gpio.port) ? 1 : 0; else vbus = -1; @@ -1338,9 +1338,9 @@ } /** - * pch_vbus_gpio_irq() - IRQ handler for GPIO intrerrupt for changing VBUS + * pch_vbus_gpio_irq() - IRQ handler for GPIO interrupt for changing VBUS * @irq: Interrupt request number - * @dev: Reference to the device structure + * @data: Reference to the device structure * * Return codes: * 0: Success @@ -1361,45 +1361,75 @@ return IRQ_HANDLED; } +static struct gpiod_lookup_table minnowboard_udc_gpios = { + .dev_id = "0000:02:02.4", + .table = { + GPIO_LOOKUP("sch_gpio.33158", 12, NULL, GPIO_ACTIVE_HIGH), + {} + }, +}; + +static const struct dmi_system_id pch_udc_gpio_dmi_table[] = { + { + .ident = "MinnowBoard", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "MinnowBoard"), + }, + .driver_data = &minnowboard_udc_gpios, + }, + { } +}; + +static void pch_vbus_gpio_remove_table(void *table) +{ + gpiod_remove_lookup_table(table); +} + +static int pch_vbus_gpio_add_table(struct pch_udc_dev *dev) +{ + struct device *d = &dev->pdev->dev; + const struct dmi_system_id *dmi; + + dmi = dmi_first_match(pch_udc_gpio_dmi_table); + if (!dmi) + return 0; + + gpiod_add_lookup_table(dmi->driver_data); + return devm_add_action_or_reset(d, pch_vbus_gpio_remove_table, dmi->driver_data); +} + /** * pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS. - * @dev: Reference to the driver structure - * @vbus_gpio Number of GPIO port to detect gpio + * @dev: Reference to the driver structure * * Return codes: * 0: Success * -EINVAL: GPIO port is invalid or can't be initialized. */ -static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) +static int pch_vbus_gpio_init(struct pch_udc_dev *dev) { + struct device *d = &dev->pdev->dev; int err; int irq_num = 0; + struct gpio_desc *gpiod; - dev->vbus_gpio.port = 0; + dev->vbus_gpio.port = NULL; dev->vbus_gpio.intr = 0; - if (vbus_gpio_port <= -1) - return -EINVAL; + err = pch_vbus_gpio_add_table(dev); + if (err) + return err; - err = gpio_is_valid(vbus_gpio_port); - if (!err) { - pr_err("%s: gpio port %d is invalid\n", - __func__, vbus_gpio_port); - return -EINVAL; - } + /* Retrieve the GPIO line from the USB gadget device */ + gpiod = devm_gpiod_get_optional(d, NULL, GPIOD_IN); + if (IS_ERR(gpiod)) + return PTR_ERR(gpiod); + gpiod_set_consumer_name(gpiod, "pch_vbus"); - err = gpio_request(vbus_gpio_port, "pch_vbus"); - if (err) { - pr_err("%s: can't request gpio port %d, err: %d\n", - __func__, vbus_gpio_port, err); - return -EINVAL; - } - - dev->vbus_gpio.port = vbus_gpio_port; - gpio_direction_input(vbus_gpio_port); + dev->vbus_gpio.port = gpiod; INIT_WORK(&dev->vbus_gpio.irq_work_fall, pch_vbus_gpio_work_fall); - irq_num = gpio_to_irq(vbus_gpio_port); + irq_num = gpiod_to_irq(gpiod); if (irq_num > 0) { irq_set_irq_type(irq_num, IRQ_TYPE_EDGE_BOTH); err = request_irq(irq_num, pch_vbus_gpio_irq, 0, @@ -1425,9 +1455,6 @@ { if (dev->vbus_gpio.intr) free_irq(dev->vbus_gpio.intr, dev); - - if (dev->vbus_gpio.port) - gpio_free(dev->vbus_gpio.port); } /** @@ -1508,8 +1535,8 @@ /** * pch_udc_free_dma_chain() - This function frees the DMA chain created * for the request - * @dev Reference to the driver structure - * @req Reference to the request to be freed + * @dev: Reference to the driver structure + * @req: Reference to the request to be freed * * Return codes: * 0: Success @@ -1716,7 +1743,7 @@ /** * pch_udc_pcd_ep_disable() - This API disables endpoint and is called * from gadget driver - * @usbep Reference to the USB endpoint structure + * @usbep: Reference to the USB endpoint structure * * Return codes: * 0: Success @@ -2005,7 +2032,6 @@ * pch_udc_pcd_set_wedge() - This function Sets or clear the endpoint * halt feature * @usbep: Reference to the USB endpoint structure - * @halt: Specifies whether to set or clear the feature * * Return codes: * 0: Success @@ -2767,7 +2793,7 @@ /** * pch_udc_isr() - This function handles interrupts from the PCH USB Device * @irq: Interrupt request number - * @dev: Reference to the device structure + * @pdev: Reference to the device structure */ static irqreturn_t pch_udc_isr(int irq, void *pdev) { @@ -2905,19 +2931,25 @@ * @dev: Reference to the driver structure * * Return codes: - * 0: Success + * 0: Success + * -%ERRNO: All kind of errors when retrieving VBUS GPIO */ static int pch_udc_pcd_init(struct pch_udc_dev *dev) { + int ret; + pch_udc_init(dev); pch_udc_pcd_reinit(dev); - pch_vbus_gpio_init(dev, vbus_gpio_port); - return 0; + + ret = pch_vbus_gpio_init(dev); + if (ret) + pch_udc_exit(dev); + return ret; } /** * init_dma_pools() - create dma pools during initialization - * @pdev: reference to struct pci_dev + * @dev: reference to struct pci_dev */ static int init_dma_pools(struct pch_udc_dev *dev) { @@ -3062,8 +3094,7 @@ #ifdef CONFIG_PM_SLEEP static int pch_udc_suspend(struct device *d) { - struct pci_dev *pdev = to_pci_dev(d); - struct pch_udc_dev *dev = pci_get_drvdata(pdev); + struct pch_udc_dev *dev = dev_get_drvdata(d); pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); pch_udc_disable_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL); @@ -3099,6 +3130,7 @@ if (retval) return retval; + dev->pdev = pdev; pci_set_drvdata(pdev, dev); /* Determine BAR based on PCI ID */ @@ -3115,8 +3147,9 @@ dev->base_addr = pcim_iomap_table(pdev)[bar]; /* initialize the hardware */ - if (pch_udc_pcd_init(dev)) - return -ENODEV; + retval = pch_udc_pcd_init(dev); + if (retval) + return retval; pci_enable_msi(pdev); @@ -3133,7 +3166,6 @@ /* device struct setup */ spin_lock_init(&dev->lock); - dev->pdev = pdev; dev->gadget.ops = &pch_udc_ops; retval = init_dma_pools(dev); -- Gitblit v1.6.2