greybus: es2: get cport count from apb1 usb device

Use the control request REQUEST_CPORT_COUNT in order to get the number of
CPorts supported by the UniPro IP.

Signed-off-by: Fabien Parent <fparent@baylibre.com>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
This commit is contained in:
Fabien Parent 2015-09-02 15:50:37 +02:00 committed by Johan Hovold
parent c011d558e1
commit 24a6112fa5
1 changed files with 46 additions and 7 deletions

View File

@ -33,9 +33,6 @@ static struct dentry *apb1_log_enable_dentry;
static struct task_struct *apb1_log_task; static struct task_struct *apb1_log_task;
static DEFINE_KFIFO(apb1_log_fifo, char, APB1_LOG_SIZE); static DEFINE_KFIFO(apb1_log_fifo, char, APB1_LOG_SIZE);
/* Number of cport present on USB bridge */
#define CPORT_COUNT 44
/* Number of bulk in and bulk out couple */ /* Number of bulk in and bulk out couple */
#define NUM_BULKS 7 #define NUM_BULKS 7
@ -60,6 +57,9 @@ static DEFINE_KFIFO(apb1_log_fifo, char, APB1_LOG_SIZE);
/* vendor request to map a cport to bulk in and bulk out endpoints */ /* vendor request to map a cport to bulk in and bulk out endpoints */
#define REQUEST_EP_MAPPING 0x03 #define REQUEST_EP_MAPPING 0x03
/* vendor request to get the number of cports available */
#define REQUEST_CPORT_COUNT 0x04
/* /*
* @endpoint: bulk in endpoint for CPort data * @endpoint: bulk in endpoint for CPort data
* @urb: array of urbs for the CPort in messages * @urb: array of urbs for the CPort in messages
@ -636,6 +636,39 @@ static const struct file_operations apb1_log_enable_fops = {
.write = apb1_log_enable_write, .write = apb1_log_enable_write,
}; };
static int apb1_get_cport_count(struct usb_device *udev)
{
int retval;
__le16 *cport_count;
cport_count = kmalloc(sizeof(*cport_count), GFP_KERNEL);
if (!cport_count)
return -ENOMEM;
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
REQUEST_CPORT_COUNT,
USB_DIR_IN | USB_TYPE_VENDOR |
USB_RECIP_INTERFACE, 0, 0, cport_count,
sizeof(*cport_count), ES1_TIMEOUT);
if (retval < 0) {
dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n",
retval);
goto out;
}
retval = le16_to_cpu(*cport_count);
/* We need to fit a CPort ID in one byte of a message header */
if (retval > U8_MAX) {
retval = U8_MAX;
dev_warn(&udev->dev, "Limiting number of CPorts to U8_MAX\n");
}
out:
kfree(cport_count);
return retval;
}
/* /*
* The ES1 USB Bridge device contains 4 endpoints * The ES1 USB Bridge device contains 4 endpoints
* 1 Control - usual USB stuff + AP -> SVC messages * 1 Control - usual USB stuff + AP -> SVC messages
@ -655,14 +688,20 @@ static int ap_probe(struct usb_interface *interface,
int bulk_out = 0; int bulk_out = 0;
int retval = -ENOMEM; int retval = -ENOMEM;
int i; int i;
int num_cports;
/* We need to fit a CPort ID in one byte of a message header */
BUILD_BUG_ON(CPORT_ID_MAX > U8_MAX);
udev = usb_get_dev(interface_to_usbdev(interface)); udev = usb_get_dev(interface_to_usbdev(interface));
num_cports = apb1_get_cport_count(udev);
if (num_cports < 0) {
usb_put_dev(udev);
dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n",
num_cports);
return num_cports;
}
hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX, hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX,
CPORT_COUNT); num_cports);
if (IS_ERR(hd)) { if (IS_ERR(hd)) {
usb_put_dev(udev); usb_put_dev(udev);
return PTR_ERR(hd); return PTR_ERR(hd);