From 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 16 May 2024 03:11:33 +0000
Subject: [PATCH] AX88772C_eeprom and ax8872c build together
---
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