From 8e2b7daa23760e7be642e87b2ea5fea78a18fd79 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 18 Dec 2015 21:23:24 +0200 Subject: [PATCH] greybus: es2: Add support for CSI transmitter configuration Export a function from the es2 driver to configure the CSI transmitter through the corresponding USB vendor control request. Signed-off-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/es2.c | 48 +++++++++++++++++++++++++++++++++++++++++++ drivers/staging/greybus/es2.h | 27 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 drivers/staging/greybus/es2.h diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c index 1be4a7c..334ed06 100644 --- a/drivers/staging/greybus/es2.c +++ b/drivers/staging/greybus/es2.c @@ -13,6 +13,7 @@ #include #include +#include "es2.h" #include "greybus.h" #include "kernel_ver.h" #include "connection.h" @@ -60,6 +61,9 @@ MODULE_DEVICE_TABLE(usb, id_table); #define REQUEST_LATENCY_TAG_EN 0x06 #define REQUEST_LATENCY_TAG_DIS 0x07 +/* vendor request to control the CSI transmitter */ +#define REQUEST_CSI_TX_CONTROL 0x08 + /* * @endpoint: bulk in endpoint for CPort data * @urb: array of urbs for the CPort in messages @@ -130,6 +134,14 @@ struct cport_to_ep { __u8 endpoint_out; }; +struct es2_ap_csi_config_request { + u8 csi_id; + u8 clock_mode; + u8 num_lanes; + u8 padding; + __le32 bus_freq; +} __attribute__((__packed__)); + static inline struct es2_ap_dev *hd_to_es2(struct gb_host_device *hd) { return (struct es2_ap_dev *)&hd->hd_priv; @@ -208,6 +220,42 @@ static int unmap_cport(struct es2_ap_dev *es2, u16 cport_id) } #endif +int es2_ap_csi_setup(struct gb_host_device *hd, bool start, + struct es2_ap_csi_config *cfg) +{ + struct es2_ap_csi_config_request cfg_req; + struct es2_ap_dev *es2 = hd_to_es2(hd); + struct usb_device *udev = es2->usb_dev; + int retval; + + cfg_req.csi_id = cfg->csi_id; + + if (start) { + cfg_req.clock_mode = cfg->clock_mode; + cfg_req.num_lanes = cfg->num_lanes; + cfg_req.padding = 0; + cfg_req.bus_freq = cfg->bus_freq; + } else { + cfg_req.clock_mode = 0; + cfg_req.num_lanes = 0; + cfg_req.padding = 0; + cfg_req.bus_freq = 0; + } + + retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + REQUEST_CSI_TX_CONTROL, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_INTERFACE, 0, 0, &cfg_req, + sizeof(cfg_req), ES2_TIMEOUT); + if (retval < 0) { + dev_err(&udev->dev, "failed to setup csi: %d\n", retval); + return retval; + } + + return 0; +} +EXPORT_SYMBOL_GPL(es2_ap_csi_setup); + static int es2_cport_in_enable(struct es2_ap_dev *es2, struct es2_cport_in *cport_in) { diff --git a/drivers/staging/greybus/es2.h b/drivers/staging/greybus/es2.h new file mode 100644 index 0000000..ea29770 --- /dev/null +++ b/drivers/staging/greybus/es2.h @@ -0,0 +1,27 @@ +/* + * Greybus "AP" USB driver for "ES2" controller chips + * + * Copyright 2015 Google Inc. + * Copyright 2015 Linaro Ltd. + * + * Released under the GPLv2 only. + */ + +#ifndef __ES2_H +#define __ES2_H + +#include + +struct gb_host_device; + +struct es2_ap_csi_config { + u8 csi_id; + u8 clock_mode; + u8 num_lanes; + u32 bus_freq; +}; + +int es2_ap_csi_setup(struct gb_host_device *hd, bool start, + struct es2_ap_csi_config *cfg); + +#endif /* __ES2_H */ -- 2.7.4