Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media fixes from Mauro Carvalho Chehab: "For bug fixes, at soc_camera, si470x, uvcvideo, iguanaworks IR driver, radio_shark Kbuild fixes, and at the V4L2 core (radio fixes)." * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: [media] media: soc_camera: don't clear pix->sizeimage in JPEG mode [media] media: mx2_camera: Fix clock handling for i.MX27 [media] video: mx2_camera: Use clk_prepare_enable/clk_disable_unprepare [media] video: mx1_camera: Use clk_prepare_enable/clk_disable_unprepare [media] media: mx3_camera: buf_init() add buffer state check [media] radio-shark2: Only compile led support when CONFIG_LED_CLASS is set [media] radio-shark: Only compile led support when CONFIG_LED_CLASS is set [media] radio-shark*: Call cancel_work_sync from disconnect rather then release [media] radio-shark*: Remove work-around for dangling pointer in usb intfdata [media] Add USB dependency for IguanaWorks USB IR Transceiver [media] Add missing logging for rangelow/high of hwseek [media] VIDIOC_ENUM_FREQ_BANDS fix [media] mem2mem_testdev: fix querycap regression [media] si470x: v4l2-compliance fixes [media] DocBook: Remove a spurious character [media] uvcvideo: Reset the bytesused field when recycling an erroneous buffer
This commit is contained in:
commit
a484147a52
15 changed files with 217 additions and 179 deletions
|
@ -125,7 +125,7 @@ the structure refers to a radio tuner the
|
||||||
<constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para>
|
<constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para>
|
||||||
<para>If multiple frequency bands are supported, then
|
<para>If multiple frequency bands are supported, then
|
||||||
<structfield>capability</structfield> is the union of all
|
<structfield>capability</structfield> is the union of all
|
||||||
<structfield>capability></structfield> fields of each &v4l2-frequency-band;.
|
<structfield>capability</structfield> fields of each &v4l2-frequency-band;.
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
#include <sound/tea575x-tuner.h>
|
#include <sound/tea575x-tuner.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_LEDS_CLASS) || \
|
||||||
|
(defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE))
|
||||||
|
#define SHARK_USE_LEDS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version Information
|
* Version Information
|
||||||
*/
|
*/
|
||||||
|
@ -56,44 +61,18 @@ MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS };
|
enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS };
|
||||||
|
|
||||||
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
|
||||||
enum led_brightness value);
|
|
||||||
static void shark_led_set_blue_pulse(struct led_classdev *led_cdev,
|
|
||||||
enum led_brightness value);
|
|
||||||
static void shark_led_set_red(struct led_classdev *led_cdev,
|
|
||||||
enum led_brightness value);
|
|
||||||
|
|
||||||
static const struct led_classdev shark_led_templates[NO_LEDS] = {
|
|
||||||
[BLUE_LED] = {
|
|
||||||
.name = "%s:blue:",
|
|
||||||
.brightness = LED_OFF,
|
|
||||||
.max_brightness = 127,
|
|
||||||
.brightness_set = shark_led_set_blue,
|
|
||||||
},
|
|
||||||
[BLUE_PULSE_LED] = {
|
|
||||||
.name = "%s:blue-pulse:",
|
|
||||||
.brightness = LED_OFF,
|
|
||||||
.max_brightness = 255,
|
|
||||||
.brightness_set = shark_led_set_blue_pulse,
|
|
||||||
},
|
|
||||||
[RED_LED] = {
|
|
||||||
.name = "%s:red:",
|
|
||||||
.brightness = LED_OFF,
|
|
||||||
.max_brightness = 1,
|
|
||||||
.brightness_set = shark_led_set_red,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shark_device {
|
struct shark_device {
|
||||||
struct usb_device *usbdev;
|
struct usb_device *usbdev;
|
||||||
struct v4l2_device v4l2_dev;
|
struct v4l2_device v4l2_dev;
|
||||||
struct snd_tea575x tea;
|
struct snd_tea575x tea;
|
||||||
|
|
||||||
|
#ifdef SHARK_USE_LEDS
|
||||||
struct work_struct led_work;
|
struct work_struct led_work;
|
||||||
struct led_classdev leds[NO_LEDS];
|
struct led_classdev leds[NO_LEDS];
|
||||||
char led_names[NO_LEDS][32];
|
char led_names[NO_LEDS][32];
|
||||||
atomic_t brightness[NO_LEDS];
|
atomic_t brightness[NO_LEDS];
|
||||||
unsigned long brightness_new;
|
unsigned long brightness_new;
|
||||||
|
#endif
|
||||||
|
|
||||||
u8 *transfer_buffer;
|
u8 *transfer_buffer;
|
||||||
u32 last_val;
|
u32 last_val;
|
||||||
|
@ -175,20 +154,13 @@ static struct snd_tea575x_ops shark_tea_ops = {
|
||||||
.read_val = shark_read_val,
|
.read_val = shark_read_val,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SHARK_USE_LEDS
|
||||||
static void shark_led_work(struct work_struct *work)
|
static void shark_led_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct shark_device *shark =
|
struct shark_device *shark =
|
||||||
container_of(work, struct shark_device, led_work);
|
container_of(work, struct shark_device, led_work);
|
||||||
int i, res, brightness, actual_len;
|
int i, res, brightness, actual_len;
|
||||||
|
|
||||||
/*
|
|
||||||
* We use the v4l2_dev lock and registered bit to ensure the device
|
|
||||||
* does not get unplugged and unreffed while we're running.
|
|
||||||
*/
|
|
||||||
mutex_lock(&shark->tea.mutex);
|
|
||||||
if (!video_is_registered(&shark->tea.vd))
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
if (!test_and_clear_bit(i, &shark->brightness_new))
|
if (!test_and_clear_bit(i, &shark->brightness_new))
|
||||||
continue;
|
continue;
|
||||||
|
@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work)
|
||||||
v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
|
v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
|
||||||
shark->led_names[i], res);
|
shark->led_names[i], res);
|
||||||
}
|
}
|
||||||
leave:
|
|
||||||
mutex_unlock(&shark->tea.mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
||||||
|
@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
|
||||||
schedule_work(&shark->led_work);
|
schedule_work(&shark->led_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct led_classdev shark_led_templates[NO_LEDS] = {
|
||||||
|
[BLUE_LED] = {
|
||||||
|
.name = "%s:blue:",
|
||||||
|
.brightness = LED_OFF,
|
||||||
|
.max_brightness = 127,
|
||||||
|
.brightness_set = shark_led_set_blue,
|
||||||
|
},
|
||||||
|
[BLUE_PULSE_LED] = {
|
||||||
|
.name = "%s:blue-pulse:",
|
||||||
|
.brightness = LED_OFF,
|
||||||
|
.max_brightness = 255,
|
||||||
|
.brightness_set = shark_led_set_blue_pulse,
|
||||||
|
},
|
||||||
|
[RED_LED] = {
|
||||||
|
.name = "%s:red:",
|
||||||
|
.brightness = LED_OFF,
|
||||||
|
.max_brightness = 1,
|
||||||
|
.brightness_set = shark_led_set_red,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int shark_register_leds(struct shark_device *shark, struct device *dev)
|
||||||
|
{
|
||||||
|
int i, retval;
|
||||||
|
|
||||||
|
INIT_WORK(&shark->led_work, shark_led_work);
|
||||||
|
for (i = 0; i < NO_LEDS; i++) {
|
||||||
|
shark->leds[i] = shark_led_templates[i];
|
||||||
|
snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
|
||||||
|
shark->leds[i].name, shark->v4l2_dev.name);
|
||||||
|
shark->leds[i].name = shark->led_names[i];
|
||||||
|
retval = led_classdev_register(dev, &shark->leds[i]);
|
||||||
|
if (retval) {
|
||||||
|
v4l2_err(&shark->v4l2_dev,
|
||||||
|
"couldn't register led: %s\n",
|
||||||
|
shark->led_names[i]);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shark_unregister_leds(struct shark_device *shark)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NO_LEDS; i++)
|
||||||
|
led_classdev_unregister(&shark->leds[i]);
|
||||||
|
|
||||||
|
cancel_work_sync(&shark->led_work);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int shark_register_leds(struct shark_device *shark, struct device *dev)
|
||||||
|
{
|
||||||
|
v4l2_warn(&shark->v4l2_dev,
|
||||||
|
"CONFIG_LED_CLASS not enabled, LED support disabled\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline void shark_unregister_leds(struct shark_device *shark) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
static void usb_shark_disconnect(struct usb_interface *intf)
|
static void usb_shark_disconnect(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
|
struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
|
||||||
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
||||||
int i;
|
|
||||||
|
|
||||||
mutex_lock(&shark->tea.mutex);
|
mutex_lock(&shark->tea.mutex);
|
||||||
v4l2_device_disconnect(&shark->v4l2_dev);
|
v4l2_device_disconnect(&shark->v4l2_dev);
|
||||||
snd_tea575x_exit(&shark->tea);
|
snd_tea575x_exit(&shark->tea);
|
||||||
mutex_unlock(&shark->tea.mutex);
|
mutex_unlock(&shark->tea.mutex);
|
||||||
|
|
||||||
for (i = 0; i < NO_LEDS; i++)
|
shark_unregister_leds(shark);
|
||||||
led_classdev_unregister(&shark->leds[i]);
|
|
||||||
|
|
||||||
v4l2_device_put(&shark->v4l2_dev);
|
v4l2_device_put(&shark->v4l2_dev);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
|
||||||
{
|
{
|
||||||
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
||||||
|
|
||||||
cancel_work_sync(&shark->led_work);
|
|
||||||
v4l2_device_unregister(&shark->v4l2_dev);
|
v4l2_device_unregister(&shark->v4l2_dev);
|
||||||
kfree(shark->transfer_buffer);
|
kfree(shark->transfer_buffer);
|
||||||
kfree(shark);
|
kfree(shark);
|
||||||
|
@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct shark_device *shark;
|
struct shark_device *shark;
|
||||||
int i, retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
|
|
||||||
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
||||||
if (!shark)
|
if (!shark)
|
||||||
|
@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
if (!shark->transfer_buffer)
|
if (!shark->transfer_buffer)
|
||||||
goto err_alloc_buffer;
|
goto err_alloc_buffer;
|
||||||
|
|
||||||
/*
|
v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
|
||||||
* Work around a bug in usbhid/hid-core.c, where it leaves a dangling
|
|
||||||
* pointer in intfdata causing v4l2-device.c to not set it. Which
|
retval = shark_register_leds(shark, &intf->dev);
|
||||||
* results in usb_shark_disconnect() referencing the dangling pointer
|
if (retval)
|
||||||
*
|
goto err_reg_leds;
|
||||||
* REMOVE (as soon as the above bug is fixed, patch submitted)
|
|
||||||
*/
|
|
||||||
usb_set_intfdata(intf, NULL);
|
|
||||||
|
|
||||||
shark->v4l2_dev.release = usb_shark_release;
|
shark->v4l2_dev.release = usb_shark_release;
|
||||||
v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
|
|
||||||
retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
|
retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
|
v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
|
||||||
|
@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
goto err_init_tea;
|
goto err_init_tea;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_WORK(&shark->led_work, shark_led_work);
|
|
||||||
for (i = 0; i < NO_LEDS; i++) {
|
|
||||||
shark->leds[i] = shark_led_templates[i];
|
|
||||||
snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
|
|
||||||
shark->leds[i].name, shark->v4l2_dev.name);
|
|
||||||
shark->leds[i].name = shark->led_names[i];
|
|
||||||
/*
|
|
||||||
* We don't fail the probe if we fail to register the leds,
|
|
||||||
* because once we've called snd_tea575x_init, the /dev/radio0
|
|
||||||
* node may be opened from userspace holding a reference to us!
|
|
||||||
*
|
|
||||||
* Note we cannot register the leds first instead as
|
|
||||||
* shark_led_work depends on the v4l2 mutex and registered bit.
|
|
||||||
*/
|
|
||||||
retval = led_classdev_register(&intf->dev, &shark->leds[i]);
|
|
||||||
if (retval)
|
|
||||||
v4l2_err(&shark->v4l2_dev,
|
|
||||||
"couldn't register led: %s\n",
|
|
||||||
shark->led_names[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_init_tea:
|
err_init_tea:
|
||||||
v4l2_device_unregister(&shark->v4l2_dev);
|
v4l2_device_unregister(&shark->v4l2_dev);
|
||||||
err_reg_dev:
|
err_reg_dev:
|
||||||
|
shark_unregister_leds(shark);
|
||||||
|
err_reg_leds:
|
||||||
kfree(shark->transfer_buffer);
|
kfree(shark->transfer_buffer);
|
||||||
err_alloc_buffer:
|
err_alloc_buffer:
|
||||||
kfree(shark);
|
kfree(shark);
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
#include "radio-tea5777.h"
|
#include "radio-tea5777.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_LEDS_CLASS) || \
|
||||||
|
(defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK2_MODULE))
|
||||||
|
#define SHARK_USE_LEDS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||||
MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver");
|
MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -43,7 +48,6 @@ static int debug;
|
||||||
module_param(debug, int, 0);
|
module_param(debug, int, 0);
|
||||||
MODULE_PARM_DESC(debug, "Debug level (0-1)");
|
MODULE_PARM_DESC(debug, "Debug level (0-1)");
|
||||||
|
|
||||||
|
|
||||||
#define SHARK_IN_EP 0x83
|
#define SHARK_IN_EP 0x83
|
||||||
#define SHARK_OUT_EP 0x05
|
#define SHARK_OUT_EP 0x05
|
||||||
|
|
||||||
|
@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
|
||||||
|
|
||||||
enum { BLUE_LED, RED_LED, NO_LEDS };
|
enum { BLUE_LED, RED_LED, NO_LEDS };
|
||||||
|
|
||||||
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
|
||||||
enum led_brightness value);
|
|
||||||
static void shark_led_set_red(struct led_classdev *led_cdev,
|
|
||||||
enum led_brightness value);
|
|
||||||
|
|
||||||
static const struct led_classdev shark_led_templates[NO_LEDS] = {
|
|
||||||
[BLUE_LED] = {
|
|
||||||
.name = "%s:blue:",
|
|
||||||
.brightness = LED_OFF,
|
|
||||||
.max_brightness = 127,
|
|
||||||
.brightness_set = shark_led_set_blue,
|
|
||||||
},
|
|
||||||
[RED_LED] = {
|
|
||||||
.name = "%s:red:",
|
|
||||||
.brightness = LED_OFF,
|
|
||||||
.max_brightness = 1,
|
|
||||||
.brightness_set = shark_led_set_red,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shark_device {
|
struct shark_device {
|
||||||
struct usb_device *usbdev;
|
struct usb_device *usbdev;
|
||||||
struct v4l2_device v4l2_dev;
|
struct v4l2_device v4l2_dev;
|
||||||
struct radio_tea5777 tea;
|
struct radio_tea5777 tea;
|
||||||
|
|
||||||
|
#ifdef SHARK_USE_LEDS
|
||||||
struct work_struct led_work;
|
struct work_struct led_work;
|
||||||
struct led_classdev leds[NO_LEDS];
|
struct led_classdev leds[NO_LEDS];
|
||||||
char led_names[NO_LEDS][32];
|
char led_names[NO_LEDS][32];
|
||||||
atomic_t brightness[NO_LEDS];
|
atomic_t brightness[NO_LEDS];
|
||||||
unsigned long brightness_new;
|
unsigned long brightness_new;
|
||||||
|
#endif
|
||||||
|
|
||||||
u8 *transfer_buffer;
|
u8 *transfer_buffer;
|
||||||
};
|
};
|
||||||
|
@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = {
|
||||||
.read_reg = shark_read_reg,
|
.read_reg = shark_read_reg,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SHARK_USE_LEDS
|
||||||
static void shark_led_work(struct work_struct *work)
|
static void shark_led_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct shark_device *shark =
|
struct shark_device *shark =
|
||||||
container_of(work, struct shark_device, led_work);
|
container_of(work, struct shark_device, led_work);
|
||||||
int i, res, brightness, actual_len;
|
int i, res, brightness, actual_len;
|
||||||
/*
|
|
||||||
* We use the v4l2_dev lock and registered bit to ensure the device
|
|
||||||
* does not get unplugged and unreffed while we're running.
|
|
||||||
*/
|
|
||||||
mutex_lock(&shark->tea.mutex);
|
|
||||||
if (!video_is_registered(&shark->tea.vd))
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (!test_and_clear_bit(i, &shark->brightness_new))
|
if (!test_and_clear_bit(i, &shark->brightness_new))
|
||||||
|
@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work)
|
||||||
v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
|
v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n",
|
||||||
shark->led_names[i], res);
|
shark->led_names[i], res);
|
||||||
}
|
}
|
||||||
leave:
|
|
||||||
mutex_unlock(&shark->tea.mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
static void shark_led_set_blue(struct led_classdev *led_cdev,
|
||||||
|
@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev,
|
||||||
schedule_work(&shark->led_work);
|
schedule_work(&shark->led_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct led_classdev shark_led_templates[NO_LEDS] = {
|
||||||
|
[BLUE_LED] = {
|
||||||
|
.name = "%s:blue:",
|
||||||
|
.brightness = LED_OFF,
|
||||||
|
.max_brightness = 127,
|
||||||
|
.brightness_set = shark_led_set_blue,
|
||||||
|
},
|
||||||
|
[RED_LED] = {
|
||||||
|
.name = "%s:red:",
|
||||||
|
.brightness = LED_OFF,
|
||||||
|
.max_brightness = 1,
|
||||||
|
.brightness_set = shark_led_set_red,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int shark_register_leds(struct shark_device *shark, struct device *dev)
|
||||||
|
{
|
||||||
|
int i, retval;
|
||||||
|
|
||||||
|
INIT_WORK(&shark->led_work, shark_led_work);
|
||||||
|
for (i = 0; i < NO_LEDS; i++) {
|
||||||
|
shark->leds[i] = shark_led_templates[i];
|
||||||
|
snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
|
||||||
|
shark->leds[i].name, shark->v4l2_dev.name);
|
||||||
|
shark->leds[i].name = shark->led_names[i];
|
||||||
|
retval = led_classdev_register(dev, &shark->leds[i]);
|
||||||
|
if (retval) {
|
||||||
|
v4l2_err(&shark->v4l2_dev,
|
||||||
|
"couldn't register led: %s\n",
|
||||||
|
shark->led_names[i]);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shark_unregister_leds(struct shark_device *shark)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NO_LEDS; i++)
|
||||||
|
led_classdev_unregister(&shark->leds[i]);
|
||||||
|
|
||||||
|
cancel_work_sync(&shark->led_work);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int shark_register_leds(struct shark_device *shark, struct device *dev)
|
||||||
|
{
|
||||||
|
v4l2_warn(&shark->v4l2_dev,
|
||||||
|
"CONFIG_LED_CLASS not enabled, LED support disabled\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline void shark_unregister_leds(struct shark_device *shark) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
static void usb_shark_disconnect(struct usb_interface *intf)
|
static void usb_shark_disconnect(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
|
struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
|
||||||
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
||||||
int i;
|
|
||||||
|
|
||||||
mutex_lock(&shark->tea.mutex);
|
mutex_lock(&shark->tea.mutex);
|
||||||
v4l2_device_disconnect(&shark->v4l2_dev);
|
v4l2_device_disconnect(&shark->v4l2_dev);
|
||||||
radio_tea5777_exit(&shark->tea);
|
radio_tea5777_exit(&shark->tea);
|
||||||
mutex_unlock(&shark->tea.mutex);
|
mutex_unlock(&shark->tea.mutex);
|
||||||
|
|
||||||
for (i = 0; i < NO_LEDS; i++)
|
shark_unregister_leds(shark);
|
||||||
led_classdev_unregister(&shark->leds[i]);
|
|
||||||
|
|
||||||
v4l2_device_put(&shark->v4l2_dev);
|
v4l2_device_put(&shark->v4l2_dev);
|
||||||
}
|
}
|
||||||
|
@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev)
|
||||||
{
|
{
|
||||||
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
|
||||||
|
|
||||||
cancel_work_sync(&shark->led_work);
|
|
||||||
v4l2_device_unregister(&shark->v4l2_dev);
|
v4l2_device_unregister(&shark->v4l2_dev);
|
||||||
kfree(shark->transfer_buffer);
|
kfree(shark->transfer_buffer);
|
||||||
kfree(shark);
|
kfree(shark);
|
||||||
|
@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct shark_device *shark;
|
struct shark_device *shark;
|
||||||
int i, retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
|
|
||||||
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL);
|
||||||
if (!shark)
|
if (!shark)
|
||||||
|
@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
if (!shark->transfer_buffer)
|
if (!shark->transfer_buffer)
|
||||||
goto err_alloc_buffer;
|
goto err_alloc_buffer;
|
||||||
|
|
||||||
/*
|
v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
|
||||||
* Work around a bug in usbhid/hid-core.c, where it leaves a dangling
|
|
||||||
* pointer in intfdata causing v4l2-device.c to not set it. Which
|
retval = shark_register_leds(shark, &intf->dev);
|
||||||
* results in usb_shark_disconnect() referencing the dangling pointer
|
if (retval)
|
||||||
*
|
goto err_reg_leds;
|
||||||
* REMOVE (as soon as the above bug is fixed, patch submitted)
|
|
||||||
*/
|
|
||||||
usb_set_intfdata(intf, NULL);
|
|
||||||
|
|
||||||
shark->v4l2_dev.release = usb_shark_release;
|
shark->v4l2_dev.release = usb_shark_release;
|
||||||
v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance);
|
|
||||||
retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
|
retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
|
v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n");
|
||||||
|
@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf,
|
||||||
goto err_init_tea;
|
goto err_init_tea;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_WORK(&shark->led_work, shark_led_work);
|
|
||||||
for (i = 0; i < NO_LEDS; i++) {
|
|
||||||
shark->leds[i] = shark_led_templates[i];
|
|
||||||
snprintf(shark->led_names[i], sizeof(shark->led_names[0]),
|
|
||||||
shark->leds[i].name, shark->v4l2_dev.name);
|
|
||||||
shark->leds[i].name = shark->led_names[i];
|
|
||||||
/*
|
|
||||||
* We don't fail the probe if we fail to register the leds,
|
|
||||||
* because once we've called radio_tea5777_init, the /dev/radio0
|
|
||||||
* node may be opened from userspace holding a reference to us!
|
|
||||||
*
|
|
||||||
* Note we cannot register the leds first instead as
|
|
||||||
* shark_led_work depends on the v4l2 mutex and registered bit.
|
|
||||||
*/
|
|
||||||
retval = led_classdev_register(&intf->dev, &shark->leds[i]);
|
|
||||||
if (retval)
|
|
||||||
v4l2_err(&shark->v4l2_dev,
|
|
||||||
"couldn't register led: %s\n",
|
|
||||||
shark->led_names[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_init_tea:
|
err_init_tea:
|
||||||
v4l2_device_unregister(&shark->v4l2_dev);
|
v4l2_device_unregister(&shark->v4l2_dev);
|
||||||
err_reg_dev:
|
err_reg_dev:
|
||||||
|
shark_unregister_leds(shark);
|
||||||
|
err_reg_leds:
|
||||||
kfree(shark->transfer_buffer);
|
kfree(shark->transfer_buffer);
|
||||||
err_alloc_buffer:
|
err_alloc_buffer:
|
||||||
kfree(shark);
|
kfree(shark);
|
||||||
|
|
|
@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = {
|
||||||
.index = 0,
|
.index = 0,
|
||||||
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
||||||
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
||||||
|
V4L2_TUNER_CAP_FREQ_BANDS |
|
||||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
||||||
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
||||||
.rangelow = 87500 * 16,
|
.rangelow = 87500 * 16,
|
||||||
|
@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = {
|
||||||
.index = 1,
|
.index = 1,
|
||||||
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
||||||
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
||||||
|
V4L2_TUNER_CAP_FREQ_BANDS |
|
||||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
||||||
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
||||||
.rangelow = 76000 * 16,
|
.rangelow = 76000 * 16,
|
||||||
|
@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = {
|
||||||
.index = 2,
|
.index = 2,
|
||||||
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
.capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
||||||
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
||||||
|
V4L2_TUNER_CAP_FREQ_BANDS |
|
||||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
||||||
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
V4L2_TUNER_CAP_HWSEEK_WRAP,
|
||||||
.rangelow = 76000 * 16,
|
.rangelow = 76000 * 16,
|
||||||
|
|
|
@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
|
||||||
{
|
{
|
||||||
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
|
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
|
||||||
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
|
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
|
||||||
capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
|
capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
|
||||||
V4L2_CAP_TUNER | V4L2_CAP_RADIO;
|
V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
|
||||||
|
capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
|
||||||
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
|
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
|
||||||
usb_make_path(radio->usbdev, capability->bus_info,
|
usb_make_path(radio->usbdev, capability->bus_info,
|
||||||
sizeof(capability->bus_info));
|
sizeof(capability->bus_info));
|
||||||
capability->device_caps = V4L2_CAP_HW_FREQ_SEEK |
|
capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
|
||||||
V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
|
V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
|
||||||
capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
|
capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -261,6 +261,7 @@ config IR_WINBOND_CIR
|
||||||
|
|
||||||
config IR_IGUANA
|
config IR_IGUANA
|
||||||
tristate "IguanaWorks USB IR Transceiver"
|
tristate "IguanaWorks USB IR Transceiver"
|
||||||
|
depends on USB_ARCH_HAS_HCD
|
||||||
depends on RC_CORE
|
depends on RC_CORE
|
||||||
select USB
|
select USB
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -431,7 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv,
|
||||||
strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
|
strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
|
||||||
strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
|
strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
|
||||||
strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
|
strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
|
||||||
cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
|
cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
|
||||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,7 +403,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
|
||||||
|
|
||||||
dev_dbg(pcdev->icd->parent, "Activate device\n");
|
dev_dbg(pcdev->icd->parent, "Activate device\n");
|
||||||
|
|
||||||
clk_enable(pcdev->clk);
|
clk_prepare_enable(pcdev->clk);
|
||||||
|
|
||||||
/* enable CSI before doing anything else */
|
/* enable CSI before doing anything else */
|
||||||
__raw_writel(csicr1, pcdev->base + CSICR1);
|
__raw_writel(csicr1, pcdev->base + CSICR1);
|
||||||
|
@ -422,7 +422,7 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
|
||||||
/* Disable all CSI interface */
|
/* Disable all CSI interface */
|
||||||
__raw_writel(0x00, pcdev->base + CSICR1);
|
__raw_writel(0x00, pcdev->base + CSICR1);
|
||||||
|
|
||||||
clk_disable(pcdev->clk);
|
clk_disable_unprepare(pcdev->clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -272,7 +272,7 @@ struct mx2_camera_dev {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct soc_camera_host soc_host;
|
struct soc_camera_host soc_host;
|
||||||
struct soc_camera_device *icd;
|
struct soc_camera_device *icd;
|
||||||
struct clk *clk_csi, *clk_emma;
|
struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
|
||||||
|
|
||||||
unsigned int irq_csi, irq_emma;
|
unsigned int irq_csi, irq_emma;
|
||||||
void __iomem *base_csi, *base_emma;
|
void __iomem *base_csi, *base_emma;
|
||||||
|
@ -407,7 +407,7 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
clk_disable(pcdev->clk_csi);
|
clk_disable_unprepare(pcdev->clk_csi);
|
||||||
writel(0, pcdev->base_csi + CSICR1);
|
writel(0, pcdev->base_csi + CSICR1);
|
||||||
if (cpu_is_mx27()) {
|
if (cpu_is_mx27()) {
|
||||||
writel(0, pcdev->base_emma + PRP_CNTL);
|
writel(0, pcdev->base_emma + PRP_CNTL);
|
||||||
|
@ -435,7 +435,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
|
||||||
if (pcdev->icd)
|
if (pcdev->icd)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
ret = clk_enable(pcdev->clk_csi);
|
ret = clk_prepare_enable(pcdev->clk_csi);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1633,23 +1633,34 @@ static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev)
|
||||||
goto exit_iounmap;
|
goto exit_iounmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcdev->clk_emma = clk_get(NULL, "emma");
|
pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg");
|
||||||
if (IS_ERR(pcdev->clk_emma)) {
|
if (IS_ERR(pcdev->clk_emma_ipg)) {
|
||||||
err = PTR_ERR(pcdev->clk_emma);
|
err = PTR_ERR(pcdev->clk_emma_ipg);
|
||||||
goto exit_free_irq;
|
goto exit_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_enable(pcdev->clk_emma);
|
clk_prepare_enable(pcdev->clk_emma_ipg);
|
||||||
|
|
||||||
|
pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb");
|
||||||
|
if (IS_ERR(pcdev->clk_emma_ahb)) {
|
||||||
|
err = PTR_ERR(pcdev->clk_emma_ahb);
|
||||||
|
goto exit_clk_emma_ipg_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
clk_prepare_enable(pcdev->clk_emma_ahb);
|
||||||
|
|
||||||
err = mx27_camera_emma_prp_reset(pcdev);
|
err = mx27_camera_emma_prp_reset(pcdev);
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_clk_emma_put;
|
goto exit_clk_emma_ahb_put;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
exit_clk_emma_put:
|
exit_clk_emma_ahb_put:
|
||||||
clk_disable(pcdev->clk_emma);
|
clk_disable_unprepare(pcdev->clk_emma_ahb);
|
||||||
clk_put(pcdev->clk_emma);
|
clk_put(pcdev->clk_emma_ahb);
|
||||||
|
exit_clk_emma_ipg_put:
|
||||||
|
clk_disable_unprepare(pcdev->clk_emma_ipg);
|
||||||
|
clk_put(pcdev->clk_emma_ipg);
|
||||||
exit_free_irq:
|
exit_free_irq:
|
||||||
free_irq(pcdev->irq_emma, pcdev);
|
free_irq(pcdev->irq_emma, pcdev);
|
||||||
exit_iounmap:
|
exit_iounmap:
|
||||||
|
@ -1685,7 +1696,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcdev->clk_csi = clk_get(&pdev->dev, NULL);
|
pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
|
||||||
if (IS_ERR(pcdev->clk_csi)) {
|
if (IS_ERR(pcdev->clk_csi)) {
|
||||||
dev_err(&pdev->dev, "Could not get csi clock\n");
|
dev_err(&pdev->dev, "Could not get csi clock\n");
|
||||||
err = PTR_ERR(pcdev->clk_csi);
|
err = PTR_ERR(pcdev->clk_csi);
|
||||||
|
@ -1785,8 +1796,10 @@ exit_free_emma:
|
||||||
eallocctx:
|
eallocctx:
|
||||||
if (cpu_is_mx27()) {
|
if (cpu_is_mx27()) {
|
||||||
free_irq(pcdev->irq_emma, pcdev);
|
free_irq(pcdev->irq_emma, pcdev);
|
||||||
clk_disable(pcdev->clk_emma);
|
clk_disable_unprepare(pcdev->clk_emma_ipg);
|
||||||
clk_put(pcdev->clk_emma);
|
clk_put(pcdev->clk_emma_ipg);
|
||||||
|
clk_disable_unprepare(pcdev->clk_emma_ahb);
|
||||||
|
clk_put(pcdev->clk_emma_ahb);
|
||||||
iounmap(pcdev->base_emma);
|
iounmap(pcdev->base_emma);
|
||||||
release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
|
release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
|
||||||
}
|
}
|
||||||
|
@ -1825,8 +1838,10 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
|
||||||
iounmap(pcdev->base_csi);
|
iounmap(pcdev->base_csi);
|
||||||
|
|
||||||
if (cpu_is_mx27()) {
|
if (cpu_is_mx27()) {
|
||||||
clk_disable(pcdev->clk_emma);
|
clk_disable_unprepare(pcdev->clk_emma_ipg);
|
||||||
clk_put(pcdev->clk_emma);
|
clk_put(pcdev->clk_emma_ipg);
|
||||||
|
clk_disable_unprepare(pcdev->clk_emma_ahb);
|
||||||
|
clk_put(pcdev->clk_emma_ahb);
|
||||||
iounmap(pcdev->base_emma);
|
iounmap(pcdev->base_emma);
|
||||||
res = pcdev->res_emma;
|
res = pcdev->res_emma;
|
||||||
release_mem_region(res->start, resource_size(res));
|
release_mem_region(res->start, resource_size(res));
|
||||||
|
|
|
@ -61,15 +61,9 @@
|
||||||
|
|
||||||
#define MAX_VIDEO_MEM 16
|
#define MAX_VIDEO_MEM 16
|
||||||
|
|
||||||
enum csi_buffer_state {
|
|
||||||
CSI_BUF_NEEDS_INIT,
|
|
||||||
CSI_BUF_PREPARED,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mx3_camera_buffer {
|
struct mx3_camera_buffer {
|
||||||
/* common v4l buffer stuff -- must be first */
|
/* common v4l buffer stuff -- must be first */
|
||||||
struct vb2_buffer vb;
|
struct vb2_buffer vb;
|
||||||
enum csi_buffer_state state;
|
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
|
|
||||||
/* One descriptot per scatterlist (per frame) */
|
/* One descriptot per scatterlist (per frame) */
|
||||||
|
@ -285,7 +279,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->state == CSI_BUF_NEEDS_INIT) {
|
if (!buf->txd) {
|
||||||
sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
|
sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
|
||||||
sg_dma_len(sg) = new_size;
|
sg_dma_len(sg) = new_size;
|
||||||
|
|
||||||
|
@ -298,7 +292,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
|
||||||
txd->callback_param = txd;
|
txd->callback_param = txd;
|
||||||
txd->callback = mx3_cam_dma_done;
|
txd->callback = mx3_cam_dma_done;
|
||||||
|
|
||||||
buf->state = CSI_BUF_PREPARED;
|
|
||||||
buf->txd = txd;
|
buf->txd = txd;
|
||||||
} else {
|
} else {
|
||||||
txd = buf->txd;
|
txd = buf->txd;
|
||||||
|
@ -385,7 +378,6 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
|
||||||
|
|
||||||
/* Doesn't hurt also if the list is empty */
|
/* Doesn't hurt also if the list is empty */
|
||||||
list_del_init(&buf->queue);
|
list_del_init(&buf->queue);
|
||||||
buf->state = CSI_BUF_NEEDS_INIT;
|
|
||||||
|
|
||||||
if (txd) {
|
if (txd) {
|
||||||
buf->txd = NULL;
|
buf->txd = NULL;
|
||||||
|
@ -405,13 +397,13 @@ static int mx3_videobuf_init(struct vb2_buffer *vb)
|
||||||
struct mx3_camera_dev *mx3_cam = ici->priv;
|
struct mx3_camera_dev *mx3_cam = ici->priv;
|
||||||
struct mx3_camera_buffer *buf = to_mx3_vb(vb);
|
struct mx3_camera_buffer *buf = to_mx3_vb(vb);
|
||||||
|
|
||||||
/* This is for locking debugging only */
|
if (!buf->txd) {
|
||||||
INIT_LIST_HEAD(&buf->queue);
|
/* This is for locking debugging only */
|
||||||
sg_init_table(&buf->sg, 1);
|
INIT_LIST_HEAD(&buf->queue);
|
||||||
|
sg_init_table(&buf->sg, 1);
|
||||||
|
|
||||||
buf->state = CSI_BUF_NEEDS_INIT;
|
mx3_cam->buf_total += vb2_plane_size(vb, 0);
|
||||||
|
}
|
||||||
mx3_cam->buf_total += vb2_plane_size(vb, 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,8 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd,
|
||||||
dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
|
dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
|
||||||
pixfmtstr(pix->pixelformat), pix->width, pix->height);
|
pixfmtstr(pix->pixelformat), pix->width, pix->height);
|
||||||
|
|
||||||
if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
|
if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
|
||||||
|
!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
|
||||||
pix->bytesperline = 0;
|
pix->bytesperline = 0;
|
||||||
pix->sizeimage = 0;
|
pix->sizeimage = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
|
||||||
|
|
||||||
s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
|
s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
|
||||||
{
|
{
|
||||||
|
if (mf->fourcc == V4L2_PIX_FMT_JPEG)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
|
if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
|
||||||
return width * mf->bits_per_sample / 8;
|
return width * mf->bits_per_sample / 8;
|
||||||
|
|
||||||
|
@ -400,6 +403,9 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
|
||||||
s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
|
s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
|
||||||
u32 bytes_per_line, u32 height)
|
u32 bytes_per_line, u32 height)
|
||||||
{
|
{
|
||||||
|
if (mf->fourcc == V4L2_PIX_FMT_JPEG)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
|
if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
|
||||||
return bytes_per_line * height;
|
return bytes_per_line * height;
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
||||||
if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
|
if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
|
||||||
buf->error = 0;
|
buf->error = 0;
|
||||||
buf->state = UVC_BUF_STATE_QUEUED;
|
buf->state = UVC_BUF_STATE_QUEUED;
|
||||||
|
buf->bytesused = 0;
|
||||||
vb2_set_plane_payload(&buf->buf, 0, 0);
|
vb2_set_plane_payload(&buf->buf, 0, 0);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,8 +402,10 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
|
||||||
{
|
{
|
||||||
const struct v4l2_hw_freq_seek *p = arg;
|
const struct v4l2_hw_freq_seek *p = arg;
|
||||||
|
|
||||||
pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
|
pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, "
|
||||||
p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
|
"rangelow=%u, rangehigh=%u\n",
|
||||||
|
p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing,
|
||||||
|
p->rangelow, p->rangehigh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v4l_print_requestbuffers(const void *arg, bool write_only)
|
static void v4l_print_requestbuffers(const void *arg, bool write_only)
|
||||||
|
@ -1853,6 +1855,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
|
||||||
.type = type,
|
.type = type,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (p->index)
|
||||||
|
return -EINVAL;
|
||||||
err = ops->vidioc_g_tuner(file, fh, &t);
|
err = ops->vidioc_g_tuner(file, fh, &t);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1870,6 +1874,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
|
||||||
|
|
||||||
if (type != V4L2_TUNER_RADIO)
|
if (type != V4L2_TUNER_RADIO)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (p->index)
|
||||||
|
return -EINVAL;
|
||||||
err = ops->vidioc_g_modulator(file, fh, &m);
|
err = ops->vidioc_g_modulator(file, fh, &m);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in a new issue