|
@@ -912,9 +912,6 @@ static inline void cx231xx_set_model(struct cx231xx *dev)
|
|
*/
|
|
*/
|
|
void cx231xx_pre_card_setup(struct cx231xx *dev)
|
|
void cx231xx_pre_card_setup(struct cx231xx *dev)
|
|
{
|
|
{
|
|
-
|
|
|
|
- cx231xx_set_model(dev);
|
|
|
|
-
|
|
|
|
dev_info(dev->dev, "Identified as %s (card=%d)\n",
|
|
dev_info(dev->dev, "Identified as %s (card=%d)\n",
|
|
dev->board.name, dev->model);
|
|
dev->board.name, dev->model);
|
|
|
|
|
|
@@ -1092,6 +1089,17 @@ void cx231xx_config_i2c(struct cx231xx *dev)
|
|
call_all(dev, video, s_stream, 1);
|
|
call_all(dev, video, s_stream, 1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void cx231xx_unregister_media_device(struct cx231xx *dev)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
|
|
+ if (dev->media_dev) {
|
|
|
|
+ media_device_unregister(dev->media_dev);
|
|
|
|
+ kfree(dev->media_dev);
|
|
|
|
+ dev->media_dev = NULL;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* cx231xx_realease_resources()
|
|
* cx231xx_realease_resources()
|
|
* unregisters the v4l2,i2c and usb devices
|
|
* unregisters the v4l2,i2c and usb devices
|
|
@@ -1099,6 +1107,8 @@ void cx231xx_config_i2c(struct cx231xx *dev)
|
|
*/
|
|
*/
|
|
void cx231xx_release_resources(struct cx231xx *dev)
|
|
void cx231xx_release_resources(struct cx231xx *dev)
|
|
{
|
|
{
|
|
|
|
+ cx231xx_unregister_media_device(dev);
|
|
|
|
+
|
|
cx231xx_release_analog_resources(dev);
|
|
cx231xx_release_analog_resources(dev);
|
|
|
|
|
|
cx231xx_remove_from_devlist(dev);
|
|
cx231xx_remove_from_devlist(dev);
|
|
@@ -1117,6 +1127,38 @@ void cx231xx_release_resources(struct cx231xx *dev)
|
|
clear_bit(dev->devno, &cx231xx_devused);
|
|
clear_bit(dev->devno, &cx231xx_devused);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void cx231xx_media_device_register(struct cx231xx *dev,
|
|
|
|
+ struct usb_device *udev)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
|
|
+ struct media_device *mdev;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
|
|
|
|
+ if (!mdev)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ mdev->dev = dev->dev;
|
|
|
|
+ strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
|
|
|
|
+ if (udev->serial)
|
|
|
|
+ strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
|
|
|
|
+ strcpy(mdev->bus_info, udev->devpath);
|
|
|
|
+ mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
|
|
|
|
+ mdev->driver_version = LINUX_VERSION_CODE;
|
|
|
|
+
|
|
|
|
+ ret = media_device_register(mdev);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(dev->dev,
|
|
|
|
+ "Couldn't create a media device. Error: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+ kfree(mdev);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dev->media_dev = mdev;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* cx231xx_init_dev()
|
|
* cx231xx_init_dev()
|
|
* allocates and inits the device structs, registers i2c bus and v4l device
|
|
* allocates and inits the device structs, registers i2c bus and v4l device
|
|
@@ -1225,10 +1267,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
|
|
}
|
|
}
|
|
|
|
|
|
retval = cx231xx_register_analog_devices(dev);
|
|
retval = cx231xx_register_analog_devices(dev);
|
|
- if (retval) {
|
|
|
|
- cx231xx_release_analog_resources(dev);
|
|
|
|
|
|
+ if (retval)
|
|
goto err_analog;
|
|
goto err_analog;
|
|
- }
|
|
|
|
|
|
|
|
cx231xx_ir_init(dev);
|
|
cx231xx_ir_init(dev);
|
|
|
|
|
|
@@ -1236,6 +1276,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
err_analog:
|
|
err_analog:
|
|
|
|
+ cx231xx_unregister_media_device(dev);
|
|
|
|
+ cx231xx_release_analog_resources(dev);
|
|
cx231xx_remove_from_devlist(dev);
|
|
cx231xx_remove_from_devlist(dev);
|
|
err_dev_init:
|
|
err_dev_init:
|
|
cx231xx_dev_uninit(dev);
|
|
cx231xx_dev_uninit(dev);
|
|
@@ -1438,6 +1480,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
|
dev->video_mode.alt = -1;
|
|
dev->video_mode.alt = -1;
|
|
dev->dev = d;
|
|
dev->dev = d;
|
|
|
|
|
|
|
|
+ cx231xx_set_model(dev);
|
|
|
|
+
|
|
dev->interface_count++;
|
|
dev->interface_count++;
|
|
/* reset gpio dir and value */
|
|
/* reset gpio dir and value */
|
|
dev->gpio_dir = 0;
|
|
dev->gpio_dir = 0;
|
|
@@ -1502,7 +1546,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
|
/* save our data pointer in this interface device */
|
|
/* save our data pointer in this interface device */
|
|
usb_set_intfdata(interface, dev);
|
|
usb_set_intfdata(interface, dev);
|
|
|
|
|
|
|
|
+ /* Register the media controller */
|
|
|
|
+ cx231xx_media_device_register(dev, udev);
|
|
|
|
+
|
|
/* Create v4l2 device */
|
|
/* Create v4l2 device */
|
|
|
|
+ dev->v4l2_dev.mdev = dev->media_dev;
|
|
retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
|
|
retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
|
|
if (retval) {
|
|
if (retval) {
|
|
dev_err(d, "v4l2_device_register failed\n");
|
|
dev_err(d, "v4l2_device_register failed\n");
|