@@ -60,6 +60,7 @@
#define S2255_MIN_BUFS 2
#define S2255_SETMODE_TIMEOUT 500
#define S2255_VIDSTATUS_TIMEOUT 350
+#define S2255_MARKER_SERIALNUM cpu_to_le32(0xDDCCBBAAL)
#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
@@ -245,6 +246,7 @@ struct s2255_vc {
struct s2255_dev {
+ struct media_device mdev;
struct s2255_vc vc[MAX_CHANNELS];
struct v4l2_device v4l2_dev;
atomic_t num_channels;
@@ -323,6 +325,7 @@ struct s2255_buffer {
#define S2255_V4L2_YC_ON 1
#define S2255_V4L2_YC_OFF 0
#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
+#define V4L2_CID_S2255_SERIALNUM (V4L2_CID_USER_S2255_BASE + 1)
/* frame prefix size (sent once every frame) */
#define PREFIX_SIZE 512
@@ -1232,6 +1235,29 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
+/*
+ * serial number is not used in usb device descriptors.
+ * returns serial number from device, 0 if none found.
+ */
+
+static int s2255_g_serialnum(struct s2255_dev *dev, u32 *serial)
+{
+#define S2255_I2C_SIZE 16
+#define S2255_I2C_SERIALNUM 0xa2
+#define S2255_I2C_SERIALNUM_OFFSET 0x1ff0
+#define S2255_VENDOR_READREG 0x22
+ u8 buf[16];
+ int rc;
+
+ rc = s2255_vendor_req(dev, S2255_VENDOR_READREG, S2255_I2C_SERIALNUM_OFFSET,
+ S2255_I2C_SERIALNUM >> 1, buf, S2255_I2C_SIZE, 0);
+ if (rc != S2255_I2C_SIZE || *(__le32 *)buf != S2255_MARKER_SERIALNUM)
+ return -EINVAL;
+ /* Unlike the other parameters, the serial number is sent as big endian */
+ *serial = be32_to_cpu(*((__be32 *)buf + 3));
+ return 0;
+}
+
static int vidioc_g_jpegcomp(struct file *file, void *priv,
struct v4l2_jpegcompression *jc)
{
@@ -1500,6 +1526,9 @@ static void s2255_destroy(struct s2255_dev *dev)
s2255_reset_dsppower(dev);
mutex_destroy(&dev->lock);
usb_put_dev(dev->udev);
+ if (media_devnode_is_registered(dev->mdev.devnode))
+ media_device_unregister(&dev->mdev);
+ media_device_cleanup(&dev->mdev);
v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev->cmdbuf);
kfree(dev);
@@ -2206,14 +2235,13 @@ static int s2255_probe(struct usb_interface *interface,
int retval = -ENOMEM;
__le32 *pdata;
int fw_size;
-
+ u32 serialno;
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
if (dev == NULL) {
s2255_dev_err(&interface->dev, "out of memory\n");
return -ENOMEM;
}
-
dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
if (dev->cmdbuf == NULL) {
s2255_dev_err(&interface->dev, "out of memory\n");
@@ -2237,6 +2265,15 @@ static int s2255_probe(struct usb_interface *interface,
dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
dev, dev->udev, interface);
dev->interface = interface;
+
+ dev->mdev.dev = &interface->dev;
+ strscpy(dev->mdev.model, "Sensoray Model 2255", sizeof(dev->mdev.model));
+ usb_make_path(dev->udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info));
+ dev->mdev.hw_revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
+ if (s2255_g_serialnum(dev, &serialno) == 0)
+ snprintf(dev->mdev.serial, sizeof(dev->mdev.serial), "%d", serialno);
+ media_device_init(&dev->mdev);
+ dev->v4l2_dev.mdev = &dev->mdev;
/* set up the endpoint information */
iface_desc = interface->cur_altsetting;
dev_dbg(&interface->dev, "num EP: %d\n",
@@ -2311,6 +2348,10 @@ static int s2255_probe(struct usb_interface *interface,
retval = s2255_probe_v4l(dev);
if (retval)
goto errorBOARDINIT;
+
+ if (media_device_register(&dev->mdev) < 0)
+ goto errorBOARDINIT;
+
dev_info(&interface->dev, "Sensoray 2255 detected\n");
return 0;
errorBOARDINIT:
Adding media_device support including the serial number. Signed-off-by: Dean Anderson <dean@sensoray.com> --- drivers/media/usb/s2255/s2255drv.c | 45 ++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-)