aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:49:44 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:49:44 -0400
commita39db27a08ef85ae37beab261744d8b38f21225c (patch)
tree7dc1964e1052f162977c45b6489b07b6f275887f
parentad98c0f674796848c6fd8fe614ef83ef971ebfcf (diff)
V4L/DVB: gspca - sn9c20x: use gspca's input device handling
Drop custom code for handling the input button in favor of using gspca's input hanlding mechinism. Signed-off-by: Brian Johnson <brijohn@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/Kconfig6
-rw-r--r--drivers/media/video/gspca/sn9c20x.c147
2 files changed, 34 insertions, 119 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index e0060c1f0544..5d920e584de7 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -172,12 +172,6 @@ config USB_GSPCA_SN9C20X
172 To compile this driver as a module, choose M here: the 172 To compile this driver as a module, choose M here: the
173 module will be called gspca_sn9c20x. 173 module will be called gspca_sn9c20x.
174 174
175config USB_GSPCA_SN9C20X_EVDEV
176 bool "Enable evdev support"
177 depends on USB_GSPCA_SN9C20X && INPUT
178 ---help---
179 Say Y here in order to enable evdev support for sn9c20x webcam button.
180
181config USB_GSPCA_SONIXB 175config USB_GSPCA_SONIXB
182 tristate "SONIX Bayer USB Camera Driver" 176 tristate "SONIX Bayer USB Camera Driver"
183 depends on VIDEO_V4L2 && USB_GSPCA 177 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 04bf80ddfbb8..1653567e992a 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -18,10 +18,7 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 21#ifdef CONFIG_INPUT
22#include <linux/kthread.h>
23#include <linux/freezer.h>
24#include <linux/usb/input.h>
25#include <linux/input.h> 22#include <linux/input.h>
26#include <linux/slab.h> 23#include <linux/slab.h>
27#endif 24#endif
@@ -55,6 +52,9 @@ MODULE_LICENSE("GPL");
55#define SENSOR_HV7131R 10 52#define SENSOR_HV7131R 10
56#define SENSOR_MT9VPRB 20 53#define SENSOR_MT9VPRB 20
57 54
55/* camera flags */
56#define HAS_BUTTON 0x1
57
58/* specific webcam descriptor */ 58/* specific webcam descriptor */
59struct sd { 59struct sd {
60 struct gspca_dev gspca_dev; 60 struct gspca_dev gspca_dev;
@@ -88,11 +88,7 @@ struct sd {
88 u8 *jpeg_hdr; 88 u8 *jpeg_hdr;
89 u8 quality; 89 u8 quality;
90 90
91#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 91 u8 flags;
92 struct input_dev *input_dev;
93 u8 input_gpio;
94 struct task_struct *input_task;
95#endif
96}; 92};
97 93
98struct i2c_reg_u8 { 94struct i2c_reg_u8 {
@@ -1421,87 +1417,6 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1421 return 0; 1417 return 0;
1422} 1418}
1423 1419
1424#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1425static int input_kthread(void *data)
1426{
1427 struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
1428 struct sd *sd = (struct sd *) gspca_dev;
1429
1430 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait);
1431 set_freezable();
1432 for (;;) {
1433 if (kthread_should_stop())
1434 break;
1435
1436 if (reg_r(gspca_dev, 0x1005, 1) < 0)
1437 continue;
1438
1439 input_report_key(sd->input_dev,
1440 KEY_CAMERA,
1441 gspca_dev->usb_buf[0] & sd->input_gpio);
1442 input_sync(sd->input_dev);
1443
1444 wait_event_freezable_timeout(wait,
1445 kthread_should_stop(),
1446 msecs_to_jiffies(100));
1447 }
1448 return 0;
1449}
1450
1451
1452static int sn9c20x_input_init(struct gspca_dev *gspca_dev)
1453{
1454 struct sd *sd = (struct sd *) gspca_dev;
1455 if (sd->input_gpio == 0)
1456 return 0;
1457
1458 sd->input_dev = input_allocate_device();
1459 if (!sd->input_dev)
1460 return -ENOMEM;
1461
1462 sd->input_dev->name = "SN9C20X Webcam";
1463
1464 sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s",
1465 gspca_dev->dev->bus->bus_name,
1466 gspca_dev->dev->devpath);
1467
1468 if (!sd->input_dev->phys)
1469 return -ENOMEM;
1470
1471 usb_to_input_id(gspca_dev->dev, &sd->input_dev->id);
1472 sd->input_dev->dev.parent = &gspca_dev->dev->dev;
1473
1474 set_bit(EV_KEY, sd->input_dev->evbit);
1475 set_bit(KEY_CAMERA, sd->input_dev->keybit);
1476
1477 if (input_register_device(sd->input_dev))
1478 return -EINVAL;
1479
1480 sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s",
1481 gspca_dev->dev->bus->bus_name,
1482 gspca_dev->dev->devpath);
1483
1484 if (IS_ERR(sd->input_task))
1485 return -EINVAL;
1486
1487 return 0;
1488}
1489
1490static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev)
1491{
1492 struct sd *sd = (struct sd *) gspca_dev;
1493 if (sd->input_task != NULL && !IS_ERR(sd->input_task))
1494 kthread_stop(sd->input_task);
1495
1496 if (sd->input_dev != NULL) {
1497 input_unregister_device(sd->input_dev);
1498 kfree(sd->input_dev->phys);
1499 input_free_device(sd->input_dev);
1500 sd->input_dev = NULL;
1501 }
1502}
1503#endif
1504
1505static int set_cmatrix(struct gspca_dev *gspca_dev) 1420static int set_cmatrix(struct gspca_dev *gspca_dev)
1506{ 1421{
1507 struct sd *sd = (struct sd *) gspca_dev; 1422 struct sd *sd = (struct sd *) gspca_dev;
@@ -2005,6 +1920,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2005 1920
2006 sd->sensor = (id->driver_info >> 8) & 0xff; 1921 sd->sensor = (id->driver_info >> 8) & 0xff;
2007 sd->i2c_addr = id->driver_info & 0xff; 1922 sd->i2c_addr = id->driver_info & 0xff;
1923 sd->flags = (id->driver_info >> 16) & 0xff;
2008 1924
2009 switch (sd->sensor) { 1925 switch (sd->sensor) {
2010 case SENSOR_MT9M111: 1926 case SENSOR_MT9M111:
@@ -2039,11 +1955,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
2039 1955
2040 sd->quality = 95; 1956 sd->quality = 95;
2041 1957
2042#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2043 sd->input_gpio = (id->driver_info >> 16) & 0xff;
2044 if (sn9c20x_input_init(gspca_dev) < 0)
2045 return -ENODEV;
2046#endif
2047 return 0; 1958 return 0;
2048} 1959}
2049 1960
@@ -2343,6 +2254,24 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2343 do_autoexposure(gspca_dev, avg_lum); 2254 do_autoexposure(gspca_dev, avg_lum);
2344} 2255}
2345 2256
2257#ifdef CONFIG_INPUT
2258static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2259 u8 *data, /* interrupt packet */
2260 int len) /* interrupt packet length */
2261{
2262 struct sd *sd = (struct sd *) gspca_dev;
2263 int ret = -EINVAL;
2264 if (sd->flags & HAS_BUTTON && len == 1) {
2265 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2266 input_sync(gspca_dev->input_dev);
2267 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2268 input_sync(gspca_dev->input_dev);
2269 ret = 0;
2270 }
2271 return ret;
2272}
2273#endif
2274
2346static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2275static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2347 u8 *data, /* isoc packet */ 2276 u8 *data, /* isoc packet */
2348 int len) /* iso packet length */ 2277 int len) /* iso packet length */
@@ -2409,6 +2338,9 @@ static const struct sd_desc sd_desc = {
2409 .stopN = sd_stopN, 2338 .stopN = sd_stopN,
2410 .stop0 = sd_stop0, 2339 .stop0 = sd_stop0,
2411 .pkt_scan = sd_pkt_scan, 2340 .pkt_scan = sd_pkt_scan,
2341#ifdef CONFIG_INPUT
2342 .int_pkt_scan = sd_int_pkt_scan,
2343#endif
2412 .dq_callback = sd_dqcallback, 2344 .dq_callback = sd_dqcallback,
2413#ifdef CONFIG_VIDEO_ADV_DEBUG 2345#ifdef CONFIG_VIDEO_ADV_DEBUG
2414 .set_register = sd_dbg_s_register, 2346 .set_register = sd_dbg_s_register,
@@ -2417,8 +2349,8 @@ static const struct sd_desc sd_desc = {
2417 .get_chip_ident = sd_chip_ident, 2349 .get_chip_ident = sd_chip_ident,
2418}; 2350};
2419 2351
2420#define SN9C20X(sensor, i2c_addr, button_mask) \ 2352#define SN9C20X(sensor, i2c_addr, flags) \
2421 .driver_info = (button_mask << 16) \ 2353 .driver_info = (flags << 16) \
2422 | (SENSOR_ ## sensor << 8) \ 2354 | (SENSOR_ ## sensor << 8) \
2423 | (i2c_addr) 2355 | (i2c_addr)
2424 2356
@@ -2426,7 +2358,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2426 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, 2358 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2427 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, 2359 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2428 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2360 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2429 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)}, 2361 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, HAS_BUTTON)},
2430 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, 2362 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)},
2431 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2363 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2432 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2364 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
@@ -2437,13 +2369,13 @@ static const __devinitdata struct usb_device_id device_table[] = {
2437 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2369 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2438 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2370 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2439 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, 2371 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2440 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, 2372 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, HAS_BUTTON)},
2441 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, 2373 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2442 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, 2374 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2443 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2375 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2444 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2376 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2445 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, 2377 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2446 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, 2378 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, HAS_BUTTON)},
2447 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2379 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2448 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2380 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2449 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2381 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
@@ -2452,7 +2384,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2452 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, 2384 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2453 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, 2385 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2454 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, 2386 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2455 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, 2387 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, HAS_BUTTON)},
2456 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, 2388 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2457 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, 2389 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2458 {} 2390 {}
@@ -2467,22 +2399,11 @@ static int sd_probe(struct usb_interface *intf,
2467 THIS_MODULE); 2399 THIS_MODULE);
2468} 2400}
2469 2401
2470static void sd_disconnect(struct usb_interface *intf)
2471{
2472#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2473 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2474
2475 sn9c20x_input_cleanup(gspca_dev);
2476#endif
2477
2478 gspca_disconnect(intf);
2479}
2480
2481static struct usb_driver sd_driver = { 2402static struct usb_driver sd_driver = {
2482 .name = MODULE_NAME, 2403 .name = MODULE_NAME,
2483 .id_table = device_table, 2404 .id_table = device_table,
2484 .probe = sd_probe, 2405 .probe = sd_probe,
2485 .disconnect = sd_disconnect, 2406 .disconnect = gspca_disconnect,
2486#ifdef CONFIG_PM 2407#ifdef CONFIG_PM
2487 .suspend = gspca_suspend, 2408 .suspend = gspca_suspend,
2488 .resume = gspca_resume, 2409 .resume = gspca_resume,